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 18f16a1750SMaggie Zhang #include "bfad_drv.h" 197826f304SKrishna Gudipati #include "bfad_im.h" 20a36c61f9SKrishna Gudipati #include "bfa_fcs.h" 21a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h" 22a36c61f9SKrishna Gudipati #include "bfa_fc.h" 237725ccfdSJing Huang 247725ccfdSJing Huang BFA_TRC_FILE(FCS, PORT); 257725ccfdSJing Huang 26a36c61f9SKrishna Gudipati static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, 277725ccfdSJing Huang struct fchs_s *rx_fchs, u8 reason_code, 287725ccfdSJing Huang u8 reason_code_expl); 29a36c61f9SKrishna Gudipati static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 30a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi); 31a36c61f9SKrishna Gudipati static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port); 32a36c61f9SKrishna Gudipati static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port); 33a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port); 34a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port); 35a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port); 36a36c61f9SKrishna Gudipati static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port); 37a36c61f9SKrishna Gudipati static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, 387725ccfdSJing Huang struct fchs_s *rx_fchs, 397725ccfdSJing Huang struct fc_echo_s *echo, u16 len); 40a36c61f9SKrishna Gudipati static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, 417725ccfdSJing Huang struct fchs_s *rx_fchs, 427725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 len); 43a36c61f9SKrishna Gudipati static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 447725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data); 457725ccfdSJing Huang 46a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port); 47a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port); 48a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port); 49a36c61f9SKrishna Gudipati 50a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port); 51a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); 52a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); 53a36c61f9SKrishna Gudipati 547725ccfdSJing Huang static struct { 55a36c61f9SKrishna Gudipati void (*init) (struct bfa_fcs_lport_s *port); 56a36c61f9SKrishna Gudipati void (*online) (struct bfa_fcs_lport_s *port); 57a36c61f9SKrishna Gudipati void (*offline) (struct bfa_fcs_lport_s *port); 587725ccfdSJing Huang } __port_action[] = { 597725ccfdSJing Huang { 60a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online, 61a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline}, { 62a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, 63a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline}, { 64a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, 65a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline}, 66a36c61f9SKrishna Gudipati }; 677725ccfdSJing Huang 685fbe25c7SJing Huang /* 697725ccfdSJing Huang * fcs_port_sm FCS logical port state machine 707725ccfdSJing Huang */ 717725ccfdSJing Huang 72a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event { 737725ccfdSJing Huang BFA_FCS_PORT_SM_CREATE = 1, 747725ccfdSJing Huang BFA_FCS_PORT_SM_ONLINE = 2, 757725ccfdSJing Huang BFA_FCS_PORT_SM_OFFLINE = 3, 767725ccfdSJing Huang BFA_FCS_PORT_SM_DELETE = 4, 777725ccfdSJing Huang BFA_FCS_PORT_SM_DELRPORT = 5, 78dd5aaf45SKrishna Gudipati BFA_FCS_PORT_SM_STOP = 6, 797725ccfdSJing Huang }; 807725ccfdSJing Huang 81a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, 82a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 83a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 84a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 85a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port, 86a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 87a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port, 88a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 89a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, 90a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 91dd5aaf45SKrishna Gudipati static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 92dd5aaf45SKrishna Gudipati enum bfa_fcs_lport_event event); 937725ccfdSJing Huang 947725ccfdSJing Huang static void 95a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_uninit( 96a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 97a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 987725ccfdSJing Huang { 997725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1007725ccfdSJing Huang bfa_trc(port->fcs, event); 1017725ccfdSJing Huang 1027725ccfdSJing Huang switch (event) { 1037725ccfdSJing Huang case BFA_FCS_PORT_SM_CREATE: 104a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 1057725ccfdSJing Huang break; 1067725ccfdSJing Huang 1077725ccfdSJing Huang default: 108e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1097725ccfdSJing Huang } 1107725ccfdSJing Huang } 1117725ccfdSJing Huang 1127725ccfdSJing Huang static void 113a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 114a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1157725ccfdSJing Huang { 1167725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1177725ccfdSJing Huang bfa_trc(port->fcs, event); 1187725ccfdSJing Huang 1197725ccfdSJing Huang switch (event) { 1207725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 121a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 122a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 1237725ccfdSJing Huang break; 1247725ccfdSJing Huang 1257725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 126a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 127a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 1287725ccfdSJing Huang break; 1297725ccfdSJing Huang 130dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 131dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 132dd5aaf45SKrishna Gudipati if (port->vport) 133dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 134dd5aaf45SKrishna Gudipati break; 135dd5aaf45SKrishna Gudipati 1363e98cc01SJing Huang case BFA_FCS_PORT_SM_OFFLINE: 1373e98cc01SJing Huang break; 1383e98cc01SJing Huang 1397725ccfdSJing Huang default: 140e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1417725ccfdSJing Huang } 1427725ccfdSJing Huang } 1437725ccfdSJing Huang 1447725ccfdSJing Huang static void 145a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online( 146a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 147a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1487725ccfdSJing Huang { 1497725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 1507725ccfdSJing Huang struct list_head *qe, *qen; 1517725ccfdSJing Huang 1527725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1537725ccfdSJing Huang bfa_trc(port->fcs, event); 1547725ccfdSJing Huang 1557725ccfdSJing Huang switch (event) { 1567725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 157a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_offline); 158a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(port); 1597725ccfdSJing Huang break; 1607725ccfdSJing Huang 161dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 162dd5aaf45SKrishna Gudipati __port_action[port->fabric->fab_type].offline(port); 163dd5aaf45SKrishna Gudipati 164dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 165dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 166dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 167dd5aaf45SKrishna Gudipati if (port->vport) 168dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 169dd5aaf45SKrishna Gudipati } else { 170dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 171dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 172dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 173dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 174dd5aaf45SKrishna Gudipati } 175dd5aaf45SKrishna Gudipati } 176dd5aaf45SKrishna Gudipati break; 177dd5aaf45SKrishna Gudipati 1787725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 1797725ccfdSJing Huang 1807725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 1817725ccfdSJing Huang 1827725ccfdSJing Huang if (port->num_rports == 0) { 183a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 184a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 1857725ccfdSJing Huang } else { 186a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 1877725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 1887725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 189f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1907725ccfdSJing Huang } 1917725ccfdSJing Huang } 1927725ccfdSJing Huang break; 1937725ccfdSJing Huang 1947725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 1957725ccfdSJing Huang break; 1967725ccfdSJing Huang 1977725ccfdSJing Huang default: 198e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1997725ccfdSJing Huang } 2007725ccfdSJing Huang } 2017725ccfdSJing Huang 2027725ccfdSJing Huang static void 203a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline( 204a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 205a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 2067725ccfdSJing Huang { 2077725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 2087725ccfdSJing Huang struct list_head *qe, *qen; 2097725ccfdSJing Huang 2107725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 2117725ccfdSJing Huang bfa_trc(port->fcs, event); 2127725ccfdSJing Huang 2137725ccfdSJing Huang switch (event) { 2147725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 215a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 216a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 2177725ccfdSJing Huang break; 2187725ccfdSJing Huang 219dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 220dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 221dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 222dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 223dd5aaf45SKrishna Gudipati if (port->vport) 224dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 225dd5aaf45SKrishna Gudipati } else { 226dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 227dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 228dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 229dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 230dd5aaf45SKrishna Gudipati } 231dd5aaf45SKrishna Gudipati } 232dd5aaf45SKrishna Gudipati break; 233dd5aaf45SKrishna Gudipati 2347725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 2357725ccfdSJing Huang if (port->num_rports == 0) { 236a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 237a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2387725ccfdSJing Huang } else { 239a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 2407725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 2417725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 242f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 2437725ccfdSJing Huang } 2447725ccfdSJing Huang } 2457725ccfdSJing Huang break; 2467725ccfdSJing Huang 2477725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2487725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 2497725ccfdSJing Huang break; 2507725ccfdSJing Huang 2517725ccfdSJing Huang default: 252e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2537725ccfdSJing Huang } 2547725ccfdSJing Huang } 2557725ccfdSJing Huang 2567725ccfdSJing Huang static void 257dd5aaf45SKrishna Gudipati bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 258dd5aaf45SKrishna Gudipati enum bfa_fcs_lport_event event) 259dd5aaf45SKrishna Gudipati { 260dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 261dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, event); 262dd5aaf45SKrishna Gudipati 263dd5aaf45SKrishna Gudipati switch (event) { 264dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_DELRPORT: 265dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 266dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 267dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 268dd5aaf45SKrishna Gudipati if (port->vport) 269dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 270dd5aaf45SKrishna Gudipati } 271dd5aaf45SKrishna Gudipati break; 272dd5aaf45SKrishna Gudipati 273dd5aaf45SKrishna Gudipati default: 274dd5aaf45SKrishna Gudipati bfa_sm_fault(port->fcs, event); 275dd5aaf45SKrishna Gudipati } 276dd5aaf45SKrishna Gudipati } 277dd5aaf45SKrishna Gudipati 278dd5aaf45SKrishna Gudipati static void 279a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting( 280a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 281a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 2827725ccfdSJing Huang { 2837725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 2847725ccfdSJing Huang bfa_trc(port->fcs, event); 2857725ccfdSJing Huang 2867725ccfdSJing Huang switch (event) { 2877725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2887725ccfdSJing Huang if (port->num_rports == 0) { 289a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 290a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2917725ccfdSJing Huang } 2927725ccfdSJing Huang break; 2937725ccfdSJing Huang 2947725ccfdSJing Huang default: 295e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2967725ccfdSJing Huang } 2977725ccfdSJing Huang } 2987725ccfdSJing Huang 2995fbe25c7SJing Huang /* 3007725ccfdSJing Huang * fcs_port_pvt 3017725ccfdSJing Huang */ 3027725ccfdSJing Huang 3037725ccfdSJing Huang /* 3047826f304SKrishna Gudipati * Send AEN notification 3057826f304SKrishna Gudipati */ 3067826f304SKrishna Gudipati static void 3077826f304SKrishna Gudipati bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port, 3087826f304SKrishna Gudipati enum bfa_lport_aen_event event) 3097826f304SKrishna Gudipati { 3107826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 3117826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 3127826f304SKrishna Gudipati 3137826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 3147826f304SKrishna Gudipati if (!aen_entry) 3157826f304SKrishna Gudipati return; 3167826f304SKrishna Gudipati 3177826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 3187826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 3197826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 3207826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 3217826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 3227826f304SKrishna Gudipati 3237826f304SKrishna Gudipati /* Send the AEN notification */ 3247826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 3257826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 3267826f304SKrishna Gudipati } 3277826f304SKrishna Gudipati 3287826f304SKrishna Gudipati /* 3297725ccfdSJing Huang * Send a LS reject 3307725ccfdSJing Huang */ 3317725ccfdSJing Huang static void 332a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 3337725ccfdSJing Huang u8 reason_code, u8 reason_code_expl) 3347725ccfdSJing Huang { 3357725ccfdSJing Huang struct fchs_s fchs; 3367725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 3377725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 3387725ccfdSJing Huang int len; 3397725ccfdSJing Huang 340a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 3417725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 3427725ccfdSJing Huang 3437725ccfdSJing Huang fcxp = bfa_fcs_fcxp_alloc(port->fcs); 3447725ccfdSJing Huang if (!fcxp) 3457725ccfdSJing Huang return; 3467725ccfdSJing Huang 347a36c61f9SKrishna Gudipati len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 348a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 349a36c61f9SKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 3507725ccfdSJing Huang 3517725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 3527725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 3537725ccfdSJing Huang FC_MAX_PDUSZ, 0); 3547725ccfdSJing Huang } 3557725ccfdSJing Huang 3565fbe25c7SJing Huang /* 357d7be54ccSKrishna Gudipati * Send a FCCT Reject 358d7be54ccSKrishna Gudipati */ 359d7be54ccSKrishna Gudipati static void 360d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port, 361d7be54ccSKrishna Gudipati struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl) 362d7be54ccSKrishna Gudipati { 363d7be54ccSKrishna Gudipati struct fchs_s fchs; 364d7be54ccSKrishna Gudipati struct bfa_fcxp_s *fcxp; 365d7be54ccSKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 366d7be54ccSKrishna Gudipati int len; 367d7be54ccSKrishna Gudipati struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1); 368d7be54ccSKrishna Gudipati struct ct_hdr_s *ct_hdr; 369d7be54ccSKrishna Gudipati 370d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 371d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 372d7be54ccSKrishna Gudipati 373d7be54ccSKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs); 374d7be54ccSKrishna Gudipati if (!fcxp) 375d7be54ccSKrishna Gudipati return; 376d7be54ccSKrishna Gudipati 377d7be54ccSKrishna Gudipati ct_hdr = bfa_fcxp_get_reqbuf(fcxp); 378d7be54ccSKrishna Gudipati ct_hdr->gs_type = rx_cthdr->gs_type; 379d7be54ccSKrishna Gudipati ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type; 380d7be54ccSKrishna Gudipati 381d7be54ccSKrishna Gudipati len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id, 382d7be54ccSKrishna Gudipati bfa_fcs_lport_get_fcid(port), 383d7be54ccSKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 384d7be54ccSKrishna Gudipati 385d7be54ccSKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 386d7be54ccSKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 387d7be54ccSKrishna Gudipati FC_MAX_PDUSZ, 0); 388d7be54ccSKrishna Gudipati } 389d7be54ccSKrishna Gudipati 390d7be54ccSKrishna Gudipati /* 3917725ccfdSJing Huang * Process incoming plogi from a remote port. 3927725ccfdSJing Huang */ 3937725ccfdSJing Huang static void 394a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 395a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi) 3967725ccfdSJing Huang { 3977725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 3987725ccfdSJing Huang 3997725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 4007725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4017725ccfdSJing Huang 4027725ccfdSJing Huang /* 4037725ccfdSJing Huang * If min cfg mode is enabled, drop any incoming PLOGIs 4047725ccfdSJing Huang */ 4057725ccfdSJing Huang if (__fcs_min_cfg(port->fcs)) { 4067725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4077725ccfdSJing Huang return; 4087725ccfdSJing Huang } 4097725ccfdSJing Huang 4107725ccfdSJing Huang if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) { 4117725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4127725ccfdSJing Huang /* 4137725ccfdSJing Huang * send a LS reject 4147725ccfdSJing Huang */ 415a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4167725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4177725ccfdSJing Huang FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS); 4187725ccfdSJing Huang return; 4197725ccfdSJing Huang } 4207725ccfdSJing Huang 4215fbe25c7SJing Huang /* 4227725ccfdSJing Huang * Direct Attach P2P mode : verify address assigned by the r-port. 4237725ccfdSJing Huang */ 424a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 425a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 426a36c61f9SKrishna Gudipati (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4277725ccfdSJing Huang if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) { 428a36c61f9SKrishna Gudipati /* Address assigned to us cannot be a WKA */ 429a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4307725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4317725ccfdSJing Huang FC_LS_RJT_EXP_INVALID_NPORT_ID); 4327725ccfdSJing Huang return; 4337725ccfdSJing Huang } 4347725ccfdSJing Huang port->pid = rx_fchs->d_id; 435b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4367725ccfdSJing Huang } 4377725ccfdSJing Huang 4385fbe25c7SJing Huang /* 4397725ccfdSJing Huang * First, check if we know the device by pwwn. 4407725ccfdSJing Huang */ 441a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name); 4427725ccfdSJing Huang if (rport) { 4435fbe25c7SJing Huang /* 444a36c61f9SKrishna Gudipati * Direct Attach P2P mode : handle address assigned by r-port. 4457725ccfdSJing Huang */ 446a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 447a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 4487725ccfdSJing Huang (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4497725ccfdSJing Huang port->pid = rx_fchs->d_id; 450b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4517725ccfdSJing Huang rport->pid = rx_fchs->s_id; 4527725ccfdSJing Huang } 4537725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 4547725ccfdSJing Huang return; 4557725ccfdSJing Huang } 4567725ccfdSJing Huang 4575fbe25c7SJing Huang /* 4587725ccfdSJing Huang * Next, lookup rport by PID. 4597725ccfdSJing Huang */ 460a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id); 4617725ccfdSJing Huang if (!rport) { 4625fbe25c7SJing Huang /* 4637725ccfdSJing Huang * Inbound PLOGI from a new device. 4647725ccfdSJing Huang */ 4657725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 4667725ccfdSJing Huang return; 4677725ccfdSJing Huang } 4687725ccfdSJing Huang 4695fbe25c7SJing Huang /* 4707725ccfdSJing Huang * Rport is known only by PID. 4717725ccfdSJing Huang */ 4727725ccfdSJing Huang if (rport->pwwn) { 4735fbe25c7SJing Huang /* 4747725ccfdSJing Huang * This is a different device with the same pid. Old device 4757725ccfdSJing Huang * disappeared. Send implicit LOGO to old device. 4767725ccfdSJing Huang */ 477d4b671c5SJing Huang WARN_ON(rport->pwwn == plogi->port_name); 478f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 4797725ccfdSJing Huang 4805fbe25c7SJing Huang /* 4817725ccfdSJing Huang * Inbound PLOGI from a new device (with old PID). 4827725ccfdSJing Huang */ 4837725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 4847725ccfdSJing Huang return; 4857725ccfdSJing Huang } 4867725ccfdSJing Huang 4875fbe25c7SJing Huang /* 4887725ccfdSJing Huang * PLOGI crossing each other. 4897725ccfdSJing Huang */ 490d4b671c5SJing Huang WARN_ON(rport->pwwn != WWN_NULL); 4917725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 4927725ccfdSJing Huang } 4937725ccfdSJing Huang 4947725ccfdSJing Huang /* 4957725ccfdSJing Huang * Process incoming ECHO. 4967725ccfdSJing Huang * Since it does not require a login, it is processed here. 4977725ccfdSJing Huang */ 4987725ccfdSJing Huang static void 499a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5007725ccfdSJing Huang struct fc_echo_s *echo, u16 rx_len) 5017725ccfdSJing Huang { 5027725ccfdSJing Huang struct fchs_s fchs; 5037725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5047725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5057725ccfdSJing Huang int len, pyld_len; 5067725ccfdSJing Huang 5077725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5087725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5097725ccfdSJing Huang 5107725ccfdSJing Huang fcxp = bfa_fcs_fcxp_alloc(port->fcs); 5117725ccfdSJing Huang if (!fcxp) 5127725ccfdSJing Huang return; 5137725ccfdSJing Huang 514a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 515a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 516a36c61f9SKrishna Gudipati rx_fchs->ox_id); 5177725ccfdSJing Huang 5187725ccfdSJing Huang /* 5197725ccfdSJing Huang * Copy the payload (if any) from the echo frame 5207725ccfdSJing Huang */ 5217725ccfdSJing Huang pyld_len = rx_len - sizeof(struct fchs_s); 522a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_len); 5237725ccfdSJing Huang bfa_trc(port->fcs, pyld_len); 5247725ccfdSJing Huang 5257725ccfdSJing Huang if (pyld_len > len) 5267725ccfdSJing Huang memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) + 5277725ccfdSJing Huang sizeof(struct fc_echo_s), (echo + 1), 5287725ccfdSJing Huang (pyld_len - sizeof(struct fc_echo_s))); 5297725ccfdSJing Huang 5307725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5317725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL, 5327725ccfdSJing Huang FC_MAX_PDUSZ, 0); 5337725ccfdSJing Huang } 5347725ccfdSJing Huang 5357725ccfdSJing Huang /* 5367725ccfdSJing Huang * Process incoming RNID. 5377725ccfdSJing Huang * Since it does not require a login, it is processed here. 5387725ccfdSJing Huang */ 5397725ccfdSJing Huang static void 540a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5417725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 rx_len) 5427725ccfdSJing Huang { 5437725ccfdSJing Huang struct fc_rnid_common_id_data_s common_id_data; 5447725ccfdSJing Huang struct fc_rnid_general_topology_data_s gen_topo_data; 5457725ccfdSJing Huang struct fchs_s fchs; 5467725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5477725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5487725ccfdSJing Huang u16 len; 5497725ccfdSJing Huang u32 data_format; 5507725ccfdSJing Huang 5517725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5527725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5537725ccfdSJing Huang bfa_trc(port->fcs, rx_len); 5547725ccfdSJing Huang 5557725ccfdSJing Huang fcxp = bfa_fcs_fcxp_alloc(port->fcs); 5567725ccfdSJing Huang if (!fcxp) 5577725ccfdSJing Huang return; 5587725ccfdSJing Huang 5597725ccfdSJing Huang /* 5607725ccfdSJing Huang * Check Node Indentification Data Format 5617725ccfdSJing Huang * We only support General Topology Discovery Format. 5627725ccfdSJing Huang * For any other requested Data Formats, we return Common Node Id Data 5637725ccfdSJing Huang * only, as per FC-LS. 5647725ccfdSJing Huang */ 5657725ccfdSJing Huang bfa_trc(port->fcs, rnid->node_id_data_format); 5667725ccfdSJing Huang if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 5677725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY; 5687725ccfdSJing Huang /* 5697725ccfdSJing Huang * Get General topology data for this port 5707725ccfdSJing Huang */ 5717725ccfdSJing Huang bfa_fs_port_get_gen_topo_data(port, &gen_topo_data); 5727725ccfdSJing Huang } else { 5737725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_COMMON; 5747725ccfdSJing Huang } 5757725ccfdSJing Huang 5767725ccfdSJing Huang /* 5777725ccfdSJing Huang * Copy the Node Id Info 5787725ccfdSJing Huang */ 579a36c61f9SKrishna Gudipati common_id_data.port_name = bfa_fcs_lport_get_pwwn(port); 580a36c61f9SKrishna Gudipati common_id_data.node_name = bfa_fcs_lport_get_nwwn(port); 5817725ccfdSJing Huang 582a36c61f9SKrishna Gudipati len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 583a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 584a36c61f9SKrishna Gudipati rx_fchs->ox_id, data_format, &common_id_data, 585a36c61f9SKrishna Gudipati &gen_topo_data); 5867725ccfdSJing Huang 5877725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5887725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 5897725ccfdSJing Huang FC_MAX_PDUSZ, 0); 5907725ccfdSJing Huang } 5917725ccfdSJing Huang 5927725ccfdSJing Huang /* 5937725ccfdSJing Huang * Fill out General Topolpgy Discovery Data for RNID ELS. 5947725ccfdSJing Huang */ 5957725ccfdSJing Huang static void 596a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 5977725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data) 5987725ccfdSJing Huang { 5996a18b167SJing Huang memset(gen_topo_data, 0, 6007725ccfdSJing Huang sizeof(struct fc_rnid_general_topology_data_s)); 6017725ccfdSJing Huang 602ba816ea8SJing Huang gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST); 6037725ccfdSJing Huang gen_topo_data->phy_port_num = 0; /* @todo */ 604ba816ea8SJing Huang gen_topo_data->num_attached_nodes = cpu_to_be32(1); 6057725ccfdSJing Huang } 6067725ccfdSJing Huang 6077725ccfdSJing Huang static void 608a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) 6097725ccfdSJing Huang { 610a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 611a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 612a36c61f9SKrishna Gudipati 6137725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6147725ccfdSJing Huang 6157725ccfdSJing Huang __port_action[port->fabric->fab_type].init(port); 6167725ccfdSJing Huang __port_action[port->fabric->fab_type].online(port); 6177725ccfdSJing Huang 618a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 61988166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 620a36c61f9SKrishna Gudipati "Logical port online: WWN = %s Role = %s\n", 621a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6227826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE); 623a36c61f9SKrishna Gudipati 624a36c61f9SKrishna Gudipati bfad->bfad_flags |= BFAD_PORT_ONLINE; 6257725ccfdSJing Huang } 6267725ccfdSJing Huang 6277725ccfdSJing Huang static void 628a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) 6297725ccfdSJing Huang { 6307725ccfdSJing Huang struct list_head *qe, *qen; 6317725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 632a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 633a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 6347725ccfdSJing Huang 6357725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6367725ccfdSJing Huang 6377725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 6387725ccfdSJing Huang 639a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 640f7f73812SMaggie Zhang if (bfa_sm_cmp_state(port->fabric, 6417826f304SKrishna Gudipati bfa_fcs_fabric_sm_online) == BFA_TRUE) { 64288166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 643a36c61f9SKrishna Gudipati "Logical port lost fabric connectivity: WWN = %s Role = %s\n", 644a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6457826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT); 6467826f304SKrishna Gudipati } else { 64788166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 648a36c61f9SKrishna Gudipati "Logical port taken offline: WWN = %s Role = %s\n", 649a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6507826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE); 6517826f304SKrishna Gudipati } 6527725ccfdSJing Huang 6537725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 6547725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 655f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 6567725ccfdSJing Huang } 6577725ccfdSJing Huang } 6587725ccfdSJing Huang 6597725ccfdSJing Huang static void 660a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port) 6617725ccfdSJing Huang { 662d4b671c5SJing Huang WARN_ON(1); 6637725ccfdSJing Huang } 6647725ccfdSJing Huang 6657725ccfdSJing Huang static void 666a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port) 6677725ccfdSJing Huang { 668d4b671c5SJing Huang WARN_ON(1); 6697725ccfdSJing Huang } 6707725ccfdSJing Huang 6717725ccfdSJing Huang static void 672a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port) 6737725ccfdSJing Huang { 674d4b671c5SJing Huang WARN_ON(1); 6757725ccfdSJing Huang } 6767725ccfdSJing Huang 6777725ccfdSJing Huang static void 678a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs) 6797725ccfdSJing Huang { 680a36c61f9SKrishna Gudipati struct fchs_s fchs; 681a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 682a36c61f9SKrishna Gudipati int len; 6837725ccfdSJing Huang 684a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 685a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 686a36c61f9SKrishna Gudipati 687a36c61f9SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs); 688a36c61f9SKrishna Gudipati if (!fcxp) 689a36c61f9SKrishna Gudipati return; 690a36c61f9SKrishna Gudipati 691a36c61f9SKrishna Gudipati len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 692a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 693a36c61f9SKrishna Gudipati rx_fchs->ox_id, 0); 694a36c61f9SKrishna Gudipati 695a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 696a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 697a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 698a36c61f9SKrishna Gudipati } 699a36c61f9SKrishna Gudipati static void 700a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) 701a36c61f9SKrishna Gudipati { 702a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 703a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 704a36c61f9SKrishna Gudipati 705a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 70688166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 707a36c61f9SKrishna Gudipati "Logical port deleted: WWN = %s Role = %s\n", 708a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 7097826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE); 710a36c61f9SKrishna Gudipati 711a36c61f9SKrishna Gudipati /* Base port will be deleted by the OS driver */ 71217c201b3SKrishna Gudipati if (port->vport) 7137725ccfdSJing Huang bfa_fcs_vport_delete_comp(port->vport); 71417c201b3SKrishna Gudipati else 715f7f73812SMaggie Zhang bfa_wc_down(&port->fabric->wc); 7167725ccfdSJing Huang } 7177725ccfdSJing Huang 7187725ccfdSJing Huang 7195fbe25c7SJing Huang /* 7207725ccfdSJing Huang * Unsolicited frame receive handling. 7217725ccfdSJing Huang */ 7227725ccfdSJing Huang void 723a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, 724a36c61f9SKrishna Gudipati struct fchs_s *fchs, u16 len) 7257725ccfdSJing Huang { 7267725ccfdSJing Huang u32 pid = fchs->s_id; 7277725ccfdSJing Huang struct bfa_fcs_rport_s *rport = NULL; 7287725ccfdSJing Huang struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 7297725ccfdSJing Huang 7307725ccfdSJing Huang bfa_stats(lport, uf_recvs); 73115821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->type); 7327725ccfdSJing Huang 733a36c61f9SKrishna Gudipati if (!bfa_fcs_lport_is_online(lport)) { 7347725ccfdSJing Huang bfa_stats(lport, uf_recv_drops); 7357725ccfdSJing Huang return; 7367725ccfdSJing Huang } 7377725ccfdSJing Huang 7385fbe25c7SJing Huang /* 7397725ccfdSJing Huang * First, handle ELSs that donot require a login. 7407725ccfdSJing Huang */ 7417725ccfdSJing Huang /* 7427725ccfdSJing Huang * Handle PLOGI first 7437725ccfdSJing Huang */ 7447725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && 7457725ccfdSJing Huang (els_cmd->els_code == FC_ELS_PLOGI)) { 746a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd); 7477725ccfdSJing Huang return; 7487725ccfdSJing Huang } 7497725ccfdSJing Huang 7507725ccfdSJing Huang /* 7517725ccfdSJing Huang * Handle ECHO separately. 7527725ccfdSJing Huang */ 7537725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) { 754a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(lport, fchs, 7557725ccfdSJing Huang (struct fc_echo_s *)els_cmd, len); 7567725ccfdSJing Huang return; 7577725ccfdSJing Huang } 7587725ccfdSJing Huang 7597725ccfdSJing Huang /* 7607725ccfdSJing Huang * Handle RNID separately. 7617725ccfdSJing Huang */ 7627725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) { 763a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(lport, fchs, 7647725ccfdSJing Huang (struct fc_rnid_cmd_s *) els_cmd, len); 7657725ccfdSJing Huang return; 7667725ccfdSJing Huang } 7677725ccfdSJing Huang 768a36c61f9SKrishna Gudipati if (fchs->type == FC_TYPE_BLS) { 769a36c61f9SKrishna Gudipati if ((fchs->routing == FC_RTG_BASIC_LINK) && 770a36c61f9SKrishna Gudipati (fchs->cat_info == FC_CAT_ABTS)) 771a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(lport, fchs); 772a36c61f9SKrishna Gudipati return; 773a36c61f9SKrishna Gudipati } 774d7be54ccSKrishna Gudipati 775d7be54ccSKrishna Gudipati if (fchs->type == FC_TYPE_SERVICES) { 776d7be54ccSKrishna Gudipati /* 777d7be54ccSKrishna Gudipati * Unhandled FC-GS frames. Send a FC-CT Reject 778d7be54ccSKrishna Gudipati */ 779d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP, 780d7be54ccSKrishna Gudipati CT_NS_EXP_NOADDITIONAL); 781d7be54ccSKrishna Gudipati return; 782d7be54ccSKrishna Gudipati } 783d7be54ccSKrishna Gudipati 7845fbe25c7SJing Huang /* 7857725ccfdSJing Huang * look for a matching remote port ID 7867725ccfdSJing Huang */ 787a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(lport, pid); 7887725ccfdSJing Huang if (rport) { 7897725ccfdSJing Huang bfa_trc(rport->fcs, fchs->s_id); 7907725ccfdSJing Huang bfa_trc(rport->fcs, fchs->d_id); 7917725ccfdSJing Huang bfa_trc(rport->fcs, fchs->type); 7927725ccfdSJing Huang 7937725ccfdSJing Huang bfa_fcs_rport_uf_recv(rport, fchs, len); 7947725ccfdSJing Huang return; 7957725ccfdSJing Huang } 7967725ccfdSJing Huang 7975fbe25c7SJing Huang /* 7987725ccfdSJing Huang * Only handles ELS frames for now. 7997725ccfdSJing Huang */ 8007725ccfdSJing Huang if (fchs->type != FC_TYPE_ELS) { 80115821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->s_id); 80215821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->d_id); 80315821f05SKrishna Gudipati /* ignore type FC_TYPE_FC_FSS */ 80415821f05SKrishna Gudipati if (fchs->type != FC_TYPE_FC_FSS) 80515821f05SKrishna Gudipati bfa_sm_fault(lport->fcs, fchs->type); 8067725ccfdSJing Huang return; 8077725ccfdSJing Huang } 8087725ccfdSJing Huang 8097725ccfdSJing Huang bfa_trc(lport->fcs, els_cmd->els_code); 8107725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_RSCN) { 811a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(lport, fchs, len); 8127725ccfdSJing Huang return; 8137725ccfdSJing Huang } 8147725ccfdSJing Huang 8157725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_LOGO) { 8165fbe25c7SJing Huang /* 8177725ccfdSJing Huang * @todo Handle LOGO frames received. 8187725ccfdSJing Huang */ 8197725ccfdSJing Huang return; 8207725ccfdSJing Huang } 8217725ccfdSJing Huang 8227725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_PRLI) { 8235fbe25c7SJing Huang /* 8247725ccfdSJing Huang * @todo Handle PRLI frames received. 8257725ccfdSJing Huang */ 8267725ccfdSJing Huang return; 8277725ccfdSJing Huang } 8287725ccfdSJing Huang 8295fbe25c7SJing Huang /* 8307725ccfdSJing Huang * Unhandled ELS frames. Send a LS_RJT. 8317725ccfdSJing Huang */ 832a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP, 8337725ccfdSJing Huang FC_LS_RJT_EXP_NO_ADDL_INFO); 8347725ccfdSJing Huang 8357725ccfdSJing Huang } 8367725ccfdSJing Huang 8375fbe25c7SJing Huang /* 8387725ccfdSJing Huang * PID based Lookup for a R-Port in the Port R-Port Queue 8397725ccfdSJing Huang */ 8407725ccfdSJing Huang struct bfa_fcs_rport_s * 841a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) 8427725ccfdSJing Huang { 8437725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 8447725ccfdSJing Huang struct list_head *qe; 8457725ccfdSJing Huang 8467725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 8477725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 8487725ccfdSJing Huang if (rport->pid == pid) 8497725ccfdSJing Huang return rport; 8507725ccfdSJing Huang } 8517725ccfdSJing Huang 8527725ccfdSJing Huang bfa_trc(port->fcs, pid); 8537725ccfdSJing Huang return NULL; 8547725ccfdSJing Huang } 8557725ccfdSJing Huang 8565fbe25c7SJing Huang /* 8577725ccfdSJing Huang * PWWN based Lookup for a R-Port in the Port R-Port Queue 8587725ccfdSJing Huang */ 8597725ccfdSJing Huang struct bfa_fcs_rport_s * 860a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn) 8617725ccfdSJing Huang { 8627725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 8637725ccfdSJing Huang struct list_head *qe; 8647725ccfdSJing Huang 8657725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 8667725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 8677725ccfdSJing Huang if (wwn_is_equal(rport->pwwn, pwwn)) 8687725ccfdSJing Huang return rport; 8697725ccfdSJing Huang } 8707725ccfdSJing Huang 8717725ccfdSJing Huang bfa_trc(port->fcs, pwwn); 872f8ceafdeSJing Huang return NULL; 8737725ccfdSJing Huang } 8747725ccfdSJing Huang 8755fbe25c7SJing Huang /* 8767725ccfdSJing Huang * NWWN based Lookup for a R-Port in the Port R-Port Queue 8777725ccfdSJing Huang */ 8787725ccfdSJing Huang struct bfa_fcs_rport_s * 879a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) 8807725ccfdSJing Huang { 8817725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 8827725ccfdSJing Huang struct list_head *qe; 8837725ccfdSJing Huang 8847725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 8857725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 8867725ccfdSJing Huang if (wwn_is_equal(rport->nwwn, nwwn)) 8877725ccfdSJing Huang return rport; 8887725ccfdSJing Huang } 8897725ccfdSJing Huang 8907725ccfdSJing Huang bfa_trc(port->fcs, nwwn); 891f8ceafdeSJing Huang return NULL; 8927725ccfdSJing Huang } 8937725ccfdSJing Huang 8945fbe25c7SJing Huang /* 8957725ccfdSJing Huang * Called by rport module when new rports are discovered. 8967725ccfdSJing Huang */ 8977725ccfdSJing Huang void 898a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport( 899a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 9007725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 9017725ccfdSJing Huang { 9027725ccfdSJing Huang list_add_tail(&rport->qe, &port->rport_q); 9037725ccfdSJing Huang port->num_rports++; 9047725ccfdSJing Huang } 9057725ccfdSJing Huang 9065fbe25c7SJing Huang /* 9077725ccfdSJing Huang * Called by rport module to when rports are deleted. 9087725ccfdSJing Huang */ 9097725ccfdSJing Huang void 910a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport( 911a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 9127725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 9137725ccfdSJing Huang { 914d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport)); 9157725ccfdSJing Huang list_del(&rport->qe); 9167725ccfdSJing Huang port->num_rports--; 9177725ccfdSJing Huang 9187725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT); 9197725ccfdSJing Huang } 9207725ccfdSJing Huang 9215fbe25c7SJing Huang /* 9227725ccfdSJing Huang * Called by fabric for base port when fabric login is complete. 9237725ccfdSJing Huang * Called by vport for virtual ports when FDISC is complete. 9247725ccfdSJing Huang */ 9257725ccfdSJing Huang void 926a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port) 9277725ccfdSJing Huang { 9287725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE); 9297725ccfdSJing Huang } 9307725ccfdSJing Huang 9315fbe25c7SJing Huang /* 9327725ccfdSJing Huang * Called by fabric for base port when fabric goes offline. 9337725ccfdSJing Huang * Called by vport for virtual ports when virtual port becomes offline. 9347725ccfdSJing Huang */ 9357725ccfdSJing Huang void 936a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port) 9377725ccfdSJing Huang { 9387725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE); 9397725ccfdSJing Huang } 9407725ccfdSJing Huang 9415fbe25c7SJing Huang /* 9427725ccfdSJing Huang * Called by fabric to delete base lport and associated resources. 9437725ccfdSJing Huang * 9447725ccfdSJing Huang * Called by vport to delete lport and associated resources. Should call 9457725ccfdSJing Huang * bfa_fcs_vport_delete_comp() for vports on completion. 9467725ccfdSJing Huang */ 9477725ccfdSJing Huang void 948a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port) 9497725ccfdSJing Huang { 9507725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE); 9517725ccfdSJing Huang } 9527725ccfdSJing Huang 9535fbe25c7SJing Huang /* 9547725ccfdSJing Huang * Return TRUE if port is online, else return FALSE 9557725ccfdSJing Huang */ 9567725ccfdSJing Huang bfa_boolean_t 957a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port) 9587725ccfdSJing Huang { 959a36c61f9SKrishna Gudipati return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online); 9607725ccfdSJing Huang } 9617725ccfdSJing Huang 9625fbe25c7SJing Huang /* 963e6714324SKrishna Gudipati * Attach time initialization of logical ports. 9647725ccfdSJing Huang */ 9657725ccfdSJing Huang void 966a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs, 967a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_fcs_vport_s *vport) 9687725ccfdSJing Huang { 9697725ccfdSJing Huang lport->fcs = fcs; 9707725ccfdSJing Huang lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); 9717725ccfdSJing Huang lport->vport = vport; 9723fd45980SKrishna Gudipati lport->lp_tag = (vport) ? vport->lps->bfa_tag : 9733fd45980SKrishna Gudipati lport->fabric->lps->bfa_tag; 9747725ccfdSJing Huang 9757725ccfdSJing Huang INIT_LIST_HEAD(&lport->rport_q); 9767725ccfdSJing Huang lport->num_rports = 0; 977e6714324SKrishna Gudipati } 9787725ccfdSJing Huang 9795fbe25c7SJing Huang /* 980e6714324SKrishna Gudipati * Logical port initialization of base or virtual port. 981e6714324SKrishna Gudipati * Called by fabric for base port or by vport for virtual ports. 982e6714324SKrishna Gudipati */ 983e6714324SKrishna Gudipati 984e6714324SKrishna Gudipati void 985a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, 986a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *port_cfg) 987e6714324SKrishna Gudipati { 988e6714324SKrishna Gudipati struct bfa_fcs_vport_s *vport = lport->vport; 989a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad; 990a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 991e6714324SKrishna Gudipati 9926a18b167SJing Huang lport->port_cfg = *port_cfg; 993e6714324SKrishna Gudipati 994a36c61f9SKrishna Gudipati lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport, 995e6714324SKrishna Gudipati lport->port_cfg.roles, 9967725ccfdSJing Huang lport->fabric->vf_drv, 9977725ccfdSJing Huang vport ? vport->vport_drv : NULL); 998e6714324SKrishna Gudipati 999a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); 100088166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 1001a36c61f9SKrishna Gudipati "New logical port created: WWN = %s Role = %s\n", 1002a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 10037826f304SKrishna Gudipati bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW); 10047725ccfdSJing Huang 1005a36c61f9SKrishna Gudipati bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit); 10067725ccfdSJing Huang bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 10077725ccfdSJing Huang } 10087725ccfdSJing Huang 10095fbe25c7SJing Huang /* 10107725ccfdSJing Huang * fcs_lport_api 10117725ccfdSJing Huang */ 10127725ccfdSJing Huang 10137725ccfdSJing Huang void 1014a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr( 1015a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 1016a36c61f9SKrishna Gudipati struct bfa_lport_attr_s *port_attr) 10177725ccfdSJing Huang { 1018a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 10197725ccfdSJing Huang port_attr->pid = port->pid; 10207725ccfdSJing Huang else 10217725ccfdSJing Huang port_attr->pid = 0; 10227725ccfdSJing Huang 10237725ccfdSJing Huang port_attr->port_cfg = port->port_cfg; 10247725ccfdSJing Huang 10257725ccfdSJing Huang if (port->fabric) { 1026f7f73812SMaggie Zhang port_attr->port_type = port->fabric->oper_type; 1027da99dcc9SMaggie Zhang port_attr->loopback = bfa_sm_cmp_state(port->fabric, 1028da99dcc9SMaggie Zhang bfa_fcs_fabric_sm_loopback); 1029f926a05fSKrishna Gudipati port_attr->authfail = 1030f7f73812SMaggie Zhang bfa_sm_cmp_state(port->fabric, 1031f7f73812SMaggie Zhang bfa_fcs_fabric_sm_auth_failed); 1032a36c61f9SKrishna Gudipati port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port); 10337725ccfdSJing Huang memcpy(port_attr->fabric_ip_addr, 1034a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fabric_ipaddr(port), 10357725ccfdSJing Huang BFA_FCS_FABRIC_IPADDR_SZ); 10367725ccfdSJing Huang 103786e32dabSKrishna Gudipati if (port->vport != NULL) { 1038a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_VPORT; 103986e32dabSKrishna Gudipati port_attr->fpma_mac = 1040f7f73812SMaggie Zhang port->vport->lps->lp_mac; 1041a36c61f9SKrishna Gudipati } else { 104286e32dabSKrishna Gudipati port_attr->fpma_mac = 1043f7f73812SMaggie Zhang port->fabric->lps->lp_mac; 1044a36c61f9SKrishna Gudipati } 1045a36c61f9SKrishna Gudipati } else { 1046a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_UNKNOWN; 1047a36c61f9SKrishna Gudipati port_attr->state = BFA_LPORT_UNINIT; 1048a36c61f9SKrishna Gudipati } 1049a36c61f9SKrishna Gudipati } 1050a36c61f9SKrishna Gudipati 10515fbe25c7SJing Huang /* 1052a36c61f9SKrishna Gudipati * bfa_fcs_lport_fab port fab functions 1053a36c61f9SKrishna Gudipati */ 1054a36c61f9SKrishna Gudipati 10555fbe25c7SJing Huang /* 1056a36c61f9SKrishna Gudipati * Called by port to initialize fabric services of the base port. 1057a36c61f9SKrishna Gudipati */ 1058a36c61f9SKrishna Gudipati static void 1059a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port) 1060a36c61f9SKrishna Gudipati { 1061a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(port); 1062a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(port); 1063a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(port); 1064a36c61f9SKrishna Gudipati } 1065a36c61f9SKrishna Gudipati 10665fbe25c7SJing Huang /* 1067a36c61f9SKrishna Gudipati * Called by port to notify transition to online state. 1068a36c61f9SKrishna Gudipati */ 1069a36c61f9SKrishna Gudipati static void 1070a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 1071a36c61f9SKrishna Gudipati { 1072a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(port); 1073a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(port); 1074a36c61f9SKrishna Gudipati } 1075a36c61f9SKrishna Gudipati 10765fbe25c7SJing Huang /* 1077a36c61f9SKrishna Gudipati * Called by port to notify transition to offline state. 1078a36c61f9SKrishna Gudipati */ 1079a36c61f9SKrishna Gudipati static void 1080a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port) 1081a36c61f9SKrishna Gudipati { 1082a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(port); 1083a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(port); 1084a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(port); 1085a36c61f9SKrishna Gudipati } 1086a36c61f9SKrishna Gudipati 10875fbe25c7SJing Huang /* 1088a36c61f9SKrishna Gudipati * bfa_fcs_lport_n2n functions 1089a36c61f9SKrishna Gudipati */ 1090a36c61f9SKrishna Gudipati 10915fbe25c7SJing Huang /* 1092a36c61f9SKrishna Gudipati * Called by fcs/port to initialize N2N topology. 1093a36c61f9SKrishna Gudipati */ 1094a36c61f9SKrishna Gudipati static void 1095a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port) 1096a36c61f9SKrishna Gudipati { 1097a36c61f9SKrishna Gudipati } 1098a36c61f9SKrishna Gudipati 10995fbe25c7SJing Huang /* 1100a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to online state. 1101a36c61f9SKrishna Gudipati */ 1102a36c61f9SKrishna Gudipati static void 1103a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port) 1104a36c61f9SKrishna Gudipati { 1105a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1106a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *pcfg = &port->port_cfg; 1107a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 1108a36c61f9SKrishna Gudipati 1109a36c61f9SKrishna Gudipati bfa_trc(port->fcs, pcfg->pwwn); 1110a36c61f9SKrishna Gudipati 1111a36c61f9SKrishna Gudipati /* 1112a36c61f9SKrishna Gudipati * If our PWWN is > than that of the r-port, we have to initiate PLOGI 1113a36c61f9SKrishna Gudipati * and assign an Address. if not, we need to wait for its PLOGI. 1114a36c61f9SKrishna Gudipati * 1115a36c61f9SKrishna Gudipati * If our PWWN is < than that of the remote port, it will send a PLOGI 1116a36c61f9SKrishna Gudipati * with the PIDs assigned. The rport state machine take care of this 1117a36c61f9SKrishna Gudipati * incoming PLOGI. 1118a36c61f9SKrishna Gudipati */ 1119a36c61f9SKrishna Gudipati if (memcmp 1120a36c61f9SKrishna Gudipati ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, 1121a36c61f9SKrishna Gudipati sizeof(wwn_t)) > 0) { 1122a36c61f9SKrishna Gudipati port->pid = N2N_LOCAL_PID; 1123b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID); 11245fbe25c7SJing Huang /* 1125a36c61f9SKrishna Gudipati * First, check if we know the device by pwwn. 1126a36c61f9SKrishna Gudipati */ 1127a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, 1128a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn); 1129a36c61f9SKrishna Gudipati if (rport) { 1130a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pid); 1131a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1132a36c61f9SKrishna Gudipati rport->pid = N2N_REMOTE_PID; 1133f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 1134a36c61f9SKrishna Gudipati return; 1135a36c61f9SKrishna Gudipati } 1136a36c61f9SKrishna Gudipati 1137a36c61f9SKrishna Gudipati /* 1138a36c61f9SKrishna Gudipati * In n2n there can be only one rport. Delete the old one 1139a36c61f9SKrishna Gudipati * whose pid should be zero, because it is offline. 1140a36c61f9SKrishna Gudipati */ 1141a36c61f9SKrishna Gudipati if (port->num_rports > 0) { 1142a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 0); 1143d4b671c5SJing Huang WARN_ON(rport == NULL); 1144a36c61f9SKrishna Gudipati if (rport) { 1145a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1146f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1147a36c61f9SKrishna Gudipati } 1148a36c61f9SKrishna Gudipati } 1149a36c61f9SKrishna Gudipati bfa_fcs_rport_create(port, N2N_REMOTE_PID); 1150a36c61f9SKrishna Gudipati } 1151a36c61f9SKrishna Gudipati } 1152a36c61f9SKrishna Gudipati 11535fbe25c7SJing Huang /* 1154a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to offline state. 1155a36c61f9SKrishna Gudipati */ 1156a36c61f9SKrishna Gudipati static void 1157a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port) 1158a36c61f9SKrishna Gudipati { 1159a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1160a36c61f9SKrishna Gudipati 1161a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 1162a36c61f9SKrishna Gudipati port->pid = 0; 1163a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn = 0; 1164a36c61f9SKrishna Gudipati n2n_port->reply_oxid = 0; 1165a36c61f9SKrishna Gudipati } 1166a36c61f9SKrishna Gudipati 1167a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 1168a36c61f9SKrishna Gudipati 1169a36c61f9SKrishna Gudipati /* 1170a36c61f9SKrishna Gudipati * forward declarations 1171a36c61f9SKrishna Gudipati */ 1172a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, 1173a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1174a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, 1175a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1176a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, 1177a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1178a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, 1179a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1180a36c61f9SKrishna Gudipati void *cbarg, 1181a36c61f9SKrishna Gudipati bfa_status_t req_status, 1182a36c61f9SKrishna Gudipati u32 rsp_len, 1183a36c61f9SKrishna Gudipati u32 resid_len, 1184a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1185a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, 1186a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1187a36c61f9SKrishna Gudipati void *cbarg, 1188a36c61f9SKrishna Gudipati bfa_status_t req_status, 1189a36c61f9SKrishna Gudipati u32 rsp_len, 1190a36c61f9SKrishna Gudipati u32 resid_len, 1191a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1192a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, 1193a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1194a36c61f9SKrishna Gudipati void *cbarg, 1195a36c61f9SKrishna Gudipati bfa_status_t req_status, 1196a36c61f9SKrishna Gudipati u32 rsp_len, 1197a36c61f9SKrishna Gudipati u32 resid_len, 1198a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1199a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_timeout(void *arg); 1200a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1201a36c61f9SKrishna Gudipati u8 *pyld); 1202a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1203a36c61f9SKrishna Gudipati u8 *pyld); 1204a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1205a36c61f9SKrishna Gudipati u8 *pyld); 1206a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s * 1207a36c61f9SKrishna Gudipati fdmi, u8 *pyld); 1208a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1209a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr); 1210a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1211a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr); 1212d7be54ccSKrishna Gudipati u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed); 1213d7be54ccSKrishna Gudipati 12145fbe25c7SJing Huang /* 1215a36c61f9SKrishna Gudipati * fcs_fdmi_sm FCS FDMI state machine 1216a36c61f9SKrishna Gudipati */ 1217a36c61f9SKrishna Gudipati 12185fbe25c7SJing Huang /* 1219a36c61f9SKrishna Gudipati * FDMI State Machine events 1220a36c61f9SKrishna Gudipati */ 1221a36c61f9SKrishna Gudipati enum port_fdmi_event { 1222a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_ONLINE = 1, 1223a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_OFFLINE = 2, 1224a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_OK = 4, 1225a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_ERROR = 5, 1226a36c61f9SKrishna Gudipati FDMISM_EVENT_TIMEOUT = 6, 1227a36c61f9SKrishna Gudipati FDMISM_EVENT_RHBA_SENT = 7, 1228a36c61f9SKrishna Gudipati FDMISM_EVENT_RPRT_SENT = 8, 1229a36c61f9SKrishna Gudipati FDMISM_EVENT_RPA_SENT = 9, 1230a36c61f9SKrishna Gudipati }; 1231a36c61f9SKrishna Gudipati 1232a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1233a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1234a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rhba( 1235a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1236a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1237a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1238a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1239a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba_retry( 1240a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1241a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1242a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rprt( 1243a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1244a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1245a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1246a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1247a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt_retry( 1248a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1249a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1250a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rpa( 1251a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1252a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1253a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1254a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1255a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa_retry( 1256a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1257a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1258a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1259a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1260a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_disabled( 1261a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1262a36c61f9SKrishna Gudipati enum port_fdmi_event event); 12635fbe25c7SJing Huang /* 1264a36c61f9SKrishna Gudipati * Start in offline state - awaiting MS to send start. 1265a36c61f9SKrishna Gudipati */ 1266a36c61f9SKrishna Gudipati static void 1267a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1268a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1269a36c61f9SKrishna Gudipati { 1270a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1271a36c61f9SKrishna Gudipati 1272a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1273a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1274a36c61f9SKrishna Gudipati 1275a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1276a36c61f9SKrishna Gudipati 1277a36c61f9SKrishna Gudipati switch (event) { 1278a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_ONLINE: 1279a36c61f9SKrishna Gudipati if (port->vport) { 1280a36c61f9SKrishna Gudipati /* 1281a36c61f9SKrishna Gudipati * For Vports, register a new port. 1282a36c61f9SKrishna Gudipati */ 1283a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1284a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt); 1285a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1286a36c61f9SKrishna Gudipati } else { 1287a36c61f9SKrishna Gudipati /* 1288a36c61f9SKrishna Gudipati * For a base port, we should first register the HBA 128925985edcSLucas De Marchi * attribute. The HBA attribute also contains the base 1290a36c61f9SKrishna Gudipati * port registration. 1291a36c61f9SKrishna Gudipati */ 1292a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1293a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba); 1294a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1295a36c61f9SKrishna Gudipati } 1296a36c61f9SKrishna Gudipati break; 1297a36c61f9SKrishna Gudipati 1298a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1299a36c61f9SKrishna Gudipati break; 1300a36c61f9SKrishna Gudipati 1301a36c61f9SKrishna Gudipati default: 1302a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1303a36c61f9SKrishna Gudipati } 1304a36c61f9SKrishna Gudipati } 1305a36c61f9SKrishna Gudipati 1306a36c61f9SKrishna Gudipati static void 1307a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1308a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1309a36c61f9SKrishna Gudipati { 1310a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1311a36c61f9SKrishna Gudipati 1312a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1313a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1314a36c61f9SKrishna Gudipati 1315a36c61f9SKrishna Gudipati switch (event) { 1316a36c61f9SKrishna Gudipati case FDMISM_EVENT_RHBA_SENT: 1317a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba); 1318a36c61f9SKrishna Gudipati break; 1319a36c61f9SKrishna Gudipati 1320a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1321a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1322a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1323a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1324a36c61f9SKrishna Gudipati break; 1325a36c61f9SKrishna Gudipati 1326a36c61f9SKrishna Gudipati default: 1327a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1328a36c61f9SKrishna Gudipati } 1329a36c61f9SKrishna Gudipati } 1330a36c61f9SKrishna Gudipati 1331a36c61f9SKrishna Gudipati static void 1332a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1333a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1334a36c61f9SKrishna Gudipati { 1335a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1336a36c61f9SKrishna Gudipati 1337a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1338a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1339a36c61f9SKrishna Gudipati 1340a36c61f9SKrishna Gudipati switch (event) { 1341a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1342a36c61f9SKrishna Gudipati /* 1343a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1344a36c61f9SKrishna Gudipati * delayed retry 1345a36c61f9SKrishna Gudipati */ 1346a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1347a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1348a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry); 1349a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1350a36c61f9SKrishna Gudipati &fdmi->timer, 1351a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1352a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1353a36c61f9SKrishna Gudipati } else { 1354a36c61f9SKrishna Gudipati /* 1355a36c61f9SKrishna Gudipati * set state to offline 1356a36c61f9SKrishna Gudipati */ 1357a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1358a36c61f9SKrishna Gudipati } 1359a36c61f9SKrishna Gudipati break; 1360a36c61f9SKrishna Gudipati 1361a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1362a36c61f9SKrishna Gudipati /* 1363a36c61f9SKrishna Gudipati * Initiate Register Port Attributes 1364a36c61f9SKrishna Gudipati */ 1365a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1366a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1367a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1368a36c61f9SKrishna Gudipati break; 1369a36c61f9SKrishna Gudipati 1370a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1371a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1372a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1373a36c61f9SKrishna Gudipati break; 1374a36c61f9SKrishna Gudipati 1375a36c61f9SKrishna Gudipati default: 1376a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1377a36c61f9SKrishna Gudipati } 1378a36c61f9SKrishna Gudipati } 1379a36c61f9SKrishna Gudipati 1380a36c61f9SKrishna Gudipati static void 1381a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1382a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1383a36c61f9SKrishna Gudipati { 1384a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1385a36c61f9SKrishna Gudipati 1386a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1387a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1388a36c61f9SKrishna Gudipati 1389a36c61f9SKrishna Gudipati switch (event) { 1390a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1391a36c61f9SKrishna Gudipati /* 1392a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1393a36c61f9SKrishna Gudipati */ 1394a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba); 1395a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1396a36c61f9SKrishna Gudipati break; 1397a36c61f9SKrishna Gudipati 1398a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1399a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1400a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1401a36c61f9SKrishna Gudipati break; 1402a36c61f9SKrishna Gudipati 1403a36c61f9SKrishna Gudipati default: 1404a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1405a36c61f9SKrishna Gudipati } 1406a36c61f9SKrishna Gudipati } 1407a36c61f9SKrishna Gudipati 1408a36c61f9SKrishna Gudipati /* 1409a36c61f9SKrishna Gudipati * RPRT : Register Port 1410a36c61f9SKrishna Gudipati */ 1411a36c61f9SKrishna Gudipati static void 1412a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1413a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1414a36c61f9SKrishna Gudipati { 1415a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1416a36c61f9SKrishna Gudipati 1417a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1418a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1419a36c61f9SKrishna Gudipati 1420a36c61f9SKrishna Gudipati switch (event) { 1421a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPRT_SENT: 1422a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt); 1423a36c61f9SKrishna Gudipati break; 1424a36c61f9SKrishna Gudipati 1425a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1426a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1427a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1428a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1429a36c61f9SKrishna Gudipati break; 1430a36c61f9SKrishna Gudipati 1431a36c61f9SKrishna Gudipati default: 1432a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1433a36c61f9SKrishna Gudipati } 1434a36c61f9SKrishna Gudipati } 1435a36c61f9SKrishna Gudipati 1436a36c61f9SKrishna Gudipati static void 1437a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1438a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1439a36c61f9SKrishna Gudipati { 1440a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1441a36c61f9SKrishna Gudipati 1442a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1443a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1444a36c61f9SKrishna Gudipati 1445a36c61f9SKrishna Gudipati switch (event) { 1446a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1447a36c61f9SKrishna Gudipati /* 1448a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1449a36c61f9SKrishna Gudipati * delayed retry 1450a36c61f9SKrishna Gudipati */ 1451a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1452a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1453a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry); 1454a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1455a36c61f9SKrishna Gudipati &fdmi->timer, 1456a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1457a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 14587725ccfdSJing Huang 14597725ccfdSJing Huang } else { 1460a36c61f9SKrishna Gudipati /* 1461a36c61f9SKrishna Gudipati * set state to offline 1462a36c61f9SKrishna Gudipati */ 1463a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1464a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 14657725ccfdSJing Huang } 1466a36c61f9SKrishna Gudipati break; 1467a36c61f9SKrishna Gudipati 1468a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1469a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1470a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1471a36c61f9SKrishna Gudipati break; 1472a36c61f9SKrishna Gudipati 1473a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1474a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1475a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1476a36c61f9SKrishna Gudipati break; 1477a36c61f9SKrishna Gudipati 1478a36c61f9SKrishna Gudipati default: 1479a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1480a36c61f9SKrishna Gudipati } 1481a36c61f9SKrishna Gudipati } 1482a36c61f9SKrishna Gudipati 1483a36c61f9SKrishna Gudipati static void 1484a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1485a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1486a36c61f9SKrishna Gudipati { 1487a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1488a36c61f9SKrishna Gudipati 1489a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1490a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1491a36c61f9SKrishna Gudipati 1492a36c61f9SKrishna Gudipati switch (event) { 1493a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1494a36c61f9SKrishna Gudipati /* 1495a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1496a36c61f9SKrishna Gudipati */ 1497a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt); 1498a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1499a36c61f9SKrishna Gudipati break; 1500a36c61f9SKrishna Gudipati 1501a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1502a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1503a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1504a36c61f9SKrishna Gudipati break; 1505a36c61f9SKrishna Gudipati 1506a36c61f9SKrishna Gudipati default: 1507a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1508a36c61f9SKrishna Gudipati } 1509a36c61f9SKrishna Gudipati } 1510a36c61f9SKrishna Gudipati 1511a36c61f9SKrishna Gudipati /* 1512a36c61f9SKrishna Gudipati * Register Port Attributes 1513a36c61f9SKrishna Gudipati */ 1514a36c61f9SKrishna Gudipati static void 1515a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1516a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1517a36c61f9SKrishna Gudipati { 1518a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1519a36c61f9SKrishna Gudipati 1520a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1521a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1522a36c61f9SKrishna Gudipati 1523a36c61f9SKrishna Gudipati switch (event) { 1524a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPA_SENT: 1525a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa); 1526a36c61f9SKrishna Gudipati break; 1527a36c61f9SKrishna Gudipati 1528a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1529a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1530a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1531a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1532a36c61f9SKrishna Gudipati break; 1533a36c61f9SKrishna Gudipati 1534a36c61f9SKrishna Gudipati default: 1535a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1536a36c61f9SKrishna Gudipati } 1537a36c61f9SKrishna Gudipati } 1538a36c61f9SKrishna Gudipati 1539a36c61f9SKrishna Gudipati static void 1540a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1541a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1542a36c61f9SKrishna Gudipati { 1543a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1544a36c61f9SKrishna Gudipati 1545a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1546a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1547a36c61f9SKrishna Gudipati 1548a36c61f9SKrishna Gudipati switch (event) { 1549a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1550a36c61f9SKrishna Gudipati /* 1551a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1552a36c61f9SKrishna Gudipati * delayed retry 1553a36c61f9SKrishna Gudipati */ 1554a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1555a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry); 1556a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1557a36c61f9SKrishna Gudipati &fdmi->timer, 1558a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1559a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1560a36c61f9SKrishna Gudipati } else { 1561a36c61f9SKrishna Gudipati /* 1562a36c61f9SKrishna Gudipati * set state to offline 1563a36c61f9SKrishna Gudipati */ 1564a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1565a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1566a36c61f9SKrishna Gudipati } 1567a36c61f9SKrishna Gudipati break; 1568a36c61f9SKrishna Gudipati 1569a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1570a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1571a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1572a36c61f9SKrishna Gudipati break; 1573a36c61f9SKrishna Gudipati 1574a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1575a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1576a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1577a36c61f9SKrishna Gudipati break; 1578a36c61f9SKrishna Gudipati 1579a36c61f9SKrishna Gudipati default: 1580a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1581a36c61f9SKrishna Gudipati } 1582a36c61f9SKrishna Gudipati } 1583a36c61f9SKrishna Gudipati 1584a36c61f9SKrishna Gudipati static void 1585a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1586a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1587a36c61f9SKrishna Gudipati { 1588a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1589a36c61f9SKrishna Gudipati 1590a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1591a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1592a36c61f9SKrishna Gudipati 1593a36c61f9SKrishna Gudipati switch (event) { 1594a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1595a36c61f9SKrishna Gudipati /* 1596a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1597a36c61f9SKrishna Gudipati */ 1598a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1599a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1600a36c61f9SKrishna Gudipati break; 1601a36c61f9SKrishna Gudipati 1602a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1603a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1604a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1605a36c61f9SKrishna Gudipati break; 1606a36c61f9SKrishna Gudipati 1607a36c61f9SKrishna Gudipati default: 1608a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1609a36c61f9SKrishna Gudipati } 1610a36c61f9SKrishna Gudipati } 1611a36c61f9SKrishna Gudipati 1612a36c61f9SKrishna Gudipati static void 1613a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1614a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1615a36c61f9SKrishna Gudipati { 1616a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1617a36c61f9SKrishna Gudipati 1618a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1619a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1620a36c61f9SKrishna Gudipati 1621a36c61f9SKrishna Gudipati switch (event) { 1622a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1623a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1624a36c61f9SKrishna Gudipati break; 1625a36c61f9SKrishna Gudipati 1626a36c61f9SKrishna Gudipati default: 1627a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1628a36c61f9SKrishna Gudipati } 1629a36c61f9SKrishna Gudipati } 16305fbe25c7SJing Huang /* 1631a36c61f9SKrishna Gudipati * FDMI is disabled state. 1632a36c61f9SKrishna Gudipati */ 1633a36c61f9SKrishna Gudipati static void 1634a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi, 1635a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1636a36c61f9SKrishna Gudipati { 1637a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1638a36c61f9SKrishna Gudipati 1639a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1640a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1641a36c61f9SKrishna Gudipati 1642a36c61f9SKrishna Gudipati /* No op State. It can only be enabled at Driver Init. */ 1643a36c61f9SKrishna Gudipati } 1644a36c61f9SKrishna Gudipati 16455fbe25c7SJing Huang /* 1646a36c61f9SKrishna Gudipati * RHBA : Register HBA Attributes. 1647a36c61f9SKrishna Gudipati */ 1648a36c61f9SKrishna Gudipati static void 1649a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1650a36c61f9SKrishna Gudipati { 1651a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1652a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1653a36c61f9SKrishna Gudipati struct fchs_s fchs; 1654a36c61f9SKrishna Gudipati int len, attr_len; 1655a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1656a36c61f9SKrishna Gudipati u8 *pyld; 1657a36c61f9SKrishna Gudipati 1658a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1659a36c61f9SKrishna Gudipati 1660a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1661a36c61f9SKrishna Gudipati if (!fcxp) { 1662a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1663a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba, fdmi); 1664a36c61f9SKrishna Gudipati return; 1665a36c61f9SKrishna Gudipati } 1666a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 1667a36c61f9SKrishna Gudipati 1668a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 16696a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 1670a36c61f9SKrishna Gudipati 1671a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1672a36c61f9SKrishna Gudipati FDMI_RHBA); 1673a36c61f9SKrishna Gudipati 1674a36c61f9SKrishna Gudipati attr_len = 1675a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi, 1676a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 1677a36c61f9SKrishna Gudipati + 1)); 1678a36c61f9SKrishna Gudipati 1679a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1680a36c61f9SKrishna Gudipati FC_CLASS_3, (len + attr_len), &fchs, 1681a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi, 1682a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 1683a36c61f9SKrishna Gudipati 1684a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); 1685a36c61f9SKrishna Gudipati } 1686a36c61f9SKrishna Gudipati 1687a36c61f9SKrishna Gudipati static u16 1688a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 1689a36c61f9SKrishna Gudipati { 1690a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1691a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s hba_attr; 1692a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; 1693a36c61f9SKrishna Gudipati struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; 1694a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 1695a36c61f9SKrishna Gudipati u8 *curr_ptr; 1696a36c61f9SKrishna Gudipati u16 len, count; 169750444a34SMaggie u16 templen; 1698a36c61f9SKrishna Gudipati 1699a36c61f9SKrishna Gudipati /* 1700a36c61f9SKrishna Gudipati * get hba attributes 1701a36c61f9SKrishna Gudipati */ 1702a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); 1703a36c61f9SKrishna Gudipati 1704a36c61f9SKrishna Gudipati rhba->hba_id = bfa_fcs_lport_get_pwwn(port); 1705ba816ea8SJing Huang rhba->port_list.num_ports = cpu_to_be32(1); 1706a36c61f9SKrishna Gudipati rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port); 1707a36c61f9SKrishna Gudipati 1708a36c61f9SKrishna Gudipati len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); 1709a36c61f9SKrishna Gudipati 1710a36c61f9SKrishna Gudipati count = 0; 1711a36c61f9SKrishna Gudipati len += sizeof(rhba->hba_attr_blk.attr_count); 1712a36c61f9SKrishna Gudipati 1713a36c61f9SKrishna Gudipati /* 1714a36c61f9SKrishna Gudipati * fill out the invididual entries of the HBA attrib Block 1715a36c61f9SKrishna Gudipati */ 1716a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; 1717a36c61f9SKrishna Gudipati 1718a36c61f9SKrishna Gudipati /* 1719a36c61f9SKrishna Gudipati * Node Name 1720a36c61f9SKrishna Gudipati */ 1721a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1722ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME); 172350444a34SMaggie templen = sizeof(wwn_t); 172450444a34SMaggie memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen); 172550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 172650444a34SMaggie len += templen; 1727a36c61f9SKrishna Gudipati count++; 172850444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 172950444a34SMaggie sizeof(templen)); 1730a36c61f9SKrishna Gudipati 1731a36c61f9SKrishna Gudipati /* 1732a36c61f9SKrishna Gudipati * Manufacturer 1733a36c61f9SKrishna Gudipati */ 1734a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1735ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER); 173650444a34SMaggie templen = (u16) strlen(fcs_hba_attr->manufacturer); 173750444a34SMaggie memcpy(attr->value, fcs_hba_attr->manufacturer, templen); 173850444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 173950444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 174050444a34SMaggie len += templen; 1741a36c61f9SKrishna Gudipati count++; 174250444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 174350444a34SMaggie sizeof(templen)); 1744a36c61f9SKrishna Gudipati 1745a36c61f9SKrishna Gudipati /* 1746a36c61f9SKrishna Gudipati * Serial Number 1747a36c61f9SKrishna Gudipati */ 1748a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1749ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM); 175050444a34SMaggie templen = (u16) strlen(fcs_hba_attr->serial_num); 175150444a34SMaggie memcpy(attr->value, fcs_hba_attr->serial_num, templen); 175250444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 175350444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 175450444a34SMaggie len += templen; 1755a36c61f9SKrishna Gudipati count++; 175650444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 175750444a34SMaggie sizeof(templen)); 1758a36c61f9SKrishna Gudipati 1759a36c61f9SKrishna Gudipati /* 1760a36c61f9SKrishna Gudipati * Model 1761a36c61f9SKrishna Gudipati */ 1762a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1763ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL); 176450444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model); 176550444a34SMaggie memcpy(attr->value, fcs_hba_attr->model, templen); 176650444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 176750444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 176850444a34SMaggie len += templen; 1769a36c61f9SKrishna Gudipati count++; 177050444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 177150444a34SMaggie sizeof(templen)); 1772a36c61f9SKrishna Gudipati 1773a36c61f9SKrishna Gudipati /* 1774a36c61f9SKrishna Gudipati * Model Desc 1775a36c61f9SKrishna Gudipati */ 1776a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1777ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC); 177850444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model_desc); 177950444a34SMaggie memcpy(attr->value, fcs_hba_attr->model_desc, templen); 178050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 178150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 178250444a34SMaggie len += templen; 1783a36c61f9SKrishna Gudipati count++; 178450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 178550444a34SMaggie sizeof(templen)); 1786a36c61f9SKrishna Gudipati 1787a36c61f9SKrishna Gudipati /* 1788a36c61f9SKrishna Gudipati * H/W Version 1789a36c61f9SKrishna Gudipati */ 1790a36c61f9SKrishna Gudipati if (fcs_hba_attr->hw_version[0] != '\0') { 1791a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1792ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION); 179350444a34SMaggie templen = (u16) strlen(fcs_hba_attr->hw_version); 179450444a34SMaggie memcpy(attr->value, fcs_hba_attr->hw_version, templen); 179550444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 179650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 179750444a34SMaggie len += templen; 1798a36c61f9SKrishna Gudipati count++; 179950444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 180050444a34SMaggie sizeof(templen)); 1801a36c61f9SKrishna Gudipati } 1802a36c61f9SKrishna Gudipati 1803a36c61f9SKrishna Gudipati /* 1804a36c61f9SKrishna Gudipati * Driver Version 1805a36c61f9SKrishna Gudipati */ 1806a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1807ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION); 180850444a34SMaggie templen = (u16) strlen(fcs_hba_attr->driver_version); 180950444a34SMaggie memcpy(attr->value, fcs_hba_attr->driver_version, templen); 181050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 181150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1812dd5aaf45SKrishna Gudipati len += templen; 1813a36c61f9SKrishna Gudipati count++; 181450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 181550444a34SMaggie sizeof(templen)); 1816a36c61f9SKrishna Gudipati 1817a36c61f9SKrishna Gudipati /* 1818a36c61f9SKrishna Gudipati * Option Rom Version 1819a36c61f9SKrishna Gudipati */ 1820a36c61f9SKrishna Gudipati if (fcs_hba_attr->option_rom_ver[0] != '\0') { 1821a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1822ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION); 182350444a34SMaggie templen = (u16) strlen(fcs_hba_attr->option_rom_ver); 182450444a34SMaggie memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen); 182550444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 182650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 182750444a34SMaggie len += templen; 1828a36c61f9SKrishna Gudipati count++; 182950444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 183050444a34SMaggie sizeof(templen)); 1831a36c61f9SKrishna Gudipati } 1832a36c61f9SKrishna Gudipati 1833a36c61f9SKrishna Gudipati /* 1834a36c61f9SKrishna Gudipati * f/w Version = driver version 1835a36c61f9SKrishna Gudipati */ 1836a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1837ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); 183850444a34SMaggie templen = (u16) strlen(fcs_hba_attr->driver_version); 183950444a34SMaggie memcpy(attr->value, fcs_hba_attr->driver_version, templen); 184050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 184150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 184250444a34SMaggie len += templen; 1843a36c61f9SKrishna Gudipati count++; 184450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 184550444a34SMaggie sizeof(templen)); 1846a36c61f9SKrishna Gudipati 1847a36c61f9SKrishna Gudipati /* 1848a36c61f9SKrishna Gudipati * OS Name 1849a36c61f9SKrishna Gudipati */ 1850a36c61f9SKrishna Gudipati if (fcs_hba_attr->os_name[0] != '\0') { 1851a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1852ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME); 185350444a34SMaggie templen = (u16) strlen(fcs_hba_attr->os_name); 185450444a34SMaggie memcpy(attr->value, fcs_hba_attr->os_name, templen); 185550444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 185650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 185750444a34SMaggie len += templen; 1858a36c61f9SKrishna Gudipati count++; 185950444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 186050444a34SMaggie sizeof(templen)); 1861a36c61f9SKrishna Gudipati } 1862a36c61f9SKrishna Gudipati 1863a36c61f9SKrishna Gudipati /* 1864a36c61f9SKrishna Gudipati * MAX_CT_PAYLOAD 1865a36c61f9SKrishna Gudipati */ 1866a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1867ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); 186850444a34SMaggie templen = sizeof(fcs_hba_attr->max_ct_pyld); 186950444a34SMaggie memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen); 187050444a34SMaggie len += templen; 1871a36c61f9SKrishna Gudipati count++; 187250444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 187350444a34SMaggie sizeof(templen)); 1874a36c61f9SKrishna Gudipati 1875a36c61f9SKrishna Gudipati /* 1876a36c61f9SKrishna Gudipati * Update size of payload 1877a36c61f9SKrishna Gudipati */ 18785fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 1879a36c61f9SKrishna Gudipati 1880ba816ea8SJing Huang rhba->hba_attr_blk.attr_count = cpu_to_be32(count); 1881a36c61f9SKrishna Gudipati return len; 1882a36c61f9SKrishna Gudipati } 1883a36c61f9SKrishna Gudipati 1884a36c61f9SKrishna Gudipati static void 1885a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 1886a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 1887a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 1888a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 1889a36c61f9SKrishna Gudipati { 1890a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 1891a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 1892a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1893a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 1894a36c61f9SKrishna Gudipati 1895a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1896a36c61f9SKrishna Gudipati 1897a36c61f9SKrishna Gudipati /* 1898a36c61f9SKrishna Gudipati * Sanity Checks 1899a36c61f9SKrishna Gudipati */ 1900a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 1901a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 1902a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1903a36c61f9SKrishna Gudipati return; 1904a36c61f9SKrishna Gudipati } 1905a36c61f9SKrishna Gudipati 1906a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1907ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1908a36c61f9SKrishna Gudipati 1909a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1910a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 1911a36c61f9SKrishna Gudipati return; 1912a36c61f9SKrishna Gudipati } 1913a36c61f9SKrishna Gudipati 1914a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 1915a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 1916a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1917a36c61f9SKrishna Gudipati } 1918a36c61f9SKrishna Gudipati 19195fbe25c7SJing Huang /* 1920a36c61f9SKrishna Gudipati * RPRT : Register Port 1921a36c61f9SKrishna Gudipati */ 1922a36c61f9SKrishna Gudipati static void 1923a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1924a36c61f9SKrishna Gudipati { 1925a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1926a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1927a36c61f9SKrishna Gudipati struct fchs_s fchs; 1928a36c61f9SKrishna Gudipati u16 len, attr_len; 1929a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1930a36c61f9SKrishna Gudipati u8 *pyld; 1931a36c61f9SKrishna Gudipati 1932a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1933a36c61f9SKrishna Gudipati 1934a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1935a36c61f9SKrishna Gudipati if (!fcxp) { 1936a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1937a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt, fdmi); 1938a36c61f9SKrishna Gudipati return; 1939a36c61f9SKrishna Gudipati } 1940a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 1941a36c61f9SKrishna Gudipati 1942a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 19436a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 1944a36c61f9SKrishna Gudipati 1945a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1946a36c61f9SKrishna Gudipati FDMI_RPRT); 1947a36c61f9SKrishna Gudipati 1948a36c61f9SKrishna Gudipati attr_len = 1949a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi, 1950a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 1951a36c61f9SKrishna Gudipati + 1)); 1952a36c61f9SKrishna Gudipati 1953a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1954a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 1955a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi, 1956a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 1957a36c61f9SKrishna Gudipati 1958a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); 1959a36c61f9SKrishna Gudipati } 1960a36c61f9SKrishna Gudipati 19615fbe25c7SJing Huang /* 1962a36c61f9SKrishna Gudipati * This routine builds Port Attribute Block that used in RPA, RPRT commands. 1963a36c61f9SKrishna Gudipati */ 1964a36c61f9SKrishna Gudipati static u16 1965a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi, 1966a36c61f9SKrishna Gudipati u8 *pyld) 1967a36c61f9SKrishna Gudipati { 1968a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 1969a36c61f9SKrishna Gudipati struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; 1970a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 1971a36c61f9SKrishna Gudipati u8 *curr_ptr; 1972a36c61f9SKrishna Gudipati u16 len; 1973a36c61f9SKrishna Gudipati u8 count = 0; 197450444a34SMaggie u16 templen; 1975a36c61f9SKrishna Gudipati 1976a36c61f9SKrishna Gudipati /* 1977a36c61f9SKrishna Gudipati * get port attributes 1978a36c61f9SKrishna Gudipati */ 1979a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 1980a36c61f9SKrishna Gudipati 1981a36c61f9SKrishna Gudipati len = sizeof(port_attrib->attr_count); 1982a36c61f9SKrishna Gudipati 1983a36c61f9SKrishna Gudipati /* 1984a36c61f9SKrishna Gudipati * fill out the invididual entries 1985a36c61f9SKrishna Gudipati */ 1986a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &port_attrib->port_attr; 1987a36c61f9SKrishna Gudipati 1988a36c61f9SKrishna Gudipati /* 1989a36c61f9SKrishna Gudipati * FC4 Types 1990a36c61f9SKrishna Gudipati */ 1991a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1992ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES); 199350444a34SMaggie templen = sizeof(fcs_port_attr.supp_fc4_types); 199450444a34SMaggie memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen); 199550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 199650444a34SMaggie len += templen; 1997a36c61f9SKrishna Gudipati ++count; 1998a36c61f9SKrishna Gudipati attr->len = 199950444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 200050444a34SMaggie sizeof(templen)); 2001a36c61f9SKrishna Gudipati 2002a36c61f9SKrishna Gudipati /* 2003a36c61f9SKrishna Gudipati * Supported Speed 2004a36c61f9SKrishna Gudipati */ 2005a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2006ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED); 200750444a34SMaggie templen = sizeof(fcs_port_attr.supp_speed); 200850444a34SMaggie memcpy(attr->value, &fcs_port_attr.supp_speed, templen); 200950444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 201050444a34SMaggie len += templen; 2011a36c61f9SKrishna Gudipati ++count; 2012a36c61f9SKrishna Gudipati attr->len = 201350444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 201450444a34SMaggie sizeof(templen)); 2015a36c61f9SKrishna Gudipati 2016a36c61f9SKrishna Gudipati /* 2017a36c61f9SKrishna Gudipati * current Port Speed 2018a36c61f9SKrishna Gudipati */ 2019a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2020ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED); 202150444a34SMaggie templen = sizeof(fcs_port_attr.curr_speed); 202250444a34SMaggie memcpy(attr->value, &fcs_port_attr.curr_speed, templen); 202350444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 202450444a34SMaggie len += templen; 2025a36c61f9SKrishna Gudipati ++count; 202650444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 202750444a34SMaggie sizeof(templen)); 2028a36c61f9SKrishna Gudipati 2029a36c61f9SKrishna Gudipati /* 2030a36c61f9SKrishna Gudipati * max frame size 2031a36c61f9SKrishna Gudipati */ 2032a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2033ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE); 203450444a34SMaggie templen = sizeof(fcs_port_attr.max_frm_size); 203550444a34SMaggie memcpy(attr->value, &fcs_port_attr.max_frm_size, templen); 203650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 203750444a34SMaggie len += templen; 2038a36c61f9SKrishna Gudipati ++count; 203950444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 204050444a34SMaggie sizeof(templen)); 2041a36c61f9SKrishna Gudipati 2042a36c61f9SKrishna Gudipati /* 2043a36c61f9SKrishna Gudipati * OS Device Name 2044a36c61f9SKrishna Gudipati */ 2045a36c61f9SKrishna Gudipati if (fcs_port_attr.os_device_name[0] != '\0') { 2046a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2047ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME); 204850444a34SMaggie templen = (u16) strlen(fcs_port_attr.os_device_name); 204950444a34SMaggie memcpy(attr->value, fcs_port_attr.os_device_name, templen); 205050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 205150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 205250444a34SMaggie len += templen; 2053a36c61f9SKrishna Gudipati ++count; 205450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 205550444a34SMaggie sizeof(templen)); 2056a36c61f9SKrishna Gudipati } 2057a36c61f9SKrishna Gudipati /* 2058a36c61f9SKrishna Gudipati * Host Name 2059a36c61f9SKrishna Gudipati */ 2060a36c61f9SKrishna Gudipati if (fcs_port_attr.host_name[0] != '\0') { 2061a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2062ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME); 206350444a34SMaggie templen = (u16) strlen(fcs_port_attr.host_name); 206450444a34SMaggie memcpy(attr->value, fcs_port_attr.host_name, templen); 206550444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 206650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 206750444a34SMaggie len += templen; 2068a36c61f9SKrishna Gudipati ++count; 206950444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 207050444a34SMaggie sizeof(templen)); 2071a36c61f9SKrishna Gudipati } 2072a36c61f9SKrishna Gudipati 2073a36c61f9SKrishna Gudipati /* 2074a36c61f9SKrishna Gudipati * Update size of payload 2075a36c61f9SKrishna Gudipati */ 2076ba816ea8SJing Huang port_attrib->attr_count = cpu_to_be32(count); 20775fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 2078a36c61f9SKrishna Gudipati return len; 2079a36c61f9SKrishna Gudipati } 2080a36c61f9SKrishna Gudipati 2081a36c61f9SKrishna Gudipati static u16 2082a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2083a36c61f9SKrishna Gudipati { 2084a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2085a36c61f9SKrishna Gudipati struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; 2086a36c61f9SKrishna Gudipati u16 len; 2087a36c61f9SKrishna Gudipati 2088a36c61f9SKrishna Gudipati rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs)); 2089a36c61f9SKrishna Gudipati rprt->port_name = bfa_fcs_lport_get_pwwn(port); 2090a36c61f9SKrishna Gudipati 2091a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2092a36c61f9SKrishna Gudipati (u8 *) &rprt->port_attr_blk); 2093a36c61f9SKrishna Gudipati 2094a36c61f9SKrishna Gudipati len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); 2095a36c61f9SKrishna Gudipati 2096a36c61f9SKrishna Gudipati return len; 2097a36c61f9SKrishna Gudipati } 2098a36c61f9SKrishna Gudipati 2099a36c61f9SKrishna Gudipati static void 2100a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2101a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2102a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2103a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2104a36c61f9SKrishna Gudipati { 2105a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2106a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2107a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2108a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2109a36c61f9SKrishna Gudipati 2110a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2111a36c61f9SKrishna Gudipati 2112a36c61f9SKrishna Gudipati /* 2113a36c61f9SKrishna Gudipati * Sanity Checks 2114a36c61f9SKrishna Gudipati */ 2115a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2116a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2117a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2118a36c61f9SKrishna Gudipati return; 2119a36c61f9SKrishna Gudipati } 2120a36c61f9SKrishna Gudipati 2121a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2122ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2123a36c61f9SKrishna Gudipati 2124a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2125a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2126a36c61f9SKrishna Gudipati return; 2127a36c61f9SKrishna Gudipati } 2128a36c61f9SKrishna Gudipati 2129a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2130a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2131a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2132a36c61f9SKrishna Gudipati } 2133a36c61f9SKrishna Gudipati 21345fbe25c7SJing Huang /* 2135a36c61f9SKrishna Gudipati * RPA : Register Port Attributes. 2136a36c61f9SKrishna Gudipati */ 2137a36c61f9SKrishna Gudipati static void 2138a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2139a36c61f9SKrishna Gudipati { 2140a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2141a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2142a36c61f9SKrishna Gudipati struct fchs_s fchs; 2143a36c61f9SKrishna Gudipati u16 len, attr_len; 2144a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2145a36c61f9SKrishna Gudipati u8 *pyld; 2146a36c61f9SKrishna Gudipati 2147a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2148a36c61f9SKrishna Gudipati 2149a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2150a36c61f9SKrishna Gudipati if (!fcxp) { 2151a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2152a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa, fdmi); 2153a36c61f9SKrishna Gudipati return; 2154a36c61f9SKrishna Gudipati } 2155a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2156a36c61f9SKrishna Gudipati 2157a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 21586a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2159a36c61f9SKrishna Gudipati 2160a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2161a36c61f9SKrishna Gudipati FDMI_RPA); 2162a36c61f9SKrishna Gudipati 21635fbe25c7SJing Huang attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi, 21645fbe25c7SJing Huang (u8 *) ((struct ct_hdr_s *) pyld + 1)); 2165a36c61f9SKrishna Gudipati 2166a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2167a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2168a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi, 2169a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2170a36c61f9SKrishna Gudipati 2171a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); 2172a36c61f9SKrishna Gudipati } 2173a36c61f9SKrishna Gudipati 2174a36c61f9SKrishna Gudipati static u16 2175a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2176a36c61f9SKrishna Gudipati { 2177a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2178a36c61f9SKrishna Gudipati struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; 2179a36c61f9SKrishna Gudipati u16 len; 2180a36c61f9SKrishna Gudipati 2181a36c61f9SKrishna Gudipati rpa->port_name = bfa_fcs_lport_get_pwwn(port); 2182a36c61f9SKrishna Gudipati 2183a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2184a36c61f9SKrishna Gudipati (u8 *) &rpa->port_attr_blk); 2185a36c61f9SKrishna Gudipati 2186a36c61f9SKrishna Gudipati len += sizeof(rpa->port_name); 2187a36c61f9SKrishna Gudipati 2188a36c61f9SKrishna Gudipati return len; 2189a36c61f9SKrishna Gudipati } 2190a36c61f9SKrishna Gudipati 2191a36c61f9SKrishna Gudipati static void 2192a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2193a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 2194a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 2195a36c61f9SKrishna Gudipati { 2196a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2197a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2198a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2199a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2200a36c61f9SKrishna Gudipati 2201a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2202a36c61f9SKrishna Gudipati 2203a36c61f9SKrishna Gudipati /* 2204a36c61f9SKrishna Gudipati * Sanity Checks 2205a36c61f9SKrishna Gudipati */ 2206a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2207a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2208a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2209a36c61f9SKrishna Gudipati return; 2210a36c61f9SKrishna Gudipati } 2211a36c61f9SKrishna Gudipati 2212a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2213ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2214a36c61f9SKrishna Gudipati 2215a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2216a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2217a36c61f9SKrishna Gudipati return; 2218a36c61f9SKrishna Gudipati } 2219a36c61f9SKrishna Gudipati 2220a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2221a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2222a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2223a36c61f9SKrishna Gudipati } 2224a36c61f9SKrishna Gudipati 2225a36c61f9SKrishna Gudipati static void 2226a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg) 2227a36c61f9SKrishna Gudipati { 2228a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg; 2229a36c61f9SKrishna Gudipati 2230a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); 2231a36c61f9SKrishna Gudipati } 2232a36c61f9SKrishna Gudipati 223352f94b6fSMaggie static void 2234a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2235a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr) 2236a36c61f9SKrishna Gudipati { 2237a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2238a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2239a36c61f9SKrishna Gudipati 22406a18b167SJing Huang memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 2241a36c61f9SKrishna Gudipati 2242a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, 2243a36c61f9SKrishna Gudipati hba_attr->manufacturer); 2244a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, 2245a36c61f9SKrishna Gudipati hba_attr->serial_num); 2246a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2247a36c61f9SKrishna Gudipati hba_attr->model); 2248a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2249a36c61f9SKrishna Gudipati hba_attr->model_desc); 2250a36c61f9SKrishna Gudipati bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, 2251a36c61f9SKrishna Gudipati hba_attr->hw_version); 2252a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, 2253a36c61f9SKrishna Gudipati hba_attr->option_rom_ver); 2254a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, 2255a36c61f9SKrishna Gudipati hba_attr->fw_version); 2256a36c61f9SKrishna Gudipati 2257a36c61f9SKrishna Gudipati strncpy(hba_attr->driver_version, (char *)driver_info->version, 2258a36c61f9SKrishna Gudipati sizeof(hba_attr->driver_version)); 2259a36c61f9SKrishna Gudipati 2260a36c61f9SKrishna Gudipati strncpy(hba_attr->os_name, driver_info->host_os_name, 2261a36c61f9SKrishna Gudipati sizeof(hba_attr->os_name)); 2262a36c61f9SKrishna Gudipati 2263a36c61f9SKrishna Gudipati /* 2264a36c61f9SKrishna Gudipati * If there is a patch level, append it 2265a36c61f9SKrishna Gudipati * to the os name along with a separator 2266a36c61f9SKrishna Gudipati */ 2267a36c61f9SKrishna Gudipati if (driver_info->host_os_patch[0] != '\0') { 2268a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 2269a36c61f9SKrishna Gudipati sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); 2270a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, driver_info->host_os_patch, 2271a36c61f9SKrishna Gudipati sizeof(driver_info->host_os_patch)); 2272a36c61f9SKrishna Gudipati } 2273a36c61f9SKrishna Gudipati 2274ba816ea8SJing Huang hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ); 2275a36c61f9SKrishna Gudipati } 2276a36c61f9SKrishna Gudipati 227752f94b6fSMaggie static void 2278a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2279a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr) 2280a36c61f9SKrishna Gudipati { 2281a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2282a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2283a36c61f9SKrishna Gudipati struct bfa_port_attr_s pport_attr; 2284a36c61f9SKrishna Gudipati 22856a18b167SJing Huang memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); 2286a36c61f9SKrishna Gudipati 2287a36c61f9SKrishna Gudipati /* 2288a36c61f9SKrishna Gudipati * get pport attributes from hal 2289a36c61f9SKrishna Gudipati */ 2290a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 2291a36c61f9SKrishna Gudipati 2292a36c61f9SKrishna Gudipati /* 2293a36c61f9SKrishna Gudipati * get FC4 type Bitmask 2294a36c61f9SKrishna Gudipati */ 2295a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); 2296a36c61f9SKrishna Gudipati 2297a36c61f9SKrishna Gudipati /* 2298a36c61f9SKrishna Gudipati * Supported Speeds 2299a36c61f9SKrishna Gudipati */ 2300d7be54ccSKrishna Gudipati switch (pport_attr.speed_supported) { 2301d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2302d7be54ccSKrishna Gudipati port_attr->supp_speed = 2303d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G); 2304d7be54ccSKrishna Gudipati break; 2305d7be54ccSKrishna Gudipati 2306d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2307d7be54ccSKrishna Gudipati port_attr->supp_speed = 2308d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G); 2309d7be54ccSKrishna Gudipati break; 2310d7be54ccSKrishna Gudipati 2311d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2312d7be54ccSKrishna Gudipati port_attr->supp_speed = 2313d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G); 2314d7be54ccSKrishna Gudipati break; 2315d7be54ccSKrishna Gudipati 2316d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2317d7be54ccSKrishna Gudipati port_attr->supp_speed = 2318d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G); 2319d7be54ccSKrishna Gudipati break; 2320d7be54ccSKrishna Gudipati 2321d7be54ccSKrishna Gudipati default: 2322d7be54ccSKrishna Gudipati bfa_sm_fault(port->fcs, pport_attr.speed_supported); 2323d7be54ccSKrishna Gudipati } 2324a36c61f9SKrishna Gudipati 2325a36c61f9SKrishna Gudipati /* 2326a36c61f9SKrishna Gudipati * Current Speed 2327a36c61f9SKrishna Gudipati */ 2328d7be54ccSKrishna Gudipati port_attr->curr_speed = cpu_to_be32( 2329d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(pport_attr.speed)); 2330a36c61f9SKrishna Gudipati 2331a36c61f9SKrishna Gudipati /* 2332a36c61f9SKrishna Gudipati * Max PDU Size. 2333a36c61f9SKrishna Gudipati */ 2334ba816ea8SJing Huang port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ); 2335a36c61f9SKrishna Gudipati 2336a36c61f9SKrishna Gudipati /* 2337a36c61f9SKrishna Gudipati * OS device Name 2338a36c61f9SKrishna Gudipati */ 2339a36c61f9SKrishna Gudipati strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, 2340a36c61f9SKrishna Gudipati sizeof(port_attr->os_device_name)); 2341a36c61f9SKrishna Gudipati 2342a36c61f9SKrishna Gudipati /* 2343a36c61f9SKrishna Gudipati * Host name 2344a36c61f9SKrishna Gudipati */ 2345a36c61f9SKrishna Gudipati strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, 2346a36c61f9SKrishna Gudipati sizeof(port_attr->host_name)); 23477725ccfdSJing Huang 23487725ccfdSJing Huang } 23497725ccfdSJing Huang 2350d7be54ccSKrishna Gudipati /* 2351d7be54ccSKrishna Gudipati * Convert BFA speed to FDMI format. 2352d7be54ccSKrishna Gudipati */ 2353d7be54ccSKrishna Gudipati u32 2354d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed) 2355d7be54ccSKrishna Gudipati { 2356d7be54ccSKrishna Gudipati u32 ret; 2357d7be54ccSKrishna Gudipati 2358d7be54ccSKrishna Gudipati switch (pport_speed) { 2359d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_1GBPS: 2360d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_2GBPS: 2361d7be54ccSKrishna Gudipati ret = pport_speed; 2362d7be54ccSKrishna Gudipati break; 2363d7be54ccSKrishna Gudipati 2364d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2365d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_4G; 2366d7be54ccSKrishna Gudipati break; 2367d7be54ccSKrishna Gudipati 2368d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2369d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_8G; 2370d7be54ccSKrishna Gudipati break; 2371d7be54ccSKrishna Gudipati 2372d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2373d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_10G; 2374d7be54ccSKrishna Gudipati break; 2375d7be54ccSKrishna Gudipati 2376d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2377d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_16G; 2378d7be54ccSKrishna Gudipati break; 2379d7be54ccSKrishna Gudipati 2380d7be54ccSKrishna Gudipati default: 2381d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_UNKNOWN; 2382d7be54ccSKrishna Gudipati } 2383d7be54ccSKrishna Gudipati return ret; 2384d7be54ccSKrishna Gudipati } 23857725ccfdSJing Huang 2386a36c61f9SKrishna Gudipati void 2387a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) 2388a36c61f9SKrishna Gudipati { 2389a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2390a36c61f9SKrishna Gudipati 2391a36c61f9SKrishna Gudipati fdmi->ms = ms; 2392a36c61f9SKrishna Gudipati if (ms->port->fcs->fdmi_enabled) 2393a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 2394a36c61f9SKrishna Gudipati else 2395a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled); 2396a36c61f9SKrishna Gudipati } 2397a36c61f9SKrishna Gudipati 2398a36c61f9SKrishna Gudipati void 2399a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms) 2400a36c61f9SKrishna Gudipati { 2401a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2402a36c61f9SKrishna Gudipati 2403a36c61f9SKrishna Gudipati fdmi->ms = ms; 2404a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); 2405a36c61f9SKrishna Gudipati } 2406a36c61f9SKrishna Gudipati 2407a36c61f9SKrishna Gudipati void 2408a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms) 2409a36c61f9SKrishna Gudipati { 2410a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2411a36c61f9SKrishna Gudipati 2412a36c61f9SKrishna Gudipati fdmi->ms = ms; 2413a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); 2414a36c61f9SKrishna Gudipati } 2415a36c61f9SKrishna Gudipati 2416a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES 2 2417a36c61f9SKrishna Gudipati 2418a36c61f9SKrishna Gudipati /* 2419a36c61f9SKrishna Gudipati * forward declarations 2420a36c61f9SKrishna Gudipati */ 2421a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, 2422a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2423a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_timeout(void *arg); 2424a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_plogi_response(void *fcsarg, 2425a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2426a36c61f9SKrishna Gudipati void *cbarg, 2427a36c61f9SKrishna Gudipati bfa_status_t req_status, 2428a36c61f9SKrishna Gudipati u32 rsp_len, 2429a36c61f9SKrishna Gudipati u32 resid_len, 2430a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2431a36c61f9SKrishna Gudipati 2432a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, 2433a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2434a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gmal_response(void *fcsarg, 2435a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2436a36c61f9SKrishna Gudipati void *cbarg, 2437a36c61f9SKrishna Gudipati bfa_status_t req_status, 2438a36c61f9SKrishna Gudipati u32 rsp_len, 2439a36c61f9SKrishna Gudipati u32 resid_len, 2440a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2441a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, 2442a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2443a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gfn_response(void *fcsarg, 2444a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2445a36c61f9SKrishna Gudipati void *cbarg, 2446a36c61f9SKrishna Gudipati bfa_status_t req_status, 2447a36c61f9SKrishna Gudipati u32 rsp_len, 2448a36c61f9SKrishna Gudipati u32 resid_len, 2449a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 24505fbe25c7SJing Huang /* 2451a36c61f9SKrishna Gudipati * fcs_ms_sm FCS MS state machine 2452a36c61f9SKrishna Gudipati */ 2453a36c61f9SKrishna Gudipati 24545fbe25c7SJing Huang /* 2455a36c61f9SKrishna Gudipati * MS State Machine events 2456a36c61f9SKrishna Gudipati */ 2457a36c61f9SKrishna Gudipati enum port_ms_event { 2458a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_ONLINE = 1, 2459a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_OFFLINE = 2, 2460a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_OK = 3, 2461a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_ERROR = 4, 2462a36c61f9SKrishna Gudipati MSSM_EVENT_TIMEOUT = 5, 2463a36c61f9SKrishna Gudipati MSSM_EVENT_FCXP_SENT = 6, 2464a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_FABRIC_RSCN = 7 2465a36c61f9SKrishna Gudipati }; 2466a36c61f9SKrishna Gudipati 2467a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2468a36c61f9SKrishna Gudipati enum port_ms_event event); 2469a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2470a36c61f9SKrishna Gudipati enum port_ms_event event); 2471a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2472a36c61f9SKrishna Gudipati enum port_ms_event event); 2473a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2474a36c61f9SKrishna Gudipati enum port_ms_event event); 2475a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2476a36c61f9SKrishna Gudipati enum port_ms_event event); 2477a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2478a36c61f9SKrishna Gudipati enum port_ms_event event); 2479a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2480a36c61f9SKrishna Gudipati enum port_ms_event event); 2481a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2482a36c61f9SKrishna Gudipati enum port_ms_event event); 2483a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2484a36c61f9SKrishna Gudipati enum port_ms_event event); 2485a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2486a36c61f9SKrishna Gudipati enum port_ms_event event); 2487a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2488a36c61f9SKrishna Gudipati enum port_ms_event event); 24895fbe25c7SJing Huang /* 2490a36c61f9SKrishna Gudipati * Start in offline state - awaiting NS to send start. 2491a36c61f9SKrishna Gudipati */ 2492a36c61f9SKrishna Gudipati static void 2493a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2494a36c61f9SKrishna Gudipati enum port_ms_event event) 2495a36c61f9SKrishna Gudipati { 2496a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2497a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2498a36c61f9SKrishna Gudipati 2499a36c61f9SKrishna Gudipati switch (event) { 2500a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_ONLINE: 2501a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2502a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2503a36c61f9SKrishna Gudipati break; 2504a36c61f9SKrishna Gudipati 2505a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2506a36c61f9SKrishna Gudipati break; 2507a36c61f9SKrishna Gudipati 2508a36c61f9SKrishna Gudipati default: 2509a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2510a36c61f9SKrishna Gudipati } 2511a36c61f9SKrishna Gudipati } 2512a36c61f9SKrishna Gudipati 2513a36c61f9SKrishna Gudipati static void 2514a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2515a36c61f9SKrishna Gudipati enum port_ms_event event) 2516a36c61f9SKrishna Gudipati { 2517a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2518a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2519a36c61f9SKrishna Gudipati 2520a36c61f9SKrishna Gudipati switch (event) { 2521a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2522a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi); 2523a36c61f9SKrishna Gudipati break; 2524a36c61f9SKrishna Gudipati 2525a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2526a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2527a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2528a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2529a36c61f9SKrishna Gudipati break; 2530a36c61f9SKrishna Gudipati 2531a36c61f9SKrishna Gudipati default: 2532a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2533a36c61f9SKrishna Gudipati } 2534a36c61f9SKrishna Gudipati } 2535a36c61f9SKrishna Gudipati 2536a36c61f9SKrishna Gudipati static void 2537a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2538a36c61f9SKrishna Gudipati enum port_ms_event event) 2539a36c61f9SKrishna Gudipati { 2540a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2541a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2542a36c61f9SKrishna Gudipati 2543a36c61f9SKrishna Gudipati switch (event) { 2544a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2545a36c61f9SKrishna Gudipati /* 2546a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2547a36c61f9SKrishna Gudipati */ 2548a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry); 2549a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2550a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2551a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2552a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2553a36c61f9SKrishna Gudipati break; 2554a36c61f9SKrishna Gudipati 2555a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2556a36c61f9SKrishna Gudipati /* 2557a36c61f9SKrishna Gudipati * since plogi is done, now invoke MS related sub-modules 2558a36c61f9SKrishna Gudipati */ 2559a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(ms); 2560a36c61f9SKrishna Gudipati 25615fbe25c7SJing Huang /* 2562a36c61f9SKrishna Gudipati * if this is a Vport, go to online state. 2563a36c61f9SKrishna Gudipati */ 2564a36c61f9SKrishna Gudipati if (ms->port->vport) { 2565a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2566a36c61f9SKrishna Gudipati break; 2567a36c61f9SKrishna Gudipati } 2568a36c61f9SKrishna Gudipati 2569a36c61f9SKrishna Gudipati /* 2570a36c61f9SKrishna Gudipati * For a base port we need to get the 2571a36c61f9SKrishna Gudipati * switch's IP address. 2572a36c61f9SKrishna Gudipati */ 2573a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2574a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2575a36c61f9SKrishna Gudipati break; 2576a36c61f9SKrishna Gudipati 2577a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2578a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2579a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2580a36c61f9SKrishna Gudipati break; 2581a36c61f9SKrishna Gudipati 2582a36c61f9SKrishna Gudipati default: 2583a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2584a36c61f9SKrishna Gudipati } 2585a36c61f9SKrishna Gudipati } 2586a36c61f9SKrishna Gudipati 2587a36c61f9SKrishna Gudipati static void 2588a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2589a36c61f9SKrishna Gudipati enum port_ms_event event) 2590a36c61f9SKrishna Gudipati { 2591a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2592a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2593a36c61f9SKrishna Gudipati 2594a36c61f9SKrishna Gudipati switch (event) { 2595a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2596a36c61f9SKrishna Gudipati /* 2597a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2598a36c61f9SKrishna Gudipati */ 2599a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2600a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2601a36c61f9SKrishna Gudipati break; 2602a36c61f9SKrishna Gudipati 2603a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2604a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2605a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2606a36c61f9SKrishna Gudipati break; 2607a36c61f9SKrishna Gudipati 2608a36c61f9SKrishna Gudipati default: 2609a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2610a36c61f9SKrishna Gudipati } 2611a36c61f9SKrishna Gudipati } 2612a36c61f9SKrishna Gudipati 2613a36c61f9SKrishna Gudipati static void 2614a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2615a36c61f9SKrishna Gudipati enum port_ms_event event) 2616a36c61f9SKrishna Gudipati { 2617a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2618a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2619a36c61f9SKrishna Gudipati 2620a36c61f9SKrishna Gudipati switch (event) { 2621a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2622a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2623a36c61f9SKrishna Gudipati break; 2624a36c61f9SKrishna Gudipati 2625a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_FABRIC_RSCN: 2626a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2627a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2628a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2629a36c61f9SKrishna Gudipati break; 2630a36c61f9SKrishna Gudipati 2631a36c61f9SKrishna Gudipati default: 2632a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2633a36c61f9SKrishna Gudipati } 2634a36c61f9SKrishna Gudipati } 2635a36c61f9SKrishna Gudipati 2636a36c61f9SKrishna Gudipati static void 2637a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2638a36c61f9SKrishna Gudipati enum port_ms_event event) 2639a36c61f9SKrishna Gudipati { 2640a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2641a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2642a36c61f9SKrishna Gudipati 2643a36c61f9SKrishna Gudipati switch (event) { 2644a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2645a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal); 2646a36c61f9SKrishna Gudipati break; 2647a36c61f9SKrishna Gudipati 2648a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2649a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2650a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2651a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2652a36c61f9SKrishna Gudipati break; 2653a36c61f9SKrishna Gudipati 2654a36c61f9SKrishna Gudipati default: 2655a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2656a36c61f9SKrishna Gudipati } 2657a36c61f9SKrishna Gudipati } 2658a36c61f9SKrishna Gudipati 2659a36c61f9SKrishna Gudipati static void 2660a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2661a36c61f9SKrishna Gudipati enum port_ms_event event) 2662a36c61f9SKrishna Gudipati { 2663a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2664a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2665a36c61f9SKrishna Gudipati 2666a36c61f9SKrishna Gudipati switch (event) { 2667a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2668a36c61f9SKrishna Gudipati /* 2669a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2670a36c61f9SKrishna Gudipati */ 2671a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2672a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry); 2673a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2674a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2675a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2676a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2677a36c61f9SKrishna Gudipati } else { 2678a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2679a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2680a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2681a36c61f9SKrishna Gudipati } 2682a36c61f9SKrishna Gudipati break; 2683a36c61f9SKrishna Gudipati 2684a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2685a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2686a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2687a36c61f9SKrishna Gudipati break; 2688a36c61f9SKrishna Gudipati 2689a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2690a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2691a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2692a36c61f9SKrishna Gudipati break; 2693a36c61f9SKrishna Gudipati 2694a36c61f9SKrishna Gudipati default: 2695a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2696a36c61f9SKrishna Gudipati } 2697a36c61f9SKrishna Gudipati } 2698a36c61f9SKrishna Gudipati 2699a36c61f9SKrishna Gudipati static void 2700a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2701a36c61f9SKrishna Gudipati enum port_ms_event event) 2702a36c61f9SKrishna Gudipati { 2703a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2704a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2705a36c61f9SKrishna Gudipati 2706a36c61f9SKrishna Gudipati switch (event) { 2707a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2708a36c61f9SKrishna Gudipati /* 2709a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2710a36c61f9SKrishna Gudipati */ 2711a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2712a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2713a36c61f9SKrishna Gudipati break; 2714a36c61f9SKrishna Gudipati 2715a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2716a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2717a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2718a36c61f9SKrishna Gudipati break; 2719a36c61f9SKrishna Gudipati 2720a36c61f9SKrishna Gudipati default: 2721a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2722a36c61f9SKrishna Gudipati } 2723a36c61f9SKrishna Gudipati } 27245fbe25c7SJing Huang /* 2725a36c61f9SKrishna Gudipati * ms_pvt MS local functions 2726a36c61f9SKrishna Gudipati */ 2727a36c61f9SKrishna Gudipati 2728a36c61f9SKrishna Gudipati static void 2729a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2730a36c61f9SKrishna Gudipati { 2731a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2732a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2733a36c61f9SKrishna Gudipati struct fchs_s fchs; 2734a36c61f9SKrishna Gudipati int len; 2735a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2736a36c61f9SKrishna Gudipati 2737a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 2738a36c61f9SKrishna Gudipati 2739a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2740a36c61f9SKrishna Gudipati if (!fcxp) { 2741a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2742a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal, ms); 2743a36c61f9SKrishna Gudipati return; 2744a36c61f9SKrishna Gudipati } 2745a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 2746a36c61f9SKrishna Gudipati 2747a36c61f9SKrishna Gudipati len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2748a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 2749f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 2750a36c61f9SKrishna Gudipati 2751a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2752a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 2753a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response, (void *)ms, 2754a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2755a36c61f9SKrishna Gudipati 2756a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2757a36c61f9SKrishna Gudipati } 2758a36c61f9SKrishna Gudipati 2759a36c61f9SKrishna Gudipati static void 2760a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2761a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2762a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2763a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2764a36c61f9SKrishna Gudipati { 2765a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2766a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2767a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2768a36c61f9SKrishna Gudipati struct fcgs_gmal_resp_s *gmal_resp; 2769a36c61f9SKrishna Gudipati struct fcgs_gmal_entry_s *gmal_entry; 2770a36c61f9SKrishna Gudipati u32 num_entries; 2771a36c61f9SKrishna Gudipati u8 *rsp_str; 2772a36c61f9SKrishna Gudipati 2773a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2774a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2775a36c61f9SKrishna Gudipati 2776a36c61f9SKrishna Gudipati /* 2777a36c61f9SKrishna Gudipati * Sanity Checks 2778a36c61f9SKrishna Gudipati */ 2779a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2780a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2781a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2782a36c61f9SKrishna Gudipati return; 2783a36c61f9SKrishna Gudipati } 2784a36c61f9SKrishna Gudipati 2785a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2786ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2787a36c61f9SKrishna Gudipati 2788a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2789a36c61f9SKrishna Gudipati gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); 2790a36c61f9SKrishna Gudipati 2791ba816ea8SJing Huang num_entries = be32_to_cpu(gmal_resp->ms_len); 2792a36c61f9SKrishna Gudipati if (num_entries == 0) { 2793a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2794a36c61f9SKrishna Gudipati return; 2795a36c61f9SKrishna Gudipati } 2796a36c61f9SKrishna Gudipati /* 2797a36c61f9SKrishna Gudipati * The response could contain multiple Entries. 2798a36c61f9SKrishna Gudipati * Entries for SNMP interface, etc. 2799a36c61f9SKrishna Gudipati * We look for the entry with a telnet prefix. 2800a36c61f9SKrishna Gudipati * First "http://" entry refers to IP addr 2801a36c61f9SKrishna Gudipati */ 2802a36c61f9SKrishna Gudipati 2803a36c61f9SKrishna Gudipati gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma; 2804a36c61f9SKrishna Gudipati while (num_entries > 0) { 2805a36c61f9SKrishna Gudipati if (strncmp(gmal_entry->prefix, 2806a36c61f9SKrishna Gudipati CT_GMAL_RESP_PREFIX_HTTP, 2807a36c61f9SKrishna Gudipati sizeof(gmal_entry->prefix)) == 0) { 2808a36c61f9SKrishna Gudipati 2809a36c61f9SKrishna Gudipati /* 2810a36c61f9SKrishna Gudipati * if the IP address is terminating with a '/', 2811a36c61f9SKrishna Gudipati * remove it. 2812a36c61f9SKrishna Gudipati * Byte 0 consists of the length of the string. 2813a36c61f9SKrishna Gudipati */ 2814a36c61f9SKrishna Gudipati rsp_str = &(gmal_entry->prefix[0]); 2815a36c61f9SKrishna Gudipati if (rsp_str[gmal_entry->len-1] == '/') 2816a36c61f9SKrishna Gudipati rsp_str[gmal_entry->len-1] = 0; 2817a36c61f9SKrishna Gudipati 2818a36c61f9SKrishna Gudipati /* copy IP Address to fabric */ 2819a36c61f9SKrishna Gudipati strncpy(bfa_fcs_lport_get_fabric_ipaddr(port), 2820a36c61f9SKrishna Gudipati gmal_entry->ip_addr, 2821a36c61f9SKrishna Gudipati BFA_FCS_FABRIC_IPADDR_SZ); 2822a36c61f9SKrishna Gudipati break; 2823a36c61f9SKrishna Gudipati } else { 2824a36c61f9SKrishna Gudipati --num_entries; 2825a36c61f9SKrishna Gudipati ++gmal_entry; 2826a36c61f9SKrishna Gudipati } 2827a36c61f9SKrishna Gudipati } 2828a36c61f9SKrishna Gudipati 2829a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2830a36c61f9SKrishna Gudipati return; 2831a36c61f9SKrishna Gudipati } 2832a36c61f9SKrishna Gudipati 2833a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2834a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2835a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2836a36c61f9SKrishna Gudipati } 2837a36c61f9SKrishna Gudipati 2838a36c61f9SKrishna Gudipati static void 2839a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2840a36c61f9SKrishna Gudipati enum port_ms_event event) 2841a36c61f9SKrishna Gudipati { 2842a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2843a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2844a36c61f9SKrishna Gudipati 2845a36c61f9SKrishna Gudipati switch (event) { 2846a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2847a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn); 2848a36c61f9SKrishna Gudipati break; 2849a36c61f9SKrishna Gudipati 2850a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2851a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2852a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2853a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2854a36c61f9SKrishna Gudipati break; 2855a36c61f9SKrishna Gudipati 2856a36c61f9SKrishna Gudipati default: 2857a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2858a36c61f9SKrishna Gudipati } 2859a36c61f9SKrishna Gudipati } 2860a36c61f9SKrishna Gudipati 2861a36c61f9SKrishna Gudipati static void 2862a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2863a36c61f9SKrishna Gudipati enum port_ms_event event) 2864a36c61f9SKrishna Gudipati { 2865a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2866a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2867a36c61f9SKrishna Gudipati 2868a36c61f9SKrishna Gudipati switch (event) { 2869a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2870a36c61f9SKrishna Gudipati /* 2871a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2872a36c61f9SKrishna Gudipati */ 2873a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2874a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry); 2875a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2876a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2877a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2878a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2879a36c61f9SKrishna Gudipati } else { 2880a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2881a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2882a36c61f9SKrishna Gudipati } 2883a36c61f9SKrishna Gudipati break; 2884a36c61f9SKrishna Gudipati 2885a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2886a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2887a36c61f9SKrishna Gudipati break; 2888a36c61f9SKrishna Gudipati 2889a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2890a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2891a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2892a36c61f9SKrishna Gudipati break; 2893a36c61f9SKrishna Gudipati 2894a36c61f9SKrishna Gudipati default: 2895a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2896a36c61f9SKrishna Gudipati } 2897a36c61f9SKrishna Gudipati } 2898a36c61f9SKrishna Gudipati 2899a36c61f9SKrishna Gudipati static void 2900a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2901a36c61f9SKrishna Gudipati enum port_ms_event event) 2902a36c61f9SKrishna Gudipati { 2903a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2904a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2905a36c61f9SKrishna Gudipati 2906a36c61f9SKrishna Gudipati switch (event) { 2907a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2908a36c61f9SKrishna Gudipati /* 2909a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2910a36c61f9SKrishna Gudipati */ 2911a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2912a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2913a36c61f9SKrishna Gudipati break; 2914a36c61f9SKrishna Gudipati 2915a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2916a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2917a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2918a36c61f9SKrishna Gudipati break; 2919a36c61f9SKrishna Gudipati 2920a36c61f9SKrishna Gudipati default: 2921a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2922a36c61f9SKrishna Gudipati } 2923a36c61f9SKrishna Gudipati } 29245fbe25c7SJing Huang /* 2925a36c61f9SKrishna Gudipati * ms_pvt MS local functions 2926a36c61f9SKrishna Gudipati */ 2927a36c61f9SKrishna Gudipati 2928a36c61f9SKrishna Gudipati static void 2929a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2930a36c61f9SKrishna Gudipati { 2931a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2932a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2933a36c61f9SKrishna Gudipati struct fchs_s fchs; 2934a36c61f9SKrishna Gudipati int len; 2935a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2936a36c61f9SKrishna Gudipati 2937a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 2938a36c61f9SKrishna Gudipati 2939a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2940a36c61f9SKrishna Gudipati if (!fcxp) { 2941a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2942a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn, ms); 2943a36c61f9SKrishna Gudipati return; 2944a36c61f9SKrishna Gudipati } 2945a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 2946a36c61f9SKrishna Gudipati 2947a36c61f9SKrishna Gudipati len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2948a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 2949f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 2950a36c61f9SKrishna Gudipati 2951a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2952a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 2953a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response, (void *)ms, 2954a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2955a36c61f9SKrishna Gudipati 2956a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2957a36c61f9SKrishna Gudipati } 2958a36c61f9SKrishna Gudipati 2959a36c61f9SKrishna Gudipati static void 2960a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2961a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 2962a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 2963a36c61f9SKrishna Gudipati { 2964a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2965a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2966a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2967a36c61f9SKrishna Gudipati wwn_t *gfn_resp; 2968a36c61f9SKrishna Gudipati 2969a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2970a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2971a36c61f9SKrishna Gudipati 2972a36c61f9SKrishna Gudipati /* 2973a36c61f9SKrishna Gudipati * Sanity Checks 2974a36c61f9SKrishna Gudipati */ 2975a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2976a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2977a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2978a36c61f9SKrishna Gudipati return; 2979a36c61f9SKrishna Gudipati } 2980a36c61f9SKrishna Gudipati 2981a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2982ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2983a36c61f9SKrishna Gudipati 2984a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2985a36c61f9SKrishna Gudipati gfn_resp = (wwn_t *)(cthdr + 1); 2986a36c61f9SKrishna Gudipati /* check if it has actually changed */ 2987a36c61f9SKrishna Gudipati if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port), 2988a36c61f9SKrishna Gudipati gfn_resp, sizeof(wwn_t)) != 0)) { 2989a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); 2990a36c61f9SKrishna Gudipati } 2991a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2992a36c61f9SKrishna Gudipati return; 2993a36c61f9SKrishna Gudipati } 2994a36c61f9SKrishna Gudipati 2995a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2996a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2997a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2998a36c61f9SKrishna Gudipati } 2999a36c61f9SKrishna Gudipati 30005fbe25c7SJing Huang /* 3001a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3002a36c61f9SKrishna Gudipati */ 3003a36c61f9SKrishna Gudipati 3004a36c61f9SKrishna Gudipati static void 3005a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3006a36c61f9SKrishna Gudipati { 3007a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3008a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3009a36c61f9SKrishna Gudipati struct fchs_s fchs; 3010a36c61f9SKrishna Gudipati int len; 3011a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3012a36c61f9SKrishna Gudipati 3013a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3014a36c61f9SKrishna Gudipati 3015a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3016a36c61f9SKrishna Gudipati if (!fcxp) { 3017a36c61f9SKrishna Gudipati port->stats.ms_plogi_alloc_wait++; 3018a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3019a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi, ms); 3020a36c61f9SKrishna Gudipati return; 3021a36c61f9SKrishna Gudipati } 3022a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3023a36c61f9SKrishna Gudipati 3024a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3025f16a1750SMaggie Zhang bfa_hton3b(FC_MGMT_SERVER), 3026a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3027a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 3028be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 3029be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3030a36c61f9SKrishna Gudipati 3031a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3032a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3033a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response, (void *)ms, 3034a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 3035a36c61f9SKrishna Gudipati 3036a36c61f9SKrishna Gudipati port->stats.ms_plogi_sent++; 3037a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3038a36c61f9SKrishna Gudipati } 3039a36c61f9SKrishna Gudipati 3040a36c61f9SKrishna Gudipati static void 3041a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3042a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3043a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) 3044a36c61f9SKrishna Gudipati { 3045a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3046a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3047a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 3048a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3049a36c61f9SKrishna Gudipati 3050a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3051a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3052a36c61f9SKrishna Gudipati 3053a36c61f9SKrishna Gudipati /* 3054a36c61f9SKrishna Gudipati * Sanity Checks 3055a36c61f9SKrishna Gudipati */ 3056a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3057a36c61f9SKrishna Gudipati port->stats.ms_plogi_rsp_err++; 3058a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3059a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3060a36c61f9SKrishna Gudipati return; 3061a36c61f9SKrishna Gudipati } 3062a36c61f9SKrishna Gudipati 3063a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3064a36c61f9SKrishna Gudipati 3065a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 3066a36c61f9SKrishna Gudipati 3067a36c61f9SKrishna Gudipati case FC_ELS_ACC: 3068a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 3069a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 3070a36c61f9SKrishna Gudipati port->stats.ms_plogi_acc_err++; 3071a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3072a36c61f9SKrishna Gudipati break; 3073a36c61f9SKrishna Gudipati } 3074a36c61f9SKrishna Gudipati port->stats.ms_plogi_accepts++; 3075a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3076a36c61f9SKrishna Gudipati break; 3077a36c61f9SKrishna Gudipati 3078a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 3079a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3080a36c61f9SKrishna Gudipati 3081a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 3082a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3083a36c61f9SKrishna Gudipati 3084a36c61f9SKrishna Gudipati port->stats.ms_rejects++; 3085a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3086a36c61f9SKrishna Gudipati break; 3087a36c61f9SKrishna Gudipati 3088a36c61f9SKrishna Gudipati default: 3089a36c61f9SKrishna Gudipati port->stats.ms_plogi_unknown_rsp++; 3090a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 3091a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3092a36c61f9SKrishna Gudipati } 3093a36c61f9SKrishna Gudipati } 3094a36c61f9SKrishna Gudipati 3095a36c61f9SKrishna Gudipati static void 3096a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg) 3097a36c61f9SKrishna Gudipati { 3098a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg; 3099a36c61f9SKrishna Gudipati 3100a36c61f9SKrishna Gudipati ms->port->stats.ms_timeouts++; 3101a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT); 3102a36c61f9SKrishna Gudipati } 3103a36c61f9SKrishna Gudipati 3104a36c61f9SKrishna Gudipati 3105a36c61f9SKrishna Gudipati void 3106a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port) 3107a36c61f9SKrishna Gudipati { 3108a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3109a36c61f9SKrishna Gudipati 3110a36c61f9SKrishna Gudipati ms->port = port; 3111a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3112a36c61f9SKrishna Gudipati 3113a36c61f9SKrishna Gudipati /* 3114a36c61f9SKrishna Gudipati * Invoke init routines of sub modules. 3115a36c61f9SKrishna Gudipati */ 3116a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(ms); 3117a36c61f9SKrishna Gudipati } 3118a36c61f9SKrishna Gudipati 3119a36c61f9SKrishna Gudipati void 3120a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port) 3121a36c61f9SKrishna Gudipati { 3122a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3123a36c61f9SKrishna Gudipati 3124a36c61f9SKrishna Gudipati ms->port = port; 3125a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); 3126a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(ms); 3127a36c61f9SKrishna Gudipati } 3128a36c61f9SKrishna Gudipati 3129a36c61f9SKrishna Gudipati void 3130a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port) 3131a36c61f9SKrishna Gudipati { 3132a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3133a36c61f9SKrishna Gudipati 3134a36c61f9SKrishna Gudipati ms->port = port; 3135a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE); 3136a36c61f9SKrishna Gudipati } 3137a36c61f9SKrishna Gudipati void 3138a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port) 3139a36c61f9SKrishna Gudipati { 3140a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3141a36c61f9SKrishna Gudipati 3142a36c61f9SKrishna Gudipati /* todo. Handle this only when in Online state */ 3143a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online)) 3144a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN); 3145a36c61f9SKrishna Gudipati } 3146a36c61f9SKrishna Gudipati 31475fbe25c7SJing Huang /* 3148a36c61f9SKrishna Gudipati * @page ns_sm_info VPORT NS State Machine 3149a36c61f9SKrishna Gudipati * 3150a36c61f9SKrishna Gudipati * @section ns_sm_interactions VPORT NS State Machine Interactions 3151a36c61f9SKrishna Gudipati * 3152a36c61f9SKrishna Gudipati * @section ns_sm VPORT NS State Machine 3153a36c61f9SKrishna Gudipati * img ns_sm.jpg 3154a36c61f9SKrishna Gudipati */ 3155a36c61f9SKrishna Gudipati 3156a36c61f9SKrishna Gudipati /* 3157a36c61f9SKrishna Gudipati * forward declarations 3158a36c61f9SKrishna Gudipati */ 3159a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, 3160a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3161a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, 3162a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3163a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, 3164a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3165a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, 3166a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3167a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, 3168a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3169a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_timeout(void *arg); 3170a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_plogi_response(void *fcsarg, 3171a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3172a36c61f9SKrishna Gudipati void *cbarg, 3173a36c61f9SKrishna Gudipati bfa_status_t req_status, 3174a36c61f9SKrishna Gudipati u32 rsp_len, 3175a36c61f9SKrishna Gudipati u32 resid_len, 3176a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3177a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, 3178a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3179a36c61f9SKrishna Gudipati void *cbarg, 3180a36c61f9SKrishna Gudipati bfa_status_t req_status, 3181a36c61f9SKrishna Gudipati u32 rsp_len, 3182a36c61f9SKrishna Gudipati u32 resid_len, 3183a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3184a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg, 3185a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3186a36c61f9SKrishna Gudipati void *cbarg, 3187a36c61f9SKrishna Gudipati bfa_status_t req_status, 3188a36c61f9SKrishna Gudipati u32 rsp_len, 3189a36c61f9SKrishna Gudipati u32 resid_len, 3190a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3191a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg, 3192a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3193a36c61f9SKrishna Gudipati void *cbarg, 3194a36c61f9SKrishna Gudipati bfa_status_t req_status, 3195a36c61f9SKrishna Gudipati u32 rsp_len, 3196a36c61f9SKrishna Gudipati u32 resid_len, 3197a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3198a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, 3199a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3200a36c61f9SKrishna Gudipati void *cbarg, 3201a36c61f9SKrishna Gudipati bfa_status_t req_status, 3202a36c61f9SKrishna Gudipati u32 rsp_len, 3203a36c61f9SKrishna Gudipati u32 resid_len, 3204a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3205a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_process_gidft_pids( 3206a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 3207a36c61f9SKrishna Gudipati u32 *pid_buf, u32 n_pids); 3208a36c61f9SKrishna Gudipati 3209a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port); 32105fbe25c7SJing Huang /* 3211a36c61f9SKrishna Gudipati * fcs_ns_sm FCS nameserver interface state machine 3212a36c61f9SKrishna Gudipati */ 3213a36c61f9SKrishna Gudipati 32145fbe25c7SJing Huang /* 3215a36c61f9SKrishna Gudipati * VPort NS State Machine events 3216a36c61f9SKrishna Gudipati */ 3217a36c61f9SKrishna Gudipati enum vport_ns_event { 3218a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_ONLINE = 1, 3219a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_OFFLINE = 2, 3220a36c61f9SKrishna Gudipati NSSM_EVENT_PLOGI_SENT = 3, 3221a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_OK = 4, 3222a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_ERROR = 5, 3223a36c61f9SKrishna Gudipati NSSM_EVENT_TIMEOUT = 6, 3224a36c61f9SKrishna Gudipati NSSM_EVENT_NS_QUERY = 7, 3225a36c61f9SKrishna Gudipati NSSM_EVENT_RSPNID_SENT = 8, 3226a36c61f9SKrishna Gudipati NSSM_EVENT_RFTID_SENT = 9, 3227a36c61f9SKrishna Gudipati NSSM_EVENT_RFFID_SENT = 10, 3228a36c61f9SKrishna Gudipati NSSM_EVENT_GIDFT_SENT = 11, 3229a36c61f9SKrishna Gudipati }; 3230a36c61f9SKrishna Gudipati 3231a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3232a36c61f9SKrishna Gudipati enum vport_ns_event event); 3233a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3234a36c61f9SKrishna Gudipati enum vport_ns_event event); 3235a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3236a36c61f9SKrishna Gudipati enum vport_ns_event event); 3237a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3238a36c61f9SKrishna Gudipati enum vport_ns_event event); 3239a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rspn_id( 3240a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3241a36c61f9SKrishna Gudipati enum vport_ns_event event); 3242a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3243a36c61f9SKrishna Gudipati enum vport_ns_event event); 3244a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3245a36c61f9SKrishna Gudipati enum vport_ns_event event); 3246a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rft_id( 3247a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3248a36c61f9SKrishna Gudipati enum vport_ns_event event); 3249a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3250a36c61f9SKrishna Gudipati enum vport_ns_event event); 3251a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3252a36c61f9SKrishna Gudipati enum vport_ns_event event); 3253a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rff_id( 3254a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3255a36c61f9SKrishna Gudipati enum vport_ns_event event); 3256a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3257a36c61f9SKrishna Gudipati enum vport_ns_event event); 3258a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3259a36c61f9SKrishna Gudipati enum vport_ns_event event); 3260a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_gid_ft( 3261a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3262a36c61f9SKrishna Gudipati enum vport_ns_event event); 3263a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3264a36c61f9SKrishna Gudipati enum vport_ns_event event); 3265a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3266a36c61f9SKrishna Gudipati enum vport_ns_event event); 3267a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3268a36c61f9SKrishna Gudipati enum vport_ns_event event); 32695fbe25c7SJing Huang /* 3270a36c61f9SKrishna Gudipati * Start in offline state - awaiting linkup 3271a36c61f9SKrishna Gudipati */ 3272a36c61f9SKrishna Gudipati static void 3273a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(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_PORT_ONLINE: 3281a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3282a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3283a36c61f9SKrishna Gudipati break; 3284a36c61f9SKrishna Gudipati 3285a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3286a36c61f9SKrishna Gudipati break; 3287a36c61f9SKrishna Gudipati 3288a36c61f9SKrishna Gudipati default: 3289a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3290a36c61f9SKrishna Gudipati } 3291a36c61f9SKrishna Gudipati } 3292a36c61f9SKrishna Gudipati 3293a36c61f9SKrishna Gudipati static void 3294a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3295a36c61f9SKrishna Gudipati enum vport_ns_event event) 3296a36c61f9SKrishna Gudipati { 3297a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3298a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3299a36c61f9SKrishna Gudipati 3300a36c61f9SKrishna Gudipati switch (event) { 3301a36c61f9SKrishna Gudipati case NSSM_EVENT_PLOGI_SENT: 3302a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi); 3303a36c61f9SKrishna Gudipati break; 3304a36c61f9SKrishna Gudipati 3305a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3306a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3307a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3308a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3309a36c61f9SKrishna Gudipati break; 3310a36c61f9SKrishna Gudipati 3311a36c61f9SKrishna Gudipati default: 3312a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3313a36c61f9SKrishna Gudipati } 3314a36c61f9SKrishna Gudipati } 3315a36c61f9SKrishna Gudipati 3316a36c61f9SKrishna Gudipati static void 3317a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3318a36c61f9SKrishna Gudipati enum vport_ns_event event) 3319a36c61f9SKrishna Gudipati { 3320a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3321a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3322a36c61f9SKrishna Gudipati 3323a36c61f9SKrishna Gudipati switch (event) { 3324a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3325a36c61f9SKrishna Gudipati /* 3326a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3327a36c61f9SKrishna Gudipati */ 3328a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry); 3329a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3330a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3331a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3332a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3333a36c61f9SKrishna Gudipati break; 3334a36c61f9SKrishna Gudipati 3335a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3336a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3337a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3338a36c61f9SKrishna Gudipati break; 3339a36c61f9SKrishna Gudipati 3340a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3341a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3342a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3343a36c61f9SKrishna Gudipati break; 3344a36c61f9SKrishna Gudipati 3345a36c61f9SKrishna Gudipati default: 3346a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3347a36c61f9SKrishna Gudipati } 3348a36c61f9SKrishna Gudipati } 3349a36c61f9SKrishna Gudipati 3350a36c61f9SKrishna Gudipati static void 3351a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3352a36c61f9SKrishna Gudipati enum vport_ns_event event) 3353a36c61f9SKrishna Gudipati { 3354a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3355a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3356a36c61f9SKrishna Gudipati 3357a36c61f9SKrishna Gudipati switch (event) { 3358a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3359a36c61f9SKrishna Gudipati /* 3360a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3361a36c61f9SKrishna Gudipati */ 3362a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3363a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3364a36c61f9SKrishna Gudipati break; 3365a36c61f9SKrishna Gudipati 3366a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3367a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3368a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3369a36c61f9SKrishna Gudipati break; 3370a36c61f9SKrishna Gudipati 3371a36c61f9SKrishna Gudipati default: 3372a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3373a36c61f9SKrishna Gudipati } 3374a36c61f9SKrishna Gudipati } 3375a36c61f9SKrishna Gudipati 3376a36c61f9SKrishna Gudipati static void 3377a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3378a36c61f9SKrishna Gudipati enum vport_ns_event event) 3379a36c61f9SKrishna Gudipati { 3380a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3381a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3382a36c61f9SKrishna Gudipati 3383a36c61f9SKrishna Gudipati switch (event) { 3384a36c61f9SKrishna Gudipati case NSSM_EVENT_RSPNID_SENT: 3385a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id); 3386a36c61f9SKrishna Gudipati break; 3387a36c61f9SKrishna Gudipati 3388a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3389a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3390a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3391a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3392a36c61f9SKrishna Gudipati break; 3393a36c61f9SKrishna Gudipati 3394a36c61f9SKrishna Gudipati default: 3395a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3396a36c61f9SKrishna Gudipati } 3397a36c61f9SKrishna Gudipati } 3398a36c61f9SKrishna Gudipati 3399a36c61f9SKrishna Gudipati static void 3400a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3401a36c61f9SKrishna Gudipati enum vport_ns_event event) 3402a36c61f9SKrishna Gudipati { 3403a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3404a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3405a36c61f9SKrishna Gudipati 3406a36c61f9SKrishna Gudipati switch (event) { 3407a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3408a36c61f9SKrishna Gudipati /* 3409a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3410a36c61f9SKrishna Gudipati */ 3411a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry); 3412a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3413a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3414a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3415a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3416a36c61f9SKrishna Gudipati break; 3417a36c61f9SKrishna Gudipati 3418a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3419a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3420a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3421a36c61f9SKrishna Gudipati break; 3422a36c61f9SKrishna Gudipati 3423a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3424a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3425a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3426a36c61f9SKrishna Gudipati break; 3427a36c61f9SKrishna Gudipati 3428a36c61f9SKrishna Gudipati default: 3429a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3430a36c61f9SKrishna Gudipati } 3431a36c61f9SKrishna Gudipati } 3432a36c61f9SKrishna Gudipati 3433a36c61f9SKrishna Gudipati static void 3434a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3435a36c61f9SKrishna Gudipati enum vport_ns_event event) 3436a36c61f9SKrishna Gudipati { 3437a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3438a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3439a36c61f9SKrishna Gudipati 3440a36c61f9SKrishna Gudipati switch (event) { 3441a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3442a36c61f9SKrishna Gudipati /* 3443a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3444a36c61f9SKrishna Gudipati */ 3445a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3446a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3447a36c61f9SKrishna Gudipati break; 3448a36c61f9SKrishna Gudipati 3449a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3450a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3451a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3452a36c61f9SKrishna Gudipati break; 3453a36c61f9SKrishna Gudipati 3454a36c61f9SKrishna Gudipati default: 3455a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3456a36c61f9SKrishna Gudipati } 3457a36c61f9SKrishna Gudipati } 3458a36c61f9SKrishna Gudipati 3459a36c61f9SKrishna Gudipati static void 3460a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns, 3461a36c61f9SKrishna Gudipati enum vport_ns_event event) 3462a36c61f9SKrishna Gudipati { 3463a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3464a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3465a36c61f9SKrishna Gudipati 3466a36c61f9SKrishna Gudipati switch (event) { 3467a36c61f9SKrishna Gudipati case NSSM_EVENT_RFTID_SENT: 3468a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id); 3469a36c61f9SKrishna Gudipati break; 3470a36c61f9SKrishna Gudipati 3471a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3472a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3473a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3474a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3475a36c61f9SKrishna Gudipati break; 3476a36c61f9SKrishna Gudipati 3477a36c61f9SKrishna Gudipati default: 3478a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3479a36c61f9SKrishna Gudipati } 3480a36c61f9SKrishna Gudipati } 3481a36c61f9SKrishna Gudipati 3482a36c61f9SKrishna Gudipati static void 3483a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3484a36c61f9SKrishna Gudipati enum vport_ns_event event) 3485a36c61f9SKrishna Gudipati { 3486a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3487a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3488a36c61f9SKrishna Gudipati 3489a36c61f9SKrishna Gudipati switch (event) { 3490a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3491a36c61f9SKrishna Gudipati /* Now move to register FC4 Features */ 3492a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3493a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3494a36c61f9SKrishna Gudipati break; 3495a36c61f9SKrishna Gudipati 3496a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3497a36c61f9SKrishna Gudipati /* 3498a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3499a36c61f9SKrishna Gudipati */ 3500a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry); 3501a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3502a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3503a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3504a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3505a36c61f9SKrishna Gudipati break; 3506a36c61f9SKrishna Gudipati 3507a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3508a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3509a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3510a36c61f9SKrishna Gudipati break; 3511a36c61f9SKrishna Gudipati 3512a36c61f9SKrishna Gudipati default: 3513a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3514a36c61f9SKrishna Gudipati } 3515a36c61f9SKrishna Gudipati } 3516a36c61f9SKrishna Gudipati 3517a36c61f9SKrishna Gudipati static void 3518a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3519a36c61f9SKrishna Gudipati enum vport_ns_event event) 3520a36c61f9SKrishna Gudipati { 3521a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3522a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3523a36c61f9SKrishna Gudipati 3524a36c61f9SKrishna Gudipati switch (event) { 3525a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3526a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3527a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3528a36c61f9SKrishna Gudipati break; 3529a36c61f9SKrishna Gudipati 3530a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3531a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3532a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3533a36c61f9SKrishna Gudipati break; 3534a36c61f9SKrishna Gudipati 3535a36c61f9SKrishna Gudipati default: 3536a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3537a36c61f9SKrishna Gudipati } 3538a36c61f9SKrishna Gudipati } 3539a36c61f9SKrishna Gudipati 3540a36c61f9SKrishna Gudipati static void 3541a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns, 3542a36c61f9SKrishna Gudipati enum vport_ns_event event) 3543a36c61f9SKrishna Gudipati { 3544a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3545a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3546a36c61f9SKrishna Gudipati 3547a36c61f9SKrishna Gudipati switch (event) { 3548a36c61f9SKrishna Gudipati case NSSM_EVENT_RFFID_SENT: 3549a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id); 3550a36c61f9SKrishna Gudipati break; 3551a36c61f9SKrishna Gudipati 3552a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3553a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3554a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3555a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3556a36c61f9SKrishna Gudipati break; 3557a36c61f9SKrishna Gudipati 3558a36c61f9SKrishna Gudipati default: 3559a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3560a36c61f9SKrishna Gudipati } 3561a36c61f9SKrishna Gudipati } 3562a36c61f9SKrishna Gudipati 3563a36c61f9SKrishna Gudipati static void 3564a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3565a36c61f9SKrishna Gudipati enum vport_ns_event event) 3566a36c61f9SKrishna Gudipati { 3567a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3568a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3569a36c61f9SKrishna Gudipati 3570a36c61f9SKrishna Gudipati switch (event) { 3571a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3572a36c61f9SKrishna Gudipati 3573a36c61f9SKrishna Gudipati /* 3574a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot initiate rport 3575a36c61f9SKrishna Gudipati * discovery with the fabric. Instead, we will retrieve the 3576a36c61f9SKrishna Gudipati * boot targets from HAL/FW. 3577a36c61f9SKrishna Gudipati */ 3578a36c61f9SKrishna Gudipati if (__fcs_min_cfg(ns->port->fcs)) { 3579a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(ns->port); 3580a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3581a36c61f9SKrishna Gudipati return; 3582a36c61f9SKrishna Gudipati } 3583a36c61f9SKrishna Gudipati 3584a36c61f9SKrishna Gudipati /* 3585a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 3586a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 3587a36c61f9SKrishna Gudipati */ 3588a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3589a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 3590a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 3591a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3592a36c61f9SKrishna Gudipati } 3593a36c61f9SKrishna Gudipati /* 3594a36c61f9SKrishna Gudipati * kick off mgmt srvr state machine 3595a36c61f9SKrishna Gudipati */ 3596a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(ns->port); 3597a36c61f9SKrishna Gudipati break; 3598a36c61f9SKrishna Gudipati 3599a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3600a36c61f9SKrishna Gudipati /* 3601a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3602a36c61f9SKrishna Gudipati */ 3603a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry); 3604a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3605a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3606a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3607a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3608a36c61f9SKrishna Gudipati break; 3609a36c61f9SKrishna Gudipati 3610a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3611a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3612a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3613a36c61f9SKrishna Gudipati break; 3614a36c61f9SKrishna Gudipati 3615a36c61f9SKrishna Gudipati default: 3616a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3617a36c61f9SKrishna Gudipati } 3618a36c61f9SKrishna Gudipati } 3619a36c61f9SKrishna Gudipati 3620a36c61f9SKrishna Gudipati static void 3621a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3622a36c61f9SKrishna Gudipati enum vport_ns_event event) 3623a36c61f9SKrishna Gudipati { 3624a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3625a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3626a36c61f9SKrishna Gudipati 3627a36c61f9SKrishna Gudipati switch (event) { 3628a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3629a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3630a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3631a36c61f9SKrishna Gudipati break; 3632a36c61f9SKrishna Gudipati 3633a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3634a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3635a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3636a36c61f9SKrishna Gudipati break; 3637a36c61f9SKrishna Gudipati 3638a36c61f9SKrishna Gudipati default: 3639a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3640a36c61f9SKrishna Gudipati } 3641a36c61f9SKrishna Gudipati } 3642a36c61f9SKrishna Gudipati static void 3643a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3644a36c61f9SKrishna Gudipati enum vport_ns_event event) 3645a36c61f9SKrishna Gudipati { 3646a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3647a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3648a36c61f9SKrishna Gudipati 3649a36c61f9SKrishna Gudipati switch (event) { 3650a36c61f9SKrishna Gudipati case NSSM_EVENT_GIDFT_SENT: 3651a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft); 3652a36c61f9SKrishna Gudipati break; 3653a36c61f9SKrishna Gudipati 3654a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3655a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3656a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3657a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3658a36c61f9SKrishna Gudipati break; 3659a36c61f9SKrishna Gudipati 3660a36c61f9SKrishna Gudipati default: 3661a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3662a36c61f9SKrishna Gudipati } 3663a36c61f9SKrishna Gudipati } 3664a36c61f9SKrishna Gudipati 3665a36c61f9SKrishna Gudipati static void 3666a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3667a36c61f9SKrishna Gudipati enum vport_ns_event event) 3668a36c61f9SKrishna Gudipati { 3669a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3670a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3671a36c61f9SKrishna Gudipati 3672a36c61f9SKrishna Gudipati switch (event) { 3673a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3674a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3675a36c61f9SKrishna Gudipati break; 3676a36c61f9SKrishna Gudipati 3677a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3678a36c61f9SKrishna Gudipati /* 3679a36c61f9SKrishna Gudipati * TBD: for certain reject codes, we don't need to retry 3680a36c61f9SKrishna Gudipati */ 3681a36c61f9SKrishna Gudipati /* 3682a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3683a36c61f9SKrishna Gudipati */ 3684a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry); 3685a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3686a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3687a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3688a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3689a36c61f9SKrishna Gudipati break; 3690a36c61f9SKrishna Gudipati 3691a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3692a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3693a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3694a36c61f9SKrishna Gudipati break; 3695a36c61f9SKrishna Gudipati 3696a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 3697a36c61f9SKrishna Gudipati break; 3698a36c61f9SKrishna Gudipati 3699a36c61f9SKrishna Gudipati default: 3700a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3701a36c61f9SKrishna Gudipati } 3702a36c61f9SKrishna Gudipati } 3703a36c61f9SKrishna Gudipati 3704a36c61f9SKrishna Gudipati static void 3705a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3706a36c61f9SKrishna Gudipati enum vport_ns_event event) 3707a36c61f9SKrishna Gudipati { 3708a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3709a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3710a36c61f9SKrishna Gudipati 3711a36c61f9SKrishna Gudipati switch (event) { 3712a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3713a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft); 3714a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3715a36c61f9SKrishna Gudipati break; 3716a36c61f9SKrishna Gudipati 3717a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3718a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3719a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3720a36c61f9SKrishna Gudipati break; 3721a36c61f9SKrishna Gudipati 3722a36c61f9SKrishna Gudipati default: 3723a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3724a36c61f9SKrishna Gudipati } 3725a36c61f9SKrishna Gudipati } 3726a36c61f9SKrishna Gudipati 3727a36c61f9SKrishna Gudipati static void 3728a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3729a36c61f9SKrishna Gudipati enum vport_ns_event event) 3730a36c61f9SKrishna Gudipati { 3731a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3732a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3733a36c61f9SKrishna Gudipati 3734a36c61f9SKrishna Gudipati switch (event) { 3735a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3736a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3737a36c61f9SKrishna Gudipati break; 3738a36c61f9SKrishna Gudipati 3739a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 3740a36c61f9SKrishna Gudipati /* 3741a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 3742a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 3743a36c61f9SKrishna Gudipati */ 3744a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3745a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 3746a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 3747a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3748a36c61f9SKrishna Gudipati }; 3749a36c61f9SKrishna Gudipati break; 3750a36c61f9SKrishna Gudipati 3751a36c61f9SKrishna Gudipati default: 3752a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3753a36c61f9SKrishna Gudipati } 3754a36c61f9SKrishna Gudipati } 3755a36c61f9SKrishna Gudipati 3756a36c61f9SKrishna Gudipati 3757a36c61f9SKrishna Gudipati 37585fbe25c7SJing Huang /* 3759a36c61f9SKrishna Gudipati * ns_pvt Nameserver local functions 3760a36c61f9SKrishna Gudipati */ 3761a36c61f9SKrishna Gudipati 3762a36c61f9SKrishna Gudipati static void 3763a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3764a36c61f9SKrishna Gudipati { 3765a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3766a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3767a36c61f9SKrishna Gudipati struct fchs_s fchs; 3768a36c61f9SKrishna Gudipati int len; 3769a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3770a36c61f9SKrishna Gudipati 3771a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3772a36c61f9SKrishna Gudipati 3773a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3774a36c61f9SKrishna Gudipati if (!fcxp) { 3775a36c61f9SKrishna Gudipati port->stats.ns_plogi_alloc_wait++; 3776a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3777a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi, ns); 3778a36c61f9SKrishna Gudipati return; 3779a36c61f9SKrishna Gudipati } 3780a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3781a36c61f9SKrishna Gudipati 3782a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3783f16a1750SMaggie Zhang bfa_hton3b(FC_NAME_SERVER), 3784a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3785a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 3786be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 3787be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3788a36c61f9SKrishna Gudipati 3789a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3790a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3791a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response, (void *)ns, 3792a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 3793a36c61f9SKrishna Gudipati port->stats.ns_plogi_sent++; 3794a36c61f9SKrishna Gudipati 3795a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); 3796a36c61f9SKrishna Gudipati } 3797a36c61f9SKrishna Gudipati 3798a36c61f9SKrishna Gudipati static void 3799a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3800a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 3801a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 3802a36c61f9SKrishna Gudipati { 3803a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3804a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3805a36c61f9SKrishna Gudipati /* struct fc_logi_s *plogi_resp; */ 3806a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 3807a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3808a36c61f9SKrishna Gudipati 3809a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3810a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3811a36c61f9SKrishna Gudipati 3812a36c61f9SKrishna Gudipati /* 3813a36c61f9SKrishna Gudipati * Sanity Checks 3814a36c61f9SKrishna Gudipati */ 3815a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3816a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3817a36c61f9SKrishna Gudipati port->stats.ns_plogi_rsp_err++; 3818a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3819a36c61f9SKrishna Gudipati return; 3820a36c61f9SKrishna Gudipati } 3821a36c61f9SKrishna Gudipati 3822a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3823a36c61f9SKrishna Gudipati 3824a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 3825a36c61f9SKrishna Gudipati 3826a36c61f9SKrishna Gudipati case FC_ELS_ACC: 3827a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 3828a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 3829a36c61f9SKrishna Gudipati port->stats.ns_plogi_acc_err++; 3830a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3831a36c61f9SKrishna Gudipati break; 3832a36c61f9SKrishna Gudipati } 3833a36c61f9SKrishna Gudipati port->stats.ns_plogi_accepts++; 3834a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3835a36c61f9SKrishna Gudipati break; 3836a36c61f9SKrishna Gudipati 3837a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 3838a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3839a36c61f9SKrishna Gudipati 3840a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 3841a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3842a36c61f9SKrishna Gudipati 3843a36c61f9SKrishna Gudipati port->stats.ns_rejects++; 3844a36c61f9SKrishna Gudipati 3845a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3846a36c61f9SKrishna Gudipati break; 3847a36c61f9SKrishna Gudipati 3848a36c61f9SKrishna Gudipati default: 3849a36c61f9SKrishna Gudipati port->stats.ns_plogi_unknown_rsp++; 3850a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 3851a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3852a36c61f9SKrishna Gudipati } 3853a36c61f9SKrishna Gudipati } 3854a36c61f9SKrishna Gudipati 38555fbe25c7SJing Huang /* 3856a36c61f9SKrishna Gudipati * Register the symbolic port name. 3857a36c61f9SKrishna Gudipati */ 3858a36c61f9SKrishna Gudipati static void 3859a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3860a36c61f9SKrishna Gudipati { 3861a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3862a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3863a36c61f9SKrishna Gudipati struct fchs_s fchs; 3864a36c61f9SKrishna Gudipati int len; 3865a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3866a36c61f9SKrishna Gudipati u8 symbl[256]; 3867a36c61f9SKrishna Gudipati u8 *psymbl = &symbl[0]; 3868a36c61f9SKrishna Gudipati 38696a18b167SJing Huang memset(symbl, 0, sizeof(symbl)); 3870a36c61f9SKrishna Gudipati 3871a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3872a36c61f9SKrishna Gudipati 3873a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3874a36c61f9SKrishna Gudipati if (!fcxp) { 3875a36c61f9SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 3876a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3877a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id, ns); 3878a36c61f9SKrishna Gudipati return; 3879a36c61f9SKrishna Gudipati } 3880a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3881a36c61f9SKrishna Gudipati 3882a36c61f9SKrishna Gudipati /* 3883a36c61f9SKrishna Gudipati * for V-Port, form a Port Symbolic Name 3884a36c61f9SKrishna Gudipati */ 3885a36c61f9SKrishna Gudipati if (port->vport) { 38865fbe25c7SJing Huang /* 3887a36c61f9SKrishna Gudipati * For Vports, we append the vport's port symbolic name 3888a36c61f9SKrishna Gudipati * to that of the base port. 3889a36c61f9SKrishna Gudipati */ 3890a36c61f9SKrishna Gudipati 3891a36c61f9SKrishna Gudipati strncpy((char *)psymbl, 3892a36c61f9SKrishna Gudipati (char *) & 3893a36c61f9SKrishna Gudipati (bfa_fcs_lport_get_psym_name 3894a36c61f9SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 3895a36c61f9SKrishna Gudipati strlen((char *) & 3896a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3897a36c61f9SKrishna Gudipati (port->fcs)))); 3898a36c61f9SKrishna Gudipati 3899a36c61f9SKrishna Gudipati /* Ensure we have a null terminating string. */ 3900a36c61f9SKrishna Gudipati ((char *)psymbl)[strlen((char *) & 3901a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3902a36c61f9SKrishna Gudipati (port->fcs)))] = 0; 3903a36c61f9SKrishna Gudipati strncat((char *)psymbl, 3904a36c61f9SKrishna Gudipati (char *) &(bfa_fcs_lport_get_psym_name(port)), 3905a36c61f9SKrishna Gudipati strlen((char *) &bfa_fcs_lport_get_psym_name(port))); 3906a36c61f9SKrishna Gudipati } else { 3907a36c61f9SKrishna Gudipati psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); 3908a36c61f9SKrishna Gudipati } 3909a36c61f9SKrishna Gudipati 3910a36c61f9SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3911a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, psymbl); 3912a36c61f9SKrishna Gudipati 3913a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3914a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3915a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response, (void *)ns, 3916a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3917a36c61f9SKrishna Gudipati 3918a36c61f9SKrishna Gudipati port->stats.ns_rspnid_sent++; 3919a36c61f9SKrishna Gudipati 3920a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); 3921a36c61f9SKrishna Gudipati } 3922a36c61f9SKrishna Gudipati 3923a36c61f9SKrishna Gudipati static void 3924a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3925a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3926a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3927a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 3928a36c61f9SKrishna Gudipati { 3929a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3930a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3931a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3932a36c61f9SKrishna Gudipati 3933a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3934a36c61f9SKrishna Gudipati 3935a36c61f9SKrishna Gudipati /* 3936a36c61f9SKrishna Gudipati * Sanity Checks 3937a36c61f9SKrishna Gudipati */ 3938a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3939a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3940a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rsp_err++; 3941a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3942a36c61f9SKrishna Gudipati return; 3943a36c61f9SKrishna Gudipati } 3944a36c61f9SKrishna Gudipati 3945a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3946ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3947a36c61f9SKrishna Gudipati 3948a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3949a36c61f9SKrishna Gudipati port->stats.ns_rspnid_accepts++; 3950a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3951a36c61f9SKrishna Gudipati return; 3952a36c61f9SKrishna Gudipati } 3953a36c61f9SKrishna Gudipati 3954a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rejects++; 3955a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3956a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3957a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3958a36c61f9SKrishna Gudipati } 3959a36c61f9SKrishna Gudipati 39605fbe25c7SJing Huang /* 3961a36c61f9SKrishna Gudipati * Register FC4-Types 3962a36c61f9SKrishna Gudipati */ 3963a36c61f9SKrishna Gudipati static void 3964a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3965a36c61f9SKrishna Gudipati { 3966a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3967a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3968a36c61f9SKrishna Gudipati struct fchs_s fchs; 3969a36c61f9SKrishna Gudipati int len; 3970a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3971a36c61f9SKrishna Gudipati 3972a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3973a36c61f9SKrishna Gudipati 3974a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3975a36c61f9SKrishna Gudipati if (!fcxp) { 3976a36c61f9SKrishna Gudipati port->stats.ns_rftid_alloc_wait++; 3977a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3978a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id, ns); 3979a36c61f9SKrishna Gudipati return; 3980a36c61f9SKrishna Gudipati } 3981a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3982a36c61f9SKrishna Gudipati 3983a36c61f9SKrishna Gudipati len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3984a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles); 3985a36c61f9SKrishna Gudipati 3986a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3987a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3988a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response, (void *)ns, 3989a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3990a36c61f9SKrishna Gudipati 3991a36c61f9SKrishna Gudipati port->stats.ns_rftid_sent++; 3992a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); 3993a36c61f9SKrishna Gudipati } 3994a36c61f9SKrishna Gudipati 3995a36c61f9SKrishna Gudipati static void 3996a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3997a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3998a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3999a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4000a36c61f9SKrishna Gudipati { 4001a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4002a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4003a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4004a36c61f9SKrishna Gudipati 4005a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4006a36c61f9SKrishna Gudipati 4007a36c61f9SKrishna Gudipati /* 4008a36c61f9SKrishna Gudipati * Sanity Checks 4009a36c61f9SKrishna Gudipati */ 4010a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4011a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4012a36c61f9SKrishna Gudipati port->stats.ns_rftid_rsp_err++; 4013a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4014a36c61f9SKrishna Gudipati return; 4015a36c61f9SKrishna Gudipati } 4016a36c61f9SKrishna Gudipati 4017a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4018ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4019a36c61f9SKrishna Gudipati 4020a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4021a36c61f9SKrishna Gudipati port->stats.ns_rftid_accepts++; 4022a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4023a36c61f9SKrishna Gudipati return; 4024a36c61f9SKrishna Gudipati } 4025a36c61f9SKrishna Gudipati 4026a36c61f9SKrishna Gudipati port->stats.ns_rftid_rejects++; 4027a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4028a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4029a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4030a36c61f9SKrishna Gudipati } 4031a36c61f9SKrishna Gudipati 40325fbe25c7SJing Huang /* 4033a36c61f9SKrishna Gudipati * Register FC4-Features : Should be done after RFT_ID 4034a36c61f9SKrishna Gudipati */ 4035a36c61f9SKrishna Gudipati static void 4036a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4037a36c61f9SKrishna Gudipati { 4038a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4039a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4040a36c61f9SKrishna Gudipati struct fchs_s fchs; 4041a36c61f9SKrishna Gudipati int len; 4042a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4043a36c61f9SKrishna Gudipati u8 fc4_ftrs = 0; 4044a36c61f9SKrishna Gudipati 4045a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4046a36c61f9SKrishna Gudipati 4047a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4048a36c61f9SKrishna Gudipati if (!fcxp) { 4049a36c61f9SKrishna Gudipati port->stats.ns_rffid_alloc_wait++; 4050a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4051a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id, ns); 4052a36c61f9SKrishna Gudipati return; 4053a36c61f9SKrishna Gudipati } 4054a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4055a36c61f9SKrishna Gudipati 4056a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) 4057a36c61f9SKrishna Gudipati fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; 4058a36c61f9SKrishna Gudipati 4059a36c61f9SKrishna Gudipati len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4060a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 4061a36c61f9SKrishna Gudipati FC_TYPE_FCP, fc4_ftrs); 4062a36c61f9SKrishna Gudipati 4063a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4064a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4065a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response, (void *)ns, 4066a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4067a36c61f9SKrishna Gudipati 4068a36c61f9SKrishna Gudipati port->stats.ns_rffid_sent++; 4069a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); 4070a36c61f9SKrishna Gudipati } 4071a36c61f9SKrishna Gudipati 4072a36c61f9SKrishna Gudipati static void 4073a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4074a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4075a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4076a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4077a36c61f9SKrishna Gudipati { 4078a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4079a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4080a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4081a36c61f9SKrishna Gudipati 4082a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4083a36c61f9SKrishna Gudipati 4084a36c61f9SKrishna Gudipati /* 4085a36c61f9SKrishna Gudipati * Sanity Checks 4086a36c61f9SKrishna Gudipati */ 4087a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4088a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4089a36c61f9SKrishna Gudipati port->stats.ns_rffid_rsp_err++; 4090a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4091a36c61f9SKrishna Gudipati return; 4092a36c61f9SKrishna Gudipati } 4093a36c61f9SKrishna Gudipati 4094a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4095ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4096a36c61f9SKrishna Gudipati 4097a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4098a36c61f9SKrishna Gudipati port->stats.ns_rffid_accepts++; 4099a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4100a36c61f9SKrishna Gudipati return; 4101a36c61f9SKrishna Gudipati } 4102a36c61f9SKrishna Gudipati 4103a36c61f9SKrishna Gudipati port->stats.ns_rffid_rejects++; 4104a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4105a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4106a36c61f9SKrishna Gudipati 4107a36c61f9SKrishna Gudipati if (cthdr->reason_code == CT_RSN_NOT_SUPP) { 4108a36c61f9SKrishna Gudipati /* if this command is not supported, we don't retry */ 4109a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4110a36c61f9SKrishna Gudipati } else 4111a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4112a36c61f9SKrishna Gudipati } 41135fbe25c7SJing Huang /* 4114a36c61f9SKrishna Gudipati * Query Fabric for FC4-Types Devices. 4115a36c61f9SKrishna Gudipati * 4116a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response 4117a36c61f9SKrishna Gudipati * can be larger than 2K. 4118a36c61f9SKrishna Gudipati */ 4119a36c61f9SKrishna Gudipati static void 4120a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4121a36c61f9SKrishna Gudipati { 4122a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4123a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4124a36c61f9SKrishna Gudipati struct fchs_s fchs; 4125a36c61f9SKrishna Gudipati int len; 4126a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4127a36c61f9SKrishna Gudipati 4128a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4129a36c61f9SKrishna Gudipati 4130a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4131a36c61f9SKrishna Gudipati if (!fcxp) { 4132a36c61f9SKrishna Gudipati port->stats.ns_gidft_alloc_wait++; 4133a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4134a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft, ns); 4135a36c61f9SKrishna Gudipati return; 4136a36c61f9SKrishna Gudipati } 4137a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4138a36c61f9SKrishna Gudipati 4139a36c61f9SKrishna Gudipati /* 4140a36c61f9SKrishna Gudipati * This query is only initiated for FCP initiator mode. 4141a36c61f9SKrishna Gudipati */ 4142a36c61f9SKrishna Gudipati len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4143a36c61f9SKrishna Gudipati ns->port->pid, FC_TYPE_FCP); 4144a36c61f9SKrishna Gudipati 4145a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4146a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4147a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response, (void *)ns, 4148a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV); 4149a36c61f9SKrishna Gudipati 4150a36c61f9SKrishna Gudipati port->stats.ns_gidft_sent++; 4151a36c61f9SKrishna Gudipati 4152a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); 4153a36c61f9SKrishna Gudipati } 4154a36c61f9SKrishna Gudipati 4155a36c61f9SKrishna Gudipati static void 4156a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4157a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4158a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4159a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4160a36c61f9SKrishna Gudipati { 4161a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4162a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4163a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4164a36c61f9SKrishna Gudipati u32 n_pids; 4165a36c61f9SKrishna Gudipati 4166a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4167a36c61f9SKrishna Gudipati 4168a36c61f9SKrishna Gudipati /* 4169a36c61f9SKrishna Gudipati * Sanity Checks 4170a36c61f9SKrishna Gudipati */ 4171a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4172a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4173a36c61f9SKrishna Gudipati port->stats.ns_gidft_rsp_err++; 4174a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4175a36c61f9SKrishna Gudipati return; 4176a36c61f9SKrishna Gudipati } 4177a36c61f9SKrishna Gudipati 4178a36c61f9SKrishna Gudipati if (resid_len != 0) { 4179a36c61f9SKrishna Gudipati /* 4180a36c61f9SKrishna Gudipati * TBD : we will need to allocate a larger buffer & retry the 4181a36c61f9SKrishna Gudipati * command 4182a36c61f9SKrishna Gudipati */ 4183a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 4184a36c61f9SKrishna Gudipati bfa_trc(port->fcs, resid_len); 4185a36c61f9SKrishna Gudipati return; 4186a36c61f9SKrishna Gudipati } 4187a36c61f9SKrishna Gudipati 4188a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4189ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4190a36c61f9SKrishna Gudipati 4191a36c61f9SKrishna Gudipati switch (cthdr->cmd_rsp_code) { 4192a36c61f9SKrishna Gudipati 4193a36c61f9SKrishna Gudipati case CT_RSP_ACCEPT: 4194a36c61f9SKrishna Gudipati 4195a36c61f9SKrishna Gudipati port->stats.ns_gidft_accepts++; 4196a36c61f9SKrishna Gudipati n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); 4197a36c61f9SKrishna Gudipati bfa_trc(port->fcs, n_pids); 4198a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(port, 4199a36c61f9SKrishna Gudipati (u32 *) (cthdr + 1), 4200a36c61f9SKrishna Gudipati n_pids); 4201a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4202a36c61f9SKrishna Gudipati break; 4203a36c61f9SKrishna Gudipati 4204a36c61f9SKrishna Gudipati case CT_RSP_REJECT: 4205a36c61f9SKrishna Gudipati 4206a36c61f9SKrishna Gudipati /* 4207a36c61f9SKrishna Gudipati * Check the reason code & explanation. 4208a36c61f9SKrishna Gudipati * There may not have been any FC4 devices in the fabric 4209a36c61f9SKrishna Gudipati */ 4210a36c61f9SKrishna Gudipati port->stats.ns_gidft_rejects++; 4211a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4212a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4213a36c61f9SKrishna Gudipati 4214a36c61f9SKrishna Gudipati if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) 4215a36c61f9SKrishna Gudipati && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { 4216a36c61f9SKrishna Gudipati 4217a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4218a36c61f9SKrishna Gudipati } else { 4219a36c61f9SKrishna Gudipati /* 4220a36c61f9SKrishna Gudipati * for all other errors, retry 4221a36c61f9SKrishna Gudipati */ 4222a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4223a36c61f9SKrishna Gudipati } 4224a36c61f9SKrishna Gudipati break; 4225a36c61f9SKrishna Gudipati 4226a36c61f9SKrishna Gudipati default: 4227a36c61f9SKrishna Gudipati port->stats.ns_gidft_unknown_rsp++; 4228a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->cmd_rsp_code); 4229a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4230a36c61f9SKrishna Gudipati } 4231a36c61f9SKrishna Gudipati } 4232a36c61f9SKrishna Gudipati 42335fbe25c7SJing Huang /* 4234a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 4235a36c61f9SKrishna Gudipati * 4236a36c61f9SKrishna Gudipati * param[in] port - pointer to bfa_fcs_lport_t. 4237a36c61f9SKrishna Gudipati * 4238a36c61f9SKrishna Gudipati * return 4239a36c61f9SKrishna Gudipati * void 4240a36c61f9SKrishna Gudipati * 4241a36c61f9SKrishna Gudipati * Special Considerations: 4242a36c61f9SKrishna Gudipati * 4243a36c61f9SKrishna Gudipati * note 4244a36c61f9SKrishna Gudipati */ 4245a36c61f9SKrishna Gudipati static void 4246a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg) 4247a36c61f9SKrishna Gudipati { 4248a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg; 4249a36c61f9SKrishna Gudipati 4250a36c61f9SKrishna Gudipati ns->port->stats.ns_timeouts++; 4251a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT); 4252a36c61f9SKrishna Gudipati } 4253a36c61f9SKrishna Gudipati 4254a36c61f9SKrishna Gudipati /* 4255a36c61f9SKrishna Gudipati * Process the PID list in GID_FT response 4256a36c61f9SKrishna Gudipati */ 4257a36c61f9SKrishna Gudipati static void 4258a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf, 4259a36c61f9SKrishna Gudipati u32 n_pids) 4260a36c61f9SKrishna Gudipati { 4261a36c61f9SKrishna Gudipati struct fcgs_gidft_resp_s *gidft_entry; 4262a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4263a36c61f9SKrishna Gudipati u32 ii; 4264a36c61f9SKrishna Gudipati 4265a36c61f9SKrishna Gudipati for (ii = 0; ii < n_pids; ii++) { 4266a36c61f9SKrishna Gudipati gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; 4267a36c61f9SKrishna Gudipati 4268a36c61f9SKrishna Gudipati if (gidft_entry->pid == port->pid) 4269a36c61f9SKrishna Gudipati continue; 4270a36c61f9SKrishna Gudipati 4271a36c61f9SKrishna Gudipati /* 4272a36c61f9SKrishna Gudipati * Check if this rport already exists 4273a36c61f9SKrishna Gudipati */ 4274a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid); 4275a36c61f9SKrishna Gudipati if (rport == NULL) { 4276a36c61f9SKrishna Gudipati /* 4277a36c61f9SKrishna Gudipati * this is a new device. create rport 4278a36c61f9SKrishna Gudipati */ 4279a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, gidft_entry->pid); 4280a36c61f9SKrishna Gudipati } else { 4281a36c61f9SKrishna Gudipati /* 4282a36c61f9SKrishna Gudipati * this rport already exists 4283a36c61f9SKrishna Gudipati */ 4284a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4285a36c61f9SKrishna Gudipati } 4286a36c61f9SKrishna Gudipati 4287a36c61f9SKrishna Gudipati bfa_trc(port->fcs, gidft_entry->pid); 4288a36c61f9SKrishna Gudipati 4289a36c61f9SKrishna Gudipati /* 4290a36c61f9SKrishna Gudipati * if the last entry bit is set, bail out. 4291a36c61f9SKrishna Gudipati */ 4292a36c61f9SKrishna Gudipati if (gidft_entry->last) 4293a36c61f9SKrishna Gudipati return; 4294a36c61f9SKrishna Gudipati } 4295a36c61f9SKrishna Gudipati } 4296a36c61f9SKrishna Gudipati 42975fbe25c7SJing Huang /* 4298a36c61f9SKrishna Gudipati * fcs_ns_public FCS nameserver public interfaces 4299a36c61f9SKrishna Gudipati */ 4300a36c61f9SKrishna Gudipati 4301a36c61f9SKrishna Gudipati /* 4302a36c61f9SKrishna Gudipati * Functions called by port/fab. 4303a36c61f9SKrishna Gudipati * These will send relevant Events to the ns state machine. 4304a36c61f9SKrishna Gudipati */ 4305a36c61f9SKrishna Gudipati void 4306a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port) 4307a36c61f9SKrishna Gudipati { 4308a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4309a36c61f9SKrishna Gudipati 4310a36c61f9SKrishna Gudipati ns->port = port; 4311a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4312a36c61f9SKrishna Gudipati } 4313a36c61f9SKrishna Gudipati 4314a36c61f9SKrishna Gudipati void 4315a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port) 4316a36c61f9SKrishna Gudipati { 4317a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4318a36c61f9SKrishna Gudipati 4319a36c61f9SKrishna Gudipati ns->port = port; 4320a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE); 4321a36c61f9SKrishna Gudipati } 4322a36c61f9SKrishna Gudipati 4323a36c61f9SKrishna Gudipati void 4324a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port) 4325a36c61f9SKrishna Gudipati { 4326a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4327a36c61f9SKrishna Gudipati 4328a36c61f9SKrishna Gudipati ns->port = port; 4329a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE); 4330a36c61f9SKrishna Gudipati } 4331a36c61f9SKrishna Gudipati 4332a36c61f9SKrishna Gudipati void 4333a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port) 4334a36c61f9SKrishna Gudipati { 4335a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4336a36c61f9SKrishna Gudipati 4337a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4338a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 4339a36c61f9SKrishna Gudipati } 4340a36c61f9SKrishna Gudipati 434152f94b6fSMaggie static void 4342a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port) 4343a36c61f9SKrishna Gudipati { 4344a36c61f9SKrishna Gudipati 4345a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4346a36c61f9SKrishna Gudipati u8 nwwns; 4347a36c61f9SKrishna Gudipati wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; 4348a36c61f9SKrishna Gudipati int ii; 4349a36c61f9SKrishna Gudipati 4350a36c61f9SKrishna Gudipati bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns); 4351a36c61f9SKrishna Gudipati 4352a36c61f9SKrishna Gudipati for (ii = 0 ; ii < nwwns; ++ii) { 4353a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]); 4354d4b671c5SJing Huang WARN_ON(!rport); 4355a36c61f9SKrishna Gudipati } 4356a36c61f9SKrishna Gudipati } 4357a36c61f9SKrishna Gudipati 43585fbe25c7SJing Huang /* 4359a36c61f9SKrishna Gudipati * FCS SCN 4360a36c61f9SKrishna Gudipati */ 4361a36c61f9SKrishna Gudipati 4362a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT 0x0c 4363a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT 0x0d 4364a36c61f9SKrishna Gudipati 4365a36c61f9SKrishna Gudipati /* 4366a36c61f9SKrishna Gudipati * forward declarations 4367a36c61f9SKrishna Gudipati */ 4368a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg, 4369a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 4370a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_scr_response(void *fcsarg, 4371a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 4372a36c61f9SKrishna Gudipati void *cbarg, 4373a36c61f9SKrishna Gudipati bfa_status_t req_status, 4374a36c61f9SKrishna Gudipati u32 rsp_len, 4375a36c61f9SKrishna Gudipati u32 resid_len, 4376a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 4377a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4378a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs); 4379a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_timeout(void *arg); 4380a36c61f9SKrishna Gudipati 43815fbe25c7SJing Huang /* 4382a36c61f9SKrishna Gudipati * fcs_scm_sm FCS SCN state machine 4383a36c61f9SKrishna Gudipati */ 4384a36c61f9SKrishna Gudipati 43855fbe25c7SJing Huang /* 4386a36c61f9SKrishna Gudipati * VPort SCN State Machine events 4387a36c61f9SKrishna Gudipati */ 4388a36c61f9SKrishna Gudipati enum port_scn_event { 4389a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_ONLINE = 1, 4390a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_OFFLINE = 2, 4391a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_OK = 3, 4392a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_ERROR = 4, 4393a36c61f9SKrishna Gudipati SCNSM_EVENT_TIMEOUT = 5, 4394a36c61f9SKrishna Gudipati SCNSM_EVENT_SCR_SENT = 6, 4395a36c61f9SKrishna Gudipati }; 4396a36c61f9SKrishna Gudipati 4397a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4398a36c61f9SKrishna Gudipati enum port_scn_event event); 4399a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_sending_scr( 4400a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn, 4401a36c61f9SKrishna Gudipati enum port_scn_event event); 4402a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4403a36c61f9SKrishna Gudipati enum port_scn_event event); 4404a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4405a36c61f9SKrishna Gudipati enum port_scn_event event); 4406a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4407a36c61f9SKrishna Gudipati enum port_scn_event event); 4408a36c61f9SKrishna Gudipati 44095fbe25c7SJing Huang /* 4410a36c61f9SKrishna Gudipati * Starting state - awaiting link up. 4411a36c61f9SKrishna Gudipati */ 4412a36c61f9SKrishna Gudipati static void 4413a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4414a36c61f9SKrishna Gudipati enum port_scn_event event) 4415a36c61f9SKrishna Gudipati { 4416a36c61f9SKrishna Gudipati switch (event) { 4417a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_ONLINE: 4418a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4419a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 4420a36c61f9SKrishna Gudipati break; 4421a36c61f9SKrishna Gudipati 4422a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4423a36c61f9SKrishna Gudipati break; 4424a36c61f9SKrishna Gudipati 4425a36c61f9SKrishna Gudipati default: 4426a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4427a36c61f9SKrishna Gudipati } 4428a36c61f9SKrishna Gudipati } 4429a36c61f9SKrishna Gudipati 4430a36c61f9SKrishna Gudipati static void 4431a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn, 4432a36c61f9SKrishna Gudipati enum port_scn_event event) 4433a36c61f9SKrishna Gudipati { 4434a36c61f9SKrishna Gudipati switch (event) { 4435a36c61f9SKrishna Gudipati case SCNSM_EVENT_SCR_SENT: 4436a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr); 4437a36c61f9SKrishna Gudipati break; 4438a36c61f9SKrishna Gudipati 4439a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4440a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4441a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe); 4442a36c61f9SKrishna Gudipati break; 4443a36c61f9SKrishna Gudipati 4444a36c61f9SKrishna Gudipati default: 4445a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4446a36c61f9SKrishna Gudipati } 4447a36c61f9SKrishna Gudipati } 4448a36c61f9SKrishna Gudipati 4449a36c61f9SKrishna Gudipati static void 4450a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4451a36c61f9SKrishna Gudipati enum port_scn_event event) 4452a36c61f9SKrishna Gudipati { 4453a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4454a36c61f9SKrishna Gudipati 4455a36c61f9SKrishna Gudipati switch (event) { 4456a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_OK: 4457a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online); 4458a36c61f9SKrishna Gudipati break; 4459a36c61f9SKrishna Gudipati 4460a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_ERROR: 4461a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry); 4462a36c61f9SKrishna Gudipati bfa_timer_start(port->fcs->bfa, &scn->timer, 4463a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout, scn, 4464a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4465a36c61f9SKrishna Gudipati break; 4466a36c61f9SKrishna Gudipati 4467a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4468a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4469a36c61f9SKrishna Gudipati bfa_fcxp_discard(scn->fcxp); 4470a36c61f9SKrishna Gudipati break; 4471a36c61f9SKrishna Gudipati 4472a36c61f9SKrishna Gudipati default: 4473a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 4474a36c61f9SKrishna Gudipati } 4475a36c61f9SKrishna Gudipati } 4476a36c61f9SKrishna Gudipati 4477a36c61f9SKrishna Gudipati static void 4478a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4479a36c61f9SKrishna Gudipati enum port_scn_event event) 4480a36c61f9SKrishna Gudipati { 4481a36c61f9SKrishna Gudipati switch (event) { 4482a36c61f9SKrishna Gudipati case SCNSM_EVENT_TIMEOUT: 4483a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4484a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 4485a36c61f9SKrishna Gudipati break; 4486a36c61f9SKrishna Gudipati 4487a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4488a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4489a36c61f9SKrishna Gudipati bfa_timer_stop(&scn->timer); 4490a36c61f9SKrishna Gudipati break; 4491a36c61f9SKrishna Gudipati 4492a36c61f9SKrishna Gudipati default: 4493a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4494a36c61f9SKrishna Gudipati } 4495a36c61f9SKrishna Gudipati } 4496a36c61f9SKrishna Gudipati 4497a36c61f9SKrishna Gudipati static void 4498a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4499a36c61f9SKrishna Gudipati enum port_scn_event event) 4500a36c61f9SKrishna Gudipati { 4501a36c61f9SKrishna Gudipati switch (event) { 4502a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4503a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4504a36c61f9SKrishna Gudipati break; 4505a36c61f9SKrishna Gudipati 4506a36c61f9SKrishna Gudipati default: 4507a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4508a36c61f9SKrishna Gudipati } 4509a36c61f9SKrishna Gudipati } 4510a36c61f9SKrishna Gudipati 4511a36c61f9SKrishna Gudipati 4512a36c61f9SKrishna Gudipati 45135fbe25c7SJing Huang /* 4514a36c61f9SKrishna Gudipati * fcs_scn_private FCS SCN private functions 4515a36c61f9SKrishna Gudipati */ 4516a36c61f9SKrishna Gudipati 45175fbe25c7SJing Huang /* 4518a36c61f9SKrishna Gudipati * This routine will be called to send a SCR command. 4519a36c61f9SKrishna Gudipati */ 4520a36c61f9SKrishna Gudipati static void 4521a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4522a36c61f9SKrishna Gudipati { 4523a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = scn_cbarg; 4524a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4525a36c61f9SKrishna Gudipati struct fchs_s fchs; 4526a36c61f9SKrishna Gudipati int len; 4527a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4528a36c61f9SKrishna Gudipati 4529a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4530a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4531a36c61f9SKrishna Gudipati 4532a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4533a36c61f9SKrishna Gudipati if (!fcxp) { 4534a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, 4535a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr, scn); 4536a36c61f9SKrishna Gudipati return; 4537a36c61f9SKrishna Gudipati } 4538a36c61f9SKrishna Gudipati scn->fcxp = fcxp; 4539a36c61f9SKrishna Gudipati 4540a36c61f9SKrishna Gudipati /* Handle VU registrations for Base port only */ 4541a36c61f9SKrishna Gudipati if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) { 4542a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4543f7f73812SMaggie Zhang port->fabric->lps->brcd_switch, 4544a36c61f9SKrishna Gudipati port->pid, 0); 4545a36c61f9SKrishna Gudipati } else { 4546a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4547a36c61f9SKrishna Gudipati BFA_FALSE, 4548a36c61f9SKrishna Gudipati port->pid, 0); 4549a36c61f9SKrishna Gudipati } 4550a36c61f9SKrishna Gudipati 4551a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4552a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4553a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response, 4554a36c61f9SKrishna Gudipati (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV); 4555a36c61f9SKrishna Gudipati 4556a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT); 4557a36c61f9SKrishna Gudipati } 4558a36c61f9SKrishna Gudipati 4559a36c61f9SKrishna Gudipati static void 4560a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4561a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 4562a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 4563a36c61f9SKrishna Gudipati { 4564a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg; 4565a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4566a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 4567a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 4568a36c61f9SKrishna Gudipati 4569a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4570a36c61f9SKrishna Gudipati 4571a36c61f9SKrishna Gudipati /* 4572a36c61f9SKrishna Gudipati * Sanity Checks 4573a36c61f9SKrishna Gudipati */ 4574a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4575a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4576a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4577a36c61f9SKrishna Gudipati return; 4578a36c61f9SKrishna Gudipati } 4579a36c61f9SKrishna Gudipati 4580a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 4581a36c61f9SKrishna Gudipati 4582a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 4583a36c61f9SKrishna Gudipati 4584a36c61f9SKrishna Gudipati case FC_ELS_ACC: 4585a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK); 4586a36c61f9SKrishna Gudipati break; 4587a36c61f9SKrishna Gudipati 4588a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 4589a36c61f9SKrishna Gudipati 4590a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 4591a36c61f9SKrishna Gudipati 4592a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 4593a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 4594a36c61f9SKrishna Gudipati 4595a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4596a36c61f9SKrishna Gudipati break; 4597a36c61f9SKrishna Gudipati 4598a36c61f9SKrishna Gudipati default: 4599a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4600a36c61f9SKrishna Gudipati } 4601a36c61f9SKrishna Gudipati } 4602a36c61f9SKrishna Gudipati 4603a36c61f9SKrishna Gudipati /* 4604a36c61f9SKrishna Gudipati * Send a LS Accept 4605a36c61f9SKrishna Gudipati */ 4606a36c61f9SKrishna Gudipati static void 4607a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4608a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs) 4609a36c61f9SKrishna Gudipati { 4610a36c61f9SKrishna Gudipati struct fchs_s fchs; 4611a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4612a36c61f9SKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 4613a36c61f9SKrishna Gudipati int len; 4614a36c61f9SKrishna Gudipati 4615a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 4616a36c61f9SKrishna Gudipati 4617a36c61f9SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs); 4618a36c61f9SKrishna Gudipati if (!fcxp) 4619a36c61f9SKrishna Gudipati return; 4620a36c61f9SKrishna Gudipati 4621a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4622a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 4623a36c61f9SKrishna Gudipati rx_fchs->ox_id); 4624a36c61f9SKrishna Gudipati 4625a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 4626a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 4627a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 4628a36c61f9SKrishna Gudipati } 4629a36c61f9SKrishna Gudipati 46305fbe25c7SJing Huang /* 4631a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 4632a36c61f9SKrishna Gudipati * 4633a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_lport_t. 4634a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 4635a36c61f9SKrishna Gudipati * 4636a36c61f9SKrishna Gudipati * return 4637a36c61f9SKrishna Gudipati * void 4638a36c61f9SKrishna Gudipati * 4639a36c61f9SKrishna Gudipati * Special Considerations: 4640a36c61f9SKrishna Gudipati * 4641a36c61f9SKrishna Gudipati * note 4642a36c61f9SKrishna Gudipati */ 4643a36c61f9SKrishna Gudipati static void 4644a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg) 4645a36c61f9SKrishna Gudipati { 4646a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg; 4647a36c61f9SKrishna Gudipati 4648a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT); 4649a36c61f9SKrishna Gudipati } 4650a36c61f9SKrishna Gudipati 4651a36c61f9SKrishna Gudipati 4652a36c61f9SKrishna Gudipati 46535fbe25c7SJing Huang /* 4654a36c61f9SKrishna Gudipati * fcs_scn_public FCS state change notification public interfaces 4655a36c61f9SKrishna Gudipati */ 4656a36c61f9SKrishna Gudipati 4657a36c61f9SKrishna Gudipati /* 4658a36c61f9SKrishna Gudipati * Functions called by port/fab 4659a36c61f9SKrishna Gudipati */ 4660a36c61f9SKrishna Gudipati void 4661a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port) 4662a36c61f9SKrishna Gudipati { 4663a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4664a36c61f9SKrishna Gudipati 4665a36c61f9SKrishna Gudipati scn->port = port; 4666a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4667a36c61f9SKrishna Gudipati } 4668a36c61f9SKrishna Gudipati 4669a36c61f9SKrishna Gudipati void 4670a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port) 4671a36c61f9SKrishna Gudipati { 4672a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4673a36c61f9SKrishna Gudipati 4674a36c61f9SKrishna Gudipati scn->port = port; 4675a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE); 4676a36c61f9SKrishna Gudipati } 4677a36c61f9SKrishna Gudipati 4678a36c61f9SKrishna Gudipati void 4679a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port) 4680a36c61f9SKrishna Gudipati { 4681a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4682a36c61f9SKrishna Gudipati 4683a36c61f9SKrishna Gudipati scn->port = port; 4684a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE); 4685a36c61f9SKrishna Gudipati } 4686a36c61f9SKrishna Gudipati 4687a36c61f9SKrishna Gudipati static void 4688a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) 4689a36c61f9SKrishna Gudipati { 4690a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4691a36c61f9SKrishna Gudipati 4692a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rpid); 4693a36c61f9SKrishna Gudipati 46945fbe25c7SJing Huang /* 4695a36c61f9SKrishna Gudipati * If this is an unknown device, then it just came online. 4696a36c61f9SKrishna Gudipati * Otherwise let rport handle the RSCN event. 4697a36c61f9SKrishna Gudipati */ 4698a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 4699a36c61f9SKrishna Gudipati if (rport == NULL) { 4700a36c61f9SKrishna Gudipati /* 4701a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot need to 4702a36c61f9SKrishna Gudipati * discover any new rports. 4703a36c61f9SKrishna Gudipati */ 4704a36c61f9SKrishna Gudipati if (!__fcs_min_cfg(port->fcs)) 4705a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, rpid); 4706a36c61f9SKrishna Gudipati } else 4707a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4708a36c61f9SKrishna Gudipati } 4709a36c61f9SKrishna Gudipati 47105fbe25c7SJing Huang /* 4711a36c61f9SKrishna Gudipati * rscn format based PID comparison 4712a36c61f9SKrishna Gudipati */ 4713a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt) \ 4714a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \ 4715a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \ 4716a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0])) || \ 4717a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_AREA) && \ 4718a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0]) && \ 4719a36c61f9SKrishna Gudipati ((__c0)[1] == (__c1)[1]))) 4720a36c61f9SKrishna Gudipati 4721a36c61f9SKrishna Gudipati static void 4722a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port, 4723a36c61f9SKrishna Gudipati enum fc_rscn_format format, 4724a36c61f9SKrishna Gudipati u32 rscn_pid) 4725a36c61f9SKrishna Gudipati { 4726a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4727a36c61f9SKrishna Gudipati struct list_head *qe, *qe_next; 4728a36c61f9SKrishna Gudipati u8 *c0, *c1; 4729a36c61f9SKrishna Gudipati 4730a36c61f9SKrishna Gudipati bfa_trc(port->fcs, format); 4731a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4732a36c61f9SKrishna Gudipati 4733a36c61f9SKrishna Gudipati c0 = (u8 *) &rscn_pid; 4734a36c61f9SKrishna Gudipati 4735a36c61f9SKrishna Gudipati list_for_each_safe(qe, qe_next, &port->rport_q) { 4736a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4737a36c61f9SKrishna Gudipati c1 = (u8 *) &rport->pid; 4738a36c61f9SKrishna Gudipati if (__fc_pid_match(c0, c1, format)) 4739a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4740a36c61f9SKrishna Gudipati } 4741a36c61f9SKrishna Gudipati } 4742a36c61f9SKrishna Gudipati 4743a36c61f9SKrishna Gudipati 4744a36c61f9SKrishna Gudipati void 4745a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 4746a36c61f9SKrishna Gudipati struct fchs_s *fchs, u32 len) 4747a36c61f9SKrishna Gudipati { 4748a36c61f9SKrishna Gudipati struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1); 4749a36c61f9SKrishna Gudipati int num_entries; 4750a36c61f9SKrishna Gudipati u32 rscn_pid; 4751a36c61f9SKrishna Gudipati bfa_boolean_t nsquery = BFA_FALSE, found; 4752a36c61f9SKrishna Gudipati int i = 0, j; 4753a36c61f9SKrishna Gudipati 4754a36c61f9SKrishna Gudipati num_entries = 4755ba816ea8SJing Huang (be16_to_cpu(rscn->payldlen) - 4756a36c61f9SKrishna Gudipati sizeof(u32)) / sizeof(rscn->event[0]); 4757a36c61f9SKrishna Gudipati 4758a36c61f9SKrishna Gudipati bfa_trc(port->fcs, num_entries); 4759a36c61f9SKrishna Gudipati 4760a36c61f9SKrishna Gudipati port->stats.num_rscn++; 4761a36c61f9SKrishna Gudipati 4762a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(port, fchs); 4763a36c61f9SKrishna Gudipati 4764a36c61f9SKrishna Gudipati for (i = 0; i < num_entries; i++) { 4765a36c61f9SKrishna Gudipati rscn_pid = rscn->event[i].portid; 4766a36c61f9SKrishna Gudipati 4767a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn->event[i].format); 4768a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4769a36c61f9SKrishna Gudipati 4770a36c61f9SKrishna Gudipati /* check for duplicate entries in the list */ 4771a36c61f9SKrishna Gudipati found = BFA_FALSE; 4772a36c61f9SKrishna Gudipati for (j = 0; j < i; j++) { 4773a36c61f9SKrishna Gudipati if (rscn->event[j].portid == rscn_pid) { 4774a36c61f9SKrishna Gudipati found = BFA_TRUE; 4775a36c61f9SKrishna Gudipati break; 4776a36c61f9SKrishna Gudipati } 4777a36c61f9SKrishna Gudipati } 4778a36c61f9SKrishna Gudipati 4779a36c61f9SKrishna Gudipati /* if found in down the list, pid has been already processed */ 4780a36c61f9SKrishna Gudipati if (found) { 4781a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4782a36c61f9SKrishna Gudipati continue; 4783a36c61f9SKrishna Gudipati } 4784a36c61f9SKrishna Gudipati 4785a36c61f9SKrishna Gudipati switch (rscn->event[i].format) { 4786a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_PORTID: 4787a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) { 4788a36c61f9SKrishna Gudipati /* 4789a36c61f9SKrishna Gudipati * Ignore this event. 4790a36c61f9SKrishna Gudipati * f/w would have processed it 4791a36c61f9SKrishna Gudipati */ 4792a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4793a36c61f9SKrishna Gudipati } else { 4794a36c61f9SKrishna Gudipati port->stats.num_portid_rscn++; 4795a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(port, rscn_pid); 4796a36c61f9SKrishna Gudipati } 4797a36c61f9SKrishna Gudipati break; 4798a36c61f9SKrishna Gudipati 4799a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_FABRIC: 4800a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == 4801a36c61f9SKrishna Gudipati FC_FABRIC_NAME_RSCN_EVENT) { 4802a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(port); 4803a36c61f9SKrishna Gudipati break; 4804a36c61f9SKrishna Gudipati } 4805a36c61f9SKrishna Gudipati /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */ 4806a36c61f9SKrishna Gudipati 4807a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_AREA: 4808a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_DOMAIN: 4809a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 4810a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(port, 4811a36c61f9SKrishna Gudipati rscn->event[i].format, 4812a36c61f9SKrishna Gudipati rscn_pid); 4813a36c61f9SKrishna Gudipati break; 4814a36c61f9SKrishna Gudipati 4815a36c61f9SKrishna Gudipati 4816a36c61f9SKrishna Gudipati default: 4817d4b671c5SJing Huang WARN_ON(1); 4818a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 4819a36c61f9SKrishna Gudipati } 4820a36c61f9SKrishna Gudipati } 4821a36c61f9SKrishna Gudipati 48225fbe25c7SJing Huang /* 48235fbe25c7SJing Huang * If any of area, domain or fabric RSCN is received, do a fresh 48245fbe25c7SJing Huang * discovery to find new devices. 4825a36c61f9SKrishna Gudipati */ 4826a36c61f9SKrishna Gudipati if (nsquery) 4827a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(port); 4828a36c61f9SKrishna Gudipati } 4829a36c61f9SKrishna Gudipati 48305fbe25c7SJing Huang /* 4831a36c61f9SKrishna Gudipati * BFA FCS port 4832a36c61f9SKrishna Gudipati */ 48335fbe25c7SJing Huang /* 4834a36c61f9SKrishna Gudipati * fcs_port_api BFA FCS port API 4835a36c61f9SKrishna Gudipati */ 4836a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 4837a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs) 4838a36c61f9SKrishna Gudipati { 4839a36c61f9SKrishna Gudipati return &fcs->fabric.bport; 4840a36c61f9SKrishna Gudipati } 4841a36c61f9SKrishna Gudipati 4842a36c61f9SKrishna Gudipati wwn_t 4843a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, 4844a36c61f9SKrishna Gudipati int nrports, bfa_boolean_t bwwn) 4845a36c61f9SKrishna Gudipati { 4846a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 4847a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 4848a36c61f9SKrishna Gudipati int i; 4849a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 4850a36c61f9SKrishna Gudipati 4851a36c61f9SKrishna Gudipati if (port == NULL || nrports == 0) 4852a36c61f9SKrishna Gudipati return (wwn_t) 0; 4853a36c61f9SKrishna Gudipati 4854a36c61f9SKrishna Gudipati fcs = port->fcs; 4855a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) nrports); 4856a36c61f9SKrishna Gudipati 4857a36c61f9SKrishna Gudipati i = 0; 4858a36c61f9SKrishna Gudipati qh = &port->rport_q; 4859a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 4860a36c61f9SKrishna Gudipati 4861a36c61f9SKrishna Gudipati while ((qe != qh) && (i < nrports)) { 4862a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4863f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 4864a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4865a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 4866a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 4867a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4868a36c61f9SKrishna Gudipati continue; 4869a36c61f9SKrishna Gudipati } 4870a36c61f9SKrishna Gudipati 4871a36c61f9SKrishna Gudipati if (bwwn) { 4872a36c61f9SKrishna Gudipati if (!memcmp(&wwn, &rport->pwwn, 8)) 4873a36c61f9SKrishna Gudipati break; 4874a36c61f9SKrishna Gudipati } else { 4875a36c61f9SKrishna Gudipati if (i == index) 4876a36c61f9SKrishna Gudipati break; 4877a36c61f9SKrishna Gudipati } 4878a36c61f9SKrishna Gudipati 4879a36c61f9SKrishna Gudipati i++; 4880a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4881a36c61f9SKrishna Gudipati } 4882a36c61f9SKrishna Gudipati 4883a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4884a36c61f9SKrishna Gudipati if (rport) 4885a36c61f9SKrishna Gudipati return rport->pwwn; 4886a36c61f9SKrishna Gudipati else 4887a36c61f9SKrishna Gudipati return (wwn_t) 0; 4888a36c61f9SKrishna Gudipati } 4889a36c61f9SKrishna Gudipati 4890a36c61f9SKrishna Gudipati void 4891a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, 4892a36c61f9SKrishna Gudipati wwn_t rport_wwns[], int *nrports) 4893a36c61f9SKrishna Gudipati { 4894a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 4895a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 4896a36c61f9SKrishna Gudipati int i; 4897a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 4898a36c61f9SKrishna Gudipati 4899a36c61f9SKrishna Gudipati if (port == NULL || rport_wwns == NULL || *nrports == 0) 4900a36c61f9SKrishna Gudipati return; 4901a36c61f9SKrishna Gudipati 4902a36c61f9SKrishna Gudipati fcs = port->fcs; 4903a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) *nrports); 4904a36c61f9SKrishna Gudipati 4905a36c61f9SKrishna Gudipati i = 0; 4906a36c61f9SKrishna Gudipati qh = &port->rport_q; 4907a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 4908a36c61f9SKrishna Gudipati 4909a36c61f9SKrishna Gudipati while ((qe != qh) && (i < *nrports)) { 4910a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4911f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 4912a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4913a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 4914a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 4915a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4916a36c61f9SKrishna Gudipati continue; 4917a36c61f9SKrishna Gudipati } 4918a36c61f9SKrishna Gudipati 4919a36c61f9SKrishna Gudipati rport_wwns[i] = rport->pwwn; 4920a36c61f9SKrishna Gudipati 4921a36c61f9SKrishna Gudipati i++; 4922a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4923a36c61f9SKrishna Gudipati } 4924a36c61f9SKrishna Gudipati 4925a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4926a36c61f9SKrishna Gudipati *nrports = i; 4927a36c61f9SKrishna Gudipati } 4928a36c61f9SKrishna Gudipati 4929a36c61f9SKrishna Gudipati /* 4930a36c61f9SKrishna Gudipati * Iterate's through all the rport's in the given port to 4931a36c61f9SKrishna Gudipati * determine the maximum operating speed. 4932a36c61f9SKrishna Gudipati * 4933a36c61f9SKrishna Gudipati * !!!! To be used in TRL Functionality only !!!! 4934a36c61f9SKrishna Gudipati */ 4935a36c61f9SKrishna Gudipati bfa_port_speed_t 4936a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) 4937a36c61f9SKrishna Gudipati { 4938a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 4939a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 4940a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 4941a36c61f9SKrishna Gudipati bfa_port_speed_t max_speed = 0; 4942a36c61f9SKrishna Gudipati struct bfa_port_attr_s port_attr; 4943a36c61f9SKrishna Gudipati bfa_port_speed_t port_speed, rport_speed; 4944a36c61f9SKrishna Gudipati bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa); 4945a36c61f9SKrishna Gudipati 4946a36c61f9SKrishna Gudipati 4947a36c61f9SKrishna Gudipati if (port == NULL) 4948a36c61f9SKrishna Gudipati return 0; 4949a36c61f9SKrishna Gudipati 4950a36c61f9SKrishna Gudipati fcs = port->fcs; 4951a36c61f9SKrishna Gudipati 4952a36c61f9SKrishna Gudipati /* Get Physical port's current speed */ 4953a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &port_attr); 4954a36c61f9SKrishna Gudipati port_speed = port_attr.speed; 4955a36c61f9SKrishna Gudipati bfa_trc(fcs, port_speed); 4956a36c61f9SKrishna Gudipati 4957a36c61f9SKrishna Gudipati qh = &port->rport_q; 4958a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 4959a36c61f9SKrishna Gudipati 4960a36c61f9SKrishna Gudipati while (qe != qh) { 4961a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4962f16a1750SMaggie Zhang if ((bfa_ntoh3b(rport->pid) > 0xFFF000) || 4963d7be54ccSKrishna Gudipati (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) || 4964d7be54ccSKrishna Gudipati (rport->scsi_function != BFA_RPORT_TARGET)) { 4965a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4966a36c61f9SKrishna Gudipati continue; 4967a36c61f9SKrishna Gudipati } 4968a36c61f9SKrishna Gudipati 4969a36c61f9SKrishna Gudipati rport_speed = rport->rpf.rpsc_speed; 4970a36c61f9SKrishna Gudipati if ((trl_enabled) && (rport_speed == 4971a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN)) { 4972a36c61f9SKrishna Gudipati /* Use default ratelim speed setting */ 4973a36c61f9SKrishna Gudipati rport_speed = 4974a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(port->fcs->bfa); 4975a36c61f9SKrishna Gudipati } 4976a36c61f9SKrishna Gudipati 4977d7be54ccSKrishna Gudipati if (rport_speed > max_speed) 4978a36c61f9SKrishna Gudipati max_speed = rport_speed; 4979a36c61f9SKrishna Gudipati 4980a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4981a36c61f9SKrishna Gudipati } 4982a36c61f9SKrishna Gudipati 4983d7be54ccSKrishna Gudipati if (max_speed > port_speed) 4984d7be54ccSKrishna Gudipati max_speed = port_speed; 4985d7be54ccSKrishna Gudipati 4986a36c61f9SKrishna Gudipati bfa_trc(fcs, max_speed); 4987a36c61f9SKrishna Gudipati return max_speed; 4988a36c61f9SKrishna Gudipati } 4989a36c61f9SKrishna Gudipati 4990a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 4991a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn) 4992a36c61f9SKrishna Gudipati { 4993a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 4994a36c61f9SKrishna Gudipati bfa_fcs_vf_t *vf; 4995a36c61f9SKrishna Gudipati 4996d4b671c5SJing Huang WARN_ON(fcs == NULL); 4997a36c61f9SKrishna Gudipati 4998a36c61f9SKrishna Gudipati vf = bfa_fcs_vf_lookup(fcs, vf_id); 4999a36c61f9SKrishna Gudipati if (vf == NULL) { 5000a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5001a36c61f9SKrishna Gudipati return NULL; 5002a36c61f9SKrishna Gudipati } 5003a36c61f9SKrishna Gudipati 5004a36c61f9SKrishna Gudipati if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn)) 5005a36c61f9SKrishna Gudipati return &vf->bport; 5006a36c61f9SKrishna Gudipati 5007a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn); 5008a36c61f9SKrishna Gudipati if (vport) 5009a36c61f9SKrishna Gudipati return &vport->lport; 5010a36c61f9SKrishna Gudipati 5011a36c61f9SKrishna Gudipati return NULL; 5012a36c61f9SKrishna Gudipati } 5013a36c61f9SKrishna Gudipati 5014a36c61f9SKrishna Gudipati /* 5015a36c61f9SKrishna Gudipati * API corresponding to NPIV_VPORT_GETINFO. 5016a36c61f9SKrishna Gudipati */ 5017a36c61f9SKrishna Gudipati void 5018a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port, 5019a36c61f9SKrishna Gudipati struct bfa_lport_info_s *port_info) 5020a36c61f9SKrishna Gudipati { 5021a36c61f9SKrishna Gudipati 5022a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->fabric->fabric_name); 5023a36c61f9SKrishna Gudipati 5024a36c61f9SKrishna Gudipati if (port->vport == NULL) { 5025a36c61f9SKrishna Gudipati /* 5026a36c61f9SKrishna Gudipati * This is a Physical port 5027a36c61f9SKrishna Gudipati */ 5028a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_PHYSICAL; 5029a36c61f9SKrishna Gudipati 5030a36c61f9SKrishna Gudipati /* 5031a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5032a36c61f9SKrishna Gudipati */ 5033a36c61f9SKrishna Gudipati port_info->port_state = 0; 5034a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5035a36c61f9SKrishna Gudipati 5036a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5037a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5038a36c61f9SKrishna Gudipati 5039a36c61f9SKrishna Gudipati port_info->max_vports_supp = 5040a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(port->fcs->bfa); 5041a36c61f9SKrishna Gudipati port_info->num_vports_inuse = 5042f7f73812SMaggie Zhang port->fabric->num_vports; 5043a36c61f9SKrishna Gudipati port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; 5044a36c61f9SKrishna Gudipati port_info->num_rports_inuse = port->num_rports; 5045a36c61f9SKrishna Gudipati } else { 5046a36c61f9SKrishna Gudipati /* 5047a36c61f9SKrishna Gudipati * This is a virtual port 5048a36c61f9SKrishna Gudipati */ 5049a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_VIRTUAL; 5050a36c61f9SKrishna Gudipati 5051a36c61f9SKrishna Gudipati /* 5052a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5053a36c61f9SKrishna Gudipati */ 5054a36c61f9SKrishna Gudipati port_info->port_state = 0; 5055a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5056a36c61f9SKrishna Gudipati 5057a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5058a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5059a36c61f9SKrishna Gudipati } 5060a36c61f9SKrishna Gudipati } 5061a36c61f9SKrishna Gudipati 5062a36c61f9SKrishna Gudipati void 5063a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port, 5064a36c61f9SKrishna Gudipati struct bfa_lport_stats_s *port_stats) 5065a36c61f9SKrishna Gudipati { 5066a36c61f9SKrishna Gudipati *port_stats = fcs_port->stats; 5067a36c61f9SKrishna Gudipati } 5068a36c61f9SKrishna Gudipati 5069a36c61f9SKrishna Gudipati void 5070a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) 5071a36c61f9SKrishna Gudipati { 50726a18b167SJing Huang memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s)); 5073a36c61f9SKrishna Gudipati } 5074a36c61f9SKrishna Gudipati 50755fbe25c7SJing Huang /* 5076a36c61f9SKrishna Gudipati * FCS virtual port state machine 5077a36c61f9SKrishna Gudipati */ 5078a36c61f9SKrishna Gudipati 5079a36c61f9SKrishna Gudipati #define __vport_fcs(__vp) ((__vp)->lport.fcs) 5080a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn) 5081a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn) 5082a36c61f9SKrishna Gudipati #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa) 5083a36c61f9SKrishna Gudipati #define __vport_fcid(__vp) ((__vp)->lport.pid) 5084a36c61f9SKrishna Gudipati #define __vport_fabric(__vp) ((__vp)->lport.fabric) 5085a36c61f9SKrishna Gudipati #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id) 5086a36c61f9SKrishna Gudipati 5087a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES 5 5088a36c61f9SKrishna Gudipati /* 5089a36c61f9SKrishna Gudipati * Forward declarations 5090a36c61f9SKrishna Gudipati */ 5091a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport); 5092a36c61f9SKrishna Gudipati static void bfa_fcs_vport_timeout(void *vport_arg); 5093a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport); 5094a36c61f9SKrishna Gudipati static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport); 5095a36c61f9SKrishna Gudipati 50965fbe25c7SJing Huang /* 5097a36c61f9SKrishna Gudipati * fcs_vport_sm FCS virtual port state machine 5098a36c61f9SKrishna Gudipati */ 5099a36c61f9SKrishna Gudipati 51005fbe25c7SJing Huang /* 5101a36c61f9SKrishna Gudipati * VPort State Machine events 5102a36c61f9SKrishna Gudipati */ 5103a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event { 5104a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */ 5105a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */ 5106a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_START = 3, /* vport start request */ 5107a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */ 5108a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */ 5109a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */ 5110a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */ 5111a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */ 5112a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */ 5113a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */ 5114a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ 5115a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ 5116a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ 5117dd5aaf45SKrishna Gudipati BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ 5118a36c61f9SKrishna Gudipati }; 5119a36c61f9SKrishna Gudipati 5120a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 5121a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5122a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 5123a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5124a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 5125a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5126a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 5127a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5128a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5129a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5130d7be54ccSKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 5131d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event); 5132a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5133a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5134a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5135a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5136a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5137a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5138a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5139a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5140a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5141a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5142dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 5143dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 5144dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 5145dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 5146a36c61f9SKrishna Gudipati 5147a36c61f9SKrishna Gudipati static struct bfa_sm_table_s vport_sm_table[] = { 5148a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, 5149a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED}, 5150a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, 5151a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, 5152a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, 5153d7be54ccSKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT}, 5154a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, 5155a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, 5156a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, 5157a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO}, 5158a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR} 5159a36c61f9SKrishna Gudipati }; 5160a36c61f9SKrishna Gudipati 51615fbe25c7SJing Huang /* 5162a36c61f9SKrishna Gudipati * Beginning state. 5163a36c61f9SKrishna Gudipati */ 5164a36c61f9SKrishna Gudipati static void 5165a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 5166a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5167a36c61f9SKrishna Gudipati { 5168a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5169a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5170a36c61f9SKrishna Gudipati 5171a36c61f9SKrishna Gudipati switch (event) { 5172a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_CREATE: 5173a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5174a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(__vport_fabric(vport), vport); 5175a36c61f9SKrishna Gudipati break; 5176a36c61f9SKrishna Gudipati 5177a36c61f9SKrishna Gudipati default: 5178a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5179a36c61f9SKrishna Gudipati } 5180a36c61f9SKrishna Gudipati } 5181a36c61f9SKrishna Gudipati 51825fbe25c7SJing Huang /* 5183a36c61f9SKrishna Gudipati * Created state - a start event is required to start up the state machine. 5184a36c61f9SKrishna Gudipati */ 5185a36c61f9SKrishna Gudipati static void 5186a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 5187a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5188a36c61f9SKrishna Gudipati { 5189a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5190a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5191a36c61f9SKrishna Gudipati 5192a36c61f9SKrishna Gudipati switch (event) { 5193a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_START: 5194f7f73812SMaggie Zhang if (bfa_sm_cmp_state(__vport_fabric(vport), 5195f7f73812SMaggie Zhang bfa_fcs_fabric_sm_online) 5196a36c61f9SKrishna Gudipati && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) { 5197a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5198a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5199a36c61f9SKrishna Gudipati } else { 52005fbe25c7SJing Huang /* 5201a36c61f9SKrishna Gudipati * Fabric is offline or not NPIV capable, stay in 5202a36c61f9SKrishna Gudipati * offline state. 5203a36c61f9SKrishna Gudipati */ 5204a36c61f9SKrishna Gudipati vport->vport_stats.fab_no_npiv++; 5205a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5206a36c61f9SKrishna Gudipati } 5207a36c61f9SKrishna Gudipati break; 5208a36c61f9SKrishna Gudipati 5209a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5210a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5211a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5212a36c61f9SKrishna Gudipati break; 5213a36c61f9SKrishna Gudipati 5214a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 5215a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 52165fbe25c7SJing Huang /* 5217a36c61f9SKrishna Gudipati * Ignore ONLINE/OFFLINE events from fabric 5218a36c61f9SKrishna Gudipati * till vport is started. 5219a36c61f9SKrishna Gudipati */ 5220a36c61f9SKrishna Gudipati break; 5221a36c61f9SKrishna Gudipati 5222a36c61f9SKrishna Gudipati default: 5223a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5224a36c61f9SKrishna Gudipati } 5225a36c61f9SKrishna Gudipati } 5226a36c61f9SKrishna Gudipati 52275fbe25c7SJing Huang /* 5228a36c61f9SKrishna Gudipati * Offline state - awaiting ONLINE event from fabric SM. 5229a36c61f9SKrishna Gudipati */ 5230a36c61f9SKrishna Gudipati static void 5231a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 5232a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5233a36c61f9SKrishna Gudipati { 5234a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5235a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5236a36c61f9SKrishna Gudipati 5237a36c61f9SKrishna Gudipati switch (event) { 5238a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5239a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5240a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5241a36c61f9SKrishna Gudipati break; 5242a36c61f9SKrishna Gudipati 5243a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 5244a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5245a36c61f9SKrishna Gudipati vport->fdisc_retries = 0; 5246a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5247a36c61f9SKrishna Gudipati break; 5248a36c61f9SKrishna Gudipati 5249dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 5250dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5251dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 5252dd5aaf45SKrishna Gudipati break; 5253dd5aaf45SKrishna Gudipati 5254a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5255a36c61f9SKrishna Gudipati /* 5256a36c61f9SKrishna Gudipati * This can happen if the vport couldn't be initialzied 5257a36c61f9SKrishna Gudipati * due the fact that the npiv was not enabled on the switch. 5258a36c61f9SKrishna Gudipati * In that case we will put the vport in offline state. 5259a36c61f9SKrishna Gudipati * However, the link can go down and cause the this event to 5260a36c61f9SKrishna Gudipati * be sent when we are already offline. Ignore it. 5261a36c61f9SKrishna Gudipati */ 5262a36c61f9SKrishna Gudipati break; 5263a36c61f9SKrishna Gudipati 5264a36c61f9SKrishna Gudipati default: 5265a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5266a36c61f9SKrishna Gudipati } 5267a36c61f9SKrishna Gudipati } 5268a36c61f9SKrishna Gudipati 5269a36c61f9SKrishna Gudipati 52705fbe25c7SJing Huang /* 5271a36c61f9SKrishna Gudipati * FDISC is sent and awaiting reply from fabric. 5272a36c61f9SKrishna Gudipati */ 5273a36c61f9SKrishna Gudipati static void 5274a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(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: 5282d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait); 5283a36c61f9SKrishna Gudipati break; 5284a36c61f9SKrishna Gudipati 5285a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5286a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5287f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5288a36c61f9SKrishna Gudipati break; 5289a36c61f9SKrishna Gudipati 5290a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5291a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_online); 5292a36c61f9SKrishna Gudipati bfa_fcs_lport_online(&vport->lport); 5293a36c61f9SKrishna Gudipati break; 5294a36c61f9SKrishna Gudipati 5295a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5296a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry); 5297a36c61f9SKrishna Gudipati bfa_timer_start(__vport_bfa(vport), &vport->timer, 5298a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout, vport, 5299a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 5300a36c61f9SKrishna Gudipati break; 5301a36c61f9SKrishna Gudipati 5302a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 5303a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5304a36c61f9SKrishna Gudipati break; 5305a36c61f9SKrishna Gudipati 5306a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 5307a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_error); 5308a36c61f9SKrishna Gudipati break; 5309a36c61f9SKrishna Gudipati 5310a36c61f9SKrishna Gudipati default: 5311a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5312a36c61f9SKrishna Gudipati } 5313a36c61f9SKrishna Gudipati } 5314a36c61f9SKrishna Gudipati 53155fbe25c7SJing Huang /* 5316a36c61f9SKrishna Gudipati * FDISC attempt failed - a timer is active to retry FDISC. 5317a36c61f9SKrishna Gudipati */ 5318a36c61f9SKrishna Gudipati static void 5319a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5320a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5321a36c61f9SKrishna Gudipati { 5322a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5323a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5324a36c61f9SKrishna Gudipati 5325a36c61f9SKrishna Gudipati switch (event) { 5326a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5327a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5328a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 5329a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5330a36c61f9SKrishna Gudipati break; 5331a36c61f9SKrishna Gudipati 5332a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5333a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5334a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 5335a36c61f9SKrishna Gudipati break; 5336a36c61f9SKrishna Gudipati 5337a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_TIMEOUT: 5338a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5339a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_retries++; 5340a36c61f9SKrishna Gudipati vport->fdisc_retries++; 5341a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5342a36c61f9SKrishna Gudipati break; 5343a36c61f9SKrishna Gudipati 5344a36c61f9SKrishna Gudipati default: 5345a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5346a36c61f9SKrishna Gudipati } 5347a36c61f9SKrishna Gudipati } 5348a36c61f9SKrishna Gudipati 53495fbe25c7SJing Huang /* 5350d7be54ccSKrishna Gudipati * FDISC is in progress and we got a vport delete request - 5351d7be54ccSKrishna Gudipati * this is a wait state while we wait for fdisc response and 5352d7be54ccSKrishna Gudipati * we will transition to the appropriate state - on rsp status. 5353d7be54ccSKrishna Gudipati */ 5354d7be54ccSKrishna Gudipati static void 5355d7be54ccSKrishna Gudipati bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 5356d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event) 5357d7be54ccSKrishna Gudipati { 5358d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5359d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5360d7be54ccSKrishna Gudipati 5361d7be54ccSKrishna Gudipati switch (event) { 5362d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5363d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 5364d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5365d7be54ccSKrishna Gudipati break; 5366d7be54ccSKrishna Gudipati 5367d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5368d7be54ccSKrishna Gudipati break; 5369d7be54ccSKrishna Gudipati 5370d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5371d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5372d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 5373d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 5374d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5375d7be54ccSKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5376d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5377d7be54ccSKrishna Gudipati break; 5378d7be54ccSKrishna Gudipati 5379d7be54ccSKrishna Gudipati default: 5380d7be54ccSKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5381d7be54ccSKrishna Gudipati } 5382d7be54ccSKrishna Gudipati } 5383d7be54ccSKrishna Gudipati 5384d7be54ccSKrishna Gudipati /* 5385a36c61f9SKrishna Gudipati * Vport is online (FDISC is complete). 5386a36c61f9SKrishna Gudipati */ 5387a36c61f9SKrishna Gudipati static void 5388a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5389a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5390a36c61f9SKrishna Gudipati { 5391a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5392a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5393a36c61f9SKrishna Gudipati 5394a36c61f9SKrishna Gudipati switch (event) { 5395a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5396a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 5397a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5398a36c61f9SKrishna Gudipati break; 5399a36c61f9SKrishna Gudipati 5400dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 5401dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping); 5402dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 5403dd5aaf45SKrishna Gudipati break; 5404dd5aaf45SKrishna Gudipati 5405a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5406a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5407f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5408a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(&vport->lport); 5409a36c61f9SKrishna Gudipati break; 5410a36c61f9SKrishna Gudipati 5411a36c61f9SKrishna Gudipati default: 5412a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5413a36c61f9SKrishna Gudipati } 5414a36c61f9SKrishna Gudipati } 5415a36c61f9SKrishna Gudipati 54165fbe25c7SJing Huang /* 5417dd5aaf45SKrishna Gudipati * Vport is being stopped - awaiting lport stop completion to send 5418dd5aaf45SKrishna Gudipati * LOGO to fabric. 5419dd5aaf45SKrishna Gudipati */ 5420dd5aaf45SKrishna Gudipati static void 5421dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 5422dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 5423dd5aaf45SKrishna Gudipati { 5424dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5425dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5426dd5aaf45SKrishna Gudipati 5427dd5aaf45SKrishna Gudipati switch (event) { 5428dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 5429dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop); 5430dd5aaf45SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 5431dd5aaf45SKrishna Gudipati break; 5432dd5aaf45SKrishna Gudipati 5433dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5434dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5435dd5aaf45SKrishna Gudipati break; 5436dd5aaf45SKrishna Gudipati 5437dd5aaf45SKrishna Gudipati default: 5438dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5439dd5aaf45SKrishna Gudipati } 5440dd5aaf45SKrishna Gudipati } 5441dd5aaf45SKrishna Gudipati 5442dd5aaf45SKrishna Gudipati /* 5443a36c61f9SKrishna Gudipati * Vport is being deleted - awaiting lport delete completion to send 5444a36c61f9SKrishna Gudipati * LOGO to fabric. 5445a36c61f9SKrishna Gudipati */ 5446a36c61f9SKrishna Gudipati static void 5447a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5448a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5449a36c61f9SKrishna Gudipati { 5450a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5451a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5452a36c61f9SKrishna Gudipati 5453a36c61f9SKrishna Gudipati switch (event) { 5454a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5455a36c61f9SKrishna Gudipati break; 5456a36c61f9SKrishna Gudipati 5457a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 5458a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); 5459a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 5460a36c61f9SKrishna Gudipati break; 5461a36c61f9SKrishna Gudipati 5462a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5463a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5464a36c61f9SKrishna Gudipati break; 5465a36c61f9SKrishna Gudipati 5466a36c61f9SKrishna Gudipati default: 5467a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5468a36c61f9SKrishna Gudipati } 5469a36c61f9SKrishna Gudipati } 5470a36c61f9SKrishna Gudipati 54715fbe25c7SJing Huang /* 5472a36c61f9SKrishna Gudipati * Error State. 5473a36c61f9SKrishna Gudipati * This state will be set when the Vport Creation fails due 5474a36c61f9SKrishna Gudipati * to errors like Dup WWN. In this state only operation allowed 5475a36c61f9SKrishna Gudipati * is a Vport Delete. 5476a36c61f9SKrishna Gudipati */ 5477a36c61f9SKrishna Gudipati static void 5478a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5479a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5480a36c61f9SKrishna Gudipati { 5481a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5482a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5483a36c61f9SKrishna Gudipati 5484a36c61f9SKrishna Gudipati switch (event) { 5485a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5486a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5487a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5488a36c61f9SKrishna Gudipati break; 5489a36c61f9SKrishna Gudipati 5490a36c61f9SKrishna Gudipati default: 5491a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5492a36c61f9SKrishna Gudipati } 5493a36c61f9SKrishna Gudipati } 5494a36c61f9SKrishna Gudipati 54955fbe25c7SJing Huang /* 5496a36c61f9SKrishna Gudipati * Lport cleanup is in progress since vport is being deleted. Fabric is 5497a36c61f9SKrishna Gudipati * offline, so no LOGO is needed to complete vport deletion. 5498a36c61f9SKrishna Gudipati */ 5499a36c61f9SKrishna Gudipati static void 5500a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5501a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5502a36c61f9SKrishna Gudipati { 5503a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5504a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5505a36c61f9SKrishna Gudipati 5506a36c61f9SKrishna Gudipati switch (event) { 5507a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 5508a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5509a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 5510a36c61f9SKrishna Gudipati break; 5511a36c61f9SKrishna Gudipati 5512dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 5513dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5514dd5aaf45SKrishna Gudipati break; 5515dd5aaf45SKrishna Gudipati 5516a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5517a36c61f9SKrishna Gudipati break; 5518a36c61f9SKrishna Gudipati 5519a36c61f9SKrishna Gudipati default: 5520a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5521a36c61f9SKrishna Gudipati } 5522a36c61f9SKrishna Gudipati } 5523a36c61f9SKrishna Gudipati 55245fbe25c7SJing Huang /* 5525dd5aaf45SKrishna Gudipati * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup 5526dd5aaf45SKrishna Gudipati * is done. 5527dd5aaf45SKrishna Gudipati */ 5528dd5aaf45SKrishna Gudipati static void 5529dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 5530dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 5531dd5aaf45SKrishna Gudipati { 5532dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5533dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5534dd5aaf45SKrishna Gudipati 5535dd5aaf45SKrishna Gudipati switch (event) { 5536dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5537dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5538dd5aaf45SKrishna Gudipati /* 5539dd5aaf45SKrishna Gudipati * !!! fall through !!! 5540dd5aaf45SKrishna Gudipati */ 5541dd5aaf45SKrishna Gudipati 5542dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5543dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5544dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5545dd5aaf45SKrishna Gudipati break; 5546dd5aaf45SKrishna Gudipati 5547dd5aaf45SKrishna Gudipati default: 5548dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5549dd5aaf45SKrishna Gudipati } 5550dd5aaf45SKrishna Gudipati } 5551dd5aaf45SKrishna Gudipati 5552dd5aaf45SKrishna Gudipati /* 5553a36c61f9SKrishna Gudipati * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup 5554a36c61f9SKrishna Gudipati * is done. 5555a36c61f9SKrishna Gudipati */ 5556a36c61f9SKrishna Gudipati static void 5557a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5558a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5559a36c61f9SKrishna Gudipati { 5560a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5561a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5562a36c61f9SKrishna Gudipati 5563a36c61f9SKrishna Gudipati switch (event) { 5564a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5565f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5566a36c61f9SKrishna Gudipati /* 5567a36c61f9SKrishna Gudipati * !!! fall through !!! 5568a36c61f9SKrishna Gudipati */ 5569a36c61f9SKrishna Gudipati 5570a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5571a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5572a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5573a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 5574a36c61f9SKrishna Gudipati break; 5575a36c61f9SKrishna Gudipati 5576a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5577a36c61f9SKrishna Gudipati break; 5578a36c61f9SKrishna Gudipati 5579a36c61f9SKrishna Gudipati default: 5580a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5581a36c61f9SKrishna Gudipati } 5582a36c61f9SKrishna Gudipati } 5583a36c61f9SKrishna Gudipati 5584a36c61f9SKrishna Gudipati 5585a36c61f9SKrishna Gudipati 55865fbe25c7SJing Huang /* 5587a36c61f9SKrishna Gudipati * fcs_vport_private FCS virtual port private functions 5588a36c61f9SKrishna Gudipati */ 55895fbe25c7SJing Huang /* 55907826f304SKrishna Gudipati * Send AEN notification 55917826f304SKrishna Gudipati */ 55927826f304SKrishna Gudipati static void 55937826f304SKrishna Gudipati bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port, 55947826f304SKrishna Gudipati enum bfa_lport_aen_event event) 55957826f304SKrishna Gudipati { 55967826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 55977826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 55987826f304SKrishna Gudipati 55997826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 56007826f304SKrishna Gudipati if (!aen_entry) 56017826f304SKrishna Gudipati return; 56027826f304SKrishna Gudipati 56037826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 56047826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 56057826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 56067826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 56077826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 56087826f304SKrishna Gudipati 56097826f304SKrishna Gudipati /* Send the AEN notification */ 56107826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 56117826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 56127826f304SKrishna Gudipati } 56137826f304SKrishna Gudipati 56147826f304SKrishna Gudipati /* 5615a36c61f9SKrishna Gudipati * This routine will be called to send a FDISC command. 5616a36c61f9SKrishna Gudipati */ 5617a36c61f9SKrishna Gudipati static void 5618a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) 5619a36c61f9SKrishna Gudipati { 5620a36c61f9SKrishna Gudipati bfa_lps_fdisc(vport->lps, vport, 5621a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(__vport_bfa(vport)), 5622a36c61f9SKrishna Gudipati __vport_pwwn(vport), __vport_nwwn(vport)); 5623a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_sent++; 5624a36c61f9SKrishna Gudipati } 5625a36c61f9SKrishna Gudipati 5626a36c61f9SKrishna Gudipati static void 5627a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) 5628a36c61f9SKrishna Gudipati { 5629f7f73812SMaggie Zhang u8 lsrjt_rsn = vport->lps->lsrjt_rsn; 5630f7f73812SMaggie Zhang u8 lsrjt_expl = vport->lps->lsrjt_expl; 5631a36c61f9SKrishna Gudipati 5632a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_rsn); 5633a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_expl); 5634a36c61f9SKrishna Gudipati 5635a36c61f9SKrishna Gudipati /* For certain reason codes, we don't want to retry. */ 5636f7f73812SMaggie Zhang switch (vport->lps->lsrjt_expl) { 5637a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */ 5638a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ 5639a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5640a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 56417826f304SKrishna Gudipati else { 56427826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 56437826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_DUP_WWN); 5644a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); 56457826f304SKrishna Gudipati } 5646a36c61f9SKrishna Gudipati break; 5647a36c61f9SKrishna Gudipati 5648a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INSUFF_RES: 5649a36c61f9SKrishna Gudipati /* 5650a36c61f9SKrishna Gudipati * This means max logins per port/switch setting on the 5651a36c61f9SKrishna Gudipati * switch was exceeded. 5652a36c61f9SKrishna Gudipati */ 5653a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5654a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 56557826f304SKrishna Gudipati else { 56567826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 56577826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_FABRIC_MAX); 5658a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 56597826f304SKrishna Gudipati } 5660a36c61f9SKrishna Gudipati break; 5661a36c61f9SKrishna Gudipati 5662a36c61f9SKrishna Gudipati default: 56637826f304SKrishna Gudipati if (vport->fdisc_retries == 0) 56647826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 56657826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_UNKNOWN); 5666a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5667a36c61f9SKrishna Gudipati } 5668a36c61f9SKrishna Gudipati } 5669a36c61f9SKrishna Gudipati 56705fbe25c7SJing Huang /* 5671a36c61f9SKrishna Gudipati * Called to send a logout to the fabric. Used when a V-Port is 5672a36c61f9SKrishna Gudipati * deleted/stopped. 5673a36c61f9SKrishna Gudipati */ 5674a36c61f9SKrishna Gudipati static void 5675a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport) 5676a36c61f9SKrishna Gudipati { 5677a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5678a36c61f9SKrishna Gudipati 5679a36c61f9SKrishna Gudipati vport->vport_stats.logo_sent++; 5680a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(vport->lps); 5681a36c61f9SKrishna Gudipati } 5682a36c61f9SKrishna Gudipati 5683a36c61f9SKrishna Gudipati 56845fbe25c7SJing Huang /* 5685a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 5686a36c61f9SKrishna Gudipati * 5687a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 5688a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 5689a36c61f9SKrishna Gudipati * 5690a36c61f9SKrishna Gudipati * return 5691a36c61f9SKrishna Gudipati * void 5692a36c61f9SKrishna Gudipati * 5693a36c61f9SKrishna Gudipati * Special Considerations: 5694a36c61f9SKrishna Gudipati * 5695a36c61f9SKrishna Gudipati * note 5696a36c61f9SKrishna Gudipati */ 5697a36c61f9SKrishna Gudipati static void 5698a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg) 5699a36c61f9SKrishna Gudipati { 5700a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg; 5701a36c61f9SKrishna Gudipati 5702a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_timeouts++; 5703a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT); 5704a36c61f9SKrishna Gudipati } 5705a36c61f9SKrishna Gudipati 5706a36c61f9SKrishna Gudipati static void 5707a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) 5708a36c61f9SKrishna Gudipati { 5709a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv = 5710a36c61f9SKrishna Gudipati (struct bfad_vport_s *)vport->vport_drv; 5711a36c61f9SKrishna Gudipati 5712a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); 5713a36c61f9SKrishna Gudipati bfa_lps_delete(vport->lps); 571417c201b3SKrishna Gudipati 571517c201b3SKrishna Gudipati if (vport_drv->comp_del) { 571617c201b3SKrishna Gudipati complete(vport_drv->comp_del); 571717c201b3SKrishna Gudipati return; 5718a36c61f9SKrishna Gudipati } 5719a36c61f9SKrishna Gudipati 572017c201b3SKrishna Gudipati /* 572117c201b3SKrishna Gudipati * We queue the vport delete work to the IM work_q from here. 572217c201b3SKrishna Gudipati * The memory for the bfad_vport_s is freed from the FC function 572317c201b3SKrishna Gudipati * template vport_delete entry point. 572417c201b3SKrishna Gudipati */ 572517c201b3SKrishna Gudipati if (vport_drv) 572617c201b3SKrishna Gudipati bfad_im_port_delete(vport_drv->drv_port.bfad, 572717c201b3SKrishna Gudipati &vport_drv->drv_port); 572817c201b3SKrishna Gudipati } 5729a36c61f9SKrishna Gudipati 57305fbe25c7SJing Huang /* 5731a36c61f9SKrishna Gudipati * fcs_vport_public FCS virtual port public interfaces 5732a36c61f9SKrishna Gudipati */ 5733a36c61f9SKrishna Gudipati 57345fbe25c7SJing Huang /* 5735a36c61f9SKrishna Gudipati * Online notification from fabric SM. 5736a36c61f9SKrishna Gudipati */ 5737a36c61f9SKrishna Gudipati void 5738a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) 5739a36c61f9SKrishna Gudipati { 5740a36c61f9SKrishna Gudipati vport->vport_stats.fab_online++; 5741d7be54ccSKrishna Gudipati if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) 5742a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 5743d7be54ccSKrishna Gudipati else 5744d7be54ccSKrishna Gudipati vport->vport_stats.fab_no_npiv++; 5745a36c61f9SKrishna Gudipati } 5746a36c61f9SKrishna Gudipati 57475fbe25c7SJing Huang /* 5748a36c61f9SKrishna Gudipati * Offline notification from fabric SM. 5749a36c61f9SKrishna Gudipati */ 5750a36c61f9SKrishna Gudipati void 5751a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport) 5752a36c61f9SKrishna Gudipati { 5753a36c61f9SKrishna Gudipati vport->vport_stats.fab_offline++; 5754a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 5755a36c61f9SKrishna Gudipati } 5756a36c61f9SKrishna Gudipati 57575fbe25c7SJing Huang /* 5758a36c61f9SKrishna Gudipati * Cleanup notification from fabric SM on link timer expiry. 5759a36c61f9SKrishna Gudipati */ 5760a36c61f9SKrishna Gudipati void 5761a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) 5762a36c61f9SKrishna Gudipati { 5763a36c61f9SKrishna Gudipati vport->vport_stats.fab_cleanup++; 5764a36c61f9SKrishna Gudipati } 57655fbe25c7SJing Huang /* 5766a36c61f9SKrishna Gudipati * delete notification from fabric SM. To be invoked from within FCS. 5767a36c61f9SKrishna Gudipati */ 5768a36c61f9SKrishna Gudipati void 5769a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) 5770a36c61f9SKrishna Gudipati { 5771a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 5772a36c61f9SKrishna Gudipati } 5773a36c61f9SKrishna Gudipati 57745fbe25c7SJing Huang /* 5775dd5aaf45SKrishna Gudipati * Stop completion callback from associated lport 5776dd5aaf45SKrishna Gudipati */ 5777dd5aaf45SKrishna Gudipati void 5778dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport) 5779dd5aaf45SKrishna Gudipati { 5780dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP); 5781dd5aaf45SKrishna Gudipati } 5782dd5aaf45SKrishna Gudipati 5783dd5aaf45SKrishna Gudipati /* 5784a36c61f9SKrishna Gudipati * Delete completion callback from associated lport 5785a36c61f9SKrishna Gudipati */ 5786a36c61f9SKrishna Gudipati void 5787a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) 5788a36c61f9SKrishna Gudipati { 5789a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); 5790a36c61f9SKrishna Gudipati } 5791a36c61f9SKrishna Gudipati 5792a36c61f9SKrishna Gudipati 5793a36c61f9SKrishna Gudipati 57945fbe25c7SJing Huang /* 5795a36c61f9SKrishna Gudipati * fcs_vport_api Virtual port API 5796a36c61f9SKrishna Gudipati */ 5797a36c61f9SKrishna Gudipati 57985fbe25c7SJing Huang /* 5799a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS vport object. This 5800a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 5801a36c61f9SKrishna Gudipati * done in vport_start() call) 5802a36c61f9SKrishna Gudipati * 5803a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 5804a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 5805a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 5806a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 5807a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 5808a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 5809a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 5810a36c61f9SKrishna Gudipati * structure 5811a36c61f9SKrishna Gudipati * 5812a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 5813a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 5814a36c61f9SKrishna Gudipati */ 5815a36c61f9SKrishna Gudipati bfa_status_t 5816a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 5817a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 5818a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 5819a36c61f9SKrishna Gudipati { 5820a36c61f9SKrishna Gudipati if (vport_cfg->pwwn == 0) 5821a36c61f9SKrishna Gudipati return BFA_STATUS_INVALID_WWN; 5822a36c61f9SKrishna Gudipati 5823a36c61f9SKrishna Gudipati if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn) 5824a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_WWN_BP; 5825a36c61f9SKrishna Gudipati 5826a36c61f9SKrishna Gudipati if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL) 5827a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_EXISTS; 5828a36c61f9SKrishna Gudipati 5829f7f73812SMaggie Zhang if (fcs->fabric.num_vports == 5830a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(fcs->bfa)) 5831a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 5832a36c61f9SKrishna Gudipati 5833a36c61f9SKrishna Gudipati vport->lps = bfa_lps_alloc(fcs->bfa); 5834a36c61f9SKrishna Gudipati if (!vport->lps) 5835a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 5836a36c61f9SKrishna Gudipati 5837a36c61f9SKrishna Gudipati vport->vport_drv = vport_drv; 5838a36c61f9SKrishna Gudipati vport_cfg->preboot_vp = BFA_FALSE; 5839a36c61f9SKrishna Gudipati 5840a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5841a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); 5842a36c61f9SKrishna Gudipati bfa_fcs_lport_init(&vport->lport, vport_cfg); 5843a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); 5844a36c61f9SKrishna Gudipati 5845a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5846a36c61f9SKrishna Gudipati } 5847a36c61f9SKrishna Gudipati 58485fbe25c7SJing Huang /* 5849a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS PBC vport object. This 5850a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 5851a36c61f9SKrishna Gudipati * done in vport_start() call) 5852a36c61f9SKrishna Gudipati * 5853a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 5854a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 5855a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 5856a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 5857a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 5858a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 5859a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 5860a36c61f9SKrishna Gudipati * structure 5861a36c61f9SKrishna Gudipati * 5862a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 5863a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 5864a36c61f9SKrishna Gudipati */ 5865a36c61f9SKrishna Gudipati bfa_status_t 5866a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 5867a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 5868a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 5869a36c61f9SKrishna Gudipati { 5870a36c61f9SKrishna Gudipati bfa_status_t rc; 5871a36c61f9SKrishna Gudipati 5872a36c61f9SKrishna Gudipati rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv); 5873a36c61f9SKrishna Gudipati vport->lport.port_cfg.preboot_vp = BFA_TRUE; 5874a36c61f9SKrishna Gudipati 5875a36c61f9SKrishna Gudipati return rc; 5876a36c61f9SKrishna Gudipati } 5877a36c61f9SKrishna Gudipati 58785fbe25c7SJing Huang /* 5879a36c61f9SKrishna Gudipati * Use this function to findout if this is a pbc vport or not. 5880a36c61f9SKrishna Gudipati * 5881a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 5882a36c61f9SKrishna Gudipati * 5883a36c61f9SKrishna Gudipati * @returns None 5884a36c61f9SKrishna Gudipati */ 5885a36c61f9SKrishna Gudipati bfa_boolean_t 5886a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport) 5887a36c61f9SKrishna Gudipati { 5888a36c61f9SKrishna Gudipati 5889a36c61f9SKrishna Gudipati if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE)) 5890a36c61f9SKrishna Gudipati return BFA_TRUE; 5891a36c61f9SKrishna Gudipati else 5892a36c61f9SKrishna Gudipati return BFA_FALSE; 5893a36c61f9SKrishna Gudipati 5894a36c61f9SKrishna Gudipati } 5895a36c61f9SKrishna Gudipati 58965fbe25c7SJing Huang /* 5897a36c61f9SKrishna Gudipati * Use this function initialize the vport. 5898a36c61f9SKrishna Gudipati * 5899a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 5900a36c61f9SKrishna Gudipati * 5901a36c61f9SKrishna Gudipati * @returns None 5902a36c61f9SKrishna Gudipati */ 5903a36c61f9SKrishna Gudipati bfa_status_t 5904a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport) 5905a36c61f9SKrishna Gudipati { 5906a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START); 5907a36c61f9SKrishna Gudipati 5908a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5909a36c61f9SKrishna Gudipati } 5910a36c61f9SKrishna Gudipati 59115fbe25c7SJing Huang /* 5912a36c61f9SKrishna Gudipati * Use this function quiese the vport object. This function will return 5913a36c61f9SKrishna Gudipati * immediately, when the vport is actually stopped, the 5914a36c61f9SKrishna Gudipati * bfa_drv_vport_stop_cb() will be called. 5915a36c61f9SKrishna Gudipati * 5916a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 5917a36c61f9SKrishna Gudipati * 5918a36c61f9SKrishna Gudipati * return None 5919a36c61f9SKrishna Gudipati */ 5920a36c61f9SKrishna Gudipati bfa_status_t 5921a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) 5922a36c61f9SKrishna Gudipati { 5923a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 5924a36c61f9SKrishna Gudipati 5925a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5926a36c61f9SKrishna Gudipati } 5927a36c61f9SKrishna Gudipati 59285fbe25c7SJing Huang /* 5929a36c61f9SKrishna Gudipati * Use this function to delete a vport object. Fabric object should 5930a36c61f9SKrishna Gudipati * be stopped before this function call. 5931a36c61f9SKrishna Gudipati * 5932a36c61f9SKrishna Gudipati * !!!!!!! Donot invoke this from within FCS !!!!!!! 5933a36c61f9SKrishna Gudipati * 5934a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 5935a36c61f9SKrishna Gudipati * 5936a36c61f9SKrishna Gudipati * return None 5937a36c61f9SKrishna Gudipati */ 5938a36c61f9SKrishna Gudipati bfa_status_t 5939a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) 5940a36c61f9SKrishna Gudipati { 5941a36c61f9SKrishna Gudipati 5942a36c61f9SKrishna Gudipati if (vport->lport.port_cfg.preboot_vp) 5943a36c61f9SKrishna Gudipati return BFA_STATUS_PBC; 5944a36c61f9SKrishna Gudipati 5945a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 5946a36c61f9SKrishna Gudipati 5947a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5948a36c61f9SKrishna Gudipati } 5949a36c61f9SKrishna Gudipati 59505fbe25c7SJing Huang /* 5951a36c61f9SKrishna Gudipati * Use this function to get vport's current status info. 5952a36c61f9SKrishna Gudipati * 5953a36c61f9SKrishna Gudipati * param[in] vport pointer to bfa_fcs_vport_t. 5954a36c61f9SKrishna Gudipati * param[out] attr pointer to return vport attributes 5955a36c61f9SKrishna Gudipati * 5956a36c61f9SKrishna Gudipati * return None 5957a36c61f9SKrishna Gudipati */ 5958a36c61f9SKrishna Gudipati void 5959a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, 5960a36c61f9SKrishna Gudipati struct bfa_vport_attr_s *attr) 5961a36c61f9SKrishna Gudipati { 5962a36c61f9SKrishna Gudipati if (vport == NULL || attr == NULL) 5963a36c61f9SKrishna Gudipati return; 5964a36c61f9SKrishna Gudipati 59656a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_vport_attr_s)); 5966a36c61f9SKrishna Gudipati 5967a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr); 5968a36c61f9SKrishna Gudipati attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm); 5969a36c61f9SKrishna Gudipati } 5970a36c61f9SKrishna Gudipati 5971a36c61f9SKrishna Gudipati 59725fbe25c7SJing Huang /* 5973a36c61f9SKrishna Gudipati * Lookup a virtual port. Excludes base port from lookup. 5974a36c61f9SKrishna Gudipati */ 5975a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s * 5976a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn) 5977a36c61f9SKrishna Gudipati { 5978a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 5979a36c61f9SKrishna Gudipati struct bfa_fcs_fabric_s *fabric; 5980a36c61f9SKrishna Gudipati 5981a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5982a36c61f9SKrishna Gudipati bfa_trc(fcs, vpwwn); 5983a36c61f9SKrishna Gudipati 5984a36c61f9SKrishna Gudipati fabric = bfa_fcs_vf_lookup(fcs, vf_id); 5985a36c61f9SKrishna Gudipati if (!fabric) { 5986a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5987a36c61f9SKrishna Gudipati return NULL; 5988a36c61f9SKrishna Gudipati } 5989a36c61f9SKrishna Gudipati 5990a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn); 5991a36c61f9SKrishna Gudipati return vport; 5992a36c61f9SKrishna Gudipati } 5993a36c61f9SKrishna Gudipati 59945fbe25c7SJing Huang /* 5995a36c61f9SKrishna Gudipati * FDISC Response 5996a36c61f9SKrishna Gudipati */ 5997a36c61f9SKrishna Gudipati void 5998a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) 5999a36c61f9SKrishna Gudipati { 6000a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6001a36c61f9SKrishna Gudipati 6002a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6003a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), status); 6004a36c61f9SKrishna Gudipati 6005a36c61f9SKrishna Gudipati switch (status) { 6006a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 6007a36c61f9SKrishna Gudipati /* 6008b595076aSUwe Kleine-König * Initialize the V-Port fields 6009a36c61f9SKrishna Gudipati */ 6010f7f73812SMaggie Zhang __vport_fcid(vport) = vport->lps->lp_pid; 6011a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_accepts++; 6012a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6013a36c61f9SKrishna Gudipati break; 6014a36c61f9SKrishna Gudipati 6015a36c61f9SKrishna Gudipati case BFA_STATUS_INVALID_MAC: 6016a36c61f9SKrishna Gudipati /* Only for CNA */ 6017a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6018a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6019a36c61f9SKrishna Gudipati 6020a36c61f9SKrishna Gudipati break; 6021a36c61f9SKrishna Gudipati 6022a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 6023f7f73812SMaggie Zhang switch (vport->lps->ext_status) { 6024a36c61f9SKrishna Gudipati case BFA_EPROTO_BAD_ACCEPT: 6025a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6026a36c61f9SKrishna Gudipati break; 6027a36c61f9SKrishna Gudipati 6028a36c61f9SKrishna Gudipati case BFA_EPROTO_UNKNOWN_RSP: 6029a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_unknown_rsp++; 6030a36c61f9SKrishna Gudipati break; 6031a36c61f9SKrishna Gudipati 6032a36c61f9SKrishna Gudipati default: 6033a36c61f9SKrishna Gudipati break; 6034a36c61f9SKrishna Gudipati } 6035a36c61f9SKrishna Gudipati 6036a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6037a36c61f9SKrishna Gudipati break; 6038a36c61f9SKrishna Gudipati 6039a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 6040a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rejects++; 6041a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(vport); 6042a36c61f9SKrishna Gudipati break; 6043a36c61f9SKrishna Gudipati 6044a36c61f9SKrishna Gudipati default: 6045a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rsp_err++; 6046a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6047a36c61f9SKrishna Gudipati } 6048a36c61f9SKrishna Gudipati } 6049a36c61f9SKrishna Gudipati 60505fbe25c7SJing Huang /* 6051a36c61f9SKrishna Gudipati * LOGO response 6052a36c61f9SKrishna Gudipati */ 6053a36c61f9SKrishna Gudipati void 6054a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) 6055a36c61f9SKrishna Gudipati { 6056a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6057a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6058a36c61f9SKrishna Gudipati } 6059a36c61f9SKrishna Gudipati 60605fbe25c7SJing Huang /* 6061a36c61f9SKrishna Gudipati * Received clear virtual link 6062a36c61f9SKrishna Gudipati */ 6063a36c61f9SKrishna Gudipati void 6064a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg) 6065a36c61f9SKrishna Gudipati { 6066a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6067a36c61f9SKrishna Gudipati 6068a36c61f9SKrishna Gudipati /* Send an Offline followed by an ONLINE */ 6069a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 6070a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 6071a36c61f9SKrishna Gudipati } 6072