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); 134881c1b3cSKrishna Gudipati else 135881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 136dd5aaf45SKrishna Gudipati break; 137dd5aaf45SKrishna Gudipati 1383e98cc01SJing Huang case BFA_FCS_PORT_SM_OFFLINE: 1393e98cc01SJing Huang break; 1403e98cc01SJing Huang 1417725ccfdSJing Huang default: 142e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1437725ccfdSJing Huang } 1447725ccfdSJing Huang } 1457725ccfdSJing Huang 1467725ccfdSJing Huang static void 147a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online( 148a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 149a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1507725ccfdSJing Huang { 1517725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 1527725ccfdSJing Huang struct list_head *qe, *qen; 1537725ccfdSJing Huang 1547725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1557725ccfdSJing Huang bfa_trc(port->fcs, event); 1567725ccfdSJing Huang 1577725ccfdSJing Huang switch (event) { 1587725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 159a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_offline); 160a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(port); 1617725ccfdSJing Huang break; 1627725ccfdSJing Huang 163dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 164dd5aaf45SKrishna Gudipati __port_action[port->fabric->fab_type].offline(port); 165dd5aaf45SKrishna Gudipati 166dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 167dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 168dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 169dd5aaf45SKrishna Gudipati if (port->vport) 170dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 171881c1b3cSKrishna Gudipati else 172881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 173dd5aaf45SKrishna Gudipati } else { 174dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 175dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 176dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 177dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 178dd5aaf45SKrishna Gudipati } 179dd5aaf45SKrishna Gudipati } 180dd5aaf45SKrishna Gudipati break; 181dd5aaf45SKrishna Gudipati 1827725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 1837725ccfdSJing Huang 1847725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 1857725ccfdSJing Huang 1867725ccfdSJing Huang if (port->num_rports == 0) { 187a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 188a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 1897725ccfdSJing Huang } else { 190a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 1917725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 1927725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 193f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1947725ccfdSJing Huang } 1957725ccfdSJing Huang } 1967725ccfdSJing Huang break; 1977725ccfdSJing Huang 1987725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 1997725ccfdSJing Huang break; 2007725ccfdSJing Huang 2017725ccfdSJing Huang default: 202e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2037725ccfdSJing Huang } 2047725ccfdSJing Huang } 2057725ccfdSJing Huang 2067725ccfdSJing Huang static void 207a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline( 208a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 209a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 2107725ccfdSJing Huang { 2117725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 2127725ccfdSJing Huang struct list_head *qe, *qen; 2137725ccfdSJing Huang 2147725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 2157725ccfdSJing Huang bfa_trc(port->fcs, event); 2167725ccfdSJing Huang 2177725ccfdSJing Huang switch (event) { 2187725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 219a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 220a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 2217725ccfdSJing Huang break; 2227725ccfdSJing Huang 223dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 224dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 225dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 226dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 227dd5aaf45SKrishna Gudipati if (port->vport) 228dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 229881c1b3cSKrishna Gudipati else 230881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 231dd5aaf45SKrishna Gudipati } else { 232dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 233dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 234dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 235dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 236dd5aaf45SKrishna Gudipati } 237dd5aaf45SKrishna Gudipati } 238dd5aaf45SKrishna Gudipati break; 239dd5aaf45SKrishna Gudipati 2407725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 2417725ccfdSJing Huang if (port->num_rports == 0) { 242a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 243a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2447725ccfdSJing Huang } else { 245a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 2467725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 2477725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 248f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 2497725ccfdSJing Huang } 2507725ccfdSJing Huang } 2517725ccfdSJing Huang break; 2527725ccfdSJing Huang 2537725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2547725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 2557725ccfdSJing Huang break; 2567725ccfdSJing Huang 2577725ccfdSJing Huang default: 258e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2597725ccfdSJing Huang } 2607725ccfdSJing Huang } 2617725ccfdSJing Huang 2627725ccfdSJing Huang static void 263dd5aaf45SKrishna Gudipati bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 264dd5aaf45SKrishna Gudipati enum bfa_fcs_lport_event event) 265dd5aaf45SKrishna Gudipati { 266dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 267dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, event); 268dd5aaf45SKrishna Gudipati 269dd5aaf45SKrishna Gudipati switch (event) { 270dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_DELRPORT: 271dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 272dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 273dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 274dd5aaf45SKrishna Gudipati if (port->vport) 275dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 276881c1b3cSKrishna Gudipati else 277881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 278dd5aaf45SKrishna Gudipati } 279dd5aaf45SKrishna Gudipati break; 280dd5aaf45SKrishna Gudipati 281dd5aaf45SKrishna Gudipati default: 282dd5aaf45SKrishna Gudipati bfa_sm_fault(port->fcs, event); 283dd5aaf45SKrishna Gudipati } 284dd5aaf45SKrishna Gudipati } 285dd5aaf45SKrishna Gudipati 286dd5aaf45SKrishna Gudipati static void 287a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting( 288a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 289a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 2907725ccfdSJing Huang { 2917725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 2927725ccfdSJing Huang bfa_trc(port->fcs, event); 2937725ccfdSJing Huang 2947725ccfdSJing Huang switch (event) { 2957725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2967725ccfdSJing Huang if (port->num_rports == 0) { 297a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 298a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2997725ccfdSJing Huang } 3007725ccfdSJing Huang break; 3017725ccfdSJing Huang 3027725ccfdSJing Huang default: 303e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 3047725ccfdSJing Huang } 3057725ccfdSJing Huang } 3067725ccfdSJing Huang 3075fbe25c7SJing Huang /* 3087725ccfdSJing Huang * fcs_port_pvt 3097725ccfdSJing Huang */ 3107725ccfdSJing Huang 3117725ccfdSJing Huang /* 3127826f304SKrishna Gudipati * Send AEN notification 3137826f304SKrishna Gudipati */ 3147826f304SKrishna Gudipati static void 3157826f304SKrishna Gudipati bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port, 3167826f304SKrishna Gudipati enum bfa_lport_aen_event event) 3177826f304SKrishna Gudipati { 3187826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 3197826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 3207826f304SKrishna Gudipati 3217826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 3227826f304SKrishna Gudipati if (!aen_entry) 3237826f304SKrishna Gudipati return; 3247826f304SKrishna Gudipati 3257826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 3267826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 3277826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 3287826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 3297826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 3307826f304SKrishna Gudipati 3317826f304SKrishna Gudipati /* Send the AEN notification */ 3327826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 3337826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 3347826f304SKrishna Gudipati } 3357826f304SKrishna Gudipati 3367826f304SKrishna Gudipati /* 3377725ccfdSJing Huang * Send a LS reject 3387725ccfdSJing Huang */ 3397725ccfdSJing Huang static void 340a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 3417725ccfdSJing Huang u8 reason_code, u8 reason_code_expl) 3427725ccfdSJing Huang { 3437725ccfdSJing Huang struct fchs_s fchs; 3447725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 3457725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 3467725ccfdSJing Huang int len; 3477725ccfdSJing Huang 348a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 3497725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 3507725ccfdSJing Huang 351c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 3527725ccfdSJing Huang if (!fcxp) 3537725ccfdSJing Huang return; 3547725ccfdSJing Huang 355a36c61f9SKrishna Gudipati len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 356a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 357a36c61f9SKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 3587725ccfdSJing Huang 3597725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 3607725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 3617725ccfdSJing Huang FC_MAX_PDUSZ, 0); 3627725ccfdSJing Huang } 3637725ccfdSJing Huang 3645fbe25c7SJing Huang /* 365d7be54ccSKrishna Gudipati * Send a FCCT Reject 366d7be54ccSKrishna Gudipati */ 367d7be54ccSKrishna Gudipati static void 368d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port, 369d7be54ccSKrishna Gudipati struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl) 370d7be54ccSKrishna Gudipati { 371d7be54ccSKrishna Gudipati struct fchs_s fchs; 372d7be54ccSKrishna Gudipati struct bfa_fcxp_s *fcxp; 373d7be54ccSKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 374d7be54ccSKrishna Gudipati int len; 375d7be54ccSKrishna Gudipati struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1); 376d7be54ccSKrishna Gudipati struct ct_hdr_s *ct_hdr; 377d7be54ccSKrishna Gudipati 378d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 379d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 380d7be54ccSKrishna Gudipati 381c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 382d7be54ccSKrishna Gudipati if (!fcxp) 383d7be54ccSKrishna Gudipati return; 384d7be54ccSKrishna Gudipati 385d7be54ccSKrishna Gudipati ct_hdr = bfa_fcxp_get_reqbuf(fcxp); 386d7be54ccSKrishna Gudipati ct_hdr->gs_type = rx_cthdr->gs_type; 387d7be54ccSKrishna Gudipati ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type; 388d7be54ccSKrishna Gudipati 389d7be54ccSKrishna Gudipati len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id, 390d7be54ccSKrishna Gudipati bfa_fcs_lport_get_fcid(port), 391d7be54ccSKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 392d7be54ccSKrishna Gudipati 393d7be54ccSKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 394d7be54ccSKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 395d7be54ccSKrishna Gudipati FC_MAX_PDUSZ, 0); 396d7be54ccSKrishna Gudipati } 397d7be54ccSKrishna Gudipati 398d7be54ccSKrishna Gudipati /* 3997725ccfdSJing Huang * Process incoming plogi from a remote port. 4007725ccfdSJing Huang */ 4017725ccfdSJing Huang static void 402a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 403a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi) 4047725ccfdSJing Huang { 4057725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 4067725ccfdSJing Huang 4077725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 4087725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4097725ccfdSJing Huang 4107725ccfdSJing Huang /* 4117725ccfdSJing Huang * If min cfg mode is enabled, drop any incoming PLOGIs 4127725ccfdSJing Huang */ 4137725ccfdSJing Huang if (__fcs_min_cfg(port->fcs)) { 4147725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4157725ccfdSJing Huang return; 4167725ccfdSJing Huang } 4177725ccfdSJing Huang 4187725ccfdSJing Huang if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) { 4197725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4207725ccfdSJing Huang /* 4217725ccfdSJing Huang * send a LS reject 4227725ccfdSJing Huang */ 423a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4247725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4257725ccfdSJing Huang FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS); 4267725ccfdSJing Huang return; 4277725ccfdSJing Huang } 4287725ccfdSJing Huang 4295fbe25c7SJing Huang /* 4307725ccfdSJing Huang * Direct Attach P2P mode : verify address assigned by the r-port. 4317725ccfdSJing Huang */ 432a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 433a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 434a36c61f9SKrishna Gudipati (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4357725ccfdSJing Huang if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) { 436a36c61f9SKrishna Gudipati /* Address assigned to us cannot be a WKA */ 437a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4387725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4397725ccfdSJing Huang FC_LS_RJT_EXP_INVALID_NPORT_ID); 4407725ccfdSJing Huang return; 4417725ccfdSJing Huang } 4427725ccfdSJing Huang port->pid = rx_fchs->d_id; 443b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4447725ccfdSJing Huang } 4457725ccfdSJing Huang 4465fbe25c7SJing Huang /* 4477725ccfdSJing Huang * First, check if we know the device by pwwn. 4487725ccfdSJing Huang */ 449a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name); 4507725ccfdSJing Huang if (rport) { 4515fbe25c7SJing Huang /* 452a36c61f9SKrishna Gudipati * Direct Attach P2P mode : handle address assigned by r-port. 4537725ccfdSJing Huang */ 454a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 455a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 4567725ccfdSJing Huang (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4577725ccfdSJing Huang port->pid = rx_fchs->d_id; 458b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4597725ccfdSJing Huang rport->pid = rx_fchs->s_id; 4607725ccfdSJing Huang } 4617725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 4627725ccfdSJing Huang return; 4637725ccfdSJing Huang } 4647725ccfdSJing Huang 4655fbe25c7SJing Huang /* 4667725ccfdSJing Huang * Next, lookup rport by PID. 4677725ccfdSJing Huang */ 468a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id); 4697725ccfdSJing Huang if (!rport) { 4705fbe25c7SJing Huang /* 4717725ccfdSJing Huang * Inbound PLOGI from a new device. 4727725ccfdSJing Huang */ 4737725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 4747725ccfdSJing Huang return; 4757725ccfdSJing Huang } 4767725ccfdSJing Huang 4775fbe25c7SJing Huang /* 4787725ccfdSJing Huang * Rport is known only by PID. 4797725ccfdSJing Huang */ 4807725ccfdSJing Huang if (rport->pwwn) { 4815fbe25c7SJing Huang /* 4827725ccfdSJing Huang * This is a different device with the same pid. Old device 4837725ccfdSJing Huang * disappeared. Send implicit LOGO to old device. 4847725ccfdSJing Huang */ 485d4b671c5SJing Huang WARN_ON(rport->pwwn == plogi->port_name); 486f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 4877725ccfdSJing Huang 4885fbe25c7SJing Huang /* 4897725ccfdSJing Huang * Inbound PLOGI from a new device (with old PID). 4907725ccfdSJing Huang */ 4917725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 4927725ccfdSJing Huang return; 4937725ccfdSJing Huang } 4947725ccfdSJing Huang 4955fbe25c7SJing Huang /* 4967725ccfdSJing Huang * PLOGI crossing each other. 4977725ccfdSJing Huang */ 498d4b671c5SJing Huang WARN_ON(rport->pwwn != WWN_NULL); 4997725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 5007725ccfdSJing Huang } 5017725ccfdSJing Huang 5027725ccfdSJing Huang /* 5037725ccfdSJing Huang * Process incoming ECHO. 5047725ccfdSJing Huang * Since it does not require a login, it is processed here. 5057725ccfdSJing Huang */ 5067725ccfdSJing Huang static void 507a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5087725ccfdSJing Huang struct fc_echo_s *echo, u16 rx_len) 5097725ccfdSJing Huang { 5107725ccfdSJing Huang struct fchs_s fchs; 5117725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5127725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5137725ccfdSJing Huang int len, pyld_len; 5147725ccfdSJing Huang 5157725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5167725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5177725ccfdSJing Huang 518c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5197725ccfdSJing Huang if (!fcxp) 5207725ccfdSJing Huang return; 5217725ccfdSJing Huang 522a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 523a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 524a36c61f9SKrishna Gudipati rx_fchs->ox_id); 5257725ccfdSJing Huang 5267725ccfdSJing Huang /* 5277725ccfdSJing Huang * Copy the payload (if any) from the echo frame 5287725ccfdSJing Huang */ 5297725ccfdSJing Huang pyld_len = rx_len - sizeof(struct fchs_s); 530a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_len); 5317725ccfdSJing Huang bfa_trc(port->fcs, pyld_len); 5327725ccfdSJing Huang 5337725ccfdSJing Huang if (pyld_len > len) 5347725ccfdSJing Huang memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) + 5357725ccfdSJing Huang sizeof(struct fc_echo_s), (echo + 1), 5367725ccfdSJing Huang (pyld_len - sizeof(struct fc_echo_s))); 5377725ccfdSJing Huang 5387725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5397725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL, 5407725ccfdSJing Huang FC_MAX_PDUSZ, 0); 5417725ccfdSJing Huang } 5427725ccfdSJing Huang 5437725ccfdSJing Huang /* 5447725ccfdSJing Huang * Process incoming RNID. 5457725ccfdSJing Huang * Since it does not require a login, it is processed here. 5467725ccfdSJing Huang */ 5477725ccfdSJing Huang static void 548a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5497725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 rx_len) 5507725ccfdSJing Huang { 5517725ccfdSJing Huang struct fc_rnid_common_id_data_s common_id_data; 5527725ccfdSJing Huang struct fc_rnid_general_topology_data_s gen_topo_data; 5537725ccfdSJing Huang struct fchs_s fchs; 5547725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5557725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5567725ccfdSJing Huang u16 len; 5577725ccfdSJing Huang u32 data_format; 5587725ccfdSJing Huang 5597725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5607725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5617725ccfdSJing Huang bfa_trc(port->fcs, rx_len); 5627725ccfdSJing Huang 563c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5647725ccfdSJing Huang if (!fcxp) 5657725ccfdSJing Huang return; 5667725ccfdSJing Huang 5677725ccfdSJing Huang /* 5687725ccfdSJing Huang * Check Node Indentification Data Format 5697725ccfdSJing Huang * We only support General Topology Discovery Format. 5707725ccfdSJing Huang * For any other requested Data Formats, we return Common Node Id Data 5717725ccfdSJing Huang * only, as per FC-LS. 5727725ccfdSJing Huang */ 5737725ccfdSJing Huang bfa_trc(port->fcs, rnid->node_id_data_format); 5747725ccfdSJing Huang if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 5757725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY; 5767725ccfdSJing Huang /* 5777725ccfdSJing Huang * Get General topology data for this port 5787725ccfdSJing Huang */ 5797725ccfdSJing Huang bfa_fs_port_get_gen_topo_data(port, &gen_topo_data); 5807725ccfdSJing Huang } else { 5817725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_COMMON; 5827725ccfdSJing Huang } 5837725ccfdSJing Huang 5847725ccfdSJing Huang /* 5857725ccfdSJing Huang * Copy the Node Id Info 5867725ccfdSJing Huang */ 587a36c61f9SKrishna Gudipati common_id_data.port_name = bfa_fcs_lport_get_pwwn(port); 588a36c61f9SKrishna Gudipati common_id_data.node_name = bfa_fcs_lport_get_nwwn(port); 5897725ccfdSJing Huang 590a36c61f9SKrishna Gudipati len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 591a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 592a36c61f9SKrishna Gudipati rx_fchs->ox_id, data_format, &common_id_data, 593a36c61f9SKrishna Gudipati &gen_topo_data); 5947725ccfdSJing Huang 5957725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5967725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 5977725ccfdSJing Huang FC_MAX_PDUSZ, 0); 5987725ccfdSJing Huang } 5997725ccfdSJing Huang 6007725ccfdSJing Huang /* 6017725ccfdSJing Huang * Fill out General Topolpgy Discovery Data for RNID ELS. 6027725ccfdSJing Huang */ 6037725ccfdSJing Huang static void 604a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 6057725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data) 6067725ccfdSJing Huang { 6076a18b167SJing Huang memset(gen_topo_data, 0, 6087725ccfdSJing Huang sizeof(struct fc_rnid_general_topology_data_s)); 6097725ccfdSJing Huang 610ba816ea8SJing Huang gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST); 6117725ccfdSJing Huang gen_topo_data->phy_port_num = 0; /* @todo */ 612ba816ea8SJing Huang gen_topo_data->num_attached_nodes = cpu_to_be32(1); 6137725ccfdSJing Huang } 6147725ccfdSJing Huang 6157725ccfdSJing Huang static void 616a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) 6177725ccfdSJing Huang { 618a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 619a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 620a36c61f9SKrishna Gudipati 6217725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6227725ccfdSJing Huang 6237725ccfdSJing Huang __port_action[port->fabric->fab_type].init(port); 6247725ccfdSJing Huang __port_action[port->fabric->fab_type].online(port); 6257725ccfdSJing Huang 626a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 627a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 628a36c61f9SKrishna Gudipati "Logical port online: WWN = %s Role = %s\n", 629a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6307826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE); 631a36c61f9SKrishna Gudipati 632a36c61f9SKrishna Gudipati bfad->bfad_flags |= BFAD_PORT_ONLINE; 6337725ccfdSJing Huang } 6347725ccfdSJing Huang 6357725ccfdSJing Huang static void 636a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) 6377725ccfdSJing Huang { 6387725ccfdSJing Huang struct list_head *qe, *qen; 6397725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 640a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 641a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 6427725ccfdSJing Huang 6437725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6447725ccfdSJing Huang 6457725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 6467725ccfdSJing Huang 647a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 648f7f73812SMaggie Zhang if (bfa_sm_cmp_state(port->fabric, 6497826f304SKrishna Gudipati bfa_fcs_fabric_sm_online) == BFA_TRUE) { 650a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 651a36c61f9SKrishna Gudipati "Logical port lost fabric connectivity: WWN = %s Role = %s\n", 652a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6537826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT); 6547826f304SKrishna Gudipati } else { 655a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 656a36c61f9SKrishna Gudipati "Logical port taken offline: WWN = %s Role = %s\n", 657a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6587826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE); 6597826f304SKrishna Gudipati } 6607725ccfdSJing Huang 6617725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 6627725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 663f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 6647725ccfdSJing Huang } 6657725ccfdSJing Huang } 6667725ccfdSJing Huang 6677725ccfdSJing Huang static void 668a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port) 6697725ccfdSJing Huang { 670d4b671c5SJing Huang WARN_ON(1); 6717725ccfdSJing Huang } 6727725ccfdSJing Huang 6737725ccfdSJing Huang static void 674a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port) 6757725ccfdSJing Huang { 676d4b671c5SJing Huang WARN_ON(1); 6777725ccfdSJing Huang } 6787725ccfdSJing Huang 6797725ccfdSJing Huang static void 680a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port) 6817725ccfdSJing Huang { 682d4b671c5SJing Huang WARN_ON(1); 6837725ccfdSJing Huang } 6847725ccfdSJing Huang 6857725ccfdSJing Huang static void 686a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs) 6877725ccfdSJing Huang { 688a36c61f9SKrishna Gudipati struct fchs_s fchs; 689a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 690a36c61f9SKrishna Gudipati int len; 6917725ccfdSJing Huang 692a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 693a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 694a36c61f9SKrishna Gudipati 695c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 696a36c61f9SKrishna Gudipati if (!fcxp) 697a36c61f9SKrishna Gudipati return; 698a36c61f9SKrishna Gudipati 699a36c61f9SKrishna Gudipati len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 700a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 701a36c61f9SKrishna Gudipati rx_fchs->ox_id, 0); 702a36c61f9SKrishna Gudipati 703a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 704a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 705a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 706a36c61f9SKrishna Gudipati } 707a36c61f9SKrishna Gudipati static void 708a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) 709a36c61f9SKrishna Gudipati { 710a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 711a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 712a36c61f9SKrishna Gudipati 713a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 71488166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 715a36c61f9SKrishna Gudipati "Logical port deleted: WWN = %s Role = %s\n", 716a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 7177826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE); 718a36c61f9SKrishna Gudipati 719a36c61f9SKrishna Gudipati /* Base port will be deleted by the OS driver */ 72017c201b3SKrishna Gudipati if (port->vport) 7217725ccfdSJing Huang bfa_fcs_vport_delete_comp(port->vport); 72217c201b3SKrishna Gudipati else 723f7f73812SMaggie Zhang bfa_wc_down(&port->fabric->wc); 7247725ccfdSJing Huang } 7257725ccfdSJing Huang 7267725ccfdSJing Huang 7275fbe25c7SJing Huang /* 7287725ccfdSJing Huang * Unsolicited frame receive handling. 7297725ccfdSJing Huang */ 7307725ccfdSJing Huang void 731a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, 732a36c61f9SKrishna Gudipati struct fchs_s *fchs, u16 len) 7337725ccfdSJing Huang { 7347725ccfdSJing Huang u32 pid = fchs->s_id; 7357725ccfdSJing Huang struct bfa_fcs_rport_s *rport = NULL; 7367725ccfdSJing Huang struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 7377725ccfdSJing Huang 7387725ccfdSJing Huang bfa_stats(lport, uf_recvs); 73915821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->type); 7407725ccfdSJing Huang 741a36c61f9SKrishna Gudipati if (!bfa_fcs_lport_is_online(lport)) { 7427725ccfdSJing Huang bfa_stats(lport, uf_recv_drops); 7437725ccfdSJing Huang return; 7447725ccfdSJing Huang } 7457725ccfdSJing Huang 7465fbe25c7SJing Huang /* 7477725ccfdSJing Huang * First, handle ELSs that donot require a login. 7487725ccfdSJing Huang */ 7497725ccfdSJing Huang /* 7507725ccfdSJing Huang * Handle PLOGI first 7517725ccfdSJing Huang */ 7527725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && 7537725ccfdSJing Huang (els_cmd->els_code == FC_ELS_PLOGI)) { 754a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd); 7557725ccfdSJing Huang return; 7567725ccfdSJing Huang } 7577725ccfdSJing Huang 7587725ccfdSJing Huang /* 7597725ccfdSJing Huang * Handle ECHO separately. 7607725ccfdSJing Huang */ 7617725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) { 762a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(lport, fchs, 7637725ccfdSJing Huang (struct fc_echo_s *)els_cmd, len); 7647725ccfdSJing Huang return; 7657725ccfdSJing Huang } 7667725ccfdSJing Huang 7677725ccfdSJing Huang /* 7687725ccfdSJing Huang * Handle RNID separately. 7697725ccfdSJing Huang */ 7707725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) { 771a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(lport, fchs, 7727725ccfdSJing Huang (struct fc_rnid_cmd_s *) els_cmd, len); 7737725ccfdSJing Huang return; 7747725ccfdSJing Huang } 7757725ccfdSJing Huang 776a36c61f9SKrishna Gudipati if (fchs->type == FC_TYPE_BLS) { 777a36c61f9SKrishna Gudipati if ((fchs->routing == FC_RTG_BASIC_LINK) && 778a36c61f9SKrishna Gudipati (fchs->cat_info == FC_CAT_ABTS)) 779a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(lport, fchs); 780a36c61f9SKrishna Gudipati return; 781a36c61f9SKrishna Gudipati } 782d7be54ccSKrishna Gudipati 783d7be54ccSKrishna Gudipati if (fchs->type == FC_TYPE_SERVICES) { 784d7be54ccSKrishna Gudipati /* 785d7be54ccSKrishna Gudipati * Unhandled FC-GS frames. Send a FC-CT Reject 786d7be54ccSKrishna Gudipati */ 787d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP, 788d7be54ccSKrishna Gudipati CT_NS_EXP_NOADDITIONAL); 789d7be54ccSKrishna Gudipati return; 790d7be54ccSKrishna Gudipati } 791d7be54ccSKrishna Gudipati 7925fbe25c7SJing Huang /* 7937725ccfdSJing Huang * look for a matching remote port ID 7947725ccfdSJing Huang */ 795a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(lport, pid); 7967725ccfdSJing Huang if (rport) { 7977725ccfdSJing Huang bfa_trc(rport->fcs, fchs->s_id); 7987725ccfdSJing Huang bfa_trc(rport->fcs, fchs->d_id); 7997725ccfdSJing Huang bfa_trc(rport->fcs, fchs->type); 8007725ccfdSJing Huang 8017725ccfdSJing Huang bfa_fcs_rport_uf_recv(rport, fchs, len); 8027725ccfdSJing Huang return; 8037725ccfdSJing Huang } 8047725ccfdSJing Huang 8055fbe25c7SJing Huang /* 8067725ccfdSJing Huang * Only handles ELS frames for now. 8077725ccfdSJing Huang */ 8087725ccfdSJing Huang if (fchs->type != FC_TYPE_ELS) { 80915821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->s_id); 81015821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->d_id); 81115821f05SKrishna Gudipati /* ignore type FC_TYPE_FC_FSS */ 81215821f05SKrishna Gudipati if (fchs->type != FC_TYPE_FC_FSS) 81315821f05SKrishna Gudipati bfa_sm_fault(lport->fcs, fchs->type); 8147725ccfdSJing Huang return; 8157725ccfdSJing Huang } 8167725ccfdSJing Huang 8177725ccfdSJing Huang bfa_trc(lport->fcs, els_cmd->els_code); 8187725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_RSCN) { 819a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(lport, fchs, len); 8207725ccfdSJing Huang return; 8217725ccfdSJing Huang } 8227725ccfdSJing Huang 8237725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_LOGO) { 8245fbe25c7SJing Huang /* 8257725ccfdSJing Huang * @todo Handle LOGO frames received. 8267725ccfdSJing Huang */ 8277725ccfdSJing Huang return; 8287725ccfdSJing Huang } 8297725ccfdSJing Huang 8307725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_PRLI) { 8315fbe25c7SJing Huang /* 8327725ccfdSJing Huang * @todo Handle PRLI frames received. 8337725ccfdSJing Huang */ 8347725ccfdSJing Huang return; 8357725ccfdSJing Huang } 8367725ccfdSJing Huang 8375fbe25c7SJing Huang /* 8387725ccfdSJing Huang * Unhandled ELS frames. Send a LS_RJT. 8397725ccfdSJing Huang */ 840a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP, 8417725ccfdSJing Huang FC_LS_RJT_EXP_NO_ADDL_INFO); 8427725ccfdSJing Huang 8437725ccfdSJing Huang } 8447725ccfdSJing Huang 8455fbe25c7SJing Huang /* 8467725ccfdSJing Huang * PID based Lookup for a R-Port in the Port R-Port Queue 8477725ccfdSJing Huang */ 8487725ccfdSJing Huang struct bfa_fcs_rport_s * 849a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) 8507725ccfdSJing Huang { 8517725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 8527725ccfdSJing Huang struct list_head *qe; 8537725ccfdSJing Huang 8547725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 8557725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 8567725ccfdSJing Huang if (rport->pid == pid) 8577725ccfdSJing Huang return rport; 8587725ccfdSJing Huang } 8597725ccfdSJing Huang 8607725ccfdSJing Huang bfa_trc(port->fcs, pid); 8617725ccfdSJing Huang return NULL; 8627725ccfdSJing Huang } 8637725ccfdSJing Huang 8645fbe25c7SJing Huang /* 865ee1a4a42SKrishna Gudipati * OLD_PID based Lookup for a R-Port in the Port R-Port Queue 866ee1a4a42SKrishna Gudipati */ 867ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s * 868ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid) 869ee1a4a42SKrishna Gudipati { 870ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *rport; 871ee1a4a42SKrishna Gudipati struct list_head *qe; 872ee1a4a42SKrishna Gudipati 873ee1a4a42SKrishna Gudipati list_for_each(qe, &port->rport_q) { 874ee1a4a42SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 875ee1a4a42SKrishna Gudipati if (rport->old_pid == pid) 876ee1a4a42SKrishna Gudipati return rport; 877ee1a4a42SKrishna Gudipati } 878ee1a4a42SKrishna Gudipati 879ee1a4a42SKrishna Gudipati bfa_trc(port->fcs, pid); 880ee1a4a42SKrishna Gudipati return NULL; 881ee1a4a42SKrishna Gudipati } 882ee1a4a42SKrishna Gudipati 883ee1a4a42SKrishna Gudipati /* 8847725ccfdSJing Huang * PWWN based Lookup for a R-Port in the Port R-Port Queue 8857725ccfdSJing Huang */ 8867725ccfdSJing Huang struct bfa_fcs_rport_s * 887a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn) 8887725ccfdSJing Huang { 8897725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 8907725ccfdSJing Huang struct list_head *qe; 8917725ccfdSJing Huang 8927725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 8937725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 8947725ccfdSJing Huang if (wwn_is_equal(rport->pwwn, pwwn)) 8957725ccfdSJing Huang return rport; 8967725ccfdSJing Huang } 8977725ccfdSJing Huang 8987725ccfdSJing Huang bfa_trc(port->fcs, pwwn); 899f8ceafdeSJing Huang return NULL; 9007725ccfdSJing Huang } 9017725ccfdSJing Huang 9025fbe25c7SJing Huang /* 9037725ccfdSJing Huang * NWWN based Lookup for a R-Port in the Port R-Port Queue 9047725ccfdSJing Huang */ 9057725ccfdSJing Huang struct bfa_fcs_rport_s * 906a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) 9077725ccfdSJing Huang { 9087725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 9097725ccfdSJing Huang struct list_head *qe; 9107725ccfdSJing Huang 9117725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 9127725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 9137725ccfdSJing Huang if (wwn_is_equal(rport->nwwn, nwwn)) 9147725ccfdSJing Huang return rport; 9157725ccfdSJing Huang } 9167725ccfdSJing Huang 9177725ccfdSJing Huang bfa_trc(port->fcs, nwwn); 918f8ceafdeSJing Huang return NULL; 9197725ccfdSJing Huang } 9207725ccfdSJing Huang 9215fbe25c7SJing Huang /* 922ee1a4a42SKrishna Gudipati * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue 923ee1a4a42SKrishna Gudipati */ 924ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s * 925ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port, 926ee1a4a42SKrishna Gudipati wwn_t pwwn, u32 pid) 927ee1a4a42SKrishna Gudipati { 928ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *rport; 929ee1a4a42SKrishna Gudipati struct list_head *qe; 930ee1a4a42SKrishna Gudipati 931ee1a4a42SKrishna Gudipati list_for_each(qe, &port->rport_q) { 932ee1a4a42SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 933ee1a4a42SKrishna Gudipati if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid) 934ee1a4a42SKrishna Gudipati return rport; 935ee1a4a42SKrishna Gudipati } 936ee1a4a42SKrishna Gudipati 937ee1a4a42SKrishna Gudipati bfa_trc(port->fcs, pwwn); 938ee1a4a42SKrishna Gudipati return NULL; 939ee1a4a42SKrishna Gudipati } 940ee1a4a42SKrishna Gudipati 941ee1a4a42SKrishna Gudipati /* 9427725ccfdSJing Huang * Called by rport module when new rports are discovered. 9437725ccfdSJing Huang */ 9447725ccfdSJing Huang void 945a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport( 946a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 9477725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 9487725ccfdSJing Huang { 9497725ccfdSJing Huang list_add_tail(&rport->qe, &port->rport_q); 9507725ccfdSJing Huang port->num_rports++; 9517725ccfdSJing Huang } 9527725ccfdSJing Huang 9535fbe25c7SJing Huang /* 9547725ccfdSJing Huang * Called by rport module to when rports are deleted. 9557725ccfdSJing Huang */ 9567725ccfdSJing Huang void 957a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport( 958a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 9597725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 9607725ccfdSJing Huang { 961d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport)); 9627725ccfdSJing Huang list_del(&rport->qe); 9637725ccfdSJing Huang port->num_rports--; 9647725ccfdSJing Huang 9657725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT); 9667725ccfdSJing Huang } 9677725ccfdSJing Huang 9685fbe25c7SJing Huang /* 9697725ccfdSJing Huang * Called by fabric for base port when fabric login is complete. 9707725ccfdSJing Huang * Called by vport for virtual ports when FDISC is complete. 9717725ccfdSJing Huang */ 9727725ccfdSJing Huang void 973a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port) 9747725ccfdSJing Huang { 9757725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE); 9767725ccfdSJing Huang } 9777725ccfdSJing Huang 9785fbe25c7SJing Huang /* 9797725ccfdSJing Huang * Called by fabric for base port when fabric goes offline. 9807725ccfdSJing Huang * Called by vport for virtual ports when virtual port becomes offline. 9817725ccfdSJing Huang */ 9827725ccfdSJing Huang void 983a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port) 9847725ccfdSJing Huang { 9857725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE); 9867725ccfdSJing Huang } 9877725ccfdSJing Huang 9885fbe25c7SJing Huang /* 989881c1b3cSKrishna Gudipati * Called by fabric for base port and by vport for virtual ports 990881c1b3cSKrishna Gudipati * when target mode driver is unloaded. 991881c1b3cSKrishna Gudipati */ 992881c1b3cSKrishna Gudipati void 993881c1b3cSKrishna Gudipati bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port) 994881c1b3cSKrishna Gudipati { 995881c1b3cSKrishna Gudipati bfa_sm_send_event(port, BFA_FCS_PORT_SM_STOP); 996881c1b3cSKrishna Gudipati } 997881c1b3cSKrishna Gudipati 998881c1b3cSKrishna Gudipati /* 9997725ccfdSJing Huang * Called by fabric to delete base lport and associated resources. 10007725ccfdSJing Huang * 10017725ccfdSJing Huang * Called by vport to delete lport and associated resources. Should call 10027725ccfdSJing Huang * bfa_fcs_vport_delete_comp() for vports on completion. 10037725ccfdSJing Huang */ 10047725ccfdSJing Huang void 1005a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port) 10067725ccfdSJing Huang { 10077725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE); 10087725ccfdSJing Huang } 10097725ccfdSJing Huang 10105fbe25c7SJing Huang /* 10117725ccfdSJing Huang * Return TRUE if port is online, else return FALSE 10127725ccfdSJing Huang */ 10137725ccfdSJing Huang bfa_boolean_t 1014a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port) 10157725ccfdSJing Huang { 1016a36c61f9SKrishna Gudipati return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online); 10177725ccfdSJing Huang } 10187725ccfdSJing Huang 10195fbe25c7SJing Huang /* 1020e6714324SKrishna Gudipati * Attach time initialization of logical ports. 10217725ccfdSJing Huang */ 10227725ccfdSJing Huang void 1023a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs, 1024a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_fcs_vport_s *vport) 10257725ccfdSJing Huang { 10267725ccfdSJing Huang lport->fcs = fcs; 10277725ccfdSJing Huang lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); 10287725ccfdSJing Huang lport->vport = vport; 10293fd45980SKrishna Gudipati lport->lp_tag = (vport) ? vport->lps->bfa_tag : 10303fd45980SKrishna Gudipati lport->fabric->lps->bfa_tag; 10317725ccfdSJing Huang 10327725ccfdSJing Huang INIT_LIST_HEAD(&lport->rport_q); 10337725ccfdSJing Huang lport->num_rports = 0; 1034e6714324SKrishna Gudipati } 10357725ccfdSJing Huang 10365fbe25c7SJing Huang /* 1037e6714324SKrishna Gudipati * Logical port initialization of base or virtual port. 1038e6714324SKrishna Gudipati * Called by fabric for base port or by vport for virtual ports. 1039e6714324SKrishna Gudipati */ 1040e6714324SKrishna Gudipati 1041e6714324SKrishna Gudipati void 1042a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, 1043a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *port_cfg) 1044e6714324SKrishna Gudipati { 1045e6714324SKrishna Gudipati struct bfa_fcs_vport_s *vport = lport->vport; 1046a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad; 1047a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 1048e6714324SKrishna Gudipati 10496a18b167SJing Huang lport->port_cfg = *port_cfg; 1050e6714324SKrishna Gudipati 1051a36c61f9SKrishna Gudipati lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport, 1052e6714324SKrishna Gudipati lport->port_cfg.roles, 10537725ccfdSJing Huang lport->fabric->vf_drv, 10547725ccfdSJing Huang vport ? vport->vport_drv : NULL); 1055e6714324SKrishna Gudipati 1056a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); 105788166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 1058a36c61f9SKrishna Gudipati "New logical port created: WWN = %s Role = %s\n", 1059a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 10607826f304SKrishna Gudipati bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW); 10617725ccfdSJing Huang 1062a36c61f9SKrishna Gudipati bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit); 10637725ccfdSJing Huang bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 10647725ccfdSJing Huang } 10657725ccfdSJing Huang 10665fbe25c7SJing Huang /* 10677725ccfdSJing Huang * fcs_lport_api 10687725ccfdSJing Huang */ 10697725ccfdSJing Huang 10707725ccfdSJing Huang void 1071a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr( 1072a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 1073a36c61f9SKrishna Gudipati struct bfa_lport_attr_s *port_attr) 10747725ccfdSJing Huang { 1075a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 10767725ccfdSJing Huang port_attr->pid = port->pid; 10777725ccfdSJing Huang else 10787725ccfdSJing Huang port_attr->pid = 0; 10797725ccfdSJing Huang 10807725ccfdSJing Huang port_attr->port_cfg = port->port_cfg; 10817725ccfdSJing Huang 10827725ccfdSJing Huang if (port->fabric) { 1083f7f73812SMaggie Zhang port_attr->port_type = port->fabric->oper_type; 1084da99dcc9SMaggie Zhang port_attr->loopback = bfa_sm_cmp_state(port->fabric, 1085da99dcc9SMaggie Zhang bfa_fcs_fabric_sm_loopback); 1086f926a05fSKrishna Gudipati port_attr->authfail = 1087f7f73812SMaggie Zhang bfa_sm_cmp_state(port->fabric, 1088f7f73812SMaggie Zhang bfa_fcs_fabric_sm_auth_failed); 1089a36c61f9SKrishna Gudipati port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port); 10907725ccfdSJing Huang memcpy(port_attr->fabric_ip_addr, 1091a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fabric_ipaddr(port), 10927725ccfdSJing Huang BFA_FCS_FABRIC_IPADDR_SZ); 10937725ccfdSJing Huang 109486e32dabSKrishna Gudipati if (port->vport != NULL) { 1095a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_VPORT; 109686e32dabSKrishna Gudipati port_attr->fpma_mac = 1097f7f73812SMaggie Zhang port->vport->lps->lp_mac; 1098a36c61f9SKrishna Gudipati } else { 109986e32dabSKrishna Gudipati port_attr->fpma_mac = 1100f7f73812SMaggie Zhang port->fabric->lps->lp_mac; 1101a36c61f9SKrishna Gudipati } 1102a36c61f9SKrishna Gudipati } else { 1103a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_UNKNOWN; 1104a36c61f9SKrishna Gudipati port_attr->state = BFA_LPORT_UNINIT; 1105a36c61f9SKrishna Gudipati } 1106a36c61f9SKrishna Gudipati } 1107a36c61f9SKrishna Gudipati 11085fbe25c7SJing Huang /* 1109a36c61f9SKrishna Gudipati * bfa_fcs_lport_fab port fab functions 1110a36c61f9SKrishna Gudipati */ 1111a36c61f9SKrishna Gudipati 11125fbe25c7SJing Huang /* 1113a36c61f9SKrishna Gudipati * Called by port to initialize fabric services of the base port. 1114a36c61f9SKrishna Gudipati */ 1115a36c61f9SKrishna Gudipati static void 1116a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port) 1117a36c61f9SKrishna Gudipati { 1118a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(port); 1119a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(port); 1120a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(port); 1121a36c61f9SKrishna Gudipati } 1122a36c61f9SKrishna Gudipati 11235fbe25c7SJing Huang /* 1124a36c61f9SKrishna Gudipati * Called by port to notify transition to online state. 1125a36c61f9SKrishna Gudipati */ 1126a36c61f9SKrishna Gudipati static void 1127a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 1128a36c61f9SKrishna Gudipati { 1129a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(port); 1130a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(port); 1131a36c61f9SKrishna Gudipati } 1132a36c61f9SKrishna Gudipati 11335fbe25c7SJing Huang /* 1134a36c61f9SKrishna Gudipati * Called by port to notify transition to offline state. 1135a36c61f9SKrishna Gudipati */ 1136a36c61f9SKrishna Gudipati static void 1137a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port) 1138a36c61f9SKrishna Gudipati { 1139a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(port); 1140a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(port); 1141a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(port); 1142a36c61f9SKrishna Gudipati } 1143a36c61f9SKrishna Gudipati 11445fbe25c7SJing Huang /* 1145a36c61f9SKrishna Gudipati * bfa_fcs_lport_n2n functions 1146a36c61f9SKrishna Gudipati */ 1147a36c61f9SKrishna Gudipati 11485fbe25c7SJing Huang /* 1149a36c61f9SKrishna Gudipati * Called by fcs/port to initialize N2N topology. 1150a36c61f9SKrishna Gudipati */ 1151a36c61f9SKrishna Gudipati static void 1152a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port) 1153a36c61f9SKrishna Gudipati { 1154a36c61f9SKrishna Gudipati } 1155a36c61f9SKrishna Gudipati 11565fbe25c7SJing Huang /* 1157a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to online state. 1158a36c61f9SKrishna Gudipati */ 1159a36c61f9SKrishna Gudipati static void 1160a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port) 1161a36c61f9SKrishna Gudipati { 1162a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1163a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *pcfg = &port->port_cfg; 1164a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 1165a36c61f9SKrishna Gudipati 1166a36c61f9SKrishna Gudipati bfa_trc(port->fcs, pcfg->pwwn); 1167a36c61f9SKrishna Gudipati 1168a36c61f9SKrishna Gudipati /* 1169a36c61f9SKrishna Gudipati * If our PWWN is > than that of the r-port, we have to initiate PLOGI 1170a36c61f9SKrishna Gudipati * and assign an Address. if not, we need to wait for its PLOGI. 1171a36c61f9SKrishna Gudipati * 1172a36c61f9SKrishna Gudipati * If our PWWN is < than that of the remote port, it will send a PLOGI 1173a36c61f9SKrishna Gudipati * with the PIDs assigned. The rport state machine take care of this 1174a36c61f9SKrishna Gudipati * incoming PLOGI. 1175a36c61f9SKrishna Gudipati */ 1176a36c61f9SKrishna Gudipati if (memcmp 1177a36c61f9SKrishna Gudipati ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, 1178a36c61f9SKrishna Gudipati sizeof(wwn_t)) > 0) { 1179a36c61f9SKrishna Gudipati port->pid = N2N_LOCAL_PID; 1180b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID); 11815fbe25c7SJing Huang /* 1182a36c61f9SKrishna Gudipati * First, check if we know the device by pwwn. 1183a36c61f9SKrishna Gudipati */ 1184a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, 1185a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn); 1186a36c61f9SKrishna Gudipati if (rport) { 1187a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pid); 1188a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1189a36c61f9SKrishna Gudipati rport->pid = N2N_REMOTE_PID; 1190f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 1191a36c61f9SKrishna Gudipati return; 1192a36c61f9SKrishna Gudipati } 1193a36c61f9SKrishna Gudipati 1194a36c61f9SKrishna Gudipati /* 1195a36c61f9SKrishna Gudipati * In n2n there can be only one rport. Delete the old one 1196a36c61f9SKrishna Gudipati * whose pid should be zero, because it is offline. 1197a36c61f9SKrishna Gudipati */ 1198a36c61f9SKrishna Gudipati if (port->num_rports > 0) { 1199a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 0); 1200d4b671c5SJing Huang WARN_ON(rport == NULL); 1201a36c61f9SKrishna Gudipati if (rport) { 1202a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1203f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1204a36c61f9SKrishna Gudipati } 1205a36c61f9SKrishna Gudipati } 1206a36c61f9SKrishna Gudipati bfa_fcs_rport_create(port, N2N_REMOTE_PID); 1207a36c61f9SKrishna Gudipati } 1208a36c61f9SKrishna Gudipati } 1209a36c61f9SKrishna Gudipati 12105fbe25c7SJing Huang /* 1211a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to offline state. 1212a36c61f9SKrishna Gudipati */ 1213a36c61f9SKrishna Gudipati static void 1214a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port) 1215a36c61f9SKrishna Gudipati { 1216a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1217a36c61f9SKrishna Gudipati 1218a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 1219a36c61f9SKrishna Gudipati port->pid = 0; 1220a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn = 0; 1221a36c61f9SKrishna Gudipati n2n_port->reply_oxid = 0; 1222a36c61f9SKrishna Gudipati } 1223a36c61f9SKrishna Gudipati 1224a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 1225a36c61f9SKrishna Gudipati 1226a36c61f9SKrishna Gudipati /* 1227a36c61f9SKrishna Gudipati * forward declarations 1228a36c61f9SKrishna Gudipati */ 1229a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, 1230a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1231a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, 1232a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1233a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, 1234a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1235a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, 1236a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1237a36c61f9SKrishna Gudipati void *cbarg, 1238a36c61f9SKrishna Gudipati bfa_status_t req_status, 1239a36c61f9SKrishna Gudipati u32 rsp_len, 1240a36c61f9SKrishna Gudipati u32 resid_len, 1241a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1242a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, 1243a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1244a36c61f9SKrishna Gudipati void *cbarg, 1245a36c61f9SKrishna Gudipati bfa_status_t req_status, 1246a36c61f9SKrishna Gudipati u32 rsp_len, 1247a36c61f9SKrishna Gudipati u32 resid_len, 1248a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1249a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, 1250a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1251a36c61f9SKrishna Gudipati void *cbarg, 1252a36c61f9SKrishna Gudipati bfa_status_t req_status, 1253a36c61f9SKrishna Gudipati u32 rsp_len, 1254a36c61f9SKrishna Gudipati u32 resid_len, 1255a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1256a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_timeout(void *arg); 1257a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1258a36c61f9SKrishna Gudipati u8 *pyld); 1259a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1260a36c61f9SKrishna Gudipati u8 *pyld); 1261a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1262a36c61f9SKrishna Gudipati u8 *pyld); 1263a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s * 1264a36c61f9SKrishna Gudipati fdmi, u8 *pyld); 1265a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1266a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr); 1267a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1268a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr); 1269d7be54ccSKrishna Gudipati u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed); 1270d7be54ccSKrishna Gudipati 12715fbe25c7SJing Huang /* 1272a36c61f9SKrishna Gudipati * fcs_fdmi_sm FCS FDMI state machine 1273a36c61f9SKrishna Gudipati */ 1274a36c61f9SKrishna Gudipati 12755fbe25c7SJing Huang /* 1276a36c61f9SKrishna Gudipati * FDMI State Machine events 1277a36c61f9SKrishna Gudipati */ 1278a36c61f9SKrishna Gudipati enum port_fdmi_event { 1279a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_ONLINE = 1, 1280a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_OFFLINE = 2, 1281a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_OK = 4, 1282a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_ERROR = 5, 1283a36c61f9SKrishna Gudipati FDMISM_EVENT_TIMEOUT = 6, 1284a36c61f9SKrishna Gudipati FDMISM_EVENT_RHBA_SENT = 7, 1285a36c61f9SKrishna Gudipati FDMISM_EVENT_RPRT_SENT = 8, 1286a36c61f9SKrishna Gudipati FDMISM_EVENT_RPA_SENT = 9, 1287a36c61f9SKrishna Gudipati }; 1288a36c61f9SKrishna Gudipati 1289a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1290a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1291a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rhba( 1292a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1293a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1294a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1295a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1296a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba_retry( 1297a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1298a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1299a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rprt( 1300a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1301a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1302a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1303a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1304a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt_retry( 1305a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1306a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1307a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rpa( 1308a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1309a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1310a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1311a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1312a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa_retry( 1313a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1314a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1315a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1316a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1317a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_disabled( 1318a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1319a36c61f9SKrishna Gudipati enum port_fdmi_event event); 13205fbe25c7SJing Huang /* 1321a36c61f9SKrishna Gudipati * Start in offline state - awaiting MS to send start. 1322a36c61f9SKrishna Gudipati */ 1323a36c61f9SKrishna Gudipati static void 1324a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1325a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1326a36c61f9SKrishna Gudipati { 1327a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1328a36c61f9SKrishna Gudipati 1329a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1330a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1331a36c61f9SKrishna Gudipati 1332a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1333a36c61f9SKrishna Gudipati 1334a36c61f9SKrishna Gudipati switch (event) { 1335a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_ONLINE: 1336a36c61f9SKrishna Gudipati if (port->vport) { 1337a36c61f9SKrishna Gudipati /* 1338a36c61f9SKrishna Gudipati * For Vports, register a new port. 1339a36c61f9SKrishna Gudipati */ 1340a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1341a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt); 1342a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1343a36c61f9SKrishna Gudipati } else { 1344a36c61f9SKrishna Gudipati /* 1345a36c61f9SKrishna Gudipati * For a base port, we should first register the HBA 134625985edcSLucas De Marchi * attribute. The HBA attribute also contains the base 1347a36c61f9SKrishna Gudipati * port registration. 1348a36c61f9SKrishna Gudipati */ 1349a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1350a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba); 1351a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1352a36c61f9SKrishna Gudipati } 1353a36c61f9SKrishna Gudipati break; 1354a36c61f9SKrishna Gudipati 1355a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1356a36c61f9SKrishna Gudipati break; 1357a36c61f9SKrishna Gudipati 1358a36c61f9SKrishna Gudipati default: 1359a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1360a36c61f9SKrishna Gudipati } 1361a36c61f9SKrishna Gudipati } 1362a36c61f9SKrishna Gudipati 1363a36c61f9SKrishna Gudipati static void 1364a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1365a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1366a36c61f9SKrishna Gudipati { 1367a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1368a36c61f9SKrishna Gudipati 1369a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1370a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1371a36c61f9SKrishna Gudipati 1372a36c61f9SKrishna Gudipati switch (event) { 1373a36c61f9SKrishna Gudipati case FDMISM_EVENT_RHBA_SENT: 1374a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba); 1375a36c61f9SKrishna Gudipati break; 1376a36c61f9SKrishna Gudipati 1377a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1378a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1379a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1380a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1381a36c61f9SKrishna Gudipati break; 1382a36c61f9SKrishna Gudipati 1383a36c61f9SKrishna Gudipati default: 1384a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1385a36c61f9SKrishna Gudipati } 1386a36c61f9SKrishna Gudipati } 1387a36c61f9SKrishna Gudipati 1388a36c61f9SKrishna Gudipati static void 1389a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1390a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1391a36c61f9SKrishna Gudipati { 1392a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1393a36c61f9SKrishna Gudipati 1394a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1395a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1396a36c61f9SKrishna Gudipati 1397a36c61f9SKrishna Gudipati switch (event) { 1398a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1399a36c61f9SKrishna Gudipati /* 1400a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1401a36c61f9SKrishna Gudipati * delayed retry 1402a36c61f9SKrishna Gudipati */ 1403a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1404a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1405a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry); 1406a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1407a36c61f9SKrishna Gudipati &fdmi->timer, 1408a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1409a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1410a36c61f9SKrishna Gudipati } else { 1411a36c61f9SKrishna Gudipati /* 1412a36c61f9SKrishna Gudipati * set state to offline 1413a36c61f9SKrishna Gudipati */ 1414a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1415a36c61f9SKrishna Gudipati } 1416a36c61f9SKrishna Gudipati break; 1417a36c61f9SKrishna Gudipati 1418a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1419a36c61f9SKrishna Gudipati /* 1420a36c61f9SKrishna Gudipati * Initiate Register Port Attributes 1421a36c61f9SKrishna Gudipati */ 1422a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1423a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1424a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1425a36c61f9SKrishna Gudipati break; 1426a36c61f9SKrishna Gudipati 1427a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1428a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1429a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1430a36c61f9SKrishna Gudipati break; 1431a36c61f9SKrishna Gudipati 1432a36c61f9SKrishna Gudipati default: 1433a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1434a36c61f9SKrishna Gudipati } 1435a36c61f9SKrishna Gudipati } 1436a36c61f9SKrishna Gudipati 1437a36c61f9SKrishna Gudipati static void 1438a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1439a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1440a36c61f9SKrishna Gudipati { 1441a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1442a36c61f9SKrishna Gudipati 1443a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1444a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1445a36c61f9SKrishna Gudipati 1446a36c61f9SKrishna Gudipati switch (event) { 1447a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1448a36c61f9SKrishna Gudipati /* 1449a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1450a36c61f9SKrishna Gudipati */ 1451a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba); 1452a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1453a36c61f9SKrishna Gudipati break; 1454a36c61f9SKrishna Gudipati 1455a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1456a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1457a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1458a36c61f9SKrishna Gudipati break; 1459a36c61f9SKrishna Gudipati 1460a36c61f9SKrishna Gudipati default: 1461a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1462a36c61f9SKrishna Gudipati } 1463a36c61f9SKrishna Gudipati } 1464a36c61f9SKrishna Gudipati 1465a36c61f9SKrishna Gudipati /* 1466a36c61f9SKrishna Gudipati * RPRT : Register Port 1467a36c61f9SKrishna Gudipati */ 1468a36c61f9SKrishna Gudipati static void 1469a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1470a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1471a36c61f9SKrishna Gudipati { 1472a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1473a36c61f9SKrishna Gudipati 1474a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1475a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1476a36c61f9SKrishna Gudipati 1477a36c61f9SKrishna Gudipati switch (event) { 1478a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPRT_SENT: 1479a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt); 1480a36c61f9SKrishna Gudipati break; 1481a36c61f9SKrishna Gudipati 1482a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1483a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1484a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1485a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1486a36c61f9SKrishna Gudipati break; 1487a36c61f9SKrishna Gudipati 1488a36c61f9SKrishna Gudipati default: 1489a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1490a36c61f9SKrishna Gudipati } 1491a36c61f9SKrishna Gudipati } 1492a36c61f9SKrishna Gudipati 1493a36c61f9SKrishna Gudipati static void 1494a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1495a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1496a36c61f9SKrishna Gudipati { 1497a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1498a36c61f9SKrishna Gudipati 1499a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1500a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1501a36c61f9SKrishna Gudipati 1502a36c61f9SKrishna Gudipati switch (event) { 1503a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1504a36c61f9SKrishna Gudipati /* 1505a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1506a36c61f9SKrishna Gudipati * delayed retry 1507a36c61f9SKrishna Gudipati */ 1508a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1509a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1510a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry); 1511a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1512a36c61f9SKrishna Gudipati &fdmi->timer, 1513a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1514a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 15157725ccfdSJing Huang 15167725ccfdSJing Huang } else { 1517a36c61f9SKrishna Gudipati /* 1518a36c61f9SKrishna Gudipati * set state to offline 1519a36c61f9SKrishna Gudipati */ 1520a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1521a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 15227725ccfdSJing Huang } 1523a36c61f9SKrishna Gudipati break; 1524a36c61f9SKrishna Gudipati 1525a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1526a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1527a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1528a36c61f9SKrishna Gudipati break; 1529a36c61f9SKrishna Gudipati 1530a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1531a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1532a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1533a36c61f9SKrishna Gudipati break; 1534a36c61f9SKrishna Gudipati 1535a36c61f9SKrishna Gudipati default: 1536a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1537a36c61f9SKrishna Gudipati } 1538a36c61f9SKrishna Gudipati } 1539a36c61f9SKrishna Gudipati 1540a36c61f9SKrishna Gudipati static void 1541a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1542a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1543a36c61f9SKrishna Gudipati { 1544a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1545a36c61f9SKrishna Gudipati 1546a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1547a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1548a36c61f9SKrishna Gudipati 1549a36c61f9SKrishna Gudipati switch (event) { 1550a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1551a36c61f9SKrishna Gudipati /* 1552a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1553a36c61f9SKrishna Gudipati */ 1554a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt); 1555a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1556a36c61f9SKrishna Gudipati break; 1557a36c61f9SKrishna Gudipati 1558a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1559a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1560a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1561a36c61f9SKrishna Gudipati break; 1562a36c61f9SKrishna Gudipati 1563a36c61f9SKrishna Gudipati default: 1564a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1565a36c61f9SKrishna Gudipati } 1566a36c61f9SKrishna Gudipati } 1567a36c61f9SKrishna Gudipati 1568a36c61f9SKrishna Gudipati /* 1569a36c61f9SKrishna Gudipati * Register Port Attributes 1570a36c61f9SKrishna Gudipati */ 1571a36c61f9SKrishna Gudipati static void 1572a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1573a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1574a36c61f9SKrishna Gudipati { 1575a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1576a36c61f9SKrishna Gudipati 1577a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1578a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1579a36c61f9SKrishna Gudipati 1580a36c61f9SKrishna Gudipati switch (event) { 1581a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPA_SENT: 1582a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa); 1583a36c61f9SKrishna Gudipati break; 1584a36c61f9SKrishna Gudipati 1585a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1586a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1587a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1588a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1589a36c61f9SKrishna Gudipati break; 1590a36c61f9SKrishna Gudipati 1591a36c61f9SKrishna Gudipati default: 1592a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1593a36c61f9SKrishna Gudipati } 1594a36c61f9SKrishna Gudipati } 1595a36c61f9SKrishna Gudipati 1596a36c61f9SKrishna Gudipati static void 1597a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1598a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1599a36c61f9SKrishna Gudipati { 1600a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1601a36c61f9SKrishna Gudipati 1602a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1603a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1604a36c61f9SKrishna Gudipati 1605a36c61f9SKrishna Gudipati switch (event) { 1606a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1607a36c61f9SKrishna Gudipati /* 1608a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1609a36c61f9SKrishna Gudipati * delayed retry 1610a36c61f9SKrishna Gudipati */ 1611a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1612a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry); 1613a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1614a36c61f9SKrishna Gudipati &fdmi->timer, 1615a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1616a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1617a36c61f9SKrishna Gudipati } else { 1618a36c61f9SKrishna Gudipati /* 1619a36c61f9SKrishna Gudipati * set state to offline 1620a36c61f9SKrishna Gudipati */ 1621a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1622a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1623a36c61f9SKrishna Gudipati } 1624a36c61f9SKrishna Gudipati break; 1625a36c61f9SKrishna Gudipati 1626a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1627a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1628a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1629a36c61f9SKrishna Gudipati break; 1630a36c61f9SKrishna Gudipati 1631a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1632a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1633a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1634a36c61f9SKrishna Gudipati break; 1635a36c61f9SKrishna Gudipati 1636a36c61f9SKrishna Gudipati default: 1637a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1638a36c61f9SKrishna Gudipati } 1639a36c61f9SKrishna Gudipati } 1640a36c61f9SKrishna Gudipati 1641a36c61f9SKrishna Gudipati static void 1642a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1643a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1644a36c61f9SKrishna Gudipati { 1645a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1646a36c61f9SKrishna Gudipati 1647a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1648a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1649a36c61f9SKrishna Gudipati 1650a36c61f9SKrishna Gudipati switch (event) { 1651a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1652a36c61f9SKrishna Gudipati /* 1653a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1654a36c61f9SKrishna Gudipati */ 1655a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1656a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1657a36c61f9SKrishna Gudipati break; 1658a36c61f9SKrishna Gudipati 1659a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1660a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1661a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1662a36c61f9SKrishna Gudipati break; 1663a36c61f9SKrishna Gudipati 1664a36c61f9SKrishna Gudipati default: 1665a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1666a36c61f9SKrishna Gudipati } 1667a36c61f9SKrishna Gudipati } 1668a36c61f9SKrishna Gudipati 1669a36c61f9SKrishna Gudipati static void 1670a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1671a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1672a36c61f9SKrishna Gudipati { 1673a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1674a36c61f9SKrishna Gudipati 1675a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1676a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1677a36c61f9SKrishna Gudipati 1678a36c61f9SKrishna Gudipati switch (event) { 1679a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1680a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1681a36c61f9SKrishna Gudipati break; 1682a36c61f9SKrishna Gudipati 1683a36c61f9SKrishna Gudipati default: 1684a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1685a36c61f9SKrishna Gudipati } 1686a36c61f9SKrishna Gudipati } 16875fbe25c7SJing Huang /* 1688a36c61f9SKrishna Gudipati * FDMI is disabled state. 1689a36c61f9SKrishna Gudipati */ 1690a36c61f9SKrishna Gudipati static void 1691a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi, 1692a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1693a36c61f9SKrishna Gudipati { 1694a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1695a36c61f9SKrishna Gudipati 1696a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1697a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1698a36c61f9SKrishna Gudipati 1699a36c61f9SKrishna Gudipati /* No op State. It can only be enabled at Driver Init. */ 1700a36c61f9SKrishna Gudipati } 1701a36c61f9SKrishna Gudipati 17025fbe25c7SJing Huang /* 1703a36c61f9SKrishna Gudipati * RHBA : Register HBA Attributes. 1704a36c61f9SKrishna Gudipati */ 1705a36c61f9SKrishna Gudipati static void 1706a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1707a36c61f9SKrishna Gudipati { 1708a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1709a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1710a36c61f9SKrishna Gudipati struct fchs_s fchs; 1711a36c61f9SKrishna Gudipati int len, attr_len; 1712a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1713a36c61f9SKrishna Gudipati u8 *pyld; 1714a36c61f9SKrishna Gudipati 1715a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1716a36c61f9SKrishna Gudipati 1717c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1718c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 1719a36c61f9SKrishna Gudipati if (!fcxp) { 1720a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1721c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE); 1722a36c61f9SKrishna Gudipati return; 1723a36c61f9SKrishna Gudipati } 1724a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 1725a36c61f9SKrishna Gudipati 1726a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 17276a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 1728a36c61f9SKrishna Gudipati 1729a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1730a36c61f9SKrishna Gudipati FDMI_RHBA); 1731a36c61f9SKrishna Gudipati 1732a36c61f9SKrishna Gudipati attr_len = 1733a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi, 1734a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 1735a36c61f9SKrishna Gudipati + 1)); 1736a36c61f9SKrishna Gudipati 1737a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1738a36c61f9SKrishna Gudipati FC_CLASS_3, (len + attr_len), &fchs, 1739a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi, 1740a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 1741a36c61f9SKrishna Gudipati 1742a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); 1743a36c61f9SKrishna Gudipati } 1744a36c61f9SKrishna Gudipati 1745a36c61f9SKrishna Gudipati static u16 1746a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 1747a36c61f9SKrishna Gudipati { 1748a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1749a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s hba_attr; 1750a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; 1751a36c61f9SKrishna Gudipati struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; 1752a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 1753a36c61f9SKrishna Gudipati u8 *curr_ptr; 1754a36c61f9SKrishna Gudipati u16 len, count; 175550444a34SMaggie u16 templen; 1756a36c61f9SKrishna Gudipati 1757a36c61f9SKrishna Gudipati /* 1758a36c61f9SKrishna Gudipati * get hba attributes 1759a36c61f9SKrishna Gudipati */ 1760a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); 1761a36c61f9SKrishna Gudipati 1762a36c61f9SKrishna Gudipati rhba->hba_id = bfa_fcs_lport_get_pwwn(port); 1763ba816ea8SJing Huang rhba->port_list.num_ports = cpu_to_be32(1); 1764a36c61f9SKrishna Gudipati rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port); 1765a36c61f9SKrishna Gudipati 1766a36c61f9SKrishna Gudipati len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); 1767a36c61f9SKrishna Gudipati 1768a36c61f9SKrishna Gudipati count = 0; 1769a36c61f9SKrishna Gudipati len += sizeof(rhba->hba_attr_blk.attr_count); 1770a36c61f9SKrishna Gudipati 1771a36c61f9SKrishna Gudipati /* 1772a36c61f9SKrishna Gudipati * fill out the invididual entries of the HBA attrib Block 1773a36c61f9SKrishna Gudipati */ 1774a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; 1775a36c61f9SKrishna Gudipati 1776a36c61f9SKrishna Gudipati /* 1777a36c61f9SKrishna Gudipati * Node Name 1778a36c61f9SKrishna Gudipati */ 1779a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1780ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME); 178150444a34SMaggie templen = sizeof(wwn_t); 178250444a34SMaggie memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen); 178350444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 178450444a34SMaggie len += templen; 1785a36c61f9SKrishna Gudipati count++; 178650444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 178750444a34SMaggie sizeof(templen)); 1788a36c61f9SKrishna Gudipati 1789a36c61f9SKrishna Gudipati /* 1790a36c61f9SKrishna Gudipati * Manufacturer 1791a36c61f9SKrishna Gudipati */ 1792a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1793ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER); 179450444a34SMaggie templen = (u16) strlen(fcs_hba_attr->manufacturer); 179550444a34SMaggie memcpy(attr->value, fcs_hba_attr->manufacturer, templen); 179650444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 179750444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 179850444a34SMaggie len += templen; 1799a36c61f9SKrishna Gudipati count++; 180050444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 180150444a34SMaggie sizeof(templen)); 1802a36c61f9SKrishna Gudipati 1803a36c61f9SKrishna Gudipati /* 1804a36c61f9SKrishna Gudipati * Serial Number 1805a36c61f9SKrishna Gudipati */ 1806a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1807ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM); 180850444a34SMaggie templen = (u16) strlen(fcs_hba_attr->serial_num); 180950444a34SMaggie memcpy(attr->value, fcs_hba_attr->serial_num, templen); 181050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 181150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 181250444a34SMaggie len += templen; 1813a36c61f9SKrishna Gudipati count++; 181450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 181550444a34SMaggie sizeof(templen)); 1816a36c61f9SKrishna Gudipati 1817a36c61f9SKrishna Gudipati /* 1818a36c61f9SKrishna Gudipati * Model 1819a36c61f9SKrishna Gudipati */ 1820a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1821ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL); 182250444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model); 182350444a34SMaggie memcpy(attr->value, fcs_hba_attr->model, templen); 182450444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 182550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 182650444a34SMaggie len += templen; 1827a36c61f9SKrishna Gudipati count++; 182850444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 182950444a34SMaggie sizeof(templen)); 1830a36c61f9SKrishna Gudipati 1831a36c61f9SKrishna Gudipati /* 1832a36c61f9SKrishna Gudipati * Model Desc 1833a36c61f9SKrishna Gudipati */ 1834a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1835ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC); 183650444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model_desc); 183750444a34SMaggie memcpy(attr->value, fcs_hba_attr->model_desc, templen); 183850444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 183950444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 184050444a34SMaggie len += templen; 1841a36c61f9SKrishna Gudipati count++; 184250444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 184350444a34SMaggie sizeof(templen)); 1844a36c61f9SKrishna Gudipati 1845a36c61f9SKrishna Gudipati /* 1846a36c61f9SKrishna Gudipati * H/W Version 1847a36c61f9SKrishna Gudipati */ 1848a36c61f9SKrishna Gudipati if (fcs_hba_attr->hw_version[0] != '\0') { 1849a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1850ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION); 185150444a34SMaggie templen = (u16) strlen(fcs_hba_attr->hw_version); 185250444a34SMaggie memcpy(attr->value, fcs_hba_attr->hw_version, templen); 185350444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 185450444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 185550444a34SMaggie len += templen; 1856a36c61f9SKrishna Gudipati count++; 185750444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 185850444a34SMaggie sizeof(templen)); 1859a36c61f9SKrishna Gudipati } 1860a36c61f9SKrishna Gudipati 1861a36c61f9SKrishna Gudipati /* 1862a36c61f9SKrishna Gudipati * Driver Version 1863a36c61f9SKrishna Gudipati */ 1864a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1865ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION); 186650444a34SMaggie templen = (u16) strlen(fcs_hba_attr->driver_version); 186750444a34SMaggie memcpy(attr->value, fcs_hba_attr->driver_version, templen); 186850444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 186950444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1870dd5aaf45SKrishna Gudipati len += templen; 1871a36c61f9SKrishna Gudipati count++; 187250444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 187350444a34SMaggie sizeof(templen)); 1874a36c61f9SKrishna Gudipati 1875a36c61f9SKrishna Gudipati /* 1876a36c61f9SKrishna Gudipati * Option Rom Version 1877a36c61f9SKrishna Gudipati */ 1878a36c61f9SKrishna Gudipati if (fcs_hba_attr->option_rom_ver[0] != '\0') { 1879a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1880ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION); 188150444a34SMaggie templen = (u16) strlen(fcs_hba_attr->option_rom_ver); 188250444a34SMaggie memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen); 188350444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 188450444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 188550444a34SMaggie len += templen; 1886a36c61f9SKrishna Gudipati count++; 188750444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 188850444a34SMaggie sizeof(templen)); 1889a36c61f9SKrishna Gudipati } 1890a36c61f9SKrishna Gudipati 1891a36c61f9SKrishna Gudipati /* 1892a36c61f9SKrishna Gudipati * f/w Version = driver version 1893a36c61f9SKrishna Gudipati */ 1894a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1895ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); 189650444a34SMaggie templen = (u16) strlen(fcs_hba_attr->driver_version); 189750444a34SMaggie memcpy(attr->value, fcs_hba_attr->driver_version, templen); 189850444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 189950444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 190050444a34SMaggie len += templen; 1901a36c61f9SKrishna Gudipati count++; 190250444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 190350444a34SMaggie sizeof(templen)); 1904a36c61f9SKrishna Gudipati 1905a36c61f9SKrishna Gudipati /* 1906a36c61f9SKrishna Gudipati * OS Name 1907a36c61f9SKrishna Gudipati */ 1908a36c61f9SKrishna Gudipati if (fcs_hba_attr->os_name[0] != '\0') { 1909a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1910ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME); 191150444a34SMaggie templen = (u16) strlen(fcs_hba_attr->os_name); 191250444a34SMaggie memcpy(attr->value, fcs_hba_attr->os_name, templen); 191350444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 191450444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 191550444a34SMaggie len += templen; 1916a36c61f9SKrishna Gudipati count++; 191750444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 191850444a34SMaggie sizeof(templen)); 1919a36c61f9SKrishna Gudipati } 1920a36c61f9SKrishna Gudipati 1921a36c61f9SKrishna Gudipati /* 1922a36c61f9SKrishna Gudipati * MAX_CT_PAYLOAD 1923a36c61f9SKrishna Gudipati */ 1924a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1925ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); 192650444a34SMaggie templen = sizeof(fcs_hba_attr->max_ct_pyld); 192750444a34SMaggie memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen); 192850444a34SMaggie len += templen; 1929a36c61f9SKrishna Gudipati count++; 193050444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 193150444a34SMaggie sizeof(templen)); 1932a36c61f9SKrishna Gudipati 1933a36c61f9SKrishna Gudipati /* 1934a36c61f9SKrishna Gudipati * Update size of payload 1935a36c61f9SKrishna Gudipati */ 19365fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 1937a36c61f9SKrishna Gudipati 1938ba816ea8SJing Huang rhba->hba_attr_blk.attr_count = cpu_to_be32(count); 1939a36c61f9SKrishna Gudipati return len; 1940a36c61f9SKrishna Gudipati } 1941a36c61f9SKrishna Gudipati 1942a36c61f9SKrishna Gudipati static void 1943a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 1944a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 1945a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 1946a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 1947a36c61f9SKrishna Gudipati { 1948a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 1949a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 1950a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1951a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 1952a36c61f9SKrishna Gudipati 1953a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1954a36c61f9SKrishna Gudipati 1955a36c61f9SKrishna Gudipati /* 1956a36c61f9SKrishna Gudipati * Sanity Checks 1957a36c61f9SKrishna Gudipati */ 1958a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 1959a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 1960a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1961a36c61f9SKrishna Gudipati return; 1962a36c61f9SKrishna Gudipati } 1963a36c61f9SKrishna Gudipati 1964a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1965ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1966a36c61f9SKrishna Gudipati 1967a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1968a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 1969a36c61f9SKrishna Gudipati return; 1970a36c61f9SKrishna Gudipati } 1971a36c61f9SKrishna Gudipati 1972a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 1973a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 1974a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1975a36c61f9SKrishna Gudipati } 1976a36c61f9SKrishna Gudipati 19775fbe25c7SJing Huang /* 1978a36c61f9SKrishna Gudipati * RPRT : Register Port 1979a36c61f9SKrishna Gudipati */ 1980a36c61f9SKrishna Gudipati static void 1981a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1982a36c61f9SKrishna Gudipati { 1983a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1984a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1985a36c61f9SKrishna Gudipati struct fchs_s fchs; 1986a36c61f9SKrishna Gudipati u16 len, attr_len; 1987a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1988a36c61f9SKrishna Gudipati u8 *pyld; 1989a36c61f9SKrishna Gudipati 1990a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1991a36c61f9SKrishna Gudipati 1992c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1993c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 1994a36c61f9SKrishna Gudipati if (!fcxp) { 1995a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1996c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE); 1997a36c61f9SKrishna Gudipati return; 1998a36c61f9SKrishna Gudipati } 1999a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2000a36c61f9SKrishna Gudipati 2001a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 20026a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2003a36c61f9SKrishna Gudipati 2004a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2005a36c61f9SKrishna Gudipati FDMI_RPRT); 2006a36c61f9SKrishna Gudipati 2007a36c61f9SKrishna Gudipati attr_len = 2008a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi, 2009a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 2010a36c61f9SKrishna Gudipati + 1)); 2011a36c61f9SKrishna Gudipati 2012a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2013a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2014a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi, 2015a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2016a36c61f9SKrishna Gudipati 2017a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); 2018a36c61f9SKrishna Gudipati } 2019a36c61f9SKrishna Gudipati 20205fbe25c7SJing Huang /* 2021a36c61f9SKrishna Gudipati * This routine builds Port Attribute Block that used in RPA, RPRT commands. 2022a36c61f9SKrishna Gudipati */ 2023a36c61f9SKrishna Gudipati static u16 2024a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi, 2025a36c61f9SKrishna Gudipati u8 *pyld) 2026a36c61f9SKrishna Gudipati { 2027a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 2028a36c61f9SKrishna Gudipati struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; 2029a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 2030a36c61f9SKrishna Gudipati u8 *curr_ptr; 2031a36c61f9SKrishna Gudipati u16 len; 2032a36c61f9SKrishna Gudipati u8 count = 0; 203350444a34SMaggie u16 templen; 2034a36c61f9SKrishna Gudipati 2035a36c61f9SKrishna Gudipati /* 2036a36c61f9SKrishna Gudipati * get port attributes 2037a36c61f9SKrishna Gudipati */ 2038a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 2039a36c61f9SKrishna Gudipati 2040a36c61f9SKrishna Gudipati len = sizeof(port_attrib->attr_count); 2041a36c61f9SKrishna Gudipati 2042a36c61f9SKrishna Gudipati /* 2043a36c61f9SKrishna Gudipati * fill out the invididual entries 2044a36c61f9SKrishna Gudipati */ 2045a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &port_attrib->port_attr; 2046a36c61f9SKrishna Gudipati 2047a36c61f9SKrishna Gudipati /* 2048a36c61f9SKrishna Gudipati * FC4 Types 2049a36c61f9SKrishna Gudipati */ 2050a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2051ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES); 205250444a34SMaggie templen = sizeof(fcs_port_attr.supp_fc4_types); 205350444a34SMaggie memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen); 205450444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 205550444a34SMaggie len += templen; 2056a36c61f9SKrishna Gudipati ++count; 2057a36c61f9SKrishna Gudipati attr->len = 205850444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 205950444a34SMaggie sizeof(templen)); 2060a36c61f9SKrishna Gudipati 2061a36c61f9SKrishna Gudipati /* 2062a36c61f9SKrishna Gudipati * Supported Speed 2063a36c61f9SKrishna Gudipati */ 2064a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2065ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED); 206650444a34SMaggie templen = sizeof(fcs_port_attr.supp_speed); 206750444a34SMaggie memcpy(attr->value, &fcs_port_attr.supp_speed, templen); 206850444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 206950444a34SMaggie len += templen; 2070a36c61f9SKrishna Gudipati ++count; 2071a36c61f9SKrishna Gudipati attr->len = 207250444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 207350444a34SMaggie sizeof(templen)); 2074a36c61f9SKrishna Gudipati 2075a36c61f9SKrishna Gudipati /* 2076a36c61f9SKrishna Gudipati * current Port Speed 2077a36c61f9SKrishna Gudipati */ 2078a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2079ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED); 208050444a34SMaggie templen = sizeof(fcs_port_attr.curr_speed); 208150444a34SMaggie memcpy(attr->value, &fcs_port_attr.curr_speed, templen); 208250444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 208350444a34SMaggie len += templen; 2084a36c61f9SKrishna Gudipati ++count; 208550444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 208650444a34SMaggie sizeof(templen)); 2087a36c61f9SKrishna Gudipati 2088a36c61f9SKrishna Gudipati /* 2089a36c61f9SKrishna Gudipati * max frame size 2090a36c61f9SKrishna Gudipati */ 2091a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2092ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE); 209350444a34SMaggie templen = sizeof(fcs_port_attr.max_frm_size); 209450444a34SMaggie memcpy(attr->value, &fcs_port_attr.max_frm_size, templen); 209550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 209650444a34SMaggie len += templen; 2097a36c61f9SKrishna Gudipati ++count; 209850444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 209950444a34SMaggie sizeof(templen)); 2100a36c61f9SKrishna Gudipati 2101a36c61f9SKrishna Gudipati /* 2102a36c61f9SKrishna Gudipati * OS Device Name 2103a36c61f9SKrishna Gudipati */ 2104a36c61f9SKrishna Gudipati if (fcs_port_attr.os_device_name[0] != '\0') { 2105a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2106ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME); 210750444a34SMaggie templen = (u16) strlen(fcs_port_attr.os_device_name); 210850444a34SMaggie memcpy(attr->value, fcs_port_attr.os_device_name, templen); 210950444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 211050444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 211150444a34SMaggie len += templen; 2112a36c61f9SKrishna Gudipati ++count; 211350444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 211450444a34SMaggie sizeof(templen)); 2115a36c61f9SKrishna Gudipati } 2116a36c61f9SKrishna Gudipati /* 2117a36c61f9SKrishna Gudipati * Host Name 2118a36c61f9SKrishna Gudipati */ 2119a36c61f9SKrishna Gudipati if (fcs_port_attr.host_name[0] != '\0') { 2120a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2121ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME); 212250444a34SMaggie templen = (u16) strlen(fcs_port_attr.host_name); 212350444a34SMaggie memcpy(attr->value, fcs_port_attr.host_name, templen); 212450444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 212550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 212650444a34SMaggie len += templen; 2127a36c61f9SKrishna Gudipati ++count; 212850444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 212950444a34SMaggie sizeof(templen)); 2130a36c61f9SKrishna Gudipati } 2131a36c61f9SKrishna Gudipati 2132a36c61f9SKrishna Gudipati /* 2133a36c61f9SKrishna Gudipati * Update size of payload 2134a36c61f9SKrishna Gudipati */ 2135ba816ea8SJing Huang port_attrib->attr_count = cpu_to_be32(count); 21365fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 2137a36c61f9SKrishna Gudipati return len; 2138a36c61f9SKrishna Gudipati } 2139a36c61f9SKrishna Gudipati 2140a36c61f9SKrishna Gudipati static u16 2141a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2142a36c61f9SKrishna Gudipati { 2143a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2144a36c61f9SKrishna Gudipati struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; 2145a36c61f9SKrishna Gudipati u16 len; 2146a36c61f9SKrishna Gudipati 2147a36c61f9SKrishna Gudipati rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs)); 2148a36c61f9SKrishna Gudipati rprt->port_name = bfa_fcs_lport_get_pwwn(port); 2149a36c61f9SKrishna Gudipati 2150a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2151a36c61f9SKrishna Gudipati (u8 *) &rprt->port_attr_blk); 2152a36c61f9SKrishna Gudipati 2153a36c61f9SKrishna Gudipati len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); 2154a36c61f9SKrishna Gudipati 2155a36c61f9SKrishna Gudipati return len; 2156a36c61f9SKrishna Gudipati } 2157a36c61f9SKrishna Gudipati 2158a36c61f9SKrishna Gudipati static void 2159a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2160a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2161a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2162a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2163a36c61f9SKrishna Gudipati { 2164a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2165a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2166a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2167a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2168a36c61f9SKrishna Gudipati 2169a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2170a36c61f9SKrishna Gudipati 2171a36c61f9SKrishna Gudipati /* 2172a36c61f9SKrishna Gudipati * Sanity Checks 2173a36c61f9SKrishna Gudipati */ 2174a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2175a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2176a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2177a36c61f9SKrishna Gudipati return; 2178a36c61f9SKrishna Gudipati } 2179a36c61f9SKrishna Gudipati 2180a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2181ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2182a36c61f9SKrishna Gudipati 2183a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2184a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2185a36c61f9SKrishna Gudipati return; 2186a36c61f9SKrishna Gudipati } 2187a36c61f9SKrishna Gudipati 2188a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2189a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2190a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2191a36c61f9SKrishna Gudipati } 2192a36c61f9SKrishna Gudipati 21935fbe25c7SJing Huang /* 2194a36c61f9SKrishna Gudipati * RPA : Register Port Attributes. 2195a36c61f9SKrishna Gudipati */ 2196a36c61f9SKrishna Gudipati static void 2197a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2198a36c61f9SKrishna Gudipati { 2199a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2200a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2201a36c61f9SKrishna Gudipati struct fchs_s fchs; 2202a36c61f9SKrishna Gudipati u16 len, attr_len; 2203a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2204a36c61f9SKrishna Gudipati u8 *pyld; 2205a36c61f9SKrishna Gudipati 2206a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2207a36c61f9SKrishna Gudipati 2208c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 2209c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 2210a36c61f9SKrishna Gudipati if (!fcxp) { 2211a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2212c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE); 2213a36c61f9SKrishna Gudipati return; 2214a36c61f9SKrishna Gudipati } 2215a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2216a36c61f9SKrishna Gudipati 2217a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 22186a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2219a36c61f9SKrishna Gudipati 2220a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2221a36c61f9SKrishna Gudipati FDMI_RPA); 2222a36c61f9SKrishna Gudipati 22235fbe25c7SJing Huang attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi, 22245fbe25c7SJing Huang (u8 *) ((struct ct_hdr_s *) pyld + 1)); 2225a36c61f9SKrishna Gudipati 2226a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2227a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2228a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi, 2229a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2230a36c61f9SKrishna Gudipati 2231a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); 2232a36c61f9SKrishna Gudipati } 2233a36c61f9SKrishna Gudipati 2234a36c61f9SKrishna Gudipati static u16 2235a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2236a36c61f9SKrishna Gudipati { 2237a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2238a36c61f9SKrishna Gudipati struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; 2239a36c61f9SKrishna Gudipati u16 len; 2240a36c61f9SKrishna Gudipati 2241a36c61f9SKrishna Gudipati rpa->port_name = bfa_fcs_lport_get_pwwn(port); 2242a36c61f9SKrishna Gudipati 2243a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2244a36c61f9SKrishna Gudipati (u8 *) &rpa->port_attr_blk); 2245a36c61f9SKrishna Gudipati 2246a36c61f9SKrishna Gudipati len += sizeof(rpa->port_name); 2247a36c61f9SKrishna Gudipati 2248a36c61f9SKrishna Gudipati return len; 2249a36c61f9SKrishna Gudipati } 2250a36c61f9SKrishna Gudipati 2251a36c61f9SKrishna Gudipati static void 2252a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2253a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 2254a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 2255a36c61f9SKrishna Gudipati { 2256a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2257a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2258a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2259a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2260a36c61f9SKrishna Gudipati 2261a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2262a36c61f9SKrishna Gudipati 2263a36c61f9SKrishna Gudipati /* 2264a36c61f9SKrishna Gudipati * Sanity Checks 2265a36c61f9SKrishna Gudipati */ 2266a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2267a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2268a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2269a36c61f9SKrishna Gudipati return; 2270a36c61f9SKrishna Gudipati } 2271a36c61f9SKrishna Gudipati 2272a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2273ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2274a36c61f9SKrishna Gudipati 2275a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2276a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2277a36c61f9SKrishna Gudipati return; 2278a36c61f9SKrishna Gudipati } 2279a36c61f9SKrishna Gudipati 2280a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2281a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2282a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2283a36c61f9SKrishna Gudipati } 2284a36c61f9SKrishna Gudipati 2285a36c61f9SKrishna Gudipati static void 2286a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg) 2287a36c61f9SKrishna Gudipati { 2288a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg; 2289a36c61f9SKrishna Gudipati 2290a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); 2291a36c61f9SKrishna Gudipati } 2292a36c61f9SKrishna Gudipati 229352f94b6fSMaggie static void 2294a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2295a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr) 2296a36c61f9SKrishna Gudipati { 2297a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2298a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2299a36c61f9SKrishna Gudipati 23006a18b167SJing Huang memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 2301a36c61f9SKrishna Gudipati 2302a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, 2303a36c61f9SKrishna Gudipati hba_attr->manufacturer); 2304a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, 2305a36c61f9SKrishna Gudipati hba_attr->serial_num); 2306a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2307a36c61f9SKrishna Gudipati hba_attr->model); 2308a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2309a36c61f9SKrishna Gudipati hba_attr->model_desc); 2310a36c61f9SKrishna Gudipati bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, 2311a36c61f9SKrishna Gudipati hba_attr->hw_version); 2312a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, 2313a36c61f9SKrishna Gudipati hba_attr->option_rom_ver); 2314a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, 2315a36c61f9SKrishna Gudipati hba_attr->fw_version); 2316a36c61f9SKrishna Gudipati 2317a36c61f9SKrishna Gudipati strncpy(hba_attr->driver_version, (char *)driver_info->version, 2318a36c61f9SKrishna Gudipati sizeof(hba_attr->driver_version)); 2319a36c61f9SKrishna Gudipati 2320a36c61f9SKrishna Gudipati strncpy(hba_attr->os_name, driver_info->host_os_name, 2321a36c61f9SKrishna Gudipati sizeof(hba_attr->os_name)); 2322a36c61f9SKrishna Gudipati 2323a36c61f9SKrishna Gudipati /* 2324a36c61f9SKrishna Gudipati * If there is a patch level, append it 2325a36c61f9SKrishna Gudipati * to the os name along with a separator 2326a36c61f9SKrishna Gudipati */ 2327a36c61f9SKrishna Gudipati if (driver_info->host_os_patch[0] != '\0') { 2328a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 2329a36c61f9SKrishna Gudipati sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); 2330a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, driver_info->host_os_patch, 2331a36c61f9SKrishna Gudipati sizeof(driver_info->host_os_patch)); 2332a36c61f9SKrishna Gudipati } 2333a36c61f9SKrishna Gudipati 2334ba816ea8SJing Huang hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ); 2335a36c61f9SKrishna Gudipati } 2336a36c61f9SKrishna Gudipati 233752f94b6fSMaggie static void 2338a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2339a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr) 2340a36c61f9SKrishna Gudipati { 2341a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2342a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2343a36c61f9SKrishna Gudipati struct bfa_port_attr_s pport_attr; 2344a36c61f9SKrishna Gudipati 23456a18b167SJing Huang memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); 2346a36c61f9SKrishna Gudipati 2347a36c61f9SKrishna Gudipati /* 2348a36c61f9SKrishna Gudipati * get pport attributes from hal 2349a36c61f9SKrishna Gudipati */ 2350a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 2351a36c61f9SKrishna Gudipati 2352a36c61f9SKrishna Gudipati /* 2353a36c61f9SKrishna Gudipati * get FC4 type Bitmask 2354a36c61f9SKrishna Gudipati */ 2355a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); 2356a36c61f9SKrishna Gudipati 2357a36c61f9SKrishna Gudipati /* 2358a36c61f9SKrishna Gudipati * Supported Speeds 2359a36c61f9SKrishna Gudipati */ 2360d7be54ccSKrishna Gudipati switch (pport_attr.speed_supported) { 2361d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2362d7be54ccSKrishna Gudipati port_attr->supp_speed = 2363d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G); 2364d7be54ccSKrishna Gudipati break; 2365d7be54ccSKrishna Gudipati 2366d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2367d7be54ccSKrishna Gudipati port_attr->supp_speed = 2368d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G); 2369d7be54ccSKrishna Gudipati break; 2370d7be54ccSKrishna Gudipati 2371d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2372d7be54ccSKrishna Gudipati port_attr->supp_speed = 2373d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G); 2374d7be54ccSKrishna Gudipati break; 2375d7be54ccSKrishna Gudipati 2376d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2377d7be54ccSKrishna Gudipati port_attr->supp_speed = 2378d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G); 2379d7be54ccSKrishna Gudipati break; 2380d7be54ccSKrishna Gudipati 2381d7be54ccSKrishna Gudipati default: 2382d7be54ccSKrishna Gudipati bfa_sm_fault(port->fcs, pport_attr.speed_supported); 2383d7be54ccSKrishna Gudipati } 2384a36c61f9SKrishna Gudipati 2385a36c61f9SKrishna Gudipati /* 2386a36c61f9SKrishna Gudipati * Current Speed 2387a36c61f9SKrishna Gudipati */ 2388d7be54ccSKrishna Gudipati port_attr->curr_speed = cpu_to_be32( 2389d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(pport_attr.speed)); 2390a36c61f9SKrishna Gudipati 2391a36c61f9SKrishna Gudipati /* 2392a36c61f9SKrishna Gudipati * Max PDU Size. 2393a36c61f9SKrishna Gudipati */ 2394ba816ea8SJing Huang port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ); 2395a36c61f9SKrishna Gudipati 2396a36c61f9SKrishna Gudipati /* 2397a36c61f9SKrishna Gudipati * OS device Name 2398a36c61f9SKrishna Gudipati */ 2399a36c61f9SKrishna Gudipati strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, 2400a36c61f9SKrishna Gudipati sizeof(port_attr->os_device_name)); 2401a36c61f9SKrishna Gudipati 2402a36c61f9SKrishna Gudipati /* 2403a36c61f9SKrishna Gudipati * Host name 2404a36c61f9SKrishna Gudipati */ 2405a36c61f9SKrishna Gudipati strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, 2406a36c61f9SKrishna Gudipati sizeof(port_attr->host_name)); 24077725ccfdSJing Huang 24087725ccfdSJing Huang } 24097725ccfdSJing Huang 2410d7be54ccSKrishna Gudipati /* 2411d7be54ccSKrishna Gudipati * Convert BFA speed to FDMI format. 2412d7be54ccSKrishna Gudipati */ 2413d7be54ccSKrishna Gudipati u32 2414d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed) 2415d7be54ccSKrishna Gudipati { 2416d7be54ccSKrishna Gudipati u32 ret; 2417d7be54ccSKrishna Gudipati 2418d7be54ccSKrishna Gudipati switch (pport_speed) { 2419d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_1GBPS: 2420d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_2GBPS: 2421d7be54ccSKrishna Gudipati ret = pport_speed; 2422d7be54ccSKrishna Gudipati break; 2423d7be54ccSKrishna Gudipati 2424d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2425d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_4G; 2426d7be54ccSKrishna Gudipati break; 2427d7be54ccSKrishna Gudipati 2428d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2429d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_8G; 2430d7be54ccSKrishna Gudipati break; 2431d7be54ccSKrishna Gudipati 2432d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2433d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_10G; 2434d7be54ccSKrishna Gudipati break; 2435d7be54ccSKrishna Gudipati 2436d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2437d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_16G; 2438d7be54ccSKrishna Gudipati break; 2439d7be54ccSKrishna Gudipati 2440d7be54ccSKrishna Gudipati default: 2441d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_UNKNOWN; 2442d7be54ccSKrishna Gudipati } 2443d7be54ccSKrishna Gudipati return ret; 2444d7be54ccSKrishna Gudipati } 24457725ccfdSJing Huang 2446a36c61f9SKrishna Gudipati void 2447a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) 2448a36c61f9SKrishna Gudipati { 2449a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2450a36c61f9SKrishna Gudipati 2451a36c61f9SKrishna Gudipati fdmi->ms = ms; 2452a36c61f9SKrishna Gudipati if (ms->port->fcs->fdmi_enabled) 2453a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 2454a36c61f9SKrishna Gudipati else 2455a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled); 2456a36c61f9SKrishna Gudipati } 2457a36c61f9SKrishna Gudipati 2458a36c61f9SKrishna Gudipati void 2459a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms) 2460a36c61f9SKrishna Gudipati { 2461a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2462a36c61f9SKrishna Gudipati 2463a36c61f9SKrishna Gudipati fdmi->ms = ms; 2464a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); 2465a36c61f9SKrishna Gudipati } 2466a36c61f9SKrishna Gudipati 2467a36c61f9SKrishna Gudipati void 2468a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms) 2469a36c61f9SKrishna Gudipati { 2470a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2471a36c61f9SKrishna Gudipati 2472a36c61f9SKrishna Gudipati fdmi->ms = ms; 2473a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); 2474a36c61f9SKrishna Gudipati } 2475a36c61f9SKrishna Gudipati 2476a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES 2 2477a36c61f9SKrishna Gudipati 2478a36c61f9SKrishna Gudipati /* 2479a36c61f9SKrishna Gudipati * forward declarations 2480a36c61f9SKrishna Gudipati */ 2481a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, 2482a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2483a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_timeout(void *arg); 2484a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_plogi_response(void *fcsarg, 2485a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2486a36c61f9SKrishna Gudipati void *cbarg, 2487a36c61f9SKrishna Gudipati bfa_status_t req_status, 2488a36c61f9SKrishna Gudipati u32 rsp_len, 2489a36c61f9SKrishna Gudipati u32 resid_len, 2490a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2491a36c61f9SKrishna Gudipati 2492a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, 2493a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2494a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gmal_response(void *fcsarg, 2495a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2496a36c61f9SKrishna Gudipati void *cbarg, 2497a36c61f9SKrishna Gudipati bfa_status_t req_status, 2498a36c61f9SKrishna Gudipati u32 rsp_len, 2499a36c61f9SKrishna Gudipati u32 resid_len, 2500a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2501a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, 2502a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2503a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gfn_response(void *fcsarg, 2504a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2505a36c61f9SKrishna Gudipati void *cbarg, 2506a36c61f9SKrishna Gudipati bfa_status_t req_status, 2507a36c61f9SKrishna Gudipati u32 rsp_len, 2508a36c61f9SKrishna Gudipati u32 resid_len, 2509a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 25105fbe25c7SJing Huang /* 2511a36c61f9SKrishna Gudipati * fcs_ms_sm FCS MS state machine 2512a36c61f9SKrishna Gudipati */ 2513a36c61f9SKrishna Gudipati 25145fbe25c7SJing Huang /* 2515a36c61f9SKrishna Gudipati * MS State Machine events 2516a36c61f9SKrishna Gudipati */ 2517a36c61f9SKrishna Gudipati enum port_ms_event { 2518a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_ONLINE = 1, 2519a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_OFFLINE = 2, 2520a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_OK = 3, 2521a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_ERROR = 4, 2522a36c61f9SKrishna Gudipati MSSM_EVENT_TIMEOUT = 5, 2523a36c61f9SKrishna Gudipati MSSM_EVENT_FCXP_SENT = 6, 2524a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_FABRIC_RSCN = 7 2525a36c61f9SKrishna Gudipati }; 2526a36c61f9SKrishna Gudipati 2527a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2528a36c61f9SKrishna Gudipati enum port_ms_event event); 2529a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2530a36c61f9SKrishna Gudipati enum port_ms_event event); 2531a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2532a36c61f9SKrishna Gudipati enum port_ms_event event); 2533a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2534a36c61f9SKrishna Gudipati enum port_ms_event event); 2535a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2536a36c61f9SKrishna Gudipati enum port_ms_event event); 2537a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2538a36c61f9SKrishna Gudipati enum port_ms_event event); 2539a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2540a36c61f9SKrishna Gudipati enum port_ms_event event); 2541a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2542a36c61f9SKrishna Gudipati enum port_ms_event event); 2543a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2544a36c61f9SKrishna Gudipati enum port_ms_event event); 2545a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2546a36c61f9SKrishna Gudipati enum port_ms_event event); 2547a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2548a36c61f9SKrishna Gudipati enum port_ms_event event); 25495fbe25c7SJing Huang /* 2550a36c61f9SKrishna Gudipati * Start in offline state - awaiting NS to send start. 2551a36c61f9SKrishna Gudipati */ 2552a36c61f9SKrishna Gudipati static void 2553a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2554a36c61f9SKrishna Gudipati enum port_ms_event event) 2555a36c61f9SKrishna Gudipati { 2556a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2557a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2558a36c61f9SKrishna Gudipati 2559a36c61f9SKrishna Gudipati switch (event) { 2560a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_ONLINE: 2561a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2562a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2563a36c61f9SKrishna Gudipati break; 2564a36c61f9SKrishna Gudipati 2565a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2566a36c61f9SKrishna Gudipati break; 2567a36c61f9SKrishna Gudipati 2568a36c61f9SKrishna Gudipati default: 2569a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2570a36c61f9SKrishna Gudipati } 2571a36c61f9SKrishna Gudipati } 2572a36c61f9SKrishna Gudipati 2573a36c61f9SKrishna Gudipati static void 2574a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2575a36c61f9SKrishna Gudipati enum port_ms_event event) 2576a36c61f9SKrishna Gudipati { 2577a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2578a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2579a36c61f9SKrishna Gudipati 2580a36c61f9SKrishna Gudipati switch (event) { 2581a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2582a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi); 2583a36c61f9SKrishna Gudipati break; 2584a36c61f9SKrishna Gudipati 2585a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2586a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2587a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2588a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2589a36c61f9SKrishna Gudipati break; 2590a36c61f9SKrishna Gudipati 2591a36c61f9SKrishna Gudipati default: 2592a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2593a36c61f9SKrishna Gudipati } 2594a36c61f9SKrishna Gudipati } 2595a36c61f9SKrishna Gudipati 2596a36c61f9SKrishna Gudipati static void 2597a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2598a36c61f9SKrishna Gudipati enum port_ms_event event) 2599a36c61f9SKrishna Gudipati { 2600a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2601a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2602a36c61f9SKrishna Gudipati 2603a36c61f9SKrishna Gudipati switch (event) { 2604a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2605a36c61f9SKrishna Gudipati /* 2606a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2607a36c61f9SKrishna Gudipati */ 2608a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry); 2609a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2610a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2611a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2612a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2613a36c61f9SKrishna Gudipati break; 2614a36c61f9SKrishna Gudipati 2615a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2616a36c61f9SKrishna Gudipati /* 2617a36c61f9SKrishna Gudipati * since plogi is done, now invoke MS related sub-modules 2618a36c61f9SKrishna Gudipati */ 2619a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(ms); 2620a36c61f9SKrishna Gudipati 26215fbe25c7SJing Huang /* 2622a36c61f9SKrishna Gudipati * if this is a Vport, go to online state. 2623a36c61f9SKrishna Gudipati */ 2624a36c61f9SKrishna Gudipati if (ms->port->vport) { 2625a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2626a36c61f9SKrishna Gudipati break; 2627a36c61f9SKrishna Gudipati } 2628a36c61f9SKrishna Gudipati 2629a36c61f9SKrishna Gudipati /* 2630a36c61f9SKrishna Gudipati * For a base port we need to get the 2631a36c61f9SKrishna Gudipati * switch's IP address. 2632a36c61f9SKrishna Gudipati */ 2633a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2634a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2635a36c61f9SKrishna Gudipati break; 2636a36c61f9SKrishna Gudipati 2637a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2638a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2639a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2640a36c61f9SKrishna Gudipati break; 2641a36c61f9SKrishna Gudipati 2642a36c61f9SKrishna Gudipati default: 2643a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2644a36c61f9SKrishna Gudipati } 2645a36c61f9SKrishna Gudipati } 2646a36c61f9SKrishna Gudipati 2647a36c61f9SKrishna Gudipati static void 2648a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2649a36c61f9SKrishna Gudipati enum port_ms_event event) 2650a36c61f9SKrishna Gudipati { 2651a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2652a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2653a36c61f9SKrishna Gudipati 2654a36c61f9SKrishna Gudipati switch (event) { 2655a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2656a36c61f9SKrishna Gudipati /* 2657a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2658a36c61f9SKrishna Gudipati */ 2659a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2660a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2661a36c61f9SKrishna Gudipati break; 2662a36c61f9SKrishna Gudipati 2663a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2664a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2665a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2666a36c61f9SKrishna Gudipati break; 2667a36c61f9SKrishna Gudipati 2668a36c61f9SKrishna Gudipati default: 2669a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2670a36c61f9SKrishna Gudipati } 2671a36c61f9SKrishna Gudipati } 2672a36c61f9SKrishna Gudipati 2673a36c61f9SKrishna Gudipati static void 2674a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2675a36c61f9SKrishna Gudipati enum port_ms_event event) 2676a36c61f9SKrishna Gudipati { 2677a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2678a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2679a36c61f9SKrishna Gudipati 2680a36c61f9SKrishna Gudipati switch (event) { 2681a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2682a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2683a36c61f9SKrishna Gudipati break; 2684a36c61f9SKrishna Gudipati 2685a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_FABRIC_RSCN: 2686a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2687a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2688a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2689a36c61f9SKrishna Gudipati break; 2690a36c61f9SKrishna Gudipati 2691a36c61f9SKrishna Gudipati default: 2692a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2693a36c61f9SKrishna Gudipati } 2694a36c61f9SKrishna Gudipati } 2695a36c61f9SKrishna Gudipati 2696a36c61f9SKrishna Gudipati static void 2697a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2698a36c61f9SKrishna Gudipati enum port_ms_event event) 2699a36c61f9SKrishna Gudipati { 2700a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2701a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2702a36c61f9SKrishna Gudipati 2703a36c61f9SKrishna Gudipati switch (event) { 2704a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2705a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal); 2706a36c61f9SKrishna Gudipati break; 2707a36c61f9SKrishna Gudipati 2708a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2709a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2710a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2711a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2712a36c61f9SKrishna Gudipati break; 2713a36c61f9SKrishna Gudipati 2714a36c61f9SKrishna Gudipati default: 2715a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2716a36c61f9SKrishna Gudipati } 2717a36c61f9SKrishna Gudipati } 2718a36c61f9SKrishna Gudipati 2719a36c61f9SKrishna Gudipati static void 2720a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2721a36c61f9SKrishna Gudipati enum port_ms_event event) 2722a36c61f9SKrishna Gudipati { 2723a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2724a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2725a36c61f9SKrishna Gudipati 2726a36c61f9SKrishna Gudipati switch (event) { 2727a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2728a36c61f9SKrishna Gudipati /* 2729a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2730a36c61f9SKrishna Gudipati */ 2731a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2732a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry); 2733a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2734a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2735a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2736a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2737a36c61f9SKrishna Gudipati } else { 2738a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2739a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2740a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2741a36c61f9SKrishna Gudipati } 2742a36c61f9SKrishna Gudipati break; 2743a36c61f9SKrishna Gudipati 2744a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2745a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2746a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2747a36c61f9SKrishna Gudipati break; 2748a36c61f9SKrishna Gudipati 2749a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2750a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2751a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2752a36c61f9SKrishna Gudipati break; 2753a36c61f9SKrishna Gudipati 2754a36c61f9SKrishna Gudipati default: 2755a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2756a36c61f9SKrishna Gudipati } 2757a36c61f9SKrishna Gudipati } 2758a36c61f9SKrishna Gudipati 2759a36c61f9SKrishna Gudipati static void 2760a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2761a36c61f9SKrishna Gudipati enum port_ms_event event) 2762a36c61f9SKrishna Gudipati { 2763a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2764a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2765a36c61f9SKrishna Gudipati 2766a36c61f9SKrishna Gudipati switch (event) { 2767a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2768a36c61f9SKrishna Gudipati /* 2769a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2770a36c61f9SKrishna Gudipati */ 2771a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2772a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2773a36c61f9SKrishna Gudipati break; 2774a36c61f9SKrishna Gudipati 2775a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2776a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2777a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2778a36c61f9SKrishna Gudipati break; 2779a36c61f9SKrishna Gudipati 2780a36c61f9SKrishna Gudipati default: 2781a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2782a36c61f9SKrishna Gudipati } 2783a36c61f9SKrishna Gudipati } 27845fbe25c7SJing Huang /* 2785a36c61f9SKrishna Gudipati * ms_pvt MS local functions 2786a36c61f9SKrishna Gudipati */ 2787a36c61f9SKrishna Gudipati 2788a36c61f9SKrishna Gudipati static void 2789a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2790a36c61f9SKrishna Gudipati { 2791a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2792a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2793a36c61f9SKrishna Gudipati struct fchs_s fchs; 2794a36c61f9SKrishna Gudipati int len; 2795a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2796a36c61f9SKrishna Gudipati 2797a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 2798a36c61f9SKrishna Gudipati 2799c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 2800c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 2801a36c61f9SKrishna Gudipati if (!fcxp) { 2802a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2803c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE); 2804a36c61f9SKrishna Gudipati return; 2805a36c61f9SKrishna Gudipati } 2806a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 2807a36c61f9SKrishna Gudipati 2808a36c61f9SKrishna Gudipati len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2809a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 2810f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 2811a36c61f9SKrishna Gudipati 2812a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2813a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 2814a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response, (void *)ms, 2815a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2816a36c61f9SKrishna Gudipati 2817a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2818a36c61f9SKrishna Gudipati } 2819a36c61f9SKrishna Gudipati 2820a36c61f9SKrishna Gudipati static void 2821a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2822a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2823a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2824a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2825a36c61f9SKrishna Gudipati { 2826a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2827a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2828a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2829a36c61f9SKrishna Gudipati struct fcgs_gmal_resp_s *gmal_resp; 2830a36c61f9SKrishna Gudipati struct fcgs_gmal_entry_s *gmal_entry; 2831a36c61f9SKrishna Gudipati u32 num_entries; 2832a36c61f9SKrishna Gudipati u8 *rsp_str; 2833a36c61f9SKrishna Gudipati 2834a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2835a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2836a36c61f9SKrishna Gudipati 2837a36c61f9SKrishna Gudipati /* 2838a36c61f9SKrishna Gudipati * Sanity Checks 2839a36c61f9SKrishna Gudipati */ 2840a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2841a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2842a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2843a36c61f9SKrishna Gudipati return; 2844a36c61f9SKrishna Gudipati } 2845a36c61f9SKrishna Gudipati 2846a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2847ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2848a36c61f9SKrishna Gudipati 2849a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2850a36c61f9SKrishna Gudipati gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); 2851a36c61f9SKrishna Gudipati 2852ba816ea8SJing Huang num_entries = be32_to_cpu(gmal_resp->ms_len); 2853a36c61f9SKrishna Gudipati if (num_entries == 0) { 2854a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2855a36c61f9SKrishna Gudipati return; 2856a36c61f9SKrishna Gudipati } 2857a36c61f9SKrishna Gudipati /* 2858a36c61f9SKrishna Gudipati * The response could contain multiple Entries. 2859a36c61f9SKrishna Gudipati * Entries for SNMP interface, etc. 2860a36c61f9SKrishna Gudipati * We look for the entry with a telnet prefix. 2861a36c61f9SKrishna Gudipati * First "http://" entry refers to IP addr 2862a36c61f9SKrishna Gudipati */ 2863a36c61f9SKrishna Gudipati 2864a36c61f9SKrishna Gudipati gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma; 2865a36c61f9SKrishna Gudipati while (num_entries > 0) { 2866a36c61f9SKrishna Gudipati if (strncmp(gmal_entry->prefix, 2867a36c61f9SKrishna Gudipati CT_GMAL_RESP_PREFIX_HTTP, 2868a36c61f9SKrishna Gudipati sizeof(gmal_entry->prefix)) == 0) { 2869a36c61f9SKrishna Gudipati 2870a36c61f9SKrishna Gudipati /* 2871a36c61f9SKrishna Gudipati * if the IP address is terminating with a '/', 2872a36c61f9SKrishna Gudipati * remove it. 2873a36c61f9SKrishna Gudipati * Byte 0 consists of the length of the string. 2874a36c61f9SKrishna Gudipati */ 2875a36c61f9SKrishna Gudipati rsp_str = &(gmal_entry->prefix[0]); 2876a36c61f9SKrishna Gudipati if (rsp_str[gmal_entry->len-1] == '/') 2877a36c61f9SKrishna Gudipati rsp_str[gmal_entry->len-1] = 0; 2878a36c61f9SKrishna Gudipati 2879a36c61f9SKrishna Gudipati /* copy IP Address to fabric */ 2880a36c61f9SKrishna Gudipati strncpy(bfa_fcs_lport_get_fabric_ipaddr(port), 2881a36c61f9SKrishna Gudipati gmal_entry->ip_addr, 2882a36c61f9SKrishna Gudipati BFA_FCS_FABRIC_IPADDR_SZ); 2883a36c61f9SKrishna Gudipati break; 2884a36c61f9SKrishna Gudipati } else { 2885a36c61f9SKrishna Gudipati --num_entries; 2886a36c61f9SKrishna Gudipati ++gmal_entry; 2887a36c61f9SKrishna Gudipati } 2888a36c61f9SKrishna Gudipati } 2889a36c61f9SKrishna Gudipati 2890a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2891a36c61f9SKrishna Gudipati return; 2892a36c61f9SKrishna Gudipati } 2893a36c61f9SKrishna Gudipati 2894a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2895a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2896a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2897a36c61f9SKrishna Gudipati } 2898a36c61f9SKrishna Gudipati 2899a36c61f9SKrishna Gudipati static void 2900a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(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_FCXP_SENT: 2908a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn); 2909a36c61f9SKrishna Gudipati break; 2910a36c61f9SKrishna Gudipati 2911a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2912a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2913a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2914a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2915a36c61f9SKrishna Gudipati break; 2916a36c61f9SKrishna Gudipati 2917a36c61f9SKrishna Gudipati default: 2918a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2919a36c61f9SKrishna Gudipati } 2920a36c61f9SKrishna Gudipati } 2921a36c61f9SKrishna Gudipati 2922a36c61f9SKrishna Gudipati static void 2923a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2924a36c61f9SKrishna Gudipati enum port_ms_event event) 2925a36c61f9SKrishna Gudipati { 2926a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2927a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2928a36c61f9SKrishna Gudipati 2929a36c61f9SKrishna Gudipati switch (event) { 2930a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2931a36c61f9SKrishna Gudipati /* 2932a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2933a36c61f9SKrishna Gudipati */ 2934a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2935a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry); 2936a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2937a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2938a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2939a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2940a36c61f9SKrishna Gudipati } else { 2941a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2942a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2943a36c61f9SKrishna Gudipati } 2944a36c61f9SKrishna Gudipati break; 2945a36c61f9SKrishna Gudipati 2946a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2947a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2948a36c61f9SKrishna Gudipati break; 2949a36c61f9SKrishna Gudipati 2950a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2951a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2952a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2953a36c61f9SKrishna Gudipati break; 2954a36c61f9SKrishna Gudipati 2955a36c61f9SKrishna Gudipati default: 2956a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2957a36c61f9SKrishna Gudipati } 2958a36c61f9SKrishna Gudipati } 2959a36c61f9SKrishna Gudipati 2960a36c61f9SKrishna Gudipati static void 2961a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2962a36c61f9SKrishna Gudipati enum port_ms_event event) 2963a36c61f9SKrishna Gudipati { 2964a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2965a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2966a36c61f9SKrishna Gudipati 2967a36c61f9SKrishna Gudipati switch (event) { 2968a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2969a36c61f9SKrishna Gudipati /* 2970a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2971a36c61f9SKrishna Gudipati */ 2972a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2973a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2974a36c61f9SKrishna Gudipati break; 2975a36c61f9SKrishna Gudipati 2976a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2977a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2978a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2979a36c61f9SKrishna Gudipati break; 2980a36c61f9SKrishna Gudipati 2981a36c61f9SKrishna Gudipati default: 2982a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2983a36c61f9SKrishna Gudipati } 2984a36c61f9SKrishna Gudipati } 29855fbe25c7SJing Huang /* 2986a36c61f9SKrishna Gudipati * ms_pvt MS local functions 2987a36c61f9SKrishna Gudipati */ 2988a36c61f9SKrishna Gudipati 2989a36c61f9SKrishna Gudipati static void 2990a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2991a36c61f9SKrishna Gudipati { 2992a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2993a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2994a36c61f9SKrishna Gudipati struct fchs_s fchs; 2995a36c61f9SKrishna Gudipati int len; 2996a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2997a36c61f9SKrishna Gudipati 2998a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 2999a36c61f9SKrishna Gudipati 3000c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3001c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3002a36c61f9SKrishna Gudipati if (!fcxp) { 3003a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3004c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE); 3005a36c61f9SKrishna Gudipati return; 3006a36c61f9SKrishna Gudipati } 3007a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3008a36c61f9SKrishna Gudipati 3009a36c61f9SKrishna Gudipati len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3010a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 3011f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 3012a36c61f9SKrishna Gudipati 3013a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3014a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3015a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response, (void *)ms, 3016a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3017a36c61f9SKrishna Gudipati 3018a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3019a36c61f9SKrishna Gudipati } 3020a36c61f9SKrishna Gudipati 3021a36c61f9SKrishna Gudipati static void 3022a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3023a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 3024a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 3025a36c61f9SKrishna Gudipati { 3026a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3027a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3028a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3029a36c61f9SKrishna Gudipati wwn_t *gfn_resp; 3030a36c61f9SKrishna Gudipati 3031a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3032a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3033a36c61f9SKrishna Gudipati 3034a36c61f9SKrishna Gudipati /* 3035a36c61f9SKrishna Gudipati * Sanity Checks 3036a36c61f9SKrishna Gudipati */ 3037a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3038a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3039a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3040a36c61f9SKrishna Gudipati return; 3041a36c61f9SKrishna Gudipati } 3042a36c61f9SKrishna Gudipati 3043a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3044ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3045a36c61f9SKrishna Gudipati 3046a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3047a36c61f9SKrishna Gudipati gfn_resp = (wwn_t *)(cthdr + 1); 3048a36c61f9SKrishna Gudipati /* check if it has actually changed */ 3049a36c61f9SKrishna Gudipati if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port), 3050a36c61f9SKrishna Gudipati gfn_resp, sizeof(wwn_t)) != 0)) { 3051a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); 3052a36c61f9SKrishna Gudipati } 3053a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3054a36c61f9SKrishna Gudipati return; 3055a36c61f9SKrishna Gudipati } 3056a36c61f9SKrishna Gudipati 3057a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3058a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3059a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3060a36c61f9SKrishna Gudipati } 3061a36c61f9SKrishna Gudipati 30625fbe25c7SJing Huang /* 3063a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3064a36c61f9SKrishna Gudipati */ 3065a36c61f9SKrishna Gudipati 3066a36c61f9SKrishna Gudipati static void 3067a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3068a36c61f9SKrishna Gudipati { 3069a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3070a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3071a36c61f9SKrishna Gudipati struct fchs_s fchs; 3072a36c61f9SKrishna Gudipati int len; 3073a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3074a36c61f9SKrishna Gudipati 3075a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3076a36c61f9SKrishna Gudipati 3077c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3078c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3079a36c61f9SKrishna Gudipati if (!fcxp) { 3080a36c61f9SKrishna Gudipati port->stats.ms_plogi_alloc_wait++; 3081a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3082c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE); 3083a36c61f9SKrishna Gudipati return; 3084a36c61f9SKrishna Gudipati } 3085a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3086a36c61f9SKrishna Gudipati 3087a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3088f16a1750SMaggie Zhang bfa_hton3b(FC_MGMT_SERVER), 3089a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3090a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 3091be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 3092be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3093a36c61f9SKrishna Gudipati 3094a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3095a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3096a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response, (void *)ms, 3097a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 3098a36c61f9SKrishna Gudipati 3099a36c61f9SKrishna Gudipati port->stats.ms_plogi_sent++; 3100a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3101a36c61f9SKrishna Gudipati } 3102a36c61f9SKrishna Gudipati 3103a36c61f9SKrishna Gudipati static void 3104a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3105a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3106a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) 3107a36c61f9SKrishna Gudipati { 3108a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3109a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3110a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 3111a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3112a36c61f9SKrishna Gudipati 3113a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3114a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3115a36c61f9SKrishna Gudipati 3116a36c61f9SKrishna Gudipati /* 3117a36c61f9SKrishna Gudipati * Sanity Checks 3118a36c61f9SKrishna Gudipati */ 3119a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3120a36c61f9SKrishna Gudipati port->stats.ms_plogi_rsp_err++; 3121a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3122a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3123a36c61f9SKrishna Gudipati return; 3124a36c61f9SKrishna Gudipati } 3125a36c61f9SKrishna Gudipati 3126a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3127a36c61f9SKrishna Gudipati 3128a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 3129a36c61f9SKrishna Gudipati 3130a36c61f9SKrishna Gudipati case FC_ELS_ACC: 3131a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 3132a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 3133a36c61f9SKrishna Gudipati port->stats.ms_plogi_acc_err++; 3134a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3135a36c61f9SKrishna Gudipati break; 3136a36c61f9SKrishna Gudipati } 3137a36c61f9SKrishna Gudipati port->stats.ms_plogi_accepts++; 3138a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3139a36c61f9SKrishna Gudipati break; 3140a36c61f9SKrishna Gudipati 3141a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 3142a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3143a36c61f9SKrishna Gudipati 3144a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 3145a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3146a36c61f9SKrishna Gudipati 3147a36c61f9SKrishna Gudipati port->stats.ms_rejects++; 3148a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3149a36c61f9SKrishna Gudipati break; 3150a36c61f9SKrishna Gudipati 3151a36c61f9SKrishna Gudipati default: 3152a36c61f9SKrishna Gudipati port->stats.ms_plogi_unknown_rsp++; 3153a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 3154a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3155a36c61f9SKrishna Gudipati } 3156a36c61f9SKrishna Gudipati } 3157a36c61f9SKrishna Gudipati 3158a36c61f9SKrishna Gudipati static void 3159a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg) 3160a36c61f9SKrishna Gudipati { 3161a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg; 3162a36c61f9SKrishna Gudipati 3163a36c61f9SKrishna Gudipati ms->port->stats.ms_timeouts++; 3164a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT); 3165a36c61f9SKrishna Gudipati } 3166a36c61f9SKrishna Gudipati 3167a36c61f9SKrishna Gudipati 3168a36c61f9SKrishna Gudipati void 3169a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port) 3170a36c61f9SKrishna Gudipati { 3171a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3172a36c61f9SKrishna Gudipati 3173a36c61f9SKrishna Gudipati ms->port = port; 3174a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3175a36c61f9SKrishna Gudipati 3176a36c61f9SKrishna Gudipati /* 3177a36c61f9SKrishna Gudipati * Invoke init routines of sub modules. 3178a36c61f9SKrishna Gudipati */ 3179a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(ms); 3180a36c61f9SKrishna Gudipati } 3181a36c61f9SKrishna Gudipati 3182a36c61f9SKrishna Gudipati void 3183a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port) 3184a36c61f9SKrishna Gudipati { 3185a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3186a36c61f9SKrishna Gudipati 3187a36c61f9SKrishna Gudipati ms->port = port; 3188a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); 3189a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(ms); 3190a36c61f9SKrishna Gudipati } 3191a36c61f9SKrishna Gudipati 3192a36c61f9SKrishna Gudipati void 3193a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port) 3194a36c61f9SKrishna Gudipati { 3195a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3196a36c61f9SKrishna Gudipati 3197a36c61f9SKrishna Gudipati ms->port = port; 3198a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE); 3199a36c61f9SKrishna Gudipati } 3200a36c61f9SKrishna Gudipati void 3201a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port) 3202a36c61f9SKrishna Gudipati { 3203a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3204a36c61f9SKrishna Gudipati 3205a36c61f9SKrishna Gudipati /* todo. Handle this only when in Online state */ 3206a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online)) 3207a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN); 3208a36c61f9SKrishna Gudipati } 3209a36c61f9SKrishna Gudipati 32105fbe25c7SJing Huang /* 3211a36c61f9SKrishna Gudipati * @page ns_sm_info VPORT NS State Machine 3212a36c61f9SKrishna Gudipati * 3213a36c61f9SKrishna Gudipati * @section ns_sm_interactions VPORT NS State Machine Interactions 3214a36c61f9SKrishna Gudipati * 3215a36c61f9SKrishna Gudipati * @section ns_sm VPORT NS State Machine 3216a36c61f9SKrishna Gudipati * img ns_sm.jpg 3217a36c61f9SKrishna Gudipati */ 3218a36c61f9SKrishna Gudipati 3219a36c61f9SKrishna Gudipati /* 3220a36c61f9SKrishna Gudipati * forward declarations 3221a36c61f9SKrishna Gudipati */ 3222a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, 3223a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3224a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, 3225a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3226a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, 3227a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3228a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, 3229a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3230a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, 3231a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3232a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_timeout(void *arg); 3233a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_plogi_response(void *fcsarg, 3234a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3235a36c61f9SKrishna Gudipati void *cbarg, 3236a36c61f9SKrishna Gudipati bfa_status_t req_status, 3237a36c61f9SKrishna Gudipati u32 rsp_len, 3238a36c61f9SKrishna Gudipati u32 resid_len, 3239a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3240a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, 3241a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3242a36c61f9SKrishna Gudipati void *cbarg, 3243a36c61f9SKrishna Gudipati bfa_status_t req_status, 3244a36c61f9SKrishna Gudipati u32 rsp_len, 3245a36c61f9SKrishna Gudipati u32 resid_len, 3246a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3247a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg, 3248a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3249a36c61f9SKrishna Gudipati void *cbarg, 3250a36c61f9SKrishna Gudipati bfa_status_t req_status, 3251a36c61f9SKrishna Gudipati u32 rsp_len, 3252a36c61f9SKrishna Gudipati u32 resid_len, 3253a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3254a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg, 3255a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3256a36c61f9SKrishna Gudipati void *cbarg, 3257a36c61f9SKrishna Gudipati bfa_status_t req_status, 3258a36c61f9SKrishna Gudipati u32 rsp_len, 3259a36c61f9SKrishna Gudipati u32 resid_len, 3260a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3261a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, 3262a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3263a36c61f9SKrishna Gudipati void *cbarg, 3264a36c61f9SKrishna Gudipati bfa_status_t req_status, 3265a36c61f9SKrishna Gudipati u32 rsp_len, 3266a36c61f9SKrishna Gudipati u32 resid_len, 3267a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3268a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_process_gidft_pids( 3269a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 3270a36c61f9SKrishna Gudipati u32 *pid_buf, u32 n_pids); 3271a36c61f9SKrishna Gudipati 3272a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port); 32735fbe25c7SJing Huang /* 3274a36c61f9SKrishna Gudipati * fcs_ns_sm FCS nameserver interface state machine 3275a36c61f9SKrishna Gudipati */ 3276a36c61f9SKrishna Gudipati 32775fbe25c7SJing Huang /* 3278a36c61f9SKrishna Gudipati * VPort NS State Machine events 3279a36c61f9SKrishna Gudipati */ 3280a36c61f9SKrishna Gudipati enum vport_ns_event { 3281a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_ONLINE = 1, 3282a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_OFFLINE = 2, 3283a36c61f9SKrishna Gudipati NSSM_EVENT_PLOGI_SENT = 3, 3284a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_OK = 4, 3285a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_ERROR = 5, 3286a36c61f9SKrishna Gudipati NSSM_EVENT_TIMEOUT = 6, 3287a36c61f9SKrishna Gudipati NSSM_EVENT_NS_QUERY = 7, 3288a36c61f9SKrishna Gudipati NSSM_EVENT_RSPNID_SENT = 8, 3289a36c61f9SKrishna Gudipati NSSM_EVENT_RFTID_SENT = 9, 3290a36c61f9SKrishna Gudipati NSSM_EVENT_RFFID_SENT = 10, 3291a36c61f9SKrishna Gudipati NSSM_EVENT_GIDFT_SENT = 11, 3292a36c61f9SKrishna Gudipati }; 3293a36c61f9SKrishna Gudipati 3294a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3295a36c61f9SKrishna Gudipati enum vport_ns_event event); 3296a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3297a36c61f9SKrishna Gudipati enum vport_ns_event event); 3298a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3299a36c61f9SKrishna Gudipati enum vport_ns_event event); 3300a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3301a36c61f9SKrishna Gudipati enum vport_ns_event event); 3302a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rspn_id( 3303a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3304a36c61f9SKrishna Gudipati enum vport_ns_event event); 3305a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3306a36c61f9SKrishna Gudipati enum vport_ns_event event); 3307a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3308a36c61f9SKrishna Gudipati enum vport_ns_event event); 3309a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rft_id( 3310a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3311a36c61f9SKrishna Gudipati enum vport_ns_event event); 3312a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3313a36c61f9SKrishna Gudipati enum vport_ns_event event); 3314a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3315a36c61f9SKrishna Gudipati enum vport_ns_event event); 3316a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rff_id( 3317a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3318a36c61f9SKrishna Gudipati enum vport_ns_event event); 3319a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3320a36c61f9SKrishna Gudipati enum vport_ns_event event); 3321a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3322a36c61f9SKrishna Gudipati enum vport_ns_event event); 3323a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_gid_ft( 3324a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3325a36c61f9SKrishna Gudipati enum vport_ns_event event); 3326a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3327a36c61f9SKrishna Gudipati enum vport_ns_event event); 3328a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3329a36c61f9SKrishna Gudipati enum vport_ns_event event); 3330a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3331a36c61f9SKrishna Gudipati enum vport_ns_event event); 33325fbe25c7SJing Huang /* 3333a36c61f9SKrishna Gudipati * Start in offline state - awaiting linkup 3334a36c61f9SKrishna Gudipati */ 3335a36c61f9SKrishna Gudipati static void 3336a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3337a36c61f9SKrishna Gudipati enum vport_ns_event event) 3338a36c61f9SKrishna Gudipati { 3339a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3340a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3341a36c61f9SKrishna Gudipati 3342a36c61f9SKrishna Gudipati switch (event) { 3343a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_ONLINE: 3344a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3345a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3346a36c61f9SKrishna Gudipati break; 3347a36c61f9SKrishna Gudipati 3348a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3349a36c61f9SKrishna Gudipati break; 3350a36c61f9SKrishna Gudipati 3351a36c61f9SKrishna Gudipati default: 3352a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3353a36c61f9SKrishna Gudipati } 3354a36c61f9SKrishna Gudipati } 3355a36c61f9SKrishna Gudipati 3356a36c61f9SKrishna Gudipati static void 3357a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3358a36c61f9SKrishna Gudipati enum vport_ns_event event) 3359a36c61f9SKrishna Gudipati { 3360a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3361a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3362a36c61f9SKrishna Gudipati 3363a36c61f9SKrishna Gudipati switch (event) { 3364a36c61f9SKrishna Gudipati case NSSM_EVENT_PLOGI_SENT: 3365a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi); 3366a36c61f9SKrishna Gudipati break; 3367a36c61f9SKrishna Gudipati 3368a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3369a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3370a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3371a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3372a36c61f9SKrishna Gudipati break; 3373a36c61f9SKrishna Gudipati 3374a36c61f9SKrishna Gudipati default: 3375a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3376a36c61f9SKrishna Gudipati } 3377a36c61f9SKrishna Gudipati } 3378a36c61f9SKrishna Gudipati 3379a36c61f9SKrishna Gudipati static void 3380a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3381a36c61f9SKrishna Gudipati enum vport_ns_event event) 3382a36c61f9SKrishna Gudipati { 3383a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3384a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3385a36c61f9SKrishna Gudipati 3386a36c61f9SKrishna Gudipati switch (event) { 3387a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3388a36c61f9SKrishna Gudipati /* 3389a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3390a36c61f9SKrishna Gudipati */ 3391a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry); 3392a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3393a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3394a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3395a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3396a36c61f9SKrishna Gudipati break; 3397a36c61f9SKrishna Gudipati 3398a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3399a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3400a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3401a36c61f9SKrishna Gudipati break; 3402a36c61f9SKrishna Gudipati 3403a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3404a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3405a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3406a36c61f9SKrishna Gudipati break; 3407a36c61f9SKrishna Gudipati 3408a36c61f9SKrishna Gudipati default: 3409a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3410a36c61f9SKrishna Gudipati } 3411a36c61f9SKrishna Gudipati } 3412a36c61f9SKrishna Gudipati 3413a36c61f9SKrishna Gudipati static void 3414a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3415a36c61f9SKrishna Gudipati enum vport_ns_event event) 3416a36c61f9SKrishna Gudipati { 3417a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3418a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3419a36c61f9SKrishna Gudipati 3420a36c61f9SKrishna Gudipati switch (event) { 3421a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3422a36c61f9SKrishna Gudipati /* 3423a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3424a36c61f9SKrishna Gudipati */ 3425a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3426a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3427a36c61f9SKrishna Gudipati break; 3428a36c61f9SKrishna Gudipati 3429a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3430a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3431a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3432a36c61f9SKrishna Gudipati break; 3433a36c61f9SKrishna Gudipati 3434a36c61f9SKrishna Gudipati default: 3435a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3436a36c61f9SKrishna Gudipati } 3437a36c61f9SKrishna Gudipati } 3438a36c61f9SKrishna Gudipati 3439a36c61f9SKrishna Gudipati static void 3440a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3441a36c61f9SKrishna Gudipati enum vport_ns_event event) 3442a36c61f9SKrishna Gudipati { 3443a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3444a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3445a36c61f9SKrishna Gudipati 3446a36c61f9SKrishna Gudipati switch (event) { 3447a36c61f9SKrishna Gudipati case NSSM_EVENT_RSPNID_SENT: 3448a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id); 3449a36c61f9SKrishna Gudipati break; 3450a36c61f9SKrishna Gudipati 3451a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3452a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3453a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3454a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3455a36c61f9SKrishna Gudipati break; 3456a36c61f9SKrishna Gudipati 3457a36c61f9SKrishna Gudipati default: 3458a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3459a36c61f9SKrishna Gudipati } 3460a36c61f9SKrishna Gudipati } 3461a36c61f9SKrishna Gudipati 3462a36c61f9SKrishna Gudipati static void 3463a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3464a36c61f9SKrishna Gudipati enum vport_ns_event event) 3465a36c61f9SKrishna Gudipati { 3466a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3467a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3468a36c61f9SKrishna Gudipati 3469a36c61f9SKrishna Gudipati switch (event) { 3470a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3471a36c61f9SKrishna Gudipati /* 3472a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3473a36c61f9SKrishna Gudipati */ 3474a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry); 3475a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3476a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3477a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3478a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3479a36c61f9SKrishna Gudipati break; 3480a36c61f9SKrishna Gudipati 3481a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3482a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3483a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3484a36c61f9SKrishna Gudipati break; 3485a36c61f9SKrishna Gudipati 3486a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3487a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3488a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3489a36c61f9SKrishna Gudipati break; 3490a36c61f9SKrishna Gudipati 3491a36c61f9SKrishna Gudipati default: 3492a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3493a36c61f9SKrishna Gudipati } 3494a36c61f9SKrishna Gudipati } 3495a36c61f9SKrishna Gudipati 3496a36c61f9SKrishna Gudipati static void 3497a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3498a36c61f9SKrishna Gudipati enum vport_ns_event event) 3499a36c61f9SKrishna Gudipati { 3500a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3501a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3502a36c61f9SKrishna Gudipati 3503a36c61f9SKrishna Gudipati switch (event) { 3504a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3505a36c61f9SKrishna Gudipati /* 3506a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3507a36c61f9SKrishna Gudipati */ 3508a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3509a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3510a36c61f9SKrishna Gudipati break; 3511a36c61f9SKrishna Gudipati 3512a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3513a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3514a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3515a36c61f9SKrishna Gudipati break; 3516a36c61f9SKrishna Gudipati 3517a36c61f9SKrishna Gudipati default: 3518a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3519a36c61f9SKrishna Gudipati } 3520a36c61f9SKrishna Gudipati } 3521a36c61f9SKrishna Gudipati 3522a36c61f9SKrishna Gudipati static void 3523a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns, 3524a36c61f9SKrishna Gudipati enum vport_ns_event event) 3525a36c61f9SKrishna Gudipati { 3526a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3527a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3528a36c61f9SKrishna Gudipati 3529a36c61f9SKrishna Gudipati switch (event) { 3530a36c61f9SKrishna Gudipati case NSSM_EVENT_RFTID_SENT: 3531a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id); 3532a36c61f9SKrishna Gudipati break; 3533a36c61f9SKrishna Gudipati 3534a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3535a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3536a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3537a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3538a36c61f9SKrishna Gudipati break; 3539a36c61f9SKrishna Gudipati 3540a36c61f9SKrishna Gudipati default: 3541a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3542a36c61f9SKrishna Gudipati } 3543a36c61f9SKrishna Gudipati } 3544a36c61f9SKrishna Gudipati 3545a36c61f9SKrishna Gudipati static void 3546a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3547a36c61f9SKrishna Gudipati enum vport_ns_event event) 3548a36c61f9SKrishna Gudipati { 3549a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3550a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3551a36c61f9SKrishna Gudipati 3552a36c61f9SKrishna Gudipati switch (event) { 3553a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3554a36c61f9SKrishna Gudipati /* Now move to register FC4 Features */ 3555a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3556a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3557a36c61f9SKrishna Gudipati break; 3558a36c61f9SKrishna Gudipati 3559a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3560a36c61f9SKrishna Gudipati /* 3561a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3562a36c61f9SKrishna Gudipati */ 3563a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry); 3564a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3565a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3566a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3567a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3568a36c61f9SKrishna Gudipati break; 3569a36c61f9SKrishna Gudipati 3570a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3571a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3572a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3573a36c61f9SKrishna Gudipati break; 3574a36c61f9SKrishna Gudipati 3575a36c61f9SKrishna Gudipati default: 3576a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3577a36c61f9SKrishna Gudipati } 3578a36c61f9SKrishna Gudipati } 3579a36c61f9SKrishna Gudipati 3580a36c61f9SKrishna Gudipati static void 3581a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3582a36c61f9SKrishna Gudipati enum vport_ns_event event) 3583a36c61f9SKrishna Gudipati { 3584a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3585a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3586a36c61f9SKrishna Gudipati 3587a36c61f9SKrishna Gudipati switch (event) { 3588a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3589a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3590a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3591a36c61f9SKrishna Gudipati break; 3592a36c61f9SKrishna Gudipati 3593a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3594a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3595a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3596a36c61f9SKrishna Gudipati break; 3597a36c61f9SKrishna Gudipati 3598a36c61f9SKrishna Gudipati default: 3599a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3600a36c61f9SKrishna Gudipati } 3601a36c61f9SKrishna Gudipati } 3602a36c61f9SKrishna Gudipati 3603a36c61f9SKrishna Gudipati static void 3604a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns, 3605a36c61f9SKrishna Gudipati enum vport_ns_event event) 3606a36c61f9SKrishna Gudipati { 3607a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3608a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3609a36c61f9SKrishna Gudipati 3610a36c61f9SKrishna Gudipati switch (event) { 3611a36c61f9SKrishna Gudipati case NSSM_EVENT_RFFID_SENT: 3612a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id); 3613a36c61f9SKrishna Gudipati break; 3614a36c61f9SKrishna Gudipati 3615a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3616a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3617a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3618a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3619a36c61f9SKrishna Gudipati break; 3620a36c61f9SKrishna Gudipati 3621a36c61f9SKrishna Gudipati default: 3622a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3623a36c61f9SKrishna Gudipati } 3624a36c61f9SKrishna Gudipati } 3625a36c61f9SKrishna Gudipati 3626a36c61f9SKrishna Gudipati static void 3627a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3628a36c61f9SKrishna Gudipati enum vport_ns_event event) 3629a36c61f9SKrishna Gudipati { 3630a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3631a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3632a36c61f9SKrishna Gudipati 3633a36c61f9SKrishna Gudipati switch (event) { 3634a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3635a36c61f9SKrishna Gudipati 3636a36c61f9SKrishna Gudipati /* 3637a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot initiate rport 3638a36c61f9SKrishna Gudipati * discovery with the fabric. Instead, we will retrieve the 3639a36c61f9SKrishna Gudipati * boot targets from HAL/FW. 3640a36c61f9SKrishna Gudipati */ 3641a36c61f9SKrishna Gudipati if (__fcs_min_cfg(ns->port->fcs)) { 3642a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(ns->port); 3643a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3644a36c61f9SKrishna Gudipati return; 3645a36c61f9SKrishna Gudipati } 3646a36c61f9SKrishna Gudipati 3647a36c61f9SKrishna Gudipati /* 3648a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 3649a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 3650a36c61f9SKrishna Gudipati */ 3651a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3652a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 3653a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 3654a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3655a36c61f9SKrishna Gudipati } 3656a36c61f9SKrishna Gudipati /* 3657a36c61f9SKrishna Gudipati * kick off mgmt srvr state machine 3658a36c61f9SKrishna Gudipati */ 3659a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(ns->port); 3660a36c61f9SKrishna Gudipati break; 3661a36c61f9SKrishna Gudipati 3662a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3663a36c61f9SKrishna Gudipati /* 3664a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3665a36c61f9SKrishna Gudipati */ 3666a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry); 3667a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3668a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3669a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3670a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3671a36c61f9SKrishna Gudipati break; 3672a36c61f9SKrishna Gudipati 3673a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3674a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3675a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3676a36c61f9SKrishna Gudipati break; 3677a36c61f9SKrishna Gudipati 3678a36c61f9SKrishna Gudipati default: 3679a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3680a36c61f9SKrishna Gudipati } 3681a36c61f9SKrishna Gudipati } 3682a36c61f9SKrishna Gudipati 3683a36c61f9SKrishna Gudipati static void 3684a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3685a36c61f9SKrishna Gudipati enum vport_ns_event event) 3686a36c61f9SKrishna Gudipati { 3687a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3688a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3689a36c61f9SKrishna Gudipati 3690a36c61f9SKrishna Gudipati switch (event) { 3691a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3692a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3693a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3694a36c61f9SKrishna Gudipati break; 3695a36c61f9SKrishna Gudipati 3696a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3697a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3698a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3699a36c61f9SKrishna Gudipati break; 3700a36c61f9SKrishna Gudipati 3701a36c61f9SKrishna Gudipati default: 3702a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3703a36c61f9SKrishna Gudipati } 3704a36c61f9SKrishna Gudipati } 3705a36c61f9SKrishna Gudipati static void 3706a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3707a36c61f9SKrishna Gudipati enum vport_ns_event event) 3708a36c61f9SKrishna Gudipati { 3709a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3710a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3711a36c61f9SKrishna Gudipati 3712a36c61f9SKrishna Gudipati switch (event) { 3713a36c61f9SKrishna Gudipati case NSSM_EVENT_GIDFT_SENT: 3714a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft); 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_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3720a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3721a36c61f9SKrishna Gudipati break; 3722a36c61f9SKrishna Gudipati 3723a36c61f9SKrishna Gudipati default: 3724a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3725a36c61f9SKrishna Gudipati } 3726a36c61f9SKrishna Gudipati } 3727a36c61f9SKrishna Gudipati 3728a36c61f9SKrishna Gudipati static void 3729a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3730a36c61f9SKrishna Gudipati enum vport_ns_event event) 3731a36c61f9SKrishna Gudipati { 3732a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3733a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3734a36c61f9SKrishna Gudipati 3735a36c61f9SKrishna Gudipati switch (event) { 3736a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3737a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3738a36c61f9SKrishna Gudipati break; 3739a36c61f9SKrishna Gudipati 3740a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3741a36c61f9SKrishna Gudipati /* 3742a36c61f9SKrishna Gudipati * TBD: for certain reject codes, we don't need to retry 3743a36c61f9SKrishna Gudipati */ 3744a36c61f9SKrishna Gudipati /* 3745a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3746a36c61f9SKrishna Gudipati */ 3747a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry); 3748a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3749a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3750a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3751a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3752a36c61f9SKrishna Gudipati break; 3753a36c61f9SKrishna Gudipati 3754a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3755a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3756a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3757a36c61f9SKrishna Gudipati break; 3758a36c61f9SKrishna Gudipati 3759a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 3760a36c61f9SKrishna Gudipati break; 3761a36c61f9SKrishna Gudipati 3762a36c61f9SKrishna Gudipati default: 3763a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3764a36c61f9SKrishna Gudipati } 3765a36c61f9SKrishna Gudipati } 3766a36c61f9SKrishna Gudipati 3767a36c61f9SKrishna Gudipati static void 3768a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3769a36c61f9SKrishna Gudipati enum vport_ns_event event) 3770a36c61f9SKrishna Gudipati { 3771a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3772a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3773a36c61f9SKrishna Gudipati 3774a36c61f9SKrishna Gudipati switch (event) { 3775a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3776a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft); 3777a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3778a36c61f9SKrishna Gudipati break; 3779a36c61f9SKrishna Gudipati 3780a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3781a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3782a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3783a36c61f9SKrishna Gudipati break; 3784a36c61f9SKrishna Gudipati 3785a36c61f9SKrishna Gudipati default: 3786a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3787a36c61f9SKrishna Gudipati } 3788a36c61f9SKrishna Gudipati } 3789a36c61f9SKrishna Gudipati 3790a36c61f9SKrishna Gudipati static void 3791a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3792a36c61f9SKrishna Gudipati enum vport_ns_event event) 3793a36c61f9SKrishna Gudipati { 3794a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3795a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3796a36c61f9SKrishna Gudipati 3797a36c61f9SKrishna Gudipati switch (event) { 3798a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3799a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3800a36c61f9SKrishna Gudipati break; 3801a36c61f9SKrishna Gudipati 3802a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 3803a36c61f9SKrishna Gudipati /* 3804a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 3805a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 3806a36c61f9SKrishna Gudipati */ 3807a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3808a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 3809a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 3810a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3811a36c61f9SKrishna Gudipati }; 3812a36c61f9SKrishna Gudipati break; 3813a36c61f9SKrishna Gudipati 3814a36c61f9SKrishna Gudipati default: 3815a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3816a36c61f9SKrishna Gudipati } 3817a36c61f9SKrishna Gudipati } 3818a36c61f9SKrishna Gudipati 3819a36c61f9SKrishna Gudipati 3820a36c61f9SKrishna Gudipati 38215fbe25c7SJing Huang /* 3822a36c61f9SKrishna Gudipati * ns_pvt Nameserver local functions 3823a36c61f9SKrishna Gudipati */ 3824a36c61f9SKrishna Gudipati 3825a36c61f9SKrishna Gudipati static void 3826a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3827a36c61f9SKrishna Gudipati { 3828a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3829a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3830a36c61f9SKrishna Gudipati struct fchs_s fchs; 3831a36c61f9SKrishna Gudipati int len; 3832a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3833a36c61f9SKrishna Gudipati 3834a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3835a36c61f9SKrishna Gudipati 3836c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3837c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3838a36c61f9SKrishna Gudipati if (!fcxp) { 3839a36c61f9SKrishna Gudipati port->stats.ns_plogi_alloc_wait++; 3840a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3841c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE); 3842a36c61f9SKrishna Gudipati return; 3843a36c61f9SKrishna Gudipati } 3844a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3845a36c61f9SKrishna Gudipati 3846a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3847f16a1750SMaggie Zhang bfa_hton3b(FC_NAME_SERVER), 3848a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3849a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 3850be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 3851be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3852a36c61f9SKrishna Gudipati 3853a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3854a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3855a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response, (void *)ns, 3856a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 3857a36c61f9SKrishna Gudipati port->stats.ns_plogi_sent++; 3858a36c61f9SKrishna Gudipati 3859a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); 3860a36c61f9SKrishna Gudipati } 3861a36c61f9SKrishna Gudipati 3862a36c61f9SKrishna Gudipati static void 3863a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3864a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 3865a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 3866a36c61f9SKrishna Gudipati { 3867a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3868a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3869a36c61f9SKrishna Gudipati /* struct fc_logi_s *plogi_resp; */ 3870a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 3871a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3872a36c61f9SKrishna Gudipati 3873a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3874a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3875a36c61f9SKrishna Gudipati 3876a36c61f9SKrishna Gudipati /* 3877a36c61f9SKrishna Gudipati * Sanity Checks 3878a36c61f9SKrishna Gudipati */ 3879a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3880a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3881a36c61f9SKrishna Gudipati port->stats.ns_plogi_rsp_err++; 3882a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3883a36c61f9SKrishna Gudipati return; 3884a36c61f9SKrishna Gudipati } 3885a36c61f9SKrishna Gudipati 3886a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3887a36c61f9SKrishna Gudipati 3888a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 3889a36c61f9SKrishna Gudipati 3890a36c61f9SKrishna Gudipati case FC_ELS_ACC: 3891a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 3892a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 3893a36c61f9SKrishna Gudipati port->stats.ns_plogi_acc_err++; 3894a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3895a36c61f9SKrishna Gudipati break; 3896a36c61f9SKrishna Gudipati } 3897a36c61f9SKrishna Gudipati port->stats.ns_plogi_accepts++; 3898a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3899a36c61f9SKrishna Gudipati break; 3900a36c61f9SKrishna Gudipati 3901a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 3902a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3903a36c61f9SKrishna Gudipati 3904a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 3905a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3906a36c61f9SKrishna Gudipati 3907a36c61f9SKrishna Gudipati port->stats.ns_rejects++; 3908a36c61f9SKrishna Gudipati 3909a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3910a36c61f9SKrishna Gudipati break; 3911a36c61f9SKrishna Gudipati 3912a36c61f9SKrishna Gudipati default: 3913a36c61f9SKrishna Gudipati port->stats.ns_plogi_unknown_rsp++; 3914a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 3915a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3916a36c61f9SKrishna Gudipati } 3917a36c61f9SKrishna Gudipati } 3918a36c61f9SKrishna Gudipati 39195fbe25c7SJing Huang /* 3920a36c61f9SKrishna Gudipati * Register the symbolic port name. 3921a36c61f9SKrishna Gudipati */ 3922a36c61f9SKrishna Gudipati static void 3923a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3924a36c61f9SKrishna Gudipati { 3925a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3926a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3927a36c61f9SKrishna Gudipati struct fchs_s fchs; 3928a36c61f9SKrishna Gudipati int len; 3929a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3930a36c61f9SKrishna Gudipati u8 symbl[256]; 3931a36c61f9SKrishna Gudipati u8 *psymbl = &symbl[0]; 3932a36c61f9SKrishna Gudipati 39336a18b167SJing Huang memset(symbl, 0, sizeof(symbl)); 3934a36c61f9SKrishna Gudipati 3935a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3936a36c61f9SKrishna Gudipati 3937c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3938c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3939a36c61f9SKrishna Gudipati if (!fcxp) { 3940a36c61f9SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 3941a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3942c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE); 3943a36c61f9SKrishna Gudipati return; 3944a36c61f9SKrishna Gudipati } 3945a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3946a36c61f9SKrishna Gudipati 3947a36c61f9SKrishna Gudipati /* 3948a36c61f9SKrishna Gudipati * for V-Port, form a Port Symbolic Name 3949a36c61f9SKrishna Gudipati */ 3950a36c61f9SKrishna Gudipati if (port->vport) { 39515fbe25c7SJing Huang /* 3952a36c61f9SKrishna Gudipati * For Vports, we append the vport's port symbolic name 3953a36c61f9SKrishna Gudipati * to that of the base port. 3954a36c61f9SKrishna Gudipati */ 3955a36c61f9SKrishna Gudipati 3956a36c61f9SKrishna Gudipati strncpy((char *)psymbl, 3957a36c61f9SKrishna Gudipati (char *) & 3958a36c61f9SKrishna Gudipati (bfa_fcs_lport_get_psym_name 3959a36c61f9SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 3960a36c61f9SKrishna Gudipati strlen((char *) & 3961a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3962a36c61f9SKrishna Gudipati (port->fcs)))); 3963a36c61f9SKrishna Gudipati 3964a36c61f9SKrishna Gudipati /* Ensure we have a null terminating string. */ 3965a36c61f9SKrishna Gudipati ((char *)psymbl)[strlen((char *) & 3966a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3967a36c61f9SKrishna Gudipati (port->fcs)))] = 0; 3968a36c61f9SKrishna Gudipati strncat((char *)psymbl, 3969a36c61f9SKrishna Gudipati (char *) &(bfa_fcs_lport_get_psym_name(port)), 3970a36c61f9SKrishna Gudipati strlen((char *) &bfa_fcs_lport_get_psym_name(port))); 3971a36c61f9SKrishna Gudipati } else { 3972a36c61f9SKrishna Gudipati psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); 3973a36c61f9SKrishna Gudipati } 3974a36c61f9SKrishna Gudipati 3975a36c61f9SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3976a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, psymbl); 3977a36c61f9SKrishna Gudipati 3978a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3979a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3980a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response, (void *)ns, 3981a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3982a36c61f9SKrishna Gudipati 3983a36c61f9SKrishna Gudipati port->stats.ns_rspnid_sent++; 3984a36c61f9SKrishna Gudipati 3985a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); 3986a36c61f9SKrishna Gudipati } 3987a36c61f9SKrishna Gudipati 3988a36c61f9SKrishna Gudipati static void 3989a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3990a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3991a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3992a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 3993a36c61f9SKrishna Gudipati { 3994a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3995a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3996a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3997a36c61f9SKrishna Gudipati 3998a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3999a36c61f9SKrishna Gudipati 4000a36c61f9SKrishna Gudipati /* 4001a36c61f9SKrishna Gudipati * Sanity Checks 4002a36c61f9SKrishna Gudipati */ 4003a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4004a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4005a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rsp_err++; 4006a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4007a36c61f9SKrishna Gudipati return; 4008a36c61f9SKrishna Gudipati } 4009a36c61f9SKrishna Gudipati 4010a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4011ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4012a36c61f9SKrishna Gudipati 4013a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4014a36c61f9SKrishna Gudipati port->stats.ns_rspnid_accepts++; 4015a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4016a36c61f9SKrishna Gudipati return; 4017a36c61f9SKrishna Gudipati } 4018a36c61f9SKrishna Gudipati 4019a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rejects++; 4020a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4021a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4022a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4023a36c61f9SKrishna Gudipati } 4024a36c61f9SKrishna Gudipati 40255fbe25c7SJing Huang /* 4026a36c61f9SKrishna Gudipati * Register FC4-Types 4027a36c61f9SKrishna Gudipati */ 4028a36c61f9SKrishna Gudipati static void 4029a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4030a36c61f9SKrishna Gudipati { 4031a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4032a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4033a36c61f9SKrishna Gudipati struct fchs_s fchs; 4034a36c61f9SKrishna Gudipati int len; 4035a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4036a36c61f9SKrishna Gudipati 4037a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4038a36c61f9SKrishna Gudipati 4039c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4040c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4041a36c61f9SKrishna Gudipati if (!fcxp) { 4042a36c61f9SKrishna Gudipati port->stats.ns_rftid_alloc_wait++; 4043a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4044c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE); 4045a36c61f9SKrishna Gudipati return; 4046a36c61f9SKrishna Gudipati } 4047a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4048a36c61f9SKrishna Gudipati 4049a36c61f9SKrishna Gudipati len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4050a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles); 4051a36c61f9SKrishna Gudipati 4052a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4053a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4054a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response, (void *)ns, 4055a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4056a36c61f9SKrishna Gudipati 4057a36c61f9SKrishna Gudipati port->stats.ns_rftid_sent++; 4058a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); 4059a36c61f9SKrishna Gudipati } 4060a36c61f9SKrishna Gudipati 4061a36c61f9SKrishna Gudipati static void 4062a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4063a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4064a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4065a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4066a36c61f9SKrishna Gudipati { 4067a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4068a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4069a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4070a36c61f9SKrishna Gudipati 4071a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4072a36c61f9SKrishna Gudipati 4073a36c61f9SKrishna Gudipati /* 4074a36c61f9SKrishna Gudipati * Sanity Checks 4075a36c61f9SKrishna Gudipati */ 4076a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4077a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4078a36c61f9SKrishna Gudipati port->stats.ns_rftid_rsp_err++; 4079a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4080a36c61f9SKrishna Gudipati return; 4081a36c61f9SKrishna Gudipati } 4082a36c61f9SKrishna Gudipati 4083a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4084ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4085a36c61f9SKrishna Gudipati 4086a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4087a36c61f9SKrishna Gudipati port->stats.ns_rftid_accepts++; 4088a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4089a36c61f9SKrishna Gudipati return; 4090a36c61f9SKrishna Gudipati } 4091a36c61f9SKrishna Gudipati 4092a36c61f9SKrishna Gudipati port->stats.ns_rftid_rejects++; 4093a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4094a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4095a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4096a36c61f9SKrishna Gudipati } 4097a36c61f9SKrishna Gudipati 40985fbe25c7SJing Huang /* 4099a36c61f9SKrishna Gudipati * Register FC4-Features : Should be done after RFT_ID 4100a36c61f9SKrishna Gudipati */ 4101a36c61f9SKrishna Gudipati static void 4102a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4103a36c61f9SKrishna Gudipati { 4104a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4105a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4106a36c61f9SKrishna Gudipati struct fchs_s fchs; 4107a36c61f9SKrishna Gudipati int len; 4108a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4109a36c61f9SKrishna Gudipati u8 fc4_ftrs = 0; 4110a36c61f9SKrishna Gudipati 4111a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4112a36c61f9SKrishna Gudipati 4113c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4114c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4115a36c61f9SKrishna Gudipati if (!fcxp) { 4116a36c61f9SKrishna Gudipati port->stats.ns_rffid_alloc_wait++; 4117a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4118c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE); 4119a36c61f9SKrishna Gudipati return; 4120a36c61f9SKrishna Gudipati } 4121a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4122a36c61f9SKrishna Gudipati 4123a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) 4124a36c61f9SKrishna Gudipati fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; 4125a36c61f9SKrishna Gudipati 4126a36c61f9SKrishna Gudipati len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4127a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 4128a36c61f9SKrishna Gudipati FC_TYPE_FCP, fc4_ftrs); 4129a36c61f9SKrishna Gudipati 4130a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4131a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4132a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response, (void *)ns, 4133a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4134a36c61f9SKrishna Gudipati 4135a36c61f9SKrishna Gudipati port->stats.ns_rffid_sent++; 4136a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); 4137a36c61f9SKrishna Gudipati } 4138a36c61f9SKrishna Gudipati 4139a36c61f9SKrishna Gudipati static void 4140a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4141a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4142a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4143a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4144a36c61f9SKrishna Gudipati { 4145a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4146a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4147a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4148a36c61f9SKrishna Gudipati 4149a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4150a36c61f9SKrishna Gudipati 4151a36c61f9SKrishna Gudipati /* 4152a36c61f9SKrishna Gudipati * Sanity Checks 4153a36c61f9SKrishna Gudipati */ 4154a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4155a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4156a36c61f9SKrishna Gudipati port->stats.ns_rffid_rsp_err++; 4157a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4158a36c61f9SKrishna Gudipati return; 4159a36c61f9SKrishna Gudipati } 4160a36c61f9SKrishna Gudipati 4161a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4162ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4163a36c61f9SKrishna Gudipati 4164a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4165a36c61f9SKrishna Gudipati port->stats.ns_rffid_accepts++; 4166a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4167a36c61f9SKrishna Gudipati return; 4168a36c61f9SKrishna Gudipati } 4169a36c61f9SKrishna Gudipati 4170a36c61f9SKrishna Gudipati port->stats.ns_rffid_rejects++; 4171a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4172a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4173a36c61f9SKrishna Gudipati 4174a36c61f9SKrishna Gudipati if (cthdr->reason_code == CT_RSN_NOT_SUPP) { 4175a36c61f9SKrishna Gudipati /* if this command is not supported, we don't retry */ 4176a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4177a36c61f9SKrishna Gudipati } else 4178a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4179a36c61f9SKrishna Gudipati } 41805fbe25c7SJing Huang /* 4181a36c61f9SKrishna Gudipati * Query Fabric for FC4-Types Devices. 4182a36c61f9SKrishna Gudipati * 4183a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response 4184a36c61f9SKrishna Gudipati * can be larger than 2K. 4185a36c61f9SKrishna Gudipati */ 4186a36c61f9SKrishna Gudipati static void 4187a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4188a36c61f9SKrishna Gudipati { 4189a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4190a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4191a36c61f9SKrishna Gudipati struct fchs_s fchs; 4192a36c61f9SKrishna Gudipati int len; 4193a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4194a36c61f9SKrishna Gudipati 4195a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4196a36c61f9SKrishna Gudipati 4197c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4198c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4199a36c61f9SKrishna Gudipati if (!fcxp) { 4200a36c61f9SKrishna Gudipati port->stats.ns_gidft_alloc_wait++; 4201a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4202c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE); 4203a36c61f9SKrishna Gudipati return; 4204a36c61f9SKrishna Gudipati } 4205a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4206a36c61f9SKrishna Gudipati 4207a36c61f9SKrishna Gudipati /* 4208a36c61f9SKrishna Gudipati * This query is only initiated for FCP initiator mode. 4209a36c61f9SKrishna Gudipati */ 4210a36c61f9SKrishna Gudipati len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4211a36c61f9SKrishna Gudipati ns->port->pid, FC_TYPE_FCP); 4212a36c61f9SKrishna Gudipati 4213a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4214a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4215a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response, (void *)ns, 4216a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV); 4217a36c61f9SKrishna Gudipati 4218a36c61f9SKrishna Gudipati port->stats.ns_gidft_sent++; 4219a36c61f9SKrishna Gudipati 4220a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); 4221a36c61f9SKrishna Gudipati } 4222a36c61f9SKrishna Gudipati 4223a36c61f9SKrishna Gudipati static void 4224a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4225a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4226a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4227a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4228a36c61f9SKrishna Gudipati { 4229a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4230a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4231a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4232a36c61f9SKrishna Gudipati u32 n_pids; 4233a36c61f9SKrishna Gudipati 4234a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4235a36c61f9SKrishna Gudipati 4236a36c61f9SKrishna Gudipati /* 4237a36c61f9SKrishna Gudipati * Sanity Checks 4238a36c61f9SKrishna Gudipati */ 4239a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4240a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4241a36c61f9SKrishna Gudipati port->stats.ns_gidft_rsp_err++; 4242a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4243a36c61f9SKrishna Gudipati return; 4244a36c61f9SKrishna Gudipati } 4245a36c61f9SKrishna Gudipati 4246a36c61f9SKrishna Gudipati if (resid_len != 0) { 4247a36c61f9SKrishna Gudipati /* 4248a36c61f9SKrishna Gudipati * TBD : we will need to allocate a larger buffer & retry the 4249a36c61f9SKrishna Gudipati * command 4250a36c61f9SKrishna Gudipati */ 4251a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 4252a36c61f9SKrishna Gudipati bfa_trc(port->fcs, resid_len); 4253a36c61f9SKrishna Gudipati return; 4254a36c61f9SKrishna Gudipati } 4255a36c61f9SKrishna Gudipati 4256a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4257ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4258a36c61f9SKrishna Gudipati 4259a36c61f9SKrishna Gudipati switch (cthdr->cmd_rsp_code) { 4260a36c61f9SKrishna Gudipati 4261a36c61f9SKrishna Gudipati case CT_RSP_ACCEPT: 4262a36c61f9SKrishna Gudipati 4263a36c61f9SKrishna Gudipati port->stats.ns_gidft_accepts++; 4264a36c61f9SKrishna Gudipati n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); 4265a36c61f9SKrishna Gudipati bfa_trc(port->fcs, n_pids); 4266a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(port, 4267a36c61f9SKrishna Gudipati (u32 *) (cthdr + 1), 4268a36c61f9SKrishna Gudipati n_pids); 4269a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4270a36c61f9SKrishna Gudipati break; 4271a36c61f9SKrishna Gudipati 4272a36c61f9SKrishna Gudipati case CT_RSP_REJECT: 4273a36c61f9SKrishna Gudipati 4274a36c61f9SKrishna Gudipati /* 4275a36c61f9SKrishna Gudipati * Check the reason code & explanation. 4276a36c61f9SKrishna Gudipati * There may not have been any FC4 devices in the fabric 4277a36c61f9SKrishna Gudipati */ 4278a36c61f9SKrishna Gudipati port->stats.ns_gidft_rejects++; 4279a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4280a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4281a36c61f9SKrishna Gudipati 4282a36c61f9SKrishna Gudipati if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) 4283a36c61f9SKrishna Gudipati && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { 4284a36c61f9SKrishna Gudipati 4285a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4286a36c61f9SKrishna Gudipati } else { 4287a36c61f9SKrishna Gudipati /* 4288a36c61f9SKrishna Gudipati * for all other errors, retry 4289a36c61f9SKrishna Gudipati */ 4290a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4291a36c61f9SKrishna Gudipati } 4292a36c61f9SKrishna Gudipati break; 4293a36c61f9SKrishna Gudipati 4294a36c61f9SKrishna Gudipati default: 4295a36c61f9SKrishna Gudipati port->stats.ns_gidft_unknown_rsp++; 4296a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->cmd_rsp_code); 4297a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4298a36c61f9SKrishna Gudipati } 4299a36c61f9SKrishna Gudipati } 4300a36c61f9SKrishna Gudipati 43015fbe25c7SJing Huang /* 4302a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 4303a36c61f9SKrishna Gudipati * 4304a36c61f9SKrishna Gudipati * param[in] port - pointer to bfa_fcs_lport_t. 4305a36c61f9SKrishna Gudipati * 4306a36c61f9SKrishna Gudipati * return 4307a36c61f9SKrishna Gudipati * void 4308a36c61f9SKrishna Gudipati * 4309a36c61f9SKrishna Gudipati * Special Considerations: 4310a36c61f9SKrishna Gudipati * 4311a36c61f9SKrishna Gudipati * note 4312a36c61f9SKrishna Gudipati */ 4313a36c61f9SKrishna Gudipati static void 4314a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg) 4315a36c61f9SKrishna Gudipati { 4316a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg; 4317a36c61f9SKrishna Gudipati 4318a36c61f9SKrishna Gudipati ns->port->stats.ns_timeouts++; 4319a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT); 4320a36c61f9SKrishna Gudipati } 4321a36c61f9SKrishna Gudipati 4322a36c61f9SKrishna Gudipati /* 4323a36c61f9SKrishna Gudipati * Process the PID list in GID_FT response 4324a36c61f9SKrishna Gudipati */ 4325a36c61f9SKrishna Gudipati static void 4326a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf, 4327a36c61f9SKrishna Gudipati u32 n_pids) 4328a36c61f9SKrishna Gudipati { 4329a36c61f9SKrishna Gudipati struct fcgs_gidft_resp_s *gidft_entry; 4330a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4331a36c61f9SKrishna Gudipati u32 ii; 4332a36c61f9SKrishna Gudipati 4333a36c61f9SKrishna Gudipati for (ii = 0; ii < n_pids; ii++) { 4334a36c61f9SKrishna Gudipati gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; 4335a36c61f9SKrishna Gudipati 4336a36c61f9SKrishna Gudipati if (gidft_entry->pid == port->pid) 4337a36c61f9SKrishna Gudipati continue; 4338a36c61f9SKrishna Gudipati 4339a36c61f9SKrishna Gudipati /* 4340a36c61f9SKrishna Gudipati * Check if this rport already exists 4341a36c61f9SKrishna Gudipati */ 4342a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid); 4343a36c61f9SKrishna Gudipati if (rport == NULL) { 4344a36c61f9SKrishna Gudipati /* 4345a36c61f9SKrishna Gudipati * this is a new device. create rport 4346a36c61f9SKrishna Gudipati */ 4347a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, gidft_entry->pid); 4348a36c61f9SKrishna Gudipati } else { 4349a36c61f9SKrishna Gudipati /* 4350a36c61f9SKrishna Gudipati * this rport already exists 4351a36c61f9SKrishna Gudipati */ 4352a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4353a36c61f9SKrishna Gudipati } 4354a36c61f9SKrishna Gudipati 4355a36c61f9SKrishna Gudipati bfa_trc(port->fcs, gidft_entry->pid); 4356a36c61f9SKrishna Gudipati 4357a36c61f9SKrishna Gudipati /* 4358a36c61f9SKrishna Gudipati * if the last entry bit is set, bail out. 4359a36c61f9SKrishna Gudipati */ 4360a36c61f9SKrishna Gudipati if (gidft_entry->last) 4361a36c61f9SKrishna Gudipati return; 4362a36c61f9SKrishna Gudipati } 4363a36c61f9SKrishna Gudipati } 4364a36c61f9SKrishna Gudipati 43655fbe25c7SJing Huang /* 4366a36c61f9SKrishna Gudipati * fcs_ns_public FCS nameserver public interfaces 4367a36c61f9SKrishna Gudipati */ 4368a36c61f9SKrishna Gudipati 4369a36c61f9SKrishna Gudipati /* 4370a36c61f9SKrishna Gudipati * Functions called by port/fab. 4371a36c61f9SKrishna Gudipati * These will send relevant Events to the ns state machine. 4372a36c61f9SKrishna Gudipati */ 4373a36c61f9SKrishna Gudipati void 4374a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port) 4375a36c61f9SKrishna Gudipati { 4376a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4377a36c61f9SKrishna Gudipati 4378a36c61f9SKrishna Gudipati ns->port = port; 4379a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4380a36c61f9SKrishna Gudipati } 4381a36c61f9SKrishna Gudipati 4382a36c61f9SKrishna Gudipati void 4383a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port) 4384a36c61f9SKrishna Gudipati { 4385a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4386a36c61f9SKrishna Gudipati 4387a36c61f9SKrishna Gudipati ns->port = port; 4388a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE); 4389a36c61f9SKrishna Gudipati } 4390a36c61f9SKrishna Gudipati 4391a36c61f9SKrishna Gudipati void 4392a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port) 4393a36c61f9SKrishna Gudipati { 4394a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4395a36c61f9SKrishna Gudipati 4396a36c61f9SKrishna Gudipati ns->port = port; 4397a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE); 4398a36c61f9SKrishna Gudipati } 4399a36c61f9SKrishna Gudipati 4400a36c61f9SKrishna Gudipati void 4401a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port) 4402a36c61f9SKrishna Gudipati { 4403a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4404a36c61f9SKrishna Gudipati 4405a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4406a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 4407a36c61f9SKrishna Gudipati } 4408a36c61f9SKrishna Gudipati 440952f94b6fSMaggie static void 4410a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port) 4411a36c61f9SKrishna Gudipati { 4412a36c61f9SKrishna Gudipati 4413a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4414a36c61f9SKrishna Gudipati u8 nwwns; 4415a36c61f9SKrishna Gudipati wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; 4416a36c61f9SKrishna Gudipati int ii; 4417a36c61f9SKrishna Gudipati 4418a36c61f9SKrishna Gudipati bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns); 4419a36c61f9SKrishna Gudipati 4420a36c61f9SKrishna Gudipati for (ii = 0 ; ii < nwwns; ++ii) { 4421a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]); 4422d4b671c5SJing Huang WARN_ON(!rport); 4423a36c61f9SKrishna Gudipati } 4424a36c61f9SKrishna Gudipati } 4425a36c61f9SKrishna Gudipati 4426ebfe8392SKrishna Gudipati void 4427ebfe8392SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) 4428ebfe8392SKrishna Gudipati { 4429ebfe8392SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = cbarg; 4430ebfe8392SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4431ebfe8392SKrishna Gudipati struct fchs_s fchs; 4432ebfe8392SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4433ebfe8392SKrishna Gudipati u8 symbl[256]; 4434ebfe8392SKrishna Gudipati u8 *psymbl = &symbl[0]; 4435ebfe8392SKrishna Gudipati int len; 4436ebfe8392SKrishna Gudipati 4437ebfe8392SKrishna Gudipati if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 4438ebfe8392SKrishna Gudipati return; 4439ebfe8392SKrishna Gudipati 4440ebfe8392SKrishna Gudipati /* Avoid sending RSPN in the following states. */ 4441ebfe8392SKrishna Gudipati if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) || 4442ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) || 4443ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) || 4444ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) || 4445ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry)) 4446ebfe8392SKrishna Gudipati return; 4447ebfe8392SKrishna Gudipati 4448ebfe8392SKrishna Gudipati memset(symbl, 0, sizeof(symbl)); 4449ebfe8392SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4450ebfe8392SKrishna Gudipati 4451c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4452c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 4453ebfe8392SKrishna Gudipati if (!fcxp) { 4454ebfe8392SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 4455ebfe8392SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4456c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE); 4457ebfe8392SKrishna Gudipati return; 4458ebfe8392SKrishna Gudipati } 4459ebfe8392SKrishna Gudipati 4460ebfe8392SKrishna Gudipati ns->fcxp = fcxp; 4461ebfe8392SKrishna Gudipati 4462ebfe8392SKrishna Gudipati if (port->vport) { 4463ebfe8392SKrishna Gudipati /* 4464ebfe8392SKrishna Gudipati * For Vports, we append the vport's port symbolic name 4465ebfe8392SKrishna Gudipati * to that of the base port. 4466ebfe8392SKrishna Gudipati */ 4467ebfe8392SKrishna Gudipati strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name 4468ebfe8392SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 4469ebfe8392SKrishna Gudipati strlen((char *)&bfa_fcs_lport_get_psym_name( 4470ebfe8392SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)))); 4471ebfe8392SKrishna Gudipati 4472ebfe8392SKrishna Gudipati /* Ensure we have a null terminating string. */ 4473ebfe8392SKrishna Gudipati ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name( 4474ebfe8392SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)))] = 0; 4475ebfe8392SKrishna Gudipati 4476ebfe8392SKrishna Gudipati strncat((char *)psymbl, 4477ebfe8392SKrishna Gudipati (char *)&(bfa_fcs_lport_get_psym_name(port)), 4478ebfe8392SKrishna Gudipati strlen((char *)&bfa_fcs_lport_get_psym_name(port))); 4479ebfe8392SKrishna Gudipati } 4480ebfe8392SKrishna Gudipati 4481ebfe8392SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4482ebfe8392SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, psymbl); 4483ebfe8392SKrishna Gudipati 4484ebfe8392SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4485ebfe8392SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 4486ebfe8392SKrishna Gudipati 4487ebfe8392SKrishna Gudipati port->stats.ns_rspnid_sent++; 4488ebfe8392SKrishna Gudipati } 4489ebfe8392SKrishna Gudipati 44905fbe25c7SJing Huang /* 4491a36c61f9SKrishna Gudipati * FCS SCN 4492a36c61f9SKrishna Gudipati */ 4493a36c61f9SKrishna Gudipati 4494a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT 0x0c 4495a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT 0x0d 4496a36c61f9SKrishna Gudipati 4497a36c61f9SKrishna Gudipati /* 4498a36c61f9SKrishna Gudipati * forward declarations 4499a36c61f9SKrishna Gudipati */ 4500a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg, 4501a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 4502a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_scr_response(void *fcsarg, 4503a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 4504a36c61f9SKrishna Gudipati void *cbarg, 4505a36c61f9SKrishna Gudipati bfa_status_t req_status, 4506a36c61f9SKrishna Gudipati u32 rsp_len, 4507a36c61f9SKrishna Gudipati u32 resid_len, 4508a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 4509a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4510a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs); 4511a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_timeout(void *arg); 4512a36c61f9SKrishna Gudipati 45135fbe25c7SJing Huang /* 4514a36c61f9SKrishna Gudipati * fcs_scm_sm FCS SCN state machine 4515a36c61f9SKrishna Gudipati */ 4516a36c61f9SKrishna Gudipati 45175fbe25c7SJing Huang /* 4518a36c61f9SKrishna Gudipati * VPort SCN State Machine events 4519a36c61f9SKrishna Gudipati */ 4520a36c61f9SKrishna Gudipati enum port_scn_event { 4521a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_ONLINE = 1, 4522a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_OFFLINE = 2, 4523a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_OK = 3, 4524a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_ERROR = 4, 4525a36c61f9SKrishna Gudipati SCNSM_EVENT_TIMEOUT = 5, 4526a36c61f9SKrishna Gudipati SCNSM_EVENT_SCR_SENT = 6, 4527a36c61f9SKrishna Gudipati }; 4528a36c61f9SKrishna Gudipati 4529a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4530a36c61f9SKrishna Gudipati enum port_scn_event event); 4531a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_sending_scr( 4532a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn, 4533a36c61f9SKrishna Gudipati enum port_scn_event event); 4534a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4535a36c61f9SKrishna Gudipati enum port_scn_event event); 4536a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4537a36c61f9SKrishna Gudipati enum port_scn_event event); 4538a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4539a36c61f9SKrishna Gudipati enum port_scn_event event); 4540a36c61f9SKrishna Gudipati 45415fbe25c7SJing Huang /* 4542a36c61f9SKrishna Gudipati * Starting state - awaiting link up. 4543a36c61f9SKrishna Gudipati */ 4544a36c61f9SKrishna Gudipati static void 4545a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4546a36c61f9SKrishna Gudipati enum port_scn_event event) 4547a36c61f9SKrishna Gudipati { 4548a36c61f9SKrishna Gudipati switch (event) { 4549a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_ONLINE: 4550a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4551a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 4552a36c61f9SKrishna Gudipati break; 4553a36c61f9SKrishna Gudipati 4554a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4555a36c61f9SKrishna Gudipati break; 4556a36c61f9SKrishna Gudipati 4557a36c61f9SKrishna Gudipati default: 4558a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4559a36c61f9SKrishna Gudipati } 4560a36c61f9SKrishna Gudipati } 4561a36c61f9SKrishna Gudipati 4562a36c61f9SKrishna Gudipati static void 4563a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn, 4564a36c61f9SKrishna Gudipati enum port_scn_event event) 4565a36c61f9SKrishna Gudipati { 4566a36c61f9SKrishna Gudipati switch (event) { 4567a36c61f9SKrishna Gudipati case SCNSM_EVENT_SCR_SENT: 4568a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr); 4569a36c61f9SKrishna Gudipati break; 4570a36c61f9SKrishna Gudipati 4571a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4572a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4573a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe); 4574a36c61f9SKrishna Gudipati break; 4575a36c61f9SKrishna Gudipati 4576a36c61f9SKrishna Gudipati default: 4577a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4578a36c61f9SKrishna Gudipati } 4579a36c61f9SKrishna Gudipati } 4580a36c61f9SKrishna Gudipati 4581a36c61f9SKrishna Gudipati static void 4582a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4583a36c61f9SKrishna Gudipati enum port_scn_event event) 4584a36c61f9SKrishna Gudipati { 4585a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4586a36c61f9SKrishna Gudipati 4587a36c61f9SKrishna Gudipati switch (event) { 4588a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_OK: 4589a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online); 4590a36c61f9SKrishna Gudipati break; 4591a36c61f9SKrishna Gudipati 4592a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_ERROR: 4593a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry); 4594a36c61f9SKrishna Gudipati bfa_timer_start(port->fcs->bfa, &scn->timer, 4595a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout, scn, 4596a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4597a36c61f9SKrishna Gudipati break; 4598a36c61f9SKrishna Gudipati 4599a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4600a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4601a36c61f9SKrishna Gudipati bfa_fcxp_discard(scn->fcxp); 4602a36c61f9SKrishna Gudipati break; 4603a36c61f9SKrishna Gudipati 4604a36c61f9SKrishna Gudipati default: 4605a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 4606a36c61f9SKrishna Gudipati } 4607a36c61f9SKrishna Gudipati } 4608a36c61f9SKrishna Gudipati 4609a36c61f9SKrishna Gudipati static void 4610a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4611a36c61f9SKrishna Gudipati enum port_scn_event event) 4612a36c61f9SKrishna Gudipati { 4613a36c61f9SKrishna Gudipati switch (event) { 4614a36c61f9SKrishna Gudipati case SCNSM_EVENT_TIMEOUT: 4615a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4616a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 4617a36c61f9SKrishna Gudipati break; 4618a36c61f9SKrishna Gudipati 4619a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4620a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4621a36c61f9SKrishna Gudipati bfa_timer_stop(&scn->timer); 4622a36c61f9SKrishna Gudipati break; 4623a36c61f9SKrishna Gudipati 4624a36c61f9SKrishna Gudipati default: 4625a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4626a36c61f9SKrishna Gudipati } 4627a36c61f9SKrishna Gudipati } 4628a36c61f9SKrishna Gudipati 4629a36c61f9SKrishna Gudipati static void 4630a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4631a36c61f9SKrishna Gudipati enum port_scn_event event) 4632a36c61f9SKrishna Gudipati { 4633a36c61f9SKrishna Gudipati switch (event) { 4634a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4635a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4636a36c61f9SKrishna Gudipati break; 4637a36c61f9SKrishna Gudipati 4638a36c61f9SKrishna Gudipati default: 4639a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4640a36c61f9SKrishna Gudipati } 4641a36c61f9SKrishna Gudipati } 4642a36c61f9SKrishna Gudipati 4643a36c61f9SKrishna Gudipati 4644a36c61f9SKrishna Gudipati 46455fbe25c7SJing Huang /* 4646a36c61f9SKrishna Gudipati * fcs_scn_private FCS SCN private functions 4647a36c61f9SKrishna Gudipati */ 4648a36c61f9SKrishna Gudipati 46495fbe25c7SJing Huang /* 4650a36c61f9SKrishna Gudipati * This routine will be called to send a SCR command. 4651a36c61f9SKrishna Gudipati */ 4652a36c61f9SKrishna Gudipati static void 4653a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4654a36c61f9SKrishna Gudipati { 4655a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = scn_cbarg; 4656a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4657a36c61f9SKrishna Gudipati struct fchs_s fchs; 4658a36c61f9SKrishna Gudipati int len; 4659a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4660a36c61f9SKrishna Gudipati 4661a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4662a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4663a36c61f9SKrishna Gudipati 4664c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4665c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4666a36c61f9SKrishna Gudipati if (!fcxp) { 4667a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, 4668c3f1b123SKrishna Gudipati bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE); 4669a36c61f9SKrishna Gudipati return; 4670a36c61f9SKrishna Gudipati } 4671a36c61f9SKrishna Gudipati scn->fcxp = fcxp; 4672a36c61f9SKrishna Gudipati 4673a36c61f9SKrishna Gudipati /* Handle VU registrations for Base port only */ 4674a36c61f9SKrishna Gudipati if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) { 4675a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4676f7f73812SMaggie Zhang port->fabric->lps->brcd_switch, 4677a36c61f9SKrishna Gudipati port->pid, 0); 4678a36c61f9SKrishna Gudipati } else { 4679a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4680a36c61f9SKrishna Gudipati BFA_FALSE, 4681a36c61f9SKrishna Gudipati port->pid, 0); 4682a36c61f9SKrishna Gudipati } 4683a36c61f9SKrishna Gudipati 4684a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4685a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4686a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response, 4687a36c61f9SKrishna Gudipati (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV); 4688a36c61f9SKrishna Gudipati 4689a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT); 4690a36c61f9SKrishna Gudipati } 4691a36c61f9SKrishna Gudipati 4692a36c61f9SKrishna Gudipati static void 4693a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4694a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 4695a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 4696a36c61f9SKrishna Gudipati { 4697a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg; 4698a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4699a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 4700a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 4701a36c61f9SKrishna Gudipati 4702a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4703a36c61f9SKrishna Gudipati 4704a36c61f9SKrishna Gudipati /* 4705a36c61f9SKrishna Gudipati * Sanity Checks 4706a36c61f9SKrishna Gudipati */ 4707a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4708a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4709a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4710a36c61f9SKrishna Gudipati return; 4711a36c61f9SKrishna Gudipati } 4712a36c61f9SKrishna Gudipati 4713a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 4714a36c61f9SKrishna Gudipati 4715a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 4716a36c61f9SKrishna Gudipati 4717a36c61f9SKrishna Gudipati case FC_ELS_ACC: 4718a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK); 4719a36c61f9SKrishna Gudipati break; 4720a36c61f9SKrishna Gudipati 4721a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 4722a36c61f9SKrishna Gudipati 4723a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 4724a36c61f9SKrishna Gudipati 4725a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 4726a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 4727a36c61f9SKrishna Gudipati 4728a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4729a36c61f9SKrishna Gudipati break; 4730a36c61f9SKrishna Gudipati 4731a36c61f9SKrishna Gudipati default: 4732a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4733a36c61f9SKrishna Gudipati } 4734a36c61f9SKrishna Gudipati } 4735a36c61f9SKrishna Gudipati 4736a36c61f9SKrishna Gudipati /* 4737a36c61f9SKrishna Gudipati * Send a LS Accept 4738a36c61f9SKrishna Gudipati */ 4739a36c61f9SKrishna Gudipati static void 4740a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4741a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs) 4742a36c61f9SKrishna Gudipati { 4743a36c61f9SKrishna Gudipati struct fchs_s fchs; 4744a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4745a36c61f9SKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 4746a36c61f9SKrishna Gudipati int len; 4747a36c61f9SKrishna Gudipati 4748a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 4749a36c61f9SKrishna Gudipati 4750c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 4751a36c61f9SKrishna Gudipati if (!fcxp) 4752a36c61f9SKrishna Gudipati return; 4753a36c61f9SKrishna Gudipati 4754a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4755a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 4756a36c61f9SKrishna Gudipati rx_fchs->ox_id); 4757a36c61f9SKrishna Gudipati 4758a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 4759a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 4760a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 4761a36c61f9SKrishna Gudipati } 4762a36c61f9SKrishna Gudipati 47635fbe25c7SJing Huang /* 4764a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 4765a36c61f9SKrishna Gudipati * 4766a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_lport_t. 4767a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 4768a36c61f9SKrishna Gudipati * 4769a36c61f9SKrishna Gudipati * return 4770a36c61f9SKrishna Gudipati * void 4771a36c61f9SKrishna Gudipati * 4772a36c61f9SKrishna Gudipati * Special Considerations: 4773a36c61f9SKrishna Gudipati * 4774a36c61f9SKrishna Gudipati * note 4775a36c61f9SKrishna Gudipati */ 4776a36c61f9SKrishna Gudipati static void 4777a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg) 4778a36c61f9SKrishna Gudipati { 4779a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg; 4780a36c61f9SKrishna Gudipati 4781a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT); 4782a36c61f9SKrishna Gudipati } 4783a36c61f9SKrishna Gudipati 4784a36c61f9SKrishna Gudipati 4785a36c61f9SKrishna Gudipati 47865fbe25c7SJing Huang /* 4787a36c61f9SKrishna Gudipati * fcs_scn_public FCS state change notification public interfaces 4788a36c61f9SKrishna Gudipati */ 4789a36c61f9SKrishna Gudipati 4790a36c61f9SKrishna Gudipati /* 4791a36c61f9SKrishna Gudipati * Functions called by port/fab 4792a36c61f9SKrishna Gudipati */ 4793a36c61f9SKrishna Gudipati void 4794a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port) 4795a36c61f9SKrishna Gudipati { 4796a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4797a36c61f9SKrishna Gudipati 4798a36c61f9SKrishna Gudipati scn->port = port; 4799a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4800a36c61f9SKrishna Gudipati } 4801a36c61f9SKrishna Gudipati 4802a36c61f9SKrishna Gudipati void 4803a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port) 4804a36c61f9SKrishna Gudipati { 4805a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4806a36c61f9SKrishna Gudipati 4807a36c61f9SKrishna Gudipati scn->port = port; 4808a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE); 4809a36c61f9SKrishna Gudipati } 4810a36c61f9SKrishna Gudipati 4811a36c61f9SKrishna Gudipati void 4812a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port) 4813a36c61f9SKrishna Gudipati { 4814a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4815a36c61f9SKrishna Gudipati 4816a36c61f9SKrishna Gudipati scn->port = port; 4817a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE); 4818a36c61f9SKrishna Gudipati } 4819a36c61f9SKrishna Gudipati 4820a36c61f9SKrishna Gudipati static void 4821a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) 4822a36c61f9SKrishna Gudipati { 4823a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4824a36c61f9SKrishna Gudipati 4825a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rpid); 4826a36c61f9SKrishna Gudipati 48275fbe25c7SJing Huang /* 4828a36c61f9SKrishna Gudipati * If this is an unknown device, then it just came online. 4829a36c61f9SKrishna Gudipati * Otherwise let rport handle the RSCN event. 4830a36c61f9SKrishna Gudipati */ 4831a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 4832ee1a4a42SKrishna Gudipati if (!rport) 4833ee1a4a42SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid); 4834ee1a4a42SKrishna Gudipati 4835a36c61f9SKrishna Gudipati if (rport == NULL) { 4836a36c61f9SKrishna Gudipati /* 4837a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot need to 4838a36c61f9SKrishna Gudipati * discover any new rports. 4839a36c61f9SKrishna Gudipati */ 4840a36c61f9SKrishna Gudipati if (!__fcs_min_cfg(port->fcs)) 4841a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, rpid); 4842a36c61f9SKrishna Gudipati } else 4843a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4844a36c61f9SKrishna Gudipati } 4845a36c61f9SKrishna Gudipati 48465fbe25c7SJing Huang /* 4847a36c61f9SKrishna Gudipati * rscn format based PID comparison 4848a36c61f9SKrishna Gudipati */ 4849a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt) \ 4850a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \ 4851a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \ 4852a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0])) || \ 4853a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_AREA) && \ 4854a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0]) && \ 4855a36c61f9SKrishna Gudipati ((__c0)[1] == (__c1)[1]))) 4856a36c61f9SKrishna Gudipati 4857a36c61f9SKrishna Gudipati static void 4858a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port, 4859a36c61f9SKrishna Gudipati enum fc_rscn_format format, 4860a36c61f9SKrishna Gudipati u32 rscn_pid) 4861a36c61f9SKrishna Gudipati { 4862a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4863a36c61f9SKrishna Gudipati struct list_head *qe, *qe_next; 4864a36c61f9SKrishna Gudipati u8 *c0, *c1; 4865a36c61f9SKrishna Gudipati 4866a36c61f9SKrishna Gudipati bfa_trc(port->fcs, format); 4867a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4868a36c61f9SKrishna Gudipati 4869a36c61f9SKrishna Gudipati c0 = (u8 *) &rscn_pid; 4870a36c61f9SKrishna Gudipati 4871a36c61f9SKrishna Gudipati list_for_each_safe(qe, qe_next, &port->rport_q) { 4872a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4873a36c61f9SKrishna Gudipati c1 = (u8 *) &rport->pid; 4874a36c61f9SKrishna Gudipati if (__fc_pid_match(c0, c1, format)) 4875a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4876a36c61f9SKrishna Gudipati } 4877a36c61f9SKrishna Gudipati } 4878a36c61f9SKrishna Gudipati 4879a36c61f9SKrishna Gudipati 4880a36c61f9SKrishna Gudipati void 4881a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 4882a36c61f9SKrishna Gudipati struct fchs_s *fchs, u32 len) 4883a36c61f9SKrishna Gudipati { 4884a36c61f9SKrishna Gudipati struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1); 4885a36c61f9SKrishna Gudipati int num_entries; 4886a36c61f9SKrishna Gudipati u32 rscn_pid; 4887a36c61f9SKrishna Gudipati bfa_boolean_t nsquery = BFA_FALSE, found; 4888a36c61f9SKrishna Gudipati int i = 0, j; 4889a36c61f9SKrishna Gudipati 4890a36c61f9SKrishna Gudipati num_entries = 4891ba816ea8SJing Huang (be16_to_cpu(rscn->payldlen) - 4892a36c61f9SKrishna Gudipati sizeof(u32)) / sizeof(rscn->event[0]); 4893a36c61f9SKrishna Gudipati 4894a36c61f9SKrishna Gudipati bfa_trc(port->fcs, num_entries); 4895a36c61f9SKrishna Gudipati 4896a36c61f9SKrishna Gudipati port->stats.num_rscn++; 4897a36c61f9SKrishna Gudipati 4898a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(port, fchs); 4899a36c61f9SKrishna Gudipati 4900a36c61f9SKrishna Gudipati for (i = 0; i < num_entries; i++) { 4901a36c61f9SKrishna Gudipati rscn_pid = rscn->event[i].portid; 4902a36c61f9SKrishna Gudipati 4903a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn->event[i].format); 4904a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4905a36c61f9SKrishna Gudipati 4906a36c61f9SKrishna Gudipati /* check for duplicate entries in the list */ 4907a36c61f9SKrishna Gudipati found = BFA_FALSE; 4908a36c61f9SKrishna Gudipati for (j = 0; j < i; j++) { 4909a36c61f9SKrishna Gudipati if (rscn->event[j].portid == rscn_pid) { 4910a36c61f9SKrishna Gudipati found = BFA_TRUE; 4911a36c61f9SKrishna Gudipati break; 4912a36c61f9SKrishna Gudipati } 4913a36c61f9SKrishna Gudipati } 4914a36c61f9SKrishna Gudipati 4915a36c61f9SKrishna Gudipati /* if found in down the list, pid has been already processed */ 4916a36c61f9SKrishna Gudipati if (found) { 4917a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4918a36c61f9SKrishna Gudipati continue; 4919a36c61f9SKrishna Gudipati } 4920a36c61f9SKrishna Gudipati 4921a36c61f9SKrishna Gudipati switch (rscn->event[i].format) { 4922a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_PORTID: 4923a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) { 4924a36c61f9SKrishna Gudipati /* 4925a36c61f9SKrishna Gudipati * Ignore this event. 4926a36c61f9SKrishna Gudipati * f/w would have processed it 4927a36c61f9SKrishna Gudipati */ 4928a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4929a36c61f9SKrishna Gudipati } else { 4930a36c61f9SKrishna Gudipati port->stats.num_portid_rscn++; 4931a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(port, rscn_pid); 4932a36c61f9SKrishna Gudipati } 4933a36c61f9SKrishna Gudipati break; 4934a36c61f9SKrishna Gudipati 4935a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_FABRIC: 4936a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == 4937a36c61f9SKrishna Gudipati FC_FABRIC_NAME_RSCN_EVENT) { 4938a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(port); 4939a36c61f9SKrishna Gudipati break; 4940a36c61f9SKrishna Gudipati } 4941a36c61f9SKrishna Gudipati /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */ 4942a36c61f9SKrishna Gudipati 4943a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_AREA: 4944a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_DOMAIN: 4945a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 4946a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(port, 4947a36c61f9SKrishna Gudipati rscn->event[i].format, 4948a36c61f9SKrishna Gudipati rscn_pid); 4949a36c61f9SKrishna Gudipati break; 4950a36c61f9SKrishna Gudipati 4951a36c61f9SKrishna Gudipati 4952a36c61f9SKrishna Gudipati default: 4953d4b671c5SJing Huang WARN_ON(1); 4954a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 4955a36c61f9SKrishna Gudipati } 4956a36c61f9SKrishna Gudipati } 4957a36c61f9SKrishna Gudipati 49585fbe25c7SJing Huang /* 49595fbe25c7SJing Huang * If any of area, domain or fabric RSCN is received, do a fresh 49605fbe25c7SJing Huang * discovery to find new devices. 4961a36c61f9SKrishna Gudipati */ 4962a36c61f9SKrishna Gudipati if (nsquery) 4963a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(port); 4964a36c61f9SKrishna Gudipati } 4965a36c61f9SKrishna Gudipati 49665fbe25c7SJing Huang /* 4967a36c61f9SKrishna Gudipati * BFA FCS port 4968a36c61f9SKrishna Gudipati */ 49695fbe25c7SJing Huang /* 4970a36c61f9SKrishna Gudipati * fcs_port_api BFA FCS port API 4971a36c61f9SKrishna Gudipati */ 4972a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 4973a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs) 4974a36c61f9SKrishna Gudipati { 4975a36c61f9SKrishna Gudipati return &fcs->fabric.bport; 4976a36c61f9SKrishna Gudipati } 4977a36c61f9SKrishna Gudipati 4978a36c61f9SKrishna Gudipati wwn_t 4979a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, 4980a36c61f9SKrishna Gudipati int nrports, bfa_boolean_t bwwn) 4981a36c61f9SKrishna Gudipati { 4982a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 4983a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 4984a36c61f9SKrishna Gudipati int i; 4985a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 4986a36c61f9SKrishna Gudipati 4987a36c61f9SKrishna Gudipati if (port == NULL || nrports == 0) 4988a36c61f9SKrishna Gudipati return (wwn_t) 0; 4989a36c61f9SKrishna Gudipati 4990a36c61f9SKrishna Gudipati fcs = port->fcs; 4991a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) nrports); 4992a36c61f9SKrishna Gudipati 4993a36c61f9SKrishna Gudipati i = 0; 4994a36c61f9SKrishna Gudipati qh = &port->rport_q; 4995a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 4996a36c61f9SKrishna Gudipati 4997a36c61f9SKrishna Gudipati while ((qe != qh) && (i < nrports)) { 4998a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4999f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 5000a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5001a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 5002a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 5003a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5004a36c61f9SKrishna Gudipati continue; 5005a36c61f9SKrishna Gudipati } 5006a36c61f9SKrishna Gudipati 5007a36c61f9SKrishna Gudipati if (bwwn) { 5008a36c61f9SKrishna Gudipati if (!memcmp(&wwn, &rport->pwwn, 8)) 5009a36c61f9SKrishna Gudipati break; 5010a36c61f9SKrishna Gudipati } else { 5011a36c61f9SKrishna Gudipati if (i == index) 5012a36c61f9SKrishna Gudipati break; 5013a36c61f9SKrishna Gudipati } 5014a36c61f9SKrishna Gudipati 5015a36c61f9SKrishna Gudipati i++; 5016a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5017a36c61f9SKrishna Gudipati } 5018a36c61f9SKrishna Gudipati 5019a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5020a36c61f9SKrishna Gudipati if (rport) 5021a36c61f9SKrishna Gudipati return rport->pwwn; 5022a36c61f9SKrishna Gudipati else 5023a36c61f9SKrishna Gudipati return (wwn_t) 0; 5024a36c61f9SKrishna Gudipati } 5025a36c61f9SKrishna Gudipati 5026a36c61f9SKrishna Gudipati void 5027ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port, 5028ee1a4a42SKrishna Gudipati struct bfa_rport_qualifier_s rports[], int *nrports) 5029a36c61f9SKrishna Gudipati { 5030a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5031a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5032a36c61f9SKrishna Gudipati int i; 5033a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5034a36c61f9SKrishna Gudipati 5035ee1a4a42SKrishna Gudipati if (port == NULL || rports == NULL || *nrports == 0) 5036a36c61f9SKrishna Gudipati return; 5037a36c61f9SKrishna Gudipati 5038a36c61f9SKrishna Gudipati fcs = port->fcs; 5039a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) *nrports); 5040a36c61f9SKrishna Gudipati 5041a36c61f9SKrishna Gudipati i = 0; 5042a36c61f9SKrishna Gudipati qh = &port->rport_q; 5043a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5044a36c61f9SKrishna Gudipati 5045a36c61f9SKrishna Gudipati while ((qe != qh) && (i < *nrports)) { 5046a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5047f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 5048a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5049a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 5050a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 5051a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5052a36c61f9SKrishna Gudipati continue; 5053a36c61f9SKrishna Gudipati } 5054a36c61f9SKrishna Gudipati 5055ee1a4a42SKrishna Gudipati if (!rport->pwwn && !rport->pid) { 5056ee1a4a42SKrishna Gudipati qe = bfa_q_next(qe); 5057ee1a4a42SKrishna Gudipati continue; 5058ee1a4a42SKrishna Gudipati } 5059ee1a4a42SKrishna Gudipati 5060ee1a4a42SKrishna Gudipati rports[i].pwwn = rport->pwwn; 5061ee1a4a42SKrishna Gudipati rports[i].pid = rport->pid; 5062a36c61f9SKrishna Gudipati 5063a36c61f9SKrishna Gudipati i++; 5064a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5065a36c61f9SKrishna Gudipati } 5066a36c61f9SKrishna Gudipati 5067a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5068a36c61f9SKrishna Gudipati *nrports = i; 5069a36c61f9SKrishna Gudipati } 5070a36c61f9SKrishna Gudipati 5071a36c61f9SKrishna Gudipati /* 5072a36c61f9SKrishna Gudipati * Iterate's through all the rport's in the given port to 5073a36c61f9SKrishna Gudipati * determine the maximum operating speed. 5074a36c61f9SKrishna Gudipati * 5075a36c61f9SKrishna Gudipati * !!!! To be used in TRL Functionality only !!!! 5076a36c61f9SKrishna Gudipati */ 5077a36c61f9SKrishna Gudipati bfa_port_speed_t 5078a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) 5079a36c61f9SKrishna Gudipati { 5080a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5081a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5082a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5083a36c61f9SKrishna Gudipati bfa_port_speed_t max_speed = 0; 5084a36c61f9SKrishna Gudipati struct bfa_port_attr_s port_attr; 5085a36c61f9SKrishna Gudipati bfa_port_speed_t port_speed, rport_speed; 5086a36c61f9SKrishna Gudipati bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa); 5087a36c61f9SKrishna Gudipati 5088a36c61f9SKrishna Gudipati 5089a36c61f9SKrishna Gudipati if (port == NULL) 5090a36c61f9SKrishna Gudipati return 0; 5091a36c61f9SKrishna Gudipati 5092a36c61f9SKrishna Gudipati fcs = port->fcs; 5093a36c61f9SKrishna Gudipati 5094a36c61f9SKrishna Gudipati /* Get Physical port's current speed */ 5095a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &port_attr); 5096a36c61f9SKrishna Gudipati port_speed = port_attr.speed; 5097a36c61f9SKrishna Gudipati bfa_trc(fcs, port_speed); 5098a36c61f9SKrishna Gudipati 5099a36c61f9SKrishna Gudipati qh = &port->rport_q; 5100a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5101a36c61f9SKrishna Gudipati 5102a36c61f9SKrishna Gudipati while (qe != qh) { 5103a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5104f16a1750SMaggie Zhang if ((bfa_ntoh3b(rport->pid) > 0xFFF000) || 5105d7be54ccSKrishna Gudipati (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) || 5106d7be54ccSKrishna Gudipati (rport->scsi_function != BFA_RPORT_TARGET)) { 5107a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5108a36c61f9SKrishna Gudipati continue; 5109a36c61f9SKrishna Gudipati } 5110a36c61f9SKrishna Gudipati 5111a36c61f9SKrishna Gudipati rport_speed = rport->rpf.rpsc_speed; 5112a36c61f9SKrishna Gudipati if ((trl_enabled) && (rport_speed == 5113a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN)) { 5114a36c61f9SKrishna Gudipati /* Use default ratelim speed setting */ 5115a36c61f9SKrishna Gudipati rport_speed = 5116a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(port->fcs->bfa); 5117a36c61f9SKrishna Gudipati } 5118a36c61f9SKrishna Gudipati 5119d7be54ccSKrishna Gudipati if (rport_speed > max_speed) 5120a36c61f9SKrishna Gudipati max_speed = rport_speed; 5121a36c61f9SKrishna Gudipati 5122a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5123a36c61f9SKrishna Gudipati } 5124a36c61f9SKrishna Gudipati 5125d7be54ccSKrishna Gudipati if (max_speed > port_speed) 5126d7be54ccSKrishna Gudipati max_speed = port_speed; 5127d7be54ccSKrishna Gudipati 5128a36c61f9SKrishna Gudipati bfa_trc(fcs, max_speed); 5129a36c61f9SKrishna Gudipati return max_speed; 5130a36c61f9SKrishna Gudipati } 5131a36c61f9SKrishna Gudipati 5132a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 5133a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn) 5134a36c61f9SKrishna Gudipati { 5135a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 5136a36c61f9SKrishna Gudipati bfa_fcs_vf_t *vf; 5137a36c61f9SKrishna Gudipati 5138d4b671c5SJing Huang WARN_ON(fcs == NULL); 5139a36c61f9SKrishna Gudipati 5140a36c61f9SKrishna Gudipati vf = bfa_fcs_vf_lookup(fcs, vf_id); 5141a36c61f9SKrishna Gudipati if (vf == NULL) { 5142a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5143a36c61f9SKrishna Gudipati return NULL; 5144a36c61f9SKrishna Gudipati } 5145a36c61f9SKrishna Gudipati 5146a36c61f9SKrishna Gudipati if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn)) 5147a36c61f9SKrishna Gudipati return &vf->bport; 5148a36c61f9SKrishna Gudipati 5149a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn); 5150a36c61f9SKrishna Gudipati if (vport) 5151a36c61f9SKrishna Gudipati return &vport->lport; 5152a36c61f9SKrishna Gudipati 5153a36c61f9SKrishna Gudipati return NULL; 5154a36c61f9SKrishna Gudipati } 5155a36c61f9SKrishna Gudipati 5156a36c61f9SKrishna Gudipati /* 5157a36c61f9SKrishna Gudipati * API corresponding to NPIV_VPORT_GETINFO. 5158a36c61f9SKrishna Gudipati */ 5159a36c61f9SKrishna Gudipati void 5160a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port, 5161a36c61f9SKrishna Gudipati struct bfa_lport_info_s *port_info) 5162a36c61f9SKrishna Gudipati { 5163a36c61f9SKrishna Gudipati 5164a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->fabric->fabric_name); 5165a36c61f9SKrishna Gudipati 5166a36c61f9SKrishna Gudipati if (port->vport == NULL) { 5167a36c61f9SKrishna Gudipati /* 5168a36c61f9SKrishna Gudipati * This is a Physical port 5169a36c61f9SKrishna Gudipati */ 5170a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_PHYSICAL; 5171a36c61f9SKrishna Gudipati 5172a36c61f9SKrishna Gudipati /* 5173a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5174a36c61f9SKrishna Gudipati */ 5175a36c61f9SKrishna Gudipati port_info->port_state = 0; 5176a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5177a36c61f9SKrishna Gudipati 5178a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5179a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5180a36c61f9SKrishna Gudipati 5181a36c61f9SKrishna Gudipati port_info->max_vports_supp = 5182a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(port->fcs->bfa); 5183a36c61f9SKrishna Gudipati port_info->num_vports_inuse = 5184f7f73812SMaggie Zhang port->fabric->num_vports; 5185a36c61f9SKrishna Gudipati port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; 5186a36c61f9SKrishna Gudipati port_info->num_rports_inuse = port->num_rports; 5187a36c61f9SKrishna Gudipati } else { 5188a36c61f9SKrishna Gudipati /* 5189a36c61f9SKrishna Gudipati * This is a virtual port 5190a36c61f9SKrishna Gudipati */ 5191a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_VIRTUAL; 5192a36c61f9SKrishna Gudipati 5193a36c61f9SKrishna Gudipati /* 5194a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5195a36c61f9SKrishna Gudipati */ 5196a36c61f9SKrishna Gudipati port_info->port_state = 0; 5197a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5198a36c61f9SKrishna Gudipati 5199a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5200a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5201a36c61f9SKrishna Gudipati } 5202a36c61f9SKrishna Gudipati } 5203a36c61f9SKrishna Gudipati 5204a36c61f9SKrishna Gudipati void 5205a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port, 5206a36c61f9SKrishna Gudipati struct bfa_lport_stats_s *port_stats) 5207a36c61f9SKrishna Gudipati { 5208a36c61f9SKrishna Gudipati *port_stats = fcs_port->stats; 5209a36c61f9SKrishna Gudipati } 5210a36c61f9SKrishna Gudipati 5211a36c61f9SKrishna Gudipati void 5212a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) 5213a36c61f9SKrishna Gudipati { 52146a18b167SJing Huang memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s)); 5215a36c61f9SKrishna Gudipati } 5216a36c61f9SKrishna Gudipati 52175fbe25c7SJing Huang /* 5218a36c61f9SKrishna Gudipati * FCS virtual port state machine 5219a36c61f9SKrishna Gudipati */ 5220a36c61f9SKrishna Gudipati 5221a36c61f9SKrishna Gudipati #define __vport_fcs(__vp) ((__vp)->lport.fcs) 5222a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn) 5223a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn) 5224a36c61f9SKrishna Gudipati #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa) 5225a36c61f9SKrishna Gudipati #define __vport_fcid(__vp) ((__vp)->lport.pid) 5226a36c61f9SKrishna Gudipati #define __vport_fabric(__vp) ((__vp)->lport.fabric) 5227a36c61f9SKrishna Gudipati #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id) 5228a36c61f9SKrishna Gudipati 5229a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES 5 5230a36c61f9SKrishna Gudipati /* 5231a36c61f9SKrishna Gudipati * Forward declarations 5232a36c61f9SKrishna Gudipati */ 5233a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport); 5234a36c61f9SKrishna Gudipati static void bfa_fcs_vport_timeout(void *vport_arg); 5235a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport); 5236a36c61f9SKrishna Gudipati static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport); 5237a36c61f9SKrishna Gudipati 52385fbe25c7SJing Huang /* 5239a36c61f9SKrishna Gudipati * fcs_vport_sm FCS virtual port state machine 5240a36c61f9SKrishna Gudipati */ 5241a36c61f9SKrishna Gudipati 52425fbe25c7SJing Huang /* 5243a36c61f9SKrishna Gudipati * VPort State Machine events 5244a36c61f9SKrishna Gudipati */ 5245a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event { 5246a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */ 5247a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */ 5248a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_START = 3, /* vport start request */ 5249a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */ 5250a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */ 5251a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */ 5252a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */ 5253a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */ 5254a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */ 5255a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */ 5256a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ 5257a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ 5258a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ 5259dd5aaf45SKrishna Gudipati BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ 5260a36c61f9SKrishna Gudipati }; 5261a36c61f9SKrishna Gudipati 5262a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 5263a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5264a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 5265a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5266a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 5267a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5268a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 5269a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5270a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5271a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5272d7be54ccSKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 5273d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event); 5274a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5275a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5276a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5277a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5278a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5279a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5280a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5281a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5282a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5283a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5284dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 5285dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 5286dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 5287dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 5288a36c61f9SKrishna Gudipati 5289a36c61f9SKrishna Gudipati static struct bfa_sm_table_s vport_sm_table[] = { 5290a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, 5291a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED}, 5292a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, 5293a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, 5294a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, 5295d7be54ccSKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT}, 5296a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, 5297a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, 5298a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, 5299a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO}, 5300a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR} 5301a36c61f9SKrishna Gudipati }; 5302a36c61f9SKrishna Gudipati 53035fbe25c7SJing Huang /* 5304a36c61f9SKrishna Gudipati * Beginning state. 5305a36c61f9SKrishna Gudipati */ 5306a36c61f9SKrishna Gudipati static void 5307a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 5308a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5309a36c61f9SKrishna Gudipati { 5310a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5311a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5312a36c61f9SKrishna Gudipati 5313a36c61f9SKrishna Gudipati switch (event) { 5314a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_CREATE: 5315a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5316a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(__vport_fabric(vport), vport); 5317a36c61f9SKrishna Gudipati break; 5318a36c61f9SKrishna Gudipati 5319a36c61f9SKrishna Gudipati default: 5320a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5321a36c61f9SKrishna Gudipati } 5322a36c61f9SKrishna Gudipati } 5323a36c61f9SKrishna Gudipati 53245fbe25c7SJing Huang /* 5325a36c61f9SKrishna Gudipati * Created state - a start event is required to start up the state machine. 5326a36c61f9SKrishna Gudipati */ 5327a36c61f9SKrishna Gudipati static void 5328a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 5329a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5330a36c61f9SKrishna Gudipati { 5331a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5332a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5333a36c61f9SKrishna Gudipati 5334a36c61f9SKrishna Gudipati switch (event) { 5335a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_START: 5336f7f73812SMaggie Zhang if (bfa_sm_cmp_state(__vport_fabric(vport), 5337f7f73812SMaggie Zhang bfa_fcs_fabric_sm_online) 5338a36c61f9SKrishna Gudipati && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) { 5339a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5340a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5341a36c61f9SKrishna Gudipati } else { 53425fbe25c7SJing Huang /* 5343a36c61f9SKrishna Gudipati * Fabric is offline or not NPIV capable, stay in 5344a36c61f9SKrishna Gudipati * offline state. 5345a36c61f9SKrishna Gudipati */ 5346a36c61f9SKrishna Gudipati vport->vport_stats.fab_no_npiv++; 5347a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5348a36c61f9SKrishna Gudipati } 5349a36c61f9SKrishna Gudipati break; 5350a36c61f9SKrishna Gudipati 5351a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5352a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5353a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5354a36c61f9SKrishna Gudipati break; 5355a36c61f9SKrishna Gudipati 5356a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 5357a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 53585fbe25c7SJing Huang /* 5359a36c61f9SKrishna Gudipati * Ignore ONLINE/OFFLINE events from fabric 5360a36c61f9SKrishna Gudipati * till vport is started. 5361a36c61f9SKrishna Gudipati */ 5362a36c61f9SKrishna Gudipati break; 5363a36c61f9SKrishna Gudipati 5364a36c61f9SKrishna Gudipati default: 5365a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5366a36c61f9SKrishna Gudipati } 5367a36c61f9SKrishna Gudipati } 5368a36c61f9SKrishna Gudipati 53695fbe25c7SJing Huang /* 5370a36c61f9SKrishna Gudipati * Offline state - awaiting ONLINE event from fabric SM. 5371a36c61f9SKrishna Gudipati */ 5372a36c61f9SKrishna Gudipati static void 5373a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 5374a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5375a36c61f9SKrishna Gudipati { 5376a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5377a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5378a36c61f9SKrishna Gudipati 5379a36c61f9SKrishna Gudipati switch (event) { 5380a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5381a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5382a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5383a36c61f9SKrishna Gudipati break; 5384a36c61f9SKrishna Gudipati 5385a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 5386a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5387a36c61f9SKrishna Gudipati vport->fdisc_retries = 0; 5388a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5389a36c61f9SKrishna Gudipati break; 5390a36c61f9SKrishna Gudipati 5391dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 5392dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5393dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 5394dd5aaf45SKrishna Gudipati break; 5395dd5aaf45SKrishna Gudipati 5396a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5397a36c61f9SKrishna Gudipati /* 5398a36c61f9SKrishna Gudipati * This can happen if the vport couldn't be initialzied 5399a36c61f9SKrishna Gudipati * due the fact that the npiv was not enabled on the switch. 5400a36c61f9SKrishna Gudipati * In that case we will put the vport in offline state. 5401a36c61f9SKrishna Gudipati * However, the link can go down and cause the this event to 5402a36c61f9SKrishna Gudipati * be sent when we are already offline. Ignore it. 5403a36c61f9SKrishna Gudipati */ 5404a36c61f9SKrishna Gudipati break; 5405a36c61f9SKrishna Gudipati 5406a36c61f9SKrishna Gudipati default: 5407a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5408a36c61f9SKrishna Gudipati } 5409a36c61f9SKrishna Gudipati } 5410a36c61f9SKrishna Gudipati 5411a36c61f9SKrishna Gudipati 54125fbe25c7SJing Huang /* 5413a36c61f9SKrishna Gudipati * FDISC is sent and awaiting reply from fabric. 5414a36c61f9SKrishna Gudipati */ 5415a36c61f9SKrishna Gudipati static void 5416a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 5417a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5418a36c61f9SKrishna Gudipati { 5419a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5420a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5421a36c61f9SKrishna Gudipati 5422a36c61f9SKrishna Gudipati switch (event) { 5423a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5424d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait); 5425a36c61f9SKrishna Gudipati break; 5426a36c61f9SKrishna Gudipati 5427a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5428a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5429f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5430a36c61f9SKrishna Gudipati break; 5431a36c61f9SKrishna Gudipati 5432a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5433a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_online); 5434a36c61f9SKrishna Gudipati bfa_fcs_lport_online(&vport->lport); 5435a36c61f9SKrishna Gudipati break; 5436a36c61f9SKrishna Gudipati 5437a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5438a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry); 5439a36c61f9SKrishna Gudipati bfa_timer_start(__vport_bfa(vport), &vport->timer, 5440a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout, vport, 5441a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 5442a36c61f9SKrishna Gudipati break; 5443a36c61f9SKrishna Gudipati 5444a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 5445a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5446a36c61f9SKrishna Gudipati break; 5447a36c61f9SKrishna Gudipati 5448a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 5449a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_error); 5450a36c61f9SKrishna Gudipati break; 5451a36c61f9SKrishna Gudipati 5452a36c61f9SKrishna Gudipati default: 5453a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5454a36c61f9SKrishna Gudipati } 5455a36c61f9SKrishna Gudipati } 5456a36c61f9SKrishna Gudipati 54575fbe25c7SJing Huang /* 5458a36c61f9SKrishna Gudipati * FDISC attempt failed - a timer is active to retry FDISC. 5459a36c61f9SKrishna Gudipati */ 5460a36c61f9SKrishna Gudipati static void 5461a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5462a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5463a36c61f9SKrishna Gudipati { 5464a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5465a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5466a36c61f9SKrishna Gudipati 5467a36c61f9SKrishna Gudipati switch (event) { 5468a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5469a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5470a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 5471a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5472a36c61f9SKrishna Gudipati break; 5473a36c61f9SKrishna Gudipati 5474a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5475a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5476a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 5477a36c61f9SKrishna Gudipati break; 5478a36c61f9SKrishna Gudipati 5479a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_TIMEOUT: 5480a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5481a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_retries++; 5482a36c61f9SKrishna Gudipati vport->fdisc_retries++; 5483a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5484a36c61f9SKrishna Gudipati break; 5485a36c61f9SKrishna Gudipati 5486a36c61f9SKrishna Gudipati default: 5487a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5488a36c61f9SKrishna Gudipati } 5489a36c61f9SKrishna Gudipati } 5490a36c61f9SKrishna Gudipati 54915fbe25c7SJing Huang /* 5492d7be54ccSKrishna Gudipati * FDISC is in progress and we got a vport delete request - 5493d7be54ccSKrishna Gudipati * this is a wait state while we wait for fdisc response and 5494d7be54ccSKrishna Gudipati * we will transition to the appropriate state - on rsp status. 5495d7be54ccSKrishna Gudipati */ 5496d7be54ccSKrishna Gudipati static void 5497d7be54ccSKrishna Gudipati bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 5498d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event) 5499d7be54ccSKrishna Gudipati { 5500d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5501d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5502d7be54ccSKrishna Gudipati 5503d7be54ccSKrishna Gudipati switch (event) { 5504d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5505d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 5506d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5507d7be54ccSKrishna Gudipati break; 5508d7be54ccSKrishna Gudipati 5509d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5510d7be54ccSKrishna Gudipati break; 5511d7be54ccSKrishna Gudipati 5512d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5513d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5514d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 5515d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 5516d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5517d7be54ccSKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5518d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5519d7be54ccSKrishna Gudipati break; 5520d7be54ccSKrishna Gudipati 5521d7be54ccSKrishna Gudipati default: 5522d7be54ccSKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5523d7be54ccSKrishna Gudipati } 5524d7be54ccSKrishna Gudipati } 5525d7be54ccSKrishna Gudipati 5526d7be54ccSKrishna Gudipati /* 5527a36c61f9SKrishna Gudipati * Vport is online (FDISC is complete). 5528a36c61f9SKrishna Gudipati */ 5529a36c61f9SKrishna Gudipati static void 5530a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5531a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5532a36c61f9SKrishna Gudipati { 5533a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5534a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5535a36c61f9SKrishna Gudipati 5536a36c61f9SKrishna Gudipati switch (event) { 5537a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5538a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 5539a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5540a36c61f9SKrishna Gudipati break; 5541a36c61f9SKrishna Gudipati 5542dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 5543dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping); 5544dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 5545dd5aaf45SKrishna Gudipati break; 5546dd5aaf45SKrishna Gudipati 5547a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5548a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5549f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5550a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(&vport->lport); 5551a36c61f9SKrishna Gudipati break; 5552a36c61f9SKrishna Gudipati 5553a36c61f9SKrishna Gudipati default: 5554a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5555a36c61f9SKrishna Gudipati } 5556a36c61f9SKrishna Gudipati } 5557a36c61f9SKrishna Gudipati 55585fbe25c7SJing Huang /* 5559dd5aaf45SKrishna Gudipati * Vport is being stopped - awaiting lport stop completion to send 5560dd5aaf45SKrishna Gudipati * LOGO to fabric. 5561dd5aaf45SKrishna Gudipati */ 5562dd5aaf45SKrishna Gudipati static void 5563dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 5564dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 5565dd5aaf45SKrishna Gudipati { 5566dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5567dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5568dd5aaf45SKrishna Gudipati 5569dd5aaf45SKrishna Gudipati switch (event) { 5570dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 5571dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop); 5572dd5aaf45SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 5573dd5aaf45SKrishna Gudipati break; 5574dd5aaf45SKrishna Gudipati 5575dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5576dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5577dd5aaf45SKrishna Gudipati break; 5578dd5aaf45SKrishna Gudipati 5579dd5aaf45SKrishna Gudipati default: 5580dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5581dd5aaf45SKrishna Gudipati } 5582dd5aaf45SKrishna Gudipati } 5583dd5aaf45SKrishna Gudipati 5584dd5aaf45SKrishna Gudipati /* 5585a36c61f9SKrishna Gudipati * Vport is being deleted - awaiting lport delete completion to send 5586a36c61f9SKrishna Gudipati * LOGO to fabric. 5587a36c61f9SKrishna Gudipati */ 5588a36c61f9SKrishna Gudipati static void 5589a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5590a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5591a36c61f9SKrishna Gudipati { 5592a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5593a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5594a36c61f9SKrishna Gudipati 5595a36c61f9SKrishna Gudipati switch (event) { 5596a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5597a36c61f9SKrishna Gudipati break; 5598a36c61f9SKrishna Gudipati 5599a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 5600a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); 5601a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 5602a36c61f9SKrishna Gudipati break; 5603a36c61f9SKrishna Gudipati 5604a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5605a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5606a36c61f9SKrishna Gudipati break; 5607a36c61f9SKrishna Gudipati 5608a36c61f9SKrishna Gudipati default: 5609a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5610a36c61f9SKrishna Gudipati } 5611a36c61f9SKrishna Gudipati } 5612a36c61f9SKrishna Gudipati 56135fbe25c7SJing Huang /* 5614a36c61f9SKrishna Gudipati * Error State. 5615a36c61f9SKrishna Gudipati * This state will be set when the Vport Creation fails due 5616a36c61f9SKrishna Gudipati * to errors like Dup WWN. In this state only operation allowed 5617a36c61f9SKrishna Gudipati * is a Vport Delete. 5618a36c61f9SKrishna Gudipati */ 5619a36c61f9SKrishna Gudipati static void 5620a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5621a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5622a36c61f9SKrishna Gudipati { 5623a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5624a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5625a36c61f9SKrishna Gudipati 5626a36c61f9SKrishna Gudipati switch (event) { 5627a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5628a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5629a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5630a36c61f9SKrishna Gudipati break; 5631a36c61f9SKrishna Gudipati 5632a36c61f9SKrishna Gudipati default: 5633a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5634a36c61f9SKrishna Gudipati } 5635a36c61f9SKrishna Gudipati } 5636a36c61f9SKrishna Gudipati 56375fbe25c7SJing Huang /* 5638a36c61f9SKrishna Gudipati * Lport cleanup is in progress since vport is being deleted. Fabric is 5639a36c61f9SKrishna Gudipati * offline, so no LOGO is needed to complete vport deletion. 5640a36c61f9SKrishna Gudipati */ 5641a36c61f9SKrishna Gudipati static void 5642a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5643a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5644a36c61f9SKrishna Gudipati { 5645a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5646a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5647a36c61f9SKrishna Gudipati 5648a36c61f9SKrishna Gudipati switch (event) { 5649a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 5650a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5651a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 5652a36c61f9SKrishna Gudipati break; 5653a36c61f9SKrishna Gudipati 5654dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 5655dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5656dd5aaf45SKrishna Gudipati break; 5657dd5aaf45SKrishna Gudipati 5658a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5659a36c61f9SKrishna Gudipati break; 5660a36c61f9SKrishna Gudipati 5661a36c61f9SKrishna Gudipati default: 5662a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5663a36c61f9SKrishna Gudipati } 5664a36c61f9SKrishna Gudipati } 5665a36c61f9SKrishna Gudipati 56665fbe25c7SJing Huang /* 5667dd5aaf45SKrishna Gudipati * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup 5668dd5aaf45SKrishna Gudipati * is done. 5669dd5aaf45SKrishna Gudipati */ 5670dd5aaf45SKrishna Gudipati static void 5671dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 5672dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 5673dd5aaf45SKrishna Gudipati { 5674dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5675dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5676dd5aaf45SKrishna Gudipati 5677dd5aaf45SKrishna Gudipati switch (event) { 5678dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5679dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5680dd5aaf45SKrishna Gudipati /* 5681dd5aaf45SKrishna Gudipati * !!! fall through !!! 5682dd5aaf45SKrishna Gudipati */ 5683dd5aaf45SKrishna Gudipati 5684dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5685dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5686dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5687dd5aaf45SKrishna Gudipati break; 5688dd5aaf45SKrishna Gudipati 5689dd5aaf45SKrishna Gudipati default: 5690dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5691dd5aaf45SKrishna Gudipati } 5692dd5aaf45SKrishna Gudipati } 5693dd5aaf45SKrishna Gudipati 5694dd5aaf45SKrishna Gudipati /* 5695a36c61f9SKrishna Gudipati * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup 5696a36c61f9SKrishna Gudipati * is done. 5697a36c61f9SKrishna Gudipati */ 5698a36c61f9SKrishna Gudipati static void 5699a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5700a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5701a36c61f9SKrishna Gudipati { 5702a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5703a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5704a36c61f9SKrishna Gudipati 5705a36c61f9SKrishna Gudipati switch (event) { 5706a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5707f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5708a36c61f9SKrishna Gudipati /* 5709a36c61f9SKrishna Gudipati * !!! fall through !!! 5710a36c61f9SKrishna Gudipati */ 5711a36c61f9SKrishna Gudipati 5712a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5713a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5714a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5715a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 5716a36c61f9SKrishna Gudipati break; 5717a36c61f9SKrishna Gudipati 5718a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5719a36c61f9SKrishna Gudipati break; 5720a36c61f9SKrishna Gudipati 5721a36c61f9SKrishna Gudipati default: 5722a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5723a36c61f9SKrishna Gudipati } 5724a36c61f9SKrishna Gudipati } 5725a36c61f9SKrishna Gudipati 5726a36c61f9SKrishna Gudipati 5727a36c61f9SKrishna Gudipati 57285fbe25c7SJing Huang /* 5729a36c61f9SKrishna Gudipati * fcs_vport_private FCS virtual port private functions 5730a36c61f9SKrishna Gudipati */ 57315fbe25c7SJing Huang /* 57327826f304SKrishna Gudipati * Send AEN notification 57337826f304SKrishna Gudipati */ 57347826f304SKrishna Gudipati static void 57357826f304SKrishna Gudipati bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port, 57367826f304SKrishna Gudipati enum bfa_lport_aen_event event) 57377826f304SKrishna Gudipati { 57387826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 57397826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 57407826f304SKrishna Gudipati 57417826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 57427826f304SKrishna Gudipati if (!aen_entry) 57437826f304SKrishna Gudipati return; 57447826f304SKrishna Gudipati 57457826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 57467826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 57477826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 57487826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 57497826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 57507826f304SKrishna Gudipati 57517826f304SKrishna Gudipati /* Send the AEN notification */ 57527826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 57537826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 57547826f304SKrishna Gudipati } 57557826f304SKrishna Gudipati 57567826f304SKrishna Gudipati /* 5757a36c61f9SKrishna Gudipati * This routine will be called to send a FDISC command. 5758a36c61f9SKrishna Gudipati */ 5759a36c61f9SKrishna Gudipati static void 5760a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) 5761a36c61f9SKrishna Gudipati { 5762a36c61f9SKrishna Gudipati bfa_lps_fdisc(vport->lps, vport, 5763a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(__vport_bfa(vport)), 5764a36c61f9SKrishna Gudipati __vport_pwwn(vport), __vport_nwwn(vport)); 5765a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_sent++; 5766a36c61f9SKrishna Gudipati } 5767a36c61f9SKrishna Gudipati 5768a36c61f9SKrishna Gudipati static void 5769a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) 5770a36c61f9SKrishna Gudipati { 5771f7f73812SMaggie Zhang u8 lsrjt_rsn = vport->lps->lsrjt_rsn; 5772f7f73812SMaggie Zhang u8 lsrjt_expl = vport->lps->lsrjt_expl; 5773a36c61f9SKrishna Gudipati 5774a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_rsn); 5775a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_expl); 5776a36c61f9SKrishna Gudipati 5777a36c61f9SKrishna Gudipati /* For certain reason codes, we don't want to retry. */ 5778f7f73812SMaggie Zhang switch (vport->lps->lsrjt_expl) { 5779a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */ 5780a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ 5781a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5782a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 57837826f304SKrishna Gudipati else { 57847826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 57857826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_DUP_WWN); 5786a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); 57877826f304SKrishna Gudipati } 5788a36c61f9SKrishna Gudipati break; 5789a36c61f9SKrishna Gudipati 5790a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INSUFF_RES: 5791a36c61f9SKrishna Gudipati /* 5792a36c61f9SKrishna Gudipati * This means max logins per port/switch setting on the 5793a36c61f9SKrishna Gudipati * switch was exceeded. 5794a36c61f9SKrishna Gudipati */ 5795a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5796a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 57977826f304SKrishna Gudipati else { 57987826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 57997826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_FABRIC_MAX); 5800a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 58017826f304SKrishna Gudipati } 5802a36c61f9SKrishna Gudipati break; 5803a36c61f9SKrishna Gudipati 5804a36c61f9SKrishna Gudipati default: 58057826f304SKrishna Gudipati if (vport->fdisc_retries == 0) 58067826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 58077826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_UNKNOWN); 5808a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5809a36c61f9SKrishna Gudipati } 5810a36c61f9SKrishna Gudipati } 5811a36c61f9SKrishna Gudipati 58125fbe25c7SJing Huang /* 5813a36c61f9SKrishna Gudipati * Called to send a logout to the fabric. Used when a V-Port is 5814a36c61f9SKrishna Gudipati * deleted/stopped. 5815a36c61f9SKrishna Gudipati */ 5816a36c61f9SKrishna Gudipati static void 5817a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport) 5818a36c61f9SKrishna Gudipati { 5819a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5820a36c61f9SKrishna Gudipati 5821a36c61f9SKrishna Gudipati vport->vport_stats.logo_sent++; 5822a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(vport->lps); 5823a36c61f9SKrishna Gudipati } 5824a36c61f9SKrishna Gudipati 5825a36c61f9SKrishna Gudipati 58265fbe25c7SJing Huang /* 5827a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 5828a36c61f9SKrishna Gudipati * 5829a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 5830a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 5831a36c61f9SKrishna Gudipati * 5832a36c61f9SKrishna Gudipati * return 5833a36c61f9SKrishna Gudipati * void 5834a36c61f9SKrishna Gudipati * 5835a36c61f9SKrishna Gudipati * Special Considerations: 5836a36c61f9SKrishna Gudipati * 5837a36c61f9SKrishna Gudipati * note 5838a36c61f9SKrishna Gudipati */ 5839a36c61f9SKrishna Gudipati static void 5840a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg) 5841a36c61f9SKrishna Gudipati { 5842a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg; 5843a36c61f9SKrishna Gudipati 5844a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_timeouts++; 5845a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT); 5846a36c61f9SKrishna Gudipati } 5847a36c61f9SKrishna Gudipati 5848a36c61f9SKrishna Gudipati static void 5849a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) 5850a36c61f9SKrishna Gudipati { 5851a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv = 5852a36c61f9SKrishna Gudipati (struct bfad_vport_s *)vport->vport_drv; 5853a36c61f9SKrishna Gudipati 5854a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); 5855a36c61f9SKrishna Gudipati bfa_lps_delete(vport->lps); 585617c201b3SKrishna Gudipati 585717c201b3SKrishna Gudipati if (vport_drv->comp_del) { 585817c201b3SKrishna Gudipati complete(vport_drv->comp_del); 585917c201b3SKrishna Gudipati return; 5860a36c61f9SKrishna Gudipati } 5861a36c61f9SKrishna Gudipati 586217c201b3SKrishna Gudipati /* 586317c201b3SKrishna Gudipati * We queue the vport delete work to the IM work_q from here. 586417c201b3SKrishna Gudipati * The memory for the bfad_vport_s is freed from the FC function 586517c201b3SKrishna Gudipati * template vport_delete entry point. 586617c201b3SKrishna Gudipati */ 5867529f9a76SKrishna Gudipati bfad_im_port_delete(vport_drv->drv_port.bfad, &vport_drv->drv_port); 586817c201b3SKrishna Gudipati } 5869a36c61f9SKrishna Gudipati 58705fbe25c7SJing Huang /* 5871a36c61f9SKrishna Gudipati * fcs_vport_public FCS virtual port public interfaces 5872a36c61f9SKrishna Gudipati */ 5873a36c61f9SKrishna Gudipati 58745fbe25c7SJing Huang /* 5875a36c61f9SKrishna Gudipati * Online notification from fabric SM. 5876a36c61f9SKrishna Gudipati */ 5877a36c61f9SKrishna Gudipati void 5878a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) 5879a36c61f9SKrishna Gudipati { 5880a36c61f9SKrishna Gudipati vport->vport_stats.fab_online++; 5881d7be54ccSKrishna Gudipati if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) 5882a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 5883d7be54ccSKrishna Gudipati else 5884d7be54ccSKrishna Gudipati vport->vport_stats.fab_no_npiv++; 5885a36c61f9SKrishna Gudipati } 5886a36c61f9SKrishna Gudipati 58875fbe25c7SJing Huang /* 5888a36c61f9SKrishna Gudipati * Offline notification from fabric SM. 5889a36c61f9SKrishna Gudipati */ 5890a36c61f9SKrishna Gudipati void 5891a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport) 5892a36c61f9SKrishna Gudipati { 5893a36c61f9SKrishna Gudipati vport->vport_stats.fab_offline++; 5894a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 5895a36c61f9SKrishna Gudipati } 5896a36c61f9SKrishna Gudipati 58975fbe25c7SJing Huang /* 5898a36c61f9SKrishna Gudipati * Cleanup notification from fabric SM on link timer expiry. 5899a36c61f9SKrishna Gudipati */ 5900a36c61f9SKrishna Gudipati void 5901a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) 5902a36c61f9SKrishna Gudipati { 5903a36c61f9SKrishna Gudipati vport->vport_stats.fab_cleanup++; 5904a36c61f9SKrishna Gudipati } 5905881c1b3cSKrishna Gudipati 5906881c1b3cSKrishna Gudipati /* 5907881c1b3cSKrishna Gudipati * Stop notification from fabric SM. To be invoked from within FCS. 5908881c1b3cSKrishna Gudipati */ 5909881c1b3cSKrishna Gudipati void 5910881c1b3cSKrishna Gudipati bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport) 5911881c1b3cSKrishna Gudipati { 5912881c1b3cSKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 5913881c1b3cSKrishna Gudipati } 5914881c1b3cSKrishna Gudipati 59155fbe25c7SJing Huang /* 5916a36c61f9SKrishna Gudipati * delete notification from fabric SM. To be invoked from within FCS. 5917a36c61f9SKrishna Gudipati */ 5918a36c61f9SKrishna Gudipati void 5919a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) 5920a36c61f9SKrishna Gudipati { 5921a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 5922a36c61f9SKrishna Gudipati } 5923a36c61f9SKrishna Gudipati 59245fbe25c7SJing Huang /* 5925dd5aaf45SKrishna Gudipati * Stop completion callback from associated lport 5926dd5aaf45SKrishna Gudipati */ 5927dd5aaf45SKrishna Gudipati void 5928dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport) 5929dd5aaf45SKrishna Gudipati { 5930dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP); 5931dd5aaf45SKrishna Gudipati } 5932dd5aaf45SKrishna Gudipati 5933dd5aaf45SKrishna Gudipati /* 5934a36c61f9SKrishna Gudipati * Delete completion callback from associated lport 5935a36c61f9SKrishna Gudipati */ 5936a36c61f9SKrishna Gudipati void 5937a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) 5938a36c61f9SKrishna Gudipati { 5939a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); 5940a36c61f9SKrishna Gudipati } 5941a36c61f9SKrishna Gudipati 5942a36c61f9SKrishna Gudipati 5943a36c61f9SKrishna Gudipati 59445fbe25c7SJing Huang /* 5945a36c61f9SKrishna Gudipati * fcs_vport_api Virtual port API 5946a36c61f9SKrishna Gudipati */ 5947a36c61f9SKrishna Gudipati 59485fbe25c7SJing Huang /* 5949a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS vport object. This 5950a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 5951a36c61f9SKrishna Gudipati * done in vport_start() call) 5952a36c61f9SKrishna Gudipati * 5953a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 5954a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 5955a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 5956a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 5957a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 5958a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 5959a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 5960a36c61f9SKrishna Gudipati * structure 5961a36c61f9SKrishna Gudipati * 5962a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 5963a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 5964a36c61f9SKrishna Gudipati */ 5965a36c61f9SKrishna Gudipati bfa_status_t 5966a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 5967a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 5968a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 5969a36c61f9SKrishna Gudipati { 5970a36c61f9SKrishna Gudipati if (vport_cfg->pwwn == 0) 5971a36c61f9SKrishna Gudipati return BFA_STATUS_INVALID_WWN; 5972a36c61f9SKrishna Gudipati 5973a36c61f9SKrishna Gudipati if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn) 5974a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_WWN_BP; 5975a36c61f9SKrishna Gudipati 5976a36c61f9SKrishna Gudipati if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL) 5977a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_EXISTS; 5978a36c61f9SKrishna Gudipati 5979f7f73812SMaggie Zhang if (fcs->fabric.num_vports == 5980a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(fcs->bfa)) 5981a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 5982a36c61f9SKrishna Gudipati 5983a36c61f9SKrishna Gudipati vport->lps = bfa_lps_alloc(fcs->bfa); 5984a36c61f9SKrishna Gudipati if (!vport->lps) 5985a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 5986a36c61f9SKrishna Gudipati 5987a36c61f9SKrishna Gudipati vport->vport_drv = vport_drv; 5988a36c61f9SKrishna Gudipati vport_cfg->preboot_vp = BFA_FALSE; 5989a36c61f9SKrishna Gudipati 5990a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5991a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); 5992a36c61f9SKrishna Gudipati bfa_fcs_lport_init(&vport->lport, vport_cfg); 5993a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); 5994a36c61f9SKrishna Gudipati 5995a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5996a36c61f9SKrishna Gudipati } 5997a36c61f9SKrishna Gudipati 59985fbe25c7SJing Huang /* 5999a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS PBC vport object. This 6000a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 6001a36c61f9SKrishna Gudipati * done in vport_start() call) 6002a36c61f9SKrishna Gudipati * 6003a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 6004a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 6005a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 6006a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 6007a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 6008a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 6009a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 6010a36c61f9SKrishna Gudipati * structure 6011a36c61f9SKrishna Gudipati * 6012a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 6013a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 6014a36c61f9SKrishna Gudipati */ 6015a36c61f9SKrishna Gudipati bfa_status_t 6016a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 6017a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 6018a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 6019a36c61f9SKrishna Gudipati { 6020a36c61f9SKrishna Gudipati bfa_status_t rc; 6021a36c61f9SKrishna Gudipati 6022a36c61f9SKrishna Gudipati rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv); 6023a36c61f9SKrishna Gudipati vport->lport.port_cfg.preboot_vp = BFA_TRUE; 6024a36c61f9SKrishna Gudipati 6025a36c61f9SKrishna Gudipati return rc; 6026a36c61f9SKrishna Gudipati } 6027a36c61f9SKrishna Gudipati 60285fbe25c7SJing Huang /* 6029a36c61f9SKrishna Gudipati * Use this function to findout if this is a pbc vport or not. 6030a36c61f9SKrishna Gudipati * 6031a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 6032a36c61f9SKrishna Gudipati * 6033a36c61f9SKrishna Gudipati * @returns None 6034a36c61f9SKrishna Gudipati */ 6035a36c61f9SKrishna Gudipati bfa_boolean_t 6036a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport) 6037a36c61f9SKrishna Gudipati { 6038a36c61f9SKrishna Gudipati 6039a36c61f9SKrishna Gudipati if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE)) 6040a36c61f9SKrishna Gudipati return BFA_TRUE; 6041a36c61f9SKrishna Gudipati else 6042a36c61f9SKrishna Gudipati return BFA_FALSE; 6043a36c61f9SKrishna Gudipati 6044a36c61f9SKrishna Gudipati } 6045a36c61f9SKrishna Gudipati 60465fbe25c7SJing Huang /* 6047a36c61f9SKrishna Gudipati * Use this function initialize the vport. 6048a36c61f9SKrishna Gudipati * 6049a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 6050a36c61f9SKrishna Gudipati * 6051a36c61f9SKrishna Gudipati * @returns None 6052a36c61f9SKrishna Gudipati */ 6053a36c61f9SKrishna Gudipati bfa_status_t 6054a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport) 6055a36c61f9SKrishna Gudipati { 6056a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START); 6057a36c61f9SKrishna Gudipati 6058a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6059a36c61f9SKrishna Gudipati } 6060a36c61f9SKrishna Gudipati 60615fbe25c7SJing Huang /* 6062a36c61f9SKrishna Gudipati * Use this function quiese the vport object. This function will return 6063a36c61f9SKrishna Gudipati * immediately, when the vport is actually stopped, the 6064a36c61f9SKrishna Gudipati * bfa_drv_vport_stop_cb() will be called. 6065a36c61f9SKrishna Gudipati * 6066a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6067a36c61f9SKrishna Gudipati * 6068a36c61f9SKrishna Gudipati * return None 6069a36c61f9SKrishna Gudipati */ 6070a36c61f9SKrishna Gudipati bfa_status_t 6071a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) 6072a36c61f9SKrishna Gudipati { 6073a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 6074a36c61f9SKrishna Gudipati 6075a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6076a36c61f9SKrishna Gudipati } 6077a36c61f9SKrishna Gudipati 60785fbe25c7SJing Huang /* 6079a36c61f9SKrishna Gudipati * Use this function to delete a vport object. Fabric object should 6080a36c61f9SKrishna Gudipati * be stopped before this function call. 6081a36c61f9SKrishna Gudipati * 6082a36c61f9SKrishna Gudipati * !!!!!!! Donot invoke this from within FCS !!!!!!! 6083a36c61f9SKrishna Gudipati * 6084a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6085a36c61f9SKrishna Gudipati * 6086a36c61f9SKrishna Gudipati * return None 6087a36c61f9SKrishna Gudipati */ 6088a36c61f9SKrishna Gudipati bfa_status_t 6089a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) 6090a36c61f9SKrishna Gudipati { 6091a36c61f9SKrishna Gudipati 6092a36c61f9SKrishna Gudipati if (vport->lport.port_cfg.preboot_vp) 6093a36c61f9SKrishna Gudipati return BFA_STATUS_PBC; 6094a36c61f9SKrishna Gudipati 6095a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 6096a36c61f9SKrishna Gudipati 6097a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6098a36c61f9SKrishna Gudipati } 6099a36c61f9SKrishna Gudipati 61005fbe25c7SJing Huang /* 6101a36c61f9SKrishna Gudipati * Use this function to get vport's current status info. 6102a36c61f9SKrishna Gudipati * 6103a36c61f9SKrishna Gudipati * param[in] vport pointer to bfa_fcs_vport_t. 6104a36c61f9SKrishna Gudipati * param[out] attr pointer to return vport attributes 6105a36c61f9SKrishna Gudipati * 6106a36c61f9SKrishna Gudipati * return None 6107a36c61f9SKrishna Gudipati */ 6108a36c61f9SKrishna Gudipati void 6109a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, 6110a36c61f9SKrishna Gudipati struct bfa_vport_attr_s *attr) 6111a36c61f9SKrishna Gudipati { 6112a36c61f9SKrishna Gudipati if (vport == NULL || attr == NULL) 6113a36c61f9SKrishna Gudipati return; 6114a36c61f9SKrishna Gudipati 61156a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_vport_attr_s)); 6116a36c61f9SKrishna Gudipati 6117a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr); 6118a36c61f9SKrishna Gudipati attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm); 6119a36c61f9SKrishna Gudipati } 6120a36c61f9SKrishna Gudipati 6121a36c61f9SKrishna Gudipati 61225fbe25c7SJing Huang /* 6123a36c61f9SKrishna Gudipati * Lookup a virtual port. Excludes base port from lookup. 6124a36c61f9SKrishna Gudipati */ 6125a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s * 6126a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn) 6127a36c61f9SKrishna Gudipati { 6128a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 6129a36c61f9SKrishna Gudipati struct bfa_fcs_fabric_s *fabric; 6130a36c61f9SKrishna Gudipati 6131a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 6132a36c61f9SKrishna Gudipati bfa_trc(fcs, vpwwn); 6133a36c61f9SKrishna Gudipati 6134a36c61f9SKrishna Gudipati fabric = bfa_fcs_vf_lookup(fcs, vf_id); 6135a36c61f9SKrishna Gudipati if (!fabric) { 6136a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 6137a36c61f9SKrishna Gudipati return NULL; 6138a36c61f9SKrishna Gudipati } 6139a36c61f9SKrishna Gudipati 6140a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn); 6141a36c61f9SKrishna Gudipati return vport; 6142a36c61f9SKrishna Gudipati } 6143a36c61f9SKrishna Gudipati 61445fbe25c7SJing Huang /* 6145a36c61f9SKrishna Gudipati * FDISC Response 6146a36c61f9SKrishna Gudipati */ 6147a36c61f9SKrishna Gudipati void 6148a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) 6149a36c61f9SKrishna Gudipati { 6150a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6151a36c61f9SKrishna Gudipati 6152a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6153a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), status); 6154a36c61f9SKrishna Gudipati 6155a36c61f9SKrishna Gudipati switch (status) { 6156a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 6157a36c61f9SKrishna Gudipati /* 6158b595076aSUwe Kleine-König * Initialize the V-Port fields 6159a36c61f9SKrishna Gudipati */ 6160f7f73812SMaggie Zhang __vport_fcid(vport) = vport->lps->lp_pid; 6161a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_accepts++; 6162a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6163a36c61f9SKrishna Gudipati break; 6164a36c61f9SKrishna Gudipati 6165a36c61f9SKrishna Gudipati case BFA_STATUS_INVALID_MAC: 6166a36c61f9SKrishna Gudipati /* Only for CNA */ 6167a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6168a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6169a36c61f9SKrishna Gudipati 6170a36c61f9SKrishna Gudipati break; 6171a36c61f9SKrishna Gudipati 6172a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 6173f7f73812SMaggie Zhang switch (vport->lps->ext_status) { 6174a36c61f9SKrishna Gudipati case BFA_EPROTO_BAD_ACCEPT: 6175a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6176a36c61f9SKrishna Gudipati break; 6177a36c61f9SKrishna Gudipati 6178a36c61f9SKrishna Gudipati case BFA_EPROTO_UNKNOWN_RSP: 6179a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_unknown_rsp++; 6180a36c61f9SKrishna Gudipati break; 6181a36c61f9SKrishna Gudipati 6182a36c61f9SKrishna Gudipati default: 6183a36c61f9SKrishna Gudipati break; 6184a36c61f9SKrishna Gudipati } 6185a36c61f9SKrishna Gudipati 6186a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6187a36c61f9SKrishna Gudipati break; 6188a36c61f9SKrishna Gudipati 6189a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 6190a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rejects++; 6191a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(vport); 6192a36c61f9SKrishna Gudipati break; 6193a36c61f9SKrishna Gudipati 6194a36c61f9SKrishna Gudipati default: 6195a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rsp_err++; 6196a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6197a36c61f9SKrishna Gudipati } 6198a36c61f9SKrishna Gudipati } 6199a36c61f9SKrishna Gudipati 62005fbe25c7SJing Huang /* 6201a36c61f9SKrishna Gudipati * LOGO response 6202a36c61f9SKrishna Gudipati */ 6203a36c61f9SKrishna Gudipati void 6204a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) 6205a36c61f9SKrishna Gudipati { 6206a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6207a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6208a36c61f9SKrishna Gudipati } 6209a36c61f9SKrishna Gudipati 62105fbe25c7SJing Huang /* 6211a36c61f9SKrishna Gudipati * Received clear virtual link 6212a36c61f9SKrishna Gudipati */ 6213a36c61f9SKrishna Gudipati void 6214a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg) 6215a36c61f9SKrishna Gudipati { 6216a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6217a36c61f9SKrishna Gudipati 6218a36c61f9SKrishna Gudipati /* Send an Offline followed by an ONLINE */ 6219a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 6220a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 6221a36c61f9SKrishna Gudipati } 6222