152fa7bf9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 27725ccfdSJing Huang /* 3889d0d42SAnil Gurumurthy * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. 4889d0d42SAnil Gurumurthy * Copyright (c) 2014- QLogic Corporation. 57725ccfdSJing Huang * All rights reserved 6889d0d42SAnil Gurumurthy * www.qlogic.com 77725ccfdSJing Huang * 831e1d569SAnil Gurumurthy * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. 97725ccfdSJing Huang */ 107725ccfdSJing Huang 11f16a1750SMaggie Zhang #include "bfad_drv.h" 127826f304SKrishna Gudipati #include "bfad_im.h" 13a36c61f9SKrishna Gudipati #include "bfa_fcs.h" 14a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h" 15a36c61f9SKrishna Gudipati #include "bfa_fc.h" 167725ccfdSJing Huang 177725ccfdSJing Huang BFA_TRC_FILE(FCS, PORT); 187725ccfdSJing Huang 19bc0e2c2aSKrishna Gudipati /* 20bc0e2c2aSKrishna Gudipati * ALPA to LIXA bitmap mapping 21bc0e2c2aSKrishna Gudipati * 22bc0e2c2aSKrishna Gudipati * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31 23bc0e2c2aSKrishna Gudipati * is for L_bit (login required) and is filled as ALPA 0x00 here. 24bc0e2c2aSKrishna Gudipati */ 25bc0e2c2aSKrishna Gudipati static const u8 loop_alpa_map[] = { 26bc0e2c2aSKrishna Gudipati 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */ 27bc0e2c2aSKrishna Gudipati 0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */ 28bc0e2c2aSKrishna Gudipati 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */ 29bc0e2c2aSKrishna Gudipati 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */ 30bc0e2c2aSKrishna Gudipati 31bc0e2c2aSKrishna Gudipati 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */ 32bc0e2c2aSKrishna Gudipati 0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */ 33bc0e2c2aSKrishna Gudipati 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */ 34bc0e2c2aSKrishna Gudipati 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */ 35bc0e2c2aSKrishna Gudipati 36bc0e2c2aSKrishna Gudipati 0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */ 37bc0e2c2aSKrishna Gudipati 0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */ 38bc0e2c2aSKrishna Gudipati 0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */ 39bc0e2c2aSKrishna Gudipati 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */ 40bc0e2c2aSKrishna Gudipati 41bc0e2c2aSKrishna Gudipati 0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */ 42bc0e2c2aSKrishna Gudipati 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */ 43bc0e2c2aSKrishna Gudipati 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */ 44bc0e2c2aSKrishna Gudipati 0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */ 45bc0e2c2aSKrishna Gudipati }; 46bc0e2c2aSKrishna Gudipati 47a36c61f9SKrishna Gudipati static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, 487725ccfdSJing Huang struct fchs_s *rx_fchs, u8 reason_code, 497725ccfdSJing Huang u8 reason_code_expl); 50a36c61f9SKrishna Gudipati static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 51a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi); 52a36c61f9SKrishna Gudipati static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port); 53a36c61f9SKrishna Gudipati static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port); 54a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port); 55a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port); 56a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port); 57a36c61f9SKrishna Gudipati static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port); 58a36c61f9SKrishna Gudipati static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, 597725ccfdSJing Huang struct fchs_s *rx_fchs, 607725ccfdSJing Huang struct fc_echo_s *echo, u16 len); 61a36c61f9SKrishna Gudipati static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, 627725ccfdSJing Huang struct fchs_s *rx_fchs, 637725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 len); 64a36c61f9SKrishna Gudipati static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 657725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data); 667725ccfdSJing Huang 67a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port); 68a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port); 69a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port); 70a36c61f9SKrishna Gudipati 71a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port); 72a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); 73a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); 74a36c61f9SKrishna Gudipati 75bc0e2c2aSKrishna Gudipati static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port); 76bc0e2c2aSKrishna Gudipati static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port); 77bc0e2c2aSKrishna Gudipati static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port); 78bc0e2c2aSKrishna Gudipati 797725ccfdSJing Huang static struct { 80a36c61f9SKrishna Gudipati void (*init) (struct bfa_fcs_lport_s *port); 81a36c61f9SKrishna Gudipati void (*online) (struct bfa_fcs_lport_s *port); 82a36c61f9SKrishna Gudipati void (*offline) (struct bfa_fcs_lport_s *port); 837725ccfdSJing Huang } __port_action[] = { 84b34b10a7SKees Cook [BFA_FCS_FABRIC_UNKNOWN] = { 85b34b10a7SKees Cook .init = bfa_fcs_lport_unknown_init, 86b34b10a7SKees Cook .online = bfa_fcs_lport_unknown_online, 87b34b10a7SKees Cook .offline = bfa_fcs_lport_unknown_offline 88b34b10a7SKees Cook }, 89b34b10a7SKees Cook [BFA_FCS_FABRIC_SWITCHED] = { 90b34b10a7SKees Cook .init = bfa_fcs_lport_fab_init, 91b34b10a7SKees Cook .online = bfa_fcs_lport_fab_online, 92b34b10a7SKees Cook .offline = bfa_fcs_lport_fab_offline 93b34b10a7SKees Cook }, 94b34b10a7SKees Cook [BFA_FCS_FABRIC_N2N] = { 95b34b10a7SKees Cook .init = bfa_fcs_lport_n2n_init, 96b34b10a7SKees Cook .online = bfa_fcs_lport_n2n_online, 97b34b10a7SKees Cook .offline = bfa_fcs_lport_n2n_offline 98b34b10a7SKees Cook }, 99b34b10a7SKees Cook [BFA_FCS_FABRIC_LOOP] = { 100b34b10a7SKees Cook .init = bfa_fcs_lport_loop_init, 101b34b10a7SKees Cook .online = bfa_fcs_lport_loop_online, 102b34b10a7SKees Cook .offline = bfa_fcs_lport_loop_offline 103b34b10a7SKees Cook }, 104a36c61f9SKrishna Gudipati }; 1057725ccfdSJing Huang 1065fbe25c7SJing Huang /* 1077725ccfdSJing Huang * fcs_port_sm FCS logical port state machine 1087725ccfdSJing Huang */ 1097725ccfdSJing Huang 110a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event { 1117725ccfdSJing Huang BFA_FCS_PORT_SM_CREATE = 1, 1127725ccfdSJing Huang BFA_FCS_PORT_SM_ONLINE = 2, 1137725ccfdSJing Huang BFA_FCS_PORT_SM_OFFLINE = 3, 1147725ccfdSJing Huang BFA_FCS_PORT_SM_DELETE = 4, 1157725ccfdSJing Huang BFA_FCS_PORT_SM_DELRPORT = 5, 116dd5aaf45SKrishna Gudipati BFA_FCS_PORT_SM_STOP = 6, 1177725ccfdSJing Huang }; 1187725ccfdSJing Huang 119a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, 120a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 121a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 122a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 123a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port, 124a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 125a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port, 126a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 127a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, 128a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 129dd5aaf45SKrishna Gudipati static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 130dd5aaf45SKrishna Gudipati enum bfa_fcs_lport_event event); 1317725ccfdSJing Huang 1327725ccfdSJing Huang static void 133a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_uninit( 134a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 135a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1367725ccfdSJing Huang { 1377725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1387725ccfdSJing Huang bfa_trc(port->fcs, event); 1397725ccfdSJing Huang 1407725ccfdSJing Huang switch (event) { 1417725ccfdSJing Huang case BFA_FCS_PORT_SM_CREATE: 142a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 1437725ccfdSJing Huang break; 1447725ccfdSJing Huang 1457725ccfdSJing Huang default: 146e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1477725ccfdSJing Huang } 1487725ccfdSJing Huang } 1497725ccfdSJing Huang 1507725ccfdSJing Huang static void 151a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 152a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 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_ONLINE: 159a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 160a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 1617725ccfdSJing Huang break; 1627725ccfdSJing Huang 1637725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 164a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 165a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 1667725ccfdSJing Huang break; 1677725ccfdSJing Huang 168dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 169dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 170dd5aaf45SKrishna Gudipati if (port->vport) 171dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 172881c1b3cSKrishna Gudipati else 173881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 174dd5aaf45SKrishna Gudipati break; 175dd5aaf45SKrishna Gudipati 1763e98cc01SJing Huang case BFA_FCS_PORT_SM_OFFLINE: 1773e98cc01SJing Huang break; 1783e98cc01SJing Huang 1797725ccfdSJing Huang default: 180e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1817725ccfdSJing Huang } 1827725ccfdSJing Huang } 1837725ccfdSJing Huang 1847725ccfdSJing Huang static void 185a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online( 186a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 187a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1887725ccfdSJing Huang { 1897725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 1907725ccfdSJing Huang struct list_head *qe, *qen; 1917725ccfdSJing Huang 1927725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1937725ccfdSJing Huang bfa_trc(port->fcs, event); 1947725ccfdSJing Huang 1957725ccfdSJing Huang switch (event) { 1967725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 197a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_offline); 198a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(port); 1997725ccfdSJing Huang break; 2007725ccfdSJing Huang 201dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 202dd5aaf45SKrishna Gudipati __port_action[port->fabric->fab_type].offline(port); 203dd5aaf45SKrishna Gudipati 204dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 205dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 206dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 207dd5aaf45SKrishna Gudipati if (port->vport) 208dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 209881c1b3cSKrishna Gudipati else 210881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 211dd5aaf45SKrishna Gudipati } else { 212dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 213dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 214dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 215dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 216dd5aaf45SKrishna Gudipati } 217dd5aaf45SKrishna Gudipati } 218dd5aaf45SKrishna Gudipati break; 219dd5aaf45SKrishna Gudipati 2207725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 2217725ccfdSJing Huang 2227725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 2237725ccfdSJing Huang 2247725ccfdSJing Huang if (port->num_rports == 0) { 225a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 226a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2277725ccfdSJing Huang } else { 228a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 2297725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 2307725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 231f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 2327725ccfdSJing Huang } 2337725ccfdSJing Huang } 2347725ccfdSJing Huang break; 2357725ccfdSJing Huang 2367725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2377725ccfdSJing Huang break; 2387725ccfdSJing Huang 2397725ccfdSJing Huang default: 240e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2417725ccfdSJing Huang } 2427725ccfdSJing Huang } 2437725ccfdSJing Huang 2447725ccfdSJing Huang static void 245a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline( 246a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 247a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 2487725ccfdSJing Huang { 2497725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 2507725ccfdSJing Huang struct list_head *qe, *qen; 2517725ccfdSJing Huang 2527725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 2537725ccfdSJing Huang bfa_trc(port->fcs, event); 2547725ccfdSJing Huang 2557725ccfdSJing Huang switch (event) { 2567725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 257a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 258a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 2597725ccfdSJing Huang break; 2607725ccfdSJing Huang 261dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 262dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 263dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 264dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 265dd5aaf45SKrishna Gudipati if (port->vport) 266dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 267881c1b3cSKrishna Gudipati else 268881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 269dd5aaf45SKrishna Gudipati } else { 270dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 271dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 272dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 273dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 274dd5aaf45SKrishna Gudipati } 275dd5aaf45SKrishna Gudipati } 276dd5aaf45SKrishna Gudipati break; 277dd5aaf45SKrishna Gudipati 2787725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 2797725ccfdSJing Huang if (port->num_rports == 0) { 280a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 281a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2827725ccfdSJing Huang } else { 283a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 2847725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 2857725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 286f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 2877725ccfdSJing Huang } 2887725ccfdSJing Huang } 2897725ccfdSJing Huang break; 2907725ccfdSJing Huang 2917725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2927725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 2937725ccfdSJing Huang break; 2947725ccfdSJing Huang 2957725ccfdSJing Huang default: 296e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2977725ccfdSJing Huang } 2987725ccfdSJing Huang } 2997725ccfdSJing Huang 3007725ccfdSJing Huang static void 301dd5aaf45SKrishna Gudipati bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 302dd5aaf45SKrishna Gudipati enum bfa_fcs_lport_event event) 303dd5aaf45SKrishna Gudipati { 304dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 305dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, event); 306dd5aaf45SKrishna Gudipati 307dd5aaf45SKrishna Gudipati switch (event) { 308dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_DELRPORT: 309dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 310dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 311dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 312dd5aaf45SKrishna Gudipati if (port->vport) 313dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 314881c1b3cSKrishna Gudipati else 315881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 316dd5aaf45SKrishna Gudipati } 317dd5aaf45SKrishna Gudipati break; 318dd5aaf45SKrishna Gudipati 319dd5aaf45SKrishna Gudipati default: 320dd5aaf45SKrishna Gudipati bfa_sm_fault(port->fcs, event); 321dd5aaf45SKrishna Gudipati } 322dd5aaf45SKrishna Gudipati } 323dd5aaf45SKrishna Gudipati 324dd5aaf45SKrishna Gudipati static void 325a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting( 326a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 327a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 3287725ccfdSJing Huang { 3297725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 3307725ccfdSJing Huang bfa_trc(port->fcs, event); 3317725ccfdSJing Huang 3327725ccfdSJing Huang switch (event) { 3337725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 3347725ccfdSJing Huang if (port->num_rports == 0) { 335a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 336a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 3377725ccfdSJing Huang } 3387725ccfdSJing Huang break; 3397725ccfdSJing Huang 3407725ccfdSJing Huang default: 341e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 3427725ccfdSJing Huang } 3437725ccfdSJing Huang } 3447725ccfdSJing Huang 3455fbe25c7SJing Huang /* 3467725ccfdSJing Huang * fcs_port_pvt 3477725ccfdSJing Huang */ 3487725ccfdSJing Huang 3497725ccfdSJing Huang /* 3507826f304SKrishna Gudipati * Send AEN notification 3517826f304SKrishna Gudipati */ 3527826f304SKrishna Gudipati static void 3537826f304SKrishna Gudipati bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port, 3547826f304SKrishna Gudipati enum bfa_lport_aen_event event) 3557826f304SKrishna Gudipati { 3567826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 3577826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 3587826f304SKrishna Gudipati 3597826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 3607826f304SKrishna Gudipati if (!aen_entry) 3617826f304SKrishna Gudipati return; 3627826f304SKrishna Gudipati 3637826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 3647826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 3657826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 3667826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 3677826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 3687826f304SKrishna Gudipati 3697826f304SKrishna Gudipati /* Send the AEN notification */ 3707826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 3717826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 3727826f304SKrishna Gudipati } 3737826f304SKrishna Gudipati 3747826f304SKrishna Gudipati /* 3757725ccfdSJing Huang * Send a LS reject 3767725ccfdSJing Huang */ 3777725ccfdSJing Huang static void 378a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 3797725ccfdSJing Huang u8 reason_code, u8 reason_code_expl) 3807725ccfdSJing Huang { 3817725ccfdSJing Huang struct fchs_s fchs; 3827725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 3837725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 3847725ccfdSJing Huang int len; 3857725ccfdSJing Huang 386a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 3877725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 3887725ccfdSJing Huang 389c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 3907725ccfdSJing Huang if (!fcxp) 3917725ccfdSJing Huang return; 3927725ccfdSJing Huang 393a36c61f9SKrishna Gudipati len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 394a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 395a36c61f9SKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 3967725ccfdSJing Huang 3977725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 3987725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 3997725ccfdSJing Huang FC_MAX_PDUSZ, 0); 4007725ccfdSJing Huang } 4017725ccfdSJing Huang 4025fbe25c7SJing Huang /* 403d7be54ccSKrishna Gudipati * Send a FCCT Reject 404d7be54ccSKrishna Gudipati */ 405d7be54ccSKrishna Gudipati static void 406d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port, 407d7be54ccSKrishna Gudipati struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl) 408d7be54ccSKrishna Gudipati { 409d7be54ccSKrishna Gudipati struct fchs_s fchs; 410d7be54ccSKrishna Gudipati struct bfa_fcxp_s *fcxp; 411d7be54ccSKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 412d7be54ccSKrishna Gudipati int len; 413d7be54ccSKrishna Gudipati struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1); 414d7be54ccSKrishna Gudipati struct ct_hdr_s *ct_hdr; 415d7be54ccSKrishna Gudipati 416d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 417d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 418d7be54ccSKrishna Gudipati 419c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 420d7be54ccSKrishna Gudipati if (!fcxp) 421d7be54ccSKrishna Gudipati return; 422d7be54ccSKrishna Gudipati 423d7be54ccSKrishna Gudipati ct_hdr = bfa_fcxp_get_reqbuf(fcxp); 424d7be54ccSKrishna Gudipati ct_hdr->gs_type = rx_cthdr->gs_type; 425d7be54ccSKrishna Gudipati ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type; 426d7be54ccSKrishna Gudipati 427d7be54ccSKrishna Gudipati len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id, 428d7be54ccSKrishna Gudipati bfa_fcs_lport_get_fcid(port), 429d7be54ccSKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 430d7be54ccSKrishna Gudipati 431d7be54ccSKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 432d7be54ccSKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 433d7be54ccSKrishna Gudipati FC_MAX_PDUSZ, 0); 434d7be54ccSKrishna Gudipati } 435d7be54ccSKrishna Gudipati 436d7be54ccSKrishna Gudipati /* 4377725ccfdSJing Huang * Process incoming plogi from a remote port. 4387725ccfdSJing Huang */ 4397725ccfdSJing Huang static void 440a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 441a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi) 4427725ccfdSJing Huang { 4437725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 4447725ccfdSJing Huang 4457725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 4467725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4477725ccfdSJing Huang 4487725ccfdSJing Huang /* 4497725ccfdSJing Huang * If min cfg mode is enabled, drop any incoming PLOGIs 4507725ccfdSJing Huang */ 4517725ccfdSJing Huang if (__fcs_min_cfg(port->fcs)) { 4527725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4537725ccfdSJing Huang return; 4547725ccfdSJing Huang } 4557725ccfdSJing Huang 4567725ccfdSJing Huang if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) { 4577725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4587725ccfdSJing Huang /* 4597725ccfdSJing Huang * send a LS reject 4607725ccfdSJing Huang */ 461a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4627725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4637725ccfdSJing Huang FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS); 4647725ccfdSJing Huang return; 4657725ccfdSJing Huang } 4667725ccfdSJing Huang 4675fbe25c7SJing Huang /* 4687725ccfdSJing Huang * Direct Attach P2P mode : verify address assigned by the r-port. 4697725ccfdSJing Huang */ 470a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 471a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 472a36c61f9SKrishna Gudipati (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4737725ccfdSJing Huang if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) { 474a36c61f9SKrishna Gudipati /* Address assigned to us cannot be a WKA */ 475a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4767725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4777725ccfdSJing Huang FC_LS_RJT_EXP_INVALID_NPORT_ID); 4787725ccfdSJing Huang return; 4797725ccfdSJing Huang } 4807725ccfdSJing Huang port->pid = rx_fchs->d_id; 481b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4827725ccfdSJing Huang } 4837725ccfdSJing Huang 4845fbe25c7SJing Huang /* 4857725ccfdSJing Huang * First, check if we know the device by pwwn. 4867725ccfdSJing Huang */ 487a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name); 4887725ccfdSJing Huang if (rport) { 4895fbe25c7SJing Huang /* 490a36c61f9SKrishna Gudipati * Direct Attach P2P mode : handle address assigned by r-port. 4917725ccfdSJing Huang */ 492a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 493a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 4947725ccfdSJing Huang (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4957725ccfdSJing Huang port->pid = rx_fchs->d_id; 496b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4977725ccfdSJing Huang rport->pid = rx_fchs->s_id; 4987725ccfdSJing Huang } 4997725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 5007725ccfdSJing Huang return; 5017725ccfdSJing Huang } 5027725ccfdSJing Huang 5035fbe25c7SJing Huang /* 5047725ccfdSJing Huang * Next, lookup rport by PID. 5057725ccfdSJing Huang */ 506a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id); 5077725ccfdSJing Huang if (!rport) { 5085fbe25c7SJing Huang /* 5097725ccfdSJing Huang * Inbound PLOGI from a new device. 5107725ccfdSJing Huang */ 5117725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 5127725ccfdSJing Huang return; 5137725ccfdSJing Huang } 5147725ccfdSJing Huang 5155fbe25c7SJing Huang /* 5167725ccfdSJing Huang * Rport is known only by PID. 5177725ccfdSJing Huang */ 5187725ccfdSJing Huang if (rport->pwwn) { 5195fbe25c7SJing Huang /* 5207725ccfdSJing Huang * This is a different device with the same pid. Old device 5217725ccfdSJing Huang * disappeared. Send implicit LOGO to old device. 5227725ccfdSJing Huang */ 523d4b671c5SJing Huang WARN_ON(rport->pwwn == plogi->port_name); 524f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 5257725ccfdSJing Huang 5265fbe25c7SJing Huang /* 5277725ccfdSJing Huang * Inbound PLOGI from a new device (with old PID). 5287725ccfdSJing Huang */ 5297725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 5307725ccfdSJing Huang return; 5317725ccfdSJing Huang } 5327725ccfdSJing Huang 5335fbe25c7SJing Huang /* 5347725ccfdSJing Huang * PLOGI crossing each other. 5357725ccfdSJing Huang */ 536d4b671c5SJing Huang WARN_ON(rport->pwwn != WWN_NULL); 5377725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 5387725ccfdSJing Huang } 5397725ccfdSJing Huang 5407725ccfdSJing Huang /* 5417725ccfdSJing Huang * Process incoming ECHO. 5427725ccfdSJing Huang * Since it does not require a login, it is processed here. 5437725ccfdSJing Huang */ 5447725ccfdSJing Huang static void 545a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5467725ccfdSJing Huang struct fc_echo_s *echo, u16 rx_len) 5477725ccfdSJing Huang { 5487725ccfdSJing Huang struct fchs_s fchs; 5497725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5507725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5517725ccfdSJing Huang int len, pyld_len; 5527725ccfdSJing Huang 5537725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5547725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5557725ccfdSJing Huang 556c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5577725ccfdSJing Huang if (!fcxp) 5587725ccfdSJing Huang return; 5597725ccfdSJing Huang 560a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 561a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 562a36c61f9SKrishna Gudipati rx_fchs->ox_id); 5637725ccfdSJing Huang 5647725ccfdSJing Huang /* 5657725ccfdSJing Huang * Copy the payload (if any) from the echo frame 5667725ccfdSJing Huang */ 5677725ccfdSJing Huang pyld_len = rx_len - sizeof(struct fchs_s); 568a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_len); 5697725ccfdSJing Huang bfa_trc(port->fcs, pyld_len); 5707725ccfdSJing Huang 5717725ccfdSJing Huang if (pyld_len > len) 5727725ccfdSJing Huang memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) + 5737725ccfdSJing Huang sizeof(struct fc_echo_s), (echo + 1), 5747725ccfdSJing Huang (pyld_len - sizeof(struct fc_echo_s))); 5757725ccfdSJing Huang 5767725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5777725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL, 5787725ccfdSJing Huang FC_MAX_PDUSZ, 0); 5797725ccfdSJing Huang } 5807725ccfdSJing Huang 5817725ccfdSJing Huang /* 5827725ccfdSJing Huang * Process incoming RNID. 5837725ccfdSJing Huang * Since it does not require a login, it is processed here. 5847725ccfdSJing Huang */ 5857725ccfdSJing Huang static void 586a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5877725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 rx_len) 5887725ccfdSJing Huang { 5897725ccfdSJing Huang struct fc_rnid_common_id_data_s common_id_data; 5907725ccfdSJing Huang struct fc_rnid_general_topology_data_s gen_topo_data; 5917725ccfdSJing Huang struct fchs_s fchs; 5927725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5937725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5947725ccfdSJing Huang u16 len; 5957725ccfdSJing Huang u32 data_format; 5967725ccfdSJing Huang 5977725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5987725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5997725ccfdSJing Huang bfa_trc(port->fcs, rx_len); 6007725ccfdSJing Huang 601c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 6027725ccfdSJing Huang if (!fcxp) 6037725ccfdSJing Huang return; 6047725ccfdSJing Huang 6057725ccfdSJing Huang /* 6067725ccfdSJing Huang * Check Node Indentification Data Format 6077725ccfdSJing Huang * We only support General Topology Discovery Format. 6087725ccfdSJing Huang * For any other requested Data Formats, we return Common Node Id Data 6097725ccfdSJing Huang * only, as per FC-LS. 6107725ccfdSJing Huang */ 6117725ccfdSJing Huang bfa_trc(port->fcs, rnid->node_id_data_format); 6127725ccfdSJing Huang if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 6137725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY; 6147725ccfdSJing Huang /* 6157725ccfdSJing Huang * Get General topology data for this port 6167725ccfdSJing Huang */ 6177725ccfdSJing Huang bfa_fs_port_get_gen_topo_data(port, &gen_topo_data); 6187725ccfdSJing Huang } else { 6197725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_COMMON; 6207725ccfdSJing Huang } 6217725ccfdSJing Huang 6227725ccfdSJing Huang /* 6237725ccfdSJing Huang * Copy the Node Id Info 6247725ccfdSJing Huang */ 625a36c61f9SKrishna Gudipati common_id_data.port_name = bfa_fcs_lport_get_pwwn(port); 626a36c61f9SKrishna Gudipati common_id_data.node_name = bfa_fcs_lport_get_nwwn(port); 6277725ccfdSJing Huang 628a36c61f9SKrishna Gudipati len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 629a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 630a36c61f9SKrishna Gudipati rx_fchs->ox_id, data_format, &common_id_data, 631a36c61f9SKrishna Gudipati &gen_topo_data); 6327725ccfdSJing Huang 6337725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 6347725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 6357725ccfdSJing Huang FC_MAX_PDUSZ, 0); 6367725ccfdSJing Huang } 6377725ccfdSJing Huang 6387725ccfdSJing Huang /* 6397725ccfdSJing Huang * Fill out General Topolpgy Discovery Data for RNID ELS. 6407725ccfdSJing Huang */ 6417725ccfdSJing Huang static void 642a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 6437725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data) 6447725ccfdSJing Huang { 6456a18b167SJing Huang memset(gen_topo_data, 0, 6467725ccfdSJing Huang sizeof(struct fc_rnid_general_topology_data_s)); 6477725ccfdSJing Huang 648ba816ea8SJing Huang gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST); 6497725ccfdSJing Huang gen_topo_data->phy_port_num = 0; /* @todo */ 650ba816ea8SJing Huang gen_topo_data->num_attached_nodes = cpu_to_be32(1); 6517725ccfdSJing Huang } 6527725ccfdSJing Huang 6537725ccfdSJing Huang static void 654a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) 6557725ccfdSJing Huang { 656a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 657a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 658a36c61f9SKrishna Gudipati 6597725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6607725ccfdSJing Huang 6617725ccfdSJing Huang __port_action[port->fabric->fab_type].init(port); 6627725ccfdSJing Huang __port_action[port->fabric->fab_type].online(port); 6637725ccfdSJing Huang 664a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 665a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 666a36c61f9SKrishna Gudipati "Logical port online: WWN = %s Role = %s\n", 667a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6687826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE); 669a36c61f9SKrishna Gudipati 670a36c61f9SKrishna Gudipati bfad->bfad_flags |= BFAD_PORT_ONLINE; 6717725ccfdSJing Huang } 6727725ccfdSJing Huang 6737725ccfdSJing Huang static void 674a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) 6757725ccfdSJing Huang { 6767725ccfdSJing Huang struct list_head *qe, *qen; 6777725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 678a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 679a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 6807725ccfdSJing Huang 6817725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6827725ccfdSJing Huang 6837725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 6847725ccfdSJing Huang 685a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 686f7f73812SMaggie Zhang if (bfa_sm_cmp_state(port->fabric, 6877826f304SKrishna Gudipati bfa_fcs_fabric_sm_online) == BFA_TRUE) { 688a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 689a36c61f9SKrishna Gudipati "Logical port lost fabric connectivity: WWN = %s Role = %s\n", 690a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6917826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT); 6927826f304SKrishna Gudipati } else { 693a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 694a36c61f9SKrishna Gudipati "Logical port taken offline: WWN = %s Role = %s\n", 695a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6967826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE); 6977826f304SKrishna Gudipati } 6987725ccfdSJing Huang 6997725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 7007725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 701f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 7027725ccfdSJing Huang } 7037725ccfdSJing Huang } 7047725ccfdSJing Huang 7057725ccfdSJing Huang static void 706a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port) 7077725ccfdSJing Huang { 708d4b671c5SJing Huang WARN_ON(1); 7097725ccfdSJing Huang } 7107725ccfdSJing Huang 7117725ccfdSJing Huang static void 712a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port) 7137725ccfdSJing Huang { 714d4b671c5SJing Huang WARN_ON(1); 7157725ccfdSJing Huang } 7167725ccfdSJing Huang 7177725ccfdSJing Huang static void 718a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port) 7197725ccfdSJing Huang { 720d4b671c5SJing Huang WARN_ON(1); 7217725ccfdSJing Huang } 7227725ccfdSJing Huang 7237725ccfdSJing Huang static void 724a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs) 7257725ccfdSJing Huang { 726a36c61f9SKrishna Gudipati struct fchs_s fchs; 727a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 728a36c61f9SKrishna Gudipati int len; 7297725ccfdSJing Huang 730a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 731a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 732a36c61f9SKrishna Gudipati 733c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 734a36c61f9SKrishna Gudipati if (!fcxp) 735a36c61f9SKrishna Gudipati return; 736a36c61f9SKrishna Gudipati 737a36c61f9SKrishna Gudipati len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 738a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 739a36c61f9SKrishna Gudipati rx_fchs->ox_id, 0); 740a36c61f9SKrishna Gudipati 741a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 742a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 743a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 744a36c61f9SKrishna Gudipati } 745a36c61f9SKrishna Gudipati static void 746a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) 747a36c61f9SKrishna Gudipati { 748a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 749a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 750a36c61f9SKrishna Gudipati 751a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 75288166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 753a36c61f9SKrishna Gudipati "Logical port deleted: WWN = %s Role = %s\n", 754a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 7557826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE); 756a36c61f9SKrishna Gudipati 757a36c61f9SKrishna Gudipati /* Base port will be deleted by the OS driver */ 75817c201b3SKrishna Gudipati if (port->vport) 7597725ccfdSJing Huang bfa_fcs_vport_delete_comp(port->vport); 76017c201b3SKrishna Gudipati else 761f7f73812SMaggie Zhang bfa_wc_down(&port->fabric->wc); 7627725ccfdSJing Huang } 7637725ccfdSJing Huang 7647725ccfdSJing Huang 7655fbe25c7SJing Huang /* 7667725ccfdSJing Huang * Unsolicited frame receive handling. 7677725ccfdSJing Huang */ 7687725ccfdSJing Huang void 769a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, 770a36c61f9SKrishna Gudipati struct fchs_s *fchs, u16 len) 7717725ccfdSJing Huang { 7727725ccfdSJing Huang u32 pid = fchs->s_id; 7737725ccfdSJing Huang struct bfa_fcs_rport_s *rport = NULL; 7747725ccfdSJing Huang struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 7757725ccfdSJing Huang 7767725ccfdSJing Huang bfa_stats(lport, uf_recvs); 77715821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->type); 7787725ccfdSJing Huang 779a36c61f9SKrishna Gudipati if (!bfa_fcs_lport_is_online(lport)) { 7809781851fSVijaya Mohan Guvva /* 7819781851fSVijaya Mohan Guvva * In direct attach topology, it is possible to get a PLOGI 7829781851fSVijaya Mohan Guvva * before the lport is online due to port feature 7839781851fSVijaya Mohan Guvva * (QoS/Trunk/FEC/CR), so send a rjt 7849781851fSVijaya Mohan Guvva */ 7859781851fSVijaya Mohan Guvva if ((fchs->type == FC_TYPE_ELS) && 7869781851fSVijaya Mohan Guvva (els_cmd->els_code == FC_ELS_PLOGI)) { 7879781851fSVijaya Mohan Guvva bfa_fcs_lport_send_ls_rjt(lport, fchs, 7889781851fSVijaya Mohan Guvva FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD, 7899781851fSVijaya Mohan Guvva FC_LS_RJT_EXP_NO_ADDL_INFO); 7909781851fSVijaya Mohan Guvva bfa_stats(lport, plogi_rcvd); 7919781851fSVijaya Mohan Guvva } else 7927725ccfdSJing Huang bfa_stats(lport, uf_recv_drops); 7939781851fSVijaya Mohan Guvva 7947725ccfdSJing Huang return; 7957725ccfdSJing Huang } 7967725ccfdSJing Huang 7975fbe25c7SJing Huang /* 7987725ccfdSJing Huang * First, handle ELSs that donot require a login. 7997725ccfdSJing Huang */ 8007725ccfdSJing Huang /* 8017725ccfdSJing Huang * Handle PLOGI first 8027725ccfdSJing Huang */ 8037725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && 8047725ccfdSJing Huang (els_cmd->els_code == FC_ELS_PLOGI)) { 805a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd); 8067725ccfdSJing Huang return; 8077725ccfdSJing Huang } 8087725ccfdSJing Huang 8097725ccfdSJing Huang /* 8107725ccfdSJing Huang * Handle ECHO separately. 8117725ccfdSJing Huang */ 8127725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) { 813a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(lport, fchs, 8147725ccfdSJing Huang (struct fc_echo_s *)els_cmd, len); 8157725ccfdSJing Huang return; 8167725ccfdSJing Huang } 8177725ccfdSJing Huang 8187725ccfdSJing Huang /* 8197725ccfdSJing Huang * Handle RNID separately. 8207725ccfdSJing Huang */ 8217725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) { 822a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(lport, fchs, 8237725ccfdSJing Huang (struct fc_rnid_cmd_s *) els_cmd, len); 8247725ccfdSJing Huang return; 8257725ccfdSJing Huang } 8267725ccfdSJing Huang 827a36c61f9SKrishna Gudipati if (fchs->type == FC_TYPE_BLS) { 828a36c61f9SKrishna Gudipati if ((fchs->routing == FC_RTG_BASIC_LINK) && 829a36c61f9SKrishna Gudipati (fchs->cat_info == FC_CAT_ABTS)) 830a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(lport, fchs); 831a36c61f9SKrishna Gudipati return; 832a36c61f9SKrishna Gudipati } 833d7be54ccSKrishna Gudipati 834d7be54ccSKrishna Gudipati if (fchs->type == FC_TYPE_SERVICES) { 835d7be54ccSKrishna Gudipati /* 836d7be54ccSKrishna Gudipati * Unhandled FC-GS frames. Send a FC-CT Reject 837d7be54ccSKrishna Gudipati */ 838d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP, 839d7be54ccSKrishna Gudipati CT_NS_EXP_NOADDITIONAL); 840d7be54ccSKrishna Gudipati return; 841d7be54ccSKrishna Gudipati } 842d7be54ccSKrishna Gudipati 8435fbe25c7SJing Huang /* 8447725ccfdSJing Huang * look for a matching remote port ID 8457725ccfdSJing Huang */ 846a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(lport, pid); 8477725ccfdSJing Huang if (rport) { 8487725ccfdSJing Huang bfa_trc(rport->fcs, fchs->s_id); 8497725ccfdSJing Huang bfa_trc(rport->fcs, fchs->d_id); 8507725ccfdSJing Huang bfa_trc(rport->fcs, fchs->type); 8517725ccfdSJing Huang 8527725ccfdSJing Huang bfa_fcs_rport_uf_recv(rport, fchs, len); 8537725ccfdSJing Huang return; 8547725ccfdSJing Huang } 8557725ccfdSJing Huang 8565fbe25c7SJing Huang /* 8577725ccfdSJing Huang * Only handles ELS frames for now. 8587725ccfdSJing Huang */ 8597725ccfdSJing Huang if (fchs->type != FC_TYPE_ELS) { 86015821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->s_id); 86115821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->d_id); 86215821f05SKrishna Gudipati /* ignore type FC_TYPE_FC_FSS */ 86315821f05SKrishna Gudipati if (fchs->type != FC_TYPE_FC_FSS) 86415821f05SKrishna Gudipati bfa_sm_fault(lport->fcs, fchs->type); 8657725ccfdSJing Huang return; 8667725ccfdSJing Huang } 8677725ccfdSJing Huang 8687725ccfdSJing Huang bfa_trc(lport->fcs, els_cmd->els_code); 8697725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_RSCN) { 870a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(lport, fchs, len); 8717725ccfdSJing Huang return; 8727725ccfdSJing Huang } 8737725ccfdSJing Huang 8747725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_LOGO) { 8755fbe25c7SJing Huang /* 8767725ccfdSJing Huang * @todo Handle LOGO frames received. 8777725ccfdSJing Huang */ 8787725ccfdSJing Huang return; 8797725ccfdSJing Huang } 8807725ccfdSJing Huang 8817725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_PRLI) { 8825fbe25c7SJing Huang /* 8837725ccfdSJing Huang * @todo Handle PRLI frames received. 8847725ccfdSJing Huang */ 8857725ccfdSJing Huang return; 8867725ccfdSJing Huang } 8877725ccfdSJing Huang 8885fbe25c7SJing Huang /* 8897725ccfdSJing Huang * Unhandled ELS frames. Send a LS_RJT. 8907725ccfdSJing Huang */ 891a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP, 8927725ccfdSJing Huang FC_LS_RJT_EXP_NO_ADDL_INFO); 8937725ccfdSJing Huang 8947725ccfdSJing Huang } 8957725ccfdSJing Huang 8965fbe25c7SJing Huang /* 8977725ccfdSJing Huang * PID based Lookup for a R-Port in the Port R-Port Queue 8987725ccfdSJing Huang */ 8997725ccfdSJing Huang struct bfa_fcs_rport_s * 900a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) 9017725ccfdSJing Huang { 9027725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 9037725ccfdSJing Huang struct list_head *qe; 9047725ccfdSJing Huang 9057725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 9067725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 9077725ccfdSJing Huang if (rport->pid == pid) 9087725ccfdSJing Huang return rport; 9097725ccfdSJing Huang } 9107725ccfdSJing Huang 9117725ccfdSJing Huang bfa_trc(port->fcs, pid); 9127725ccfdSJing Huang return NULL; 9137725ccfdSJing Huang } 9147725ccfdSJing Huang 9155fbe25c7SJing Huang /* 916ee1a4a42SKrishna Gudipati * OLD_PID based Lookup for a R-Port in the Port R-Port Queue 917ee1a4a42SKrishna Gudipati */ 918ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s * 919ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid) 920ee1a4a42SKrishna Gudipati { 921ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *rport; 922ee1a4a42SKrishna Gudipati struct list_head *qe; 923ee1a4a42SKrishna Gudipati 924ee1a4a42SKrishna Gudipati list_for_each(qe, &port->rport_q) { 925ee1a4a42SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 926ee1a4a42SKrishna Gudipati if (rport->old_pid == pid) 927ee1a4a42SKrishna Gudipati return rport; 928ee1a4a42SKrishna Gudipati } 929ee1a4a42SKrishna Gudipati 930ee1a4a42SKrishna Gudipati bfa_trc(port->fcs, pid); 931ee1a4a42SKrishna Gudipati return NULL; 932ee1a4a42SKrishna Gudipati } 933ee1a4a42SKrishna Gudipati 934ee1a4a42SKrishna Gudipati /* 9357725ccfdSJing Huang * PWWN based Lookup for a R-Port in the Port R-Port Queue 9367725ccfdSJing Huang */ 9377725ccfdSJing Huang struct bfa_fcs_rport_s * 938a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn) 9397725ccfdSJing Huang { 9407725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 9417725ccfdSJing Huang struct list_head *qe; 9427725ccfdSJing Huang 9437725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 9447725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 9457725ccfdSJing Huang if (wwn_is_equal(rport->pwwn, pwwn)) 9467725ccfdSJing Huang return rport; 9477725ccfdSJing Huang } 9487725ccfdSJing Huang 9497725ccfdSJing Huang bfa_trc(port->fcs, pwwn); 950f8ceafdeSJing Huang return NULL; 9517725ccfdSJing Huang } 9527725ccfdSJing Huang 9535fbe25c7SJing Huang /* 9547725ccfdSJing Huang * NWWN based Lookup for a R-Port in the Port R-Port Queue 9557725ccfdSJing Huang */ 9567725ccfdSJing Huang struct bfa_fcs_rport_s * 957a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) 9587725ccfdSJing Huang { 9597725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 9607725ccfdSJing Huang struct list_head *qe; 9617725ccfdSJing Huang 9627725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 9637725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 9647725ccfdSJing Huang if (wwn_is_equal(rport->nwwn, nwwn)) 9657725ccfdSJing Huang return rport; 9667725ccfdSJing Huang } 9677725ccfdSJing Huang 9687725ccfdSJing Huang bfa_trc(port->fcs, nwwn); 969f8ceafdeSJing Huang return NULL; 9707725ccfdSJing Huang } 9717725ccfdSJing Huang 9725fbe25c7SJing Huang /* 973ee1a4a42SKrishna Gudipati * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue 974ee1a4a42SKrishna Gudipati */ 975ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s * 976ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port, 977ee1a4a42SKrishna Gudipati wwn_t pwwn, u32 pid) 978ee1a4a42SKrishna Gudipati { 979ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *rport; 980ee1a4a42SKrishna Gudipati struct list_head *qe; 981ee1a4a42SKrishna Gudipati 982ee1a4a42SKrishna Gudipati list_for_each(qe, &port->rport_q) { 983ee1a4a42SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 984ee1a4a42SKrishna Gudipati if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid) 985ee1a4a42SKrishna Gudipati return rport; 986ee1a4a42SKrishna Gudipati } 987ee1a4a42SKrishna Gudipati 988ee1a4a42SKrishna Gudipati bfa_trc(port->fcs, pwwn); 989ee1a4a42SKrishna Gudipati return NULL; 990ee1a4a42SKrishna Gudipati } 991ee1a4a42SKrishna Gudipati 992ee1a4a42SKrishna Gudipati /* 9937725ccfdSJing Huang * Called by rport module when new rports are discovered. 9947725ccfdSJing Huang */ 9957725ccfdSJing Huang void 996a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport( 997a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 9987725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 9997725ccfdSJing Huang { 10007725ccfdSJing Huang list_add_tail(&rport->qe, &port->rport_q); 10017725ccfdSJing Huang port->num_rports++; 10027725ccfdSJing Huang } 10037725ccfdSJing Huang 10045fbe25c7SJing Huang /* 10057725ccfdSJing Huang * Called by rport module to when rports are deleted. 10067725ccfdSJing Huang */ 10077725ccfdSJing Huang void 1008a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport( 1009a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 10107725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 10117725ccfdSJing Huang { 1012d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport)); 10137725ccfdSJing Huang list_del(&rport->qe); 10147725ccfdSJing Huang port->num_rports--; 10157725ccfdSJing Huang 10167725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT); 10177725ccfdSJing Huang } 10187725ccfdSJing Huang 10195fbe25c7SJing Huang /* 10207725ccfdSJing Huang * Called by fabric for base port when fabric login is complete. 10217725ccfdSJing Huang * Called by vport for virtual ports when FDISC is complete. 10227725ccfdSJing Huang */ 10237725ccfdSJing Huang void 1024a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port) 10257725ccfdSJing Huang { 10267725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE); 10277725ccfdSJing Huang } 10287725ccfdSJing Huang 10295fbe25c7SJing Huang /* 10307725ccfdSJing Huang * Called by fabric for base port when fabric goes offline. 10317725ccfdSJing Huang * Called by vport for virtual ports when virtual port becomes offline. 10327725ccfdSJing Huang */ 10337725ccfdSJing Huang void 1034a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port) 10357725ccfdSJing Huang { 10367725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE); 10377725ccfdSJing Huang } 10387725ccfdSJing Huang 10395fbe25c7SJing Huang /* 1040881c1b3cSKrishna Gudipati * Called by fabric for base port and by vport for virtual ports 1041881c1b3cSKrishna Gudipati * when target mode driver is unloaded. 1042881c1b3cSKrishna Gudipati */ 1043881c1b3cSKrishna Gudipati void 1044881c1b3cSKrishna Gudipati bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port) 1045881c1b3cSKrishna Gudipati { 1046881c1b3cSKrishna Gudipati bfa_sm_send_event(port, BFA_FCS_PORT_SM_STOP); 1047881c1b3cSKrishna Gudipati } 1048881c1b3cSKrishna Gudipati 1049881c1b3cSKrishna Gudipati /* 10507725ccfdSJing Huang * Called by fabric to delete base lport and associated resources. 10517725ccfdSJing Huang * 10527725ccfdSJing Huang * Called by vport to delete lport and associated resources. Should call 10537725ccfdSJing Huang * bfa_fcs_vport_delete_comp() for vports on completion. 10547725ccfdSJing Huang */ 10557725ccfdSJing Huang void 1056a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port) 10577725ccfdSJing Huang { 10587725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE); 10597725ccfdSJing Huang } 10607725ccfdSJing Huang 10615fbe25c7SJing Huang /* 10627725ccfdSJing Huang * Return TRUE if port is online, else return FALSE 10637725ccfdSJing Huang */ 10647725ccfdSJing Huang bfa_boolean_t 1065a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port) 10667725ccfdSJing Huang { 1067a36c61f9SKrishna Gudipati return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online); 10687725ccfdSJing Huang } 10697725ccfdSJing Huang 10705fbe25c7SJing Huang /* 1071e6714324SKrishna Gudipati * Attach time initialization of logical ports. 10727725ccfdSJing Huang */ 10737725ccfdSJing Huang void 1074a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs, 1075a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_fcs_vport_s *vport) 10767725ccfdSJing Huang { 10777725ccfdSJing Huang lport->fcs = fcs; 10787725ccfdSJing Huang lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); 10797725ccfdSJing Huang lport->vport = vport; 10803fd45980SKrishna Gudipati lport->lp_tag = (vport) ? vport->lps->bfa_tag : 10813fd45980SKrishna Gudipati lport->fabric->lps->bfa_tag; 10827725ccfdSJing Huang 10837725ccfdSJing Huang INIT_LIST_HEAD(&lport->rport_q); 10847725ccfdSJing Huang lport->num_rports = 0; 1085e6714324SKrishna Gudipati } 10867725ccfdSJing Huang 10875fbe25c7SJing Huang /* 1088e6714324SKrishna Gudipati * Logical port initialization of base or virtual port. 1089e6714324SKrishna Gudipati * Called by fabric for base port or by vport for virtual ports. 1090e6714324SKrishna Gudipati */ 1091e6714324SKrishna Gudipati 1092e6714324SKrishna Gudipati void 1093a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, 1094a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *port_cfg) 1095e6714324SKrishna Gudipati { 1096e6714324SKrishna Gudipati struct bfa_fcs_vport_s *vport = lport->vport; 1097a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad; 1098a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 1099e6714324SKrishna Gudipati 11006a18b167SJing Huang lport->port_cfg = *port_cfg; 1101e6714324SKrishna Gudipati 1102a36c61f9SKrishna Gudipati lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport, 1103e6714324SKrishna Gudipati lport->port_cfg.roles, 11047725ccfdSJing Huang lport->fabric->vf_drv, 11057725ccfdSJing Huang vport ? vport->vport_drv : NULL); 1106e6714324SKrishna Gudipati 1107a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); 110888166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 1109a36c61f9SKrishna Gudipati "New logical port created: WWN = %s Role = %s\n", 1110a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 11117826f304SKrishna Gudipati bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW); 11127725ccfdSJing Huang 1113a36c61f9SKrishna Gudipati bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit); 11147725ccfdSJing Huang bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 11157725ccfdSJing Huang } 11167725ccfdSJing Huang 111722a08538SVijaya Mohan Guvva void 111822a08538SVijaya Mohan Guvva bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port, 111922a08538SVijaya Mohan Guvva char *symname) 112022a08538SVijaya Mohan Guvva { 112122a08538SVijaya Mohan Guvva strcpy(port->port_cfg.sym_name.symname, symname); 112222a08538SVijaya Mohan Guvva 112322a08538SVijaya Mohan Guvva if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 112422a08538SVijaya Mohan Guvva bfa_fcs_lport_ns_util_send_rspn_id( 112522a08538SVijaya Mohan Guvva BFA_FCS_GET_NS_FROM_PORT(port), NULL); 112622a08538SVijaya Mohan Guvva } 112722a08538SVijaya Mohan Guvva 11285fbe25c7SJing Huang /* 11297725ccfdSJing Huang * fcs_lport_api 11307725ccfdSJing Huang */ 11317725ccfdSJing Huang 11327725ccfdSJing Huang void 1133a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr( 1134a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 1135a36c61f9SKrishna Gudipati struct bfa_lport_attr_s *port_attr) 11367725ccfdSJing Huang { 1137a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 11387725ccfdSJing Huang port_attr->pid = port->pid; 11397725ccfdSJing Huang else 11407725ccfdSJing Huang port_attr->pid = 0; 11417725ccfdSJing Huang 11427725ccfdSJing Huang port_attr->port_cfg = port->port_cfg; 11437725ccfdSJing Huang 11447725ccfdSJing Huang if (port->fabric) { 1145f7f73812SMaggie Zhang port_attr->port_type = port->fabric->oper_type; 1146da99dcc9SMaggie Zhang port_attr->loopback = bfa_sm_cmp_state(port->fabric, 1147da99dcc9SMaggie Zhang bfa_fcs_fabric_sm_loopback); 1148f926a05fSKrishna Gudipati port_attr->authfail = 1149f7f73812SMaggie Zhang bfa_sm_cmp_state(port->fabric, 1150f7f73812SMaggie Zhang bfa_fcs_fabric_sm_auth_failed); 1151a36c61f9SKrishna Gudipati port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port); 11527725ccfdSJing Huang memcpy(port_attr->fabric_ip_addr, 1153a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fabric_ipaddr(port), 11547725ccfdSJing Huang BFA_FCS_FABRIC_IPADDR_SZ); 11557725ccfdSJing Huang 115686e32dabSKrishna Gudipati if (port->vport != NULL) { 1157a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_VPORT; 115886e32dabSKrishna Gudipati port_attr->fpma_mac = 1159f7f73812SMaggie Zhang port->vport->lps->lp_mac; 1160a36c61f9SKrishna Gudipati } else { 116186e32dabSKrishna Gudipati port_attr->fpma_mac = 1162f7f73812SMaggie Zhang port->fabric->lps->lp_mac; 1163a36c61f9SKrishna Gudipati } 1164a36c61f9SKrishna Gudipati } else { 1165a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_UNKNOWN; 1166a36c61f9SKrishna Gudipati port_attr->state = BFA_LPORT_UNINIT; 1167a36c61f9SKrishna Gudipati } 1168a36c61f9SKrishna Gudipati } 1169a36c61f9SKrishna Gudipati 11705fbe25c7SJing Huang /* 1171a36c61f9SKrishna Gudipati * bfa_fcs_lport_fab port fab functions 1172a36c61f9SKrishna Gudipati */ 1173a36c61f9SKrishna Gudipati 11745fbe25c7SJing Huang /* 1175a36c61f9SKrishna Gudipati * Called by port to initialize fabric services of the base port. 1176a36c61f9SKrishna Gudipati */ 1177a36c61f9SKrishna Gudipati static void 1178a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port) 1179a36c61f9SKrishna Gudipati { 1180a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(port); 1181a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(port); 1182a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(port); 1183a36c61f9SKrishna Gudipati } 1184a36c61f9SKrishna Gudipati 11855fbe25c7SJing Huang /* 1186a36c61f9SKrishna Gudipati * Called by port to notify transition to online state. 1187a36c61f9SKrishna Gudipati */ 1188a36c61f9SKrishna Gudipati static void 1189a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 1190a36c61f9SKrishna Gudipati { 1191a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(port); 1192bc0e2c2aSKrishna Gudipati bfa_fcs_lport_fab_scn_online(port); 1193a36c61f9SKrishna Gudipati } 1194a36c61f9SKrishna Gudipati 11955fbe25c7SJing Huang /* 1196a36c61f9SKrishna Gudipati * Called by port to notify transition to offline state. 1197a36c61f9SKrishna Gudipati */ 1198a36c61f9SKrishna Gudipati static void 1199a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port) 1200a36c61f9SKrishna Gudipati { 1201a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(port); 1202a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(port); 1203a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(port); 1204a36c61f9SKrishna Gudipati } 1205a36c61f9SKrishna Gudipati 12065fbe25c7SJing Huang /* 1207a36c61f9SKrishna Gudipati * bfa_fcs_lport_n2n functions 1208a36c61f9SKrishna Gudipati */ 1209a36c61f9SKrishna Gudipati 12105fbe25c7SJing Huang /* 1211a36c61f9SKrishna Gudipati * Called by fcs/port to initialize N2N topology. 1212a36c61f9SKrishna Gudipati */ 1213a36c61f9SKrishna Gudipati static void 1214a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port) 1215a36c61f9SKrishna Gudipati { 1216a36c61f9SKrishna Gudipati } 1217a36c61f9SKrishna Gudipati 12185fbe25c7SJing Huang /* 1219a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to online state. 1220a36c61f9SKrishna Gudipati */ 1221a36c61f9SKrishna Gudipati static void 1222a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port) 1223a36c61f9SKrishna Gudipati { 1224a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1225a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *pcfg = &port->port_cfg; 1226a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 1227a36c61f9SKrishna Gudipati 1228a36c61f9SKrishna Gudipati bfa_trc(port->fcs, pcfg->pwwn); 1229a36c61f9SKrishna Gudipati 1230a36c61f9SKrishna Gudipati /* 1231a36c61f9SKrishna Gudipati * If our PWWN is > than that of the r-port, we have to initiate PLOGI 1232a36c61f9SKrishna Gudipati * and assign an Address. if not, we need to wait for its PLOGI. 1233a36c61f9SKrishna Gudipati * 1234a36c61f9SKrishna Gudipati * If our PWWN is < than that of the remote port, it will send a PLOGI 1235a36c61f9SKrishna Gudipati * with the PIDs assigned. The rport state machine take care of this 1236a36c61f9SKrishna Gudipati * incoming PLOGI. 1237a36c61f9SKrishna Gudipati */ 1238a36c61f9SKrishna Gudipati if (memcmp 1239a36c61f9SKrishna Gudipati ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, 1240a36c61f9SKrishna Gudipati sizeof(wwn_t)) > 0) { 1241a36c61f9SKrishna Gudipati port->pid = N2N_LOCAL_PID; 1242b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID); 12435fbe25c7SJing Huang /* 1244a36c61f9SKrishna Gudipati * First, check if we know the device by pwwn. 1245a36c61f9SKrishna Gudipati */ 1246a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, 1247a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn); 1248a36c61f9SKrishna Gudipati if (rport) { 1249a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pid); 1250a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1251a36c61f9SKrishna Gudipati rport->pid = N2N_REMOTE_PID; 1252f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 1253a36c61f9SKrishna Gudipati return; 1254a36c61f9SKrishna Gudipati } 1255a36c61f9SKrishna Gudipati 1256a36c61f9SKrishna Gudipati /* 1257a36c61f9SKrishna Gudipati * In n2n there can be only one rport. Delete the old one 1258a36c61f9SKrishna Gudipati * whose pid should be zero, because it is offline. 1259a36c61f9SKrishna Gudipati */ 1260a36c61f9SKrishna Gudipati if (port->num_rports > 0) { 1261a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 0); 1262d4b671c5SJing Huang WARN_ON(rport == NULL); 1263a36c61f9SKrishna Gudipati if (rport) { 1264a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1265f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1266a36c61f9SKrishna Gudipati } 1267a36c61f9SKrishna Gudipati } 1268a36c61f9SKrishna Gudipati bfa_fcs_rport_create(port, N2N_REMOTE_PID); 1269a36c61f9SKrishna Gudipati } 1270a36c61f9SKrishna Gudipati } 1271a36c61f9SKrishna Gudipati 12725fbe25c7SJing Huang /* 1273a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to offline state. 1274a36c61f9SKrishna Gudipati */ 1275a36c61f9SKrishna Gudipati static void 1276a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port) 1277a36c61f9SKrishna Gudipati { 1278a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1279a36c61f9SKrishna Gudipati 1280a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 1281a36c61f9SKrishna Gudipati port->pid = 0; 1282a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn = 0; 1283a36c61f9SKrishna Gudipati n2n_port->reply_oxid = 0; 1284a36c61f9SKrishna Gudipati } 1285a36c61f9SKrishna Gudipati 1286bc0e2c2aSKrishna Gudipati void 1287bc0e2c2aSKrishna Gudipati bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port) 1288bc0e2c2aSKrishna Gudipati { 1289bc0e2c2aSKrishna Gudipati int i = 0, j = 0, bit = 0, alpa_bit = 0; 1290bc0e2c2aSKrishna Gudipati u8 k = 0; 1291bc0e2c2aSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa); 1292bc0e2c2aSKrishna Gudipati 1293bc0e2c2aSKrishna Gudipati port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid; 1294bc0e2c2aSKrishna Gudipati port->pid = fcport->myalpa; 1295bc0e2c2aSKrishna Gudipati port->pid = bfa_hton3b(port->pid); 1296bc0e2c2aSKrishna Gudipati 1297bc0e2c2aSKrishna Gudipati for (i = 0; i < (FC_ALPA_MAX / 8); i++) { 1298bc0e2c2aSKrishna Gudipati for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) { 1299bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]); 1300bc0e2c2aSKrishna Gudipati bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j))); 1301bc0e2c2aSKrishna Gudipati if (bit) { 1302bc0e2c2aSKrishna Gudipati port->port_topo.ploop.alpa_pos_map[k] = 1303bc0e2c2aSKrishna Gudipati loop_alpa_map[(i * 8) + alpa_bit]; 1304bc0e2c2aSKrishna Gudipati k++; 1305bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, k); 1306bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, 1307bc0e2c2aSKrishna Gudipati port->port_topo.ploop.alpa_pos_map[k]); 1308bc0e2c2aSKrishna Gudipati } 1309bc0e2c2aSKrishna Gudipati } 1310bc0e2c2aSKrishna Gudipati } 1311bc0e2c2aSKrishna Gudipati port->port_topo.ploop.num_alpa = k; 1312bc0e2c2aSKrishna Gudipati } 1313bc0e2c2aSKrishna Gudipati 1314bc0e2c2aSKrishna Gudipati /* 1315bc0e2c2aSKrishna Gudipati * Called by fcs/port to initialize Loop topology. 1316bc0e2c2aSKrishna Gudipati */ 1317bc0e2c2aSKrishna Gudipati static void 1318bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port) 1319bc0e2c2aSKrishna Gudipati { 1320bc0e2c2aSKrishna Gudipati } 1321bc0e2c2aSKrishna Gudipati 1322bc0e2c2aSKrishna Gudipati /* 1323bc0e2c2aSKrishna Gudipati * Called by fcs/port to notify transition to online state. 1324bc0e2c2aSKrishna Gudipati */ 1325bc0e2c2aSKrishna Gudipati static void 1326bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port) 1327bc0e2c2aSKrishna Gudipati { 1328bc0e2c2aSKrishna Gudipati u8 num_alpa = 0, alpabm_valid = 0; 1329bc0e2c2aSKrishna Gudipati struct bfa_fcs_rport_s *rport; 1330bc0e2c2aSKrishna Gudipati u8 *alpa_map = NULL; 1331bc0e2c2aSKrishna Gudipati int i = 0; 1332bc0e2c2aSKrishna Gudipati u32 pid; 1333bc0e2c2aSKrishna Gudipati 1334bc0e2c2aSKrishna Gudipati bfa_fcport_get_loop_attr(port); 1335bc0e2c2aSKrishna Gudipati 1336bc0e2c2aSKrishna Gudipati num_alpa = port->port_topo.ploop.num_alpa; 1337bc0e2c2aSKrishna Gudipati alpabm_valid = port->port_topo.ploop.alpabm_valid; 1338bc0e2c2aSKrishna Gudipati alpa_map = port->port_topo.ploop.alpa_pos_map; 1339bc0e2c2aSKrishna Gudipati 1340bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, port->pid); 1341bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, num_alpa); 1342bc0e2c2aSKrishna Gudipati if (alpabm_valid == 1) { 1343bc0e2c2aSKrishna Gudipati for (i = 0; i < num_alpa; i++) { 1344bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, alpa_map[i]); 1345bc0e2c2aSKrishna Gudipati if (alpa_map[i] != bfa_hton3b(port->pid)) { 1346bc0e2c2aSKrishna Gudipati pid = alpa_map[i]; 1347bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, pid); 1348bc0e2c2aSKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 1349bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1350bc0e2c2aSKrishna Gudipati if (!rport) 1351bc0e2c2aSKrishna Gudipati rport = bfa_fcs_rport_create(port, 1352bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1353bc0e2c2aSKrishna Gudipati } 1354bc0e2c2aSKrishna Gudipati } 1355bc0e2c2aSKrishna Gudipati } else { 1356bc0e2c2aSKrishna Gudipati for (i = 0; i < MAX_ALPA_COUNT; i++) { 1357bc0e2c2aSKrishna Gudipati if (alpa_map[i] != port->pid) { 1358bc0e2c2aSKrishna Gudipati pid = loop_alpa_map[i]; 1359bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, pid); 1360bc0e2c2aSKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 1361bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1362bc0e2c2aSKrishna Gudipati if (!rport) 1363bc0e2c2aSKrishna Gudipati rport = bfa_fcs_rport_create(port, 1364bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1365bc0e2c2aSKrishna Gudipati } 1366bc0e2c2aSKrishna Gudipati } 1367bc0e2c2aSKrishna Gudipati } 1368bc0e2c2aSKrishna Gudipati } 1369bc0e2c2aSKrishna Gudipati 1370bc0e2c2aSKrishna Gudipati /* 1371bc0e2c2aSKrishna Gudipati * Called by fcs/port to notify transition to offline state. 1372bc0e2c2aSKrishna Gudipati */ 1373bc0e2c2aSKrishna Gudipati static void 1374bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port) 1375bc0e2c2aSKrishna Gudipati { 1376bc0e2c2aSKrishna Gudipati } 1377bc0e2c2aSKrishna Gudipati 1378a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 1379a36c61f9SKrishna Gudipati 1380a36c61f9SKrishna Gudipati /* 1381a36c61f9SKrishna Gudipati * forward declarations 1382a36c61f9SKrishna Gudipati */ 1383a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, 1384a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1385a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, 1386a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1387a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, 1388a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1389a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, 1390a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1391a36c61f9SKrishna Gudipati void *cbarg, 1392a36c61f9SKrishna Gudipati bfa_status_t req_status, 1393a36c61f9SKrishna Gudipati u32 rsp_len, 1394a36c61f9SKrishna Gudipati u32 resid_len, 1395a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1396a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, 1397a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1398a36c61f9SKrishna Gudipati void *cbarg, 1399a36c61f9SKrishna Gudipati bfa_status_t req_status, 1400a36c61f9SKrishna Gudipati u32 rsp_len, 1401a36c61f9SKrishna Gudipati u32 resid_len, 1402a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1403a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, 1404a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1405a36c61f9SKrishna Gudipati void *cbarg, 1406a36c61f9SKrishna Gudipati bfa_status_t req_status, 1407a36c61f9SKrishna Gudipati u32 rsp_len, 1408a36c61f9SKrishna Gudipati u32 resid_len, 1409a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1410a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_timeout(void *arg); 1411a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1412a36c61f9SKrishna Gudipati u8 *pyld); 1413a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1414a36c61f9SKrishna Gudipati u8 *pyld); 1415a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1416a36c61f9SKrishna Gudipati u8 *pyld); 1417a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s * 1418a36c61f9SKrishna Gudipati fdmi, u8 *pyld); 1419a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1420a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr); 1421a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1422a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr); 1423d7be54ccSKrishna Gudipati u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed); 1424d7be54ccSKrishna Gudipati 14255fbe25c7SJing Huang /* 1426a36c61f9SKrishna Gudipati * fcs_fdmi_sm FCS FDMI state machine 1427a36c61f9SKrishna Gudipati */ 1428a36c61f9SKrishna Gudipati 14295fbe25c7SJing Huang /* 1430a36c61f9SKrishna Gudipati * FDMI State Machine events 1431a36c61f9SKrishna Gudipati */ 1432a36c61f9SKrishna Gudipati enum port_fdmi_event { 1433a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_ONLINE = 1, 1434a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_OFFLINE = 2, 1435a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_OK = 4, 1436a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_ERROR = 5, 1437a36c61f9SKrishna Gudipati FDMISM_EVENT_TIMEOUT = 6, 1438a36c61f9SKrishna Gudipati FDMISM_EVENT_RHBA_SENT = 7, 1439a36c61f9SKrishna Gudipati FDMISM_EVENT_RPRT_SENT = 8, 1440a36c61f9SKrishna Gudipati FDMISM_EVENT_RPA_SENT = 9, 1441a36c61f9SKrishna Gudipati }; 1442a36c61f9SKrishna Gudipati 1443a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1444a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1445a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rhba( 1446a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1447a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1448a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1449a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1450a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba_retry( 1451a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1452a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1453a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rprt( 1454a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1455a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1456a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1457a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1458a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt_retry( 1459a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1460a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1461a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rpa( 1462a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1463a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1464a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1465a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1466a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa_retry( 1467a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1468a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1469a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1470a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1471a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_disabled( 1472a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1473a36c61f9SKrishna Gudipati enum port_fdmi_event event); 14745fbe25c7SJing Huang /* 1475a36c61f9SKrishna Gudipati * Start in offline state - awaiting MS to send start. 1476a36c61f9SKrishna Gudipati */ 1477a36c61f9SKrishna Gudipati static void 1478a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1479a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1480a36c61f9SKrishna Gudipati { 1481a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1482a36c61f9SKrishna Gudipati 1483a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1484a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1485a36c61f9SKrishna Gudipati 1486a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1487a36c61f9SKrishna Gudipati 1488a36c61f9SKrishna Gudipati switch (event) { 1489a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_ONLINE: 1490a36c61f9SKrishna Gudipati if (port->vport) { 1491a36c61f9SKrishna Gudipati /* 1492a36c61f9SKrishna Gudipati * For Vports, register a new port. 1493a36c61f9SKrishna Gudipati */ 1494a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1495a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt); 1496a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1497a36c61f9SKrishna Gudipati } else { 1498a36c61f9SKrishna Gudipati /* 1499a36c61f9SKrishna Gudipati * For a base port, we should first register the HBA 150025985edcSLucas De Marchi * attribute. The HBA attribute also contains the base 1501a36c61f9SKrishna Gudipati * port registration. 1502a36c61f9SKrishna Gudipati */ 1503a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1504a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba); 1505a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1506a36c61f9SKrishna Gudipati } 1507a36c61f9SKrishna Gudipati break; 1508a36c61f9SKrishna Gudipati 1509a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1510a36c61f9SKrishna Gudipati break; 1511a36c61f9SKrishna Gudipati 1512a36c61f9SKrishna Gudipati default: 1513a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1514a36c61f9SKrishna Gudipati } 1515a36c61f9SKrishna Gudipati } 1516a36c61f9SKrishna Gudipati 1517a36c61f9SKrishna Gudipati static void 1518a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1519a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1520a36c61f9SKrishna Gudipati { 1521a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1522a36c61f9SKrishna Gudipati 1523a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1524a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1525a36c61f9SKrishna Gudipati 1526a36c61f9SKrishna Gudipati switch (event) { 1527a36c61f9SKrishna Gudipati case FDMISM_EVENT_RHBA_SENT: 1528a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba); 1529a36c61f9SKrishna Gudipati break; 1530a36c61f9SKrishna Gudipati 1531a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1532a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1533a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1534a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1535a36c61f9SKrishna Gudipati break; 1536a36c61f9SKrishna Gudipati 1537a36c61f9SKrishna Gudipati default: 1538a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1539a36c61f9SKrishna Gudipati } 1540a36c61f9SKrishna Gudipati } 1541a36c61f9SKrishna Gudipati 1542a36c61f9SKrishna Gudipati static void 1543a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1544a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1545a36c61f9SKrishna Gudipati { 1546a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1547a36c61f9SKrishna Gudipati 1548a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1549a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1550a36c61f9SKrishna Gudipati 1551a36c61f9SKrishna Gudipati switch (event) { 1552a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1553a36c61f9SKrishna Gudipati /* 1554a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1555a36c61f9SKrishna Gudipati * delayed retry 1556a36c61f9SKrishna Gudipati */ 1557a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1558a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1559a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry); 1560a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1561a36c61f9SKrishna Gudipati &fdmi->timer, 1562a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1563a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1564a36c61f9SKrishna Gudipati } else { 1565a36c61f9SKrishna Gudipati /* 1566a36c61f9SKrishna Gudipati * set state to offline 1567a36c61f9SKrishna Gudipati */ 1568a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1569a36c61f9SKrishna Gudipati } 1570a36c61f9SKrishna Gudipati break; 1571a36c61f9SKrishna Gudipati 1572a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1573a36c61f9SKrishna Gudipati /* 1574a36c61f9SKrishna Gudipati * Initiate Register Port Attributes 1575a36c61f9SKrishna Gudipati */ 1576a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1577a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1578a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1579a36c61f9SKrishna Gudipati break; 1580a36c61f9SKrishna Gudipati 1581a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1582a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1583a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1584a36c61f9SKrishna Gudipati break; 1585a36c61f9SKrishna Gudipati 1586a36c61f9SKrishna Gudipati default: 1587a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1588a36c61f9SKrishna Gudipati } 1589a36c61f9SKrishna Gudipati } 1590a36c61f9SKrishna Gudipati 1591a36c61f9SKrishna Gudipati static void 1592a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1593a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1594a36c61f9SKrishna Gudipati { 1595a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1596a36c61f9SKrishna Gudipati 1597a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1598a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1599a36c61f9SKrishna Gudipati 1600a36c61f9SKrishna Gudipati switch (event) { 1601a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1602a36c61f9SKrishna Gudipati /* 1603a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1604a36c61f9SKrishna Gudipati */ 1605a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba); 1606a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1607a36c61f9SKrishna Gudipati break; 1608a36c61f9SKrishna Gudipati 1609a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1610a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1611a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1612a36c61f9SKrishna Gudipati break; 1613a36c61f9SKrishna Gudipati 1614a36c61f9SKrishna Gudipati default: 1615a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1616a36c61f9SKrishna Gudipati } 1617a36c61f9SKrishna Gudipati } 1618a36c61f9SKrishna Gudipati 1619a36c61f9SKrishna Gudipati /* 1620a36c61f9SKrishna Gudipati * RPRT : Register Port 1621a36c61f9SKrishna Gudipati */ 1622a36c61f9SKrishna Gudipati static void 1623a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1624a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1625a36c61f9SKrishna Gudipati { 1626a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1627a36c61f9SKrishna Gudipati 1628a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1629a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1630a36c61f9SKrishna Gudipati 1631a36c61f9SKrishna Gudipati switch (event) { 1632a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPRT_SENT: 1633a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt); 1634a36c61f9SKrishna Gudipati break; 1635a36c61f9SKrishna Gudipati 1636a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1637a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1638a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1639a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1640a36c61f9SKrishna Gudipati break; 1641a36c61f9SKrishna Gudipati 1642a36c61f9SKrishna Gudipati default: 1643a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1644a36c61f9SKrishna Gudipati } 1645a36c61f9SKrishna Gudipati } 1646a36c61f9SKrishna Gudipati 1647a36c61f9SKrishna Gudipati static void 1648a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1649a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1650a36c61f9SKrishna Gudipati { 1651a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1652a36c61f9SKrishna Gudipati 1653a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1654a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1655a36c61f9SKrishna Gudipati 1656a36c61f9SKrishna Gudipati switch (event) { 1657a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1658a36c61f9SKrishna Gudipati /* 1659a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1660a36c61f9SKrishna Gudipati * delayed retry 1661a36c61f9SKrishna Gudipati */ 1662a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1663a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1664a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry); 1665a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1666a36c61f9SKrishna Gudipati &fdmi->timer, 1667a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1668a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 16697725ccfdSJing Huang 16707725ccfdSJing Huang } else { 1671a36c61f9SKrishna Gudipati /* 1672a36c61f9SKrishna Gudipati * set state to offline 1673a36c61f9SKrishna Gudipati */ 1674a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1675a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 16767725ccfdSJing Huang } 1677a36c61f9SKrishna Gudipati break; 1678a36c61f9SKrishna Gudipati 1679a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1680a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1681a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1682a36c61f9SKrishna Gudipati break; 1683a36c61f9SKrishna Gudipati 1684a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1685a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1686a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1687a36c61f9SKrishna Gudipati break; 1688a36c61f9SKrishna Gudipati 1689a36c61f9SKrishna Gudipati default: 1690a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1691a36c61f9SKrishna Gudipati } 1692a36c61f9SKrishna Gudipati } 1693a36c61f9SKrishna Gudipati 1694a36c61f9SKrishna Gudipati static void 1695a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1696a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1697a36c61f9SKrishna Gudipati { 1698a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1699a36c61f9SKrishna Gudipati 1700a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1701a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1702a36c61f9SKrishna Gudipati 1703a36c61f9SKrishna Gudipati switch (event) { 1704a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1705a36c61f9SKrishna Gudipati /* 1706a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1707a36c61f9SKrishna Gudipati */ 1708a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt); 1709a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1710a36c61f9SKrishna Gudipati break; 1711a36c61f9SKrishna Gudipati 1712a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1713a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1714a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1715a36c61f9SKrishna Gudipati break; 1716a36c61f9SKrishna Gudipati 1717a36c61f9SKrishna Gudipati default: 1718a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1719a36c61f9SKrishna Gudipati } 1720a36c61f9SKrishna Gudipati } 1721a36c61f9SKrishna Gudipati 1722a36c61f9SKrishna Gudipati /* 1723a36c61f9SKrishna Gudipati * Register Port Attributes 1724a36c61f9SKrishna Gudipati */ 1725a36c61f9SKrishna Gudipati static void 1726a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1727a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1728a36c61f9SKrishna Gudipati { 1729a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1730a36c61f9SKrishna Gudipati 1731a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1732a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1733a36c61f9SKrishna Gudipati 1734a36c61f9SKrishna Gudipati switch (event) { 1735a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPA_SENT: 1736a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa); 1737a36c61f9SKrishna Gudipati break; 1738a36c61f9SKrishna Gudipati 1739a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1740a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1741a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1742a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1743a36c61f9SKrishna Gudipati break; 1744a36c61f9SKrishna Gudipati 1745a36c61f9SKrishna Gudipati default: 1746a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1747a36c61f9SKrishna Gudipati } 1748a36c61f9SKrishna Gudipati } 1749a36c61f9SKrishna Gudipati 1750a36c61f9SKrishna Gudipati static void 1751a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1752a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1753a36c61f9SKrishna Gudipati { 1754a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1755a36c61f9SKrishna Gudipati 1756a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1757a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1758a36c61f9SKrishna Gudipati 1759a36c61f9SKrishna Gudipati switch (event) { 1760a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1761a36c61f9SKrishna Gudipati /* 1762a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1763a36c61f9SKrishna Gudipati * delayed retry 1764a36c61f9SKrishna Gudipati */ 1765a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1766a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry); 1767a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1768a36c61f9SKrishna Gudipati &fdmi->timer, 1769a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1770a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1771a36c61f9SKrishna Gudipati } else { 1772a36c61f9SKrishna Gudipati /* 1773a36c61f9SKrishna Gudipati * set state to offline 1774a36c61f9SKrishna Gudipati */ 1775a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1776a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1777a36c61f9SKrishna Gudipati } 1778a36c61f9SKrishna Gudipati break; 1779a36c61f9SKrishna Gudipati 1780a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1781a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1782a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1783a36c61f9SKrishna Gudipati break; 1784a36c61f9SKrishna Gudipati 1785a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1786a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1787a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1788a36c61f9SKrishna Gudipati break; 1789a36c61f9SKrishna Gudipati 1790a36c61f9SKrishna Gudipati default: 1791a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1792a36c61f9SKrishna Gudipati } 1793a36c61f9SKrishna Gudipati } 1794a36c61f9SKrishna Gudipati 1795a36c61f9SKrishna Gudipati static void 1796a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1797a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1798a36c61f9SKrishna Gudipati { 1799a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1800a36c61f9SKrishna Gudipati 1801a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1802a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1803a36c61f9SKrishna Gudipati 1804a36c61f9SKrishna Gudipati switch (event) { 1805a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1806a36c61f9SKrishna Gudipati /* 1807a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1808a36c61f9SKrishna Gudipati */ 1809a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1810a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1811a36c61f9SKrishna Gudipati break; 1812a36c61f9SKrishna Gudipati 1813a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1814a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1815a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1816a36c61f9SKrishna Gudipati break; 1817a36c61f9SKrishna Gudipati 1818a36c61f9SKrishna Gudipati default: 1819a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1820a36c61f9SKrishna Gudipati } 1821a36c61f9SKrishna Gudipati } 1822a36c61f9SKrishna Gudipati 1823a36c61f9SKrishna Gudipati static void 1824a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1825a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1826a36c61f9SKrishna Gudipati { 1827a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1828a36c61f9SKrishna Gudipati 1829a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1830a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1831a36c61f9SKrishna Gudipati 1832a36c61f9SKrishna Gudipati switch (event) { 1833a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1834a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1835a36c61f9SKrishna Gudipati break; 1836a36c61f9SKrishna Gudipati 1837a36c61f9SKrishna Gudipati default: 1838a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1839a36c61f9SKrishna Gudipati } 1840a36c61f9SKrishna Gudipati } 18415fbe25c7SJing Huang /* 1842a36c61f9SKrishna Gudipati * FDMI is disabled state. 1843a36c61f9SKrishna Gudipati */ 1844a36c61f9SKrishna Gudipati static void 1845a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi, 1846a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1847a36c61f9SKrishna Gudipati { 1848a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1849a36c61f9SKrishna Gudipati 1850a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1851a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1852a36c61f9SKrishna Gudipati 1853a36c61f9SKrishna Gudipati /* No op State. It can only be enabled at Driver Init. */ 1854a36c61f9SKrishna Gudipati } 1855a36c61f9SKrishna Gudipati 18565fbe25c7SJing Huang /* 1857a36c61f9SKrishna Gudipati * RHBA : Register HBA Attributes. 1858a36c61f9SKrishna Gudipati */ 1859a36c61f9SKrishna Gudipati static void 1860a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1861a36c61f9SKrishna Gudipati { 1862a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1863a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1864a36c61f9SKrishna Gudipati struct fchs_s fchs; 1865a36c61f9SKrishna Gudipati int len, attr_len; 1866a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1867a36c61f9SKrishna Gudipati u8 *pyld; 1868a36c61f9SKrishna Gudipati 1869a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1870a36c61f9SKrishna Gudipati 1871c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1872c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 1873a36c61f9SKrishna Gudipati if (!fcxp) { 1874a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1875c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE); 1876a36c61f9SKrishna Gudipati return; 1877a36c61f9SKrishna Gudipati } 1878a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 1879a36c61f9SKrishna Gudipati 1880a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 18816a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 1882a36c61f9SKrishna Gudipati 1883a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1884a36c61f9SKrishna Gudipati FDMI_RHBA); 1885a36c61f9SKrishna Gudipati 1886a36c61f9SKrishna Gudipati attr_len = 1887a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi, 1888a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 1889a36c61f9SKrishna Gudipati + 1)); 1890a36c61f9SKrishna Gudipati 1891a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1892a36c61f9SKrishna Gudipati FC_CLASS_3, (len + attr_len), &fchs, 1893a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi, 1894a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 1895a36c61f9SKrishna Gudipati 1896a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); 1897a36c61f9SKrishna Gudipati } 1898a36c61f9SKrishna Gudipati 1899a36c61f9SKrishna Gudipati static u16 1900a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 1901a36c61f9SKrishna Gudipati { 1902a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1903a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s hba_attr; 1904a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; 1905a36c61f9SKrishna Gudipati struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; 1906a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 1907a36c61f9SKrishna Gudipati u8 *curr_ptr; 1908a36c61f9SKrishna Gudipati u16 len, count; 190950444a34SMaggie u16 templen; 1910a36c61f9SKrishna Gudipati 1911a36c61f9SKrishna Gudipati /* 1912a36c61f9SKrishna Gudipati * get hba attributes 1913a36c61f9SKrishna Gudipati */ 1914a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); 1915a36c61f9SKrishna Gudipati 1916a36c61f9SKrishna Gudipati rhba->hba_id = bfa_fcs_lport_get_pwwn(port); 1917ba816ea8SJing Huang rhba->port_list.num_ports = cpu_to_be32(1); 1918a36c61f9SKrishna Gudipati rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port); 1919a36c61f9SKrishna Gudipati 1920a36c61f9SKrishna Gudipati len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); 1921a36c61f9SKrishna Gudipati 1922a36c61f9SKrishna Gudipati count = 0; 1923a36c61f9SKrishna Gudipati len += sizeof(rhba->hba_attr_blk.attr_count); 1924a36c61f9SKrishna Gudipati 1925a36c61f9SKrishna Gudipati /* 1926a36c61f9SKrishna Gudipati * fill out the invididual entries of the HBA attrib Block 1927a36c61f9SKrishna Gudipati */ 1928a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; 1929a36c61f9SKrishna Gudipati 1930a36c61f9SKrishna Gudipati /* 1931a36c61f9SKrishna Gudipati * Node Name 1932a36c61f9SKrishna Gudipati */ 1933a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1934ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME); 193550444a34SMaggie templen = sizeof(wwn_t); 193650444a34SMaggie memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen); 193750444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 193850444a34SMaggie len += templen; 1939a36c61f9SKrishna Gudipati count++; 194050444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 194150444a34SMaggie sizeof(templen)); 1942a36c61f9SKrishna Gudipati 1943a36c61f9SKrishna Gudipati /* 1944a36c61f9SKrishna Gudipati * Manufacturer 1945a36c61f9SKrishna Gudipati */ 1946a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1947ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER); 194850444a34SMaggie templen = (u16) strlen(fcs_hba_attr->manufacturer); 194950444a34SMaggie memcpy(attr->value, fcs_hba_attr->manufacturer, templen); 195050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 195150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 195250444a34SMaggie len += templen; 1953a36c61f9SKrishna Gudipati count++; 195450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 195550444a34SMaggie sizeof(templen)); 1956a36c61f9SKrishna Gudipati 1957a36c61f9SKrishna Gudipati /* 1958a36c61f9SKrishna Gudipati * Serial Number 1959a36c61f9SKrishna Gudipati */ 1960a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1961ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM); 196250444a34SMaggie templen = (u16) strlen(fcs_hba_attr->serial_num); 196350444a34SMaggie memcpy(attr->value, fcs_hba_attr->serial_num, templen); 196450444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 196550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 196650444a34SMaggie len += templen; 1967a36c61f9SKrishna Gudipati count++; 196850444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 196950444a34SMaggie sizeof(templen)); 1970a36c61f9SKrishna Gudipati 1971a36c61f9SKrishna Gudipati /* 1972a36c61f9SKrishna Gudipati * Model 1973a36c61f9SKrishna Gudipati */ 1974a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1975ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL); 197650444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model); 197750444a34SMaggie memcpy(attr->value, fcs_hba_attr->model, templen); 197850444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 197950444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 198050444a34SMaggie len += templen; 1981a36c61f9SKrishna Gudipati count++; 198250444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 198350444a34SMaggie sizeof(templen)); 1984a36c61f9SKrishna Gudipati 1985a36c61f9SKrishna Gudipati /* 1986a36c61f9SKrishna Gudipati * Model Desc 1987a36c61f9SKrishna Gudipati */ 1988a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1989ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC); 199050444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model_desc); 199150444a34SMaggie memcpy(attr->value, fcs_hba_attr->model_desc, templen); 199250444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 199350444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 199450444a34SMaggie len += templen; 1995a36c61f9SKrishna Gudipati count++; 199650444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 199750444a34SMaggie sizeof(templen)); 1998a36c61f9SKrishna Gudipati 1999a36c61f9SKrishna Gudipati /* 2000a36c61f9SKrishna Gudipati * H/W Version 2001a36c61f9SKrishna Gudipati */ 2002a36c61f9SKrishna Gudipati if (fcs_hba_attr->hw_version[0] != '\0') { 2003a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2004ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION); 200550444a34SMaggie templen = (u16) strlen(fcs_hba_attr->hw_version); 200650444a34SMaggie memcpy(attr->value, fcs_hba_attr->hw_version, templen); 200750444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 200850444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 200950444a34SMaggie len += templen; 2010a36c61f9SKrishna Gudipati count++; 201150444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 201250444a34SMaggie sizeof(templen)); 2013a36c61f9SKrishna Gudipati } 2014a36c61f9SKrishna Gudipati 2015a36c61f9SKrishna Gudipati /* 2016a36c61f9SKrishna Gudipati * Driver Version 2017a36c61f9SKrishna Gudipati */ 2018a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2019ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION); 202050444a34SMaggie templen = (u16) strlen(fcs_hba_attr->driver_version); 202150444a34SMaggie memcpy(attr->value, fcs_hba_attr->driver_version, templen); 202250444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 202350444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2024dd5aaf45SKrishna Gudipati len += templen; 2025a36c61f9SKrishna Gudipati count++; 202650444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 202750444a34SMaggie sizeof(templen)); 2028a36c61f9SKrishna Gudipati 2029a36c61f9SKrishna Gudipati /* 2030a36c61f9SKrishna Gudipati * Option Rom Version 2031a36c61f9SKrishna Gudipati */ 2032a36c61f9SKrishna Gudipati if (fcs_hba_attr->option_rom_ver[0] != '\0') { 2033a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2034ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION); 203550444a34SMaggie templen = (u16) strlen(fcs_hba_attr->option_rom_ver); 203650444a34SMaggie memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen); 203750444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 203850444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 203950444a34SMaggie len += templen; 2040a36c61f9SKrishna Gudipati count++; 204150444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 204250444a34SMaggie sizeof(templen)); 2043a36c61f9SKrishna Gudipati } 2044a36c61f9SKrishna Gudipati 2045a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2046ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); 2047b480a32eSKrishna Gudipati templen = (u16) strlen(fcs_hba_attr->fw_version); 2048b480a32eSKrishna Gudipati memcpy(attr->value, fcs_hba_attr->fw_version, templen); 204950444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 205050444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 205150444a34SMaggie len += templen; 2052a36c61f9SKrishna Gudipati count++; 205350444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 205450444a34SMaggie sizeof(templen)); 2055a36c61f9SKrishna Gudipati 2056a36c61f9SKrishna Gudipati /* 2057a36c61f9SKrishna Gudipati * OS Name 2058a36c61f9SKrishna Gudipati */ 2059a36c61f9SKrishna Gudipati if (fcs_hba_attr->os_name[0] != '\0') { 2060a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2061ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME); 206250444a34SMaggie templen = (u16) strlen(fcs_hba_attr->os_name); 206350444a34SMaggie memcpy(attr->value, fcs_hba_attr->os_name, templen); 206450444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 206550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 206650444a34SMaggie len += templen; 2067a36c61f9SKrishna Gudipati count++; 206850444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 206950444a34SMaggie sizeof(templen)); 2070a36c61f9SKrishna Gudipati } 2071a36c61f9SKrishna Gudipati 2072a36c61f9SKrishna Gudipati /* 2073a36c61f9SKrishna Gudipati * MAX_CT_PAYLOAD 2074a36c61f9SKrishna Gudipati */ 2075a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2076ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); 207750444a34SMaggie templen = sizeof(fcs_hba_attr->max_ct_pyld); 207850444a34SMaggie memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen); 2079d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2080d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 208150444a34SMaggie len += templen; 2082a36c61f9SKrishna Gudipati count++; 208350444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 208450444a34SMaggie sizeof(templen)); 2085d7cbc304SVijaya Mohan Guvva /* 2086d7cbc304SVijaya Mohan Guvva * Send extended attributes ( FOS 7.1 support ) 2087d7cbc304SVijaya Mohan Guvva */ 2088d7cbc304SVijaya Mohan Guvva if (fdmi->retry_cnt == 0) { 2089d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2090d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODE_SYM_NAME); 2091d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->node_sym_name); 2092d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->node_sym_name, templen); 2093d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2094d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2095d7cbc304SVijaya Mohan Guvva len += templen; 2096d7cbc304SVijaya Mohan Guvva count++; 2097d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2098d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2099d7cbc304SVijaya Mohan Guvva 2100d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2101d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_VENDOR_ID); 2102d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->vendor_info); 2103d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->vendor_info, templen); 2104d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2105d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2106d7cbc304SVijaya Mohan Guvva len += templen; 2107d7cbc304SVijaya Mohan Guvva count++; 2108d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2109d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2110d7cbc304SVijaya Mohan Guvva 2111d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2112d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NUM_PORTS); 2113d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->num_ports); 2114d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->num_ports, templen); 2115d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2116d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2117d7cbc304SVijaya Mohan Guvva len += templen; 2118d7cbc304SVijaya Mohan Guvva count++; 2119d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2120d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2121d7cbc304SVijaya Mohan Guvva 2122d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2123d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FABRIC_NAME); 2124d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->fabric_name); 2125d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->fabric_name, templen); 2126d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2127d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2128d7cbc304SVijaya Mohan Guvva len += templen; 2129d7cbc304SVijaya Mohan Guvva count++; 2130d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2131d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2132d7cbc304SVijaya Mohan Guvva 2133d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2134d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_BIOS_VER); 2135d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->bios_ver); 2136d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->bios_ver, templen); 2137d7cbc304SVijaya Mohan Guvva templen = fc_roundup(attr->len, sizeof(u32)); 2138d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2139d7cbc304SVijaya Mohan Guvva len += templen; 2140d7cbc304SVijaya Mohan Guvva count++; 2141d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2142d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2143d7cbc304SVijaya Mohan Guvva } 2144a36c61f9SKrishna Gudipati 2145a36c61f9SKrishna Gudipati /* 2146a36c61f9SKrishna Gudipati * Update size of payload 2147a36c61f9SKrishna Gudipati */ 21485fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 2149a36c61f9SKrishna Gudipati 2150ba816ea8SJing Huang rhba->hba_attr_blk.attr_count = cpu_to_be32(count); 2151a36c61f9SKrishna Gudipati return len; 2152a36c61f9SKrishna Gudipati } 2153a36c61f9SKrishna Gudipati 2154a36c61f9SKrishna Gudipati static void 2155a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2156a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2157a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2158a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2159a36c61f9SKrishna Gudipati { 2160a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2161a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2162a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2163a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2164a36c61f9SKrishna Gudipati 2165a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2166a36c61f9SKrishna Gudipati 2167a36c61f9SKrishna Gudipati /* 2168a36c61f9SKrishna Gudipati * Sanity Checks 2169a36c61f9SKrishna Gudipati */ 2170a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2171a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2172a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2173a36c61f9SKrishna Gudipati return; 2174a36c61f9SKrishna Gudipati } 2175a36c61f9SKrishna Gudipati 2176a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2177ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2178a36c61f9SKrishna Gudipati 2179a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2180a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2181a36c61f9SKrishna Gudipati return; 2182a36c61f9SKrishna Gudipati } 2183a36c61f9SKrishna Gudipati 2184a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2185a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2186a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2187a36c61f9SKrishna Gudipati } 2188a36c61f9SKrishna Gudipati 21895fbe25c7SJing Huang /* 2190a36c61f9SKrishna Gudipati * RPRT : Register Port 2191a36c61f9SKrishna Gudipati */ 2192a36c61f9SKrishna Gudipati static void 2193a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2194a36c61f9SKrishna Gudipati { 2195a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2196a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2197a36c61f9SKrishna Gudipati struct fchs_s fchs; 2198a36c61f9SKrishna Gudipati u16 len, attr_len; 2199a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2200a36c61f9SKrishna Gudipati u8 *pyld; 2201a36c61f9SKrishna Gudipati 2202a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2203a36c61f9SKrishna Gudipati 2204c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 2205c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 2206a36c61f9SKrishna Gudipati if (!fcxp) { 2207a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2208c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE); 2209a36c61f9SKrishna Gudipati return; 2210a36c61f9SKrishna Gudipati } 2211a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2212a36c61f9SKrishna Gudipati 2213a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 22146a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2215a36c61f9SKrishna Gudipati 2216a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2217a36c61f9SKrishna Gudipati FDMI_RPRT); 2218a36c61f9SKrishna Gudipati 2219a36c61f9SKrishna Gudipati attr_len = 2220a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi, 2221a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 2222a36c61f9SKrishna Gudipati + 1)); 2223a36c61f9SKrishna Gudipati 2224a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2225a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2226a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi, 2227a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2228a36c61f9SKrishna Gudipati 2229a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); 2230a36c61f9SKrishna Gudipati } 2231a36c61f9SKrishna Gudipati 22325fbe25c7SJing Huang /* 2233a36c61f9SKrishna Gudipati * This routine builds Port Attribute Block that used in RPA, RPRT commands. 2234a36c61f9SKrishna Gudipati */ 2235a36c61f9SKrishna Gudipati static u16 2236a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi, 2237a36c61f9SKrishna Gudipati u8 *pyld) 2238a36c61f9SKrishna Gudipati { 2239a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 2240a36c61f9SKrishna Gudipati struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; 2241a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 2242a36c61f9SKrishna Gudipati u8 *curr_ptr; 2243a36c61f9SKrishna Gudipati u16 len; 2244a36c61f9SKrishna Gudipati u8 count = 0; 224550444a34SMaggie u16 templen; 2246a36c61f9SKrishna Gudipati 2247a36c61f9SKrishna Gudipati /* 2248a36c61f9SKrishna Gudipati * get port attributes 2249a36c61f9SKrishna Gudipati */ 2250a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 2251a36c61f9SKrishna Gudipati 2252a36c61f9SKrishna Gudipati len = sizeof(port_attrib->attr_count); 2253a36c61f9SKrishna Gudipati 2254a36c61f9SKrishna Gudipati /* 2255a36c61f9SKrishna Gudipati * fill out the invididual entries 2256a36c61f9SKrishna Gudipati */ 2257a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &port_attrib->port_attr; 2258a36c61f9SKrishna Gudipati 2259a36c61f9SKrishna Gudipati /* 2260a36c61f9SKrishna Gudipati * FC4 Types 2261a36c61f9SKrishna Gudipati */ 2262a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2263ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES); 226450444a34SMaggie templen = sizeof(fcs_port_attr.supp_fc4_types); 226550444a34SMaggie memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen); 226650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 226750444a34SMaggie len += templen; 2268a36c61f9SKrishna Gudipati ++count; 2269a36c61f9SKrishna Gudipati attr->len = 227050444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 227150444a34SMaggie sizeof(templen)); 2272a36c61f9SKrishna Gudipati 2273a36c61f9SKrishna Gudipati /* 2274a36c61f9SKrishna Gudipati * Supported Speed 2275a36c61f9SKrishna Gudipati */ 2276a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2277ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED); 227850444a34SMaggie templen = sizeof(fcs_port_attr.supp_speed); 227950444a34SMaggie memcpy(attr->value, &fcs_port_attr.supp_speed, templen); 228050444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 228150444a34SMaggie len += templen; 2282a36c61f9SKrishna Gudipati ++count; 2283a36c61f9SKrishna Gudipati attr->len = 228450444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 228550444a34SMaggie sizeof(templen)); 2286a36c61f9SKrishna Gudipati 2287a36c61f9SKrishna Gudipati /* 2288a36c61f9SKrishna Gudipati * current Port Speed 2289a36c61f9SKrishna Gudipati */ 2290a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2291ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED); 229250444a34SMaggie templen = sizeof(fcs_port_attr.curr_speed); 229350444a34SMaggie memcpy(attr->value, &fcs_port_attr.curr_speed, templen); 229450444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 229550444a34SMaggie len += templen; 2296a36c61f9SKrishna Gudipati ++count; 229750444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 229850444a34SMaggie sizeof(templen)); 2299a36c61f9SKrishna Gudipati 2300a36c61f9SKrishna Gudipati /* 2301a36c61f9SKrishna Gudipati * max frame size 2302a36c61f9SKrishna Gudipati */ 2303a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2304ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE); 230550444a34SMaggie templen = sizeof(fcs_port_attr.max_frm_size); 230650444a34SMaggie memcpy(attr->value, &fcs_port_attr.max_frm_size, templen); 230750444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 230850444a34SMaggie len += templen; 2309a36c61f9SKrishna Gudipati ++count; 231050444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 231150444a34SMaggie sizeof(templen)); 2312a36c61f9SKrishna Gudipati 2313a36c61f9SKrishna Gudipati /* 2314a36c61f9SKrishna Gudipati * OS Device Name 2315a36c61f9SKrishna Gudipati */ 2316a36c61f9SKrishna Gudipati if (fcs_port_attr.os_device_name[0] != '\0') { 2317a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2318ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME); 231950444a34SMaggie templen = (u16) strlen(fcs_port_attr.os_device_name); 232050444a34SMaggie memcpy(attr->value, fcs_port_attr.os_device_name, templen); 232150444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 232250444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 232350444a34SMaggie len += templen; 2324a36c61f9SKrishna Gudipati ++count; 232550444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 232650444a34SMaggie sizeof(templen)); 2327a36c61f9SKrishna Gudipati } 2328a36c61f9SKrishna Gudipati /* 2329a36c61f9SKrishna Gudipati * Host Name 2330a36c61f9SKrishna Gudipati */ 2331a36c61f9SKrishna Gudipati if (fcs_port_attr.host_name[0] != '\0') { 2332a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2333ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME); 233450444a34SMaggie templen = (u16) strlen(fcs_port_attr.host_name); 233550444a34SMaggie memcpy(attr->value, fcs_port_attr.host_name, templen); 233650444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 233750444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 233850444a34SMaggie len += templen; 2339a36c61f9SKrishna Gudipati ++count; 234050444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 234150444a34SMaggie sizeof(templen)); 2342a36c61f9SKrishna Gudipati } 2343a36c61f9SKrishna Gudipati 2344d7cbc304SVijaya Mohan Guvva if (fdmi->retry_cnt == 0) { 2345d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2346d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_NODE_NAME); 2347d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.node_name); 2348d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.node_name, templen); 2349d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2350d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2351d7cbc304SVijaya Mohan Guvva len += templen; 2352d7cbc304SVijaya Mohan Guvva ++count; 2353d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2354d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2355d7cbc304SVijaya Mohan Guvva 2356d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2357d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NAME); 2358d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_name); 2359d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_name, templen); 2360d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2361d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(attr->len) + templen; 2362d7cbc304SVijaya Mohan Guvva len += templen; 2363d7cbc304SVijaya Mohan Guvva ++count; 2364d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2365d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2366d7cbc304SVijaya Mohan Guvva 2367d7cbc304SVijaya Mohan Guvva if (fcs_port_attr.port_sym_name.symname[0] != '\0') { 2368d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2369d7cbc304SVijaya Mohan Guvva attr->type = 2370d7cbc304SVijaya Mohan Guvva cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SYM_NAME); 2371d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_sym_name); 2372d7cbc304SVijaya Mohan Guvva memcpy(attr->value, 2373d7cbc304SVijaya Mohan Guvva &fcs_port_attr.port_sym_name, templen); 2374d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2375d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + 2376d7cbc304SVijaya Mohan Guvva sizeof(templen) + templen; 2377d7cbc304SVijaya Mohan Guvva len += templen; 2378d7cbc304SVijaya Mohan Guvva ++count; 2379d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + 2380d7cbc304SVijaya Mohan Guvva sizeof(attr->type) + sizeof(templen)); 2381d7cbc304SVijaya Mohan Guvva } 2382d7cbc304SVijaya Mohan Guvva 2383d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2384d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_TYPE); 2385d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_type); 2386d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_type, templen); 2387d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2388d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2389d7cbc304SVijaya Mohan Guvva len += templen; 2390d7cbc304SVijaya Mohan Guvva ++count; 2391d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2392d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2393d7cbc304SVijaya Mohan Guvva 2394d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2395d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_COS); 2396d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.scos); 2397d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.scos, templen); 2398d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2399d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2400d7cbc304SVijaya Mohan Guvva len += templen; 2401d7cbc304SVijaya Mohan Guvva ++count; 2402d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2403d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2404d7cbc304SVijaya Mohan Guvva 2405d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2406d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FAB_NAME); 2407d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_fabric_name); 2408d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_fabric_name, templen); 2409d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2410d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2411d7cbc304SVijaya Mohan Guvva len += templen; 2412d7cbc304SVijaya Mohan Guvva ++count; 2413d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2414d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2415d7cbc304SVijaya Mohan Guvva 2416d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2417d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FC4_TYPE); 2418d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_act_fc4_type); 2419d7cbc304SVijaya Mohan Guvva memcpy(attr->value, fcs_port_attr.port_act_fc4_type, 2420d7cbc304SVijaya Mohan Guvva templen); 2421d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2422d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2423d7cbc304SVijaya Mohan Guvva len += templen; 2424d7cbc304SVijaya Mohan Guvva ++count; 2425d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2426d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2427d7cbc304SVijaya Mohan Guvva 2428d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2429d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_STATE); 2430d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_state); 2431d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_state, templen); 2432d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2433d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2434d7cbc304SVijaya Mohan Guvva len += templen; 2435d7cbc304SVijaya Mohan Guvva ++count; 2436d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2437d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2438d7cbc304SVijaya Mohan Guvva 2439d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2440d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NUM_RPRT); 2441d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.num_ports); 2442d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.num_ports, templen); 2443d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2444d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2445d7cbc304SVijaya Mohan Guvva len += templen; 2446d7cbc304SVijaya Mohan Guvva ++count; 2447d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2448d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2449d7cbc304SVijaya Mohan Guvva } 2450d7cbc304SVijaya Mohan Guvva 2451a36c61f9SKrishna Gudipati /* 2452a36c61f9SKrishna Gudipati * Update size of payload 2453a36c61f9SKrishna Gudipati */ 2454ba816ea8SJing Huang port_attrib->attr_count = cpu_to_be32(count); 24555fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 2456a36c61f9SKrishna Gudipati return len; 2457a36c61f9SKrishna Gudipati } 2458a36c61f9SKrishna Gudipati 2459a36c61f9SKrishna Gudipati static u16 2460a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2461a36c61f9SKrishna Gudipati { 2462a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2463a36c61f9SKrishna Gudipati struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; 2464a36c61f9SKrishna Gudipati u16 len; 2465a36c61f9SKrishna Gudipati 2466a36c61f9SKrishna Gudipati rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs)); 2467a36c61f9SKrishna Gudipati rprt->port_name = bfa_fcs_lport_get_pwwn(port); 2468a36c61f9SKrishna Gudipati 2469a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2470a36c61f9SKrishna Gudipati (u8 *) &rprt->port_attr_blk); 2471a36c61f9SKrishna Gudipati 2472a36c61f9SKrishna Gudipati len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); 2473a36c61f9SKrishna Gudipati 2474a36c61f9SKrishna Gudipati return len; 2475a36c61f9SKrishna Gudipati } 2476a36c61f9SKrishna Gudipati 2477a36c61f9SKrishna Gudipati static void 2478a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2479a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2480a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2481a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2482a36c61f9SKrishna Gudipati { 2483a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2484a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2485a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2486a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2487a36c61f9SKrishna Gudipati 2488a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2489a36c61f9SKrishna Gudipati 2490a36c61f9SKrishna Gudipati /* 2491a36c61f9SKrishna Gudipati * Sanity Checks 2492a36c61f9SKrishna Gudipati */ 2493a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2494a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2495a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2496a36c61f9SKrishna Gudipati return; 2497a36c61f9SKrishna Gudipati } 2498a36c61f9SKrishna Gudipati 2499a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2500ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2501a36c61f9SKrishna Gudipati 2502a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2503a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2504a36c61f9SKrishna Gudipati return; 2505a36c61f9SKrishna Gudipati } 2506a36c61f9SKrishna Gudipati 2507a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2508a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2509a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2510a36c61f9SKrishna Gudipati } 2511a36c61f9SKrishna Gudipati 25125fbe25c7SJing Huang /* 2513a36c61f9SKrishna Gudipati * RPA : Register Port Attributes. 2514a36c61f9SKrishna Gudipati */ 2515a36c61f9SKrishna Gudipati static void 2516a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2517a36c61f9SKrishna Gudipati { 2518a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2519a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2520a36c61f9SKrishna Gudipati struct fchs_s fchs; 2521a36c61f9SKrishna Gudipati u16 len, attr_len; 2522a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2523a36c61f9SKrishna Gudipati u8 *pyld; 2524a36c61f9SKrishna Gudipati 2525a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2526a36c61f9SKrishna Gudipati 2527c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 2528c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 2529a36c61f9SKrishna Gudipati if (!fcxp) { 2530a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2531c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE); 2532a36c61f9SKrishna Gudipati return; 2533a36c61f9SKrishna Gudipati } 2534a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2535a36c61f9SKrishna Gudipati 2536a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 25376a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2538a36c61f9SKrishna Gudipati 2539a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2540a36c61f9SKrishna Gudipati FDMI_RPA); 2541a36c61f9SKrishna Gudipati 25425fbe25c7SJing Huang attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi, 25435fbe25c7SJing Huang (u8 *) ((struct ct_hdr_s *) pyld + 1)); 2544a36c61f9SKrishna Gudipati 2545a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2546a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2547a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi, 2548a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2549a36c61f9SKrishna Gudipati 2550a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); 2551a36c61f9SKrishna Gudipati } 2552a36c61f9SKrishna Gudipati 2553a36c61f9SKrishna Gudipati static u16 2554a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2555a36c61f9SKrishna Gudipati { 2556a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2557a36c61f9SKrishna Gudipati struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; 2558a36c61f9SKrishna Gudipati u16 len; 2559a36c61f9SKrishna Gudipati 2560a36c61f9SKrishna Gudipati rpa->port_name = bfa_fcs_lport_get_pwwn(port); 2561a36c61f9SKrishna Gudipati 2562a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2563a36c61f9SKrishna Gudipati (u8 *) &rpa->port_attr_blk); 2564a36c61f9SKrishna Gudipati 2565a36c61f9SKrishna Gudipati len += sizeof(rpa->port_name); 2566a36c61f9SKrishna Gudipati 2567a36c61f9SKrishna Gudipati return len; 2568a36c61f9SKrishna Gudipati } 2569a36c61f9SKrishna Gudipati 2570a36c61f9SKrishna Gudipati static void 2571a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2572a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 2573a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 2574a36c61f9SKrishna Gudipati { 2575a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2576a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2577a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2578a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2579a36c61f9SKrishna Gudipati 2580a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2581a36c61f9SKrishna Gudipati 2582a36c61f9SKrishna Gudipati /* 2583a36c61f9SKrishna Gudipati * Sanity Checks 2584a36c61f9SKrishna Gudipati */ 2585a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2586a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2587a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2588a36c61f9SKrishna Gudipati return; 2589a36c61f9SKrishna Gudipati } 2590a36c61f9SKrishna Gudipati 2591a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2592ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2593a36c61f9SKrishna Gudipati 2594a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2595a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2596a36c61f9SKrishna Gudipati return; 2597a36c61f9SKrishna Gudipati } 2598a36c61f9SKrishna Gudipati 2599a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2600a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2601a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2602a36c61f9SKrishna Gudipati } 2603a36c61f9SKrishna Gudipati 2604a36c61f9SKrishna Gudipati static void 2605a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg) 2606a36c61f9SKrishna Gudipati { 2607a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg; 2608a36c61f9SKrishna Gudipati 2609a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); 2610a36c61f9SKrishna Gudipati } 2611a36c61f9SKrishna Gudipati 261252f94b6fSMaggie static void 2613a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2614a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr) 2615a36c61f9SKrishna Gudipati { 2616a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2617a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2618b480a32eSKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 2619a36c61f9SKrishna Gudipati 26206a18b167SJing Huang memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 2621a36c61f9SKrishna Gudipati 2622a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, 2623a36c61f9SKrishna Gudipati hba_attr->manufacturer); 2624a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, 2625a36c61f9SKrishna Gudipati hba_attr->serial_num); 2626a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2627a36c61f9SKrishna Gudipati hba_attr->model); 2628a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2629a36c61f9SKrishna Gudipati hba_attr->model_desc); 2630a36c61f9SKrishna Gudipati bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, 2631a36c61f9SKrishna Gudipati hba_attr->hw_version); 2632a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, 2633a36c61f9SKrishna Gudipati hba_attr->option_rom_ver); 2634a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, 2635a36c61f9SKrishna Gudipati hba_attr->fw_version); 2636a36c61f9SKrishna Gudipati 26378c5a50e8SArnd Bergmann strlcpy(hba_attr->driver_version, (char *)driver_info->version, 2638a36c61f9SKrishna Gudipati sizeof(hba_attr->driver_version)); 2639a36c61f9SKrishna Gudipati 26408c5a50e8SArnd Bergmann strlcpy(hba_attr->os_name, driver_info->host_os_name, 2641a36c61f9SKrishna Gudipati sizeof(hba_attr->os_name)); 2642a36c61f9SKrishna Gudipati 2643a36c61f9SKrishna Gudipati /* 2644a36c61f9SKrishna Gudipati * If there is a patch level, append it 2645a36c61f9SKrishna Gudipati * to the os name along with a separator 2646a36c61f9SKrishna Gudipati */ 2647a36c61f9SKrishna Gudipati if (driver_info->host_os_patch[0] != '\0') { 26488c5a50e8SArnd Bergmann strlcat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 26498c5a50e8SArnd Bergmann sizeof(hba_attr->os_name)); 26508c5a50e8SArnd Bergmann strlcat(hba_attr->os_name, driver_info->host_os_patch, 26518c5a50e8SArnd Bergmann sizeof(hba_attr->os_name)); 2652a36c61f9SKrishna Gudipati } 2653a36c61f9SKrishna Gudipati 2654b480a32eSKrishna Gudipati /* Retrieve the max frame size from the port attr */ 2655b480a32eSKrishna Gudipati bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 2656b480a32eSKrishna Gudipati hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size; 2657d7cbc304SVijaya Mohan Guvva 26588c5a50e8SArnd Bergmann strlcpy(hba_attr->node_sym_name.symname, 2659d7cbc304SVijaya Mohan Guvva port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); 266031e1d569SAnil Gurumurthy strcpy(hba_attr->vendor_info, "QLogic"); 2661d7cbc304SVijaya Mohan Guvva hba_attr->num_ports = 2662d7cbc304SVijaya Mohan Guvva cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); 2663d7cbc304SVijaya Mohan Guvva hba_attr->fabric_name = port->fabric->lps->pr_nwwn; 26648c5a50e8SArnd Bergmann strlcpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); 2665d7cbc304SVijaya Mohan Guvva 2666a36c61f9SKrishna Gudipati } 2667a36c61f9SKrishna Gudipati 266852f94b6fSMaggie static void 2669a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2670a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr) 2671a36c61f9SKrishna Gudipati { 2672a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2673a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2674a36c61f9SKrishna Gudipati struct bfa_port_attr_s pport_attr; 2675d7cbc304SVijaya Mohan Guvva struct bfa_lport_attr_s lport_attr; 2676a36c61f9SKrishna Gudipati 26776a18b167SJing Huang memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); 2678a36c61f9SKrishna Gudipati 2679a36c61f9SKrishna Gudipati /* 2680a36c61f9SKrishna Gudipati * get pport attributes from hal 2681a36c61f9SKrishna Gudipati */ 2682a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 2683a36c61f9SKrishna Gudipati 2684a36c61f9SKrishna Gudipati /* 2685a36c61f9SKrishna Gudipati * get FC4 type Bitmask 2686a36c61f9SKrishna Gudipati */ 2687a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); 2688a36c61f9SKrishna Gudipati 2689a36c61f9SKrishna Gudipati /* 2690a36c61f9SKrishna Gudipati * Supported Speeds 2691a36c61f9SKrishna Gudipati */ 2692d7be54ccSKrishna Gudipati switch (pport_attr.speed_supported) { 2693d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2694d7be54ccSKrishna Gudipati port_attr->supp_speed = 2695d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G); 2696d7be54ccSKrishna Gudipati break; 2697d7be54ccSKrishna Gudipati 2698d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2699d7be54ccSKrishna Gudipati port_attr->supp_speed = 2700d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G); 2701d7be54ccSKrishna Gudipati break; 2702d7be54ccSKrishna Gudipati 2703d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2704d7be54ccSKrishna Gudipati port_attr->supp_speed = 2705d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G); 2706d7be54ccSKrishna Gudipati break; 2707d7be54ccSKrishna Gudipati 2708d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2709d7be54ccSKrishna Gudipati port_attr->supp_speed = 2710d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G); 2711d7be54ccSKrishna Gudipati break; 2712d7be54ccSKrishna Gudipati 2713d7be54ccSKrishna Gudipati default: 2714d7be54ccSKrishna Gudipati bfa_sm_fault(port->fcs, pport_attr.speed_supported); 2715d7be54ccSKrishna Gudipati } 2716a36c61f9SKrishna Gudipati 2717a36c61f9SKrishna Gudipati /* 2718a36c61f9SKrishna Gudipati * Current Speed 2719a36c61f9SKrishna Gudipati */ 2720d7be54ccSKrishna Gudipati port_attr->curr_speed = cpu_to_be32( 2721d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(pport_attr.speed)); 2722a36c61f9SKrishna Gudipati 2723a36c61f9SKrishna Gudipati /* 2724a36c61f9SKrishna Gudipati * Max PDU Size. 2725a36c61f9SKrishna Gudipati */ 2726b480a32eSKrishna Gudipati port_attr->max_frm_size = cpu_to_be32(pport_attr.pport_cfg.maxfrsize); 2727a36c61f9SKrishna Gudipati 2728a36c61f9SKrishna Gudipati /* 2729a36c61f9SKrishna Gudipati * OS device Name 2730a36c61f9SKrishna Gudipati */ 27318c5a50e8SArnd Bergmann strlcpy(port_attr->os_device_name, driver_info->os_device_name, 2732a36c61f9SKrishna Gudipati sizeof(port_attr->os_device_name)); 2733a36c61f9SKrishna Gudipati 2734a36c61f9SKrishna Gudipati /* 2735a36c61f9SKrishna Gudipati * Host name 2736a36c61f9SKrishna Gudipati */ 27378c5a50e8SArnd Bergmann strlcpy(port_attr->host_name, driver_info->host_machine_name, 2738a36c61f9SKrishna Gudipati sizeof(port_attr->host_name)); 27397725ccfdSJing Huang 2740d7cbc304SVijaya Mohan Guvva port_attr->node_name = bfa_fcs_lport_get_nwwn(port); 2741d7cbc304SVijaya Mohan Guvva port_attr->port_name = bfa_fcs_lport_get_pwwn(port); 2742d7cbc304SVijaya Mohan Guvva 27438c5a50e8SArnd Bergmann strlcpy(port_attr->port_sym_name.symname, 27448c5a50e8SArnd Bergmann bfa_fcs_lport_get_psym_name(port).symname, BFA_SYMNAME_MAXLEN); 2745d7cbc304SVijaya Mohan Guvva bfa_fcs_lport_get_attr(port, &lport_attr); 2746d7cbc304SVijaya Mohan Guvva port_attr->port_type = cpu_to_be32(lport_attr.port_type); 2747d7cbc304SVijaya Mohan Guvva port_attr->scos = pport_attr.cos_supported; 2748d7cbc304SVijaya Mohan Guvva port_attr->port_fabric_name = port->fabric->lps->pr_nwwn; 2749d7cbc304SVijaya Mohan Guvva fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->port_act_fc4_type); 2750d7cbc304SVijaya Mohan Guvva port_attr->port_state = cpu_to_be32(pport_attr.port_state); 2751d7cbc304SVijaya Mohan Guvva port_attr->num_ports = cpu_to_be32(port->num_rports); 27527725ccfdSJing Huang } 27537725ccfdSJing Huang 2754d7be54ccSKrishna Gudipati /* 2755d7be54ccSKrishna Gudipati * Convert BFA speed to FDMI format. 2756d7be54ccSKrishna Gudipati */ 2757d7be54ccSKrishna Gudipati u32 2758d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed) 2759d7be54ccSKrishna Gudipati { 2760d7be54ccSKrishna Gudipati u32 ret; 2761d7be54ccSKrishna Gudipati 2762d7be54ccSKrishna Gudipati switch (pport_speed) { 2763d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_1GBPS: 2764d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_2GBPS: 2765d7be54ccSKrishna Gudipati ret = pport_speed; 2766d7be54ccSKrishna Gudipati break; 2767d7be54ccSKrishna Gudipati 2768d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2769d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_4G; 2770d7be54ccSKrishna Gudipati break; 2771d7be54ccSKrishna Gudipati 2772d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2773d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_8G; 2774d7be54ccSKrishna Gudipati break; 2775d7be54ccSKrishna Gudipati 2776d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2777d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_10G; 2778d7be54ccSKrishna Gudipati break; 2779d7be54ccSKrishna Gudipati 2780d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2781d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_16G; 2782d7be54ccSKrishna Gudipati break; 2783d7be54ccSKrishna Gudipati 2784d7be54ccSKrishna Gudipati default: 2785d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_UNKNOWN; 2786d7be54ccSKrishna Gudipati } 2787d7be54ccSKrishna Gudipati return ret; 2788d7be54ccSKrishna Gudipati } 27897725ccfdSJing Huang 2790a36c61f9SKrishna Gudipati void 2791a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) 2792a36c61f9SKrishna Gudipati { 2793a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2794a36c61f9SKrishna Gudipati 2795a36c61f9SKrishna Gudipati fdmi->ms = ms; 2796a36c61f9SKrishna Gudipati if (ms->port->fcs->fdmi_enabled) 2797a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 2798a36c61f9SKrishna Gudipati else 2799a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled); 2800a36c61f9SKrishna Gudipati } 2801a36c61f9SKrishna Gudipati 2802a36c61f9SKrishna Gudipati void 2803a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms) 2804a36c61f9SKrishna Gudipati { 2805a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2806a36c61f9SKrishna Gudipati 2807a36c61f9SKrishna Gudipati fdmi->ms = ms; 2808a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); 2809a36c61f9SKrishna Gudipati } 2810a36c61f9SKrishna Gudipati 2811a36c61f9SKrishna Gudipati void 2812a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms) 2813a36c61f9SKrishna Gudipati { 2814a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2815a36c61f9SKrishna Gudipati 2816a36c61f9SKrishna Gudipati fdmi->ms = ms; 2817a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); 2818a36c61f9SKrishna Gudipati } 2819a36c61f9SKrishna Gudipati 2820a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES 2 2821a36c61f9SKrishna Gudipati 2822a36c61f9SKrishna Gudipati /* 2823a36c61f9SKrishna Gudipati * forward declarations 2824a36c61f9SKrishna Gudipati */ 2825a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, 2826a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2827a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_timeout(void *arg); 2828a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_plogi_response(void *fcsarg, 2829a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2830a36c61f9SKrishna Gudipati void *cbarg, 2831a36c61f9SKrishna Gudipati bfa_status_t req_status, 2832a36c61f9SKrishna Gudipati u32 rsp_len, 2833a36c61f9SKrishna Gudipati u32 resid_len, 2834a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2835a36c61f9SKrishna Gudipati 2836a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, 2837a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2838a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gmal_response(void *fcsarg, 2839a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2840a36c61f9SKrishna Gudipati void *cbarg, 2841a36c61f9SKrishna Gudipati bfa_status_t req_status, 2842a36c61f9SKrishna Gudipati u32 rsp_len, 2843a36c61f9SKrishna Gudipati u32 resid_len, 2844a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2845a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, 2846a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2847a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gfn_response(void *fcsarg, 2848a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2849a36c61f9SKrishna Gudipati void *cbarg, 2850a36c61f9SKrishna Gudipati bfa_status_t req_status, 2851a36c61f9SKrishna Gudipati u32 rsp_len, 2852a36c61f9SKrishna Gudipati u32 resid_len, 2853a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 28545fbe25c7SJing Huang /* 2855a36c61f9SKrishna Gudipati * fcs_ms_sm FCS MS state machine 2856a36c61f9SKrishna Gudipati */ 2857a36c61f9SKrishna Gudipati 28585fbe25c7SJing Huang /* 2859a36c61f9SKrishna Gudipati * MS State Machine events 2860a36c61f9SKrishna Gudipati */ 2861a36c61f9SKrishna Gudipati enum port_ms_event { 2862a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_ONLINE = 1, 2863a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_OFFLINE = 2, 2864a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_OK = 3, 2865a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_ERROR = 4, 2866a36c61f9SKrishna Gudipati MSSM_EVENT_TIMEOUT = 5, 2867a36c61f9SKrishna Gudipati MSSM_EVENT_FCXP_SENT = 6, 2868a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_FABRIC_RSCN = 7 2869a36c61f9SKrishna Gudipati }; 2870a36c61f9SKrishna Gudipati 2871a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2872a36c61f9SKrishna Gudipati enum port_ms_event event); 2873a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2874a36c61f9SKrishna Gudipati enum port_ms_event event); 2875a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2876a36c61f9SKrishna Gudipati enum port_ms_event event); 2877a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2878a36c61f9SKrishna Gudipati enum port_ms_event event); 2879a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2880a36c61f9SKrishna Gudipati enum port_ms_event event); 2881a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2882a36c61f9SKrishna Gudipati enum port_ms_event event); 2883a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2884a36c61f9SKrishna Gudipati enum port_ms_event event); 2885a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2886a36c61f9SKrishna Gudipati enum port_ms_event event); 2887a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2888a36c61f9SKrishna Gudipati enum port_ms_event event); 2889a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2890a36c61f9SKrishna Gudipati enum port_ms_event event); 2891a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2892a36c61f9SKrishna Gudipati enum port_ms_event event); 28935fbe25c7SJing Huang /* 2894a36c61f9SKrishna Gudipati * Start in offline state - awaiting NS to send start. 2895a36c61f9SKrishna Gudipati */ 2896a36c61f9SKrishna Gudipati static void 2897a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2898a36c61f9SKrishna Gudipati enum port_ms_event event) 2899a36c61f9SKrishna Gudipati { 2900a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2901a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2902a36c61f9SKrishna Gudipati 2903a36c61f9SKrishna Gudipati switch (event) { 2904a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_ONLINE: 2905a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2906a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2907a36c61f9SKrishna Gudipati break; 2908a36c61f9SKrishna Gudipati 2909a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2910a36c61f9SKrishna Gudipati break; 2911a36c61f9SKrishna Gudipati 2912a36c61f9SKrishna Gudipati default: 2913a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2914a36c61f9SKrishna Gudipati } 2915a36c61f9SKrishna Gudipati } 2916a36c61f9SKrishna Gudipati 2917a36c61f9SKrishna Gudipati static void 2918a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2919a36c61f9SKrishna Gudipati enum port_ms_event event) 2920a36c61f9SKrishna Gudipati { 2921a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2922a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2923a36c61f9SKrishna Gudipati 2924a36c61f9SKrishna Gudipati switch (event) { 2925a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2926a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi); 2927a36c61f9SKrishna Gudipati break; 2928a36c61f9SKrishna Gudipati 2929a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2930a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2931a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2932a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2933a36c61f9SKrishna Gudipati break; 2934a36c61f9SKrishna Gudipati 2935a36c61f9SKrishna Gudipati default: 2936a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2937a36c61f9SKrishna Gudipati } 2938a36c61f9SKrishna Gudipati } 2939a36c61f9SKrishna Gudipati 2940a36c61f9SKrishna Gudipati static void 2941a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2942a36c61f9SKrishna Gudipati enum port_ms_event event) 2943a36c61f9SKrishna Gudipati { 2944a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2945a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2946a36c61f9SKrishna Gudipati 2947a36c61f9SKrishna Gudipati switch (event) { 2948a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2949a36c61f9SKrishna Gudipati /* 2950a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2951a36c61f9SKrishna Gudipati */ 2952a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry); 2953a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2954a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2955a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2956a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2957a36c61f9SKrishna Gudipati break; 2958a36c61f9SKrishna Gudipati 2959a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2960a36c61f9SKrishna Gudipati /* 2961a36c61f9SKrishna Gudipati * since plogi is done, now invoke MS related sub-modules 2962a36c61f9SKrishna Gudipati */ 2963a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(ms); 2964a36c61f9SKrishna Gudipati 29655fbe25c7SJing Huang /* 2966a36c61f9SKrishna Gudipati * if this is a Vport, go to online state. 2967a36c61f9SKrishna Gudipati */ 2968a36c61f9SKrishna Gudipati if (ms->port->vport) { 2969a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2970a36c61f9SKrishna Gudipati break; 2971a36c61f9SKrishna Gudipati } 2972a36c61f9SKrishna Gudipati 2973a36c61f9SKrishna Gudipati /* 2974a36c61f9SKrishna Gudipati * For a base port we need to get the 2975a36c61f9SKrishna Gudipati * switch's IP address. 2976a36c61f9SKrishna Gudipati */ 2977a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2978a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2979a36c61f9SKrishna Gudipati break; 2980a36c61f9SKrishna Gudipati 2981a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2982a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2983a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2984a36c61f9SKrishna Gudipati break; 2985a36c61f9SKrishna Gudipati 2986a36c61f9SKrishna Gudipati default: 2987a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2988a36c61f9SKrishna Gudipati } 2989a36c61f9SKrishna Gudipati } 2990a36c61f9SKrishna Gudipati 2991a36c61f9SKrishna Gudipati static void 2992a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2993a36c61f9SKrishna Gudipati enum port_ms_event event) 2994a36c61f9SKrishna Gudipati { 2995a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2996a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2997a36c61f9SKrishna Gudipati 2998a36c61f9SKrishna Gudipati switch (event) { 2999a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 3000a36c61f9SKrishna Gudipati /* 3001a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3002a36c61f9SKrishna Gudipati */ 3003a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 3004a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 3005a36c61f9SKrishna Gudipati break; 3006a36c61f9SKrishna Gudipati 3007a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3008a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3009a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 3010a36c61f9SKrishna Gudipati break; 3011a36c61f9SKrishna Gudipati 3012a36c61f9SKrishna Gudipati default: 3013a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3014a36c61f9SKrishna Gudipati } 3015a36c61f9SKrishna Gudipati } 3016a36c61f9SKrishna Gudipati 3017a36c61f9SKrishna Gudipati static void 3018a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 3019a36c61f9SKrishna Gudipati enum port_ms_event event) 3020a36c61f9SKrishna Gudipati { 3021a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3022a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3023a36c61f9SKrishna Gudipati 3024a36c61f9SKrishna Gudipati switch (event) { 3025a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3026a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3027a36c61f9SKrishna Gudipati break; 3028a36c61f9SKrishna Gudipati 3029a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_FABRIC_RSCN: 3030a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3031a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 3032a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3033a36c61f9SKrishna Gudipati break; 3034a36c61f9SKrishna Gudipati 3035a36c61f9SKrishna Gudipati default: 3036a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3037a36c61f9SKrishna Gudipati } 3038a36c61f9SKrishna Gudipati } 3039a36c61f9SKrishna Gudipati 3040a36c61f9SKrishna Gudipati static void 3041a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 3042a36c61f9SKrishna Gudipati enum port_ms_event event) 3043a36c61f9SKrishna Gudipati { 3044a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3045a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3046a36c61f9SKrishna Gudipati 3047a36c61f9SKrishna Gudipati switch (event) { 3048a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 3049a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal); 3050a36c61f9SKrishna Gudipati break; 3051a36c61f9SKrishna Gudipati 3052a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3053a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3054a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3055a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 3056a36c61f9SKrishna Gudipati break; 3057a36c61f9SKrishna Gudipati 3058a36c61f9SKrishna Gudipati default: 3059a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3060a36c61f9SKrishna Gudipati } 3061a36c61f9SKrishna Gudipati } 3062a36c61f9SKrishna Gudipati 3063a36c61f9SKrishna Gudipati static void 3064a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 3065a36c61f9SKrishna Gudipati enum port_ms_event event) 3066a36c61f9SKrishna Gudipati { 3067a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3068a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3069a36c61f9SKrishna Gudipati 3070a36c61f9SKrishna Gudipati switch (event) { 3071a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 3072a36c61f9SKrishna Gudipati /* 3073a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3074a36c61f9SKrishna Gudipati */ 3075a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 3076a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry); 3077a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 3078a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3079a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 3080a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3081a36c61f9SKrishna Gudipati } else { 3082a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3083a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3084a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 3085a36c61f9SKrishna Gudipati } 3086a36c61f9SKrishna Gudipati break; 3087a36c61f9SKrishna Gudipati 3088a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 3089a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3090a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3091a36c61f9SKrishna Gudipati break; 3092a36c61f9SKrishna Gudipati 3093a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3094a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3095a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 3096a36c61f9SKrishna Gudipati break; 3097a36c61f9SKrishna Gudipati 3098a36c61f9SKrishna Gudipati default: 3099a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3100a36c61f9SKrishna Gudipati } 3101a36c61f9SKrishna Gudipati } 3102a36c61f9SKrishna Gudipati 3103a36c61f9SKrishna Gudipati static void 3104a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 3105a36c61f9SKrishna Gudipati enum port_ms_event event) 3106a36c61f9SKrishna Gudipati { 3107a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3108a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3109a36c61f9SKrishna Gudipati 3110a36c61f9SKrishna Gudipati switch (event) { 3111a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 3112a36c61f9SKrishna Gudipati /* 3113a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3114a36c61f9SKrishna Gudipati */ 3115a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 3116a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 3117a36c61f9SKrishna Gudipati break; 3118a36c61f9SKrishna Gudipati 3119a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3120a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3121a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 3122a36c61f9SKrishna Gudipati break; 3123a36c61f9SKrishna Gudipati 3124a36c61f9SKrishna Gudipati default: 3125a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3126a36c61f9SKrishna Gudipati } 3127a36c61f9SKrishna Gudipati } 31285fbe25c7SJing Huang /* 3129a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3130a36c61f9SKrishna Gudipati */ 3131a36c61f9SKrishna Gudipati 3132a36c61f9SKrishna Gudipati static void 3133a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3134a36c61f9SKrishna Gudipati { 3135a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3136a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3137a36c61f9SKrishna Gudipati struct fchs_s fchs; 3138a36c61f9SKrishna Gudipati int len; 3139a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3140a36c61f9SKrishna Gudipati 3141a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3142a36c61f9SKrishna Gudipati 3143c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3144c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3145a36c61f9SKrishna Gudipati if (!fcxp) { 3146a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3147c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE); 3148a36c61f9SKrishna Gudipati return; 3149a36c61f9SKrishna Gudipati } 3150a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3151a36c61f9SKrishna Gudipati 3152a36c61f9SKrishna Gudipati len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3153a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 3154f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 3155a36c61f9SKrishna Gudipati 3156a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3157a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3158a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response, (void *)ms, 3159a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3160a36c61f9SKrishna Gudipati 3161a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3162a36c61f9SKrishna Gudipati } 3163a36c61f9SKrishna Gudipati 3164a36c61f9SKrishna Gudipati static void 3165a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3166a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3167a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3168a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 3169a36c61f9SKrishna Gudipati { 3170a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3171a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3172a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3173a36c61f9SKrishna Gudipati struct fcgs_gmal_resp_s *gmal_resp; 3174a36c61f9SKrishna Gudipati struct fcgs_gmal_entry_s *gmal_entry; 3175a36c61f9SKrishna Gudipati u32 num_entries; 3176a36c61f9SKrishna Gudipati u8 *rsp_str; 3177a36c61f9SKrishna Gudipati 3178a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3179a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3180a36c61f9SKrishna Gudipati 3181a36c61f9SKrishna Gudipati /* 3182a36c61f9SKrishna Gudipati * Sanity Checks 3183a36c61f9SKrishna Gudipati */ 3184a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3185a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3186a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3187a36c61f9SKrishna Gudipati return; 3188a36c61f9SKrishna Gudipati } 3189a36c61f9SKrishna Gudipati 3190a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3191ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3192a36c61f9SKrishna Gudipati 3193a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3194a36c61f9SKrishna Gudipati gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); 3195a36c61f9SKrishna Gudipati 3196ba816ea8SJing Huang num_entries = be32_to_cpu(gmal_resp->ms_len); 3197a36c61f9SKrishna Gudipati if (num_entries == 0) { 3198a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3199a36c61f9SKrishna Gudipati return; 3200a36c61f9SKrishna Gudipati } 3201a36c61f9SKrishna Gudipati /* 3202a36c61f9SKrishna Gudipati * The response could contain multiple Entries. 3203a36c61f9SKrishna Gudipati * Entries for SNMP interface, etc. 3204a36c61f9SKrishna Gudipati * We look for the entry with a telnet prefix. 3205a36c61f9SKrishna Gudipati * First "http://" entry refers to IP addr 3206a36c61f9SKrishna Gudipati */ 3207a36c61f9SKrishna Gudipati 3208a36c61f9SKrishna Gudipati gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma; 3209a36c61f9SKrishna Gudipati while (num_entries > 0) { 3210a36c61f9SKrishna Gudipati if (strncmp(gmal_entry->prefix, 3211a36c61f9SKrishna Gudipati CT_GMAL_RESP_PREFIX_HTTP, 3212a36c61f9SKrishna Gudipati sizeof(gmal_entry->prefix)) == 0) { 3213a36c61f9SKrishna Gudipati 3214a36c61f9SKrishna Gudipati /* 3215a36c61f9SKrishna Gudipati * if the IP address is terminating with a '/', 3216a36c61f9SKrishna Gudipati * remove it. 3217a36c61f9SKrishna Gudipati * Byte 0 consists of the length of the string. 3218a36c61f9SKrishna Gudipati */ 3219a36c61f9SKrishna Gudipati rsp_str = &(gmal_entry->prefix[0]); 3220a36c61f9SKrishna Gudipati if (rsp_str[gmal_entry->len-1] == '/') 3221a36c61f9SKrishna Gudipati rsp_str[gmal_entry->len-1] = 0; 3222a36c61f9SKrishna Gudipati 3223a36c61f9SKrishna Gudipati /* copy IP Address to fabric */ 32248c5a50e8SArnd Bergmann strlcpy(bfa_fcs_lport_get_fabric_ipaddr(port), 3225a36c61f9SKrishna Gudipati gmal_entry->ip_addr, 3226a36c61f9SKrishna Gudipati BFA_FCS_FABRIC_IPADDR_SZ); 3227a36c61f9SKrishna Gudipati break; 3228a36c61f9SKrishna Gudipati } else { 3229a36c61f9SKrishna Gudipati --num_entries; 3230a36c61f9SKrishna Gudipati ++gmal_entry; 3231a36c61f9SKrishna Gudipati } 3232a36c61f9SKrishna Gudipati } 3233a36c61f9SKrishna Gudipati 3234a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3235a36c61f9SKrishna Gudipati return; 3236a36c61f9SKrishna Gudipati } 3237a36c61f9SKrishna Gudipati 3238a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3239a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3240a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3241a36c61f9SKrishna Gudipati } 3242a36c61f9SKrishna Gudipati 3243a36c61f9SKrishna Gudipati static void 3244a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 3245a36c61f9SKrishna Gudipati enum port_ms_event event) 3246a36c61f9SKrishna Gudipati { 3247a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3248a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3249a36c61f9SKrishna Gudipati 3250a36c61f9SKrishna Gudipati switch (event) { 3251a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 3252a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn); 3253a36c61f9SKrishna Gudipati break; 3254a36c61f9SKrishna Gudipati 3255a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3256a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3257a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3258a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 3259a36c61f9SKrishna Gudipati break; 3260a36c61f9SKrishna Gudipati 3261a36c61f9SKrishna Gudipati default: 3262a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3263a36c61f9SKrishna Gudipati } 3264a36c61f9SKrishna Gudipati } 3265a36c61f9SKrishna Gudipati 3266a36c61f9SKrishna Gudipati static void 3267a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 3268a36c61f9SKrishna Gudipati enum port_ms_event event) 3269a36c61f9SKrishna Gudipati { 3270a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3271a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3272a36c61f9SKrishna Gudipati 3273a36c61f9SKrishna Gudipati switch (event) { 3274a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 3275a36c61f9SKrishna Gudipati /* 3276a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3277a36c61f9SKrishna Gudipati */ 3278a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 3279a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry); 3280a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 3281a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3282a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 3283a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3284a36c61f9SKrishna Gudipati } else { 3285a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 3286a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 3287a36c61f9SKrishna Gudipati } 3288a36c61f9SKrishna Gudipati break; 3289a36c61f9SKrishna Gudipati 3290a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 3291a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 3292a36c61f9SKrishna Gudipati break; 3293a36c61f9SKrishna Gudipati 3294a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3295a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3296a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 3297a36c61f9SKrishna Gudipati break; 3298a36c61f9SKrishna Gudipati 3299a36c61f9SKrishna Gudipati default: 3300a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3301a36c61f9SKrishna Gudipati } 3302a36c61f9SKrishna Gudipati } 3303a36c61f9SKrishna Gudipati 3304a36c61f9SKrishna Gudipati static void 3305a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 3306a36c61f9SKrishna Gudipati enum port_ms_event event) 3307a36c61f9SKrishna Gudipati { 3308a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3309a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3310a36c61f9SKrishna Gudipati 3311a36c61f9SKrishna Gudipati switch (event) { 3312a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 3313a36c61f9SKrishna Gudipati /* 3314a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3315a36c61f9SKrishna Gudipati */ 3316a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3317a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3318a36c61f9SKrishna Gudipati break; 3319a36c61f9SKrishna Gudipati 3320a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3321a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3322a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 3323a36c61f9SKrishna Gudipati break; 3324a36c61f9SKrishna Gudipati 3325a36c61f9SKrishna Gudipati default: 3326a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3327a36c61f9SKrishna Gudipati } 3328a36c61f9SKrishna Gudipati } 33295fbe25c7SJing Huang /* 3330a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3331a36c61f9SKrishna Gudipati */ 3332a36c61f9SKrishna Gudipati 3333a36c61f9SKrishna Gudipati static void 3334a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3335a36c61f9SKrishna Gudipati { 3336a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3337a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3338a36c61f9SKrishna Gudipati struct fchs_s fchs; 3339a36c61f9SKrishna Gudipati int len; 3340a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3341a36c61f9SKrishna Gudipati 3342a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3343a36c61f9SKrishna Gudipati 3344c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3345c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3346a36c61f9SKrishna Gudipati if (!fcxp) { 3347a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3348c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE); 3349a36c61f9SKrishna Gudipati return; 3350a36c61f9SKrishna Gudipati } 3351a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3352a36c61f9SKrishna Gudipati 3353a36c61f9SKrishna Gudipati len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3354a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 3355f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 3356a36c61f9SKrishna Gudipati 3357a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3358a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3359a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response, (void *)ms, 3360a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3361a36c61f9SKrishna Gudipati 3362a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3363a36c61f9SKrishna Gudipati } 3364a36c61f9SKrishna Gudipati 3365a36c61f9SKrishna Gudipati static void 3366a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3367a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 3368a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 3369a36c61f9SKrishna Gudipati { 3370a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3371a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3372a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3373a36c61f9SKrishna Gudipati wwn_t *gfn_resp; 3374a36c61f9SKrishna Gudipati 3375a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3376a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3377a36c61f9SKrishna Gudipati 3378a36c61f9SKrishna Gudipati /* 3379a36c61f9SKrishna Gudipati * Sanity Checks 3380a36c61f9SKrishna Gudipati */ 3381a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3382a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3383a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3384a36c61f9SKrishna Gudipati return; 3385a36c61f9SKrishna Gudipati } 3386a36c61f9SKrishna Gudipati 3387a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3388ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3389a36c61f9SKrishna Gudipati 3390a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3391a36c61f9SKrishna Gudipati gfn_resp = (wwn_t *)(cthdr + 1); 3392a36c61f9SKrishna Gudipati /* check if it has actually changed */ 3393a36c61f9SKrishna Gudipati if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port), 3394a36c61f9SKrishna Gudipati gfn_resp, sizeof(wwn_t)) != 0)) { 3395a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); 3396a36c61f9SKrishna Gudipati } 3397a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3398a36c61f9SKrishna Gudipati return; 3399a36c61f9SKrishna Gudipati } 3400a36c61f9SKrishna Gudipati 3401a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3402a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3403a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3404a36c61f9SKrishna Gudipati } 3405a36c61f9SKrishna Gudipati 34065fbe25c7SJing Huang /* 3407a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3408a36c61f9SKrishna Gudipati */ 3409a36c61f9SKrishna Gudipati 3410a36c61f9SKrishna Gudipati static void 3411a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3412a36c61f9SKrishna Gudipati { 3413a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3414a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3415a36c61f9SKrishna Gudipati struct fchs_s fchs; 3416a36c61f9SKrishna Gudipati int len; 3417a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3418a36c61f9SKrishna Gudipati 3419a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3420a36c61f9SKrishna Gudipati 3421c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3422c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3423a36c61f9SKrishna Gudipati if (!fcxp) { 3424a36c61f9SKrishna Gudipati port->stats.ms_plogi_alloc_wait++; 3425a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3426c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE); 3427a36c61f9SKrishna Gudipati return; 3428a36c61f9SKrishna Gudipati } 3429a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3430a36c61f9SKrishna Gudipati 3431a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3432f16a1750SMaggie Zhang bfa_hton3b(FC_MGMT_SERVER), 3433a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3434a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 3435be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 3436be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3437a36c61f9SKrishna Gudipati 3438a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3439a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3440a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response, (void *)ms, 3441a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 3442a36c61f9SKrishna Gudipati 3443a36c61f9SKrishna Gudipati port->stats.ms_plogi_sent++; 3444a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3445a36c61f9SKrishna Gudipati } 3446a36c61f9SKrishna Gudipati 3447a36c61f9SKrishna Gudipati static void 3448a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3449a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3450a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) 3451a36c61f9SKrishna Gudipati { 3452a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3453a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3454a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 3455a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3456a36c61f9SKrishna Gudipati 3457a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3458a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3459a36c61f9SKrishna Gudipati 3460a36c61f9SKrishna Gudipati /* 3461a36c61f9SKrishna Gudipati * Sanity Checks 3462a36c61f9SKrishna Gudipati */ 3463a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3464a36c61f9SKrishna Gudipati port->stats.ms_plogi_rsp_err++; 3465a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3466a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3467a36c61f9SKrishna Gudipati return; 3468a36c61f9SKrishna Gudipati } 3469a36c61f9SKrishna Gudipati 3470a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3471a36c61f9SKrishna Gudipati 3472a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 3473a36c61f9SKrishna Gudipati 3474a36c61f9SKrishna Gudipati case FC_ELS_ACC: 3475a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 3476a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 3477a36c61f9SKrishna Gudipati port->stats.ms_plogi_acc_err++; 3478a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3479a36c61f9SKrishna Gudipati break; 3480a36c61f9SKrishna Gudipati } 3481a36c61f9SKrishna Gudipati port->stats.ms_plogi_accepts++; 3482a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3483a36c61f9SKrishna Gudipati break; 3484a36c61f9SKrishna Gudipati 3485a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 3486a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3487a36c61f9SKrishna Gudipati 3488a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 3489a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3490a36c61f9SKrishna Gudipati 3491a36c61f9SKrishna Gudipati port->stats.ms_rejects++; 3492a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3493a36c61f9SKrishna Gudipati break; 3494a36c61f9SKrishna Gudipati 3495a36c61f9SKrishna Gudipati default: 3496a36c61f9SKrishna Gudipati port->stats.ms_plogi_unknown_rsp++; 3497a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 3498a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3499a36c61f9SKrishna Gudipati } 3500a36c61f9SKrishna Gudipati } 3501a36c61f9SKrishna Gudipati 3502a36c61f9SKrishna Gudipati static void 3503a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg) 3504a36c61f9SKrishna Gudipati { 3505a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg; 3506a36c61f9SKrishna Gudipati 3507a36c61f9SKrishna Gudipati ms->port->stats.ms_timeouts++; 3508a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT); 3509a36c61f9SKrishna Gudipati } 3510a36c61f9SKrishna Gudipati 3511a36c61f9SKrishna Gudipati 3512a36c61f9SKrishna Gudipati void 3513a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port) 3514a36c61f9SKrishna Gudipati { 3515a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3516a36c61f9SKrishna Gudipati 3517a36c61f9SKrishna Gudipati ms->port = port; 3518a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3519a36c61f9SKrishna Gudipati 3520a36c61f9SKrishna Gudipati /* 3521a36c61f9SKrishna Gudipati * Invoke init routines of sub modules. 3522a36c61f9SKrishna Gudipati */ 3523a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(ms); 3524a36c61f9SKrishna Gudipati } 3525a36c61f9SKrishna Gudipati 3526a36c61f9SKrishna Gudipati void 3527a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port) 3528a36c61f9SKrishna Gudipati { 3529a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3530a36c61f9SKrishna Gudipati 3531a36c61f9SKrishna Gudipati ms->port = port; 3532a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); 3533a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(ms); 3534a36c61f9SKrishna Gudipati } 3535a36c61f9SKrishna Gudipati 3536a36c61f9SKrishna Gudipati void 3537a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port) 3538a36c61f9SKrishna Gudipati { 3539a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3540a36c61f9SKrishna Gudipati 3541a36c61f9SKrishna Gudipati ms->port = port; 3542a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE); 3543a36c61f9SKrishna Gudipati } 3544a36c61f9SKrishna Gudipati void 3545a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port) 3546a36c61f9SKrishna Gudipati { 3547a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3548a36c61f9SKrishna Gudipati 3549a36c61f9SKrishna Gudipati /* todo. Handle this only when in Online state */ 3550a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online)) 3551a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN); 3552a36c61f9SKrishna Gudipati } 3553a36c61f9SKrishna Gudipati 35545fbe25c7SJing Huang /* 3555a36c61f9SKrishna Gudipati * @page ns_sm_info VPORT NS State Machine 3556a36c61f9SKrishna Gudipati * 3557a36c61f9SKrishna Gudipati * @section ns_sm_interactions VPORT NS State Machine Interactions 3558a36c61f9SKrishna Gudipati * 3559a36c61f9SKrishna Gudipati * @section ns_sm VPORT NS State Machine 3560a36c61f9SKrishna Gudipati * img ns_sm.jpg 3561a36c61f9SKrishna Gudipati */ 3562a36c61f9SKrishna Gudipati 3563a36c61f9SKrishna Gudipati /* 3564a36c61f9SKrishna Gudipati * forward declarations 3565a36c61f9SKrishna Gudipati */ 3566a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, 3567a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3568a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, 3569a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3570a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, 3571a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3572a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, 3573a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3574a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, 3575a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3576ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, 3577ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3578ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, 3579ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3580a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_timeout(void *arg); 3581a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_plogi_response(void *fcsarg, 3582a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3583a36c61f9SKrishna Gudipati void *cbarg, 3584a36c61f9SKrishna Gudipati bfa_status_t req_status, 3585a36c61f9SKrishna Gudipati u32 rsp_len, 3586a36c61f9SKrishna Gudipati u32 resid_len, 3587a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3588a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, 3589a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3590a36c61f9SKrishna Gudipati void *cbarg, 3591a36c61f9SKrishna Gudipati bfa_status_t req_status, 3592a36c61f9SKrishna Gudipati u32 rsp_len, 3593a36c61f9SKrishna Gudipati u32 resid_len, 3594a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3595a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg, 3596a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3597a36c61f9SKrishna Gudipati void *cbarg, 3598a36c61f9SKrishna Gudipati bfa_status_t req_status, 3599a36c61f9SKrishna Gudipati u32 rsp_len, 3600a36c61f9SKrishna Gudipati u32 resid_len, 3601a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3602a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg, 3603a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3604a36c61f9SKrishna Gudipati void *cbarg, 3605a36c61f9SKrishna Gudipati bfa_status_t req_status, 3606a36c61f9SKrishna Gudipati u32 rsp_len, 3607a36c61f9SKrishna Gudipati u32 resid_len, 3608a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3609a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, 3610a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3611a36c61f9SKrishna Gudipati void *cbarg, 3612a36c61f9SKrishna Gudipati bfa_status_t req_status, 3613a36c61f9SKrishna Gudipati u32 rsp_len, 3614a36c61f9SKrishna Gudipati u32 resid_len, 3615a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3616ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, 3617ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3618ce7242b8SKrishna Gudipati void *cbarg, 3619ce7242b8SKrishna Gudipati bfa_status_t req_status, 3620ce7242b8SKrishna Gudipati u32 rsp_len, 3621ce7242b8SKrishna Gudipati u32 resid_len, 3622ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs); 3623ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, 3624ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3625ce7242b8SKrishna Gudipati void *cbarg, 3626ce7242b8SKrishna Gudipati bfa_status_t req_status, 3627ce7242b8SKrishna Gudipati u32 rsp_len, 3628ce7242b8SKrishna Gudipati u32 resid_len, 3629ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs); 3630a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_process_gidft_pids( 3631a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 3632a36c61f9SKrishna Gudipati u32 *pid_buf, u32 n_pids); 3633a36c61f9SKrishna Gudipati 3634a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port); 36355fbe25c7SJing Huang /* 3636a36c61f9SKrishna Gudipati * fcs_ns_sm FCS nameserver interface state machine 3637a36c61f9SKrishna Gudipati */ 3638a36c61f9SKrishna Gudipati 36395fbe25c7SJing Huang /* 3640a36c61f9SKrishna Gudipati * VPort NS State Machine events 3641a36c61f9SKrishna Gudipati */ 3642a36c61f9SKrishna Gudipati enum vport_ns_event { 3643a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_ONLINE = 1, 3644a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_OFFLINE = 2, 3645a36c61f9SKrishna Gudipati NSSM_EVENT_PLOGI_SENT = 3, 3646a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_OK = 4, 3647a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_ERROR = 5, 3648a36c61f9SKrishna Gudipati NSSM_EVENT_TIMEOUT = 6, 3649a36c61f9SKrishna Gudipati NSSM_EVENT_NS_QUERY = 7, 3650a36c61f9SKrishna Gudipati NSSM_EVENT_RSPNID_SENT = 8, 3651a36c61f9SKrishna Gudipati NSSM_EVENT_RFTID_SENT = 9, 3652a36c61f9SKrishna Gudipati NSSM_EVENT_RFFID_SENT = 10, 3653a36c61f9SKrishna Gudipati NSSM_EVENT_GIDFT_SENT = 11, 3654ce7242b8SKrishna Gudipati NSSM_EVENT_RNNID_SENT = 12, 3655ce7242b8SKrishna Gudipati NSSM_EVENT_RSNN_NN_SENT = 13, 3656a36c61f9SKrishna Gudipati }; 3657a36c61f9SKrishna Gudipati 3658a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3659a36c61f9SKrishna Gudipati enum vport_ns_event event); 3660a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3661a36c61f9SKrishna Gudipati enum vport_ns_event event); 3662a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3663a36c61f9SKrishna Gudipati enum vport_ns_event event); 3664a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3665a36c61f9SKrishna Gudipati enum vport_ns_event event); 3666a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rspn_id( 3667a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3668a36c61f9SKrishna Gudipati enum vport_ns_event event); 3669a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3670a36c61f9SKrishna Gudipati enum vport_ns_event event); 3671a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3672a36c61f9SKrishna Gudipati enum vport_ns_event event); 3673a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rft_id( 3674a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3675a36c61f9SKrishna Gudipati enum vport_ns_event event); 3676a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3677a36c61f9SKrishna Gudipati enum vport_ns_event event); 3678a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3679a36c61f9SKrishna Gudipati enum vport_ns_event event); 3680a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rff_id( 3681a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3682a36c61f9SKrishna Gudipati enum vport_ns_event event); 3683a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3684a36c61f9SKrishna Gudipati enum vport_ns_event event); 3685a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3686a36c61f9SKrishna Gudipati enum vport_ns_event event); 3687a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_gid_ft( 3688a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3689a36c61f9SKrishna Gudipati enum vport_ns_event event); 3690a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3691a36c61f9SKrishna Gudipati enum vport_ns_event event); 3692a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3693a36c61f9SKrishna Gudipati enum vport_ns_event event); 3694a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3695a36c61f9SKrishna Gudipati enum vport_ns_event event); 3696ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rnn_id( 3697ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3698ce7242b8SKrishna Gudipati enum vport_ns_event event); 3699ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns, 3700ce7242b8SKrishna Gudipati enum vport_ns_event event); 3701ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3702ce7242b8SKrishna Gudipati enum vport_ns_event event); 3703ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rsnn_nn( 3704ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3705ce7242b8SKrishna Gudipati enum vport_ns_event event); 3706ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns, 3707ce7242b8SKrishna Gudipati enum vport_ns_event event); 3708ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rsnn_nn_retry( 3709ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3710ce7242b8SKrishna Gudipati enum vport_ns_event event); 37115fbe25c7SJing Huang /* 3712a36c61f9SKrishna Gudipati * Start in offline state - awaiting linkup 3713a36c61f9SKrishna Gudipati */ 3714a36c61f9SKrishna Gudipati static void 3715a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3716a36c61f9SKrishna Gudipati enum vport_ns_event event) 3717a36c61f9SKrishna Gudipati { 3718a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3719a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3720a36c61f9SKrishna Gudipati 3721a36c61f9SKrishna Gudipati switch (event) { 3722a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_ONLINE: 3723a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3724a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3725a36c61f9SKrishna Gudipati break; 3726a36c61f9SKrishna Gudipati 3727a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3728a36c61f9SKrishna Gudipati break; 3729a36c61f9SKrishna Gudipati 3730a36c61f9SKrishna Gudipati default: 3731a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3732a36c61f9SKrishna Gudipati } 3733a36c61f9SKrishna Gudipati } 3734a36c61f9SKrishna Gudipati 3735a36c61f9SKrishna Gudipati static void 3736a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3737a36c61f9SKrishna Gudipati enum vport_ns_event event) 3738a36c61f9SKrishna Gudipati { 3739a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3740a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3741a36c61f9SKrishna Gudipati 3742a36c61f9SKrishna Gudipati switch (event) { 3743a36c61f9SKrishna Gudipati case NSSM_EVENT_PLOGI_SENT: 3744a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi); 3745a36c61f9SKrishna Gudipati break; 3746a36c61f9SKrishna Gudipati 3747a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3748a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3749a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3750a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3751a36c61f9SKrishna Gudipati break; 3752a36c61f9SKrishna Gudipati 3753a36c61f9SKrishna Gudipati default: 3754a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3755a36c61f9SKrishna Gudipati } 3756a36c61f9SKrishna Gudipati } 3757a36c61f9SKrishna Gudipati 3758a36c61f9SKrishna Gudipati static void 3759a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3760a36c61f9SKrishna Gudipati enum vport_ns_event event) 3761a36c61f9SKrishna Gudipati { 3762a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3763a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3764a36c61f9SKrishna Gudipati 3765a36c61f9SKrishna Gudipati switch (event) { 3766a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3767a36c61f9SKrishna Gudipati /* 3768a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3769a36c61f9SKrishna Gudipati */ 3770a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry); 3771a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3772a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3773a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3774a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3775a36c61f9SKrishna Gudipati break; 3776a36c61f9SKrishna Gudipati 3777a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3778ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id); 3779ce7242b8SKrishna Gudipati ns->num_rnnid_retries = 0; 3780ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id(ns, NULL); 3781a36c61f9SKrishna Gudipati break; 3782a36c61f9SKrishna Gudipati 3783a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3784a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3785a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3786a36c61f9SKrishna Gudipati break; 3787a36c61f9SKrishna Gudipati 3788a36c61f9SKrishna Gudipati default: 3789a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3790a36c61f9SKrishna Gudipati } 3791a36c61f9SKrishna Gudipati } 3792a36c61f9SKrishna Gudipati 3793a36c61f9SKrishna Gudipati static void 3794a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3795a36c61f9SKrishna Gudipati enum vport_ns_event event) 3796a36c61f9SKrishna Gudipati { 3797a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3798a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3799a36c61f9SKrishna Gudipati 3800a36c61f9SKrishna Gudipati switch (event) { 3801a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3802a36c61f9SKrishna Gudipati /* 3803a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3804a36c61f9SKrishna Gudipati */ 3805a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3806a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3807a36c61f9SKrishna Gudipati break; 3808a36c61f9SKrishna Gudipati 3809a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3810a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3811a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 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 static void 3820ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rnn_id(struct bfa_fcs_lport_ns_s *ns, 3821ce7242b8SKrishna Gudipati enum vport_ns_event event) 3822ce7242b8SKrishna Gudipati { 3823ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3824ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3825ce7242b8SKrishna Gudipati 3826ce7242b8SKrishna Gudipati switch (event) { 3827ce7242b8SKrishna Gudipati case NSSM_EVENT_RNNID_SENT: 3828ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id); 3829ce7242b8SKrishna Gudipati break; 3830ce7242b8SKrishna Gudipati 3831ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3832ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3833ce7242b8SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3834ce7242b8SKrishna Gudipati &ns->fcxp_wqe); 3835ce7242b8SKrishna Gudipati break; 3836ce7242b8SKrishna Gudipati default: 3837ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3838ce7242b8SKrishna Gudipati } 3839ce7242b8SKrishna Gudipati } 3840ce7242b8SKrishna Gudipati 3841ce7242b8SKrishna Gudipati static void 3842ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns, 3843ce7242b8SKrishna Gudipati enum vport_ns_event event) 3844ce7242b8SKrishna Gudipati { 3845ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3846ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3847ce7242b8SKrishna Gudipati 3848ce7242b8SKrishna Gudipati switch (event) { 3849ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3850ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn); 3851ce7242b8SKrishna Gudipati ns->num_rnnid_retries = 0; 3852ce7242b8SKrishna Gudipati ns->num_rsnn_nn_retries = 0; 3853ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL); 3854ce7242b8SKrishna Gudipati break; 3855ce7242b8SKrishna Gudipati 3856ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3857ce7242b8SKrishna Gudipati if (ns->num_rnnid_retries < BFA_FCS_MAX_NS_RETRIES) { 3858ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id_retry); 3859ce7242b8SKrishna Gudipati ns->port->stats.ns_retries++; 3860ce7242b8SKrishna Gudipati ns->num_rnnid_retries++; 3861ce7242b8SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3862ce7242b8SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3863ce7242b8SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3864ce7242b8SKrishna Gudipati } else { 3865ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, 3866ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id); 3867ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3868ce7242b8SKrishna Gudipati } 3869ce7242b8SKrishna Gudipati break; 3870ce7242b8SKrishna Gudipati 3871ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3872ce7242b8SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3873ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3874ce7242b8SKrishna Gudipati break; 3875ce7242b8SKrishna Gudipati 3876ce7242b8SKrishna Gudipati default: 3877ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3878ce7242b8SKrishna Gudipati } 3879ce7242b8SKrishna Gudipati } 3880ce7242b8SKrishna Gudipati 3881ce7242b8SKrishna Gudipati static void 3882ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3883ce7242b8SKrishna Gudipati enum vport_ns_event event) 3884ce7242b8SKrishna Gudipati { 3885ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3886ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3887ce7242b8SKrishna Gudipati 3888ce7242b8SKrishna Gudipati switch (event) { 3889ce7242b8SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3890ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id); 3891ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id(ns, NULL); 3892ce7242b8SKrishna Gudipati break; 3893ce7242b8SKrishna Gudipati 3894ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3895ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3896ce7242b8SKrishna Gudipati bfa_timer_stop(&ns->timer); 3897ce7242b8SKrishna Gudipati break; 3898ce7242b8SKrishna Gudipati 3899ce7242b8SKrishna Gudipati default: 3900ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3901ce7242b8SKrishna Gudipati } 3902ce7242b8SKrishna Gudipati } 3903ce7242b8SKrishna Gudipati 3904ce7242b8SKrishna Gudipati static void 3905ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rsnn_nn(struct bfa_fcs_lport_ns_s *ns, 3906ce7242b8SKrishna Gudipati enum vport_ns_event event) 3907ce7242b8SKrishna Gudipati { 3908ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3909ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3910ce7242b8SKrishna Gudipati 3911ce7242b8SKrishna Gudipati switch (event) { 3912ce7242b8SKrishna Gudipati case NSSM_EVENT_RSNN_NN_SENT: 3913ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn); 3914ce7242b8SKrishna Gudipati break; 3915ce7242b8SKrishna Gudipati 3916ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3917ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3918ce7242b8SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3919ce7242b8SKrishna Gudipati &ns->fcxp_wqe); 3920ce7242b8SKrishna Gudipati break; 3921ce7242b8SKrishna Gudipati 3922ce7242b8SKrishna Gudipati default: 3923ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3924ce7242b8SKrishna Gudipati } 3925ce7242b8SKrishna Gudipati } 3926ce7242b8SKrishna Gudipati 3927ce7242b8SKrishna Gudipati static void 3928ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns, 3929ce7242b8SKrishna Gudipati enum vport_ns_event event) 3930ce7242b8SKrishna Gudipati { 3931ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3932ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3933ce7242b8SKrishna Gudipati 3934ce7242b8SKrishna Gudipati switch (event) { 3935ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3936ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3937ce7242b8SKrishna Gudipati ns->num_rsnn_nn_retries = 0; 3938ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3939ce7242b8SKrishna Gudipati break; 3940ce7242b8SKrishna Gudipati 3941ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3942ce7242b8SKrishna Gudipati if (ns->num_rsnn_nn_retries < BFA_FCS_MAX_NS_RETRIES) { 3943ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn_retry); 3944ce7242b8SKrishna Gudipati ns->port->stats.ns_retries++; 3945ce7242b8SKrishna Gudipati ns->num_rsnn_nn_retries++; 3946ce7242b8SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3947ce7242b8SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, 3948ce7242b8SKrishna Gudipati ns, BFA_FCS_RETRY_TIMEOUT); 3949ce7242b8SKrishna Gudipati } else { 3950ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, 3951ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id); 3952ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3953ce7242b8SKrishna Gudipati } 3954ce7242b8SKrishna Gudipati break; 3955ce7242b8SKrishna Gudipati 3956ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3957ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3958ce7242b8SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3959ce7242b8SKrishna Gudipati break; 3960ce7242b8SKrishna Gudipati 3961ce7242b8SKrishna Gudipati default: 3962ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3963ce7242b8SKrishna Gudipati } 3964ce7242b8SKrishna Gudipati } 3965ce7242b8SKrishna Gudipati 3966ce7242b8SKrishna Gudipati static void 3967ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rsnn_nn_retry(struct bfa_fcs_lport_ns_s *ns, 3968ce7242b8SKrishna Gudipati enum vport_ns_event event) 3969ce7242b8SKrishna Gudipati { 3970ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3971ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3972ce7242b8SKrishna Gudipati 3973ce7242b8SKrishna Gudipati switch (event) { 3974ce7242b8SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3975ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn); 3976ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL); 3977ce7242b8SKrishna Gudipati break; 3978ce7242b8SKrishna Gudipati 3979ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3980ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3981ce7242b8SKrishna Gudipati bfa_timer_stop(&ns->timer); 3982ce7242b8SKrishna Gudipati break; 3983ce7242b8SKrishna Gudipati 3984ce7242b8SKrishna Gudipati default: 3985ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3986ce7242b8SKrishna Gudipati } 3987ce7242b8SKrishna Gudipati } 3988ce7242b8SKrishna Gudipati 3989ce7242b8SKrishna Gudipati static void 3990a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3991a36c61f9SKrishna Gudipati enum vport_ns_event event) 3992a36c61f9SKrishna Gudipati { 3993a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3994a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3995a36c61f9SKrishna Gudipati 3996a36c61f9SKrishna Gudipati switch (event) { 3997a36c61f9SKrishna Gudipati case NSSM_EVENT_RSPNID_SENT: 3998a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id); 3999a36c61f9SKrishna Gudipati break; 4000a36c61f9SKrishna Gudipati 4001a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4002a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4003a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4004a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 4005a36c61f9SKrishna Gudipati break; 4006a36c61f9SKrishna Gudipati 4007a36c61f9SKrishna Gudipati default: 4008a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4009a36c61f9SKrishna Gudipati } 4010a36c61f9SKrishna Gudipati } 4011a36c61f9SKrishna Gudipati 4012a36c61f9SKrishna Gudipati static void 4013a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 4014a36c61f9SKrishna Gudipati enum vport_ns_event event) 4015a36c61f9SKrishna Gudipati { 4016a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4017a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4018a36c61f9SKrishna Gudipati 4019a36c61f9SKrishna Gudipati switch (event) { 4020a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4021a36c61f9SKrishna Gudipati /* 4022a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4023a36c61f9SKrishna Gudipati */ 4024a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry); 4025a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4026a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4027a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4028a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4029a36c61f9SKrishna Gudipati break; 4030a36c61f9SKrishna Gudipati 4031a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4032a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 4033a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 4034a36c61f9SKrishna Gudipati break; 4035a36c61f9SKrishna Gudipati 4036a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4037a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4038a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4039a36c61f9SKrishna Gudipati break; 4040a36c61f9SKrishna Gudipati 4041a36c61f9SKrishna Gudipati default: 4042a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4043a36c61f9SKrishna Gudipati } 4044a36c61f9SKrishna Gudipati } 4045a36c61f9SKrishna Gudipati 4046a36c61f9SKrishna Gudipati static void 4047a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 4048a36c61f9SKrishna Gudipati enum vport_ns_event event) 4049a36c61f9SKrishna Gudipati { 4050a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4051a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4052a36c61f9SKrishna Gudipati 4053a36c61f9SKrishna Gudipati switch (event) { 4054a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4055a36c61f9SKrishna Gudipati /* 4056a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 4057a36c61f9SKrishna Gudipati */ 4058a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 4059a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 4060a36c61f9SKrishna Gudipati break; 4061a36c61f9SKrishna Gudipati 4062a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4063a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4064a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4065a36c61f9SKrishna Gudipati break; 4066a36c61f9SKrishna Gudipati 4067a36c61f9SKrishna Gudipati default: 4068a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4069a36c61f9SKrishna Gudipati } 4070a36c61f9SKrishna Gudipati } 4071a36c61f9SKrishna Gudipati 4072a36c61f9SKrishna Gudipati static void 4073a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns, 4074a36c61f9SKrishna Gudipati enum vport_ns_event event) 4075a36c61f9SKrishna Gudipati { 4076a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4077a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4078a36c61f9SKrishna Gudipati 4079a36c61f9SKrishna Gudipati switch (event) { 4080a36c61f9SKrishna Gudipati case NSSM_EVENT_RFTID_SENT: 4081a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id); 4082a36c61f9SKrishna Gudipati break; 4083a36c61f9SKrishna Gudipati 4084a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4085a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4086a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4087a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 4088a36c61f9SKrishna Gudipati break; 4089a36c61f9SKrishna Gudipati 4090a36c61f9SKrishna Gudipati default: 4091a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4092a36c61f9SKrishna Gudipati } 4093a36c61f9SKrishna Gudipati } 4094a36c61f9SKrishna Gudipati 4095a36c61f9SKrishna Gudipati static void 4096a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 4097a36c61f9SKrishna Gudipati enum vport_ns_event event) 4098a36c61f9SKrishna Gudipati { 4099a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4100a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4101a36c61f9SKrishna Gudipati 4102a36c61f9SKrishna Gudipati switch (event) { 4103a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4104a36c61f9SKrishna Gudipati /* Now move to register FC4 Features */ 4105a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 4106a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 4107a36c61f9SKrishna Gudipati break; 4108a36c61f9SKrishna Gudipati 4109a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4110a36c61f9SKrishna Gudipati /* 4111a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4112a36c61f9SKrishna Gudipati */ 4113a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry); 4114a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4115a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4116a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4117a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4118a36c61f9SKrishna Gudipati break; 4119a36c61f9SKrishna Gudipati 4120a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4121a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4122a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4123a36c61f9SKrishna Gudipati break; 4124a36c61f9SKrishna Gudipati 4125a36c61f9SKrishna Gudipati default: 4126a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4127a36c61f9SKrishna Gudipati } 4128a36c61f9SKrishna Gudipati } 4129a36c61f9SKrishna Gudipati 4130a36c61f9SKrishna Gudipati static void 4131a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 4132a36c61f9SKrishna Gudipati enum vport_ns_event event) 4133a36c61f9SKrishna Gudipati { 4134a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4135a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4136a36c61f9SKrishna Gudipati 4137a36c61f9SKrishna Gudipati switch (event) { 4138a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4139a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 4140a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 4141a36c61f9SKrishna Gudipati break; 4142a36c61f9SKrishna Gudipati 4143a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4144a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4145a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4146a36c61f9SKrishna Gudipati break; 4147a36c61f9SKrishna Gudipati 4148a36c61f9SKrishna Gudipati default: 4149a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4150a36c61f9SKrishna Gudipati } 4151a36c61f9SKrishna Gudipati } 4152a36c61f9SKrishna Gudipati 4153a36c61f9SKrishna Gudipati static void 4154a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns, 4155a36c61f9SKrishna Gudipati enum vport_ns_event event) 4156a36c61f9SKrishna Gudipati { 4157a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4158a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4159a36c61f9SKrishna Gudipati 4160a36c61f9SKrishna Gudipati switch (event) { 4161a36c61f9SKrishna Gudipati case NSSM_EVENT_RFFID_SENT: 4162a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id); 4163a36c61f9SKrishna Gudipati break; 4164a36c61f9SKrishna Gudipati 4165a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4166a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4167a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4168a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 4169a36c61f9SKrishna Gudipati break; 4170a36c61f9SKrishna Gudipati 4171a36c61f9SKrishna Gudipati default: 4172a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4173a36c61f9SKrishna Gudipati } 4174a36c61f9SKrishna Gudipati } 4175a36c61f9SKrishna Gudipati 4176a36c61f9SKrishna Gudipati static void 4177a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 4178a36c61f9SKrishna Gudipati enum vport_ns_event event) 4179a36c61f9SKrishna Gudipati { 4180a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4181a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4182a36c61f9SKrishna Gudipati 4183a36c61f9SKrishna Gudipati switch (event) { 4184a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4185a36c61f9SKrishna Gudipati 4186a36c61f9SKrishna Gudipati /* 4187a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot initiate rport 4188a36c61f9SKrishna Gudipati * discovery with the fabric. Instead, we will retrieve the 4189a36c61f9SKrishna Gudipati * boot targets from HAL/FW. 4190a36c61f9SKrishna Gudipati */ 4191a36c61f9SKrishna Gudipati if (__fcs_min_cfg(ns->port->fcs)) { 4192a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(ns->port); 4193a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 4194a36c61f9SKrishna Gudipati return; 4195a36c61f9SKrishna Gudipati } 4196a36c61f9SKrishna Gudipati 4197a36c61f9SKrishna Gudipati /* 4198a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 4199a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 4200a36c61f9SKrishna Gudipati */ 4201a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 4202a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 4203a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 4204a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 4205a36c61f9SKrishna Gudipati } 4206a36c61f9SKrishna Gudipati /* 4207a36c61f9SKrishna Gudipati * kick off mgmt srvr state machine 4208a36c61f9SKrishna Gudipati */ 4209a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(ns->port); 4210a36c61f9SKrishna Gudipati break; 4211a36c61f9SKrishna Gudipati 4212a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4213a36c61f9SKrishna Gudipati /* 4214a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4215a36c61f9SKrishna Gudipati */ 4216a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry); 4217a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4218a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4219a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4220a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4221a36c61f9SKrishna Gudipati break; 4222a36c61f9SKrishna Gudipati 4223a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4224a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4225a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4226a36c61f9SKrishna Gudipati break; 4227a36c61f9SKrishna Gudipati 4228a36c61f9SKrishna Gudipati default: 4229a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4230a36c61f9SKrishna Gudipati } 4231a36c61f9SKrishna Gudipati } 4232a36c61f9SKrishna Gudipati 4233a36c61f9SKrishna Gudipati static void 4234a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 4235a36c61f9SKrishna Gudipati enum vport_ns_event event) 4236a36c61f9SKrishna Gudipati { 4237a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4238a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4239a36c61f9SKrishna Gudipati 4240a36c61f9SKrishna Gudipati switch (event) { 4241a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4242a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 4243a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 4244a36c61f9SKrishna Gudipati break; 4245a36c61f9SKrishna Gudipati 4246a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4247a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4248a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4249a36c61f9SKrishna Gudipati break; 4250a36c61f9SKrishna Gudipati 4251a36c61f9SKrishna Gudipati default: 4252a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4253a36c61f9SKrishna Gudipati } 4254a36c61f9SKrishna Gudipati } 4255a36c61f9SKrishna Gudipati static void 4256a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns, 4257a36c61f9SKrishna Gudipati enum vport_ns_event event) 4258a36c61f9SKrishna Gudipati { 4259a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4260a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4261a36c61f9SKrishna Gudipati 4262a36c61f9SKrishna Gudipati switch (event) { 4263a36c61f9SKrishna Gudipati case NSSM_EVENT_GIDFT_SENT: 4264a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft); 4265a36c61f9SKrishna Gudipati break; 4266a36c61f9SKrishna Gudipati 4267a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4268a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4269a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4270a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 4271a36c61f9SKrishna Gudipati break; 4272a36c61f9SKrishna Gudipati 4273a36c61f9SKrishna Gudipati default: 4274a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4275a36c61f9SKrishna Gudipati } 4276a36c61f9SKrishna Gudipati } 4277a36c61f9SKrishna Gudipati 4278a36c61f9SKrishna Gudipati static void 4279a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 4280a36c61f9SKrishna Gudipati enum vport_ns_event event) 4281a36c61f9SKrishna Gudipati { 4282a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4283a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4284a36c61f9SKrishna Gudipati 4285a36c61f9SKrishna Gudipati switch (event) { 4286a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4287a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 4288a36c61f9SKrishna Gudipati break; 4289a36c61f9SKrishna Gudipati 4290a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4291a36c61f9SKrishna Gudipati /* 4292a36c61f9SKrishna Gudipati * TBD: for certain reject codes, we don't need to retry 4293a36c61f9SKrishna Gudipati */ 4294a36c61f9SKrishna Gudipati /* 4295a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4296a36c61f9SKrishna Gudipati */ 4297a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry); 4298a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4299a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4300a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4301a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4302a36c61f9SKrishna Gudipati break; 4303a36c61f9SKrishna Gudipati 4304a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4305a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4306a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4307a36c61f9SKrishna Gudipati break; 4308a36c61f9SKrishna Gudipati 4309a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 4310a36c61f9SKrishna Gudipati break; 4311a36c61f9SKrishna Gudipati 4312a36c61f9SKrishna Gudipati default: 4313a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4314a36c61f9SKrishna Gudipati } 4315a36c61f9SKrishna Gudipati } 4316a36c61f9SKrishna Gudipati 4317a36c61f9SKrishna Gudipati static void 4318a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 4319a36c61f9SKrishna Gudipati enum vport_ns_event event) 4320a36c61f9SKrishna Gudipati { 4321a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4322a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4323a36c61f9SKrishna Gudipati 4324a36c61f9SKrishna Gudipati switch (event) { 4325a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4326a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft); 4327a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 4328a36c61f9SKrishna Gudipati break; 4329a36c61f9SKrishna Gudipati 4330a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4331a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4332a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4333a36c61f9SKrishna Gudipati break; 4334a36c61f9SKrishna Gudipati 4335a36c61f9SKrishna Gudipati default: 4336a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4337a36c61f9SKrishna Gudipati } 4338a36c61f9SKrishna Gudipati } 4339a36c61f9SKrishna Gudipati 4340a36c61f9SKrishna Gudipati static void 4341a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 4342a36c61f9SKrishna Gudipati enum vport_ns_event event) 4343a36c61f9SKrishna Gudipati { 4344a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4345a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4346a36c61f9SKrishna Gudipati 4347a36c61f9SKrishna Gudipati switch (event) { 4348a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4349a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4350a36c61f9SKrishna Gudipati break; 4351a36c61f9SKrishna Gudipati 4352a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 4353a36c61f9SKrishna Gudipati /* 4354a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 4355a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 4356a36c61f9SKrishna Gudipati */ 4357a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 4358a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 4359a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 4360a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 4361a36c61f9SKrishna Gudipati }; 4362a36c61f9SKrishna Gudipati break; 4363a36c61f9SKrishna Gudipati 4364a36c61f9SKrishna Gudipati default: 4365a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4366a36c61f9SKrishna Gudipati } 4367a36c61f9SKrishna Gudipati } 4368a36c61f9SKrishna Gudipati 4369a36c61f9SKrishna Gudipati 4370a36c61f9SKrishna Gudipati 43715fbe25c7SJing Huang /* 4372a36c61f9SKrishna Gudipati * ns_pvt Nameserver local functions 4373a36c61f9SKrishna Gudipati */ 4374a36c61f9SKrishna Gudipati 4375a36c61f9SKrishna Gudipati static void 4376a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4377a36c61f9SKrishna Gudipati { 4378a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4379a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4380a36c61f9SKrishna Gudipati struct fchs_s fchs; 4381a36c61f9SKrishna Gudipati int len; 4382a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4383a36c61f9SKrishna Gudipati 4384a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4385a36c61f9SKrishna Gudipati 4386c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4387c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4388a36c61f9SKrishna Gudipati if (!fcxp) { 4389a36c61f9SKrishna Gudipati port->stats.ns_plogi_alloc_wait++; 4390a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4391c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE); 4392a36c61f9SKrishna Gudipati return; 4393a36c61f9SKrishna Gudipati } 4394a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4395a36c61f9SKrishna Gudipati 4396a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4397f16a1750SMaggie Zhang bfa_hton3b(FC_NAME_SERVER), 4398a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 4399a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 4400be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 4401be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 4402a36c61f9SKrishna Gudipati 4403a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4404a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4405a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response, (void *)ns, 4406a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 4407a36c61f9SKrishna Gudipati port->stats.ns_plogi_sent++; 4408a36c61f9SKrishna Gudipati 4409a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); 4410a36c61f9SKrishna Gudipati } 4411a36c61f9SKrishna Gudipati 4412a36c61f9SKrishna Gudipati static void 4413a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4414a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 4415a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 4416a36c61f9SKrishna Gudipati { 4417a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4418a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4419a36c61f9SKrishna Gudipati /* struct fc_logi_s *plogi_resp; */ 4420a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 4421a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 4422a36c61f9SKrishna Gudipati 4423a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4424a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4425a36c61f9SKrishna Gudipati 4426a36c61f9SKrishna Gudipati /* 4427a36c61f9SKrishna Gudipati * Sanity Checks 4428a36c61f9SKrishna Gudipati */ 4429a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4430a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4431a36c61f9SKrishna Gudipati port->stats.ns_plogi_rsp_err++; 4432a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4433a36c61f9SKrishna Gudipati return; 4434a36c61f9SKrishna Gudipati } 4435a36c61f9SKrishna Gudipati 4436a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 4437a36c61f9SKrishna Gudipati 4438a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 4439a36c61f9SKrishna Gudipati 4440a36c61f9SKrishna Gudipati case FC_ELS_ACC: 4441a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 4442a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 4443a36c61f9SKrishna Gudipati port->stats.ns_plogi_acc_err++; 4444a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4445a36c61f9SKrishna Gudipati break; 4446a36c61f9SKrishna Gudipati } 4447a36c61f9SKrishna Gudipati port->stats.ns_plogi_accepts++; 4448a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4449a36c61f9SKrishna Gudipati break; 4450a36c61f9SKrishna Gudipati 4451a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 4452a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 4453a36c61f9SKrishna Gudipati 4454a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 4455a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 4456a36c61f9SKrishna Gudipati 4457a36c61f9SKrishna Gudipati port->stats.ns_rejects++; 4458a36c61f9SKrishna Gudipati 4459a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4460a36c61f9SKrishna Gudipati break; 4461a36c61f9SKrishna Gudipati 4462a36c61f9SKrishna Gudipati default: 4463a36c61f9SKrishna Gudipati port->stats.ns_plogi_unknown_rsp++; 4464a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 4465a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4466a36c61f9SKrishna Gudipati } 4467a36c61f9SKrishna Gudipati } 4468a36c61f9SKrishna Gudipati 44695fbe25c7SJing Huang /* 4470ce7242b8SKrishna Gudipati * Register node name for port_id 4471ce7242b8SKrishna Gudipati */ 4472ce7242b8SKrishna Gudipati static void 4473ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4474ce7242b8SKrishna Gudipati { 4475ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4476ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4477ce7242b8SKrishna Gudipati struct fchs_s fchs; 4478ce7242b8SKrishna Gudipati int len; 4479ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4480ce7242b8SKrishna Gudipati 4481ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4482ce7242b8SKrishna Gudipati 4483ce7242b8SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4484ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4485ce7242b8SKrishna Gudipati if (!fcxp) { 4486ce7242b8SKrishna Gudipati port->stats.ns_rnnid_alloc_wait++; 4487ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4488ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id, ns, BFA_TRUE); 4489ce7242b8SKrishna Gudipati return; 4490ce7242b8SKrishna Gudipati } 4491ce7242b8SKrishna Gudipati 4492ce7242b8SKrishna Gudipati ns->fcxp = fcxp; 4493ce7242b8SKrishna Gudipati 4494ce7242b8SKrishna Gudipati len = fc_rnnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4495ce7242b8SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 4496ce7242b8SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 4497ce7242b8SKrishna Gudipati bfa_fcs_lport_get_nwwn(port)); 4498ce7242b8SKrishna Gudipati 4499ce7242b8SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4500ce7242b8SKrishna Gudipati FC_CLASS_3, len, &fchs, 4501ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rnn_id_response, (void *)ns, 4502ce7242b8SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4503ce7242b8SKrishna Gudipati 4504ce7242b8SKrishna Gudipati port->stats.ns_rnnid_sent++; 4505ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RNNID_SENT); 4506ce7242b8SKrishna Gudipati } 4507ce7242b8SKrishna Gudipati 4508ce7242b8SKrishna Gudipati static void 4509ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4510ce7242b8SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4511ce7242b8SKrishna Gudipati u32 rsp_len, u32 resid_len, 4512ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs) 4513ce7242b8SKrishna Gudipati 4514ce7242b8SKrishna Gudipati { 4515ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4516ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4517ce7242b8SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4518ce7242b8SKrishna Gudipati 4519ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4520ce7242b8SKrishna Gudipati 4521ce7242b8SKrishna Gudipati /* 4522ce7242b8SKrishna Gudipati * Sanity Checks 4523ce7242b8SKrishna Gudipati */ 4524ce7242b8SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4525ce7242b8SKrishna Gudipati bfa_trc(port->fcs, req_status); 4526ce7242b8SKrishna Gudipati port->stats.ns_rnnid_rsp_err++; 4527ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4528ce7242b8SKrishna Gudipati return; 4529ce7242b8SKrishna Gudipati } 4530ce7242b8SKrishna Gudipati 4531ce7242b8SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4532ce7242b8SKrishna Gudipati cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4533ce7242b8SKrishna Gudipati 4534ce7242b8SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4535ce7242b8SKrishna Gudipati port->stats.ns_rnnid_accepts++; 4536ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4537ce7242b8SKrishna Gudipati return; 4538ce7242b8SKrishna Gudipati } 4539ce7242b8SKrishna Gudipati 4540ce7242b8SKrishna Gudipati port->stats.ns_rnnid_rejects++; 4541ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4542ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4543ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4544ce7242b8SKrishna Gudipati } 4545ce7242b8SKrishna Gudipati 4546ce7242b8SKrishna Gudipati /* 4547ce7242b8SKrishna Gudipati * Register the symbolic node name for a given node name. 4548ce7242b8SKrishna Gudipati */ 4549ce7242b8SKrishna Gudipati static void 4550ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4551ce7242b8SKrishna Gudipati { 4552ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4553ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4554ce7242b8SKrishna Gudipati struct fchs_s fchs; 4555ce7242b8SKrishna Gudipati int len; 4556ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4557ce7242b8SKrishna Gudipati u8 *nsymbl; 4558ce7242b8SKrishna Gudipati 4559ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4560ce7242b8SKrishna Gudipati 4561ce7242b8SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4562ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4563ce7242b8SKrishna Gudipati if (!fcxp) { 4564ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_alloc_wait++; 4565ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4566ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn, ns, BFA_TRUE); 4567ce7242b8SKrishna Gudipati return; 4568ce7242b8SKrishna Gudipati } 4569ce7242b8SKrishna Gudipati ns->fcxp = fcxp; 4570ce7242b8SKrishna Gudipati 4571ce7242b8SKrishna Gudipati nsymbl = (u8 *) &(bfa_fcs_lport_get_nsym_name( 4572ce7242b8SKrishna Gudipati bfa_fcs_get_base_port(port->fcs))); 4573ce7242b8SKrishna Gudipati 4574ce7242b8SKrishna Gudipati len = fc_rsnn_nn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4575ce7242b8SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 4576ce7242b8SKrishna Gudipati bfa_fcs_lport_get_nwwn(port), nsymbl); 4577ce7242b8SKrishna Gudipati 4578ce7242b8SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4579ce7242b8SKrishna Gudipati FC_CLASS_3, len, &fchs, 4580ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rsnn_nn_response, (void *)ns, 4581ce7242b8SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4582ce7242b8SKrishna Gudipati 4583ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_sent++; 4584ce7242b8SKrishna Gudipati 4585ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSNN_NN_SENT); 4586ce7242b8SKrishna Gudipati } 4587ce7242b8SKrishna Gudipati 4588ce7242b8SKrishna Gudipati static void 4589ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4590ce7242b8SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4591ce7242b8SKrishna Gudipati u32 rsp_len, u32 resid_len, 4592ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs) 4593ce7242b8SKrishna Gudipati { 4594ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4595ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4596ce7242b8SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4597ce7242b8SKrishna Gudipati 4598ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4599ce7242b8SKrishna Gudipati 4600ce7242b8SKrishna Gudipati /* 4601ce7242b8SKrishna Gudipati * Sanity Checks 4602ce7242b8SKrishna Gudipati */ 4603ce7242b8SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4604ce7242b8SKrishna Gudipati bfa_trc(port->fcs, req_status); 4605ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_rsp_err++; 4606ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4607ce7242b8SKrishna Gudipati return; 4608ce7242b8SKrishna Gudipati } 4609ce7242b8SKrishna Gudipati 4610ce7242b8SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4611ce7242b8SKrishna Gudipati cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4612ce7242b8SKrishna Gudipati 4613ce7242b8SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4614ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_accepts++; 4615ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4616ce7242b8SKrishna Gudipati return; 4617ce7242b8SKrishna Gudipati } 4618ce7242b8SKrishna Gudipati 4619ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_rejects++; 4620ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4621ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4622ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4623ce7242b8SKrishna Gudipati } 4624ce7242b8SKrishna Gudipati 4625ce7242b8SKrishna Gudipati /* 4626a36c61f9SKrishna Gudipati * Register the symbolic port name. 4627a36c61f9SKrishna Gudipati */ 4628a36c61f9SKrishna Gudipati static void 4629a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4630a36c61f9SKrishna Gudipati { 4631a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4632a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4633a36c61f9SKrishna Gudipati struct fchs_s fchs; 4634a36c61f9SKrishna Gudipati int len; 4635a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4636a36c61f9SKrishna Gudipati u8 symbl[256]; 4637a36c61f9SKrishna Gudipati u8 *psymbl = &symbl[0]; 4638a36c61f9SKrishna Gudipati 46396a18b167SJing Huang memset(symbl, 0, sizeof(symbl)); 4640a36c61f9SKrishna Gudipati 4641a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4642a36c61f9SKrishna Gudipati 4643c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4644c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4645a36c61f9SKrishna Gudipati if (!fcxp) { 4646a36c61f9SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 4647a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4648c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE); 4649a36c61f9SKrishna Gudipati return; 4650a36c61f9SKrishna Gudipati } 4651a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4652a36c61f9SKrishna Gudipati 4653a36c61f9SKrishna Gudipati /* 4654a36c61f9SKrishna Gudipati * for V-Port, form a Port Symbolic Name 4655a36c61f9SKrishna Gudipati */ 4656a36c61f9SKrishna Gudipati if (port->vport) { 46575fbe25c7SJing Huang /* 4658a36c61f9SKrishna Gudipati * For Vports, we append the vport's port symbolic name 4659a36c61f9SKrishna Gudipati * to that of the base port. 4660a36c61f9SKrishna Gudipati */ 4661a36c61f9SKrishna Gudipati 46628c5a50e8SArnd Bergmann strlcpy(symbl, 46638c5a50e8SArnd Bergmann (char *)&(bfa_fcs_lport_get_psym_name 4664a36c61f9SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 46658c5a50e8SArnd Bergmann sizeof(symbl)); 4666a36c61f9SKrishna Gudipati 46678c5a50e8SArnd Bergmann strlcat(symbl, (char *)&(bfa_fcs_lport_get_psym_name(port)), 46688c5a50e8SArnd Bergmann sizeof(symbl)); 4669a36c61f9SKrishna Gudipati } else { 4670a36c61f9SKrishna Gudipati psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); 4671a36c61f9SKrishna Gudipati } 4672a36c61f9SKrishna Gudipati 4673a36c61f9SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4674a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, psymbl); 4675a36c61f9SKrishna Gudipati 4676a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4677a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4678a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response, (void *)ns, 4679a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4680a36c61f9SKrishna Gudipati 4681a36c61f9SKrishna Gudipati port->stats.ns_rspnid_sent++; 4682a36c61f9SKrishna Gudipati 4683a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); 4684a36c61f9SKrishna Gudipati } 4685a36c61f9SKrishna Gudipati 4686a36c61f9SKrishna Gudipati static void 4687a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4688a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4689a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4690a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4691a36c61f9SKrishna Gudipati { 4692a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4693a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4694a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4695a36c61f9SKrishna Gudipati 4696a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4697a36c61f9SKrishna Gudipati 4698a36c61f9SKrishna Gudipati /* 4699a36c61f9SKrishna Gudipati * Sanity Checks 4700a36c61f9SKrishna Gudipati */ 4701a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4702a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4703a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rsp_err++; 4704a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4705a36c61f9SKrishna Gudipati return; 4706a36c61f9SKrishna Gudipati } 4707a36c61f9SKrishna Gudipati 4708a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4709ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4710a36c61f9SKrishna Gudipati 4711a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4712a36c61f9SKrishna Gudipati port->stats.ns_rspnid_accepts++; 4713a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4714a36c61f9SKrishna Gudipati return; 4715a36c61f9SKrishna Gudipati } 4716a36c61f9SKrishna Gudipati 4717a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rejects++; 4718a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4719a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4720a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4721a36c61f9SKrishna Gudipati } 4722a36c61f9SKrishna Gudipati 47235fbe25c7SJing Huang /* 4724a36c61f9SKrishna Gudipati * Register FC4-Types 4725a36c61f9SKrishna Gudipati */ 4726a36c61f9SKrishna Gudipati static void 4727a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4728a36c61f9SKrishna Gudipati { 4729a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4730a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4731a36c61f9SKrishna Gudipati struct fchs_s fchs; 4732a36c61f9SKrishna Gudipati int len; 4733a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4734a36c61f9SKrishna Gudipati 4735a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4736a36c61f9SKrishna Gudipati 4737c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4738c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4739a36c61f9SKrishna Gudipati if (!fcxp) { 4740a36c61f9SKrishna Gudipati port->stats.ns_rftid_alloc_wait++; 4741a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4742c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE); 4743a36c61f9SKrishna Gudipati return; 4744a36c61f9SKrishna Gudipati } 4745a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4746a36c61f9SKrishna Gudipati 4747a36c61f9SKrishna Gudipati len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4748a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles); 4749a36c61f9SKrishna Gudipati 4750a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4751a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4752a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response, (void *)ns, 4753a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4754a36c61f9SKrishna Gudipati 4755a36c61f9SKrishna Gudipati port->stats.ns_rftid_sent++; 4756a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); 4757a36c61f9SKrishna Gudipati } 4758a36c61f9SKrishna Gudipati 4759a36c61f9SKrishna Gudipati static void 4760a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4761a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4762a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4763a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4764a36c61f9SKrishna Gudipati { 4765a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4766a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4767a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4768a36c61f9SKrishna Gudipati 4769a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4770a36c61f9SKrishna Gudipati 4771a36c61f9SKrishna Gudipati /* 4772a36c61f9SKrishna Gudipati * Sanity Checks 4773a36c61f9SKrishna Gudipati */ 4774a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4775a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4776a36c61f9SKrishna Gudipati port->stats.ns_rftid_rsp_err++; 4777a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4778a36c61f9SKrishna Gudipati return; 4779a36c61f9SKrishna Gudipati } 4780a36c61f9SKrishna Gudipati 4781a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4782ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4783a36c61f9SKrishna Gudipati 4784a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4785a36c61f9SKrishna Gudipati port->stats.ns_rftid_accepts++; 4786a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4787a36c61f9SKrishna Gudipati return; 4788a36c61f9SKrishna Gudipati } 4789a36c61f9SKrishna Gudipati 4790a36c61f9SKrishna Gudipati port->stats.ns_rftid_rejects++; 4791a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4792a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4793a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4794a36c61f9SKrishna Gudipati } 4795a36c61f9SKrishna Gudipati 47965fbe25c7SJing Huang /* 4797a36c61f9SKrishna Gudipati * Register FC4-Features : Should be done after RFT_ID 4798a36c61f9SKrishna Gudipati */ 4799a36c61f9SKrishna Gudipati static void 4800a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4801a36c61f9SKrishna Gudipati { 4802a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4803a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4804a36c61f9SKrishna Gudipati struct fchs_s fchs; 4805a36c61f9SKrishna Gudipati int len; 4806a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4807a36c61f9SKrishna Gudipati u8 fc4_ftrs = 0; 4808a36c61f9SKrishna Gudipati 4809a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4810a36c61f9SKrishna Gudipati 4811c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4812c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4813a36c61f9SKrishna Gudipati if (!fcxp) { 4814a36c61f9SKrishna Gudipati port->stats.ns_rffid_alloc_wait++; 4815a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4816c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE); 4817a36c61f9SKrishna Gudipati return; 4818a36c61f9SKrishna Gudipati } 4819a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4820a36c61f9SKrishna Gudipati 4821a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) 4822a36c61f9SKrishna Gudipati fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; 4823a36c61f9SKrishna Gudipati 4824a36c61f9SKrishna Gudipati len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4825a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 4826a36c61f9SKrishna Gudipati FC_TYPE_FCP, fc4_ftrs); 4827a36c61f9SKrishna Gudipati 4828a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4829a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4830a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response, (void *)ns, 4831a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4832a36c61f9SKrishna Gudipati 4833a36c61f9SKrishna Gudipati port->stats.ns_rffid_sent++; 4834a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); 4835a36c61f9SKrishna Gudipati } 4836a36c61f9SKrishna Gudipati 4837a36c61f9SKrishna Gudipati static void 4838a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4839a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4840a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4841a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4842a36c61f9SKrishna Gudipati { 4843a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4844a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4845a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4846a36c61f9SKrishna Gudipati 4847a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4848a36c61f9SKrishna Gudipati 4849a36c61f9SKrishna Gudipati /* 4850a36c61f9SKrishna Gudipati * Sanity Checks 4851a36c61f9SKrishna Gudipati */ 4852a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4853a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4854a36c61f9SKrishna Gudipati port->stats.ns_rffid_rsp_err++; 4855a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4856a36c61f9SKrishna Gudipati return; 4857a36c61f9SKrishna Gudipati } 4858a36c61f9SKrishna Gudipati 4859a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4860ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4861a36c61f9SKrishna Gudipati 4862a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4863a36c61f9SKrishna Gudipati port->stats.ns_rffid_accepts++; 4864a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4865a36c61f9SKrishna Gudipati return; 4866a36c61f9SKrishna Gudipati } 4867a36c61f9SKrishna Gudipati 4868a36c61f9SKrishna Gudipati port->stats.ns_rffid_rejects++; 4869a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4870a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4871a36c61f9SKrishna Gudipati 4872a36c61f9SKrishna Gudipati if (cthdr->reason_code == CT_RSN_NOT_SUPP) { 4873a36c61f9SKrishna Gudipati /* if this command is not supported, we don't retry */ 4874a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4875a36c61f9SKrishna Gudipati } else 4876a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4877a36c61f9SKrishna Gudipati } 48785fbe25c7SJing Huang /* 4879a36c61f9SKrishna Gudipati * Query Fabric for FC4-Types Devices. 4880a36c61f9SKrishna Gudipati * 4881a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response 4882a36c61f9SKrishna Gudipati * can be larger than 2K. 4883a36c61f9SKrishna Gudipati */ 4884a36c61f9SKrishna Gudipati static void 4885a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4886a36c61f9SKrishna Gudipati { 4887a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4888a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4889a36c61f9SKrishna Gudipati struct fchs_s fchs; 4890a36c61f9SKrishna Gudipati int len; 4891a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4892a36c61f9SKrishna Gudipati 4893a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4894a36c61f9SKrishna Gudipati 4895c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4896c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4897a36c61f9SKrishna Gudipati if (!fcxp) { 4898a36c61f9SKrishna Gudipati port->stats.ns_gidft_alloc_wait++; 4899a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4900c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE); 4901a36c61f9SKrishna Gudipati return; 4902a36c61f9SKrishna Gudipati } 4903a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4904a36c61f9SKrishna Gudipati 4905a36c61f9SKrishna Gudipati /* 4906a36c61f9SKrishna Gudipati * This query is only initiated for FCP initiator mode. 4907a36c61f9SKrishna Gudipati */ 4908a36c61f9SKrishna Gudipati len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4909a36c61f9SKrishna Gudipati ns->port->pid, FC_TYPE_FCP); 4910a36c61f9SKrishna Gudipati 4911a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4912a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4913a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response, (void *)ns, 4914a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV); 4915a36c61f9SKrishna Gudipati 4916a36c61f9SKrishna Gudipati port->stats.ns_gidft_sent++; 4917a36c61f9SKrishna Gudipati 4918a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); 4919a36c61f9SKrishna Gudipati } 4920a36c61f9SKrishna Gudipati 4921a36c61f9SKrishna Gudipati static void 4922a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4923a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4924a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4925a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4926a36c61f9SKrishna Gudipati { 4927a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4928a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4929a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4930a36c61f9SKrishna Gudipati u32 n_pids; 4931a36c61f9SKrishna Gudipati 4932a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4933a36c61f9SKrishna Gudipati 4934a36c61f9SKrishna Gudipati /* 4935a36c61f9SKrishna Gudipati * Sanity Checks 4936a36c61f9SKrishna Gudipati */ 4937a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4938a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4939a36c61f9SKrishna Gudipati port->stats.ns_gidft_rsp_err++; 4940a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4941a36c61f9SKrishna Gudipati return; 4942a36c61f9SKrishna Gudipati } 4943a36c61f9SKrishna Gudipati 4944a36c61f9SKrishna Gudipati if (resid_len != 0) { 4945a36c61f9SKrishna Gudipati /* 4946a36c61f9SKrishna Gudipati * TBD : we will need to allocate a larger buffer & retry the 4947a36c61f9SKrishna Gudipati * command 4948a36c61f9SKrishna Gudipati */ 4949a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 4950a36c61f9SKrishna Gudipati bfa_trc(port->fcs, resid_len); 4951a36c61f9SKrishna Gudipati return; 4952a36c61f9SKrishna Gudipati } 4953a36c61f9SKrishna Gudipati 4954a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4955ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4956a36c61f9SKrishna Gudipati 4957a36c61f9SKrishna Gudipati switch (cthdr->cmd_rsp_code) { 4958a36c61f9SKrishna Gudipati 4959a36c61f9SKrishna Gudipati case CT_RSP_ACCEPT: 4960a36c61f9SKrishna Gudipati 4961a36c61f9SKrishna Gudipati port->stats.ns_gidft_accepts++; 4962a36c61f9SKrishna Gudipati n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); 4963a36c61f9SKrishna Gudipati bfa_trc(port->fcs, n_pids); 4964a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(port, 4965a36c61f9SKrishna Gudipati (u32 *) (cthdr + 1), 4966a36c61f9SKrishna Gudipati n_pids); 4967a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4968a36c61f9SKrishna Gudipati break; 4969a36c61f9SKrishna Gudipati 4970a36c61f9SKrishna Gudipati case CT_RSP_REJECT: 4971a36c61f9SKrishna Gudipati 4972a36c61f9SKrishna Gudipati /* 4973a36c61f9SKrishna Gudipati * Check the reason code & explanation. 4974a36c61f9SKrishna Gudipati * There may not have been any FC4 devices in the fabric 4975a36c61f9SKrishna Gudipati */ 4976a36c61f9SKrishna Gudipati port->stats.ns_gidft_rejects++; 4977a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4978a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4979a36c61f9SKrishna Gudipati 4980a36c61f9SKrishna Gudipati if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) 4981a36c61f9SKrishna Gudipati && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { 4982a36c61f9SKrishna Gudipati 4983a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4984a36c61f9SKrishna Gudipati } else { 4985a36c61f9SKrishna Gudipati /* 4986a36c61f9SKrishna Gudipati * for all other errors, retry 4987a36c61f9SKrishna Gudipati */ 4988a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4989a36c61f9SKrishna Gudipati } 4990a36c61f9SKrishna Gudipati break; 4991a36c61f9SKrishna Gudipati 4992a36c61f9SKrishna Gudipati default: 4993a36c61f9SKrishna Gudipati port->stats.ns_gidft_unknown_rsp++; 4994a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->cmd_rsp_code); 4995a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4996a36c61f9SKrishna Gudipati } 4997a36c61f9SKrishna Gudipati } 4998a36c61f9SKrishna Gudipati 49995fbe25c7SJing Huang /* 5000a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 5001a36c61f9SKrishna Gudipati * 5002a36c61f9SKrishna Gudipati * param[in] port - pointer to bfa_fcs_lport_t. 5003a36c61f9SKrishna Gudipati * 5004a36c61f9SKrishna Gudipati * return 5005a36c61f9SKrishna Gudipati * void 5006a36c61f9SKrishna Gudipati * 5007a36c61f9SKrishna Gudipati * Special Considerations: 5008a36c61f9SKrishna Gudipati * 5009a36c61f9SKrishna Gudipati * note 5010a36c61f9SKrishna Gudipati */ 5011a36c61f9SKrishna Gudipati static void 5012a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg) 5013a36c61f9SKrishna Gudipati { 5014a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg; 5015a36c61f9SKrishna Gudipati 5016a36c61f9SKrishna Gudipati ns->port->stats.ns_timeouts++; 5017a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT); 5018a36c61f9SKrishna Gudipati } 5019a36c61f9SKrishna Gudipati 5020a36c61f9SKrishna Gudipati /* 5021a36c61f9SKrishna Gudipati * Process the PID list in GID_FT response 5022a36c61f9SKrishna Gudipati */ 5023a36c61f9SKrishna Gudipati static void 5024a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf, 5025a36c61f9SKrishna Gudipati u32 n_pids) 5026a36c61f9SKrishna Gudipati { 5027a36c61f9SKrishna Gudipati struct fcgs_gidft_resp_s *gidft_entry; 5028a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 5029a36c61f9SKrishna Gudipati u32 ii; 503061ba4394SKrishna Gudipati struct bfa_fcs_fabric_s *fabric = port->fabric; 503161ba4394SKrishna Gudipati struct bfa_fcs_vport_s *vport; 503261ba4394SKrishna Gudipati struct list_head *qe; 503361ba4394SKrishna Gudipati u8 found = 0; 5034a36c61f9SKrishna Gudipati 5035a36c61f9SKrishna Gudipati for (ii = 0; ii < n_pids; ii++) { 5036a36c61f9SKrishna Gudipati gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; 5037a36c61f9SKrishna Gudipati 5038a36c61f9SKrishna Gudipati if (gidft_entry->pid == port->pid) 5039a36c61f9SKrishna Gudipati continue; 5040a36c61f9SKrishna Gudipati 5041a36c61f9SKrishna Gudipati /* 504261ba4394SKrishna Gudipati * Ignore PID if it is of base port 504361ba4394SKrishna Gudipati * (Avoid vports discovering base port as remote port) 504461ba4394SKrishna Gudipati */ 504561ba4394SKrishna Gudipati if (gidft_entry->pid == fabric->bport.pid) 504661ba4394SKrishna Gudipati continue; 504761ba4394SKrishna Gudipati 504861ba4394SKrishna Gudipati /* 504961ba4394SKrishna Gudipati * Ignore PID if it is of vport created on the same base port 505061ba4394SKrishna Gudipati * (Avoid vport discovering every other vport created on the 505161ba4394SKrishna Gudipati * same port as remote port) 505261ba4394SKrishna Gudipati */ 505361ba4394SKrishna Gudipati list_for_each(qe, &fabric->vport_q) { 505461ba4394SKrishna Gudipati vport = (struct bfa_fcs_vport_s *) qe; 505561ba4394SKrishna Gudipati if (vport->lport.pid == gidft_entry->pid) 505661ba4394SKrishna Gudipati found = 1; 505761ba4394SKrishna Gudipati } 505861ba4394SKrishna Gudipati 505961ba4394SKrishna Gudipati if (found) { 506061ba4394SKrishna Gudipati found = 0; 506161ba4394SKrishna Gudipati continue; 506261ba4394SKrishna Gudipati } 506361ba4394SKrishna Gudipati 506461ba4394SKrishna Gudipati /* 5065a36c61f9SKrishna Gudipati * Check if this rport already exists 5066a36c61f9SKrishna Gudipati */ 5067a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid); 5068a36c61f9SKrishna Gudipati if (rport == NULL) { 5069a36c61f9SKrishna Gudipati /* 5070a36c61f9SKrishna Gudipati * this is a new device. create rport 5071a36c61f9SKrishna Gudipati */ 5072a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, gidft_entry->pid); 5073a36c61f9SKrishna Gudipati } else { 5074a36c61f9SKrishna Gudipati /* 5075a36c61f9SKrishna Gudipati * this rport already exists 5076a36c61f9SKrishna Gudipati */ 5077a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 5078a36c61f9SKrishna Gudipati } 5079a36c61f9SKrishna Gudipati 5080a36c61f9SKrishna Gudipati bfa_trc(port->fcs, gidft_entry->pid); 5081a36c61f9SKrishna Gudipati 5082a36c61f9SKrishna Gudipati /* 5083a36c61f9SKrishna Gudipati * if the last entry bit is set, bail out. 5084a36c61f9SKrishna Gudipati */ 5085a36c61f9SKrishna Gudipati if (gidft_entry->last) 5086a36c61f9SKrishna Gudipati return; 5087a36c61f9SKrishna Gudipati } 5088a36c61f9SKrishna Gudipati } 5089a36c61f9SKrishna Gudipati 50905fbe25c7SJing Huang /* 5091a36c61f9SKrishna Gudipati * fcs_ns_public FCS nameserver public interfaces 5092a36c61f9SKrishna Gudipati */ 5093a36c61f9SKrishna Gudipati 5094a36c61f9SKrishna Gudipati /* 5095a36c61f9SKrishna Gudipati * Functions called by port/fab. 5096a36c61f9SKrishna Gudipati * These will send relevant Events to the ns state machine. 5097a36c61f9SKrishna Gudipati */ 5098a36c61f9SKrishna Gudipati void 5099a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port) 5100a36c61f9SKrishna Gudipati { 5101a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 5102a36c61f9SKrishna Gudipati 5103a36c61f9SKrishna Gudipati ns->port = port; 5104a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 5105a36c61f9SKrishna Gudipati } 5106a36c61f9SKrishna Gudipati 5107a36c61f9SKrishna Gudipati void 5108a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port) 5109a36c61f9SKrishna Gudipati { 5110a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 5111a36c61f9SKrishna Gudipati 5112a36c61f9SKrishna Gudipati ns->port = port; 5113a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE); 5114a36c61f9SKrishna Gudipati } 5115a36c61f9SKrishna Gudipati 5116a36c61f9SKrishna Gudipati void 5117a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port) 5118a36c61f9SKrishna Gudipati { 5119a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 5120a36c61f9SKrishna Gudipati 5121a36c61f9SKrishna Gudipati ns->port = port; 5122a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE); 5123a36c61f9SKrishna Gudipati } 5124a36c61f9SKrishna Gudipati 5125a36c61f9SKrishna Gudipati void 5126a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port) 5127a36c61f9SKrishna Gudipati { 5128a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 5129a36c61f9SKrishna Gudipati 5130a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 513161ba4394SKrishna Gudipati if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_online)) 5132a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 5133a36c61f9SKrishna Gudipati } 5134a36c61f9SKrishna Gudipati 513552f94b6fSMaggie static void 5136a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port) 5137a36c61f9SKrishna Gudipati { 5138a36c61f9SKrishna Gudipati 5139a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 5140a36c61f9SKrishna Gudipati u8 nwwns; 5141a36c61f9SKrishna Gudipati wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; 5142a36c61f9SKrishna Gudipati int ii; 5143a36c61f9SKrishna Gudipati 5144a36c61f9SKrishna Gudipati bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns); 5145a36c61f9SKrishna Gudipati 5146a36c61f9SKrishna Gudipati for (ii = 0 ; ii < nwwns; ++ii) { 5147a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]); 5148d4b671c5SJing Huang WARN_ON(!rport); 5149a36c61f9SKrishna Gudipati } 5150a36c61f9SKrishna Gudipati } 5151a36c61f9SKrishna Gudipati 5152ebfe8392SKrishna Gudipati void 5153ebfe8392SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) 5154ebfe8392SKrishna Gudipati { 5155ebfe8392SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = cbarg; 5156ebfe8392SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 5157ebfe8392SKrishna Gudipati struct fchs_s fchs; 5158ebfe8392SKrishna Gudipati struct bfa_fcxp_s *fcxp; 5159ebfe8392SKrishna Gudipati u8 symbl[256]; 5160ebfe8392SKrishna Gudipati int len; 5161ebfe8392SKrishna Gudipati 5162ebfe8392SKrishna Gudipati /* Avoid sending RSPN in the following states. */ 5163ebfe8392SKrishna Gudipati if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) || 5164ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) || 5165ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) || 5166ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) || 5167ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry)) 5168ebfe8392SKrishna Gudipati return; 5169ebfe8392SKrishna Gudipati 5170ebfe8392SKrishna Gudipati memset(symbl, 0, sizeof(symbl)); 5171ebfe8392SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 5172ebfe8392SKrishna Gudipati 5173c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 5174c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5175ebfe8392SKrishna Gudipati if (!fcxp) { 5176ebfe8392SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 5177ebfe8392SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 5178c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE); 5179ebfe8392SKrishna Gudipati return; 5180ebfe8392SKrishna Gudipati } 5181ebfe8392SKrishna Gudipati 5182ebfe8392SKrishna Gudipati ns->fcxp = fcxp; 5183ebfe8392SKrishna Gudipati 5184ebfe8392SKrishna Gudipati if (port->vport) { 5185ebfe8392SKrishna Gudipati /* 5186ebfe8392SKrishna Gudipati * For Vports, we append the vport's port symbolic name 5187ebfe8392SKrishna Gudipati * to that of the base port. 5188ebfe8392SKrishna Gudipati */ 51898c5a50e8SArnd Bergmann strlcpy(symbl, (char *)&(bfa_fcs_lport_get_psym_name 5190ebfe8392SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 51918c5a50e8SArnd Bergmann sizeof(symbl)); 5192ebfe8392SKrishna Gudipati 51938c5a50e8SArnd Bergmann strlcat(symbl, 5194ebfe8392SKrishna Gudipati (char *)&(bfa_fcs_lport_get_psym_name(port)), 51958c5a50e8SArnd Bergmann sizeof(symbl)); 5196ebfe8392SKrishna Gudipati } 5197ebfe8392SKrishna Gudipati 5198ebfe8392SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 51998c5a50e8SArnd Bergmann bfa_fcs_lport_get_fcid(port), 0, symbl); 5200ebfe8392SKrishna Gudipati 5201ebfe8392SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 5202ebfe8392SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 5203ebfe8392SKrishna Gudipati 5204ebfe8392SKrishna Gudipati port->stats.ns_rspnid_sent++; 5205ebfe8392SKrishna Gudipati } 5206ebfe8392SKrishna Gudipati 52075fbe25c7SJing Huang /* 5208a36c61f9SKrishna Gudipati * FCS SCN 5209a36c61f9SKrishna Gudipati */ 5210a36c61f9SKrishna Gudipati 5211a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT 0x0c 5212a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT 0x0d 5213a36c61f9SKrishna Gudipati 5214a36c61f9SKrishna Gudipati /* 5215a36c61f9SKrishna Gudipati * forward declarations 5216a36c61f9SKrishna Gudipati */ 5217a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg, 5218a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 5219a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_scr_response(void *fcsarg, 5220a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 5221a36c61f9SKrishna Gudipati void *cbarg, 5222a36c61f9SKrishna Gudipati bfa_status_t req_status, 5223a36c61f9SKrishna Gudipati u32 rsp_len, 5224a36c61f9SKrishna Gudipati u32 resid_len, 5225a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 5226a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 5227a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs); 5228a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_timeout(void *arg); 5229a36c61f9SKrishna Gudipati 52305fbe25c7SJing Huang /* 5231a36c61f9SKrishna Gudipati * fcs_scm_sm FCS SCN state machine 5232a36c61f9SKrishna Gudipati */ 5233a36c61f9SKrishna Gudipati 52345fbe25c7SJing Huang /* 5235a36c61f9SKrishna Gudipati * VPort SCN State Machine events 5236a36c61f9SKrishna Gudipati */ 5237a36c61f9SKrishna Gudipati enum port_scn_event { 5238a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_ONLINE = 1, 5239a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_OFFLINE = 2, 5240a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_OK = 3, 5241a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_ERROR = 4, 5242a36c61f9SKrishna Gudipati SCNSM_EVENT_TIMEOUT = 5, 5243a36c61f9SKrishna Gudipati SCNSM_EVENT_SCR_SENT = 6, 5244a36c61f9SKrishna Gudipati }; 5245a36c61f9SKrishna Gudipati 5246a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 5247a36c61f9SKrishna Gudipati enum port_scn_event event); 5248a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_sending_scr( 5249a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn, 5250a36c61f9SKrishna Gudipati enum port_scn_event event); 5251a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 5252a36c61f9SKrishna Gudipati enum port_scn_event event); 5253a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 5254a36c61f9SKrishna Gudipati enum port_scn_event event); 5255a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 5256a36c61f9SKrishna Gudipati enum port_scn_event event); 5257a36c61f9SKrishna Gudipati 52585fbe25c7SJing Huang /* 5259a36c61f9SKrishna Gudipati * Starting state - awaiting link up. 5260a36c61f9SKrishna Gudipati */ 5261a36c61f9SKrishna Gudipati static void 5262a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 5263a36c61f9SKrishna Gudipati enum port_scn_event event) 5264a36c61f9SKrishna Gudipati { 5265a36c61f9SKrishna Gudipati switch (event) { 5266a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_ONLINE: 5267a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 5268a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 5269a36c61f9SKrishna Gudipati break; 5270a36c61f9SKrishna Gudipati 5271a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5272a36c61f9SKrishna Gudipati break; 5273a36c61f9SKrishna Gudipati 5274a36c61f9SKrishna Gudipati default: 5275a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5276a36c61f9SKrishna Gudipati } 5277a36c61f9SKrishna Gudipati } 5278a36c61f9SKrishna Gudipati 5279a36c61f9SKrishna Gudipati static void 5280a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn, 5281a36c61f9SKrishna Gudipati enum port_scn_event event) 5282a36c61f9SKrishna Gudipati { 5283a36c61f9SKrishna Gudipati switch (event) { 5284a36c61f9SKrishna Gudipati case SCNSM_EVENT_SCR_SENT: 5285a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr); 5286a36c61f9SKrishna Gudipati break; 5287a36c61f9SKrishna Gudipati 5288a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5289a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5290a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe); 5291a36c61f9SKrishna Gudipati break; 5292a36c61f9SKrishna Gudipati 5293a36c61f9SKrishna Gudipati default: 5294a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5295a36c61f9SKrishna Gudipati } 5296a36c61f9SKrishna Gudipati } 5297a36c61f9SKrishna Gudipati 5298a36c61f9SKrishna Gudipati static void 5299a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 5300a36c61f9SKrishna Gudipati enum port_scn_event event) 5301a36c61f9SKrishna Gudipati { 5302a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 5303a36c61f9SKrishna Gudipati 5304a36c61f9SKrishna Gudipati switch (event) { 5305a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_OK: 5306a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online); 5307a36c61f9SKrishna Gudipati break; 5308a36c61f9SKrishna Gudipati 5309a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_ERROR: 5310a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry); 5311a36c61f9SKrishna Gudipati bfa_timer_start(port->fcs->bfa, &scn->timer, 5312a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout, scn, 5313a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 5314a36c61f9SKrishna Gudipati break; 5315a36c61f9SKrishna Gudipati 5316a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5317a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5318a36c61f9SKrishna Gudipati bfa_fcxp_discard(scn->fcxp); 5319a36c61f9SKrishna Gudipati break; 5320a36c61f9SKrishna Gudipati 5321a36c61f9SKrishna Gudipati default: 5322a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 5323a36c61f9SKrishna Gudipati } 5324a36c61f9SKrishna Gudipati } 5325a36c61f9SKrishna Gudipati 5326a36c61f9SKrishna Gudipati static void 5327a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 5328a36c61f9SKrishna Gudipati enum port_scn_event event) 5329a36c61f9SKrishna Gudipati { 5330a36c61f9SKrishna Gudipati switch (event) { 5331a36c61f9SKrishna Gudipati case SCNSM_EVENT_TIMEOUT: 5332a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 5333a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 5334a36c61f9SKrishna Gudipati break; 5335a36c61f9SKrishna Gudipati 5336a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5337a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5338a36c61f9SKrishna Gudipati bfa_timer_stop(&scn->timer); 5339a36c61f9SKrishna Gudipati break; 5340a36c61f9SKrishna Gudipati 5341a36c61f9SKrishna Gudipati default: 5342a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5343a36c61f9SKrishna Gudipati } 5344a36c61f9SKrishna Gudipati } 5345a36c61f9SKrishna Gudipati 5346a36c61f9SKrishna Gudipati static void 5347a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 5348a36c61f9SKrishna Gudipati enum port_scn_event event) 5349a36c61f9SKrishna Gudipati { 5350a36c61f9SKrishna Gudipati switch (event) { 5351a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5352a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5353a36c61f9SKrishna Gudipati break; 5354a36c61f9SKrishna Gudipati 5355a36c61f9SKrishna Gudipati default: 5356a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5357a36c61f9SKrishna Gudipati } 5358a36c61f9SKrishna Gudipati } 5359a36c61f9SKrishna Gudipati 5360a36c61f9SKrishna Gudipati 5361a36c61f9SKrishna Gudipati 53625fbe25c7SJing Huang /* 5363a36c61f9SKrishna Gudipati * fcs_scn_private FCS SCN private functions 5364a36c61f9SKrishna Gudipati */ 5365a36c61f9SKrishna Gudipati 53665fbe25c7SJing Huang /* 5367a36c61f9SKrishna Gudipati * This routine will be called to send a SCR command. 5368a36c61f9SKrishna Gudipati */ 5369a36c61f9SKrishna Gudipati static void 5370a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced) 5371a36c61f9SKrishna Gudipati { 5372a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = scn_cbarg; 5373a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 5374a36c61f9SKrishna Gudipati struct fchs_s fchs; 5375a36c61f9SKrishna Gudipati int len; 5376a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 5377a36c61f9SKrishna Gudipati 5378a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 5379a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 5380a36c61f9SKrishna Gudipati 5381c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 5382c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 5383a36c61f9SKrishna Gudipati if (!fcxp) { 5384a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, 5385c3f1b123SKrishna Gudipati bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE); 5386a36c61f9SKrishna Gudipati return; 5387a36c61f9SKrishna Gudipati } 5388a36c61f9SKrishna Gudipati scn->fcxp = fcxp; 5389a36c61f9SKrishna Gudipati 5390a36c61f9SKrishna Gudipati /* Handle VU registrations for Base port only */ 5391a36c61f9SKrishna Gudipati if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) { 5392a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 5393f7f73812SMaggie Zhang port->fabric->lps->brcd_switch, 5394a36c61f9SKrishna Gudipati port->pid, 0); 5395a36c61f9SKrishna Gudipati } else { 5396a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 5397a36c61f9SKrishna Gudipati BFA_FALSE, 5398a36c61f9SKrishna Gudipati port->pid, 0); 5399a36c61f9SKrishna Gudipati } 5400a36c61f9SKrishna Gudipati 5401a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 5402a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 5403a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response, 5404a36c61f9SKrishna Gudipati (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV); 5405a36c61f9SKrishna Gudipati 5406a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT); 5407a36c61f9SKrishna Gudipati } 5408a36c61f9SKrishna Gudipati 5409a36c61f9SKrishna Gudipati static void 5410a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 5411a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 5412a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 5413a36c61f9SKrishna Gudipati { 5414a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg; 5415a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 5416a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 5417a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 5418a36c61f9SKrishna Gudipati 5419a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 5420a36c61f9SKrishna Gudipati 5421a36c61f9SKrishna Gudipati /* 5422a36c61f9SKrishna Gudipati * Sanity Checks 5423a36c61f9SKrishna Gudipati */ 5424a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 5425a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 5426a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 5427a36c61f9SKrishna Gudipati return; 5428a36c61f9SKrishna Gudipati } 5429a36c61f9SKrishna Gudipati 5430a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 5431a36c61f9SKrishna Gudipati 5432a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 5433a36c61f9SKrishna Gudipati 5434a36c61f9SKrishna Gudipati case FC_ELS_ACC: 5435a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK); 5436a36c61f9SKrishna Gudipati break; 5437a36c61f9SKrishna Gudipati 5438a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 5439a36c61f9SKrishna Gudipati 5440a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 5441a36c61f9SKrishna Gudipati 5442a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 5443a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 5444a36c61f9SKrishna Gudipati 5445a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 5446a36c61f9SKrishna Gudipati break; 5447a36c61f9SKrishna Gudipati 5448a36c61f9SKrishna Gudipati default: 5449a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 5450a36c61f9SKrishna Gudipati } 5451a36c61f9SKrishna Gudipati } 5452a36c61f9SKrishna Gudipati 5453a36c61f9SKrishna Gudipati /* 5454a36c61f9SKrishna Gudipati * Send a LS Accept 5455a36c61f9SKrishna Gudipati */ 5456a36c61f9SKrishna Gudipati static void 5457a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 5458a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs) 5459a36c61f9SKrishna Gudipati { 5460a36c61f9SKrishna Gudipati struct fchs_s fchs; 5461a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 5462a36c61f9SKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 5463a36c61f9SKrishna Gudipati int len; 5464a36c61f9SKrishna Gudipati 5465a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 5466a36c61f9SKrishna Gudipati 5467c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5468a36c61f9SKrishna Gudipati if (!fcxp) 5469a36c61f9SKrishna Gudipati return; 5470a36c61f9SKrishna Gudipati 5471a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 5472a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 5473a36c61f9SKrishna Gudipati rx_fchs->ox_id); 5474a36c61f9SKrishna Gudipati 5475a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5476a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 5477a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 5478a36c61f9SKrishna Gudipati } 5479a36c61f9SKrishna Gudipati 54805fbe25c7SJing Huang /* 5481a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 5482a36c61f9SKrishna Gudipati * 5483a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_lport_t. 5484a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 5485a36c61f9SKrishna Gudipati * 5486a36c61f9SKrishna Gudipati * return 5487a36c61f9SKrishna Gudipati * void 5488a36c61f9SKrishna Gudipati * 5489a36c61f9SKrishna Gudipati * Special Considerations: 5490a36c61f9SKrishna Gudipati * 5491a36c61f9SKrishna Gudipati * note 5492a36c61f9SKrishna Gudipati */ 5493a36c61f9SKrishna Gudipati static void 5494a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg) 5495a36c61f9SKrishna Gudipati { 5496a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg; 5497a36c61f9SKrishna Gudipati 5498a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT); 5499a36c61f9SKrishna Gudipati } 5500a36c61f9SKrishna Gudipati 5501a36c61f9SKrishna Gudipati 5502a36c61f9SKrishna Gudipati 55035fbe25c7SJing Huang /* 5504a36c61f9SKrishna Gudipati * fcs_scn_public FCS state change notification public interfaces 5505a36c61f9SKrishna Gudipati */ 5506a36c61f9SKrishna Gudipati 5507a36c61f9SKrishna Gudipati /* 5508a36c61f9SKrishna Gudipati * Functions called by port/fab 5509a36c61f9SKrishna Gudipati */ 5510a36c61f9SKrishna Gudipati void 5511a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port) 5512a36c61f9SKrishna Gudipati { 5513a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5514a36c61f9SKrishna Gudipati 5515a36c61f9SKrishna Gudipati scn->port = port; 5516a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5517a36c61f9SKrishna Gudipati } 5518a36c61f9SKrishna Gudipati 5519a36c61f9SKrishna Gudipati void 5520a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port) 5521a36c61f9SKrishna Gudipati { 5522a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5523a36c61f9SKrishna Gudipati 5524a36c61f9SKrishna Gudipati scn->port = port; 5525a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE); 5526a36c61f9SKrishna Gudipati } 5527a36c61f9SKrishna Gudipati 5528a36c61f9SKrishna Gudipati void 5529bc0e2c2aSKrishna Gudipati bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port) 5530a36c61f9SKrishna Gudipati { 5531a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5532a36c61f9SKrishna Gudipati 5533a36c61f9SKrishna Gudipati scn->port = port; 5534a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE); 5535a36c61f9SKrishna Gudipati } 5536a36c61f9SKrishna Gudipati 5537a36c61f9SKrishna Gudipati static void 5538a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) 5539a36c61f9SKrishna Gudipati { 5540a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 554161ba4394SKrishna Gudipati struct bfa_fcs_fabric_s *fabric = port->fabric; 554261ba4394SKrishna Gudipati struct bfa_fcs_vport_s *vport; 554361ba4394SKrishna Gudipati struct list_head *qe; 5544a36c61f9SKrishna Gudipati 5545a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rpid); 5546a36c61f9SKrishna Gudipati 55475fbe25c7SJing Huang /* 554861ba4394SKrishna Gudipati * Ignore PID if it is of base port or of vports created on the 554961ba4394SKrishna Gudipati * same base port. It is to avoid vports discovering base port or 555061ba4394SKrishna Gudipati * other vports created on same base port as remote port 555161ba4394SKrishna Gudipati */ 555261ba4394SKrishna Gudipati if (rpid == fabric->bport.pid) 555361ba4394SKrishna Gudipati return; 555461ba4394SKrishna Gudipati 555561ba4394SKrishna Gudipati list_for_each(qe, &fabric->vport_q) { 555661ba4394SKrishna Gudipati vport = (struct bfa_fcs_vport_s *) qe; 555761ba4394SKrishna Gudipati if (vport->lport.pid == rpid) 555861ba4394SKrishna Gudipati return; 555961ba4394SKrishna Gudipati } 556061ba4394SKrishna Gudipati /* 5561a36c61f9SKrishna Gudipati * If this is an unknown device, then it just came online. 5562a36c61f9SKrishna Gudipati * Otherwise let rport handle the RSCN event. 5563a36c61f9SKrishna Gudipati */ 5564a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 5565ee1a4a42SKrishna Gudipati if (!rport) 5566ee1a4a42SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid); 5567ee1a4a42SKrishna Gudipati 5568a36c61f9SKrishna Gudipati if (rport == NULL) { 5569a36c61f9SKrishna Gudipati /* 5570a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot need to 5571a36c61f9SKrishna Gudipati * discover any new rports. 5572a36c61f9SKrishna Gudipati */ 5573a36c61f9SKrishna Gudipati if (!__fcs_min_cfg(port->fcs)) 5574a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, rpid); 5575a36c61f9SKrishna Gudipati } else 5576a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 5577a36c61f9SKrishna Gudipati } 5578a36c61f9SKrishna Gudipati 55795fbe25c7SJing Huang /* 5580a36c61f9SKrishna Gudipati * rscn format based PID comparison 5581a36c61f9SKrishna Gudipati */ 5582a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt) \ 5583a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \ 5584a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \ 5585a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0])) || \ 5586a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_AREA) && \ 5587a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0]) && \ 5588a36c61f9SKrishna Gudipati ((__c0)[1] == (__c1)[1]))) 5589a36c61f9SKrishna Gudipati 5590a36c61f9SKrishna Gudipati static void 5591a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port, 5592a36c61f9SKrishna Gudipati enum fc_rscn_format format, 5593a36c61f9SKrishna Gudipati u32 rscn_pid) 5594a36c61f9SKrishna Gudipati { 5595a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 5596a36c61f9SKrishna Gudipati struct list_head *qe, *qe_next; 5597a36c61f9SKrishna Gudipati u8 *c0, *c1; 5598a36c61f9SKrishna Gudipati 5599a36c61f9SKrishna Gudipati bfa_trc(port->fcs, format); 5600a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5601a36c61f9SKrishna Gudipati 5602a36c61f9SKrishna Gudipati c0 = (u8 *) &rscn_pid; 5603a36c61f9SKrishna Gudipati 5604a36c61f9SKrishna Gudipati list_for_each_safe(qe, qe_next, &port->rport_q) { 5605a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5606a36c61f9SKrishna Gudipati c1 = (u8 *) &rport->pid; 5607a36c61f9SKrishna Gudipati if (__fc_pid_match(c0, c1, format)) 5608a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 5609a36c61f9SKrishna Gudipati } 5610a36c61f9SKrishna Gudipati } 5611a36c61f9SKrishna Gudipati 5612a36c61f9SKrishna Gudipati 5613a36c61f9SKrishna Gudipati void 5614a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 5615a36c61f9SKrishna Gudipati struct fchs_s *fchs, u32 len) 5616a36c61f9SKrishna Gudipati { 5617a36c61f9SKrishna Gudipati struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1); 5618a36c61f9SKrishna Gudipati int num_entries; 5619a36c61f9SKrishna Gudipati u32 rscn_pid; 5620a36c61f9SKrishna Gudipati bfa_boolean_t nsquery = BFA_FALSE, found; 5621a36c61f9SKrishna Gudipati int i = 0, j; 5622a36c61f9SKrishna Gudipati 5623a36c61f9SKrishna Gudipati num_entries = 5624ba816ea8SJing Huang (be16_to_cpu(rscn->payldlen) - 5625a36c61f9SKrishna Gudipati sizeof(u32)) / sizeof(rscn->event[0]); 5626a36c61f9SKrishna Gudipati 5627a36c61f9SKrishna Gudipati bfa_trc(port->fcs, num_entries); 5628a36c61f9SKrishna Gudipati 5629a36c61f9SKrishna Gudipati port->stats.num_rscn++; 5630a36c61f9SKrishna Gudipati 5631a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(port, fchs); 5632a36c61f9SKrishna Gudipati 5633a36c61f9SKrishna Gudipati for (i = 0; i < num_entries; i++) { 5634a36c61f9SKrishna Gudipati rscn_pid = rscn->event[i].portid; 5635a36c61f9SKrishna Gudipati 5636a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn->event[i].format); 5637a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5638a36c61f9SKrishna Gudipati 5639a36c61f9SKrishna Gudipati /* check for duplicate entries in the list */ 5640a36c61f9SKrishna Gudipati found = BFA_FALSE; 5641a36c61f9SKrishna Gudipati for (j = 0; j < i; j++) { 5642a36c61f9SKrishna Gudipati if (rscn->event[j].portid == rscn_pid) { 5643a36c61f9SKrishna Gudipati found = BFA_TRUE; 5644a36c61f9SKrishna Gudipati break; 5645a36c61f9SKrishna Gudipati } 5646a36c61f9SKrishna Gudipati } 5647a36c61f9SKrishna Gudipati 5648a36c61f9SKrishna Gudipati /* if found in down the list, pid has been already processed */ 5649a36c61f9SKrishna Gudipati if (found) { 5650a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5651a36c61f9SKrishna Gudipati continue; 5652a36c61f9SKrishna Gudipati } 5653a36c61f9SKrishna Gudipati 5654a36c61f9SKrishna Gudipati switch (rscn->event[i].format) { 5655a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_PORTID: 5656a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) { 5657a36c61f9SKrishna Gudipati /* 5658a36c61f9SKrishna Gudipati * Ignore this event. 5659a36c61f9SKrishna Gudipati * f/w would have processed it 5660a36c61f9SKrishna Gudipati */ 5661a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5662a36c61f9SKrishna Gudipati } else { 5663a36c61f9SKrishna Gudipati port->stats.num_portid_rscn++; 5664a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(port, rscn_pid); 5665a36c61f9SKrishna Gudipati } 5666a36c61f9SKrishna Gudipati break; 5667a36c61f9SKrishna Gudipati 5668a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_FABRIC: 5669a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == 5670a36c61f9SKrishna Gudipati FC_FABRIC_NAME_RSCN_EVENT) { 5671a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(port); 5672a36c61f9SKrishna Gudipati break; 5673a36c61f9SKrishna Gudipati } 5674a36c61f9SKrishna Gudipati /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */ 5675a36c61f9SKrishna Gudipati 5676a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_AREA: 5677a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_DOMAIN: 5678a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 5679a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(port, 5680a36c61f9SKrishna Gudipati rscn->event[i].format, 5681a36c61f9SKrishna Gudipati rscn_pid); 5682a36c61f9SKrishna Gudipati break; 5683a36c61f9SKrishna Gudipati 5684a36c61f9SKrishna Gudipati 5685a36c61f9SKrishna Gudipati default: 5686d4b671c5SJing Huang WARN_ON(1); 5687a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 5688a36c61f9SKrishna Gudipati } 5689a36c61f9SKrishna Gudipati } 5690a36c61f9SKrishna Gudipati 56915fbe25c7SJing Huang /* 56925fbe25c7SJing Huang * If any of area, domain or fabric RSCN is received, do a fresh 56935fbe25c7SJing Huang * discovery to find new devices. 5694a36c61f9SKrishna Gudipati */ 5695a36c61f9SKrishna Gudipati if (nsquery) 5696a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(port); 5697a36c61f9SKrishna Gudipati } 5698a36c61f9SKrishna Gudipati 56995fbe25c7SJing Huang /* 5700a36c61f9SKrishna Gudipati * BFA FCS port 5701a36c61f9SKrishna Gudipati */ 57025fbe25c7SJing Huang /* 5703a36c61f9SKrishna Gudipati * fcs_port_api BFA FCS port API 5704a36c61f9SKrishna Gudipati */ 5705a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 5706a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs) 5707a36c61f9SKrishna Gudipati { 5708a36c61f9SKrishna Gudipati return &fcs->fabric.bport; 5709a36c61f9SKrishna Gudipati } 5710a36c61f9SKrishna Gudipati 5711a36c61f9SKrishna Gudipati wwn_t 5712a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, 5713a36c61f9SKrishna Gudipati int nrports, bfa_boolean_t bwwn) 5714a36c61f9SKrishna Gudipati { 5715a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5716a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5717a36c61f9SKrishna Gudipati int i; 5718a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5719a36c61f9SKrishna Gudipati 5720a36c61f9SKrishna Gudipati if (port == NULL || nrports == 0) 5721a36c61f9SKrishna Gudipati return (wwn_t) 0; 5722a36c61f9SKrishna Gudipati 5723a36c61f9SKrishna Gudipati fcs = port->fcs; 5724a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) nrports); 5725a36c61f9SKrishna Gudipati 5726a36c61f9SKrishna Gudipati i = 0; 5727a36c61f9SKrishna Gudipati qh = &port->rport_q; 5728a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5729a36c61f9SKrishna Gudipati 5730a36c61f9SKrishna Gudipati while ((qe != qh) && (i < nrports)) { 5731a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5732f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 5733a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5734a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 5735a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 5736a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5737a36c61f9SKrishna Gudipati continue; 5738a36c61f9SKrishna Gudipati } 5739a36c61f9SKrishna Gudipati 5740a36c61f9SKrishna Gudipati if (bwwn) { 5741a36c61f9SKrishna Gudipati if (!memcmp(&wwn, &rport->pwwn, 8)) 5742a36c61f9SKrishna Gudipati break; 5743a36c61f9SKrishna Gudipati } else { 5744a36c61f9SKrishna Gudipati if (i == index) 5745a36c61f9SKrishna Gudipati break; 5746a36c61f9SKrishna Gudipati } 5747a36c61f9SKrishna Gudipati 5748a36c61f9SKrishna Gudipati i++; 5749a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5750a36c61f9SKrishna Gudipati } 5751a36c61f9SKrishna Gudipati 5752a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5753a36c61f9SKrishna Gudipati if (rport) 5754a36c61f9SKrishna Gudipati return rport->pwwn; 5755a36c61f9SKrishna Gudipati else 5756a36c61f9SKrishna Gudipati return (wwn_t) 0; 5757a36c61f9SKrishna Gudipati } 5758a36c61f9SKrishna Gudipati 5759a36c61f9SKrishna Gudipati void 5760ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port, 5761ee1a4a42SKrishna Gudipati struct bfa_rport_qualifier_s rports[], int *nrports) 5762a36c61f9SKrishna Gudipati { 5763a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5764a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5765a36c61f9SKrishna Gudipati int i; 5766a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5767a36c61f9SKrishna Gudipati 5768ee1a4a42SKrishna Gudipati if (port == NULL || rports == NULL || *nrports == 0) 5769a36c61f9SKrishna Gudipati return; 5770a36c61f9SKrishna Gudipati 5771a36c61f9SKrishna Gudipati fcs = port->fcs; 5772a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) *nrports); 5773a36c61f9SKrishna Gudipati 5774a36c61f9SKrishna Gudipati i = 0; 5775a36c61f9SKrishna Gudipati qh = &port->rport_q; 5776a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5777a36c61f9SKrishna Gudipati 5778a36c61f9SKrishna Gudipati while ((qe != qh) && (i < *nrports)) { 5779a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5780f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 5781a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5782a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 5783a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 5784a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5785a36c61f9SKrishna Gudipati continue; 5786a36c61f9SKrishna Gudipati } 5787a36c61f9SKrishna Gudipati 5788ee1a4a42SKrishna Gudipati if (!rport->pwwn && !rport->pid) { 5789ee1a4a42SKrishna Gudipati qe = bfa_q_next(qe); 5790ee1a4a42SKrishna Gudipati continue; 5791ee1a4a42SKrishna Gudipati } 5792ee1a4a42SKrishna Gudipati 5793ee1a4a42SKrishna Gudipati rports[i].pwwn = rport->pwwn; 5794ee1a4a42SKrishna Gudipati rports[i].pid = rport->pid; 5795a36c61f9SKrishna Gudipati 5796a36c61f9SKrishna Gudipati i++; 5797a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5798a36c61f9SKrishna Gudipati } 5799a36c61f9SKrishna Gudipati 5800a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5801a36c61f9SKrishna Gudipati *nrports = i; 5802a36c61f9SKrishna Gudipati } 5803a36c61f9SKrishna Gudipati 5804a36c61f9SKrishna Gudipati /* 5805a36c61f9SKrishna Gudipati * Iterate's through all the rport's in the given port to 5806a36c61f9SKrishna Gudipati * determine the maximum operating speed. 5807a36c61f9SKrishna Gudipati * 5808a36c61f9SKrishna Gudipati * !!!! To be used in TRL Functionality only !!!! 5809a36c61f9SKrishna Gudipati */ 5810a36c61f9SKrishna Gudipati bfa_port_speed_t 5811a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) 5812a36c61f9SKrishna Gudipati { 5813a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5814a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5815a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5816a36c61f9SKrishna Gudipati bfa_port_speed_t max_speed = 0; 5817a36c61f9SKrishna Gudipati struct bfa_port_attr_s port_attr; 5818a36c61f9SKrishna Gudipati bfa_port_speed_t port_speed, rport_speed; 58195f6ac2ceSColin Ian King bfa_boolean_t trl_enabled; 5820a36c61f9SKrishna Gudipati 5821a36c61f9SKrishna Gudipati if (port == NULL) 5822a36c61f9SKrishna Gudipati return 0; 5823a36c61f9SKrishna Gudipati 5824a36c61f9SKrishna Gudipati fcs = port->fcs; 58255f6ac2ceSColin Ian King trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa); 5826a36c61f9SKrishna Gudipati 5827a36c61f9SKrishna Gudipati /* Get Physical port's current speed */ 5828a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &port_attr); 5829a36c61f9SKrishna Gudipati port_speed = port_attr.speed; 5830a36c61f9SKrishna Gudipati bfa_trc(fcs, port_speed); 5831a36c61f9SKrishna Gudipati 5832a36c61f9SKrishna Gudipati qh = &port->rport_q; 5833a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5834a36c61f9SKrishna Gudipati 5835a36c61f9SKrishna Gudipati while (qe != qh) { 5836a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5837f16a1750SMaggie Zhang if ((bfa_ntoh3b(rport->pid) > 0xFFF000) || 5838d7be54ccSKrishna Gudipati (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) || 5839d7be54ccSKrishna Gudipati (rport->scsi_function != BFA_RPORT_TARGET)) { 5840a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5841a36c61f9SKrishna Gudipati continue; 5842a36c61f9SKrishna Gudipati } 5843a36c61f9SKrishna Gudipati 5844a36c61f9SKrishna Gudipati rport_speed = rport->rpf.rpsc_speed; 5845a36c61f9SKrishna Gudipati if ((trl_enabled) && (rport_speed == 5846a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN)) { 5847a36c61f9SKrishna Gudipati /* Use default ratelim speed setting */ 5848a36c61f9SKrishna Gudipati rport_speed = 5849a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(port->fcs->bfa); 5850a36c61f9SKrishna Gudipati } 5851a36c61f9SKrishna Gudipati 5852d7be54ccSKrishna Gudipati if (rport_speed > max_speed) 5853a36c61f9SKrishna Gudipati max_speed = rport_speed; 5854a36c61f9SKrishna Gudipati 5855a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5856a36c61f9SKrishna Gudipati } 5857a36c61f9SKrishna Gudipati 5858d7be54ccSKrishna Gudipati if (max_speed > port_speed) 5859d7be54ccSKrishna Gudipati max_speed = port_speed; 5860d7be54ccSKrishna Gudipati 5861a36c61f9SKrishna Gudipati bfa_trc(fcs, max_speed); 5862a36c61f9SKrishna Gudipati return max_speed; 5863a36c61f9SKrishna Gudipati } 5864a36c61f9SKrishna Gudipati 5865a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 5866a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn) 5867a36c61f9SKrishna Gudipati { 5868a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 5869a36c61f9SKrishna Gudipati bfa_fcs_vf_t *vf; 5870a36c61f9SKrishna Gudipati 5871d4b671c5SJing Huang WARN_ON(fcs == NULL); 5872a36c61f9SKrishna Gudipati 5873a36c61f9SKrishna Gudipati vf = bfa_fcs_vf_lookup(fcs, vf_id); 5874a36c61f9SKrishna Gudipati if (vf == NULL) { 5875a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5876a36c61f9SKrishna Gudipati return NULL; 5877a36c61f9SKrishna Gudipati } 5878a36c61f9SKrishna Gudipati 5879a36c61f9SKrishna Gudipati if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn)) 5880a36c61f9SKrishna Gudipati return &vf->bport; 5881a36c61f9SKrishna Gudipati 5882a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn); 5883a36c61f9SKrishna Gudipati if (vport) 5884a36c61f9SKrishna Gudipati return &vport->lport; 5885a36c61f9SKrishna Gudipati 5886a36c61f9SKrishna Gudipati return NULL; 5887a36c61f9SKrishna Gudipati } 5888a36c61f9SKrishna Gudipati 5889a36c61f9SKrishna Gudipati /* 5890a36c61f9SKrishna Gudipati * API corresponding to NPIV_VPORT_GETINFO. 5891a36c61f9SKrishna Gudipati */ 5892a36c61f9SKrishna Gudipati void 5893a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port, 5894a36c61f9SKrishna Gudipati struct bfa_lport_info_s *port_info) 5895a36c61f9SKrishna Gudipati { 5896a36c61f9SKrishna Gudipati 5897a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->fabric->fabric_name); 5898a36c61f9SKrishna Gudipati 5899a36c61f9SKrishna Gudipati if (port->vport == NULL) { 5900a36c61f9SKrishna Gudipati /* 5901a36c61f9SKrishna Gudipati * This is a Physical port 5902a36c61f9SKrishna Gudipati */ 5903a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_PHYSICAL; 5904a36c61f9SKrishna Gudipati 5905a36c61f9SKrishna Gudipati /* 5906a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5907a36c61f9SKrishna Gudipati */ 5908a36c61f9SKrishna Gudipati port_info->port_state = 0; 5909a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5910a36c61f9SKrishna Gudipati 5911a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5912a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5913a36c61f9SKrishna Gudipati 5914a36c61f9SKrishna Gudipati port_info->max_vports_supp = 5915a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(port->fcs->bfa); 5916a36c61f9SKrishna Gudipati port_info->num_vports_inuse = 5917f7f73812SMaggie Zhang port->fabric->num_vports; 5918a36c61f9SKrishna Gudipati port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; 5919a36c61f9SKrishna Gudipati port_info->num_rports_inuse = port->num_rports; 5920a36c61f9SKrishna Gudipati } else { 5921a36c61f9SKrishna Gudipati /* 5922a36c61f9SKrishna Gudipati * This is a virtual port 5923a36c61f9SKrishna Gudipati */ 5924a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_VIRTUAL; 5925a36c61f9SKrishna Gudipati 5926a36c61f9SKrishna Gudipati /* 5927a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5928a36c61f9SKrishna Gudipati */ 5929a36c61f9SKrishna Gudipati port_info->port_state = 0; 5930a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5931a36c61f9SKrishna Gudipati 5932a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5933a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5934a36c61f9SKrishna Gudipati } 5935a36c61f9SKrishna Gudipati } 5936a36c61f9SKrishna Gudipati 5937a36c61f9SKrishna Gudipati void 5938a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port, 5939a36c61f9SKrishna Gudipati struct bfa_lport_stats_s *port_stats) 5940a36c61f9SKrishna Gudipati { 5941a36c61f9SKrishna Gudipati *port_stats = fcs_port->stats; 5942a36c61f9SKrishna Gudipati } 5943a36c61f9SKrishna Gudipati 5944a36c61f9SKrishna Gudipati void 5945a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) 5946a36c61f9SKrishna Gudipati { 59476a18b167SJing Huang memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s)); 5948a36c61f9SKrishna Gudipati } 5949a36c61f9SKrishna Gudipati 59505fbe25c7SJing Huang /* 5951bc0e2c2aSKrishna Gudipati * Let new loop map create missing rports 5952bc0e2c2aSKrishna Gudipati */ 5953bc0e2c2aSKrishna Gudipati void 5954bc0e2c2aSKrishna Gudipati bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port) 5955bc0e2c2aSKrishna Gudipati { 5956bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_online(port); 5957bc0e2c2aSKrishna Gudipati } 5958bc0e2c2aSKrishna Gudipati 5959bc0e2c2aSKrishna Gudipati /* 5960a36c61f9SKrishna Gudipati * FCS virtual port state machine 5961a36c61f9SKrishna Gudipati */ 5962a36c61f9SKrishna Gudipati 5963a36c61f9SKrishna Gudipati #define __vport_fcs(__vp) ((__vp)->lport.fcs) 5964a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn) 5965a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn) 5966a36c61f9SKrishna Gudipati #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa) 5967a36c61f9SKrishna Gudipati #define __vport_fcid(__vp) ((__vp)->lport.pid) 5968a36c61f9SKrishna Gudipati #define __vport_fabric(__vp) ((__vp)->lport.fabric) 5969a36c61f9SKrishna Gudipati #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id) 5970a36c61f9SKrishna Gudipati 5971a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES 5 5972a36c61f9SKrishna Gudipati /* 5973a36c61f9SKrishna Gudipati * Forward declarations 5974a36c61f9SKrishna Gudipati */ 5975a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport); 5976a36c61f9SKrishna Gudipati static void bfa_fcs_vport_timeout(void *vport_arg); 5977a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport); 5978a36c61f9SKrishna Gudipati static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport); 5979a36c61f9SKrishna Gudipati 59805fbe25c7SJing Huang /* 5981a36c61f9SKrishna Gudipati * fcs_vport_sm FCS virtual port state machine 5982a36c61f9SKrishna Gudipati */ 5983a36c61f9SKrishna Gudipati 59845fbe25c7SJing Huang /* 5985a36c61f9SKrishna Gudipati * VPort State Machine events 5986a36c61f9SKrishna Gudipati */ 5987a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event { 5988a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */ 5989a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */ 5990a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_START = 3, /* vport start request */ 5991a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */ 5992a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */ 5993a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */ 5994a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */ 5995a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */ 5996a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */ 5997a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */ 5998a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ 5999a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ 6000a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ 6001dd5aaf45SKrishna Gudipati BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ 6002f2a0cc3fSVijaya Mohan Guvva BFA_FCS_VPORT_SM_FABRIC_MAX = 15, /* max vports on fabric */ 6003a36c61f9SKrishna Gudipati }; 6004a36c61f9SKrishna Gudipati 6005a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 6006a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6007a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 6008a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6009a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 6010a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6011a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 6012a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6013a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 6014a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6015d7be54ccSKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 6016d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event); 6017a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 6018a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6019a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 6020a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6021a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 6022a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6023a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 6024a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6025a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 6026a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6027dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 6028dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 6029dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 6030dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 6031a36c61f9SKrishna Gudipati 6032a36c61f9SKrishna Gudipati static struct bfa_sm_table_s vport_sm_table[] = { 6033a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, 6034a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED}, 6035a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, 6036a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, 6037a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, 6038d7be54ccSKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT}, 6039a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, 6040a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, 6041a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, 6042a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO}, 6043a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR} 6044a36c61f9SKrishna Gudipati }; 6045a36c61f9SKrishna Gudipati 60465fbe25c7SJing Huang /* 6047a36c61f9SKrishna Gudipati * Beginning state. 6048a36c61f9SKrishna Gudipati */ 6049a36c61f9SKrishna Gudipati static void 6050a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 6051a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6052a36c61f9SKrishna Gudipati { 6053a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6054a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6055a36c61f9SKrishna Gudipati 6056a36c61f9SKrishna Gudipati switch (event) { 6057a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_CREATE: 6058a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 6059a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(__vport_fabric(vport), vport); 6060a36c61f9SKrishna Gudipati break; 6061a36c61f9SKrishna Gudipati 6062a36c61f9SKrishna Gudipati default: 6063a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6064a36c61f9SKrishna Gudipati } 6065a36c61f9SKrishna Gudipati } 6066a36c61f9SKrishna Gudipati 60675fbe25c7SJing Huang /* 6068a36c61f9SKrishna Gudipati * Created state - a start event is required to start up the state machine. 6069a36c61f9SKrishna Gudipati */ 6070a36c61f9SKrishna Gudipati static void 6071a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 6072a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6073a36c61f9SKrishna Gudipati { 6074a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6075a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6076a36c61f9SKrishna Gudipati 6077a36c61f9SKrishna Gudipati switch (event) { 6078a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_START: 6079f7f73812SMaggie Zhang if (bfa_sm_cmp_state(__vport_fabric(vport), 6080f7f73812SMaggie Zhang bfa_fcs_fabric_sm_online) 6081a36c61f9SKrishna Gudipati && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) { 6082a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 6083a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 6084a36c61f9SKrishna Gudipati } else { 60855fbe25c7SJing Huang /* 6086a36c61f9SKrishna Gudipati * Fabric is offline or not NPIV capable, stay in 6087a36c61f9SKrishna Gudipati * offline state. 6088a36c61f9SKrishna Gudipati */ 6089a36c61f9SKrishna Gudipati vport->vport_stats.fab_no_npiv++; 6090a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6091a36c61f9SKrishna Gudipati } 6092a36c61f9SKrishna Gudipati break; 6093a36c61f9SKrishna Gudipati 6094a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6095a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6096a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6097a36c61f9SKrishna Gudipati break; 6098a36c61f9SKrishna Gudipati 6099a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 6100a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 61015fbe25c7SJing Huang /* 6102a36c61f9SKrishna Gudipati * Ignore ONLINE/OFFLINE events from fabric 6103a36c61f9SKrishna Gudipati * till vport is started. 6104a36c61f9SKrishna Gudipati */ 6105a36c61f9SKrishna Gudipati break; 6106a36c61f9SKrishna Gudipati 6107a36c61f9SKrishna Gudipati default: 6108a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6109a36c61f9SKrishna Gudipati } 6110a36c61f9SKrishna Gudipati } 6111a36c61f9SKrishna Gudipati 61125fbe25c7SJing Huang /* 6113a36c61f9SKrishna Gudipati * Offline state - awaiting ONLINE event from fabric SM. 6114a36c61f9SKrishna Gudipati */ 6115a36c61f9SKrishna Gudipati static void 6116a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 6117a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6118a36c61f9SKrishna Gudipati { 6119a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6120a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6121a36c61f9SKrishna Gudipati 6122a36c61f9SKrishna Gudipati switch (event) { 6123a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6124a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6125a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6126a36c61f9SKrishna Gudipati break; 6127a36c61f9SKrishna Gudipati 6128a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 6129a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 6130a36c61f9SKrishna Gudipati vport->fdisc_retries = 0; 6131a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 6132a36c61f9SKrishna Gudipati break; 6133a36c61f9SKrishna Gudipati 6134dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 6135dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6136dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 6137dd5aaf45SKrishna Gudipati break; 6138dd5aaf45SKrishna Gudipati 6139a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6140a36c61f9SKrishna Gudipati /* 6141a36c61f9SKrishna Gudipati * This can happen if the vport couldn't be initialzied 6142a36c61f9SKrishna Gudipati * due the fact that the npiv was not enabled on the switch. 6143a36c61f9SKrishna Gudipati * In that case we will put the vport in offline state. 6144a36c61f9SKrishna Gudipati * However, the link can go down and cause the this event to 6145a36c61f9SKrishna Gudipati * be sent when we are already offline. Ignore it. 6146a36c61f9SKrishna Gudipati */ 6147a36c61f9SKrishna Gudipati break; 6148a36c61f9SKrishna Gudipati 6149a36c61f9SKrishna Gudipati default: 6150a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6151a36c61f9SKrishna Gudipati } 6152a36c61f9SKrishna Gudipati } 6153a36c61f9SKrishna Gudipati 6154a36c61f9SKrishna Gudipati 61555fbe25c7SJing Huang /* 6156a36c61f9SKrishna Gudipati * FDISC is sent and awaiting reply from fabric. 6157a36c61f9SKrishna Gudipati */ 6158a36c61f9SKrishna Gudipati static void 6159a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 6160a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6161a36c61f9SKrishna Gudipati { 6162a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6163a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6164a36c61f9SKrishna Gudipati 6165a36c61f9SKrishna Gudipati switch (event) { 6166a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6167d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait); 6168a36c61f9SKrishna Gudipati break; 6169a36c61f9SKrishna Gudipati 6170a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6171a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6172f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6173a36c61f9SKrishna Gudipati break; 6174a36c61f9SKrishna Gudipati 6175a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6176a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_online); 6177a36c61f9SKrishna Gudipati bfa_fcs_lport_online(&vport->lport); 6178a36c61f9SKrishna Gudipati break; 6179a36c61f9SKrishna Gudipati 6180a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6181a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry); 6182a36c61f9SKrishna Gudipati bfa_timer_start(__vport_bfa(vport), &vport->timer, 6183a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout, vport, 6184a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 6185a36c61f9SKrishna Gudipati break; 6186a36c61f9SKrishna Gudipati 6187a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 6188f2a0cc3fSVijaya Mohan Guvva case BFA_FCS_VPORT_SM_FABRIC_MAX: 6189a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6190a36c61f9SKrishna Gudipati break; 6191a36c61f9SKrishna Gudipati 6192a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 6193a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_error); 6194a36c61f9SKrishna Gudipati break; 6195a36c61f9SKrishna Gudipati 6196a36c61f9SKrishna Gudipati default: 6197a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6198a36c61f9SKrishna Gudipati } 6199a36c61f9SKrishna Gudipati } 6200a36c61f9SKrishna Gudipati 62015fbe25c7SJing Huang /* 6202a36c61f9SKrishna Gudipati * FDISC attempt failed - a timer is active to retry FDISC. 6203a36c61f9SKrishna Gudipati */ 6204a36c61f9SKrishna Gudipati static void 6205a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 6206a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6207a36c61f9SKrishna Gudipati { 6208a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6209a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6210a36c61f9SKrishna Gudipati 6211a36c61f9SKrishna Gudipati switch (event) { 6212a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6213a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6214a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 6215a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6216a36c61f9SKrishna Gudipati break; 6217a36c61f9SKrishna Gudipati 6218a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6219a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6220a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 6221a36c61f9SKrishna Gudipati break; 6222a36c61f9SKrishna Gudipati 6223a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_TIMEOUT: 6224a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 6225a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_retries++; 6226a36c61f9SKrishna Gudipati vport->fdisc_retries++; 6227a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 6228a36c61f9SKrishna Gudipati break; 6229a36c61f9SKrishna Gudipati 6230a36c61f9SKrishna Gudipati default: 6231a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6232a36c61f9SKrishna Gudipati } 6233a36c61f9SKrishna Gudipati } 6234a36c61f9SKrishna Gudipati 62355fbe25c7SJing Huang /* 6236d7be54ccSKrishna Gudipati * FDISC is in progress and we got a vport delete request - 6237d7be54ccSKrishna Gudipati * this is a wait state while we wait for fdisc response and 6238d7be54ccSKrishna Gudipati * we will transition to the appropriate state - on rsp status. 6239d7be54ccSKrishna Gudipati */ 6240d7be54ccSKrishna Gudipati static void 6241d7be54ccSKrishna Gudipati bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 6242d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event) 6243d7be54ccSKrishna Gudipati { 6244d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6245d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6246d7be54ccSKrishna Gudipati 6247d7be54ccSKrishna Gudipati switch (event) { 6248d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6249d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 6250d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6251d7be54ccSKrishna Gudipati break; 6252d7be54ccSKrishna Gudipati 6253d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6254d7be54ccSKrishna Gudipati break; 6255d7be54ccSKrishna Gudipati 6256d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6257d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6258d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 6259f2a0cc3fSVijaya Mohan Guvva case BFA_FCS_VPORT_SM_FABRIC_MAX: 6260d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 6261d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6262d7be54ccSKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6263d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6264d7be54ccSKrishna Gudipati break; 6265d7be54ccSKrishna Gudipati 6266d7be54ccSKrishna Gudipati default: 6267d7be54ccSKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6268d7be54ccSKrishna Gudipati } 6269d7be54ccSKrishna Gudipati } 6270d7be54ccSKrishna Gudipati 6271d7be54ccSKrishna Gudipati /* 6272a36c61f9SKrishna Gudipati * Vport is online (FDISC is complete). 6273a36c61f9SKrishna Gudipati */ 6274a36c61f9SKrishna Gudipati static void 6275a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 6276a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6277a36c61f9SKrishna Gudipati { 6278a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6279a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6280a36c61f9SKrishna Gudipati 6281a36c61f9SKrishna Gudipati switch (event) { 6282a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6283a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 6284a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6285a36c61f9SKrishna Gudipati break; 6286a36c61f9SKrishna Gudipati 6287dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 6288dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping); 6289dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 6290dd5aaf45SKrishna Gudipati break; 6291dd5aaf45SKrishna Gudipati 6292a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6293a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6294f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6295a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(&vport->lport); 6296a36c61f9SKrishna Gudipati break; 6297a36c61f9SKrishna Gudipati 6298a36c61f9SKrishna Gudipati default: 6299a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6300a36c61f9SKrishna Gudipati } 6301a36c61f9SKrishna Gudipati } 6302a36c61f9SKrishna Gudipati 63035fbe25c7SJing Huang /* 6304dd5aaf45SKrishna Gudipati * Vport is being stopped - awaiting lport stop completion to send 6305dd5aaf45SKrishna Gudipati * LOGO to fabric. 6306dd5aaf45SKrishna Gudipati */ 6307dd5aaf45SKrishna Gudipati static void 6308dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 6309dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 6310dd5aaf45SKrishna Gudipati { 6311dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6312dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6313dd5aaf45SKrishna Gudipati 6314dd5aaf45SKrishna Gudipati switch (event) { 6315dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 6316dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop); 6317dd5aaf45SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 6318dd5aaf45SKrishna Gudipati break; 6319dd5aaf45SKrishna Gudipati 6320dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6321dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6322dd5aaf45SKrishna Gudipati break; 6323dd5aaf45SKrishna Gudipati 6324dd5aaf45SKrishna Gudipati default: 6325dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6326dd5aaf45SKrishna Gudipati } 6327dd5aaf45SKrishna Gudipati } 6328dd5aaf45SKrishna Gudipati 6329dd5aaf45SKrishna Gudipati /* 6330a36c61f9SKrishna Gudipati * Vport is being deleted - awaiting lport delete completion to send 6331a36c61f9SKrishna Gudipati * LOGO to fabric. 6332a36c61f9SKrishna Gudipati */ 6333a36c61f9SKrishna Gudipati static void 6334a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 6335a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6336a36c61f9SKrishna Gudipati { 6337a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6338a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6339a36c61f9SKrishna Gudipati 6340a36c61f9SKrishna Gudipati switch (event) { 6341a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6342a36c61f9SKrishna Gudipati break; 6343a36c61f9SKrishna Gudipati 6344a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 6345a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); 6346a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 6347a36c61f9SKrishna Gudipati break; 6348a36c61f9SKrishna Gudipati 6349a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6350a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6351a36c61f9SKrishna Gudipati break; 6352a36c61f9SKrishna Gudipati 6353a36c61f9SKrishna Gudipati default: 6354a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6355a36c61f9SKrishna Gudipati } 6356a36c61f9SKrishna Gudipati } 6357a36c61f9SKrishna Gudipati 63585fbe25c7SJing Huang /* 6359a36c61f9SKrishna Gudipati * Error State. 6360a36c61f9SKrishna Gudipati * This state will be set when the Vport Creation fails due 6361a36c61f9SKrishna Gudipati * to errors like Dup WWN. In this state only operation allowed 6362a36c61f9SKrishna Gudipati * is a Vport Delete. 6363a36c61f9SKrishna Gudipati */ 6364a36c61f9SKrishna Gudipati static void 6365a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 6366a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6367a36c61f9SKrishna Gudipati { 6368a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6369a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6370a36c61f9SKrishna Gudipati 6371a36c61f9SKrishna Gudipati switch (event) { 6372a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6373a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6374a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6375a36c61f9SKrishna Gudipati break; 6376a36c61f9SKrishna Gudipati 6377a36c61f9SKrishna Gudipati default: 6378a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6379a36c61f9SKrishna Gudipati } 6380a36c61f9SKrishna Gudipati } 6381a36c61f9SKrishna Gudipati 63825fbe25c7SJing Huang /* 6383a36c61f9SKrishna Gudipati * Lport cleanup is in progress since vport is being deleted. Fabric is 6384a36c61f9SKrishna Gudipati * offline, so no LOGO is needed to complete vport deletion. 6385a36c61f9SKrishna Gudipati */ 6386a36c61f9SKrishna Gudipati static void 6387a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 6388a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6389a36c61f9SKrishna Gudipati { 6390a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6391a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6392a36c61f9SKrishna Gudipati 6393a36c61f9SKrishna Gudipati switch (event) { 6394a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 6395a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 6396a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 6397a36c61f9SKrishna Gudipati break; 6398a36c61f9SKrishna Gudipati 6399dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 6400dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 6401dd5aaf45SKrishna Gudipati break; 6402dd5aaf45SKrishna Gudipati 6403a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6404a36c61f9SKrishna Gudipati break; 6405a36c61f9SKrishna Gudipati 6406a36c61f9SKrishna Gudipati default: 6407a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6408a36c61f9SKrishna Gudipati } 6409a36c61f9SKrishna Gudipati } 6410a36c61f9SKrishna Gudipati 64115fbe25c7SJing Huang /* 6412dd5aaf45SKrishna Gudipati * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup 6413dd5aaf45SKrishna Gudipati * is done. 6414dd5aaf45SKrishna Gudipati */ 6415dd5aaf45SKrishna Gudipati static void 6416dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 6417dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 6418dd5aaf45SKrishna Gudipati { 6419dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6420dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6421dd5aaf45SKrishna Gudipati 6422dd5aaf45SKrishna Gudipati switch (event) { 6423dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6424dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 64258425811bSGustavo A. R. Silva /* fall through */ 6426dd5aaf45SKrishna Gudipati 6427dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6428dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6429dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 6430dd5aaf45SKrishna Gudipati break; 6431dd5aaf45SKrishna Gudipati 6432dd5aaf45SKrishna Gudipati default: 6433dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6434dd5aaf45SKrishna Gudipati } 6435dd5aaf45SKrishna Gudipati } 6436dd5aaf45SKrishna Gudipati 6437dd5aaf45SKrishna Gudipati /* 6438a36c61f9SKrishna Gudipati * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup 6439a36c61f9SKrishna Gudipati * is done. 6440a36c61f9SKrishna Gudipati */ 6441a36c61f9SKrishna Gudipati static void 6442a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 6443a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6444a36c61f9SKrishna Gudipati { 6445a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6446a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6447a36c61f9SKrishna Gudipati 6448a36c61f9SKrishna Gudipati switch (event) { 6449a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6450f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 64518425811bSGustavo A. R. Silva /* fall through */ 6452a36c61f9SKrishna Gudipati 6453a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6454a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6455a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 6456a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 6457a36c61f9SKrishna Gudipati break; 6458a36c61f9SKrishna Gudipati 6459a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6460a36c61f9SKrishna Gudipati break; 6461a36c61f9SKrishna Gudipati 6462a36c61f9SKrishna Gudipati default: 6463a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6464a36c61f9SKrishna Gudipati } 6465a36c61f9SKrishna Gudipati } 6466a36c61f9SKrishna Gudipati 6467a36c61f9SKrishna Gudipati 6468a36c61f9SKrishna Gudipati 64695fbe25c7SJing Huang /* 6470a36c61f9SKrishna Gudipati * fcs_vport_private FCS virtual port private functions 6471a36c61f9SKrishna Gudipati */ 64725fbe25c7SJing Huang /* 64737826f304SKrishna Gudipati * Send AEN notification 64747826f304SKrishna Gudipati */ 64757826f304SKrishna Gudipati static void 64767826f304SKrishna Gudipati bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port, 64777826f304SKrishna Gudipati enum bfa_lport_aen_event event) 64787826f304SKrishna Gudipati { 64797826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 64807826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 64817826f304SKrishna Gudipati 64827826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 64837826f304SKrishna Gudipati if (!aen_entry) 64847826f304SKrishna Gudipati return; 64857826f304SKrishna Gudipati 64867826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 64877826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 64887826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 64897826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 64907826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 64917826f304SKrishna Gudipati 64927826f304SKrishna Gudipati /* Send the AEN notification */ 64937826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 64947826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 64957826f304SKrishna Gudipati } 64967826f304SKrishna Gudipati 64977826f304SKrishna Gudipati /* 6498a36c61f9SKrishna Gudipati * This routine will be called to send a FDISC command. 6499a36c61f9SKrishna Gudipati */ 6500a36c61f9SKrishna Gudipati static void 6501a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) 6502a36c61f9SKrishna Gudipati { 6503a36c61f9SKrishna Gudipati bfa_lps_fdisc(vport->lps, vport, 6504a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(__vport_bfa(vport)), 6505a36c61f9SKrishna Gudipati __vport_pwwn(vport), __vport_nwwn(vport)); 6506a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_sent++; 6507a36c61f9SKrishna Gudipati } 6508a36c61f9SKrishna Gudipati 6509a36c61f9SKrishna Gudipati static void 6510a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) 6511a36c61f9SKrishna Gudipati { 6512f7f73812SMaggie Zhang u8 lsrjt_rsn = vport->lps->lsrjt_rsn; 6513f7f73812SMaggie Zhang u8 lsrjt_expl = vport->lps->lsrjt_expl; 6514a36c61f9SKrishna Gudipati 6515a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_rsn); 6516a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_expl); 6517a36c61f9SKrishna Gudipati 6518a36c61f9SKrishna Gudipati /* For certain reason codes, we don't want to retry. */ 6519f7f73812SMaggie Zhang switch (vport->lps->lsrjt_expl) { 6520a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */ 6521a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ 6522a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6523a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 65247826f304SKrishna Gudipati else { 65257826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 65267826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_DUP_WWN); 6527a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); 65287826f304SKrishna Gudipati } 6529a36c61f9SKrishna Gudipati break; 6530a36c61f9SKrishna Gudipati 6531a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INSUFF_RES: 6532a36c61f9SKrishna Gudipati /* 6533a36c61f9SKrishna Gudipati * This means max logins per port/switch setting on the 6534a36c61f9SKrishna Gudipati * switch was exceeded. 6535a36c61f9SKrishna Gudipati */ 6536a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6537a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 65387826f304SKrishna Gudipati else { 65397826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 65407826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_FABRIC_MAX); 6541f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_FABRIC_MAX); 65427826f304SKrishna Gudipati } 6543a36c61f9SKrishna Gudipati break; 6544a36c61f9SKrishna Gudipati 6545a36c61f9SKrishna Gudipati default: 65467826f304SKrishna Gudipati if (vport->fdisc_retries == 0) 65477826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 65487826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_UNKNOWN); 6549a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6550a36c61f9SKrishna Gudipati } 6551a36c61f9SKrishna Gudipati } 6552a36c61f9SKrishna Gudipati 65535fbe25c7SJing Huang /* 6554a36c61f9SKrishna Gudipati * Called to send a logout to the fabric. Used when a V-Port is 6555a36c61f9SKrishna Gudipati * deleted/stopped. 6556a36c61f9SKrishna Gudipati */ 6557a36c61f9SKrishna Gudipati static void 6558a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport) 6559a36c61f9SKrishna Gudipati { 6560a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6561a36c61f9SKrishna Gudipati 6562a36c61f9SKrishna Gudipati vport->vport_stats.logo_sent++; 6563a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(vport->lps); 6564a36c61f9SKrishna Gudipati } 6565a36c61f9SKrishna Gudipati 6566a36c61f9SKrishna Gudipati 65675fbe25c7SJing Huang /* 6568a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 6569a36c61f9SKrishna Gudipati * 6570a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6571a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 6572a36c61f9SKrishna Gudipati * 6573a36c61f9SKrishna Gudipati * return 6574a36c61f9SKrishna Gudipati * void 6575a36c61f9SKrishna Gudipati * 6576a36c61f9SKrishna Gudipati * Special Considerations: 6577a36c61f9SKrishna Gudipati * 6578a36c61f9SKrishna Gudipati * note 6579a36c61f9SKrishna Gudipati */ 6580a36c61f9SKrishna Gudipati static void 6581a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg) 6582a36c61f9SKrishna Gudipati { 6583a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg; 6584a36c61f9SKrishna Gudipati 6585a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_timeouts++; 6586a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT); 6587a36c61f9SKrishna Gudipati } 6588a36c61f9SKrishna Gudipati 6589a36c61f9SKrishna Gudipati static void 6590a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) 6591a36c61f9SKrishna Gudipati { 6592a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv = 6593a36c61f9SKrishna Gudipati (struct bfad_vport_s *)vport->vport_drv; 6594a36c61f9SKrishna Gudipati 6595a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); 6596a36c61f9SKrishna Gudipati bfa_lps_delete(vport->lps); 659717c201b3SKrishna Gudipati 659817c201b3SKrishna Gudipati if (vport_drv->comp_del) { 659917c201b3SKrishna Gudipati complete(vport_drv->comp_del); 660017c201b3SKrishna Gudipati return; 6601a36c61f9SKrishna Gudipati } 6602a36c61f9SKrishna Gudipati 660317c201b3SKrishna Gudipati /* 660417c201b3SKrishna Gudipati * We queue the vport delete work to the IM work_q from here. 660517c201b3SKrishna Gudipati * The memory for the bfad_vport_s is freed from the FC function 660617c201b3SKrishna Gudipati * template vport_delete entry point. 660717c201b3SKrishna Gudipati */ 6608529f9a76SKrishna Gudipati bfad_im_port_delete(vport_drv->drv_port.bfad, &vport_drv->drv_port); 660917c201b3SKrishna Gudipati } 6610a36c61f9SKrishna Gudipati 66115fbe25c7SJing Huang /* 6612a36c61f9SKrishna Gudipati * fcs_vport_public FCS virtual port public interfaces 6613a36c61f9SKrishna Gudipati */ 6614a36c61f9SKrishna Gudipati 66155fbe25c7SJing Huang /* 6616a36c61f9SKrishna Gudipati * Online notification from fabric SM. 6617a36c61f9SKrishna Gudipati */ 6618a36c61f9SKrishna Gudipati void 6619a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) 6620a36c61f9SKrishna Gudipati { 6621a36c61f9SKrishna Gudipati vport->vport_stats.fab_online++; 6622d7be54ccSKrishna Gudipati if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) 6623a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 6624d7be54ccSKrishna Gudipati else 6625d7be54ccSKrishna Gudipati vport->vport_stats.fab_no_npiv++; 6626a36c61f9SKrishna Gudipati } 6627a36c61f9SKrishna Gudipati 66285fbe25c7SJing Huang /* 6629a36c61f9SKrishna Gudipati * Offline notification from fabric SM. 6630a36c61f9SKrishna Gudipati */ 6631a36c61f9SKrishna Gudipati void 6632a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport) 6633a36c61f9SKrishna Gudipati { 6634a36c61f9SKrishna Gudipati vport->vport_stats.fab_offline++; 6635a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 6636a36c61f9SKrishna Gudipati } 6637a36c61f9SKrishna Gudipati 66385fbe25c7SJing Huang /* 6639a36c61f9SKrishna Gudipati * Cleanup notification from fabric SM on link timer expiry. 6640a36c61f9SKrishna Gudipati */ 6641a36c61f9SKrishna Gudipati void 6642a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) 6643a36c61f9SKrishna Gudipati { 6644a36c61f9SKrishna Gudipati vport->vport_stats.fab_cleanup++; 6645a36c61f9SKrishna Gudipati } 6646881c1b3cSKrishna Gudipati 6647881c1b3cSKrishna Gudipati /* 6648881c1b3cSKrishna Gudipati * Stop notification from fabric SM. To be invoked from within FCS. 6649881c1b3cSKrishna Gudipati */ 6650881c1b3cSKrishna Gudipati void 6651881c1b3cSKrishna Gudipati bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport) 6652881c1b3cSKrishna Gudipati { 6653881c1b3cSKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 6654881c1b3cSKrishna Gudipati } 6655881c1b3cSKrishna Gudipati 66565fbe25c7SJing Huang /* 6657a36c61f9SKrishna Gudipati * delete notification from fabric SM. To be invoked from within FCS. 6658a36c61f9SKrishna Gudipati */ 6659a36c61f9SKrishna Gudipati void 6660a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) 6661a36c61f9SKrishna Gudipati { 6662a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 6663a36c61f9SKrishna Gudipati } 6664a36c61f9SKrishna Gudipati 66655fbe25c7SJing Huang /* 6666dd5aaf45SKrishna Gudipati * Stop completion callback from associated lport 6667dd5aaf45SKrishna Gudipati */ 6668dd5aaf45SKrishna Gudipati void 6669dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport) 6670dd5aaf45SKrishna Gudipati { 6671dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP); 6672dd5aaf45SKrishna Gudipati } 6673dd5aaf45SKrishna Gudipati 6674dd5aaf45SKrishna Gudipati /* 6675a36c61f9SKrishna Gudipati * Delete completion callback from associated lport 6676a36c61f9SKrishna Gudipati */ 6677a36c61f9SKrishna Gudipati void 6678a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) 6679a36c61f9SKrishna Gudipati { 6680a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); 6681a36c61f9SKrishna Gudipati } 6682a36c61f9SKrishna Gudipati 6683a36c61f9SKrishna Gudipati 6684a36c61f9SKrishna Gudipati 66855fbe25c7SJing Huang /* 6686a36c61f9SKrishna Gudipati * fcs_vport_api Virtual port API 6687a36c61f9SKrishna Gudipati */ 6688a36c61f9SKrishna Gudipati 66895fbe25c7SJing Huang /* 6690a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS vport object. This 6691a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 6692a36c61f9SKrishna Gudipati * done in vport_start() call) 6693a36c61f9SKrishna Gudipati * 6694a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 6695a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 6696a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 6697a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 6698a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 6699a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 6700a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 6701a36c61f9SKrishna Gudipati * structure 6702a36c61f9SKrishna Gudipati * 6703a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 6704a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 6705a36c61f9SKrishna Gudipati */ 6706a36c61f9SKrishna Gudipati bfa_status_t 6707a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 6708a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 6709a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 6710a36c61f9SKrishna Gudipati { 6711a36c61f9SKrishna Gudipati if (vport_cfg->pwwn == 0) 6712a36c61f9SKrishna Gudipati return BFA_STATUS_INVALID_WWN; 6713a36c61f9SKrishna Gudipati 6714a36c61f9SKrishna Gudipati if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn) 6715a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_WWN_BP; 6716a36c61f9SKrishna Gudipati 6717a36c61f9SKrishna Gudipati if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL) 6718a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_EXISTS; 6719a36c61f9SKrishna Gudipati 6720f7f73812SMaggie Zhang if (fcs->fabric.num_vports == 6721a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(fcs->bfa)) 6722a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 6723a36c61f9SKrishna Gudipati 6724a36c61f9SKrishna Gudipati vport->lps = bfa_lps_alloc(fcs->bfa); 6725a36c61f9SKrishna Gudipati if (!vport->lps) 6726a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 6727a36c61f9SKrishna Gudipati 6728a36c61f9SKrishna Gudipati vport->vport_drv = vport_drv; 6729a36c61f9SKrishna Gudipati vport_cfg->preboot_vp = BFA_FALSE; 6730a36c61f9SKrishna Gudipati 6731a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 6732a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); 6733a36c61f9SKrishna Gudipati bfa_fcs_lport_init(&vport->lport, vport_cfg); 6734a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); 6735a36c61f9SKrishna Gudipati 6736a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6737a36c61f9SKrishna Gudipati } 6738a36c61f9SKrishna Gudipati 67395fbe25c7SJing Huang /* 6740a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS PBC vport object. This 6741a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 6742a36c61f9SKrishna Gudipati * done in vport_start() call) 6743a36c61f9SKrishna Gudipati * 6744a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 6745a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 6746a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 6747a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 6748a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 6749a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 6750a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 6751a36c61f9SKrishna Gudipati * structure 6752a36c61f9SKrishna Gudipati * 6753a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 6754a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 6755a36c61f9SKrishna Gudipati */ 6756a36c61f9SKrishna Gudipati bfa_status_t 6757a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 6758a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 6759a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 6760a36c61f9SKrishna Gudipati { 6761a36c61f9SKrishna Gudipati bfa_status_t rc; 6762a36c61f9SKrishna Gudipati 6763a36c61f9SKrishna Gudipati rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv); 6764a36c61f9SKrishna Gudipati vport->lport.port_cfg.preboot_vp = BFA_TRUE; 6765a36c61f9SKrishna Gudipati 6766a36c61f9SKrishna Gudipati return rc; 6767a36c61f9SKrishna Gudipati } 6768a36c61f9SKrishna Gudipati 67695fbe25c7SJing Huang /* 6770a36c61f9SKrishna Gudipati * Use this function to findout if this is a pbc vport or not. 6771a36c61f9SKrishna Gudipati * 6772a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 6773a36c61f9SKrishna Gudipati * 6774a36c61f9SKrishna Gudipati * @returns None 6775a36c61f9SKrishna Gudipati */ 6776a36c61f9SKrishna Gudipati bfa_boolean_t 6777a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport) 6778a36c61f9SKrishna Gudipati { 6779a36c61f9SKrishna Gudipati 6780a36c61f9SKrishna Gudipati if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE)) 6781a36c61f9SKrishna Gudipati return BFA_TRUE; 6782a36c61f9SKrishna Gudipati else 6783a36c61f9SKrishna Gudipati return BFA_FALSE; 6784a36c61f9SKrishna Gudipati 6785a36c61f9SKrishna Gudipati } 6786a36c61f9SKrishna Gudipati 67875fbe25c7SJing Huang /* 6788a36c61f9SKrishna Gudipati * Use this function initialize the vport. 6789a36c61f9SKrishna Gudipati * 6790a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 6791a36c61f9SKrishna Gudipati * 6792a36c61f9SKrishna Gudipati * @returns None 6793a36c61f9SKrishna Gudipati */ 6794a36c61f9SKrishna Gudipati bfa_status_t 6795a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport) 6796a36c61f9SKrishna Gudipati { 6797a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START); 6798a36c61f9SKrishna Gudipati 6799a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6800a36c61f9SKrishna Gudipati } 6801a36c61f9SKrishna Gudipati 68025fbe25c7SJing Huang /* 6803a36c61f9SKrishna Gudipati * Use this function quiese the vport object. This function will return 6804a36c61f9SKrishna Gudipati * immediately, when the vport is actually stopped, the 6805a36c61f9SKrishna Gudipati * bfa_drv_vport_stop_cb() will be called. 6806a36c61f9SKrishna Gudipati * 6807a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6808a36c61f9SKrishna Gudipati * 6809a36c61f9SKrishna Gudipati * return None 6810a36c61f9SKrishna Gudipati */ 6811a36c61f9SKrishna Gudipati bfa_status_t 6812a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) 6813a36c61f9SKrishna Gudipati { 6814a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 6815a36c61f9SKrishna Gudipati 6816a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6817a36c61f9SKrishna Gudipati } 6818a36c61f9SKrishna Gudipati 68195fbe25c7SJing Huang /* 6820a36c61f9SKrishna Gudipati * Use this function to delete a vport object. Fabric object should 6821a36c61f9SKrishna Gudipati * be stopped before this function call. 6822a36c61f9SKrishna Gudipati * 6823a36c61f9SKrishna Gudipati * !!!!!!! Donot invoke this from within FCS !!!!!!! 6824a36c61f9SKrishna Gudipati * 6825a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6826a36c61f9SKrishna Gudipati * 6827a36c61f9SKrishna Gudipati * return None 6828a36c61f9SKrishna Gudipati */ 6829a36c61f9SKrishna Gudipati bfa_status_t 6830a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) 6831a36c61f9SKrishna Gudipati { 6832a36c61f9SKrishna Gudipati 6833a36c61f9SKrishna Gudipati if (vport->lport.port_cfg.preboot_vp) 6834a36c61f9SKrishna Gudipati return BFA_STATUS_PBC; 6835a36c61f9SKrishna Gudipati 6836a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 6837a36c61f9SKrishna Gudipati 6838a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6839a36c61f9SKrishna Gudipati } 6840a36c61f9SKrishna Gudipati 68415fbe25c7SJing Huang /* 6842a36c61f9SKrishna Gudipati * Use this function to get vport's current status info. 6843a36c61f9SKrishna Gudipati * 6844a36c61f9SKrishna Gudipati * param[in] vport pointer to bfa_fcs_vport_t. 6845a36c61f9SKrishna Gudipati * param[out] attr pointer to return vport attributes 6846a36c61f9SKrishna Gudipati * 6847a36c61f9SKrishna Gudipati * return None 6848a36c61f9SKrishna Gudipati */ 6849a36c61f9SKrishna Gudipati void 6850a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, 6851a36c61f9SKrishna Gudipati struct bfa_vport_attr_s *attr) 6852a36c61f9SKrishna Gudipati { 6853a36c61f9SKrishna Gudipati if (vport == NULL || attr == NULL) 6854a36c61f9SKrishna Gudipati return; 6855a36c61f9SKrishna Gudipati 68566a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_vport_attr_s)); 6857a36c61f9SKrishna Gudipati 6858a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr); 6859a36c61f9SKrishna Gudipati attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm); 6860a36c61f9SKrishna Gudipati } 6861a36c61f9SKrishna Gudipati 6862a36c61f9SKrishna Gudipati 68635fbe25c7SJing Huang /* 6864a36c61f9SKrishna Gudipati * Lookup a virtual port. Excludes base port from lookup. 6865a36c61f9SKrishna Gudipati */ 6866a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s * 6867a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn) 6868a36c61f9SKrishna Gudipati { 6869a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 6870a36c61f9SKrishna Gudipati struct bfa_fcs_fabric_s *fabric; 6871a36c61f9SKrishna Gudipati 6872a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 6873a36c61f9SKrishna Gudipati bfa_trc(fcs, vpwwn); 6874a36c61f9SKrishna Gudipati 6875a36c61f9SKrishna Gudipati fabric = bfa_fcs_vf_lookup(fcs, vf_id); 6876a36c61f9SKrishna Gudipati if (!fabric) { 6877a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 6878a36c61f9SKrishna Gudipati return NULL; 6879a36c61f9SKrishna Gudipati } 6880a36c61f9SKrishna Gudipati 6881a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn); 6882a36c61f9SKrishna Gudipati return vport; 6883a36c61f9SKrishna Gudipati } 6884a36c61f9SKrishna Gudipati 68855fbe25c7SJing Huang /* 6886a36c61f9SKrishna Gudipati * FDISC Response 6887a36c61f9SKrishna Gudipati */ 6888a36c61f9SKrishna Gudipati void 6889a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) 6890a36c61f9SKrishna Gudipati { 6891a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6892a36c61f9SKrishna Gudipati 6893a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6894a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), status); 6895a36c61f9SKrishna Gudipati 6896a36c61f9SKrishna Gudipati switch (status) { 6897a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 6898a36c61f9SKrishna Gudipati /* 6899b595076aSUwe Kleine-König * Initialize the V-Port fields 6900a36c61f9SKrishna Gudipati */ 6901f7f73812SMaggie Zhang __vport_fcid(vport) = vport->lps->lp_pid; 6902a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_accepts++; 6903a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6904a36c61f9SKrishna Gudipati break; 6905a36c61f9SKrishna Gudipati 6906a36c61f9SKrishna Gudipati case BFA_STATUS_INVALID_MAC: 6907a36c61f9SKrishna Gudipati /* Only for CNA */ 6908a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6909a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6910a36c61f9SKrishna Gudipati 6911a36c61f9SKrishna Gudipati break; 6912a36c61f9SKrishna Gudipati 6913a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 6914f7f73812SMaggie Zhang switch (vport->lps->ext_status) { 6915a36c61f9SKrishna Gudipati case BFA_EPROTO_BAD_ACCEPT: 6916a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6917a36c61f9SKrishna Gudipati break; 6918a36c61f9SKrishna Gudipati 6919a36c61f9SKrishna Gudipati case BFA_EPROTO_UNKNOWN_RSP: 6920a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_unknown_rsp++; 6921a36c61f9SKrishna Gudipati break; 6922a36c61f9SKrishna Gudipati 6923a36c61f9SKrishna Gudipati default: 6924a36c61f9SKrishna Gudipati break; 6925a36c61f9SKrishna Gudipati } 6926a36c61f9SKrishna Gudipati 6927f2a0cc3fSVijaya Mohan Guvva if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6928a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6929f2a0cc3fSVijaya Mohan Guvva else 6930f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 6931f2a0cc3fSVijaya Mohan Guvva 6932f2a0cc3fSVijaya Mohan Guvva break; 6933f2a0cc3fSVijaya Mohan Guvva 6934f2a0cc3fSVijaya Mohan Guvva case BFA_STATUS_ETIMER: 6935f2a0cc3fSVijaya Mohan Guvva vport->vport_stats.fdisc_timeouts++; 6936f2a0cc3fSVijaya Mohan Guvva if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6937f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6938f2a0cc3fSVijaya Mohan Guvva else 6939f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 6940a36c61f9SKrishna Gudipati break; 6941a36c61f9SKrishna Gudipati 6942a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 6943a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rejects++; 6944a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(vport); 6945a36c61f9SKrishna Gudipati break; 6946a36c61f9SKrishna Gudipati 6947a36c61f9SKrishna Gudipati default: 6948a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rsp_err++; 6949a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6950a36c61f9SKrishna Gudipati } 6951a36c61f9SKrishna Gudipati } 6952a36c61f9SKrishna Gudipati 69535fbe25c7SJing Huang /* 6954a36c61f9SKrishna Gudipati * LOGO response 6955a36c61f9SKrishna Gudipati */ 6956a36c61f9SKrishna Gudipati void 6957a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) 6958a36c61f9SKrishna Gudipati { 6959a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6960a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6961a36c61f9SKrishna Gudipati } 6962a36c61f9SKrishna Gudipati 69635fbe25c7SJing Huang /* 6964a36c61f9SKrishna Gudipati * Received clear virtual link 6965a36c61f9SKrishna Gudipati */ 6966a36c61f9SKrishna Gudipati void 6967a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg) 6968a36c61f9SKrishna Gudipati { 6969a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6970a36c61f9SKrishna Gudipati 6971a36c61f9SKrishna Gudipati /* Send an Offline followed by an ONLINE */ 6972a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 6973a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 6974a36c61f9SKrishna Gudipati } 6975