17725ccfdSJing Huang /* 2a36c61f9SKrishna Gudipati * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 37725ccfdSJing Huang * All rights reserved 47725ccfdSJing Huang * www.brocade.com 57725ccfdSJing Huang * 67725ccfdSJing Huang * Linux driver for Brocade Fibre Channel Host Bus Adapter. 77725ccfdSJing Huang * 87725ccfdSJing Huang * This program is free software; you can redistribute it and/or modify it 97725ccfdSJing Huang * under the terms of the GNU General Public License (GPL) Version 2 as 107725ccfdSJing Huang * published by the Free Software Foundation 117725ccfdSJing Huang * 127725ccfdSJing Huang * This program is distributed in the hope that it will be useful, but 137725ccfdSJing Huang * WITHOUT ANY WARRANTY; without even the implied warranty of 147725ccfdSJing Huang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 157725ccfdSJing Huang * General Public License for more details. 167725ccfdSJing Huang */ 177725ccfdSJing Huang 18f16a1750SMaggie Zhang #include "bfad_drv.h" 197826f304SKrishna Gudipati #include "bfad_im.h" 20a36c61f9SKrishna Gudipati #include "bfa_fcs.h" 21a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h" 22a36c61f9SKrishna Gudipati #include "bfa_fc.h" 237725ccfdSJing Huang 247725ccfdSJing Huang BFA_TRC_FILE(FCS, PORT); 257725ccfdSJing Huang 26bc0e2c2aSKrishna Gudipati /* 27bc0e2c2aSKrishna Gudipati * ALPA to LIXA bitmap mapping 28bc0e2c2aSKrishna Gudipati * 29bc0e2c2aSKrishna Gudipati * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31 30bc0e2c2aSKrishna Gudipati * is for L_bit (login required) and is filled as ALPA 0x00 here. 31bc0e2c2aSKrishna Gudipati */ 32bc0e2c2aSKrishna Gudipati static const u8 loop_alpa_map[] = { 33bc0e2c2aSKrishna Gudipati 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */ 34bc0e2c2aSKrishna Gudipati 0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */ 35bc0e2c2aSKrishna Gudipati 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */ 36bc0e2c2aSKrishna Gudipati 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */ 37bc0e2c2aSKrishna Gudipati 38bc0e2c2aSKrishna Gudipati 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */ 39bc0e2c2aSKrishna Gudipati 0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */ 40bc0e2c2aSKrishna Gudipati 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */ 41bc0e2c2aSKrishna Gudipati 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */ 42bc0e2c2aSKrishna Gudipati 43bc0e2c2aSKrishna Gudipati 0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */ 44bc0e2c2aSKrishna Gudipati 0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */ 45bc0e2c2aSKrishna Gudipati 0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */ 46bc0e2c2aSKrishna Gudipati 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */ 47bc0e2c2aSKrishna Gudipati 48bc0e2c2aSKrishna Gudipati 0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */ 49bc0e2c2aSKrishna Gudipati 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */ 50bc0e2c2aSKrishna Gudipati 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */ 51bc0e2c2aSKrishna Gudipati 0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */ 52bc0e2c2aSKrishna Gudipati }; 53bc0e2c2aSKrishna Gudipati 54a36c61f9SKrishna Gudipati static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, 557725ccfdSJing Huang struct fchs_s *rx_fchs, u8 reason_code, 567725ccfdSJing Huang u8 reason_code_expl); 57a36c61f9SKrishna Gudipati static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 58a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi); 59a36c61f9SKrishna Gudipati static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port); 60a36c61f9SKrishna Gudipati static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port); 61a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port); 62a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port); 63a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port); 64a36c61f9SKrishna Gudipati static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port); 65a36c61f9SKrishna Gudipati static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, 667725ccfdSJing Huang struct fchs_s *rx_fchs, 677725ccfdSJing Huang struct fc_echo_s *echo, u16 len); 68a36c61f9SKrishna Gudipati static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, 697725ccfdSJing Huang struct fchs_s *rx_fchs, 707725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 len); 71a36c61f9SKrishna Gudipati static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 727725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data); 737725ccfdSJing Huang 74a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port); 75a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port); 76a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port); 77a36c61f9SKrishna Gudipati 78a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port); 79a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); 80a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); 81a36c61f9SKrishna Gudipati 82bc0e2c2aSKrishna Gudipati static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port); 83bc0e2c2aSKrishna Gudipati static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port); 84bc0e2c2aSKrishna Gudipati static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port); 85bc0e2c2aSKrishna Gudipati 867725ccfdSJing Huang static struct { 87a36c61f9SKrishna Gudipati void (*init) (struct bfa_fcs_lport_s *port); 88a36c61f9SKrishna Gudipati void (*online) (struct bfa_fcs_lport_s *port); 89a36c61f9SKrishna Gudipati void (*offline) (struct bfa_fcs_lport_s *port); 907725ccfdSJing Huang } __port_action[] = { 917725ccfdSJing Huang { 92a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online, 93a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline}, { 94a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, 95a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline}, { 96a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, 97bc0e2c2aSKrishna Gudipati bfa_fcs_lport_n2n_offline}, { 98bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online, 99bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_offline}, 100a36c61f9SKrishna Gudipati }; 1017725ccfdSJing Huang 1025fbe25c7SJing Huang /* 1037725ccfdSJing Huang * fcs_port_sm FCS logical port state machine 1047725ccfdSJing Huang */ 1057725ccfdSJing Huang 106a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event { 1077725ccfdSJing Huang BFA_FCS_PORT_SM_CREATE = 1, 1087725ccfdSJing Huang BFA_FCS_PORT_SM_ONLINE = 2, 1097725ccfdSJing Huang BFA_FCS_PORT_SM_OFFLINE = 3, 1107725ccfdSJing Huang BFA_FCS_PORT_SM_DELETE = 4, 1117725ccfdSJing Huang BFA_FCS_PORT_SM_DELRPORT = 5, 112dd5aaf45SKrishna Gudipati BFA_FCS_PORT_SM_STOP = 6, 1137725ccfdSJing Huang }; 1147725ccfdSJing Huang 115a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, 116a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 117a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 118a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 119a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port, 120a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 121a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port, 122a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 123a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, 124a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 125dd5aaf45SKrishna Gudipati static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 126dd5aaf45SKrishna Gudipati enum bfa_fcs_lport_event event); 1277725ccfdSJing Huang 1287725ccfdSJing Huang static void 129a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_uninit( 130a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 131a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1327725ccfdSJing Huang { 1337725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1347725ccfdSJing Huang bfa_trc(port->fcs, event); 1357725ccfdSJing Huang 1367725ccfdSJing Huang switch (event) { 1377725ccfdSJing Huang case BFA_FCS_PORT_SM_CREATE: 138a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 1397725ccfdSJing Huang break; 1407725ccfdSJing Huang 1417725ccfdSJing Huang default: 142e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1437725ccfdSJing Huang } 1447725ccfdSJing Huang } 1457725ccfdSJing Huang 1467725ccfdSJing Huang static void 147a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 148a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1497725ccfdSJing Huang { 1507725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1517725ccfdSJing Huang bfa_trc(port->fcs, event); 1527725ccfdSJing Huang 1537725ccfdSJing Huang switch (event) { 1547725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 155a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 156a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 1577725ccfdSJing Huang break; 1587725ccfdSJing Huang 1597725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 160a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 161a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 1627725ccfdSJing Huang break; 1637725ccfdSJing Huang 164dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 165dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 166dd5aaf45SKrishna Gudipati if (port->vport) 167dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 168881c1b3cSKrishna Gudipati else 169881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 170dd5aaf45SKrishna Gudipati break; 171dd5aaf45SKrishna Gudipati 1723e98cc01SJing Huang case BFA_FCS_PORT_SM_OFFLINE: 1733e98cc01SJing Huang break; 1743e98cc01SJing Huang 1757725ccfdSJing Huang default: 176e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1777725ccfdSJing Huang } 1787725ccfdSJing Huang } 1797725ccfdSJing Huang 1807725ccfdSJing Huang static void 181a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online( 182a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 183a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1847725ccfdSJing Huang { 1857725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 1867725ccfdSJing Huang struct list_head *qe, *qen; 1877725ccfdSJing Huang 1887725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1897725ccfdSJing Huang bfa_trc(port->fcs, event); 1907725ccfdSJing Huang 1917725ccfdSJing Huang switch (event) { 1927725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 193a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_offline); 194a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(port); 1957725ccfdSJing Huang break; 1967725ccfdSJing Huang 197dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 198dd5aaf45SKrishna Gudipati __port_action[port->fabric->fab_type].offline(port); 199dd5aaf45SKrishna Gudipati 200dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 201dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 202dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 203dd5aaf45SKrishna Gudipati if (port->vport) 204dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 205881c1b3cSKrishna Gudipati else 206881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 207dd5aaf45SKrishna Gudipati } else { 208dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 209dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 210dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 211dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 212dd5aaf45SKrishna Gudipati } 213dd5aaf45SKrishna Gudipati } 214dd5aaf45SKrishna Gudipati break; 215dd5aaf45SKrishna Gudipati 2167725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 2177725ccfdSJing Huang 2187725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 2197725ccfdSJing Huang 2207725ccfdSJing Huang if (port->num_rports == 0) { 221a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 222a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2237725ccfdSJing Huang } else { 224a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 2257725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 2267725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 227f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 2287725ccfdSJing Huang } 2297725ccfdSJing Huang } 2307725ccfdSJing Huang break; 2317725ccfdSJing Huang 2327725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2337725ccfdSJing Huang break; 2347725ccfdSJing Huang 2357725ccfdSJing Huang default: 236e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2377725ccfdSJing Huang } 2387725ccfdSJing Huang } 2397725ccfdSJing Huang 2407725ccfdSJing Huang static void 241a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline( 242a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 243a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 2447725ccfdSJing Huang { 2457725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 2467725ccfdSJing Huang struct list_head *qe, *qen; 2477725ccfdSJing Huang 2487725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 2497725ccfdSJing Huang bfa_trc(port->fcs, event); 2507725ccfdSJing Huang 2517725ccfdSJing Huang switch (event) { 2527725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 253a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 254a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 2557725ccfdSJing Huang break; 2567725ccfdSJing Huang 257dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_STOP: 258dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 259dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 260dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 261dd5aaf45SKrishna Gudipati if (port->vport) 262dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 263881c1b3cSKrishna Gudipati else 264881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 265dd5aaf45SKrishna Gudipati } else { 266dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 267dd5aaf45SKrishna Gudipati list_for_each_safe(qe, qen, &port->rport_q) { 268dd5aaf45SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 269dd5aaf45SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 270dd5aaf45SKrishna Gudipati } 271dd5aaf45SKrishna Gudipati } 272dd5aaf45SKrishna Gudipati break; 273dd5aaf45SKrishna Gudipati 2747725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 2757725ccfdSJing Huang if (port->num_rports == 0) { 276a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 277a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2787725ccfdSJing Huang } else { 279a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 2807725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 2817725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 282f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 2837725ccfdSJing Huang } 2847725ccfdSJing Huang } 2857725ccfdSJing Huang break; 2867725ccfdSJing Huang 2877725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2887725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 2897725ccfdSJing Huang break; 2907725ccfdSJing Huang 2917725ccfdSJing Huang default: 292e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2937725ccfdSJing Huang } 2947725ccfdSJing Huang } 2957725ccfdSJing Huang 2967725ccfdSJing Huang static void 297dd5aaf45SKrishna Gudipati bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 298dd5aaf45SKrishna Gudipati enum bfa_fcs_lport_event event) 299dd5aaf45SKrishna Gudipati { 300dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 301dd5aaf45SKrishna Gudipati bfa_trc(port->fcs, event); 302dd5aaf45SKrishna Gudipati 303dd5aaf45SKrishna Gudipati switch (event) { 304dd5aaf45SKrishna Gudipati case BFA_FCS_PORT_SM_DELRPORT: 305dd5aaf45SKrishna Gudipati if (port->num_rports == 0) { 306dd5aaf45SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 307dd5aaf45SKrishna Gudipati /* If vport - send completion call back */ 308dd5aaf45SKrishna Gudipati if (port->vport) 309dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(port->vport); 310881c1b3cSKrishna Gudipati else 311881c1b3cSKrishna Gudipati bfa_wc_down(&(port->fabric->stop_wc)); 312dd5aaf45SKrishna Gudipati } 313dd5aaf45SKrishna Gudipati break; 314dd5aaf45SKrishna Gudipati 315dd5aaf45SKrishna Gudipati default: 316dd5aaf45SKrishna Gudipati bfa_sm_fault(port->fcs, event); 317dd5aaf45SKrishna Gudipati } 318dd5aaf45SKrishna Gudipati } 319dd5aaf45SKrishna Gudipati 320dd5aaf45SKrishna Gudipati static void 321a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting( 322a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 323a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 3247725ccfdSJing Huang { 3257725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 3267725ccfdSJing Huang bfa_trc(port->fcs, event); 3277725ccfdSJing Huang 3287725ccfdSJing Huang switch (event) { 3297725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 3307725ccfdSJing Huang if (port->num_rports == 0) { 331a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 332a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 3337725ccfdSJing Huang } 3347725ccfdSJing Huang break; 3357725ccfdSJing Huang 3367725ccfdSJing Huang default: 337e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 3387725ccfdSJing Huang } 3397725ccfdSJing Huang } 3407725ccfdSJing Huang 3415fbe25c7SJing Huang /* 3427725ccfdSJing Huang * fcs_port_pvt 3437725ccfdSJing Huang */ 3447725ccfdSJing Huang 3457725ccfdSJing Huang /* 3467826f304SKrishna Gudipati * Send AEN notification 3477826f304SKrishna Gudipati */ 3487826f304SKrishna Gudipati static void 3497826f304SKrishna Gudipati bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port, 3507826f304SKrishna Gudipati enum bfa_lport_aen_event event) 3517826f304SKrishna Gudipati { 3527826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 3537826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 3547826f304SKrishna Gudipati 3557826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 3567826f304SKrishna Gudipati if (!aen_entry) 3577826f304SKrishna Gudipati return; 3587826f304SKrishna Gudipati 3597826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 3607826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 3617826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 3627826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 3637826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 3647826f304SKrishna Gudipati 3657826f304SKrishna Gudipati /* Send the AEN notification */ 3667826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 3677826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 3687826f304SKrishna Gudipati } 3697826f304SKrishna Gudipati 3707826f304SKrishna Gudipati /* 3717725ccfdSJing Huang * Send a LS reject 3727725ccfdSJing Huang */ 3737725ccfdSJing Huang static void 374a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 3757725ccfdSJing Huang u8 reason_code, u8 reason_code_expl) 3767725ccfdSJing Huang { 3777725ccfdSJing Huang struct fchs_s fchs; 3787725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 3797725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 3807725ccfdSJing Huang int len; 3817725ccfdSJing Huang 382a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 3837725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 3847725ccfdSJing Huang 385c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 3867725ccfdSJing Huang if (!fcxp) 3877725ccfdSJing Huang return; 3887725ccfdSJing Huang 389a36c61f9SKrishna Gudipati len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 390a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 391a36c61f9SKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 3927725ccfdSJing Huang 3937725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 3947725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 3957725ccfdSJing Huang FC_MAX_PDUSZ, 0); 3967725ccfdSJing Huang } 3977725ccfdSJing Huang 3985fbe25c7SJing Huang /* 399d7be54ccSKrishna Gudipati * Send a FCCT Reject 400d7be54ccSKrishna Gudipati */ 401d7be54ccSKrishna Gudipati static void 402d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port, 403d7be54ccSKrishna Gudipati struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl) 404d7be54ccSKrishna Gudipati { 405d7be54ccSKrishna Gudipati struct fchs_s fchs; 406d7be54ccSKrishna Gudipati struct bfa_fcxp_s *fcxp; 407d7be54ccSKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 408d7be54ccSKrishna Gudipati int len; 409d7be54ccSKrishna Gudipati struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1); 410d7be54ccSKrishna Gudipati struct ct_hdr_s *ct_hdr; 411d7be54ccSKrishna Gudipati 412d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 413d7be54ccSKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 414d7be54ccSKrishna Gudipati 415c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 416d7be54ccSKrishna Gudipati if (!fcxp) 417d7be54ccSKrishna Gudipati return; 418d7be54ccSKrishna Gudipati 419d7be54ccSKrishna Gudipati ct_hdr = bfa_fcxp_get_reqbuf(fcxp); 420d7be54ccSKrishna Gudipati ct_hdr->gs_type = rx_cthdr->gs_type; 421d7be54ccSKrishna Gudipati ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type; 422d7be54ccSKrishna Gudipati 423d7be54ccSKrishna Gudipati len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id, 424d7be54ccSKrishna Gudipati bfa_fcs_lport_get_fcid(port), 425d7be54ccSKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 426d7be54ccSKrishna Gudipati 427d7be54ccSKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 428d7be54ccSKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 429d7be54ccSKrishna Gudipati FC_MAX_PDUSZ, 0); 430d7be54ccSKrishna Gudipati } 431d7be54ccSKrishna Gudipati 432d7be54ccSKrishna Gudipati /* 4337725ccfdSJing Huang * Process incoming plogi from a remote port. 4347725ccfdSJing Huang */ 4357725ccfdSJing Huang static void 436a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 437a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi) 4387725ccfdSJing Huang { 4397725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 4407725ccfdSJing Huang 4417725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 4427725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4437725ccfdSJing Huang 4447725ccfdSJing Huang /* 4457725ccfdSJing Huang * If min cfg mode is enabled, drop any incoming PLOGIs 4467725ccfdSJing Huang */ 4477725ccfdSJing Huang if (__fcs_min_cfg(port->fcs)) { 4487725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4497725ccfdSJing Huang return; 4507725ccfdSJing Huang } 4517725ccfdSJing Huang 4527725ccfdSJing Huang if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) { 4537725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4547725ccfdSJing Huang /* 4557725ccfdSJing Huang * send a LS reject 4567725ccfdSJing Huang */ 457a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4587725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4597725ccfdSJing Huang FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS); 4607725ccfdSJing Huang return; 4617725ccfdSJing Huang } 4627725ccfdSJing Huang 4635fbe25c7SJing Huang /* 4647725ccfdSJing Huang * Direct Attach P2P mode : verify address assigned by the r-port. 4657725ccfdSJing Huang */ 466a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 467a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 468a36c61f9SKrishna Gudipati (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4697725ccfdSJing Huang if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) { 470a36c61f9SKrishna Gudipati /* Address assigned to us cannot be a WKA */ 471a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 4727725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 4737725ccfdSJing Huang FC_LS_RJT_EXP_INVALID_NPORT_ID); 4747725ccfdSJing Huang return; 4757725ccfdSJing Huang } 4767725ccfdSJing Huang port->pid = rx_fchs->d_id; 477b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4787725ccfdSJing Huang } 4797725ccfdSJing Huang 4805fbe25c7SJing Huang /* 4817725ccfdSJing Huang * First, check if we know the device by pwwn. 4827725ccfdSJing Huang */ 483a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name); 4847725ccfdSJing Huang if (rport) { 4855fbe25c7SJing Huang /* 486a36c61f9SKrishna Gudipati * Direct Attach P2P mode : handle address assigned by r-port. 4877725ccfdSJing Huang */ 488a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 489a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 4907725ccfdSJing Huang (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 4917725ccfdSJing Huang port->pid = rx_fchs->d_id; 492b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 4937725ccfdSJing Huang rport->pid = rx_fchs->s_id; 4947725ccfdSJing Huang } 4957725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 4967725ccfdSJing Huang return; 4977725ccfdSJing Huang } 4987725ccfdSJing Huang 4995fbe25c7SJing Huang /* 5007725ccfdSJing Huang * Next, lookup rport by PID. 5017725ccfdSJing Huang */ 502a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id); 5037725ccfdSJing Huang if (!rport) { 5045fbe25c7SJing Huang /* 5057725ccfdSJing Huang * Inbound PLOGI from a new device. 5067725ccfdSJing Huang */ 5077725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 5087725ccfdSJing Huang return; 5097725ccfdSJing Huang } 5107725ccfdSJing Huang 5115fbe25c7SJing Huang /* 5127725ccfdSJing Huang * Rport is known only by PID. 5137725ccfdSJing Huang */ 5147725ccfdSJing Huang if (rport->pwwn) { 5155fbe25c7SJing Huang /* 5167725ccfdSJing Huang * This is a different device with the same pid. Old device 5177725ccfdSJing Huang * disappeared. Send implicit LOGO to old device. 5187725ccfdSJing Huang */ 519d4b671c5SJing Huang WARN_ON(rport->pwwn == plogi->port_name); 520f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 5217725ccfdSJing Huang 5225fbe25c7SJing Huang /* 5237725ccfdSJing Huang * Inbound PLOGI from a new device (with old PID). 5247725ccfdSJing Huang */ 5257725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 5267725ccfdSJing Huang return; 5277725ccfdSJing Huang } 5287725ccfdSJing Huang 5295fbe25c7SJing Huang /* 5307725ccfdSJing Huang * PLOGI crossing each other. 5317725ccfdSJing Huang */ 532d4b671c5SJing Huang WARN_ON(rport->pwwn != WWN_NULL); 5337725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 5347725ccfdSJing Huang } 5357725ccfdSJing Huang 5367725ccfdSJing Huang /* 5377725ccfdSJing Huang * Process incoming ECHO. 5387725ccfdSJing Huang * Since it does not require a login, it is processed here. 5397725ccfdSJing Huang */ 5407725ccfdSJing Huang static void 541a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5427725ccfdSJing Huang struct fc_echo_s *echo, u16 rx_len) 5437725ccfdSJing Huang { 5447725ccfdSJing Huang struct fchs_s fchs; 5457725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5467725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5477725ccfdSJing Huang int len, pyld_len; 5487725ccfdSJing Huang 5497725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5507725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5517725ccfdSJing Huang 552c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5537725ccfdSJing Huang if (!fcxp) 5547725ccfdSJing Huang return; 5557725ccfdSJing Huang 556a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 557a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 558a36c61f9SKrishna Gudipati rx_fchs->ox_id); 5597725ccfdSJing Huang 5607725ccfdSJing Huang /* 5617725ccfdSJing Huang * Copy the payload (if any) from the echo frame 5627725ccfdSJing Huang */ 5637725ccfdSJing Huang pyld_len = rx_len - sizeof(struct fchs_s); 564a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_len); 5657725ccfdSJing Huang bfa_trc(port->fcs, pyld_len); 5667725ccfdSJing Huang 5677725ccfdSJing Huang if (pyld_len > len) 5687725ccfdSJing Huang memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) + 5697725ccfdSJing Huang sizeof(struct fc_echo_s), (echo + 1), 5707725ccfdSJing Huang (pyld_len - sizeof(struct fc_echo_s))); 5717725ccfdSJing Huang 5727725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5737725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL, 5747725ccfdSJing Huang FC_MAX_PDUSZ, 0); 5757725ccfdSJing Huang } 5767725ccfdSJing Huang 5777725ccfdSJing Huang /* 5787725ccfdSJing Huang * Process incoming RNID. 5797725ccfdSJing Huang * Since it does not require a login, it is processed here. 5807725ccfdSJing Huang */ 5817725ccfdSJing Huang static void 582a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 5837725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 rx_len) 5847725ccfdSJing Huang { 5857725ccfdSJing Huang struct fc_rnid_common_id_data_s common_id_data; 5867725ccfdSJing Huang struct fc_rnid_general_topology_data_s gen_topo_data; 5877725ccfdSJing Huang struct fchs_s fchs; 5887725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 5897725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 5907725ccfdSJing Huang u16 len; 5917725ccfdSJing Huang u32 data_format; 5927725ccfdSJing Huang 5937725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 5947725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 5957725ccfdSJing Huang bfa_trc(port->fcs, rx_len); 5967725ccfdSJing Huang 597c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5987725ccfdSJing Huang if (!fcxp) 5997725ccfdSJing Huang return; 6007725ccfdSJing Huang 6017725ccfdSJing Huang /* 6027725ccfdSJing Huang * Check Node Indentification Data Format 6037725ccfdSJing Huang * We only support General Topology Discovery Format. 6047725ccfdSJing Huang * For any other requested Data Formats, we return Common Node Id Data 6057725ccfdSJing Huang * only, as per FC-LS. 6067725ccfdSJing Huang */ 6077725ccfdSJing Huang bfa_trc(port->fcs, rnid->node_id_data_format); 6087725ccfdSJing Huang if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 6097725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY; 6107725ccfdSJing Huang /* 6117725ccfdSJing Huang * Get General topology data for this port 6127725ccfdSJing Huang */ 6137725ccfdSJing Huang bfa_fs_port_get_gen_topo_data(port, &gen_topo_data); 6147725ccfdSJing Huang } else { 6157725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_COMMON; 6167725ccfdSJing Huang } 6177725ccfdSJing Huang 6187725ccfdSJing Huang /* 6197725ccfdSJing Huang * Copy the Node Id Info 6207725ccfdSJing Huang */ 621a36c61f9SKrishna Gudipati common_id_data.port_name = bfa_fcs_lport_get_pwwn(port); 622a36c61f9SKrishna Gudipati common_id_data.node_name = bfa_fcs_lport_get_nwwn(port); 6237725ccfdSJing Huang 624a36c61f9SKrishna Gudipati len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 625a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 626a36c61f9SKrishna Gudipati rx_fchs->ox_id, data_format, &common_id_data, 627a36c61f9SKrishna Gudipati &gen_topo_data); 6287725ccfdSJing Huang 6297725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 6307725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 6317725ccfdSJing Huang FC_MAX_PDUSZ, 0); 6327725ccfdSJing Huang } 6337725ccfdSJing Huang 6347725ccfdSJing Huang /* 6357725ccfdSJing Huang * Fill out General Topolpgy Discovery Data for RNID ELS. 6367725ccfdSJing Huang */ 6377725ccfdSJing Huang static void 638a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 6397725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data) 6407725ccfdSJing Huang { 6416a18b167SJing Huang memset(gen_topo_data, 0, 6427725ccfdSJing Huang sizeof(struct fc_rnid_general_topology_data_s)); 6437725ccfdSJing Huang 644ba816ea8SJing Huang gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST); 6457725ccfdSJing Huang gen_topo_data->phy_port_num = 0; /* @todo */ 646ba816ea8SJing Huang gen_topo_data->num_attached_nodes = cpu_to_be32(1); 6477725ccfdSJing Huang } 6487725ccfdSJing Huang 6497725ccfdSJing Huang static void 650a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) 6517725ccfdSJing Huang { 652a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 653a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 654a36c61f9SKrishna Gudipati 6557725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6567725ccfdSJing Huang 6577725ccfdSJing Huang __port_action[port->fabric->fab_type].init(port); 6587725ccfdSJing Huang __port_action[port->fabric->fab_type].online(port); 6597725ccfdSJing Huang 660a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 661a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 662a36c61f9SKrishna Gudipati "Logical port online: WWN = %s Role = %s\n", 663a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6647826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE); 665a36c61f9SKrishna Gudipati 666a36c61f9SKrishna Gudipati bfad->bfad_flags |= BFAD_PORT_ONLINE; 6677725ccfdSJing Huang } 6687725ccfdSJing Huang 6697725ccfdSJing Huang static void 670a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) 6717725ccfdSJing Huang { 6727725ccfdSJing Huang struct list_head *qe, *qen; 6737725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 674a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 675a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 6767725ccfdSJing Huang 6777725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 6787725ccfdSJing Huang 6797725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 6807725ccfdSJing Huang 681a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 682f7f73812SMaggie Zhang if (bfa_sm_cmp_state(port->fabric, 6837826f304SKrishna Gudipati bfa_fcs_fabric_sm_online) == BFA_TRUE) { 684a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 685a36c61f9SKrishna Gudipati "Logical port lost fabric connectivity: WWN = %s Role = %s\n", 686a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6877826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT); 6887826f304SKrishna Gudipati } else { 689a3f29cccSKrishna Gudipati BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 690a36c61f9SKrishna Gudipati "Logical port taken offline: WWN = %s Role = %s\n", 691a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 6927826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE); 6937826f304SKrishna Gudipati } 6947725ccfdSJing Huang 6957725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 6967725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 697f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 6987725ccfdSJing Huang } 6997725ccfdSJing Huang } 7007725ccfdSJing Huang 7017725ccfdSJing Huang static void 702a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port) 7037725ccfdSJing Huang { 704d4b671c5SJing Huang WARN_ON(1); 7057725ccfdSJing Huang } 7067725ccfdSJing Huang 7077725ccfdSJing Huang static void 708a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port) 7097725ccfdSJing Huang { 710d4b671c5SJing Huang WARN_ON(1); 7117725ccfdSJing Huang } 7127725ccfdSJing Huang 7137725ccfdSJing Huang static void 714a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port) 7157725ccfdSJing Huang { 716d4b671c5SJing Huang WARN_ON(1); 7177725ccfdSJing Huang } 7187725ccfdSJing Huang 7197725ccfdSJing Huang static void 720a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs) 7217725ccfdSJing Huang { 722a36c61f9SKrishna Gudipati struct fchs_s fchs; 723a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 724a36c61f9SKrishna Gudipati int len; 7257725ccfdSJing Huang 726a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 727a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 728a36c61f9SKrishna Gudipati 729c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 730a36c61f9SKrishna Gudipati if (!fcxp) 731a36c61f9SKrishna Gudipati return; 732a36c61f9SKrishna Gudipati 733a36c61f9SKrishna Gudipati len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 734a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 735a36c61f9SKrishna Gudipati rx_fchs->ox_id, 0); 736a36c61f9SKrishna Gudipati 737a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 738a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 739a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 740a36c61f9SKrishna Gudipati } 741a36c61f9SKrishna Gudipati static void 742a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) 743a36c61f9SKrishna Gudipati { 744a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 745a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 746a36c61f9SKrishna Gudipati 747a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 74888166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 749a36c61f9SKrishna Gudipati "Logical port deleted: WWN = %s Role = %s\n", 750a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 7517826f304SKrishna Gudipati bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE); 752a36c61f9SKrishna Gudipati 753a36c61f9SKrishna Gudipati /* Base port will be deleted by the OS driver */ 75417c201b3SKrishna Gudipati if (port->vport) 7557725ccfdSJing Huang bfa_fcs_vport_delete_comp(port->vport); 75617c201b3SKrishna Gudipati else 757f7f73812SMaggie Zhang bfa_wc_down(&port->fabric->wc); 7587725ccfdSJing Huang } 7597725ccfdSJing Huang 7607725ccfdSJing Huang 7615fbe25c7SJing Huang /* 7627725ccfdSJing Huang * Unsolicited frame receive handling. 7637725ccfdSJing Huang */ 7647725ccfdSJing Huang void 765a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, 766a36c61f9SKrishna Gudipati struct fchs_s *fchs, u16 len) 7677725ccfdSJing Huang { 7687725ccfdSJing Huang u32 pid = fchs->s_id; 7697725ccfdSJing Huang struct bfa_fcs_rport_s *rport = NULL; 7707725ccfdSJing Huang struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 7717725ccfdSJing Huang 7727725ccfdSJing Huang bfa_stats(lport, uf_recvs); 77315821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->type); 7747725ccfdSJing Huang 775a36c61f9SKrishna Gudipati if (!bfa_fcs_lport_is_online(lport)) { 7767725ccfdSJing Huang bfa_stats(lport, uf_recv_drops); 7777725ccfdSJing Huang return; 7787725ccfdSJing Huang } 7797725ccfdSJing Huang 7805fbe25c7SJing Huang /* 7817725ccfdSJing Huang * First, handle ELSs that donot require a login. 7827725ccfdSJing Huang */ 7837725ccfdSJing Huang /* 7847725ccfdSJing Huang * Handle PLOGI first 7857725ccfdSJing Huang */ 7867725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && 7877725ccfdSJing Huang (els_cmd->els_code == FC_ELS_PLOGI)) { 788a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd); 7897725ccfdSJing Huang return; 7907725ccfdSJing Huang } 7917725ccfdSJing Huang 7927725ccfdSJing Huang /* 7937725ccfdSJing Huang * Handle ECHO separately. 7947725ccfdSJing Huang */ 7957725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) { 796a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(lport, fchs, 7977725ccfdSJing Huang (struct fc_echo_s *)els_cmd, len); 7987725ccfdSJing Huang return; 7997725ccfdSJing Huang } 8007725ccfdSJing Huang 8017725ccfdSJing Huang /* 8027725ccfdSJing Huang * Handle RNID separately. 8037725ccfdSJing Huang */ 8047725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) { 805a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(lport, fchs, 8067725ccfdSJing Huang (struct fc_rnid_cmd_s *) els_cmd, len); 8077725ccfdSJing Huang return; 8087725ccfdSJing Huang } 8097725ccfdSJing Huang 810a36c61f9SKrishna Gudipati if (fchs->type == FC_TYPE_BLS) { 811a36c61f9SKrishna Gudipati if ((fchs->routing == FC_RTG_BASIC_LINK) && 812a36c61f9SKrishna Gudipati (fchs->cat_info == FC_CAT_ABTS)) 813a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(lport, fchs); 814a36c61f9SKrishna Gudipati return; 815a36c61f9SKrishna Gudipati } 816d7be54ccSKrishna Gudipati 817d7be54ccSKrishna Gudipati if (fchs->type == FC_TYPE_SERVICES) { 818d7be54ccSKrishna Gudipati /* 819d7be54ccSKrishna Gudipati * Unhandled FC-GS frames. Send a FC-CT Reject 820d7be54ccSKrishna Gudipati */ 821d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP, 822d7be54ccSKrishna Gudipati CT_NS_EXP_NOADDITIONAL); 823d7be54ccSKrishna Gudipati return; 824d7be54ccSKrishna Gudipati } 825d7be54ccSKrishna Gudipati 8265fbe25c7SJing Huang /* 8277725ccfdSJing Huang * look for a matching remote port ID 8287725ccfdSJing Huang */ 829a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(lport, pid); 8307725ccfdSJing Huang if (rport) { 8317725ccfdSJing Huang bfa_trc(rport->fcs, fchs->s_id); 8327725ccfdSJing Huang bfa_trc(rport->fcs, fchs->d_id); 8337725ccfdSJing Huang bfa_trc(rport->fcs, fchs->type); 8347725ccfdSJing Huang 8357725ccfdSJing Huang bfa_fcs_rport_uf_recv(rport, fchs, len); 8367725ccfdSJing Huang return; 8377725ccfdSJing Huang } 8387725ccfdSJing Huang 8395fbe25c7SJing Huang /* 8407725ccfdSJing Huang * Only handles ELS frames for now. 8417725ccfdSJing Huang */ 8427725ccfdSJing Huang if (fchs->type != FC_TYPE_ELS) { 84315821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->s_id); 84415821f05SKrishna Gudipati bfa_trc(lport->fcs, fchs->d_id); 84515821f05SKrishna Gudipati /* ignore type FC_TYPE_FC_FSS */ 84615821f05SKrishna Gudipati if (fchs->type != FC_TYPE_FC_FSS) 84715821f05SKrishna Gudipati bfa_sm_fault(lport->fcs, fchs->type); 8487725ccfdSJing Huang return; 8497725ccfdSJing Huang } 8507725ccfdSJing Huang 8517725ccfdSJing Huang bfa_trc(lport->fcs, els_cmd->els_code); 8527725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_RSCN) { 853a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(lport, fchs, len); 8547725ccfdSJing Huang return; 8557725ccfdSJing Huang } 8567725ccfdSJing Huang 8577725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_LOGO) { 8585fbe25c7SJing Huang /* 8597725ccfdSJing Huang * @todo Handle LOGO frames received. 8607725ccfdSJing Huang */ 8617725ccfdSJing Huang return; 8627725ccfdSJing Huang } 8637725ccfdSJing Huang 8647725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_PRLI) { 8655fbe25c7SJing Huang /* 8667725ccfdSJing Huang * @todo Handle PRLI frames received. 8677725ccfdSJing Huang */ 8687725ccfdSJing Huang return; 8697725ccfdSJing Huang } 8707725ccfdSJing Huang 8715fbe25c7SJing Huang /* 8727725ccfdSJing Huang * Unhandled ELS frames. Send a LS_RJT. 8737725ccfdSJing Huang */ 874a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP, 8757725ccfdSJing Huang FC_LS_RJT_EXP_NO_ADDL_INFO); 8767725ccfdSJing Huang 8777725ccfdSJing Huang } 8787725ccfdSJing Huang 8795fbe25c7SJing Huang /* 8807725ccfdSJing Huang * PID based Lookup for a R-Port in the Port R-Port Queue 8817725ccfdSJing Huang */ 8827725ccfdSJing Huang struct bfa_fcs_rport_s * 883a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) 8847725ccfdSJing Huang { 8857725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 8867725ccfdSJing Huang struct list_head *qe; 8877725ccfdSJing Huang 8887725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 8897725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 8907725ccfdSJing Huang if (rport->pid == pid) 8917725ccfdSJing Huang return rport; 8927725ccfdSJing Huang } 8937725ccfdSJing Huang 8947725ccfdSJing Huang bfa_trc(port->fcs, pid); 8957725ccfdSJing Huang return NULL; 8967725ccfdSJing Huang } 8977725ccfdSJing Huang 8985fbe25c7SJing Huang /* 899ee1a4a42SKrishna Gudipati * OLD_PID based Lookup for a R-Port in the Port R-Port Queue 900ee1a4a42SKrishna Gudipati */ 901ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s * 902ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid) 903ee1a4a42SKrishna Gudipati { 904ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *rport; 905ee1a4a42SKrishna Gudipati struct list_head *qe; 906ee1a4a42SKrishna Gudipati 907ee1a4a42SKrishna Gudipati list_for_each(qe, &port->rport_q) { 908ee1a4a42SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 909ee1a4a42SKrishna Gudipati if (rport->old_pid == pid) 910ee1a4a42SKrishna Gudipati return rport; 911ee1a4a42SKrishna Gudipati } 912ee1a4a42SKrishna Gudipati 913ee1a4a42SKrishna Gudipati bfa_trc(port->fcs, pid); 914ee1a4a42SKrishna Gudipati return NULL; 915ee1a4a42SKrishna Gudipati } 916ee1a4a42SKrishna Gudipati 917ee1a4a42SKrishna Gudipati /* 9187725ccfdSJing Huang * PWWN based Lookup for a R-Port in the Port R-Port Queue 9197725ccfdSJing Huang */ 9207725ccfdSJing Huang struct bfa_fcs_rport_s * 921a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn) 9227725ccfdSJing Huang { 9237725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 9247725ccfdSJing Huang struct list_head *qe; 9257725ccfdSJing Huang 9267725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 9277725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 9287725ccfdSJing Huang if (wwn_is_equal(rport->pwwn, pwwn)) 9297725ccfdSJing Huang return rport; 9307725ccfdSJing Huang } 9317725ccfdSJing Huang 9327725ccfdSJing Huang bfa_trc(port->fcs, pwwn); 933f8ceafdeSJing Huang return NULL; 9347725ccfdSJing Huang } 9357725ccfdSJing Huang 9365fbe25c7SJing Huang /* 9377725ccfdSJing Huang * NWWN based Lookup for a R-Port in the Port R-Port Queue 9387725ccfdSJing Huang */ 9397725ccfdSJing Huang struct bfa_fcs_rport_s * 940a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) 9417725ccfdSJing Huang { 9427725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 9437725ccfdSJing Huang struct list_head *qe; 9447725ccfdSJing Huang 9457725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 9467725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 9477725ccfdSJing Huang if (wwn_is_equal(rport->nwwn, nwwn)) 9487725ccfdSJing Huang return rport; 9497725ccfdSJing Huang } 9507725ccfdSJing Huang 9517725ccfdSJing Huang bfa_trc(port->fcs, nwwn); 952f8ceafdeSJing Huang return NULL; 9537725ccfdSJing Huang } 9547725ccfdSJing Huang 9555fbe25c7SJing Huang /* 956ee1a4a42SKrishna Gudipati * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue 957ee1a4a42SKrishna Gudipati */ 958ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s * 959ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port, 960ee1a4a42SKrishna Gudipati wwn_t pwwn, u32 pid) 961ee1a4a42SKrishna Gudipati { 962ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *rport; 963ee1a4a42SKrishna Gudipati struct list_head *qe; 964ee1a4a42SKrishna Gudipati 965ee1a4a42SKrishna Gudipati list_for_each(qe, &port->rport_q) { 966ee1a4a42SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 967ee1a4a42SKrishna Gudipati if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid) 968ee1a4a42SKrishna Gudipati return rport; 969ee1a4a42SKrishna Gudipati } 970ee1a4a42SKrishna Gudipati 971ee1a4a42SKrishna Gudipati bfa_trc(port->fcs, pwwn); 972ee1a4a42SKrishna Gudipati return NULL; 973ee1a4a42SKrishna Gudipati } 974ee1a4a42SKrishna Gudipati 975ee1a4a42SKrishna Gudipati /* 9767725ccfdSJing Huang * Called by rport module when new rports are discovered. 9777725ccfdSJing Huang */ 9787725ccfdSJing Huang void 979a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport( 980a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 9817725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 9827725ccfdSJing Huang { 9837725ccfdSJing Huang list_add_tail(&rport->qe, &port->rport_q); 9847725ccfdSJing Huang port->num_rports++; 9857725ccfdSJing Huang } 9867725ccfdSJing Huang 9875fbe25c7SJing Huang /* 9887725ccfdSJing Huang * Called by rport module to when rports are deleted. 9897725ccfdSJing Huang */ 9907725ccfdSJing Huang void 991a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport( 992a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 9937725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 9947725ccfdSJing Huang { 995d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport)); 9967725ccfdSJing Huang list_del(&rport->qe); 9977725ccfdSJing Huang port->num_rports--; 9987725ccfdSJing Huang 9997725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT); 10007725ccfdSJing Huang } 10017725ccfdSJing Huang 10025fbe25c7SJing Huang /* 10037725ccfdSJing Huang * Called by fabric for base port when fabric login is complete. 10047725ccfdSJing Huang * Called by vport for virtual ports when FDISC is complete. 10057725ccfdSJing Huang */ 10067725ccfdSJing Huang void 1007a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port) 10087725ccfdSJing Huang { 10097725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE); 10107725ccfdSJing Huang } 10117725ccfdSJing Huang 10125fbe25c7SJing Huang /* 10137725ccfdSJing Huang * Called by fabric for base port when fabric goes offline. 10147725ccfdSJing Huang * Called by vport for virtual ports when virtual port becomes offline. 10157725ccfdSJing Huang */ 10167725ccfdSJing Huang void 1017a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port) 10187725ccfdSJing Huang { 10197725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE); 10207725ccfdSJing Huang } 10217725ccfdSJing Huang 10225fbe25c7SJing Huang /* 1023881c1b3cSKrishna Gudipati * Called by fabric for base port and by vport for virtual ports 1024881c1b3cSKrishna Gudipati * when target mode driver is unloaded. 1025881c1b3cSKrishna Gudipati */ 1026881c1b3cSKrishna Gudipati void 1027881c1b3cSKrishna Gudipati bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port) 1028881c1b3cSKrishna Gudipati { 1029881c1b3cSKrishna Gudipati bfa_sm_send_event(port, BFA_FCS_PORT_SM_STOP); 1030881c1b3cSKrishna Gudipati } 1031881c1b3cSKrishna Gudipati 1032881c1b3cSKrishna Gudipati /* 10337725ccfdSJing Huang * Called by fabric to delete base lport and associated resources. 10347725ccfdSJing Huang * 10357725ccfdSJing Huang * Called by vport to delete lport and associated resources. Should call 10367725ccfdSJing Huang * bfa_fcs_vport_delete_comp() for vports on completion. 10377725ccfdSJing Huang */ 10387725ccfdSJing Huang void 1039a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port) 10407725ccfdSJing Huang { 10417725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE); 10427725ccfdSJing Huang } 10437725ccfdSJing Huang 10445fbe25c7SJing Huang /* 10457725ccfdSJing Huang * Return TRUE if port is online, else return FALSE 10467725ccfdSJing Huang */ 10477725ccfdSJing Huang bfa_boolean_t 1048a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port) 10497725ccfdSJing Huang { 1050a36c61f9SKrishna Gudipati return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online); 10517725ccfdSJing Huang } 10527725ccfdSJing Huang 10535fbe25c7SJing Huang /* 1054e6714324SKrishna Gudipati * Attach time initialization of logical ports. 10557725ccfdSJing Huang */ 10567725ccfdSJing Huang void 1057a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs, 1058a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_fcs_vport_s *vport) 10597725ccfdSJing Huang { 10607725ccfdSJing Huang lport->fcs = fcs; 10617725ccfdSJing Huang lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); 10627725ccfdSJing Huang lport->vport = vport; 10633fd45980SKrishna Gudipati lport->lp_tag = (vport) ? vport->lps->bfa_tag : 10643fd45980SKrishna Gudipati lport->fabric->lps->bfa_tag; 10657725ccfdSJing Huang 10667725ccfdSJing Huang INIT_LIST_HEAD(&lport->rport_q); 10677725ccfdSJing Huang lport->num_rports = 0; 1068e6714324SKrishna Gudipati } 10697725ccfdSJing Huang 10705fbe25c7SJing Huang /* 1071e6714324SKrishna Gudipati * Logical port initialization of base or virtual port. 1072e6714324SKrishna Gudipati * Called by fabric for base port or by vport for virtual ports. 1073e6714324SKrishna Gudipati */ 1074e6714324SKrishna Gudipati 1075e6714324SKrishna Gudipati void 1076a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, 1077a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *port_cfg) 1078e6714324SKrishna Gudipati { 1079e6714324SKrishna Gudipati struct bfa_fcs_vport_s *vport = lport->vport; 1080a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad; 1081a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 1082e6714324SKrishna Gudipati 10836a18b167SJing Huang lport->port_cfg = *port_cfg; 1084e6714324SKrishna Gudipati 1085a36c61f9SKrishna Gudipati lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport, 1086e6714324SKrishna Gudipati lport->port_cfg.roles, 10877725ccfdSJing Huang lport->fabric->vf_drv, 10887725ccfdSJing Huang vport ? vport->vport_drv : NULL); 1089e6714324SKrishna Gudipati 1090a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); 109188166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 1092a36c61f9SKrishna Gudipati "New logical port created: WWN = %s Role = %s\n", 1093a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 10947826f304SKrishna Gudipati bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW); 10957725ccfdSJing Huang 1096a36c61f9SKrishna Gudipati bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit); 10977725ccfdSJing Huang bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 10987725ccfdSJing Huang } 10997725ccfdSJing Huang 110022a08538SVijaya Mohan Guvva void 110122a08538SVijaya Mohan Guvva bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port, 110222a08538SVijaya Mohan Guvva char *symname) 110322a08538SVijaya Mohan Guvva { 110422a08538SVijaya Mohan Guvva strcpy(port->port_cfg.sym_name.symname, symname); 110522a08538SVijaya Mohan Guvva 110622a08538SVijaya Mohan Guvva if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 110722a08538SVijaya Mohan Guvva bfa_fcs_lport_ns_util_send_rspn_id( 110822a08538SVijaya Mohan Guvva BFA_FCS_GET_NS_FROM_PORT(port), NULL); 110922a08538SVijaya Mohan Guvva } 111022a08538SVijaya Mohan Guvva 11115fbe25c7SJing Huang /* 11127725ccfdSJing Huang * fcs_lport_api 11137725ccfdSJing Huang */ 11147725ccfdSJing Huang 11157725ccfdSJing Huang void 1116a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr( 1117a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 1118a36c61f9SKrishna Gudipati struct bfa_lport_attr_s *port_attr) 11197725ccfdSJing Huang { 1120a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 11217725ccfdSJing Huang port_attr->pid = port->pid; 11227725ccfdSJing Huang else 11237725ccfdSJing Huang port_attr->pid = 0; 11247725ccfdSJing Huang 11257725ccfdSJing Huang port_attr->port_cfg = port->port_cfg; 11267725ccfdSJing Huang 11277725ccfdSJing Huang if (port->fabric) { 1128f7f73812SMaggie Zhang port_attr->port_type = port->fabric->oper_type; 1129da99dcc9SMaggie Zhang port_attr->loopback = bfa_sm_cmp_state(port->fabric, 1130da99dcc9SMaggie Zhang bfa_fcs_fabric_sm_loopback); 1131f926a05fSKrishna Gudipati port_attr->authfail = 1132f7f73812SMaggie Zhang bfa_sm_cmp_state(port->fabric, 1133f7f73812SMaggie Zhang bfa_fcs_fabric_sm_auth_failed); 1134a36c61f9SKrishna Gudipati port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port); 11357725ccfdSJing Huang memcpy(port_attr->fabric_ip_addr, 1136a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fabric_ipaddr(port), 11377725ccfdSJing Huang BFA_FCS_FABRIC_IPADDR_SZ); 11387725ccfdSJing Huang 113986e32dabSKrishna Gudipati if (port->vport != NULL) { 1140a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_VPORT; 114186e32dabSKrishna Gudipati port_attr->fpma_mac = 1142f7f73812SMaggie Zhang port->vport->lps->lp_mac; 1143a36c61f9SKrishna Gudipati } else { 114486e32dabSKrishna Gudipati port_attr->fpma_mac = 1145f7f73812SMaggie Zhang port->fabric->lps->lp_mac; 1146a36c61f9SKrishna Gudipati } 1147a36c61f9SKrishna Gudipati } else { 1148a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_UNKNOWN; 1149a36c61f9SKrishna Gudipati port_attr->state = BFA_LPORT_UNINIT; 1150a36c61f9SKrishna Gudipati } 1151a36c61f9SKrishna Gudipati } 1152a36c61f9SKrishna Gudipati 11535fbe25c7SJing Huang /* 1154a36c61f9SKrishna Gudipati * bfa_fcs_lport_fab port fab functions 1155a36c61f9SKrishna Gudipati */ 1156a36c61f9SKrishna Gudipati 11575fbe25c7SJing Huang /* 1158a36c61f9SKrishna Gudipati * Called by port to initialize fabric services of the base port. 1159a36c61f9SKrishna Gudipati */ 1160a36c61f9SKrishna Gudipati static void 1161a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port) 1162a36c61f9SKrishna Gudipati { 1163a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(port); 1164a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(port); 1165a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(port); 1166a36c61f9SKrishna Gudipati } 1167a36c61f9SKrishna Gudipati 11685fbe25c7SJing Huang /* 1169a36c61f9SKrishna Gudipati * Called by port to notify transition to online state. 1170a36c61f9SKrishna Gudipati */ 1171a36c61f9SKrishna Gudipati static void 1172a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 1173a36c61f9SKrishna Gudipati { 1174a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(port); 1175bc0e2c2aSKrishna Gudipati bfa_fcs_lport_fab_scn_online(port); 1176a36c61f9SKrishna Gudipati } 1177a36c61f9SKrishna Gudipati 11785fbe25c7SJing Huang /* 1179a36c61f9SKrishna Gudipati * Called by port to notify transition to offline state. 1180a36c61f9SKrishna Gudipati */ 1181a36c61f9SKrishna Gudipati static void 1182a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port) 1183a36c61f9SKrishna Gudipati { 1184a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(port); 1185a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(port); 1186a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(port); 1187a36c61f9SKrishna Gudipati } 1188a36c61f9SKrishna Gudipati 11895fbe25c7SJing Huang /* 1190a36c61f9SKrishna Gudipati * bfa_fcs_lport_n2n functions 1191a36c61f9SKrishna Gudipati */ 1192a36c61f9SKrishna Gudipati 11935fbe25c7SJing Huang /* 1194a36c61f9SKrishna Gudipati * Called by fcs/port to initialize N2N topology. 1195a36c61f9SKrishna Gudipati */ 1196a36c61f9SKrishna Gudipati static void 1197a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port) 1198a36c61f9SKrishna Gudipati { 1199a36c61f9SKrishna Gudipati } 1200a36c61f9SKrishna Gudipati 12015fbe25c7SJing Huang /* 1202a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to online state. 1203a36c61f9SKrishna Gudipati */ 1204a36c61f9SKrishna Gudipati static void 1205a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port) 1206a36c61f9SKrishna Gudipati { 1207a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1208a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *pcfg = &port->port_cfg; 1209a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 1210a36c61f9SKrishna Gudipati 1211a36c61f9SKrishna Gudipati bfa_trc(port->fcs, pcfg->pwwn); 1212a36c61f9SKrishna Gudipati 1213a36c61f9SKrishna Gudipati /* 1214a36c61f9SKrishna Gudipati * If our PWWN is > than that of the r-port, we have to initiate PLOGI 1215a36c61f9SKrishna Gudipati * and assign an Address. if not, we need to wait for its PLOGI. 1216a36c61f9SKrishna Gudipati * 1217a36c61f9SKrishna Gudipati * If our PWWN is < than that of the remote port, it will send a PLOGI 1218a36c61f9SKrishna Gudipati * with the PIDs assigned. The rport state machine take care of this 1219a36c61f9SKrishna Gudipati * incoming PLOGI. 1220a36c61f9SKrishna Gudipati */ 1221a36c61f9SKrishna Gudipati if (memcmp 1222a36c61f9SKrishna Gudipati ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, 1223a36c61f9SKrishna Gudipati sizeof(wwn_t)) > 0) { 1224a36c61f9SKrishna Gudipati port->pid = N2N_LOCAL_PID; 1225b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID); 12265fbe25c7SJing Huang /* 1227a36c61f9SKrishna Gudipati * First, check if we know the device by pwwn. 1228a36c61f9SKrishna Gudipati */ 1229a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, 1230a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn); 1231a36c61f9SKrishna Gudipati if (rport) { 1232a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pid); 1233a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1234a36c61f9SKrishna Gudipati rport->pid = N2N_REMOTE_PID; 1235f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 1236a36c61f9SKrishna Gudipati return; 1237a36c61f9SKrishna Gudipati } 1238a36c61f9SKrishna Gudipati 1239a36c61f9SKrishna Gudipati /* 1240a36c61f9SKrishna Gudipati * In n2n there can be only one rport. Delete the old one 1241a36c61f9SKrishna Gudipati * whose pid should be zero, because it is offline. 1242a36c61f9SKrishna Gudipati */ 1243a36c61f9SKrishna Gudipati if (port->num_rports > 0) { 1244a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 0); 1245d4b671c5SJing Huang WARN_ON(rport == NULL); 1246a36c61f9SKrishna Gudipati if (rport) { 1247a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1248f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1249a36c61f9SKrishna Gudipati } 1250a36c61f9SKrishna Gudipati } 1251a36c61f9SKrishna Gudipati bfa_fcs_rport_create(port, N2N_REMOTE_PID); 1252a36c61f9SKrishna Gudipati } 1253a36c61f9SKrishna Gudipati } 1254a36c61f9SKrishna Gudipati 12555fbe25c7SJing Huang /* 1256a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to offline state. 1257a36c61f9SKrishna Gudipati */ 1258a36c61f9SKrishna Gudipati static void 1259a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port) 1260a36c61f9SKrishna Gudipati { 1261a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1262a36c61f9SKrishna Gudipati 1263a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 1264a36c61f9SKrishna Gudipati port->pid = 0; 1265a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn = 0; 1266a36c61f9SKrishna Gudipati n2n_port->reply_oxid = 0; 1267a36c61f9SKrishna Gudipati } 1268a36c61f9SKrishna Gudipati 1269bc0e2c2aSKrishna Gudipati void 1270bc0e2c2aSKrishna Gudipati bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port) 1271bc0e2c2aSKrishna Gudipati { 1272bc0e2c2aSKrishna Gudipati int i = 0, j = 0, bit = 0, alpa_bit = 0; 1273bc0e2c2aSKrishna Gudipati u8 k = 0; 1274bc0e2c2aSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa); 1275bc0e2c2aSKrishna Gudipati 1276bc0e2c2aSKrishna Gudipati port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid; 1277bc0e2c2aSKrishna Gudipati port->pid = fcport->myalpa; 1278bc0e2c2aSKrishna Gudipati port->pid = bfa_hton3b(port->pid); 1279bc0e2c2aSKrishna Gudipati 1280bc0e2c2aSKrishna Gudipati for (i = 0; i < (FC_ALPA_MAX / 8); i++) { 1281bc0e2c2aSKrishna Gudipati for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) { 1282bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]); 1283bc0e2c2aSKrishna Gudipati bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j))); 1284bc0e2c2aSKrishna Gudipati if (bit) { 1285bc0e2c2aSKrishna Gudipati port->port_topo.ploop.alpa_pos_map[k] = 1286bc0e2c2aSKrishna Gudipati loop_alpa_map[(i * 8) + alpa_bit]; 1287bc0e2c2aSKrishna Gudipati k++; 1288bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, k); 1289bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, 1290bc0e2c2aSKrishna Gudipati port->port_topo.ploop.alpa_pos_map[k]); 1291bc0e2c2aSKrishna Gudipati } 1292bc0e2c2aSKrishna Gudipati } 1293bc0e2c2aSKrishna Gudipati } 1294bc0e2c2aSKrishna Gudipati port->port_topo.ploop.num_alpa = k; 1295bc0e2c2aSKrishna Gudipati } 1296bc0e2c2aSKrishna Gudipati 1297bc0e2c2aSKrishna Gudipati /* 1298bc0e2c2aSKrishna Gudipati * Called by fcs/port to initialize Loop topology. 1299bc0e2c2aSKrishna Gudipati */ 1300bc0e2c2aSKrishna Gudipati static void 1301bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port) 1302bc0e2c2aSKrishna Gudipati { 1303bc0e2c2aSKrishna Gudipati } 1304bc0e2c2aSKrishna Gudipati 1305bc0e2c2aSKrishna Gudipati /* 1306bc0e2c2aSKrishna Gudipati * Called by fcs/port to notify transition to online state. 1307bc0e2c2aSKrishna Gudipati */ 1308bc0e2c2aSKrishna Gudipati static void 1309bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port) 1310bc0e2c2aSKrishna Gudipati { 1311bc0e2c2aSKrishna Gudipati u8 num_alpa = 0, alpabm_valid = 0; 1312bc0e2c2aSKrishna Gudipati struct bfa_fcs_rport_s *rport; 1313bc0e2c2aSKrishna Gudipati u8 *alpa_map = NULL; 1314bc0e2c2aSKrishna Gudipati int i = 0; 1315bc0e2c2aSKrishna Gudipati u32 pid; 1316bc0e2c2aSKrishna Gudipati 1317bc0e2c2aSKrishna Gudipati bfa_fcport_get_loop_attr(port); 1318bc0e2c2aSKrishna Gudipati 1319bc0e2c2aSKrishna Gudipati num_alpa = port->port_topo.ploop.num_alpa; 1320bc0e2c2aSKrishna Gudipati alpabm_valid = port->port_topo.ploop.alpabm_valid; 1321bc0e2c2aSKrishna Gudipati alpa_map = port->port_topo.ploop.alpa_pos_map; 1322bc0e2c2aSKrishna Gudipati 1323bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, port->pid); 1324bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, num_alpa); 1325bc0e2c2aSKrishna Gudipati if (alpabm_valid == 1) { 1326bc0e2c2aSKrishna Gudipati for (i = 0; i < num_alpa; i++) { 1327bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, alpa_map[i]); 1328bc0e2c2aSKrishna Gudipati if (alpa_map[i] != bfa_hton3b(port->pid)) { 1329bc0e2c2aSKrishna Gudipati pid = alpa_map[i]; 1330bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, pid); 1331bc0e2c2aSKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 1332bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1333bc0e2c2aSKrishna Gudipati if (!rport) 1334bc0e2c2aSKrishna Gudipati rport = bfa_fcs_rport_create(port, 1335bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1336bc0e2c2aSKrishna Gudipati } 1337bc0e2c2aSKrishna Gudipati } 1338bc0e2c2aSKrishna Gudipati } else { 1339bc0e2c2aSKrishna Gudipati for (i = 0; i < MAX_ALPA_COUNT; i++) { 1340bc0e2c2aSKrishna Gudipati if (alpa_map[i] != port->pid) { 1341bc0e2c2aSKrishna Gudipati pid = loop_alpa_map[i]; 1342bc0e2c2aSKrishna Gudipati bfa_trc(port->fcs->bfa, pid); 1343bc0e2c2aSKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 1344bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1345bc0e2c2aSKrishna Gudipati if (!rport) 1346bc0e2c2aSKrishna Gudipati rport = bfa_fcs_rport_create(port, 1347bc0e2c2aSKrishna Gudipati bfa_hton3b(pid)); 1348bc0e2c2aSKrishna Gudipati } 1349bc0e2c2aSKrishna Gudipati } 1350bc0e2c2aSKrishna Gudipati } 1351bc0e2c2aSKrishna Gudipati } 1352bc0e2c2aSKrishna Gudipati 1353bc0e2c2aSKrishna Gudipati /* 1354bc0e2c2aSKrishna Gudipati * Called by fcs/port to notify transition to offline state. 1355bc0e2c2aSKrishna Gudipati */ 1356bc0e2c2aSKrishna Gudipati static void 1357bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port) 1358bc0e2c2aSKrishna Gudipati { 1359bc0e2c2aSKrishna Gudipati } 1360bc0e2c2aSKrishna Gudipati 1361a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 1362a36c61f9SKrishna Gudipati 1363a36c61f9SKrishna Gudipati /* 1364a36c61f9SKrishna Gudipati * forward declarations 1365a36c61f9SKrishna Gudipati */ 1366a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, 1367a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1368a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, 1369a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1370a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, 1371a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1372a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, 1373a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1374a36c61f9SKrishna Gudipati void *cbarg, 1375a36c61f9SKrishna Gudipati bfa_status_t req_status, 1376a36c61f9SKrishna Gudipati u32 rsp_len, 1377a36c61f9SKrishna Gudipati u32 resid_len, 1378a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1379a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, 1380a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1381a36c61f9SKrishna Gudipati void *cbarg, 1382a36c61f9SKrishna Gudipati bfa_status_t req_status, 1383a36c61f9SKrishna Gudipati u32 rsp_len, 1384a36c61f9SKrishna Gudipati u32 resid_len, 1385a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1386a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, 1387a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1388a36c61f9SKrishna Gudipati void *cbarg, 1389a36c61f9SKrishna Gudipati bfa_status_t req_status, 1390a36c61f9SKrishna Gudipati u32 rsp_len, 1391a36c61f9SKrishna Gudipati u32 resid_len, 1392a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1393a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_timeout(void *arg); 1394a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1395a36c61f9SKrishna Gudipati u8 *pyld); 1396a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1397a36c61f9SKrishna Gudipati u8 *pyld); 1398a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1399a36c61f9SKrishna Gudipati u8 *pyld); 1400a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s * 1401a36c61f9SKrishna Gudipati fdmi, u8 *pyld); 1402a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1403a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr); 1404a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1405a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr); 1406d7be54ccSKrishna Gudipati u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed); 1407d7be54ccSKrishna Gudipati 14085fbe25c7SJing Huang /* 1409a36c61f9SKrishna Gudipati * fcs_fdmi_sm FCS FDMI state machine 1410a36c61f9SKrishna Gudipati */ 1411a36c61f9SKrishna Gudipati 14125fbe25c7SJing Huang /* 1413a36c61f9SKrishna Gudipati * FDMI State Machine events 1414a36c61f9SKrishna Gudipati */ 1415a36c61f9SKrishna Gudipati enum port_fdmi_event { 1416a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_ONLINE = 1, 1417a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_OFFLINE = 2, 1418a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_OK = 4, 1419a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_ERROR = 5, 1420a36c61f9SKrishna Gudipati FDMISM_EVENT_TIMEOUT = 6, 1421a36c61f9SKrishna Gudipati FDMISM_EVENT_RHBA_SENT = 7, 1422a36c61f9SKrishna Gudipati FDMISM_EVENT_RPRT_SENT = 8, 1423a36c61f9SKrishna Gudipati FDMISM_EVENT_RPA_SENT = 9, 1424a36c61f9SKrishna Gudipati }; 1425a36c61f9SKrishna Gudipati 1426a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1427a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1428a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rhba( 1429a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1430a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1431a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1432a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1433a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba_retry( 1434a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1435a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1436a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rprt( 1437a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1438a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1439a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1440a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1441a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt_retry( 1442a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1443a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1444a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rpa( 1445a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1446a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1447a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1448a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1449a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa_retry( 1450a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1451a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1452a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1453a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1454a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_disabled( 1455a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1456a36c61f9SKrishna Gudipati enum port_fdmi_event event); 14575fbe25c7SJing Huang /* 1458a36c61f9SKrishna Gudipati * Start in offline state - awaiting MS to send start. 1459a36c61f9SKrishna Gudipati */ 1460a36c61f9SKrishna Gudipati static void 1461a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1462a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1463a36c61f9SKrishna Gudipati { 1464a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1465a36c61f9SKrishna Gudipati 1466a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1467a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1468a36c61f9SKrishna Gudipati 1469a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1470a36c61f9SKrishna Gudipati 1471a36c61f9SKrishna Gudipati switch (event) { 1472a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_ONLINE: 1473a36c61f9SKrishna Gudipati if (port->vport) { 1474a36c61f9SKrishna Gudipati /* 1475a36c61f9SKrishna Gudipati * For Vports, register a new port. 1476a36c61f9SKrishna Gudipati */ 1477a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1478a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt); 1479a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1480a36c61f9SKrishna Gudipati } else { 1481a36c61f9SKrishna Gudipati /* 1482a36c61f9SKrishna Gudipati * For a base port, we should first register the HBA 148325985edcSLucas De Marchi * attribute. The HBA attribute also contains the base 1484a36c61f9SKrishna Gudipati * port registration. 1485a36c61f9SKrishna Gudipati */ 1486a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1487a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba); 1488a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1489a36c61f9SKrishna Gudipati } 1490a36c61f9SKrishna Gudipati break; 1491a36c61f9SKrishna Gudipati 1492a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1493a36c61f9SKrishna Gudipati break; 1494a36c61f9SKrishna Gudipati 1495a36c61f9SKrishna Gudipati default: 1496a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1497a36c61f9SKrishna Gudipati } 1498a36c61f9SKrishna Gudipati } 1499a36c61f9SKrishna Gudipati 1500a36c61f9SKrishna Gudipati static void 1501a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1502a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1503a36c61f9SKrishna Gudipati { 1504a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1505a36c61f9SKrishna Gudipati 1506a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1507a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1508a36c61f9SKrishna Gudipati 1509a36c61f9SKrishna Gudipati switch (event) { 1510a36c61f9SKrishna Gudipati case FDMISM_EVENT_RHBA_SENT: 1511a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba); 1512a36c61f9SKrishna Gudipati break; 1513a36c61f9SKrishna Gudipati 1514a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1515a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1516a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1517a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1518a36c61f9SKrishna Gudipati break; 1519a36c61f9SKrishna Gudipati 1520a36c61f9SKrishna Gudipati default: 1521a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1522a36c61f9SKrishna Gudipati } 1523a36c61f9SKrishna Gudipati } 1524a36c61f9SKrishna Gudipati 1525a36c61f9SKrishna Gudipati static void 1526a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1527a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1528a36c61f9SKrishna Gudipati { 1529a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1530a36c61f9SKrishna Gudipati 1531a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1532a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1533a36c61f9SKrishna Gudipati 1534a36c61f9SKrishna Gudipati switch (event) { 1535a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1536a36c61f9SKrishna Gudipati /* 1537a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1538a36c61f9SKrishna Gudipati * delayed retry 1539a36c61f9SKrishna Gudipati */ 1540a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1541a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1542a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry); 1543a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1544a36c61f9SKrishna Gudipati &fdmi->timer, 1545a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1546a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1547a36c61f9SKrishna Gudipati } else { 1548a36c61f9SKrishna Gudipati /* 1549a36c61f9SKrishna Gudipati * set state to offline 1550a36c61f9SKrishna Gudipati */ 1551a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1552a36c61f9SKrishna Gudipati } 1553a36c61f9SKrishna Gudipati break; 1554a36c61f9SKrishna Gudipati 1555a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1556a36c61f9SKrishna Gudipati /* 1557a36c61f9SKrishna Gudipati * Initiate Register Port Attributes 1558a36c61f9SKrishna Gudipati */ 1559a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1560a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1561a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1562a36c61f9SKrishna Gudipati break; 1563a36c61f9SKrishna Gudipati 1564a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1565a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1566a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1567a36c61f9SKrishna Gudipati break; 1568a36c61f9SKrishna Gudipati 1569a36c61f9SKrishna Gudipati default: 1570a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1571a36c61f9SKrishna Gudipati } 1572a36c61f9SKrishna Gudipati } 1573a36c61f9SKrishna Gudipati 1574a36c61f9SKrishna Gudipati static void 1575a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1576a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1577a36c61f9SKrishna Gudipati { 1578a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1579a36c61f9SKrishna Gudipati 1580a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1581a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1582a36c61f9SKrishna Gudipati 1583a36c61f9SKrishna Gudipati switch (event) { 1584a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1585a36c61f9SKrishna Gudipati /* 1586a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1587a36c61f9SKrishna Gudipati */ 1588a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba); 1589a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1590a36c61f9SKrishna Gudipati break; 1591a36c61f9SKrishna Gudipati 1592a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1593a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1594a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1595a36c61f9SKrishna Gudipati break; 1596a36c61f9SKrishna Gudipati 1597a36c61f9SKrishna Gudipati default: 1598a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1599a36c61f9SKrishna Gudipati } 1600a36c61f9SKrishna Gudipati } 1601a36c61f9SKrishna Gudipati 1602a36c61f9SKrishna Gudipati /* 1603a36c61f9SKrishna Gudipati * RPRT : Register Port 1604a36c61f9SKrishna Gudipati */ 1605a36c61f9SKrishna Gudipati static void 1606a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1607a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1608a36c61f9SKrishna Gudipati { 1609a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1610a36c61f9SKrishna Gudipati 1611a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1612a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1613a36c61f9SKrishna Gudipati 1614a36c61f9SKrishna Gudipati switch (event) { 1615a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPRT_SENT: 1616a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt); 1617a36c61f9SKrishna Gudipati break; 1618a36c61f9SKrishna Gudipati 1619a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1620a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1621a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1622a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1623a36c61f9SKrishna Gudipati break; 1624a36c61f9SKrishna Gudipati 1625a36c61f9SKrishna Gudipati default: 1626a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1627a36c61f9SKrishna Gudipati } 1628a36c61f9SKrishna Gudipati } 1629a36c61f9SKrishna Gudipati 1630a36c61f9SKrishna Gudipati static void 1631a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1632a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1633a36c61f9SKrishna Gudipati { 1634a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1635a36c61f9SKrishna Gudipati 1636a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1637a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1638a36c61f9SKrishna Gudipati 1639a36c61f9SKrishna Gudipati switch (event) { 1640a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1641a36c61f9SKrishna Gudipati /* 1642a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1643a36c61f9SKrishna Gudipati * delayed retry 1644a36c61f9SKrishna Gudipati */ 1645a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1646a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1647a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry); 1648a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1649a36c61f9SKrishna Gudipati &fdmi->timer, 1650a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1651a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 16527725ccfdSJing Huang 16537725ccfdSJing Huang } else { 1654a36c61f9SKrishna Gudipati /* 1655a36c61f9SKrishna Gudipati * set state to offline 1656a36c61f9SKrishna Gudipati */ 1657a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1658a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 16597725ccfdSJing Huang } 1660a36c61f9SKrishna Gudipati break; 1661a36c61f9SKrishna Gudipati 1662a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1663a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1664a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1665a36c61f9SKrishna Gudipati break; 1666a36c61f9SKrishna Gudipati 1667a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1668a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1669a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1670a36c61f9SKrishna Gudipati break; 1671a36c61f9SKrishna Gudipati 1672a36c61f9SKrishna Gudipati default: 1673a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1674a36c61f9SKrishna Gudipati } 1675a36c61f9SKrishna Gudipati } 1676a36c61f9SKrishna Gudipati 1677a36c61f9SKrishna Gudipati static void 1678a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1679a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1680a36c61f9SKrishna Gudipati { 1681a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1682a36c61f9SKrishna Gudipati 1683a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1684a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1685a36c61f9SKrishna Gudipati 1686a36c61f9SKrishna Gudipati switch (event) { 1687a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1688a36c61f9SKrishna Gudipati /* 1689a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1690a36c61f9SKrishna Gudipati */ 1691a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt); 1692a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1693a36c61f9SKrishna Gudipati break; 1694a36c61f9SKrishna Gudipati 1695a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1696a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1697a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1698a36c61f9SKrishna Gudipati break; 1699a36c61f9SKrishna Gudipati 1700a36c61f9SKrishna Gudipati default: 1701a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1702a36c61f9SKrishna Gudipati } 1703a36c61f9SKrishna Gudipati } 1704a36c61f9SKrishna Gudipati 1705a36c61f9SKrishna Gudipati /* 1706a36c61f9SKrishna Gudipati * Register Port Attributes 1707a36c61f9SKrishna Gudipati */ 1708a36c61f9SKrishna Gudipati static void 1709a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1710a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1711a36c61f9SKrishna Gudipati { 1712a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1713a36c61f9SKrishna Gudipati 1714a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1715a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1716a36c61f9SKrishna Gudipati 1717a36c61f9SKrishna Gudipati switch (event) { 1718a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPA_SENT: 1719a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa); 1720a36c61f9SKrishna Gudipati break; 1721a36c61f9SKrishna Gudipati 1722a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1723a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1724a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1725a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1726a36c61f9SKrishna Gudipati break; 1727a36c61f9SKrishna Gudipati 1728a36c61f9SKrishna Gudipati default: 1729a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1730a36c61f9SKrishna Gudipati } 1731a36c61f9SKrishna Gudipati } 1732a36c61f9SKrishna Gudipati 1733a36c61f9SKrishna Gudipati static void 1734a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1735a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1736a36c61f9SKrishna Gudipati { 1737a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1738a36c61f9SKrishna Gudipati 1739a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1740a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1741a36c61f9SKrishna Gudipati 1742a36c61f9SKrishna Gudipati switch (event) { 1743a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1744a36c61f9SKrishna Gudipati /* 1745a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1746a36c61f9SKrishna Gudipati * delayed retry 1747a36c61f9SKrishna Gudipati */ 1748a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1749a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry); 1750a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1751a36c61f9SKrishna Gudipati &fdmi->timer, 1752a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1753a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1754a36c61f9SKrishna Gudipati } else { 1755a36c61f9SKrishna Gudipati /* 1756a36c61f9SKrishna Gudipati * set state to offline 1757a36c61f9SKrishna Gudipati */ 1758a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1759a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1760a36c61f9SKrishna Gudipati } 1761a36c61f9SKrishna Gudipati break; 1762a36c61f9SKrishna Gudipati 1763a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1764a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1765a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1766a36c61f9SKrishna Gudipati break; 1767a36c61f9SKrishna Gudipati 1768a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1769a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1770a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1771a36c61f9SKrishna Gudipati break; 1772a36c61f9SKrishna Gudipati 1773a36c61f9SKrishna Gudipati default: 1774a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1775a36c61f9SKrishna Gudipati } 1776a36c61f9SKrishna Gudipati } 1777a36c61f9SKrishna Gudipati 1778a36c61f9SKrishna Gudipati static void 1779a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1780a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1781a36c61f9SKrishna Gudipati { 1782a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1783a36c61f9SKrishna Gudipati 1784a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1785a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1786a36c61f9SKrishna Gudipati 1787a36c61f9SKrishna Gudipati switch (event) { 1788a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1789a36c61f9SKrishna Gudipati /* 1790a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1791a36c61f9SKrishna Gudipati */ 1792a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1793a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1794a36c61f9SKrishna Gudipati break; 1795a36c61f9SKrishna Gudipati 1796a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1797a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1798a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1799a36c61f9SKrishna Gudipati break; 1800a36c61f9SKrishna Gudipati 1801a36c61f9SKrishna Gudipati default: 1802a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1803a36c61f9SKrishna Gudipati } 1804a36c61f9SKrishna Gudipati } 1805a36c61f9SKrishna Gudipati 1806a36c61f9SKrishna Gudipati static void 1807a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1808a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1809a36c61f9SKrishna Gudipati { 1810a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1811a36c61f9SKrishna Gudipati 1812a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1813a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1814a36c61f9SKrishna Gudipati 1815a36c61f9SKrishna Gudipati switch (event) { 1816a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1817a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1818a36c61f9SKrishna Gudipati break; 1819a36c61f9SKrishna Gudipati 1820a36c61f9SKrishna Gudipati default: 1821a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1822a36c61f9SKrishna Gudipati } 1823a36c61f9SKrishna Gudipati } 18245fbe25c7SJing Huang /* 1825a36c61f9SKrishna Gudipati * FDMI is disabled state. 1826a36c61f9SKrishna Gudipati */ 1827a36c61f9SKrishna Gudipati static void 1828a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi, 1829a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1830a36c61f9SKrishna Gudipati { 1831a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1832a36c61f9SKrishna Gudipati 1833a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1834a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1835a36c61f9SKrishna Gudipati 1836a36c61f9SKrishna Gudipati /* No op State. It can only be enabled at Driver Init. */ 1837a36c61f9SKrishna Gudipati } 1838a36c61f9SKrishna Gudipati 18395fbe25c7SJing Huang /* 1840a36c61f9SKrishna Gudipati * RHBA : Register HBA Attributes. 1841a36c61f9SKrishna Gudipati */ 1842a36c61f9SKrishna Gudipati static void 1843a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1844a36c61f9SKrishna Gudipati { 1845a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1846a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1847a36c61f9SKrishna Gudipati struct fchs_s fchs; 1848a36c61f9SKrishna Gudipati int len, attr_len; 1849a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1850a36c61f9SKrishna Gudipati u8 *pyld; 1851a36c61f9SKrishna Gudipati 1852a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1853a36c61f9SKrishna Gudipati 1854c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1855c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 1856a36c61f9SKrishna Gudipati if (!fcxp) { 1857a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1858c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE); 1859a36c61f9SKrishna Gudipati return; 1860a36c61f9SKrishna Gudipati } 1861a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 1862a36c61f9SKrishna Gudipati 1863a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 18646a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 1865a36c61f9SKrishna Gudipati 1866a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1867a36c61f9SKrishna Gudipati FDMI_RHBA); 1868a36c61f9SKrishna Gudipati 1869a36c61f9SKrishna Gudipati attr_len = 1870a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi, 1871a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 1872a36c61f9SKrishna Gudipati + 1)); 1873a36c61f9SKrishna Gudipati 1874a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1875a36c61f9SKrishna Gudipati FC_CLASS_3, (len + attr_len), &fchs, 1876a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi, 1877a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 1878a36c61f9SKrishna Gudipati 1879a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); 1880a36c61f9SKrishna Gudipati } 1881a36c61f9SKrishna Gudipati 1882a36c61f9SKrishna Gudipati static u16 1883a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 1884a36c61f9SKrishna Gudipati { 1885a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1886a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s hba_attr; 1887a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; 1888a36c61f9SKrishna Gudipati struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; 1889a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 1890a36c61f9SKrishna Gudipati u8 *curr_ptr; 1891a36c61f9SKrishna Gudipati u16 len, count; 189250444a34SMaggie u16 templen; 1893a36c61f9SKrishna Gudipati 1894a36c61f9SKrishna Gudipati /* 1895a36c61f9SKrishna Gudipati * get hba attributes 1896a36c61f9SKrishna Gudipati */ 1897a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); 1898a36c61f9SKrishna Gudipati 1899a36c61f9SKrishna Gudipati rhba->hba_id = bfa_fcs_lport_get_pwwn(port); 1900ba816ea8SJing Huang rhba->port_list.num_ports = cpu_to_be32(1); 1901a36c61f9SKrishna Gudipati rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port); 1902a36c61f9SKrishna Gudipati 1903a36c61f9SKrishna Gudipati len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); 1904a36c61f9SKrishna Gudipati 1905a36c61f9SKrishna Gudipati count = 0; 1906a36c61f9SKrishna Gudipati len += sizeof(rhba->hba_attr_blk.attr_count); 1907a36c61f9SKrishna Gudipati 1908a36c61f9SKrishna Gudipati /* 1909a36c61f9SKrishna Gudipati * fill out the invididual entries of the HBA attrib Block 1910a36c61f9SKrishna Gudipati */ 1911a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; 1912a36c61f9SKrishna Gudipati 1913a36c61f9SKrishna Gudipati /* 1914a36c61f9SKrishna Gudipati * Node Name 1915a36c61f9SKrishna Gudipati */ 1916a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1917ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME); 191850444a34SMaggie templen = sizeof(wwn_t); 191950444a34SMaggie memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen); 192050444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 192150444a34SMaggie len += templen; 1922a36c61f9SKrishna Gudipati count++; 192350444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 192450444a34SMaggie sizeof(templen)); 1925a36c61f9SKrishna Gudipati 1926a36c61f9SKrishna Gudipati /* 1927a36c61f9SKrishna Gudipati * Manufacturer 1928a36c61f9SKrishna Gudipati */ 1929a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1930ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER); 193150444a34SMaggie templen = (u16) strlen(fcs_hba_attr->manufacturer); 193250444a34SMaggie memcpy(attr->value, fcs_hba_attr->manufacturer, templen); 193350444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 193450444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 193550444a34SMaggie len += templen; 1936a36c61f9SKrishna Gudipati count++; 193750444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 193850444a34SMaggie sizeof(templen)); 1939a36c61f9SKrishna Gudipati 1940a36c61f9SKrishna Gudipati /* 1941a36c61f9SKrishna Gudipati * Serial Number 1942a36c61f9SKrishna Gudipati */ 1943a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1944ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM); 194550444a34SMaggie templen = (u16) strlen(fcs_hba_attr->serial_num); 194650444a34SMaggie memcpy(attr->value, fcs_hba_attr->serial_num, templen); 194750444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 194850444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 194950444a34SMaggie len += templen; 1950a36c61f9SKrishna Gudipati count++; 195150444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 195250444a34SMaggie sizeof(templen)); 1953a36c61f9SKrishna Gudipati 1954a36c61f9SKrishna Gudipati /* 1955a36c61f9SKrishna Gudipati * Model 1956a36c61f9SKrishna Gudipati */ 1957a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1958ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL); 195950444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model); 196050444a34SMaggie memcpy(attr->value, fcs_hba_attr->model, templen); 196150444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 196250444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 196350444a34SMaggie len += templen; 1964a36c61f9SKrishna Gudipati count++; 196550444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 196650444a34SMaggie sizeof(templen)); 1967a36c61f9SKrishna Gudipati 1968a36c61f9SKrishna Gudipati /* 1969a36c61f9SKrishna Gudipati * Model Desc 1970a36c61f9SKrishna Gudipati */ 1971a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1972ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC); 197350444a34SMaggie templen = (u16) strlen(fcs_hba_attr->model_desc); 197450444a34SMaggie memcpy(attr->value, fcs_hba_attr->model_desc, templen); 197550444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 197650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 197750444a34SMaggie len += templen; 1978a36c61f9SKrishna Gudipati count++; 197950444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 198050444a34SMaggie sizeof(templen)); 1981a36c61f9SKrishna Gudipati 1982a36c61f9SKrishna Gudipati /* 1983a36c61f9SKrishna Gudipati * H/W Version 1984a36c61f9SKrishna Gudipati */ 1985a36c61f9SKrishna Gudipati if (fcs_hba_attr->hw_version[0] != '\0') { 1986a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1987ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION); 198850444a34SMaggie templen = (u16) strlen(fcs_hba_attr->hw_version); 198950444a34SMaggie memcpy(attr->value, fcs_hba_attr->hw_version, templen); 199050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 199150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 199250444a34SMaggie len += templen; 1993a36c61f9SKrishna Gudipati count++; 199450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 199550444a34SMaggie sizeof(templen)); 1996a36c61f9SKrishna Gudipati } 1997a36c61f9SKrishna Gudipati 1998a36c61f9SKrishna Gudipati /* 1999a36c61f9SKrishna Gudipati * Driver Version 2000a36c61f9SKrishna Gudipati */ 2001a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2002ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION); 200350444a34SMaggie templen = (u16) strlen(fcs_hba_attr->driver_version); 200450444a34SMaggie memcpy(attr->value, fcs_hba_attr->driver_version, templen); 200550444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 200650444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2007dd5aaf45SKrishna Gudipati len += templen; 2008a36c61f9SKrishna Gudipati count++; 200950444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 201050444a34SMaggie sizeof(templen)); 2011a36c61f9SKrishna Gudipati 2012a36c61f9SKrishna Gudipati /* 2013a36c61f9SKrishna Gudipati * Option Rom Version 2014a36c61f9SKrishna Gudipati */ 2015a36c61f9SKrishna Gudipati if (fcs_hba_attr->option_rom_ver[0] != '\0') { 2016a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2017ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION); 201850444a34SMaggie templen = (u16) strlen(fcs_hba_attr->option_rom_ver); 201950444a34SMaggie memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen); 202050444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 202150444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 202250444a34SMaggie len += templen; 2023a36c61f9SKrishna Gudipati count++; 202450444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 202550444a34SMaggie sizeof(templen)); 2026a36c61f9SKrishna Gudipati } 2027a36c61f9SKrishna Gudipati 2028a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2029ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); 2030b480a32eSKrishna Gudipati templen = (u16) strlen(fcs_hba_attr->fw_version); 2031b480a32eSKrishna Gudipati memcpy(attr->value, fcs_hba_attr->fw_version, templen); 203250444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 203350444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 203450444a34SMaggie len += templen; 2035a36c61f9SKrishna Gudipati count++; 203650444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 203750444a34SMaggie sizeof(templen)); 2038a36c61f9SKrishna Gudipati 2039a36c61f9SKrishna Gudipati /* 2040a36c61f9SKrishna Gudipati * OS Name 2041a36c61f9SKrishna Gudipati */ 2042a36c61f9SKrishna Gudipati if (fcs_hba_attr->os_name[0] != '\0') { 2043a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2044ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME); 204550444a34SMaggie templen = (u16) strlen(fcs_hba_attr->os_name); 204650444a34SMaggie memcpy(attr->value, fcs_hba_attr->os_name, templen); 204750444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 204850444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 204950444a34SMaggie len += templen; 2050a36c61f9SKrishna Gudipati count++; 205150444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 205250444a34SMaggie sizeof(templen)); 2053a36c61f9SKrishna Gudipati } 2054a36c61f9SKrishna Gudipati 2055a36c61f9SKrishna Gudipati /* 2056a36c61f9SKrishna Gudipati * MAX_CT_PAYLOAD 2057a36c61f9SKrishna Gudipati */ 2058a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2059ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); 206050444a34SMaggie templen = sizeof(fcs_hba_attr->max_ct_pyld); 206150444a34SMaggie memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen); 2062d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2063d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 206450444a34SMaggie len += templen; 2065a36c61f9SKrishna Gudipati count++; 206650444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 206750444a34SMaggie sizeof(templen)); 2068d7cbc304SVijaya Mohan Guvva /* 2069d7cbc304SVijaya Mohan Guvva * Send extended attributes ( FOS 7.1 support ) 2070d7cbc304SVijaya Mohan Guvva */ 2071d7cbc304SVijaya Mohan Guvva if (fdmi->retry_cnt == 0) { 2072d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2073d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODE_SYM_NAME); 2074d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->node_sym_name); 2075d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->node_sym_name, templen); 2076d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2077d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2078d7cbc304SVijaya Mohan Guvva len += templen; 2079d7cbc304SVijaya Mohan Guvva count++; 2080d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2081d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2082d7cbc304SVijaya Mohan Guvva 2083d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2084d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_VENDOR_ID); 2085d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->vendor_info); 2086d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->vendor_info, templen); 2087d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2088d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2089d7cbc304SVijaya Mohan Guvva len += templen; 2090d7cbc304SVijaya Mohan Guvva count++; 2091d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2092d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2093d7cbc304SVijaya Mohan Guvva 2094d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2095d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NUM_PORTS); 2096d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->num_ports); 2097d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->num_ports, templen); 2098d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2099d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2100d7cbc304SVijaya Mohan Guvva len += templen; 2101d7cbc304SVijaya Mohan Guvva count++; 2102d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2103d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2104d7cbc304SVijaya Mohan Guvva 2105d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2106d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FABRIC_NAME); 2107d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->fabric_name); 2108d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->fabric_name, templen); 2109d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2110d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2111d7cbc304SVijaya Mohan Guvva len += templen; 2112d7cbc304SVijaya Mohan Guvva count++; 2113d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2114d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2115d7cbc304SVijaya Mohan Guvva 2116d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2117d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_BIOS_VER); 2118d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_hba_attr->bios_ver); 2119d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_hba_attr->bios_ver, templen); 2120d7cbc304SVijaya Mohan Guvva templen = fc_roundup(attr->len, sizeof(u32)); 2121d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2122d7cbc304SVijaya Mohan Guvva len += templen; 2123d7cbc304SVijaya Mohan Guvva count++; 2124d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2125d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2126d7cbc304SVijaya Mohan Guvva } 2127a36c61f9SKrishna Gudipati 2128a36c61f9SKrishna Gudipati /* 2129a36c61f9SKrishna Gudipati * Update size of payload 2130a36c61f9SKrishna Gudipati */ 21315fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 2132a36c61f9SKrishna Gudipati 2133ba816ea8SJing Huang rhba->hba_attr_blk.attr_count = cpu_to_be32(count); 2134a36c61f9SKrishna Gudipati return len; 2135a36c61f9SKrishna Gudipati } 2136a36c61f9SKrishna Gudipati 2137a36c61f9SKrishna Gudipati static void 2138a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2139a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2140a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2141a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2142a36c61f9SKrishna Gudipati { 2143a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2144a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2145a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2146a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2147a36c61f9SKrishna Gudipati 2148a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2149a36c61f9SKrishna Gudipati 2150a36c61f9SKrishna Gudipati /* 2151a36c61f9SKrishna Gudipati * Sanity Checks 2152a36c61f9SKrishna Gudipati */ 2153a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2154a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2155a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2156a36c61f9SKrishna Gudipati return; 2157a36c61f9SKrishna Gudipati } 2158a36c61f9SKrishna Gudipati 2159a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2160ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2161a36c61f9SKrishna Gudipati 2162a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2163a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2164a36c61f9SKrishna Gudipati return; 2165a36c61f9SKrishna Gudipati } 2166a36c61f9SKrishna Gudipati 2167a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2168a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2169a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2170a36c61f9SKrishna Gudipati } 2171a36c61f9SKrishna Gudipati 21725fbe25c7SJing Huang /* 2173a36c61f9SKrishna Gudipati * RPRT : Register Port 2174a36c61f9SKrishna Gudipati */ 2175a36c61f9SKrishna Gudipati static void 2176a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2177a36c61f9SKrishna Gudipati { 2178a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2179a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2180a36c61f9SKrishna Gudipati struct fchs_s fchs; 2181a36c61f9SKrishna Gudipati u16 len, attr_len; 2182a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2183a36c61f9SKrishna Gudipati u8 *pyld; 2184a36c61f9SKrishna Gudipati 2185a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2186a36c61f9SKrishna Gudipati 2187c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 2188c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 2189a36c61f9SKrishna Gudipati if (!fcxp) { 2190a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2191c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE); 2192a36c61f9SKrishna Gudipati return; 2193a36c61f9SKrishna Gudipati } 2194a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2195a36c61f9SKrishna Gudipati 2196a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 21976a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2198a36c61f9SKrishna Gudipati 2199a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2200a36c61f9SKrishna Gudipati FDMI_RPRT); 2201a36c61f9SKrishna Gudipati 2202a36c61f9SKrishna Gudipati attr_len = 2203a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi, 2204a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 2205a36c61f9SKrishna Gudipati + 1)); 2206a36c61f9SKrishna Gudipati 2207a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2208a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2209a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi, 2210a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2211a36c61f9SKrishna Gudipati 2212a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); 2213a36c61f9SKrishna Gudipati } 2214a36c61f9SKrishna Gudipati 22155fbe25c7SJing Huang /* 2216a36c61f9SKrishna Gudipati * This routine builds Port Attribute Block that used in RPA, RPRT commands. 2217a36c61f9SKrishna Gudipati */ 2218a36c61f9SKrishna Gudipati static u16 2219a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi, 2220a36c61f9SKrishna Gudipati u8 *pyld) 2221a36c61f9SKrishna Gudipati { 2222a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 2223a36c61f9SKrishna Gudipati struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; 2224a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 2225a36c61f9SKrishna Gudipati u8 *curr_ptr; 2226a36c61f9SKrishna Gudipati u16 len; 2227a36c61f9SKrishna Gudipati u8 count = 0; 222850444a34SMaggie u16 templen; 2229a36c61f9SKrishna Gudipati 2230a36c61f9SKrishna Gudipati /* 2231a36c61f9SKrishna Gudipati * get port attributes 2232a36c61f9SKrishna Gudipati */ 2233a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 2234a36c61f9SKrishna Gudipati 2235a36c61f9SKrishna Gudipati len = sizeof(port_attrib->attr_count); 2236a36c61f9SKrishna Gudipati 2237a36c61f9SKrishna Gudipati /* 2238a36c61f9SKrishna Gudipati * fill out the invididual entries 2239a36c61f9SKrishna Gudipati */ 2240a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &port_attrib->port_attr; 2241a36c61f9SKrishna Gudipati 2242a36c61f9SKrishna Gudipati /* 2243a36c61f9SKrishna Gudipati * FC4 Types 2244a36c61f9SKrishna Gudipati */ 2245a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2246ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES); 224750444a34SMaggie templen = sizeof(fcs_port_attr.supp_fc4_types); 224850444a34SMaggie memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen); 224950444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 225050444a34SMaggie len += templen; 2251a36c61f9SKrishna Gudipati ++count; 2252a36c61f9SKrishna Gudipati attr->len = 225350444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 225450444a34SMaggie sizeof(templen)); 2255a36c61f9SKrishna Gudipati 2256a36c61f9SKrishna Gudipati /* 2257a36c61f9SKrishna Gudipati * Supported Speed 2258a36c61f9SKrishna Gudipati */ 2259a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2260ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED); 226150444a34SMaggie templen = sizeof(fcs_port_attr.supp_speed); 226250444a34SMaggie memcpy(attr->value, &fcs_port_attr.supp_speed, templen); 226350444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 226450444a34SMaggie len += templen; 2265a36c61f9SKrishna Gudipati ++count; 2266a36c61f9SKrishna Gudipati attr->len = 226750444a34SMaggie cpu_to_be16(templen + sizeof(attr->type) + 226850444a34SMaggie sizeof(templen)); 2269a36c61f9SKrishna Gudipati 2270a36c61f9SKrishna Gudipati /* 2271a36c61f9SKrishna Gudipati * current Port Speed 2272a36c61f9SKrishna Gudipati */ 2273a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2274ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED); 227550444a34SMaggie templen = sizeof(fcs_port_attr.curr_speed); 227650444a34SMaggie memcpy(attr->value, &fcs_port_attr.curr_speed, templen); 227750444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 227850444a34SMaggie len += templen; 2279a36c61f9SKrishna Gudipati ++count; 228050444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 228150444a34SMaggie sizeof(templen)); 2282a36c61f9SKrishna Gudipati 2283a36c61f9SKrishna Gudipati /* 2284a36c61f9SKrishna Gudipati * max frame size 2285a36c61f9SKrishna Gudipati */ 2286a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2287ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE); 228850444a34SMaggie templen = sizeof(fcs_port_attr.max_frm_size); 228950444a34SMaggie memcpy(attr->value, &fcs_port_attr.max_frm_size, templen); 229050444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 229150444a34SMaggie len += templen; 2292a36c61f9SKrishna Gudipati ++count; 229350444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 229450444a34SMaggie sizeof(templen)); 2295a36c61f9SKrishna Gudipati 2296a36c61f9SKrishna Gudipati /* 2297a36c61f9SKrishna Gudipati * OS Device Name 2298a36c61f9SKrishna Gudipati */ 2299a36c61f9SKrishna Gudipati if (fcs_port_attr.os_device_name[0] != '\0') { 2300a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2301ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME); 230250444a34SMaggie templen = (u16) strlen(fcs_port_attr.os_device_name); 230350444a34SMaggie memcpy(attr->value, fcs_port_attr.os_device_name, templen); 230450444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 230550444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 230650444a34SMaggie len += templen; 2307a36c61f9SKrishna Gudipati ++count; 230850444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 230950444a34SMaggie sizeof(templen)); 2310a36c61f9SKrishna Gudipati } 2311a36c61f9SKrishna Gudipati /* 2312a36c61f9SKrishna Gudipati * Host Name 2313a36c61f9SKrishna Gudipati */ 2314a36c61f9SKrishna Gudipati if (fcs_port_attr.host_name[0] != '\0') { 2315a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 2316ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME); 231750444a34SMaggie templen = (u16) strlen(fcs_port_attr.host_name); 231850444a34SMaggie memcpy(attr->value, fcs_port_attr.host_name, templen); 231950444a34SMaggie templen = fc_roundup(templen, sizeof(u32)); 232050444a34SMaggie curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 232150444a34SMaggie len += templen; 2322a36c61f9SKrishna Gudipati ++count; 232350444a34SMaggie attr->len = cpu_to_be16(templen + sizeof(attr->type) + 232450444a34SMaggie sizeof(templen)); 2325a36c61f9SKrishna Gudipati } 2326a36c61f9SKrishna Gudipati 2327d7cbc304SVijaya Mohan Guvva if (fdmi->retry_cnt == 0) { 2328d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2329d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_NODE_NAME); 2330d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.node_name); 2331d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.node_name, templen); 2332d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2333d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2334d7cbc304SVijaya Mohan Guvva len += templen; 2335d7cbc304SVijaya Mohan Guvva ++count; 2336d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2337d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2338d7cbc304SVijaya Mohan Guvva 2339d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2340d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NAME); 2341d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_name); 2342d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_name, templen); 2343d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2344d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(attr->len) + templen; 2345d7cbc304SVijaya Mohan Guvva len += templen; 2346d7cbc304SVijaya Mohan Guvva ++count; 2347d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2348d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2349d7cbc304SVijaya Mohan Guvva 2350d7cbc304SVijaya Mohan Guvva if (fcs_port_attr.port_sym_name.symname[0] != '\0') { 2351d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2352d7cbc304SVijaya Mohan Guvva attr->type = 2353d7cbc304SVijaya Mohan Guvva cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SYM_NAME); 2354d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_sym_name); 2355d7cbc304SVijaya Mohan Guvva memcpy(attr->value, 2356d7cbc304SVijaya Mohan Guvva &fcs_port_attr.port_sym_name, templen); 2357d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2358d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + 2359d7cbc304SVijaya Mohan Guvva sizeof(templen) + templen; 2360d7cbc304SVijaya Mohan Guvva len += templen; 2361d7cbc304SVijaya Mohan Guvva ++count; 2362d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + 2363d7cbc304SVijaya Mohan Guvva sizeof(attr->type) + sizeof(templen)); 2364d7cbc304SVijaya Mohan Guvva } 2365d7cbc304SVijaya Mohan Guvva 2366d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2367d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_TYPE); 2368d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_type); 2369d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_type, templen); 2370d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2371d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2372d7cbc304SVijaya Mohan Guvva len += templen; 2373d7cbc304SVijaya Mohan Guvva ++count; 2374d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2375d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2376d7cbc304SVijaya Mohan Guvva 2377d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2378d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_COS); 2379d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.scos); 2380d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.scos, templen); 2381d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2382d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2383d7cbc304SVijaya Mohan Guvva len += templen; 2384d7cbc304SVijaya Mohan Guvva ++count; 2385d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2386d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2387d7cbc304SVijaya Mohan Guvva 2388d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2389d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FAB_NAME); 2390d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_fabric_name); 2391d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_fabric_name, templen); 2392d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2393d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2394d7cbc304SVijaya Mohan Guvva len += templen; 2395d7cbc304SVijaya Mohan Guvva ++count; 2396d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2397d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2398d7cbc304SVijaya Mohan Guvva 2399d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2400d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FC4_TYPE); 2401d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_act_fc4_type); 2402d7cbc304SVijaya Mohan Guvva memcpy(attr->value, fcs_port_attr.port_act_fc4_type, 2403d7cbc304SVijaya Mohan Guvva templen); 2404d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2405d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2406d7cbc304SVijaya Mohan Guvva len += templen; 2407d7cbc304SVijaya Mohan Guvva ++count; 2408d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2409d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2410d7cbc304SVijaya Mohan Guvva 2411d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2412d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_STATE); 2413d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.port_state); 2414d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.port_state, templen); 2415d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2416d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2417d7cbc304SVijaya Mohan Guvva len += templen; 2418d7cbc304SVijaya Mohan Guvva ++count; 2419d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2420d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2421d7cbc304SVijaya Mohan Guvva 2422d7cbc304SVijaya Mohan Guvva attr = (struct fdmi_attr_s *) curr_ptr; 2423d7cbc304SVijaya Mohan Guvva attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NUM_RPRT); 2424d7cbc304SVijaya Mohan Guvva templen = sizeof(fcs_port_attr.num_ports); 2425d7cbc304SVijaya Mohan Guvva memcpy(attr->value, &fcs_port_attr.num_ports, templen); 2426d7cbc304SVijaya Mohan Guvva templen = fc_roundup(templen, sizeof(u32)); 2427d7cbc304SVijaya Mohan Guvva curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2428d7cbc304SVijaya Mohan Guvva len += templen; 2429d7cbc304SVijaya Mohan Guvva ++count; 2430d7cbc304SVijaya Mohan Guvva attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2431d7cbc304SVijaya Mohan Guvva sizeof(templen)); 2432d7cbc304SVijaya Mohan Guvva } 2433d7cbc304SVijaya Mohan Guvva 2434a36c61f9SKrishna Gudipati /* 2435a36c61f9SKrishna Gudipati * Update size of payload 2436a36c61f9SKrishna Gudipati */ 2437ba816ea8SJing Huang port_attrib->attr_count = cpu_to_be32(count); 24385fbe25c7SJing Huang len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 2439a36c61f9SKrishna Gudipati return len; 2440a36c61f9SKrishna Gudipati } 2441a36c61f9SKrishna Gudipati 2442a36c61f9SKrishna Gudipati static u16 2443a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2444a36c61f9SKrishna Gudipati { 2445a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2446a36c61f9SKrishna Gudipati struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; 2447a36c61f9SKrishna Gudipati u16 len; 2448a36c61f9SKrishna Gudipati 2449a36c61f9SKrishna Gudipati rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs)); 2450a36c61f9SKrishna Gudipati rprt->port_name = bfa_fcs_lport_get_pwwn(port); 2451a36c61f9SKrishna Gudipati 2452a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2453a36c61f9SKrishna Gudipati (u8 *) &rprt->port_attr_blk); 2454a36c61f9SKrishna Gudipati 2455a36c61f9SKrishna Gudipati len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); 2456a36c61f9SKrishna Gudipati 2457a36c61f9SKrishna Gudipati return len; 2458a36c61f9SKrishna Gudipati } 2459a36c61f9SKrishna Gudipati 2460a36c61f9SKrishna Gudipati static void 2461a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2462a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2463a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2464a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2465a36c61f9SKrishna Gudipati { 2466a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2467a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2468a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2469a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2470a36c61f9SKrishna Gudipati 2471a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2472a36c61f9SKrishna Gudipati 2473a36c61f9SKrishna Gudipati /* 2474a36c61f9SKrishna Gudipati * Sanity Checks 2475a36c61f9SKrishna Gudipati */ 2476a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2477a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2478a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2479a36c61f9SKrishna Gudipati return; 2480a36c61f9SKrishna Gudipati } 2481a36c61f9SKrishna Gudipati 2482a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2483ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2484a36c61f9SKrishna Gudipati 2485a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2486a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2487a36c61f9SKrishna Gudipati return; 2488a36c61f9SKrishna Gudipati } 2489a36c61f9SKrishna Gudipati 2490a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2491a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2492a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2493a36c61f9SKrishna Gudipati } 2494a36c61f9SKrishna Gudipati 24955fbe25c7SJing Huang /* 2496a36c61f9SKrishna Gudipati * RPA : Register Port Attributes. 2497a36c61f9SKrishna Gudipati */ 2498a36c61f9SKrishna Gudipati static void 2499a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2500a36c61f9SKrishna Gudipati { 2501a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2502a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2503a36c61f9SKrishna Gudipati struct fchs_s fchs; 2504a36c61f9SKrishna Gudipati u16 len, attr_len; 2505a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2506a36c61f9SKrishna Gudipati u8 *pyld; 2507a36c61f9SKrishna Gudipati 2508a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2509a36c61f9SKrishna Gudipati 2510c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 2511c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 2512a36c61f9SKrishna Gudipati if (!fcxp) { 2513a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2514c3f1b123SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE); 2515a36c61f9SKrishna Gudipati return; 2516a36c61f9SKrishna Gudipati } 2517a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2518a36c61f9SKrishna Gudipati 2519a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 25206a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2521a36c61f9SKrishna Gudipati 2522a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2523a36c61f9SKrishna Gudipati FDMI_RPA); 2524a36c61f9SKrishna Gudipati 25255fbe25c7SJing Huang attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi, 25265fbe25c7SJing Huang (u8 *) ((struct ct_hdr_s *) pyld + 1)); 2527a36c61f9SKrishna Gudipati 2528a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2529a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2530a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi, 2531a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2532a36c61f9SKrishna Gudipati 2533a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); 2534a36c61f9SKrishna Gudipati } 2535a36c61f9SKrishna Gudipati 2536a36c61f9SKrishna Gudipati static u16 2537a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2538a36c61f9SKrishna Gudipati { 2539a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2540a36c61f9SKrishna Gudipati struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; 2541a36c61f9SKrishna Gudipati u16 len; 2542a36c61f9SKrishna Gudipati 2543a36c61f9SKrishna Gudipati rpa->port_name = bfa_fcs_lport_get_pwwn(port); 2544a36c61f9SKrishna Gudipati 2545a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2546a36c61f9SKrishna Gudipati (u8 *) &rpa->port_attr_blk); 2547a36c61f9SKrishna Gudipati 2548a36c61f9SKrishna Gudipati len += sizeof(rpa->port_name); 2549a36c61f9SKrishna Gudipati 2550a36c61f9SKrishna Gudipati return len; 2551a36c61f9SKrishna Gudipati } 2552a36c61f9SKrishna Gudipati 2553a36c61f9SKrishna Gudipati static void 2554a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2555a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 2556a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 2557a36c61f9SKrishna Gudipati { 2558a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2559a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2560a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2561a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2562a36c61f9SKrishna Gudipati 2563a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2564a36c61f9SKrishna Gudipati 2565a36c61f9SKrishna Gudipati /* 2566a36c61f9SKrishna Gudipati * Sanity Checks 2567a36c61f9SKrishna Gudipati */ 2568a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2569a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2570a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2571a36c61f9SKrishna Gudipati return; 2572a36c61f9SKrishna Gudipati } 2573a36c61f9SKrishna Gudipati 2574a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2575ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2576a36c61f9SKrishna Gudipati 2577a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2578a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2579a36c61f9SKrishna Gudipati return; 2580a36c61f9SKrishna Gudipati } 2581a36c61f9SKrishna Gudipati 2582a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2583a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2584a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2585a36c61f9SKrishna Gudipati } 2586a36c61f9SKrishna Gudipati 2587a36c61f9SKrishna Gudipati static void 2588a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg) 2589a36c61f9SKrishna Gudipati { 2590a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg; 2591a36c61f9SKrishna Gudipati 2592a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); 2593a36c61f9SKrishna Gudipati } 2594a36c61f9SKrishna Gudipati 259552f94b6fSMaggie static void 2596a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2597a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr) 2598a36c61f9SKrishna Gudipati { 2599a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2600a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2601b480a32eSKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 2602a36c61f9SKrishna Gudipati 26036a18b167SJing Huang memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 2604a36c61f9SKrishna Gudipati 2605a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, 2606a36c61f9SKrishna Gudipati hba_attr->manufacturer); 2607a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, 2608a36c61f9SKrishna Gudipati hba_attr->serial_num); 2609a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2610a36c61f9SKrishna Gudipati hba_attr->model); 2611a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2612a36c61f9SKrishna Gudipati hba_attr->model_desc); 2613a36c61f9SKrishna Gudipati bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, 2614a36c61f9SKrishna Gudipati hba_attr->hw_version); 2615a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, 2616a36c61f9SKrishna Gudipati hba_attr->option_rom_ver); 2617a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, 2618a36c61f9SKrishna Gudipati hba_attr->fw_version); 2619a36c61f9SKrishna Gudipati 2620a36c61f9SKrishna Gudipati strncpy(hba_attr->driver_version, (char *)driver_info->version, 2621a36c61f9SKrishna Gudipati sizeof(hba_attr->driver_version)); 2622a36c61f9SKrishna Gudipati 2623a36c61f9SKrishna Gudipati strncpy(hba_attr->os_name, driver_info->host_os_name, 2624a36c61f9SKrishna Gudipati sizeof(hba_attr->os_name)); 2625a36c61f9SKrishna Gudipati 2626a36c61f9SKrishna Gudipati /* 2627a36c61f9SKrishna Gudipati * If there is a patch level, append it 2628a36c61f9SKrishna Gudipati * to the os name along with a separator 2629a36c61f9SKrishna Gudipati */ 2630a36c61f9SKrishna Gudipati if (driver_info->host_os_patch[0] != '\0') { 2631a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 2632a36c61f9SKrishna Gudipati sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); 2633a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, driver_info->host_os_patch, 2634a36c61f9SKrishna Gudipati sizeof(driver_info->host_os_patch)); 2635a36c61f9SKrishna Gudipati } 2636a36c61f9SKrishna Gudipati 2637b480a32eSKrishna Gudipati /* Retrieve the max frame size from the port attr */ 2638b480a32eSKrishna Gudipati bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 2639b480a32eSKrishna Gudipati hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size; 2640d7cbc304SVijaya Mohan Guvva 2641d7cbc304SVijaya Mohan Guvva strncpy(hba_attr->node_sym_name.symname, 2642d7cbc304SVijaya Mohan Guvva port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); 2643d7cbc304SVijaya Mohan Guvva strcpy(hba_attr->vendor_info, "BROCADE"); 2644d7cbc304SVijaya Mohan Guvva hba_attr->num_ports = 2645d7cbc304SVijaya Mohan Guvva cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); 2646d7cbc304SVijaya Mohan Guvva hba_attr->fabric_name = port->fabric->lps->pr_nwwn; 2647d7cbc304SVijaya Mohan Guvva strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); 2648d7cbc304SVijaya Mohan Guvva 2649a36c61f9SKrishna Gudipati } 2650a36c61f9SKrishna Gudipati 265152f94b6fSMaggie static void 2652a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2653a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr) 2654a36c61f9SKrishna Gudipati { 2655a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2656a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2657a36c61f9SKrishna Gudipati struct bfa_port_attr_s pport_attr; 2658d7cbc304SVijaya Mohan Guvva struct bfa_lport_attr_s lport_attr; 2659a36c61f9SKrishna Gudipati 26606a18b167SJing Huang memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); 2661a36c61f9SKrishna Gudipati 2662a36c61f9SKrishna Gudipati /* 2663a36c61f9SKrishna Gudipati * get pport attributes from hal 2664a36c61f9SKrishna Gudipati */ 2665a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 2666a36c61f9SKrishna Gudipati 2667a36c61f9SKrishna Gudipati /* 2668a36c61f9SKrishna Gudipati * get FC4 type Bitmask 2669a36c61f9SKrishna Gudipati */ 2670a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); 2671a36c61f9SKrishna Gudipati 2672a36c61f9SKrishna Gudipati /* 2673a36c61f9SKrishna Gudipati * Supported Speeds 2674a36c61f9SKrishna Gudipati */ 2675d7be54ccSKrishna Gudipati switch (pport_attr.speed_supported) { 2676d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2677d7be54ccSKrishna Gudipati port_attr->supp_speed = 2678d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G); 2679d7be54ccSKrishna Gudipati break; 2680d7be54ccSKrishna Gudipati 2681d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2682d7be54ccSKrishna Gudipati port_attr->supp_speed = 2683d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G); 2684d7be54ccSKrishna Gudipati break; 2685d7be54ccSKrishna Gudipati 2686d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2687d7be54ccSKrishna Gudipati port_attr->supp_speed = 2688d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G); 2689d7be54ccSKrishna Gudipati break; 2690d7be54ccSKrishna Gudipati 2691d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2692d7be54ccSKrishna Gudipati port_attr->supp_speed = 2693d7be54ccSKrishna Gudipati cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G); 2694d7be54ccSKrishna Gudipati break; 2695d7be54ccSKrishna Gudipati 2696d7be54ccSKrishna Gudipati default: 2697d7be54ccSKrishna Gudipati bfa_sm_fault(port->fcs, pport_attr.speed_supported); 2698d7be54ccSKrishna Gudipati } 2699a36c61f9SKrishna Gudipati 2700a36c61f9SKrishna Gudipati /* 2701a36c61f9SKrishna Gudipati * Current Speed 2702a36c61f9SKrishna Gudipati */ 2703d7be54ccSKrishna Gudipati port_attr->curr_speed = cpu_to_be32( 2704d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(pport_attr.speed)); 2705a36c61f9SKrishna Gudipati 2706a36c61f9SKrishna Gudipati /* 2707a36c61f9SKrishna Gudipati * Max PDU Size. 2708a36c61f9SKrishna Gudipati */ 2709b480a32eSKrishna Gudipati port_attr->max_frm_size = cpu_to_be32(pport_attr.pport_cfg.maxfrsize); 2710a36c61f9SKrishna Gudipati 2711a36c61f9SKrishna Gudipati /* 2712a36c61f9SKrishna Gudipati * OS device Name 2713a36c61f9SKrishna Gudipati */ 2714a36c61f9SKrishna Gudipati strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, 2715a36c61f9SKrishna Gudipati sizeof(port_attr->os_device_name)); 2716a36c61f9SKrishna Gudipati 2717a36c61f9SKrishna Gudipati /* 2718a36c61f9SKrishna Gudipati * Host name 2719a36c61f9SKrishna Gudipati */ 2720a36c61f9SKrishna Gudipati strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, 2721a36c61f9SKrishna Gudipati sizeof(port_attr->host_name)); 27227725ccfdSJing Huang 2723d7cbc304SVijaya Mohan Guvva port_attr->node_name = bfa_fcs_lport_get_nwwn(port); 2724d7cbc304SVijaya Mohan Guvva port_attr->port_name = bfa_fcs_lport_get_pwwn(port); 2725d7cbc304SVijaya Mohan Guvva 2726d7cbc304SVijaya Mohan Guvva strncpy(port_attr->port_sym_name.symname, 2727d7cbc304SVijaya Mohan Guvva (char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN); 2728d7cbc304SVijaya Mohan Guvva bfa_fcs_lport_get_attr(port, &lport_attr); 2729d7cbc304SVijaya Mohan Guvva port_attr->port_type = cpu_to_be32(lport_attr.port_type); 2730d7cbc304SVijaya Mohan Guvva port_attr->scos = pport_attr.cos_supported; 2731d7cbc304SVijaya Mohan Guvva port_attr->port_fabric_name = port->fabric->lps->pr_nwwn; 2732d7cbc304SVijaya Mohan Guvva fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->port_act_fc4_type); 2733d7cbc304SVijaya Mohan Guvva port_attr->port_state = cpu_to_be32(pport_attr.port_state); 2734d7cbc304SVijaya Mohan Guvva port_attr->num_ports = cpu_to_be32(port->num_rports); 27357725ccfdSJing Huang } 27367725ccfdSJing Huang 2737d7be54ccSKrishna Gudipati /* 2738d7be54ccSKrishna Gudipati * Convert BFA speed to FDMI format. 2739d7be54ccSKrishna Gudipati */ 2740d7be54ccSKrishna Gudipati u32 2741d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed) 2742d7be54ccSKrishna Gudipati { 2743d7be54ccSKrishna Gudipati u32 ret; 2744d7be54ccSKrishna Gudipati 2745d7be54ccSKrishna Gudipati switch (pport_speed) { 2746d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_1GBPS: 2747d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_2GBPS: 2748d7be54ccSKrishna Gudipati ret = pport_speed; 2749d7be54ccSKrishna Gudipati break; 2750d7be54ccSKrishna Gudipati 2751d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_4GBPS: 2752d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_4G; 2753d7be54ccSKrishna Gudipati break; 2754d7be54ccSKrishna Gudipati 2755d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_8GBPS: 2756d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_8G; 2757d7be54ccSKrishna Gudipati break; 2758d7be54ccSKrishna Gudipati 2759d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_10GBPS: 2760d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_10G; 2761d7be54ccSKrishna Gudipati break; 2762d7be54ccSKrishna Gudipati 2763d7be54ccSKrishna Gudipati case BFA_PORT_SPEED_16GBPS: 2764d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_16G; 2765d7be54ccSKrishna Gudipati break; 2766d7be54ccSKrishna Gudipati 2767d7be54ccSKrishna Gudipati default: 2768d7be54ccSKrishna Gudipati ret = FDMI_TRANS_SPEED_UNKNOWN; 2769d7be54ccSKrishna Gudipati } 2770d7be54ccSKrishna Gudipati return ret; 2771d7be54ccSKrishna Gudipati } 27727725ccfdSJing Huang 2773a36c61f9SKrishna Gudipati void 2774a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) 2775a36c61f9SKrishna Gudipati { 2776a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2777a36c61f9SKrishna Gudipati 2778a36c61f9SKrishna Gudipati fdmi->ms = ms; 2779a36c61f9SKrishna Gudipati if (ms->port->fcs->fdmi_enabled) 2780a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 2781a36c61f9SKrishna Gudipati else 2782a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled); 2783a36c61f9SKrishna Gudipati } 2784a36c61f9SKrishna Gudipati 2785a36c61f9SKrishna Gudipati void 2786a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms) 2787a36c61f9SKrishna Gudipati { 2788a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2789a36c61f9SKrishna Gudipati 2790a36c61f9SKrishna Gudipati fdmi->ms = ms; 2791a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); 2792a36c61f9SKrishna Gudipati } 2793a36c61f9SKrishna Gudipati 2794a36c61f9SKrishna Gudipati void 2795a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms) 2796a36c61f9SKrishna Gudipati { 2797a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2798a36c61f9SKrishna Gudipati 2799a36c61f9SKrishna Gudipati fdmi->ms = ms; 2800a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); 2801a36c61f9SKrishna Gudipati } 2802a36c61f9SKrishna Gudipati 2803a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES 2 2804a36c61f9SKrishna Gudipati 2805a36c61f9SKrishna Gudipati /* 2806a36c61f9SKrishna Gudipati * forward declarations 2807a36c61f9SKrishna Gudipati */ 2808a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, 2809a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2810a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_timeout(void *arg); 2811a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_plogi_response(void *fcsarg, 2812a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2813a36c61f9SKrishna Gudipati void *cbarg, 2814a36c61f9SKrishna Gudipati bfa_status_t req_status, 2815a36c61f9SKrishna Gudipati u32 rsp_len, 2816a36c61f9SKrishna Gudipati u32 resid_len, 2817a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2818a36c61f9SKrishna Gudipati 2819a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, 2820a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2821a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gmal_response(void *fcsarg, 2822a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2823a36c61f9SKrishna Gudipati void *cbarg, 2824a36c61f9SKrishna Gudipati bfa_status_t req_status, 2825a36c61f9SKrishna Gudipati u32 rsp_len, 2826a36c61f9SKrishna Gudipati u32 resid_len, 2827a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2828a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, 2829a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2830a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gfn_response(void *fcsarg, 2831a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2832a36c61f9SKrishna Gudipati void *cbarg, 2833a36c61f9SKrishna Gudipati bfa_status_t req_status, 2834a36c61f9SKrishna Gudipati u32 rsp_len, 2835a36c61f9SKrishna Gudipati u32 resid_len, 2836a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 28375fbe25c7SJing Huang /* 2838a36c61f9SKrishna Gudipati * fcs_ms_sm FCS MS state machine 2839a36c61f9SKrishna Gudipati */ 2840a36c61f9SKrishna Gudipati 28415fbe25c7SJing Huang /* 2842a36c61f9SKrishna Gudipati * MS State Machine events 2843a36c61f9SKrishna Gudipati */ 2844a36c61f9SKrishna Gudipati enum port_ms_event { 2845a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_ONLINE = 1, 2846a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_OFFLINE = 2, 2847a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_OK = 3, 2848a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_ERROR = 4, 2849a36c61f9SKrishna Gudipati MSSM_EVENT_TIMEOUT = 5, 2850a36c61f9SKrishna Gudipati MSSM_EVENT_FCXP_SENT = 6, 2851a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_FABRIC_RSCN = 7 2852a36c61f9SKrishna Gudipati }; 2853a36c61f9SKrishna Gudipati 2854a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2855a36c61f9SKrishna Gudipati enum port_ms_event event); 2856a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2857a36c61f9SKrishna Gudipati enum port_ms_event event); 2858a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2859a36c61f9SKrishna Gudipati enum port_ms_event event); 2860a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2861a36c61f9SKrishna Gudipati enum port_ms_event event); 2862a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2863a36c61f9SKrishna Gudipati enum port_ms_event event); 2864a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2865a36c61f9SKrishna Gudipati enum port_ms_event event); 2866a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2867a36c61f9SKrishna Gudipati enum port_ms_event event); 2868a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2869a36c61f9SKrishna Gudipati enum port_ms_event event); 2870a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2871a36c61f9SKrishna Gudipati enum port_ms_event event); 2872a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2873a36c61f9SKrishna Gudipati enum port_ms_event event); 2874a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2875a36c61f9SKrishna Gudipati enum port_ms_event event); 28765fbe25c7SJing Huang /* 2877a36c61f9SKrishna Gudipati * Start in offline state - awaiting NS to send start. 2878a36c61f9SKrishna Gudipati */ 2879a36c61f9SKrishna Gudipati static void 2880a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2881a36c61f9SKrishna Gudipati enum port_ms_event event) 2882a36c61f9SKrishna Gudipati { 2883a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2884a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2885a36c61f9SKrishna Gudipati 2886a36c61f9SKrishna Gudipati switch (event) { 2887a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_ONLINE: 2888a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2889a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2890a36c61f9SKrishna Gudipati break; 2891a36c61f9SKrishna Gudipati 2892a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2893a36c61f9SKrishna Gudipati break; 2894a36c61f9SKrishna Gudipati 2895a36c61f9SKrishna Gudipati default: 2896a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2897a36c61f9SKrishna Gudipati } 2898a36c61f9SKrishna Gudipati } 2899a36c61f9SKrishna Gudipati 2900a36c61f9SKrishna Gudipati static void 2901a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2902a36c61f9SKrishna Gudipati enum port_ms_event event) 2903a36c61f9SKrishna Gudipati { 2904a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2905a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2906a36c61f9SKrishna Gudipati 2907a36c61f9SKrishna Gudipati switch (event) { 2908a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2909a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi); 2910a36c61f9SKrishna Gudipati break; 2911a36c61f9SKrishna Gudipati 2912a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2913a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2914a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2915a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2916a36c61f9SKrishna Gudipati break; 2917a36c61f9SKrishna Gudipati 2918a36c61f9SKrishna Gudipati default: 2919a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2920a36c61f9SKrishna Gudipati } 2921a36c61f9SKrishna Gudipati } 2922a36c61f9SKrishna Gudipati 2923a36c61f9SKrishna Gudipati static void 2924a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2925a36c61f9SKrishna Gudipati enum port_ms_event event) 2926a36c61f9SKrishna Gudipati { 2927a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2928a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2929a36c61f9SKrishna Gudipati 2930a36c61f9SKrishna Gudipati switch (event) { 2931a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2932a36c61f9SKrishna Gudipati /* 2933a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2934a36c61f9SKrishna Gudipati */ 2935a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry); 2936a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2937a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2938a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2939a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2940a36c61f9SKrishna Gudipati break; 2941a36c61f9SKrishna Gudipati 2942a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2943a36c61f9SKrishna Gudipati /* 2944a36c61f9SKrishna Gudipati * since plogi is done, now invoke MS related sub-modules 2945a36c61f9SKrishna Gudipati */ 2946a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(ms); 2947a36c61f9SKrishna Gudipati 29485fbe25c7SJing Huang /* 2949a36c61f9SKrishna Gudipati * if this is a Vport, go to online state. 2950a36c61f9SKrishna Gudipati */ 2951a36c61f9SKrishna Gudipati if (ms->port->vport) { 2952a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2953a36c61f9SKrishna Gudipati break; 2954a36c61f9SKrishna Gudipati } 2955a36c61f9SKrishna Gudipati 2956a36c61f9SKrishna Gudipati /* 2957a36c61f9SKrishna Gudipati * For a base port we need to get the 2958a36c61f9SKrishna Gudipati * switch's IP address. 2959a36c61f9SKrishna Gudipati */ 2960a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2961a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2962a36c61f9SKrishna Gudipati break; 2963a36c61f9SKrishna Gudipati 2964a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2965a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2966a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2967a36c61f9SKrishna Gudipati break; 2968a36c61f9SKrishna Gudipati 2969a36c61f9SKrishna Gudipati default: 2970a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2971a36c61f9SKrishna Gudipati } 2972a36c61f9SKrishna Gudipati } 2973a36c61f9SKrishna Gudipati 2974a36c61f9SKrishna Gudipati static void 2975a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2976a36c61f9SKrishna Gudipati enum port_ms_event event) 2977a36c61f9SKrishna Gudipati { 2978a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2979a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2980a36c61f9SKrishna Gudipati 2981a36c61f9SKrishna Gudipati switch (event) { 2982a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2983a36c61f9SKrishna Gudipati /* 2984a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2985a36c61f9SKrishna Gudipati */ 2986a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2987a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2988a36c61f9SKrishna Gudipati break; 2989a36c61f9SKrishna Gudipati 2990a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2991a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2992a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2993a36c61f9SKrishna Gudipati break; 2994a36c61f9SKrishna Gudipati 2995a36c61f9SKrishna Gudipati default: 2996a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2997a36c61f9SKrishna Gudipati } 2998a36c61f9SKrishna Gudipati } 2999a36c61f9SKrishna Gudipati 3000a36c61f9SKrishna Gudipati static void 3001a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 3002a36c61f9SKrishna Gudipati enum port_ms_event event) 3003a36c61f9SKrishna Gudipati { 3004a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3005a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3006a36c61f9SKrishna Gudipati 3007a36c61f9SKrishna Gudipati switch (event) { 3008a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3009a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3010a36c61f9SKrishna Gudipati break; 3011a36c61f9SKrishna Gudipati 3012a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_FABRIC_RSCN: 3013a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3014a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 3015a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3016a36c61f9SKrishna Gudipati break; 3017a36c61f9SKrishna Gudipati 3018a36c61f9SKrishna Gudipati default: 3019a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3020a36c61f9SKrishna Gudipati } 3021a36c61f9SKrishna Gudipati } 3022a36c61f9SKrishna Gudipati 3023a36c61f9SKrishna Gudipati static void 3024a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 3025a36c61f9SKrishna Gudipati enum port_ms_event event) 3026a36c61f9SKrishna Gudipati { 3027a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3028a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3029a36c61f9SKrishna Gudipati 3030a36c61f9SKrishna Gudipati switch (event) { 3031a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 3032a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal); 3033a36c61f9SKrishna Gudipati break; 3034a36c61f9SKrishna Gudipati 3035a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3036a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3037a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3038a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 3039a36c61f9SKrishna Gudipati break; 3040a36c61f9SKrishna Gudipati 3041a36c61f9SKrishna Gudipati default: 3042a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3043a36c61f9SKrishna Gudipati } 3044a36c61f9SKrishna Gudipati } 3045a36c61f9SKrishna Gudipati 3046a36c61f9SKrishna Gudipati static void 3047a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 3048a36c61f9SKrishna Gudipati enum port_ms_event event) 3049a36c61f9SKrishna Gudipati { 3050a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3051a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3052a36c61f9SKrishna Gudipati 3053a36c61f9SKrishna Gudipati switch (event) { 3054a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 3055a36c61f9SKrishna Gudipati /* 3056a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3057a36c61f9SKrishna Gudipati */ 3058a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 3059a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry); 3060a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 3061a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3062a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 3063a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3064a36c61f9SKrishna Gudipati } else { 3065a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3066a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3067a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 3068a36c61f9SKrishna Gudipati } 3069a36c61f9SKrishna Gudipati break; 3070a36c61f9SKrishna Gudipati 3071a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 3072a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3073a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3074a36c61f9SKrishna Gudipati break; 3075a36c61f9SKrishna Gudipati 3076a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3077a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3078a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 3079a36c61f9SKrishna Gudipati break; 3080a36c61f9SKrishna Gudipati 3081a36c61f9SKrishna Gudipati default: 3082a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3083a36c61f9SKrishna Gudipati } 3084a36c61f9SKrishna Gudipati } 3085a36c61f9SKrishna Gudipati 3086a36c61f9SKrishna Gudipati static void 3087a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 3088a36c61f9SKrishna Gudipati enum port_ms_event event) 3089a36c61f9SKrishna Gudipati { 3090a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3091a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3092a36c61f9SKrishna Gudipati 3093a36c61f9SKrishna Gudipati switch (event) { 3094a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 3095a36c61f9SKrishna Gudipati /* 3096a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3097a36c61f9SKrishna Gudipati */ 3098a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 3099a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 3100a36c61f9SKrishna Gudipati break; 3101a36c61f9SKrishna Gudipati 3102a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3103a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3104a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 3105a36c61f9SKrishna Gudipati break; 3106a36c61f9SKrishna Gudipati 3107a36c61f9SKrishna Gudipati default: 3108a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3109a36c61f9SKrishna Gudipati } 3110a36c61f9SKrishna Gudipati } 31115fbe25c7SJing Huang /* 3112a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3113a36c61f9SKrishna Gudipati */ 3114a36c61f9SKrishna Gudipati 3115a36c61f9SKrishna Gudipati static void 3116a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3117a36c61f9SKrishna Gudipati { 3118a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3119a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3120a36c61f9SKrishna Gudipati struct fchs_s fchs; 3121a36c61f9SKrishna Gudipati int len; 3122a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3123a36c61f9SKrishna Gudipati 3124a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3125a36c61f9SKrishna Gudipati 3126c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3127c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3128a36c61f9SKrishna Gudipati if (!fcxp) { 3129a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3130c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE); 3131a36c61f9SKrishna Gudipati return; 3132a36c61f9SKrishna Gudipati } 3133a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3134a36c61f9SKrishna Gudipati 3135a36c61f9SKrishna Gudipati len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3136a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 3137f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 3138a36c61f9SKrishna Gudipati 3139a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3140a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3141a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response, (void *)ms, 3142a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3143a36c61f9SKrishna Gudipati 3144a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3145a36c61f9SKrishna Gudipati } 3146a36c61f9SKrishna Gudipati 3147a36c61f9SKrishna Gudipati static void 3148a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3149a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3150a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3151a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 3152a36c61f9SKrishna Gudipati { 3153a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3154a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3155a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3156a36c61f9SKrishna Gudipati struct fcgs_gmal_resp_s *gmal_resp; 3157a36c61f9SKrishna Gudipati struct fcgs_gmal_entry_s *gmal_entry; 3158a36c61f9SKrishna Gudipati u32 num_entries; 3159a36c61f9SKrishna Gudipati u8 *rsp_str; 3160a36c61f9SKrishna Gudipati 3161a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3162a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3163a36c61f9SKrishna Gudipati 3164a36c61f9SKrishna Gudipati /* 3165a36c61f9SKrishna Gudipati * Sanity Checks 3166a36c61f9SKrishna Gudipati */ 3167a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3168a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3169a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3170a36c61f9SKrishna Gudipati return; 3171a36c61f9SKrishna Gudipati } 3172a36c61f9SKrishna Gudipati 3173a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3174ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3175a36c61f9SKrishna Gudipati 3176a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3177a36c61f9SKrishna Gudipati gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); 3178a36c61f9SKrishna Gudipati 3179ba816ea8SJing Huang num_entries = be32_to_cpu(gmal_resp->ms_len); 3180a36c61f9SKrishna Gudipati if (num_entries == 0) { 3181a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3182a36c61f9SKrishna Gudipati return; 3183a36c61f9SKrishna Gudipati } 3184a36c61f9SKrishna Gudipati /* 3185a36c61f9SKrishna Gudipati * The response could contain multiple Entries. 3186a36c61f9SKrishna Gudipati * Entries for SNMP interface, etc. 3187a36c61f9SKrishna Gudipati * We look for the entry with a telnet prefix. 3188a36c61f9SKrishna Gudipati * First "http://" entry refers to IP addr 3189a36c61f9SKrishna Gudipati */ 3190a36c61f9SKrishna Gudipati 3191a36c61f9SKrishna Gudipati gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma; 3192a36c61f9SKrishna Gudipati while (num_entries > 0) { 3193a36c61f9SKrishna Gudipati if (strncmp(gmal_entry->prefix, 3194a36c61f9SKrishna Gudipati CT_GMAL_RESP_PREFIX_HTTP, 3195a36c61f9SKrishna Gudipati sizeof(gmal_entry->prefix)) == 0) { 3196a36c61f9SKrishna Gudipati 3197a36c61f9SKrishna Gudipati /* 3198a36c61f9SKrishna Gudipati * if the IP address is terminating with a '/', 3199a36c61f9SKrishna Gudipati * remove it. 3200a36c61f9SKrishna Gudipati * Byte 0 consists of the length of the string. 3201a36c61f9SKrishna Gudipati */ 3202a36c61f9SKrishna Gudipati rsp_str = &(gmal_entry->prefix[0]); 3203a36c61f9SKrishna Gudipati if (rsp_str[gmal_entry->len-1] == '/') 3204a36c61f9SKrishna Gudipati rsp_str[gmal_entry->len-1] = 0; 3205a36c61f9SKrishna Gudipati 3206a36c61f9SKrishna Gudipati /* copy IP Address to fabric */ 3207a36c61f9SKrishna Gudipati strncpy(bfa_fcs_lport_get_fabric_ipaddr(port), 3208a36c61f9SKrishna Gudipati gmal_entry->ip_addr, 3209a36c61f9SKrishna Gudipati BFA_FCS_FABRIC_IPADDR_SZ); 3210a36c61f9SKrishna Gudipati break; 3211a36c61f9SKrishna Gudipati } else { 3212a36c61f9SKrishna Gudipati --num_entries; 3213a36c61f9SKrishna Gudipati ++gmal_entry; 3214a36c61f9SKrishna Gudipati } 3215a36c61f9SKrishna Gudipati } 3216a36c61f9SKrishna Gudipati 3217a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3218a36c61f9SKrishna Gudipati return; 3219a36c61f9SKrishna Gudipati } 3220a36c61f9SKrishna Gudipati 3221a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3222a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3223a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3224a36c61f9SKrishna Gudipati } 3225a36c61f9SKrishna Gudipati 3226a36c61f9SKrishna Gudipati static void 3227a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 3228a36c61f9SKrishna Gudipati enum port_ms_event event) 3229a36c61f9SKrishna Gudipati { 3230a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3231a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3232a36c61f9SKrishna Gudipati 3233a36c61f9SKrishna Gudipati switch (event) { 3234a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 3235a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn); 3236a36c61f9SKrishna Gudipati break; 3237a36c61f9SKrishna Gudipati 3238a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3239a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3240a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3241a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 3242a36c61f9SKrishna Gudipati break; 3243a36c61f9SKrishna Gudipati 3244a36c61f9SKrishna Gudipati default: 3245a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3246a36c61f9SKrishna Gudipati } 3247a36c61f9SKrishna Gudipati } 3248a36c61f9SKrishna Gudipati 3249a36c61f9SKrishna Gudipati static void 3250a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 3251a36c61f9SKrishna Gudipati enum port_ms_event event) 3252a36c61f9SKrishna Gudipati { 3253a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3254a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3255a36c61f9SKrishna Gudipati 3256a36c61f9SKrishna Gudipati switch (event) { 3257a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 3258a36c61f9SKrishna Gudipati /* 3259a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3260a36c61f9SKrishna Gudipati */ 3261a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 3262a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry); 3263a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 3264a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 3265a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 3266a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3267a36c61f9SKrishna Gudipati } else { 3268a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 3269a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 3270a36c61f9SKrishna Gudipati } 3271a36c61f9SKrishna Gudipati break; 3272a36c61f9SKrishna Gudipati 3273a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 3274a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 3275a36c61f9SKrishna Gudipati break; 3276a36c61f9SKrishna Gudipati 3277a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3278a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3279a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 3280a36c61f9SKrishna Gudipati break; 3281a36c61f9SKrishna Gudipati 3282a36c61f9SKrishna Gudipati default: 3283a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3284a36c61f9SKrishna Gudipati } 3285a36c61f9SKrishna Gudipati } 3286a36c61f9SKrishna Gudipati 3287a36c61f9SKrishna Gudipati static void 3288a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 3289a36c61f9SKrishna Gudipati enum port_ms_event event) 3290a36c61f9SKrishna Gudipati { 3291a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 3292a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 3293a36c61f9SKrishna Gudipati 3294a36c61f9SKrishna Gudipati switch (event) { 3295a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 3296a36c61f9SKrishna Gudipati /* 3297a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3298a36c61f9SKrishna Gudipati */ 3299a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 3300a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 3301a36c61f9SKrishna Gudipati break; 3302a36c61f9SKrishna Gudipati 3303a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 3304a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3305a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 3306a36c61f9SKrishna Gudipati break; 3307a36c61f9SKrishna Gudipati 3308a36c61f9SKrishna Gudipati default: 3309a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 3310a36c61f9SKrishna Gudipati } 3311a36c61f9SKrishna Gudipati } 33125fbe25c7SJing Huang /* 3313a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3314a36c61f9SKrishna Gudipati */ 3315a36c61f9SKrishna Gudipati 3316a36c61f9SKrishna Gudipati static void 3317a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3318a36c61f9SKrishna Gudipati { 3319a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3320a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3321a36c61f9SKrishna Gudipati struct fchs_s fchs; 3322a36c61f9SKrishna Gudipati int len; 3323a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3324a36c61f9SKrishna Gudipati 3325a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3326a36c61f9SKrishna Gudipati 3327c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3328c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3329a36c61f9SKrishna Gudipati if (!fcxp) { 3330a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3331c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE); 3332a36c61f9SKrishna Gudipati return; 3333a36c61f9SKrishna Gudipati } 3334a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3335a36c61f9SKrishna Gudipati 3336a36c61f9SKrishna Gudipati len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3337a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 3338f7f73812SMaggie Zhang port->fabric->lps->pr_nwwn); 3339a36c61f9SKrishna Gudipati 3340a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3341a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3342a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response, (void *)ms, 3343a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3344a36c61f9SKrishna Gudipati 3345a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3346a36c61f9SKrishna Gudipati } 3347a36c61f9SKrishna Gudipati 3348a36c61f9SKrishna Gudipati static void 3349a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3350a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 3351a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 3352a36c61f9SKrishna Gudipati { 3353a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3354a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 3355a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3356a36c61f9SKrishna Gudipati wwn_t *gfn_resp; 3357a36c61f9SKrishna Gudipati 3358a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3359a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3360a36c61f9SKrishna Gudipati 3361a36c61f9SKrishna Gudipati /* 3362a36c61f9SKrishna Gudipati * Sanity Checks 3363a36c61f9SKrishna Gudipati */ 3364a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3365a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3366a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3367a36c61f9SKrishna Gudipati return; 3368a36c61f9SKrishna Gudipati } 3369a36c61f9SKrishna Gudipati 3370a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3371ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3372a36c61f9SKrishna Gudipati 3373a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3374a36c61f9SKrishna Gudipati gfn_resp = (wwn_t *)(cthdr + 1); 3375a36c61f9SKrishna Gudipati /* check if it has actually changed */ 3376a36c61f9SKrishna Gudipati if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port), 3377a36c61f9SKrishna Gudipati gfn_resp, sizeof(wwn_t)) != 0)) { 3378a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); 3379a36c61f9SKrishna Gudipati } 3380a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3381a36c61f9SKrishna Gudipati return; 3382a36c61f9SKrishna Gudipati } 3383a36c61f9SKrishna Gudipati 3384a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3385a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3386a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3387a36c61f9SKrishna Gudipati } 3388a36c61f9SKrishna Gudipati 33895fbe25c7SJing Huang /* 3390a36c61f9SKrishna Gudipati * ms_pvt MS local functions 3391a36c61f9SKrishna Gudipati */ 3392a36c61f9SKrishna Gudipati 3393a36c61f9SKrishna Gudipati static void 3394a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3395a36c61f9SKrishna Gudipati { 3396a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 3397a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3398a36c61f9SKrishna Gudipati struct fchs_s fchs; 3399a36c61f9SKrishna Gudipati int len; 3400a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3401a36c61f9SKrishna Gudipati 3402a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3403a36c61f9SKrishna Gudipati 3404c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3405c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3406a36c61f9SKrishna Gudipati if (!fcxp) { 3407a36c61f9SKrishna Gudipati port->stats.ms_plogi_alloc_wait++; 3408a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3409c3f1b123SKrishna Gudipati bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE); 3410a36c61f9SKrishna Gudipati return; 3411a36c61f9SKrishna Gudipati } 3412a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 3413a36c61f9SKrishna Gudipati 3414a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3415f16a1750SMaggie Zhang bfa_hton3b(FC_MGMT_SERVER), 3416a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3417a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 3418be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 3419be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3420a36c61f9SKrishna Gudipati 3421a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3422a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3423a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response, (void *)ms, 3424a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 3425a36c61f9SKrishna Gudipati 3426a36c61f9SKrishna Gudipati port->stats.ms_plogi_sent++; 3427a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3428a36c61f9SKrishna Gudipati } 3429a36c61f9SKrishna Gudipati 3430a36c61f9SKrishna Gudipati static void 3431a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3432a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3433a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) 3434a36c61f9SKrishna Gudipati { 3435a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3436a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 3437a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 3438a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3439a36c61f9SKrishna Gudipati 3440a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3441a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3442a36c61f9SKrishna Gudipati 3443a36c61f9SKrishna Gudipati /* 3444a36c61f9SKrishna Gudipati * Sanity Checks 3445a36c61f9SKrishna Gudipati */ 3446a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3447a36c61f9SKrishna Gudipati port->stats.ms_plogi_rsp_err++; 3448a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3449a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3450a36c61f9SKrishna Gudipati return; 3451a36c61f9SKrishna Gudipati } 3452a36c61f9SKrishna Gudipati 3453a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3454a36c61f9SKrishna Gudipati 3455a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 3456a36c61f9SKrishna Gudipati 3457a36c61f9SKrishna Gudipati case FC_ELS_ACC: 3458a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 3459a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 3460a36c61f9SKrishna Gudipati port->stats.ms_plogi_acc_err++; 3461a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3462a36c61f9SKrishna Gudipati break; 3463a36c61f9SKrishna Gudipati } 3464a36c61f9SKrishna Gudipati port->stats.ms_plogi_accepts++; 3465a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3466a36c61f9SKrishna Gudipati break; 3467a36c61f9SKrishna Gudipati 3468a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 3469a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3470a36c61f9SKrishna Gudipati 3471a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 3472a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3473a36c61f9SKrishna Gudipati 3474a36c61f9SKrishna Gudipati port->stats.ms_rejects++; 3475a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3476a36c61f9SKrishna Gudipati break; 3477a36c61f9SKrishna Gudipati 3478a36c61f9SKrishna Gudipati default: 3479a36c61f9SKrishna Gudipati port->stats.ms_plogi_unknown_rsp++; 3480a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 3481a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3482a36c61f9SKrishna Gudipati } 3483a36c61f9SKrishna Gudipati } 3484a36c61f9SKrishna Gudipati 3485a36c61f9SKrishna Gudipati static void 3486a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg) 3487a36c61f9SKrishna Gudipati { 3488a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg; 3489a36c61f9SKrishna Gudipati 3490a36c61f9SKrishna Gudipati ms->port->stats.ms_timeouts++; 3491a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT); 3492a36c61f9SKrishna Gudipati } 3493a36c61f9SKrishna Gudipati 3494a36c61f9SKrishna Gudipati 3495a36c61f9SKrishna Gudipati void 3496a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port) 3497a36c61f9SKrishna Gudipati { 3498a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3499a36c61f9SKrishna Gudipati 3500a36c61f9SKrishna Gudipati ms->port = port; 3501a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3502a36c61f9SKrishna Gudipati 3503a36c61f9SKrishna Gudipati /* 3504a36c61f9SKrishna Gudipati * Invoke init routines of sub modules. 3505a36c61f9SKrishna Gudipati */ 3506a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(ms); 3507a36c61f9SKrishna Gudipati } 3508a36c61f9SKrishna Gudipati 3509a36c61f9SKrishna Gudipati void 3510a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port) 3511a36c61f9SKrishna Gudipati { 3512a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3513a36c61f9SKrishna Gudipati 3514a36c61f9SKrishna Gudipati ms->port = port; 3515a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); 3516a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(ms); 3517a36c61f9SKrishna Gudipati } 3518a36c61f9SKrishna Gudipati 3519a36c61f9SKrishna Gudipati void 3520a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port) 3521a36c61f9SKrishna Gudipati { 3522a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3523a36c61f9SKrishna Gudipati 3524a36c61f9SKrishna Gudipati ms->port = port; 3525a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE); 3526a36c61f9SKrishna Gudipati } 3527a36c61f9SKrishna Gudipati void 3528a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port) 3529a36c61f9SKrishna Gudipati { 3530a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3531a36c61f9SKrishna Gudipati 3532a36c61f9SKrishna Gudipati /* todo. Handle this only when in Online state */ 3533a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online)) 3534a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN); 3535a36c61f9SKrishna Gudipati } 3536a36c61f9SKrishna Gudipati 35375fbe25c7SJing Huang /* 3538a36c61f9SKrishna Gudipati * @page ns_sm_info VPORT NS State Machine 3539a36c61f9SKrishna Gudipati * 3540a36c61f9SKrishna Gudipati * @section ns_sm_interactions VPORT NS State Machine Interactions 3541a36c61f9SKrishna Gudipati * 3542a36c61f9SKrishna Gudipati * @section ns_sm VPORT NS State Machine 3543a36c61f9SKrishna Gudipati * img ns_sm.jpg 3544a36c61f9SKrishna Gudipati */ 3545a36c61f9SKrishna Gudipati 3546a36c61f9SKrishna Gudipati /* 3547a36c61f9SKrishna Gudipati * forward declarations 3548a36c61f9SKrishna Gudipati */ 3549a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, 3550a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3551a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, 3552a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3553a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, 3554a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3555a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, 3556a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3557a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, 3558a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3559ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, 3560ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3561ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, 3562ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3563a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_timeout(void *arg); 3564a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_plogi_response(void *fcsarg, 3565a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3566a36c61f9SKrishna Gudipati void *cbarg, 3567a36c61f9SKrishna Gudipati bfa_status_t req_status, 3568a36c61f9SKrishna Gudipati u32 rsp_len, 3569a36c61f9SKrishna Gudipati u32 resid_len, 3570a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3571a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, 3572a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3573a36c61f9SKrishna Gudipati void *cbarg, 3574a36c61f9SKrishna Gudipati bfa_status_t req_status, 3575a36c61f9SKrishna Gudipati u32 rsp_len, 3576a36c61f9SKrishna Gudipati u32 resid_len, 3577a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3578a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg, 3579a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3580a36c61f9SKrishna Gudipati void *cbarg, 3581a36c61f9SKrishna Gudipati bfa_status_t req_status, 3582a36c61f9SKrishna Gudipati u32 rsp_len, 3583a36c61f9SKrishna Gudipati u32 resid_len, 3584a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3585a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg, 3586a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3587a36c61f9SKrishna Gudipati void *cbarg, 3588a36c61f9SKrishna Gudipati bfa_status_t req_status, 3589a36c61f9SKrishna Gudipati u32 rsp_len, 3590a36c61f9SKrishna Gudipati u32 resid_len, 3591a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3592a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, 3593a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3594a36c61f9SKrishna Gudipati void *cbarg, 3595a36c61f9SKrishna Gudipati bfa_status_t req_status, 3596a36c61f9SKrishna Gudipati u32 rsp_len, 3597a36c61f9SKrishna Gudipati u32 resid_len, 3598a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3599ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, 3600ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3601ce7242b8SKrishna Gudipati void *cbarg, 3602ce7242b8SKrishna Gudipati bfa_status_t req_status, 3603ce7242b8SKrishna Gudipati u32 rsp_len, 3604ce7242b8SKrishna Gudipati u32 resid_len, 3605ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs); 3606ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, 3607ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3608ce7242b8SKrishna Gudipati void *cbarg, 3609ce7242b8SKrishna Gudipati bfa_status_t req_status, 3610ce7242b8SKrishna Gudipati u32 rsp_len, 3611ce7242b8SKrishna Gudipati u32 resid_len, 3612ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs); 3613a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_process_gidft_pids( 3614a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 3615a36c61f9SKrishna Gudipati u32 *pid_buf, u32 n_pids); 3616a36c61f9SKrishna Gudipati 3617a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port); 36185fbe25c7SJing Huang /* 3619a36c61f9SKrishna Gudipati * fcs_ns_sm FCS nameserver interface state machine 3620a36c61f9SKrishna Gudipati */ 3621a36c61f9SKrishna Gudipati 36225fbe25c7SJing Huang /* 3623a36c61f9SKrishna Gudipati * VPort NS State Machine events 3624a36c61f9SKrishna Gudipati */ 3625a36c61f9SKrishna Gudipati enum vport_ns_event { 3626a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_ONLINE = 1, 3627a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_OFFLINE = 2, 3628a36c61f9SKrishna Gudipati NSSM_EVENT_PLOGI_SENT = 3, 3629a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_OK = 4, 3630a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_ERROR = 5, 3631a36c61f9SKrishna Gudipati NSSM_EVENT_TIMEOUT = 6, 3632a36c61f9SKrishna Gudipati NSSM_EVENT_NS_QUERY = 7, 3633a36c61f9SKrishna Gudipati NSSM_EVENT_RSPNID_SENT = 8, 3634a36c61f9SKrishna Gudipati NSSM_EVENT_RFTID_SENT = 9, 3635a36c61f9SKrishna Gudipati NSSM_EVENT_RFFID_SENT = 10, 3636a36c61f9SKrishna Gudipati NSSM_EVENT_GIDFT_SENT = 11, 3637ce7242b8SKrishna Gudipati NSSM_EVENT_RNNID_SENT = 12, 3638ce7242b8SKrishna Gudipati NSSM_EVENT_RSNN_NN_SENT = 13, 3639a36c61f9SKrishna Gudipati }; 3640a36c61f9SKrishna Gudipati 3641a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3642a36c61f9SKrishna Gudipati enum vport_ns_event event); 3643a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3644a36c61f9SKrishna Gudipati enum vport_ns_event event); 3645a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3646a36c61f9SKrishna Gudipati enum vport_ns_event event); 3647a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3648a36c61f9SKrishna Gudipati enum vport_ns_event event); 3649a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rspn_id( 3650a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3651a36c61f9SKrishna Gudipati enum vport_ns_event event); 3652a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3653a36c61f9SKrishna Gudipati enum vport_ns_event event); 3654a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3655a36c61f9SKrishna Gudipati enum vport_ns_event event); 3656a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rft_id( 3657a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3658a36c61f9SKrishna Gudipati enum vport_ns_event event); 3659a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3660a36c61f9SKrishna Gudipati enum vport_ns_event event); 3661a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3662a36c61f9SKrishna Gudipati enum vport_ns_event event); 3663a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rff_id( 3664a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3665a36c61f9SKrishna Gudipati enum vport_ns_event event); 3666a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3667a36c61f9SKrishna Gudipati enum vport_ns_event event); 3668a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3669a36c61f9SKrishna Gudipati enum vport_ns_event event); 3670a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_gid_ft( 3671a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3672a36c61f9SKrishna Gudipati enum vport_ns_event event); 3673a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3674a36c61f9SKrishna Gudipati enum vport_ns_event event); 3675a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3676a36c61f9SKrishna Gudipati enum vport_ns_event event); 3677a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3678a36c61f9SKrishna Gudipati enum vport_ns_event event); 3679ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rnn_id( 3680ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3681ce7242b8SKrishna Gudipati enum vport_ns_event event); 3682ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns, 3683ce7242b8SKrishna Gudipati enum vport_ns_event event); 3684ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3685ce7242b8SKrishna Gudipati enum vport_ns_event event); 3686ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rsnn_nn( 3687ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3688ce7242b8SKrishna Gudipati enum vport_ns_event event); 3689ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns, 3690ce7242b8SKrishna Gudipati enum vport_ns_event event); 3691ce7242b8SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rsnn_nn_retry( 3692ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3693ce7242b8SKrishna Gudipati enum vport_ns_event event); 36945fbe25c7SJing Huang /* 3695a36c61f9SKrishna Gudipati * Start in offline state - awaiting linkup 3696a36c61f9SKrishna Gudipati */ 3697a36c61f9SKrishna Gudipati static void 3698a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3699a36c61f9SKrishna Gudipati enum vport_ns_event event) 3700a36c61f9SKrishna Gudipati { 3701a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3702a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3703a36c61f9SKrishna Gudipati 3704a36c61f9SKrishna Gudipati switch (event) { 3705a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_ONLINE: 3706a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3707a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3708a36c61f9SKrishna Gudipati break; 3709a36c61f9SKrishna Gudipati 3710a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3711a36c61f9SKrishna Gudipati break; 3712a36c61f9SKrishna Gudipati 3713a36c61f9SKrishna Gudipati default: 3714a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3715a36c61f9SKrishna Gudipati } 3716a36c61f9SKrishna Gudipati } 3717a36c61f9SKrishna Gudipati 3718a36c61f9SKrishna Gudipati static void 3719a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3720a36c61f9SKrishna Gudipati enum vport_ns_event event) 3721a36c61f9SKrishna Gudipati { 3722a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3723a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3724a36c61f9SKrishna Gudipati 3725a36c61f9SKrishna Gudipati switch (event) { 3726a36c61f9SKrishna Gudipati case NSSM_EVENT_PLOGI_SENT: 3727a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi); 3728a36c61f9SKrishna Gudipati break; 3729a36c61f9SKrishna Gudipati 3730a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3731a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3732a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3733a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3734a36c61f9SKrishna Gudipati break; 3735a36c61f9SKrishna Gudipati 3736a36c61f9SKrishna Gudipati default: 3737a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3738a36c61f9SKrishna Gudipati } 3739a36c61f9SKrishna Gudipati } 3740a36c61f9SKrishna Gudipati 3741a36c61f9SKrishna Gudipati static void 3742a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3743a36c61f9SKrishna Gudipati enum vport_ns_event event) 3744a36c61f9SKrishna Gudipati { 3745a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3746a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3747a36c61f9SKrishna Gudipati 3748a36c61f9SKrishna Gudipati switch (event) { 3749a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3750a36c61f9SKrishna Gudipati /* 3751a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3752a36c61f9SKrishna Gudipati */ 3753a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry); 3754a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3755a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3756a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3757a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3758a36c61f9SKrishna Gudipati break; 3759a36c61f9SKrishna Gudipati 3760a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3761ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id); 3762ce7242b8SKrishna Gudipati ns->num_rnnid_retries = 0; 3763ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id(ns, NULL); 3764a36c61f9SKrishna Gudipati break; 3765a36c61f9SKrishna Gudipati 3766a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3767a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3768a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3769a36c61f9SKrishna Gudipati break; 3770a36c61f9SKrishna Gudipati 3771a36c61f9SKrishna Gudipati default: 3772a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3773a36c61f9SKrishna Gudipati } 3774a36c61f9SKrishna Gudipati } 3775a36c61f9SKrishna Gudipati 3776a36c61f9SKrishna Gudipati static void 3777a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3778a36c61f9SKrishna Gudipati enum vport_ns_event event) 3779a36c61f9SKrishna Gudipati { 3780a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3781a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3782a36c61f9SKrishna Gudipati 3783a36c61f9SKrishna Gudipati switch (event) { 3784a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3785a36c61f9SKrishna Gudipati /* 3786a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3787a36c61f9SKrishna Gudipati */ 3788a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3789a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3790a36c61f9SKrishna Gudipati break; 3791a36c61f9SKrishna Gudipati 3792a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3793a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3794a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3795a36c61f9SKrishna Gudipati break; 3796a36c61f9SKrishna Gudipati 3797a36c61f9SKrishna Gudipati default: 3798a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3799a36c61f9SKrishna Gudipati } 3800a36c61f9SKrishna Gudipati } 3801a36c61f9SKrishna Gudipati 3802a36c61f9SKrishna Gudipati static void 3803ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rnn_id(struct bfa_fcs_lport_ns_s *ns, 3804ce7242b8SKrishna Gudipati enum vport_ns_event event) 3805ce7242b8SKrishna Gudipati { 3806ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3807ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3808ce7242b8SKrishna Gudipati 3809ce7242b8SKrishna Gudipati switch (event) { 3810ce7242b8SKrishna Gudipati case NSSM_EVENT_RNNID_SENT: 3811ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id); 3812ce7242b8SKrishna Gudipati break; 3813ce7242b8SKrishna Gudipati 3814ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3815ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3816ce7242b8SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3817ce7242b8SKrishna Gudipati &ns->fcxp_wqe); 3818ce7242b8SKrishna Gudipati break; 3819ce7242b8SKrishna Gudipati default: 3820ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3821ce7242b8SKrishna Gudipati } 3822ce7242b8SKrishna Gudipati } 3823ce7242b8SKrishna Gudipati 3824ce7242b8SKrishna Gudipati static void 3825ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns, 3826ce7242b8SKrishna Gudipati enum vport_ns_event event) 3827ce7242b8SKrishna Gudipati { 3828ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3829ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3830ce7242b8SKrishna Gudipati 3831ce7242b8SKrishna Gudipati switch (event) { 3832ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3833ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn); 3834ce7242b8SKrishna Gudipati ns->num_rnnid_retries = 0; 3835ce7242b8SKrishna Gudipati ns->num_rsnn_nn_retries = 0; 3836ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL); 3837ce7242b8SKrishna Gudipati break; 3838ce7242b8SKrishna Gudipati 3839ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3840ce7242b8SKrishna Gudipati if (ns->num_rnnid_retries < BFA_FCS_MAX_NS_RETRIES) { 3841ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id_retry); 3842ce7242b8SKrishna Gudipati ns->port->stats.ns_retries++; 3843ce7242b8SKrishna Gudipati ns->num_rnnid_retries++; 3844ce7242b8SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3845ce7242b8SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3846ce7242b8SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3847ce7242b8SKrishna Gudipati } else { 3848ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, 3849ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id); 3850ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3851ce7242b8SKrishna Gudipati } 3852ce7242b8SKrishna Gudipati break; 3853ce7242b8SKrishna Gudipati 3854ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3855ce7242b8SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3856ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3857ce7242b8SKrishna Gudipati break; 3858ce7242b8SKrishna Gudipati 3859ce7242b8SKrishna Gudipati default: 3860ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3861ce7242b8SKrishna Gudipati } 3862ce7242b8SKrishna Gudipati } 3863ce7242b8SKrishna Gudipati 3864ce7242b8SKrishna Gudipati static void 3865ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3866ce7242b8SKrishna Gudipati enum vport_ns_event event) 3867ce7242b8SKrishna Gudipati { 3868ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3869ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3870ce7242b8SKrishna Gudipati 3871ce7242b8SKrishna Gudipati switch (event) { 3872ce7242b8SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3873ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id); 3874ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id(ns, NULL); 3875ce7242b8SKrishna Gudipati break; 3876ce7242b8SKrishna Gudipati 3877ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3878ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3879ce7242b8SKrishna Gudipati bfa_timer_stop(&ns->timer); 3880ce7242b8SKrishna Gudipati break; 3881ce7242b8SKrishna Gudipati 3882ce7242b8SKrishna Gudipati default: 3883ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3884ce7242b8SKrishna Gudipati } 3885ce7242b8SKrishna Gudipati } 3886ce7242b8SKrishna Gudipati 3887ce7242b8SKrishna Gudipati static void 3888ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rsnn_nn(struct bfa_fcs_lport_ns_s *ns, 3889ce7242b8SKrishna Gudipati enum vport_ns_event event) 3890ce7242b8SKrishna Gudipati { 3891ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3892ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3893ce7242b8SKrishna Gudipati 3894ce7242b8SKrishna Gudipati switch (event) { 3895ce7242b8SKrishna Gudipati case NSSM_EVENT_RSNN_NN_SENT: 3896ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn); 3897ce7242b8SKrishna Gudipati break; 3898ce7242b8SKrishna Gudipati 3899ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3900ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3901ce7242b8SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3902ce7242b8SKrishna Gudipati &ns->fcxp_wqe); 3903ce7242b8SKrishna Gudipati break; 3904ce7242b8SKrishna Gudipati 3905ce7242b8SKrishna Gudipati default: 3906ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3907ce7242b8SKrishna Gudipati } 3908ce7242b8SKrishna Gudipati } 3909ce7242b8SKrishna Gudipati 3910ce7242b8SKrishna Gudipati static void 3911ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns, 3912ce7242b8SKrishna Gudipati enum vport_ns_event event) 3913ce7242b8SKrishna Gudipati { 3914ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3915ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3916ce7242b8SKrishna Gudipati 3917ce7242b8SKrishna Gudipati switch (event) { 3918ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3919ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3920ce7242b8SKrishna Gudipati ns->num_rsnn_nn_retries = 0; 3921ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3922ce7242b8SKrishna Gudipati break; 3923ce7242b8SKrishna Gudipati 3924ce7242b8SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3925ce7242b8SKrishna Gudipati if (ns->num_rsnn_nn_retries < BFA_FCS_MAX_NS_RETRIES) { 3926ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn_retry); 3927ce7242b8SKrishna Gudipati ns->port->stats.ns_retries++; 3928ce7242b8SKrishna Gudipati ns->num_rsnn_nn_retries++; 3929ce7242b8SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3930ce7242b8SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, 3931ce7242b8SKrishna Gudipati ns, BFA_FCS_RETRY_TIMEOUT); 3932ce7242b8SKrishna Gudipati } else { 3933ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, 3934ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id); 3935ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3936ce7242b8SKrishna Gudipati } 3937ce7242b8SKrishna Gudipati break; 3938ce7242b8SKrishna Gudipati 3939ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3940ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3941ce7242b8SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3942ce7242b8SKrishna Gudipati break; 3943ce7242b8SKrishna Gudipati 3944ce7242b8SKrishna Gudipati default: 3945ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3946ce7242b8SKrishna Gudipati } 3947ce7242b8SKrishna Gudipati } 3948ce7242b8SKrishna Gudipati 3949ce7242b8SKrishna Gudipati static void 3950ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rsnn_nn_retry(struct bfa_fcs_lport_ns_s *ns, 3951ce7242b8SKrishna Gudipati enum vport_ns_event event) 3952ce7242b8SKrishna Gudipati { 3953ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3954ce7242b8SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3955ce7242b8SKrishna Gudipati 3956ce7242b8SKrishna Gudipati switch (event) { 3957ce7242b8SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3958ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn); 3959ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL); 3960ce7242b8SKrishna Gudipati break; 3961ce7242b8SKrishna Gudipati 3962ce7242b8SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3963ce7242b8SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3964ce7242b8SKrishna Gudipati bfa_timer_stop(&ns->timer); 3965ce7242b8SKrishna Gudipati break; 3966ce7242b8SKrishna Gudipati 3967ce7242b8SKrishna Gudipati default: 3968ce7242b8SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3969ce7242b8SKrishna Gudipati } 3970ce7242b8SKrishna Gudipati } 3971ce7242b8SKrishna Gudipati 3972ce7242b8SKrishna Gudipati static void 3973a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3974a36c61f9SKrishna Gudipati enum vport_ns_event event) 3975a36c61f9SKrishna Gudipati { 3976a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3977a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3978a36c61f9SKrishna Gudipati 3979a36c61f9SKrishna Gudipati switch (event) { 3980a36c61f9SKrishna Gudipati case NSSM_EVENT_RSPNID_SENT: 3981a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id); 3982a36c61f9SKrishna Gudipati break; 3983a36c61f9SKrishna Gudipati 3984a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3985a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3986a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3987a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3988a36c61f9SKrishna Gudipati break; 3989a36c61f9SKrishna Gudipati 3990a36c61f9SKrishna Gudipati default: 3991a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3992a36c61f9SKrishna Gudipati } 3993a36c61f9SKrishna Gudipati } 3994a36c61f9SKrishna Gudipati 3995a36c61f9SKrishna Gudipati static void 3996a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3997a36c61f9SKrishna Gudipati enum vport_ns_event event) 3998a36c61f9SKrishna Gudipati { 3999a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4000a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4001a36c61f9SKrishna Gudipati 4002a36c61f9SKrishna Gudipati switch (event) { 4003a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4004a36c61f9SKrishna Gudipati /* 4005a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4006a36c61f9SKrishna Gudipati */ 4007a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry); 4008a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4009a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4010a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4011a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4012a36c61f9SKrishna Gudipati break; 4013a36c61f9SKrishna Gudipati 4014a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4015a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 4016a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 4017a36c61f9SKrishna Gudipati break; 4018a36c61f9SKrishna Gudipati 4019a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4020a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4021a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4022a36c61f9SKrishna Gudipati break; 4023a36c61f9SKrishna Gudipati 4024a36c61f9SKrishna Gudipati default: 4025a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4026a36c61f9SKrishna Gudipati } 4027a36c61f9SKrishna Gudipati } 4028a36c61f9SKrishna Gudipati 4029a36c61f9SKrishna Gudipati static void 4030a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 4031a36c61f9SKrishna Gudipati enum vport_ns_event event) 4032a36c61f9SKrishna Gudipati { 4033a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4034a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4035a36c61f9SKrishna Gudipati 4036a36c61f9SKrishna Gudipati switch (event) { 4037a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4038a36c61f9SKrishna Gudipati /* 4039a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 4040a36c61f9SKrishna Gudipati */ 4041a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 4042a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 4043a36c61f9SKrishna Gudipati break; 4044a36c61f9SKrishna Gudipati 4045a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4046a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4047a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4048a36c61f9SKrishna Gudipati break; 4049a36c61f9SKrishna Gudipati 4050a36c61f9SKrishna Gudipati default: 4051a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4052a36c61f9SKrishna Gudipati } 4053a36c61f9SKrishna Gudipati } 4054a36c61f9SKrishna Gudipati 4055a36c61f9SKrishna Gudipati static void 4056a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns, 4057a36c61f9SKrishna Gudipati enum vport_ns_event event) 4058a36c61f9SKrishna Gudipati { 4059a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4060a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4061a36c61f9SKrishna Gudipati 4062a36c61f9SKrishna Gudipati switch (event) { 4063a36c61f9SKrishna Gudipati case NSSM_EVENT_RFTID_SENT: 4064a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id); 4065a36c61f9SKrishna Gudipati break; 4066a36c61f9SKrishna Gudipati 4067a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4068a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4069a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4070a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 4071a36c61f9SKrishna Gudipati break; 4072a36c61f9SKrishna Gudipati 4073a36c61f9SKrishna Gudipati default: 4074a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4075a36c61f9SKrishna Gudipati } 4076a36c61f9SKrishna Gudipati } 4077a36c61f9SKrishna Gudipati 4078a36c61f9SKrishna Gudipati static void 4079a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 4080a36c61f9SKrishna Gudipati enum vport_ns_event event) 4081a36c61f9SKrishna Gudipati { 4082a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4083a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4084a36c61f9SKrishna Gudipati 4085a36c61f9SKrishna Gudipati switch (event) { 4086a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4087a36c61f9SKrishna Gudipati /* Now move to register FC4 Features */ 4088a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 4089a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 4090a36c61f9SKrishna Gudipati break; 4091a36c61f9SKrishna Gudipati 4092a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4093a36c61f9SKrishna Gudipati /* 4094a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4095a36c61f9SKrishna Gudipati */ 4096a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry); 4097a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4098a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4099a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4100a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4101a36c61f9SKrishna Gudipati break; 4102a36c61f9SKrishna Gudipati 4103a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4104a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4105a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4106a36c61f9SKrishna Gudipati break; 4107a36c61f9SKrishna Gudipati 4108a36c61f9SKrishna Gudipati default: 4109a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4110a36c61f9SKrishna Gudipati } 4111a36c61f9SKrishna Gudipati } 4112a36c61f9SKrishna Gudipati 4113a36c61f9SKrishna Gudipati static void 4114a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 4115a36c61f9SKrishna Gudipati enum vport_ns_event event) 4116a36c61f9SKrishna Gudipati { 4117a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4118a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4119a36c61f9SKrishna Gudipati 4120a36c61f9SKrishna Gudipati switch (event) { 4121a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4122a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 4123a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 4124a36c61f9SKrishna Gudipati break; 4125a36c61f9SKrishna Gudipati 4126a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4127a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4128a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4129a36c61f9SKrishna Gudipati break; 4130a36c61f9SKrishna Gudipati 4131a36c61f9SKrishna Gudipati default: 4132a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4133a36c61f9SKrishna Gudipati } 4134a36c61f9SKrishna Gudipati } 4135a36c61f9SKrishna Gudipati 4136a36c61f9SKrishna Gudipati static void 4137a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns, 4138a36c61f9SKrishna Gudipati enum vport_ns_event event) 4139a36c61f9SKrishna Gudipati { 4140a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4141a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4142a36c61f9SKrishna Gudipati 4143a36c61f9SKrishna Gudipati switch (event) { 4144a36c61f9SKrishna Gudipati case NSSM_EVENT_RFFID_SENT: 4145a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id); 4146a36c61f9SKrishna Gudipati break; 4147a36c61f9SKrishna Gudipati 4148a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4149a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4150a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4151a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 4152a36c61f9SKrishna Gudipati break; 4153a36c61f9SKrishna Gudipati 4154a36c61f9SKrishna Gudipati default: 4155a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4156a36c61f9SKrishna Gudipati } 4157a36c61f9SKrishna Gudipati } 4158a36c61f9SKrishna Gudipati 4159a36c61f9SKrishna Gudipati static void 4160a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 4161a36c61f9SKrishna Gudipati enum vport_ns_event event) 4162a36c61f9SKrishna Gudipati { 4163a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4164a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4165a36c61f9SKrishna Gudipati 4166a36c61f9SKrishna Gudipati switch (event) { 4167a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4168a36c61f9SKrishna Gudipati 4169a36c61f9SKrishna Gudipati /* 4170a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot initiate rport 4171a36c61f9SKrishna Gudipati * discovery with the fabric. Instead, we will retrieve the 4172a36c61f9SKrishna Gudipati * boot targets from HAL/FW. 4173a36c61f9SKrishna Gudipati */ 4174a36c61f9SKrishna Gudipati if (__fcs_min_cfg(ns->port->fcs)) { 4175a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(ns->port); 4176a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 4177a36c61f9SKrishna Gudipati return; 4178a36c61f9SKrishna Gudipati } 4179a36c61f9SKrishna Gudipati 4180a36c61f9SKrishna Gudipati /* 4181a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 4182a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 4183a36c61f9SKrishna Gudipati */ 4184a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 4185a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 4186a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 4187a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 4188a36c61f9SKrishna Gudipati } 4189a36c61f9SKrishna Gudipati /* 4190a36c61f9SKrishna Gudipati * kick off mgmt srvr state machine 4191a36c61f9SKrishna Gudipati */ 4192a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(ns->port); 4193a36c61f9SKrishna Gudipati break; 4194a36c61f9SKrishna Gudipati 4195a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4196a36c61f9SKrishna Gudipati /* 4197a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4198a36c61f9SKrishna Gudipati */ 4199a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry); 4200a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4201a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4202a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4203a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4204a36c61f9SKrishna Gudipati break; 4205a36c61f9SKrishna Gudipati 4206a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4207a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4208a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4209a36c61f9SKrishna Gudipati break; 4210a36c61f9SKrishna Gudipati 4211a36c61f9SKrishna Gudipati default: 4212a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4213a36c61f9SKrishna Gudipati } 4214a36c61f9SKrishna Gudipati } 4215a36c61f9SKrishna Gudipati 4216a36c61f9SKrishna Gudipati static void 4217a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 4218a36c61f9SKrishna Gudipati enum vport_ns_event event) 4219a36c61f9SKrishna Gudipati { 4220a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4221a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4222a36c61f9SKrishna Gudipati 4223a36c61f9SKrishna Gudipati switch (event) { 4224a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4225a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 4226a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 4227a36c61f9SKrishna Gudipati break; 4228a36c61f9SKrishna Gudipati 4229a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4230a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4231a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4232a36c61f9SKrishna Gudipati break; 4233a36c61f9SKrishna Gudipati 4234a36c61f9SKrishna Gudipati default: 4235a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4236a36c61f9SKrishna Gudipati } 4237a36c61f9SKrishna Gudipati } 4238a36c61f9SKrishna Gudipati static void 4239a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns, 4240a36c61f9SKrishna Gudipati enum vport_ns_event event) 4241a36c61f9SKrishna Gudipati { 4242a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4243a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4244a36c61f9SKrishna Gudipati 4245a36c61f9SKrishna Gudipati switch (event) { 4246a36c61f9SKrishna Gudipati case NSSM_EVENT_GIDFT_SENT: 4247a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft); 4248a36c61f9SKrishna Gudipati break; 4249a36c61f9SKrishna Gudipati 4250a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4251a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4252a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4253a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 4254a36c61f9SKrishna Gudipati break; 4255a36c61f9SKrishna Gudipati 4256a36c61f9SKrishna Gudipati default: 4257a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4258a36c61f9SKrishna Gudipati } 4259a36c61f9SKrishna Gudipati } 4260a36c61f9SKrishna Gudipati 4261a36c61f9SKrishna Gudipati static void 4262a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 4263a36c61f9SKrishna Gudipati enum vport_ns_event event) 4264a36c61f9SKrishna Gudipati { 4265a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4266a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4267a36c61f9SKrishna Gudipati 4268a36c61f9SKrishna Gudipati switch (event) { 4269a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 4270a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 4271a36c61f9SKrishna Gudipati break; 4272a36c61f9SKrishna Gudipati 4273a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 4274a36c61f9SKrishna Gudipati /* 4275a36c61f9SKrishna Gudipati * TBD: for certain reject codes, we don't need to retry 4276a36c61f9SKrishna Gudipati */ 4277a36c61f9SKrishna Gudipati /* 4278a36c61f9SKrishna Gudipati * Start timer for a delayed retry 4279a36c61f9SKrishna Gudipati */ 4280a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry); 4281a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 4282a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 4283a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 4284a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4285a36c61f9SKrishna Gudipati break; 4286a36c61f9SKrishna Gudipati 4287a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4288a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4289a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 4290a36c61f9SKrishna Gudipati break; 4291a36c61f9SKrishna Gudipati 4292a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 4293a36c61f9SKrishna Gudipati break; 4294a36c61f9SKrishna Gudipati 4295a36c61f9SKrishna Gudipati default: 4296a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4297a36c61f9SKrishna Gudipati } 4298a36c61f9SKrishna Gudipati } 4299a36c61f9SKrishna Gudipati 4300a36c61f9SKrishna Gudipati static void 4301a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 4302a36c61f9SKrishna Gudipati enum vport_ns_event event) 4303a36c61f9SKrishna Gudipati { 4304a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4305a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4306a36c61f9SKrishna Gudipati 4307a36c61f9SKrishna Gudipati switch (event) { 4308a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 4309a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft); 4310a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 4311a36c61f9SKrishna Gudipati break; 4312a36c61f9SKrishna Gudipati 4313a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4314a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4315a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 4316a36c61f9SKrishna Gudipati break; 4317a36c61f9SKrishna Gudipati 4318a36c61f9SKrishna Gudipati default: 4319a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4320a36c61f9SKrishna Gudipati } 4321a36c61f9SKrishna Gudipati } 4322a36c61f9SKrishna Gudipati 4323a36c61f9SKrishna Gudipati static void 4324a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 4325a36c61f9SKrishna Gudipati enum vport_ns_event event) 4326a36c61f9SKrishna Gudipati { 4327a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 4328a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 4329a36c61f9SKrishna Gudipati 4330a36c61f9SKrishna Gudipati switch (event) { 4331a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 4332a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4333a36c61f9SKrishna Gudipati break; 4334a36c61f9SKrishna Gudipati 4335a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 4336a36c61f9SKrishna Gudipati /* 4337a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 4338a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 4339a36c61f9SKrishna Gudipati */ 4340a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 4341a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 4342a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 4343a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 4344a36c61f9SKrishna Gudipati }; 4345a36c61f9SKrishna Gudipati break; 4346a36c61f9SKrishna Gudipati 4347a36c61f9SKrishna Gudipati default: 4348a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 4349a36c61f9SKrishna Gudipati } 4350a36c61f9SKrishna Gudipati } 4351a36c61f9SKrishna Gudipati 4352a36c61f9SKrishna Gudipati 4353a36c61f9SKrishna Gudipati 43545fbe25c7SJing Huang /* 4355a36c61f9SKrishna Gudipati * ns_pvt Nameserver local functions 4356a36c61f9SKrishna Gudipati */ 4357a36c61f9SKrishna Gudipati 4358a36c61f9SKrishna Gudipati static void 4359a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4360a36c61f9SKrishna Gudipati { 4361a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4362a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4363a36c61f9SKrishna Gudipati struct fchs_s fchs; 4364a36c61f9SKrishna Gudipati int len; 4365a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4366a36c61f9SKrishna Gudipati 4367a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4368a36c61f9SKrishna Gudipati 4369c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4370c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4371a36c61f9SKrishna Gudipati if (!fcxp) { 4372a36c61f9SKrishna Gudipati port->stats.ns_plogi_alloc_wait++; 4373a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4374c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE); 4375a36c61f9SKrishna Gudipati return; 4376a36c61f9SKrishna Gudipati } 4377a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4378a36c61f9SKrishna Gudipati 4379a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4380f16a1750SMaggie Zhang bfa_hton3b(FC_NAME_SERVER), 4381a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 4382a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 4383be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 4384be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 4385a36c61f9SKrishna Gudipati 4386a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4387a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4388a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response, (void *)ns, 4389a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 4390a36c61f9SKrishna Gudipati port->stats.ns_plogi_sent++; 4391a36c61f9SKrishna Gudipati 4392a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); 4393a36c61f9SKrishna Gudipati } 4394a36c61f9SKrishna Gudipati 4395a36c61f9SKrishna Gudipati static void 4396a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4397a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 4398a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 4399a36c61f9SKrishna Gudipati { 4400a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4401a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4402a36c61f9SKrishna Gudipati /* struct fc_logi_s *plogi_resp; */ 4403a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 4404a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 4405a36c61f9SKrishna Gudipati 4406a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4407a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4408a36c61f9SKrishna Gudipati 4409a36c61f9SKrishna Gudipati /* 4410a36c61f9SKrishna Gudipati * Sanity Checks 4411a36c61f9SKrishna Gudipati */ 4412a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4413a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4414a36c61f9SKrishna Gudipati port->stats.ns_plogi_rsp_err++; 4415a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4416a36c61f9SKrishna Gudipati return; 4417a36c61f9SKrishna Gudipati } 4418a36c61f9SKrishna Gudipati 4419a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 4420a36c61f9SKrishna Gudipati 4421a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 4422a36c61f9SKrishna Gudipati 4423a36c61f9SKrishna Gudipati case FC_ELS_ACC: 4424a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 4425a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 4426a36c61f9SKrishna Gudipati port->stats.ns_plogi_acc_err++; 4427a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4428a36c61f9SKrishna Gudipati break; 4429a36c61f9SKrishna Gudipati } 4430a36c61f9SKrishna Gudipati port->stats.ns_plogi_accepts++; 4431a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4432a36c61f9SKrishna Gudipati break; 4433a36c61f9SKrishna Gudipati 4434a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 4435a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 4436a36c61f9SKrishna Gudipati 4437a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 4438a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 4439a36c61f9SKrishna Gudipati 4440a36c61f9SKrishna Gudipati port->stats.ns_rejects++; 4441a36c61f9SKrishna Gudipati 4442a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4443a36c61f9SKrishna Gudipati break; 4444a36c61f9SKrishna Gudipati 4445a36c61f9SKrishna Gudipati default: 4446a36c61f9SKrishna Gudipati port->stats.ns_plogi_unknown_rsp++; 4447a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 4448a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4449a36c61f9SKrishna Gudipati } 4450a36c61f9SKrishna Gudipati } 4451a36c61f9SKrishna Gudipati 44525fbe25c7SJing Huang /* 4453ce7242b8SKrishna Gudipati * Register node name for port_id 4454ce7242b8SKrishna Gudipati */ 4455ce7242b8SKrishna Gudipati static void 4456ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4457ce7242b8SKrishna Gudipati { 4458ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4459ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4460ce7242b8SKrishna Gudipati struct fchs_s fchs; 4461ce7242b8SKrishna Gudipati int len; 4462ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4463ce7242b8SKrishna Gudipati 4464ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4465ce7242b8SKrishna Gudipati 4466ce7242b8SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4467ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4468ce7242b8SKrishna Gudipati if (!fcxp) { 4469ce7242b8SKrishna Gudipati port->stats.ns_rnnid_alloc_wait++; 4470ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4471ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id, ns, BFA_TRUE); 4472ce7242b8SKrishna Gudipati return; 4473ce7242b8SKrishna Gudipati } 4474ce7242b8SKrishna Gudipati 4475ce7242b8SKrishna Gudipati ns->fcxp = fcxp; 4476ce7242b8SKrishna Gudipati 4477ce7242b8SKrishna Gudipati len = fc_rnnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4478ce7242b8SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 4479ce7242b8SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 4480ce7242b8SKrishna Gudipati bfa_fcs_lport_get_nwwn(port)); 4481ce7242b8SKrishna Gudipati 4482ce7242b8SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4483ce7242b8SKrishna Gudipati FC_CLASS_3, len, &fchs, 4484ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rnn_id_response, (void *)ns, 4485ce7242b8SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4486ce7242b8SKrishna Gudipati 4487ce7242b8SKrishna Gudipati port->stats.ns_rnnid_sent++; 4488ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RNNID_SENT); 4489ce7242b8SKrishna Gudipati } 4490ce7242b8SKrishna Gudipati 4491ce7242b8SKrishna Gudipati static void 4492ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4493ce7242b8SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4494ce7242b8SKrishna Gudipati u32 rsp_len, u32 resid_len, 4495ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs) 4496ce7242b8SKrishna Gudipati 4497ce7242b8SKrishna Gudipati { 4498ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4499ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4500ce7242b8SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4501ce7242b8SKrishna Gudipati 4502ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4503ce7242b8SKrishna Gudipati 4504ce7242b8SKrishna Gudipati /* 4505ce7242b8SKrishna Gudipati * Sanity Checks 4506ce7242b8SKrishna Gudipati */ 4507ce7242b8SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4508ce7242b8SKrishna Gudipati bfa_trc(port->fcs, req_status); 4509ce7242b8SKrishna Gudipati port->stats.ns_rnnid_rsp_err++; 4510ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4511ce7242b8SKrishna Gudipati return; 4512ce7242b8SKrishna Gudipati } 4513ce7242b8SKrishna Gudipati 4514ce7242b8SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4515ce7242b8SKrishna Gudipati cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4516ce7242b8SKrishna Gudipati 4517ce7242b8SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4518ce7242b8SKrishna Gudipati port->stats.ns_rnnid_accepts++; 4519ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4520ce7242b8SKrishna Gudipati return; 4521ce7242b8SKrishna Gudipati } 4522ce7242b8SKrishna Gudipati 4523ce7242b8SKrishna Gudipati port->stats.ns_rnnid_rejects++; 4524ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4525ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4526ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4527ce7242b8SKrishna Gudipati } 4528ce7242b8SKrishna Gudipati 4529ce7242b8SKrishna Gudipati /* 4530ce7242b8SKrishna Gudipati * Register the symbolic node name for a given node name. 4531ce7242b8SKrishna Gudipati */ 4532ce7242b8SKrishna Gudipati static void 4533ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4534ce7242b8SKrishna Gudipati { 4535ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4536ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4537ce7242b8SKrishna Gudipati struct fchs_s fchs; 4538ce7242b8SKrishna Gudipati int len; 4539ce7242b8SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4540ce7242b8SKrishna Gudipati u8 *nsymbl; 4541ce7242b8SKrishna Gudipati 4542ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4543ce7242b8SKrishna Gudipati 4544ce7242b8SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4545ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4546ce7242b8SKrishna Gudipati if (!fcxp) { 4547ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_alloc_wait++; 4548ce7242b8SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4549ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn, ns, BFA_TRUE); 4550ce7242b8SKrishna Gudipati return; 4551ce7242b8SKrishna Gudipati } 4552ce7242b8SKrishna Gudipati ns->fcxp = fcxp; 4553ce7242b8SKrishna Gudipati 4554ce7242b8SKrishna Gudipati nsymbl = (u8 *) &(bfa_fcs_lport_get_nsym_name( 4555ce7242b8SKrishna Gudipati bfa_fcs_get_base_port(port->fcs))); 4556ce7242b8SKrishna Gudipati 4557ce7242b8SKrishna Gudipati len = fc_rsnn_nn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4558ce7242b8SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 4559ce7242b8SKrishna Gudipati bfa_fcs_lport_get_nwwn(port), nsymbl); 4560ce7242b8SKrishna Gudipati 4561ce7242b8SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4562ce7242b8SKrishna Gudipati FC_CLASS_3, len, &fchs, 4563ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rsnn_nn_response, (void *)ns, 4564ce7242b8SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4565ce7242b8SKrishna Gudipati 4566ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_sent++; 4567ce7242b8SKrishna Gudipati 4568ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSNN_NN_SENT); 4569ce7242b8SKrishna Gudipati } 4570ce7242b8SKrishna Gudipati 4571ce7242b8SKrishna Gudipati static void 4572ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4573ce7242b8SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4574ce7242b8SKrishna Gudipati u32 rsp_len, u32 resid_len, 4575ce7242b8SKrishna Gudipati struct fchs_s *rsp_fchs) 4576ce7242b8SKrishna Gudipati { 4577ce7242b8SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4578ce7242b8SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4579ce7242b8SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4580ce7242b8SKrishna Gudipati 4581ce7242b8SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4582ce7242b8SKrishna Gudipati 4583ce7242b8SKrishna Gudipati /* 4584ce7242b8SKrishna Gudipati * Sanity Checks 4585ce7242b8SKrishna Gudipati */ 4586ce7242b8SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4587ce7242b8SKrishna Gudipati bfa_trc(port->fcs, req_status); 4588ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_rsp_err++; 4589ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4590ce7242b8SKrishna Gudipati return; 4591ce7242b8SKrishna Gudipati } 4592ce7242b8SKrishna Gudipati 4593ce7242b8SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4594ce7242b8SKrishna Gudipati cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4595ce7242b8SKrishna Gudipati 4596ce7242b8SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4597ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_accepts++; 4598ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4599ce7242b8SKrishna Gudipati return; 4600ce7242b8SKrishna Gudipati } 4601ce7242b8SKrishna Gudipati 4602ce7242b8SKrishna Gudipati port->stats.ns_rsnn_nn_rejects++; 4603ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4604ce7242b8SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4605ce7242b8SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4606ce7242b8SKrishna Gudipati } 4607ce7242b8SKrishna Gudipati 4608ce7242b8SKrishna Gudipati /* 4609a36c61f9SKrishna Gudipati * Register the symbolic port name. 4610a36c61f9SKrishna Gudipati */ 4611a36c61f9SKrishna Gudipati static void 4612a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4613a36c61f9SKrishna Gudipati { 4614a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4615a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4616a36c61f9SKrishna Gudipati struct fchs_s fchs; 4617a36c61f9SKrishna Gudipati int len; 4618a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4619a36c61f9SKrishna Gudipati u8 symbl[256]; 4620a36c61f9SKrishna Gudipati u8 *psymbl = &symbl[0]; 4621a36c61f9SKrishna Gudipati 46226a18b167SJing Huang memset(symbl, 0, sizeof(symbl)); 4623a36c61f9SKrishna Gudipati 4624a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4625a36c61f9SKrishna Gudipati 4626c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4627c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4628a36c61f9SKrishna Gudipati if (!fcxp) { 4629a36c61f9SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 4630a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4631c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE); 4632a36c61f9SKrishna Gudipati return; 4633a36c61f9SKrishna Gudipati } 4634a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4635a36c61f9SKrishna Gudipati 4636a36c61f9SKrishna Gudipati /* 4637a36c61f9SKrishna Gudipati * for V-Port, form a Port Symbolic Name 4638a36c61f9SKrishna Gudipati */ 4639a36c61f9SKrishna Gudipati if (port->vport) { 46405fbe25c7SJing Huang /* 4641a36c61f9SKrishna Gudipati * For Vports, we append the vport's port symbolic name 4642a36c61f9SKrishna Gudipati * to that of the base port. 4643a36c61f9SKrishna Gudipati */ 4644a36c61f9SKrishna Gudipati 4645a36c61f9SKrishna Gudipati strncpy((char *)psymbl, 4646a36c61f9SKrishna Gudipati (char *) & 4647a36c61f9SKrishna Gudipati (bfa_fcs_lport_get_psym_name 4648a36c61f9SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 4649a36c61f9SKrishna Gudipati strlen((char *) & 4650a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 4651a36c61f9SKrishna Gudipati (port->fcs)))); 4652a36c61f9SKrishna Gudipati 4653a36c61f9SKrishna Gudipati /* Ensure we have a null terminating string. */ 4654a36c61f9SKrishna Gudipati ((char *)psymbl)[strlen((char *) & 4655a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 4656a36c61f9SKrishna Gudipati (port->fcs)))] = 0; 4657a36c61f9SKrishna Gudipati strncat((char *)psymbl, 4658a36c61f9SKrishna Gudipati (char *) &(bfa_fcs_lport_get_psym_name(port)), 4659a36c61f9SKrishna Gudipati strlen((char *) &bfa_fcs_lport_get_psym_name(port))); 4660a36c61f9SKrishna Gudipati } else { 4661a36c61f9SKrishna Gudipati psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); 4662a36c61f9SKrishna Gudipati } 4663a36c61f9SKrishna Gudipati 4664a36c61f9SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4665a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, psymbl); 4666a36c61f9SKrishna Gudipati 4667a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4668a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4669a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response, (void *)ns, 4670a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4671a36c61f9SKrishna Gudipati 4672a36c61f9SKrishna Gudipati port->stats.ns_rspnid_sent++; 4673a36c61f9SKrishna Gudipati 4674a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); 4675a36c61f9SKrishna Gudipati } 4676a36c61f9SKrishna Gudipati 4677a36c61f9SKrishna Gudipati static void 4678a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4679a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4680a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4681a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4682a36c61f9SKrishna Gudipati { 4683a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4684a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4685a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4686a36c61f9SKrishna Gudipati 4687a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4688a36c61f9SKrishna Gudipati 4689a36c61f9SKrishna Gudipati /* 4690a36c61f9SKrishna Gudipati * Sanity Checks 4691a36c61f9SKrishna Gudipati */ 4692a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4693a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4694a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rsp_err++; 4695a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4696a36c61f9SKrishna Gudipati return; 4697a36c61f9SKrishna Gudipati } 4698a36c61f9SKrishna Gudipati 4699a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4700ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4701a36c61f9SKrishna Gudipati 4702a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4703a36c61f9SKrishna Gudipati port->stats.ns_rspnid_accepts++; 4704a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4705a36c61f9SKrishna Gudipati return; 4706a36c61f9SKrishna Gudipati } 4707a36c61f9SKrishna Gudipati 4708a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rejects++; 4709a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4710a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4711a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4712a36c61f9SKrishna Gudipati } 4713a36c61f9SKrishna Gudipati 47145fbe25c7SJing Huang /* 4715a36c61f9SKrishna Gudipati * Register FC4-Types 4716a36c61f9SKrishna Gudipati */ 4717a36c61f9SKrishna Gudipati static void 4718a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4719a36c61f9SKrishna Gudipati { 4720a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4721a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4722a36c61f9SKrishna Gudipati struct fchs_s fchs; 4723a36c61f9SKrishna Gudipati int len; 4724a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4725a36c61f9SKrishna Gudipati 4726a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4727a36c61f9SKrishna Gudipati 4728c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4729c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4730a36c61f9SKrishna Gudipati if (!fcxp) { 4731a36c61f9SKrishna Gudipati port->stats.ns_rftid_alloc_wait++; 4732a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4733c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE); 4734a36c61f9SKrishna Gudipati return; 4735a36c61f9SKrishna Gudipati } 4736a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4737a36c61f9SKrishna Gudipati 4738a36c61f9SKrishna Gudipati len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4739a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles); 4740a36c61f9SKrishna Gudipati 4741a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4742a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4743a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response, (void *)ns, 4744a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4745a36c61f9SKrishna Gudipati 4746a36c61f9SKrishna Gudipati port->stats.ns_rftid_sent++; 4747a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); 4748a36c61f9SKrishna Gudipati } 4749a36c61f9SKrishna Gudipati 4750a36c61f9SKrishna Gudipati static void 4751a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4752a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4753a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4754a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4755a36c61f9SKrishna Gudipati { 4756a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4757a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4758a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4759a36c61f9SKrishna Gudipati 4760a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4761a36c61f9SKrishna Gudipati 4762a36c61f9SKrishna Gudipati /* 4763a36c61f9SKrishna Gudipati * Sanity Checks 4764a36c61f9SKrishna Gudipati */ 4765a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4766a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4767a36c61f9SKrishna Gudipati port->stats.ns_rftid_rsp_err++; 4768a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4769a36c61f9SKrishna Gudipati return; 4770a36c61f9SKrishna Gudipati } 4771a36c61f9SKrishna Gudipati 4772a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4773ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4774a36c61f9SKrishna Gudipati 4775a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4776a36c61f9SKrishna Gudipati port->stats.ns_rftid_accepts++; 4777a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4778a36c61f9SKrishna Gudipati return; 4779a36c61f9SKrishna Gudipati } 4780a36c61f9SKrishna Gudipati 4781a36c61f9SKrishna Gudipati port->stats.ns_rftid_rejects++; 4782a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4783a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4784a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4785a36c61f9SKrishna Gudipati } 4786a36c61f9SKrishna Gudipati 47875fbe25c7SJing Huang /* 4788a36c61f9SKrishna Gudipati * Register FC4-Features : Should be done after RFT_ID 4789a36c61f9SKrishna Gudipati */ 4790a36c61f9SKrishna Gudipati static void 4791a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4792a36c61f9SKrishna Gudipati { 4793a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4794a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4795a36c61f9SKrishna Gudipati struct fchs_s fchs; 4796a36c61f9SKrishna Gudipati int len; 4797a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4798a36c61f9SKrishna Gudipati u8 fc4_ftrs = 0; 4799a36c61f9SKrishna Gudipati 4800a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4801a36c61f9SKrishna Gudipati 4802c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4803c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4804a36c61f9SKrishna Gudipati if (!fcxp) { 4805a36c61f9SKrishna Gudipati port->stats.ns_rffid_alloc_wait++; 4806a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4807c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE); 4808a36c61f9SKrishna Gudipati return; 4809a36c61f9SKrishna Gudipati } 4810a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4811a36c61f9SKrishna Gudipati 4812a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) 4813a36c61f9SKrishna Gudipati fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; 4814a36c61f9SKrishna Gudipati 4815a36c61f9SKrishna Gudipati len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4816a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 4817a36c61f9SKrishna Gudipati FC_TYPE_FCP, fc4_ftrs); 4818a36c61f9SKrishna Gudipati 4819a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4820a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4821a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response, (void *)ns, 4822a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 4823a36c61f9SKrishna Gudipati 4824a36c61f9SKrishna Gudipati port->stats.ns_rffid_sent++; 4825a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); 4826a36c61f9SKrishna Gudipati } 4827a36c61f9SKrishna Gudipati 4828a36c61f9SKrishna Gudipati static void 4829a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4830a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4831a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4832a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4833a36c61f9SKrishna Gudipati { 4834a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4835a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4836a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4837a36c61f9SKrishna Gudipati 4838a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4839a36c61f9SKrishna Gudipati 4840a36c61f9SKrishna Gudipati /* 4841a36c61f9SKrishna Gudipati * Sanity Checks 4842a36c61f9SKrishna Gudipati */ 4843a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4844a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4845a36c61f9SKrishna Gudipati port->stats.ns_rffid_rsp_err++; 4846a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4847a36c61f9SKrishna Gudipati return; 4848a36c61f9SKrishna Gudipati } 4849a36c61f9SKrishna Gudipati 4850a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4851ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4852a36c61f9SKrishna Gudipati 4853a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4854a36c61f9SKrishna Gudipati port->stats.ns_rffid_accepts++; 4855a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4856a36c61f9SKrishna Gudipati return; 4857a36c61f9SKrishna Gudipati } 4858a36c61f9SKrishna Gudipati 4859a36c61f9SKrishna Gudipati port->stats.ns_rffid_rejects++; 4860a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4861a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4862a36c61f9SKrishna Gudipati 4863a36c61f9SKrishna Gudipati if (cthdr->reason_code == CT_RSN_NOT_SUPP) { 4864a36c61f9SKrishna Gudipati /* if this command is not supported, we don't retry */ 4865a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4866a36c61f9SKrishna Gudipati } else 4867a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4868a36c61f9SKrishna Gudipati } 48695fbe25c7SJing Huang /* 4870a36c61f9SKrishna Gudipati * Query Fabric for FC4-Types Devices. 4871a36c61f9SKrishna Gudipati * 4872a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response 4873a36c61f9SKrishna Gudipati * can be larger than 2K. 4874a36c61f9SKrishna Gudipati */ 4875a36c61f9SKrishna Gudipati static void 4876a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4877a36c61f9SKrishna Gudipati { 4878a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4879a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4880a36c61f9SKrishna Gudipati struct fchs_s fchs; 4881a36c61f9SKrishna Gudipati int len; 4882a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4883a36c61f9SKrishna Gudipati 4884a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4885a36c61f9SKrishna Gudipati 4886c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 4887c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 4888a36c61f9SKrishna Gudipati if (!fcxp) { 4889a36c61f9SKrishna Gudipati port->stats.ns_gidft_alloc_wait++; 4890a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4891c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE); 4892a36c61f9SKrishna Gudipati return; 4893a36c61f9SKrishna Gudipati } 4894a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4895a36c61f9SKrishna Gudipati 4896a36c61f9SKrishna Gudipati /* 4897a36c61f9SKrishna Gudipati * This query is only initiated for FCP initiator mode. 4898a36c61f9SKrishna Gudipati */ 4899a36c61f9SKrishna Gudipati len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4900a36c61f9SKrishna Gudipati ns->port->pid, FC_TYPE_FCP); 4901a36c61f9SKrishna Gudipati 4902a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4903a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4904a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response, (void *)ns, 4905a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV); 4906a36c61f9SKrishna Gudipati 4907a36c61f9SKrishna Gudipati port->stats.ns_gidft_sent++; 4908a36c61f9SKrishna Gudipati 4909a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); 4910a36c61f9SKrishna Gudipati } 4911a36c61f9SKrishna Gudipati 4912a36c61f9SKrishna Gudipati static void 4913a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4914a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4915a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4916a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4917a36c61f9SKrishna Gudipati { 4918a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4919a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4920a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4921a36c61f9SKrishna Gudipati u32 n_pids; 4922a36c61f9SKrishna Gudipati 4923a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4924a36c61f9SKrishna Gudipati 4925a36c61f9SKrishna Gudipati /* 4926a36c61f9SKrishna Gudipati * Sanity Checks 4927a36c61f9SKrishna Gudipati */ 4928a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4929a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4930a36c61f9SKrishna Gudipati port->stats.ns_gidft_rsp_err++; 4931a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4932a36c61f9SKrishna Gudipati return; 4933a36c61f9SKrishna Gudipati } 4934a36c61f9SKrishna Gudipati 4935a36c61f9SKrishna Gudipati if (resid_len != 0) { 4936a36c61f9SKrishna Gudipati /* 4937a36c61f9SKrishna Gudipati * TBD : we will need to allocate a larger buffer & retry the 4938a36c61f9SKrishna Gudipati * command 4939a36c61f9SKrishna Gudipati */ 4940a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 4941a36c61f9SKrishna Gudipati bfa_trc(port->fcs, resid_len); 4942a36c61f9SKrishna Gudipati return; 4943a36c61f9SKrishna Gudipati } 4944a36c61f9SKrishna Gudipati 4945a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4946ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4947a36c61f9SKrishna Gudipati 4948a36c61f9SKrishna Gudipati switch (cthdr->cmd_rsp_code) { 4949a36c61f9SKrishna Gudipati 4950a36c61f9SKrishna Gudipati case CT_RSP_ACCEPT: 4951a36c61f9SKrishna Gudipati 4952a36c61f9SKrishna Gudipati port->stats.ns_gidft_accepts++; 4953a36c61f9SKrishna Gudipati n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); 4954a36c61f9SKrishna Gudipati bfa_trc(port->fcs, n_pids); 4955a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(port, 4956a36c61f9SKrishna Gudipati (u32 *) (cthdr + 1), 4957a36c61f9SKrishna Gudipati n_pids); 4958a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4959a36c61f9SKrishna Gudipati break; 4960a36c61f9SKrishna Gudipati 4961a36c61f9SKrishna Gudipati case CT_RSP_REJECT: 4962a36c61f9SKrishna Gudipati 4963a36c61f9SKrishna Gudipati /* 4964a36c61f9SKrishna Gudipati * Check the reason code & explanation. 4965a36c61f9SKrishna Gudipati * There may not have been any FC4 devices in the fabric 4966a36c61f9SKrishna Gudipati */ 4967a36c61f9SKrishna Gudipati port->stats.ns_gidft_rejects++; 4968a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4969a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4970a36c61f9SKrishna Gudipati 4971a36c61f9SKrishna Gudipati if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) 4972a36c61f9SKrishna Gudipati && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { 4973a36c61f9SKrishna Gudipati 4974a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4975a36c61f9SKrishna Gudipati } else { 4976a36c61f9SKrishna Gudipati /* 4977a36c61f9SKrishna Gudipati * for all other errors, retry 4978a36c61f9SKrishna Gudipati */ 4979a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4980a36c61f9SKrishna Gudipati } 4981a36c61f9SKrishna Gudipati break; 4982a36c61f9SKrishna Gudipati 4983a36c61f9SKrishna Gudipati default: 4984a36c61f9SKrishna Gudipati port->stats.ns_gidft_unknown_rsp++; 4985a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->cmd_rsp_code); 4986a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4987a36c61f9SKrishna Gudipati } 4988a36c61f9SKrishna Gudipati } 4989a36c61f9SKrishna Gudipati 49905fbe25c7SJing Huang /* 4991a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 4992a36c61f9SKrishna Gudipati * 4993a36c61f9SKrishna Gudipati * param[in] port - pointer to bfa_fcs_lport_t. 4994a36c61f9SKrishna Gudipati * 4995a36c61f9SKrishna Gudipati * return 4996a36c61f9SKrishna Gudipati * void 4997a36c61f9SKrishna Gudipati * 4998a36c61f9SKrishna Gudipati * Special Considerations: 4999a36c61f9SKrishna Gudipati * 5000a36c61f9SKrishna Gudipati * note 5001a36c61f9SKrishna Gudipati */ 5002a36c61f9SKrishna Gudipati static void 5003a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg) 5004a36c61f9SKrishna Gudipati { 5005a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg; 5006a36c61f9SKrishna Gudipati 5007a36c61f9SKrishna Gudipati ns->port->stats.ns_timeouts++; 5008a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT); 5009a36c61f9SKrishna Gudipati } 5010a36c61f9SKrishna Gudipati 5011a36c61f9SKrishna Gudipati /* 5012a36c61f9SKrishna Gudipati * Process the PID list in GID_FT response 5013a36c61f9SKrishna Gudipati */ 5014a36c61f9SKrishna Gudipati static void 5015a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf, 5016a36c61f9SKrishna Gudipati u32 n_pids) 5017a36c61f9SKrishna Gudipati { 5018a36c61f9SKrishna Gudipati struct fcgs_gidft_resp_s *gidft_entry; 5019a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 5020a36c61f9SKrishna Gudipati u32 ii; 502161ba4394SKrishna Gudipati struct bfa_fcs_fabric_s *fabric = port->fabric; 502261ba4394SKrishna Gudipati struct bfa_fcs_vport_s *vport; 502361ba4394SKrishna Gudipati struct list_head *qe; 502461ba4394SKrishna Gudipati u8 found = 0; 5025a36c61f9SKrishna Gudipati 5026a36c61f9SKrishna Gudipati for (ii = 0; ii < n_pids; ii++) { 5027a36c61f9SKrishna Gudipati gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; 5028a36c61f9SKrishna Gudipati 5029a36c61f9SKrishna Gudipati if (gidft_entry->pid == port->pid) 5030a36c61f9SKrishna Gudipati continue; 5031a36c61f9SKrishna Gudipati 5032a36c61f9SKrishna Gudipati /* 503361ba4394SKrishna Gudipati * Ignore PID if it is of base port 503461ba4394SKrishna Gudipati * (Avoid vports discovering base port as remote port) 503561ba4394SKrishna Gudipati */ 503661ba4394SKrishna Gudipati if (gidft_entry->pid == fabric->bport.pid) 503761ba4394SKrishna Gudipati continue; 503861ba4394SKrishna Gudipati 503961ba4394SKrishna Gudipati /* 504061ba4394SKrishna Gudipati * Ignore PID if it is of vport created on the same base port 504161ba4394SKrishna Gudipati * (Avoid vport discovering every other vport created on the 504261ba4394SKrishna Gudipati * same port as remote port) 504361ba4394SKrishna Gudipati */ 504461ba4394SKrishna Gudipati list_for_each(qe, &fabric->vport_q) { 504561ba4394SKrishna Gudipati vport = (struct bfa_fcs_vport_s *) qe; 504661ba4394SKrishna Gudipati if (vport->lport.pid == gidft_entry->pid) 504761ba4394SKrishna Gudipati found = 1; 504861ba4394SKrishna Gudipati } 504961ba4394SKrishna Gudipati 505061ba4394SKrishna Gudipati if (found) { 505161ba4394SKrishna Gudipati found = 0; 505261ba4394SKrishna Gudipati continue; 505361ba4394SKrishna Gudipati } 505461ba4394SKrishna Gudipati 505561ba4394SKrishna Gudipati /* 5056a36c61f9SKrishna Gudipati * Check if this rport already exists 5057a36c61f9SKrishna Gudipati */ 5058a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid); 5059a36c61f9SKrishna Gudipati if (rport == NULL) { 5060a36c61f9SKrishna Gudipati /* 5061a36c61f9SKrishna Gudipati * this is a new device. create rport 5062a36c61f9SKrishna Gudipati */ 5063a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, gidft_entry->pid); 5064a36c61f9SKrishna Gudipati } else { 5065a36c61f9SKrishna Gudipati /* 5066a36c61f9SKrishna Gudipati * this rport already exists 5067a36c61f9SKrishna Gudipati */ 5068a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 5069a36c61f9SKrishna Gudipati } 5070a36c61f9SKrishna Gudipati 5071a36c61f9SKrishna Gudipati bfa_trc(port->fcs, gidft_entry->pid); 5072a36c61f9SKrishna Gudipati 5073a36c61f9SKrishna Gudipati /* 5074a36c61f9SKrishna Gudipati * if the last entry bit is set, bail out. 5075a36c61f9SKrishna Gudipati */ 5076a36c61f9SKrishna Gudipati if (gidft_entry->last) 5077a36c61f9SKrishna Gudipati return; 5078a36c61f9SKrishna Gudipati } 5079a36c61f9SKrishna Gudipati } 5080a36c61f9SKrishna Gudipati 50815fbe25c7SJing Huang /* 5082a36c61f9SKrishna Gudipati * fcs_ns_public FCS nameserver public interfaces 5083a36c61f9SKrishna Gudipati */ 5084a36c61f9SKrishna Gudipati 5085a36c61f9SKrishna Gudipati /* 5086a36c61f9SKrishna Gudipati * Functions called by port/fab. 5087a36c61f9SKrishna Gudipati * These will send relevant Events to the ns state machine. 5088a36c61f9SKrishna Gudipati */ 5089a36c61f9SKrishna Gudipati void 5090a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port) 5091a36c61f9SKrishna Gudipati { 5092a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 5093a36c61f9SKrishna Gudipati 5094a36c61f9SKrishna Gudipati ns->port = port; 5095a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 5096a36c61f9SKrishna Gudipati } 5097a36c61f9SKrishna Gudipati 5098a36c61f9SKrishna Gudipati void 5099a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(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_send_event(ns, NSSM_EVENT_PORT_OFFLINE); 5105a36c61f9SKrishna Gudipati } 5106a36c61f9SKrishna Gudipati 5107a36c61f9SKrishna Gudipati void 5108a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(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_ONLINE); 5114a36c61f9SKrishna Gudipati } 5115a36c61f9SKrishna Gudipati 5116a36c61f9SKrishna Gudipati void 5117a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(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 bfa_trc(port->fcs, port->pid); 512261ba4394SKrishna Gudipati if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_online)) 5123a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 5124a36c61f9SKrishna Gudipati } 5125a36c61f9SKrishna Gudipati 512652f94b6fSMaggie static void 5127a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port) 5128a36c61f9SKrishna Gudipati { 5129a36c61f9SKrishna Gudipati 5130a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 5131a36c61f9SKrishna Gudipati u8 nwwns; 5132a36c61f9SKrishna Gudipati wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; 5133a36c61f9SKrishna Gudipati int ii; 5134a36c61f9SKrishna Gudipati 5135a36c61f9SKrishna Gudipati bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns); 5136a36c61f9SKrishna Gudipati 5137a36c61f9SKrishna Gudipati for (ii = 0 ; ii < nwwns; ++ii) { 5138a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]); 5139d4b671c5SJing Huang WARN_ON(!rport); 5140a36c61f9SKrishna Gudipati } 5141a36c61f9SKrishna Gudipati } 5142a36c61f9SKrishna Gudipati 5143ebfe8392SKrishna Gudipati void 5144ebfe8392SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) 5145ebfe8392SKrishna Gudipati { 5146ebfe8392SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = cbarg; 5147ebfe8392SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 5148ebfe8392SKrishna Gudipati struct fchs_s fchs; 5149ebfe8392SKrishna Gudipati struct bfa_fcxp_s *fcxp; 5150ebfe8392SKrishna Gudipati u8 symbl[256]; 5151ebfe8392SKrishna Gudipati u8 *psymbl = &symbl[0]; 5152ebfe8392SKrishna Gudipati int len; 5153ebfe8392SKrishna Gudipati 5154ebfe8392SKrishna Gudipati /* Avoid sending RSPN in the following states. */ 5155ebfe8392SKrishna Gudipati if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) || 5156ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) || 5157ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) || 5158ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) || 5159ebfe8392SKrishna Gudipati bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry)) 5160ebfe8392SKrishna Gudipati return; 5161ebfe8392SKrishna Gudipati 5162ebfe8392SKrishna Gudipati memset(symbl, 0, sizeof(symbl)); 5163ebfe8392SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 5164ebfe8392SKrishna Gudipati 5165c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 5166c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5167ebfe8392SKrishna Gudipati if (!fcxp) { 5168ebfe8392SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 5169ebfe8392SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 5170c3f1b123SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE); 5171ebfe8392SKrishna Gudipati return; 5172ebfe8392SKrishna Gudipati } 5173ebfe8392SKrishna Gudipati 5174ebfe8392SKrishna Gudipati ns->fcxp = fcxp; 5175ebfe8392SKrishna Gudipati 5176ebfe8392SKrishna Gudipati if (port->vport) { 5177ebfe8392SKrishna Gudipati /* 5178ebfe8392SKrishna Gudipati * For Vports, we append the vport's port symbolic name 5179ebfe8392SKrishna Gudipati * to that of the base port. 5180ebfe8392SKrishna Gudipati */ 5181ebfe8392SKrishna Gudipati strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name 5182ebfe8392SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 5183ebfe8392SKrishna Gudipati strlen((char *)&bfa_fcs_lport_get_psym_name( 5184ebfe8392SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)))); 5185ebfe8392SKrishna Gudipati 5186ebfe8392SKrishna Gudipati /* Ensure we have a null terminating string. */ 5187ebfe8392SKrishna Gudipati ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name( 5188ebfe8392SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)))] = 0; 5189ebfe8392SKrishna Gudipati 5190ebfe8392SKrishna Gudipati strncat((char *)psymbl, 5191ebfe8392SKrishna Gudipati (char *)&(bfa_fcs_lport_get_psym_name(port)), 5192ebfe8392SKrishna Gudipati strlen((char *)&bfa_fcs_lport_get_psym_name(port))); 5193ebfe8392SKrishna Gudipati } 5194ebfe8392SKrishna Gudipati 5195ebfe8392SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 5196ebfe8392SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, psymbl); 5197ebfe8392SKrishna Gudipati 5198ebfe8392SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 5199ebfe8392SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 5200ebfe8392SKrishna Gudipati 5201ebfe8392SKrishna Gudipati port->stats.ns_rspnid_sent++; 5202ebfe8392SKrishna Gudipati } 5203ebfe8392SKrishna Gudipati 52045fbe25c7SJing Huang /* 5205a36c61f9SKrishna Gudipati * FCS SCN 5206a36c61f9SKrishna Gudipati */ 5207a36c61f9SKrishna Gudipati 5208a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT 0x0c 5209a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT 0x0d 5210a36c61f9SKrishna Gudipati 5211a36c61f9SKrishna Gudipati /* 5212a36c61f9SKrishna Gudipati * forward declarations 5213a36c61f9SKrishna Gudipati */ 5214a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg, 5215a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 5216a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_scr_response(void *fcsarg, 5217a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 5218a36c61f9SKrishna Gudipati void *cbarg, 5219a36c61f9SKrishna Gudipati bfa_status_t req_status, 5220a36c61f9SKrishna Gudipati u32 rsp_len, 5221a36c61f9SKrishna Gudipati u32 resid_len, 5222a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 5223a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 5224a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs); 5225a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_timeout(void *arg); 5226a36c61f9SKrishna Gudipati 52275fbe25c7SJing Huang /* 5228a36c61f9SKrishna Gudipati * fcs_scm_sm FCS SCN state machine 5229a36c61f9SKrishna Gudipati */ 5230a36c61f9SKrishna Gudipati 52315fbe25c7SJing Huang /* 5232a36c61f9SKrishna Gudipati * VPort SCN State Machine events 5233a36c61f9SKrishna Gudipati */ 5234a36c61f9SKrishna Gudipati enum port_scn_event { 5235a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_ONLINE = 1, 5236a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_OFFLINE = 2, 5237a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_OK = 3, 5238a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_ERROR = 4, 5239a36c61f9SKrishna Gudipati SCNSM_EVENT_TIMEOUT = 5, 5240a36c61f9SKrishna Gudipati SCNSM_EVENT_SCR_SENT = 6, 5241a36c61f9SKrishna Gudipati }; 5242a36c61f9SKrishna Gudipati 5243a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 5244a36c61f9SKrishna Gudipati enum port_scn_event event); 5245a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_sending_scr( 5246a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn, 5247a36c61f9SKrishna Gudipati enum port_scn_event event); 5248a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 5249a36c61f9SKrishna Gudipati enum port_scn_event event); 5250a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 5251a36c61f9SKrishna Gudipati enum port_scn_event event); 5252a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 5253a36c61f9SKrishna Gudipati enum port_scn_event event); 5254a36c61f9SKrishna Gudipati 52555fbe25c7SJing Huang /* 5256a36c61f9SKrishna Gudipati * Starting state - awaiting link up. 5257a36c61f9SKrishna Gudipati */ 5258a36c61f9SKrishna Gudipati static void 5259a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 5260a36c61f9SKrishna Gudipati enum port_scn_event event) 5261a36c61f9SKrishna Gudipati { 5262a36c61f9SKrishna Gudipati switch (event) { 5263a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_ONLINE: 5264a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 5265a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 5266a36c61f9SKrishna Gudipati break; 5267a36c61f9SKrishna Gudipati 5268a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5269a36c61f9SKrishna Gudipati break; 5270a36c61f9SKrishna Gudipati 5271a36c61f9SKrishna Gudipati default: 5272a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5273a36c61f9SKrishna Gudipati } 5274a36c61f9SKrishna Gudipati } 5275a36c61f9SKrishna Gudipati 5276a36c61f9SKrishna Gudipati static void 5277a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn, 5278a36c61f9SKrishna Gudipati enum port_scn_event event) 5279a36c61f9SKrishna Gudipati { 5280a36c61f9SKrishna Gudipati switch (event) { 5281a36c61f9SKrishna Gudipati case SCNSM_EVENT_SCR_SENT: 5282a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr); 5283a36c61f9SKrishna Gudipati break; 5284a36c61f9SKrishna Gudipati 5285a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5286a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5287a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe); 5288a36c61f9SKrishna Gudipati break; 5289a36c61f9SKrishna Gudipati 5290a36c61f9SKrishna Gudipati default: 5291a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5292a36c61f9SKrishna Gudipati } 5293a36c61f9SKrishna Gudipati } 5294a36c61f9SKrishna Gudipati 5295a36c61f9SKrishna Gudipati static void 5296a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 5297a36c61f9SKrishna Gudipati enum port_scn_event event) 5298a36c61f9SKrishna Gudipati { 5299a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 5300a36c61f9SKrishna Gudipati 5301a36c61f9SKrishna Gudipati switch (event) { 5302a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_OK: 5303a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online); 5304a36c61f9SKrishna Gudipati break; 5305a36c61f9SKrishna Gudipati 5306a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_ERROR: 5307a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry); 5308a36c61f9SKrishna Gudipati bfa_timer_start(port->fcs->bfa, &scn->timer, 5309a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout, scn, 5310a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 5311a36c61f9SKrishna Gudipati break; 5312a36c61f9SKrishna Gudipati 5313a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5314a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5315a36c61f9SKrishna Gudipati bfa_fcxp_discard(scn->fcxp); 5316a36c61f9SKrishna Gudipati break; 5317a36c61f9SKrishna Gudipati 5318a36c61f9SKrishna Gudipati default: 5319a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 5320a36c61f9SKrishna Gudipati } 5321a36c61f9SKrishna Gudipati } 5322a36c61f9SKrishna Gudipati 5323a36c61f9SKrishna Gudipati static void 5324a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 5325a36c61f9SKrishna Gudipati enum port_scn_event event) 5326a36c61f9SKrishna Gudipati { 5327a36c61f9SKrishna Gudipati switch (event) { 5328a36c61f9SKrishna Gudipati case SCNSM_EVENT_TIMEOUT: 5329a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 5330a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 5331a36c61f9SKrishna Gudipati break; 5332a36c61f9SKrishna Gudipati 5333a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5334a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5335a36c61f9SKrishna Gudipati bfa_timer_stop(&scn->timer); 5336a36c61f9SKrishna Gudipati break; 5337a36c61f9SKrishna Gudipati 5338a36c61f9SKrishna Gudipati default: 5339a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5340a36c61f9SKrishna Gudipati } 5341a36c61f9SKrishna Gudipati } 5342a36c61f9SKrishna Gudipati 5343a36c61f9SKrishna Gudipati static void 5344a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 5345a36c61f9SKrishna Gudipati enum port_scn_event event) 5346a36c61f9SKrishna Gudipati { 5347a36c61f9SKrishna Gudipati switch (event) { 5348a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 5349a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5350a36c61f9SKrishna Gudipati break; 5351a36c61f9SKrishna Gudipati 5352a36c61f9SKrishna Gudipati default: 5353a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 5354a36c61f9SKrishna Gudipati } 5355a36c61f9SKrishna Gudipati } 5356a36c61f9SKrishna Gudipati 5357a36c61f9SKrishna Gudipati 5358a36c61f9SKrishna Gudipati 53595fbe25c7SJing Huang /* 5360a36c61f9SKrishna Gudipati * fcs_scn_private FCS SCN private functions 5361a36c61f9SKrishna Gudipati */ 5362a36c61f9SKrishna Gudipati 53635fbe25c7SJing Huang /* 5364a36c61f9SKrishna Gudipati * This routine will be called to send a SCR command. 5365a36c61f9SKrishna Gudipati */ 5366a36c61f9SKrishna Gudipati static void 5367a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced) 5368a36c61f9SKrishna Gudipati { 5369a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = scn_cbarg; 5370a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 5371a36c61f9SKrishna Gudipati struct fchs_s fchs; 5372a36c61f9SKrishna Gudipati int len; 5373a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 5374a36c61f9SKrishna Gudipati 5375a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 5376a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 5377a36c61f9SKrishna Gudipati 5378c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 5379c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 5380a36c61f9SKrishna Gudipati if (!fcxp) { 5381a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, 5382c3f1b123SKrishna Gudipati bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE); 5383a36c61f9SKrishna Gudipati return; 5384a36c61f9SKrishna Gudipati } 5385a36c61f9SKrishna Gudipati scn->fcxp = fcxp; 5386a36c61f9SKrishna Gudipati 5387a36c61f9SKrishna Gudipati /* Handle VU registrations for Base port only */ 5388a36c61f9SKrishna Gudipati if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) { 5389a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 5390f7f73812SMaggie Zhang port->fabric->lps->brcd_switch, 5391a36c61f9SKrishna Gudipati port->pid, 0); 5392a36c61f9SKrishna Gudipati } else { 5393a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 5394a36c61f9SKrishna Gudipati BFA_FALSE, 5395a36c61f9SKrishna Gudipati port->pid, 0); 5396a36c61f9SKrishna Gudipati } 5397a36c61f9SKrishna Gudipati 5398a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 5399a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 5400a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response, 5401a36c61f9SKrishna Gudipati (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV); 5402a36c61f9SKrishna Gudipati 5403a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT); 5404a36c61f9SKrishna Gudipati } 5405a36c61f9SKrishna Gudipati 5406a36c61f9SKrishna Gudipati static void 5407a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 5408a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 5409a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 5410a36c61f9SKrishna Gudipati { 5411a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg; 5412a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 5413a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 5414a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 5415a36c61f9SKrishna Gudipati 5416a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 5417a36c61f9SKrishna Gudipati 5418a36c61f9SKrishna Gudipati /* 5419a36c61f9SKrishna Gudipati * Sanity Checks 5420a36c61f9SKrishna Gudipati */ 5421a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 5422a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 5423a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 5424a36c61f9SKrishna Gudipati return; 5425a36c61f9SKrishna Gudipati } 5426a36c61f9SKrishna Gudipati 5427a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 5428a36c61f9SKrishna Gudipati 5429a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 5430a36c61f9SKrishna Gudipati 5431a36c61f9SKrishna Gudipati case FC_ELS_ACC: 5432a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK); 5433a36c61f9SKrishna Gudipati break; 5434a36c61f9SKrishna Gudipati 5435a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 5436a36c61f9SKrishna Gudipati 5437a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 5438a36c61f9SKrishna Gudipati 5439a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 5440a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 5441a36c61f9SKrishna Gudipati 5442a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 5443a36c61f9SKrishna Gudipati break; 5444a36c61f9SKrishna Gudipati 5445a36c61f9SKrishna Gudipati default: 5446a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 5447a36c61f9SKrishna Gudipati } 5448a36c61f9SKrishna Gudipati } 5449a36c61f9SKrishna Gudipati 5450a36c61f9SKrishna Gudipati /* 5451a36c61f9SKrishna Gudipati * Send a LS Accept 5452a36c61f9SKrishna Gudipati */ 5453a36c61f9SKrishna Gudipati static void 5454a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 5455a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs) 5456a36c61f9SKrishna Gudipati { 5457a36c61f9SKrishna Gudipati struct fchs_s fchs; 5458a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 5459a36c61f9SKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 5460a36c61f9SKrishna Gudipati int len; 5461a36c61f9SKrishna Gudipati 5462a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 5463a36c61f9SKrishna Gudipati 5464c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 5465a36c61f9SKrishna Gudipati if (!fcxp) 5466a36c61f9SKrishna Gudipati return; 5467a36c61f9SKrishna Gudipati 5468a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 5469a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 5470a36c61f9SKrishna Gudipati rx_fchs->ox_id); 5471a36c61f9SKrishna Gudipati 5472a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 5473a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 5474a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 5475a36c61f9SKrishna Gudipati } 5476a36c61f9SKrishna Gudipati 54775fbe25c7SJing Huang /* 5478a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 5479a36c61f9SKrishna Gudipati * 5480a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_lport_t. 5481a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 5482a36c61f9SKrishna Gudipati * 5483a36c61f9SKrishna Gudipati * return 5484a36c61f9SKrishna Gudipati * void 5485a36c61f9SKrishna Gudipati * 5486a36c61f9SKrishna Gudipati * Special Considerations: 5487a36c61f9SKrishna Gudipati * 5488a36c61f9SKrishna Gudipati * note 5489a36c61f9SKrishna Gudipati */ 5490a36c61f9SKrishna Gudipati static void 5491a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg) 5492a36c61f9SKrishna Gudipati { 5493a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg; 5494a36c61f9SKrishna Gudipati 5495a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT); 5496a36c61f9SKrishna Gudipati } 5497a36c61f9SKrishna Gudipati 5498a36c61f9SKrishna Gudipati 5499a36c61f9SKrishna Gudipati 55005fbe25c7SJing Huang /* 5501a36c61f9SKrishna Gudipati * fcs_scn_public FCS state change notification public interfaces 5502a36c61f9SKrishna Gudipati */ 5503a36c61f9SKrishna Gudipati 5504a36c61f9SKrishna Gudipati /* 5505a36c61f9SKrishna Gudipati * Functions called by port/fab 5506a36c61f9SKrishna Gudipati */ 5507a36c61f9SKrishna Gudipati void 5508a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port) 5509a36c61f9SKrishna Gudipati { 5510a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5511a36c61f9SKrishna Gudipati 5512a36c61f9SKrishna Gudipati scn->port = port; 5513a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 5514a36c61f9SKrishna Gudipati } 5515a36c61f9SKrishna Gudipati 5516a36c61f9SKrishna Gudipati void 5517a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port) 5518a36c61f9SKrishna Gudipati { 5519a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5520a36c61f9SKrishna Gudipati 5521a36c61f9SKrishna Gudipati scn->port = port; 5522a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE); 5523a36c61f9SKrishna Gudipati } 5524a36c61f9SKrishna Gudipati 5525a36c61f9SKrishna Gudipati void 5526bc0e2c2aSKrishna Gudipati bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port) 5527a36c61f9SKrishna Gudipati { 5528a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 5529a36c61f9SKrishna Gudipati 5530a36c61f9SKrishna Gudipati scn->port = port; 5531a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE); 5532a36c61f9SKrishna Gudipati } 5533a36c61f9SKrishna Gudipati 5534a36c61f9SKrishna Gudipati static void 5535a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) 5536a36c61f9SKrishna Gudipati { 5537a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 553861ba4394SKrishna Gudipati struct bfa_fcs_fabric_s *fabric = port->fabric; 553961ba4394SKrishna Gudipati struct bfa_fcs_vport_s *vport; 554061ba4394SKrishna Gudipati struct list_head *qe; 5541a36c61f9SKrishna Gudipati 5542a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rpid); 5543a36c61f9SKrishna Gudipati 55445fbe25c7SJing Huang /* 554561ba4394SKrishna Gudipati * Ignore PID if it is of base port or of vports created on the 554661ba4394SKrishna Gudipati * same base port. It is to avoid vports discovering base port or 554761ba4394SKrishna Gudipati * other vports created on same base port as remote port 554861ba4394SKrishna Gudipati */ 554961ba4394SKrishna Gudipati if (rpid == fabric->bport.pid) 555061ba4394SKrishna Gudipati return; 555161ba4394SKrishna Gudipati 555261ba4394SKrishna Gudipati list_for_each(qe, &fabric->vport_q) { 555361ba4394SKrishna Gudipati vport = (struct bfa_fcs_vport_s *) qe; 555461ba4394SKrishna Gudipati if (vport->lport.pid == rpid) 555561ba4394SKrishna Gudipati return; 555661ba4394SKrishna Gudipati } 555761ba4394SKrishna Gudipati /* 5558a36c61f9SKrishna Gudipati * If this is an unknown device, then it just came online. 5559a36c61f9SKrishna Gudipati * Otherwise let rport handle the RSCN event. 5560a36c61f9SKrishna Gudipati */ 5561a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 5562ee1a4a42SKrishna Gudipati if (!rport) 5563ee1a4a42SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid); 5564ee1a4a42SKrishna Gudipati 5565a36c61f9SKrishna Gudipati if (rport == NULL) { 5566a36c61f9SKrishna Gudipati /* 5567a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot need to 5568a36c61f9SKrishna Gudipati * discover any new rports. 5569a36c61f9SKrishna Gudipati */ 5570a36c61f9SKrishna Gudipati if (!__fcs_min_cfg(port->fcs)) 5571a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, rpid); 5572a36c61f9SKrishna Gudipati } else 5573a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 5574a36c61f9SKrishna Gudipati } 5575a36c61f9SKrishna Gudipati 55765fbe25c7SJing Huang /* 5577a36c61f9SKrishna Gudipati * rscn format based PID comparison 5578a36c61f9SKrishna Gudipati */ 5579a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt) \ 5580a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \ 5581a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \ 5582a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0])) || \ 5583a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_AREA) && \ 5584a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0]) && \ 5585a36c61f9SKrishna Gudipati ((__c0)[1] == (__c1)[1]))) 5586a36c61f9SKrishna Gudipati 5587a36c61f9SKrishna Gudipati static void 5588a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port, 5589a36c61f9SKrishna Gudipati enum fc_rscn_format format, 5590a36c61f9SKrishna Gudipati u32 rscn_pid) 5591a36c61f9SKrishna Gudipati { 5592a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 5593a36c61f9SKrishna Gudipati struct list_head *qe, *qe_next; 5594a36c61f9SKrishna Gudipati u8 *c0, *c1; 5595a36c61f9SKrishna Gudipati 5596a36c61f9SKrishna Gudipati bfa_trc(port->fcs, format); 5597a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5598a36c61f9SKrishna Gudipati 5599a36c61f9SKrishna Gudipati c0 = (u8 *) &rscn_pid; 5600a36c61f9SKrishna Gudipati 5601a36c61f9SKrishna Gudipati list_for_each_safe(qe, qe_next, &port->rport_q) { 5602a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5603a36c61f9SKrishna Gudipati c1 = (u8 *) &rport->pid; 5604a36c61f9SKrishna Gudipati if (__fc_pid_match(c0, c1, format)) 5605a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 5606a36c61f9SKrishna Gudipati } 5607a36c61f9SKrishna Gudipati } 5608a36c61f9SKrishna Gudipati 5609a36c61f9SKrishna Gudipati 5610a36c61f9SKrishna Gudipati void 5611a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 5612a36c61f9SKrishna Gudipati struct fchs_s *fchs, u32 len) 5613a36c61f9SKrishna Gudipati { 5614a36c61f9SKrishna Gudipati struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1); 5615a36c61f9SKrishna Gudipati int num_entries; 5616a36c61f9SKrishna Gudipati u32 rscn_pid; 5617a36c61f9SKrishna Gudipati bfa_boolean_t nsquery = BFA_FALSE, found; 5618a36c61f9SKrishna Gudipati int i = 0, j; 5619a36c61f9SKrishna Gudipati 5620a36c61f9SKrishna Gudipati num_entries = 5621ba816ea8SJing Huang (be16_to_cpu(rscn->payldlen) - 5622a36c61f9SKrishna Gudipati sizeof(u32)) / sizeof(rscn->event[0]); 5623a36c61f9SKrishna Gudipati 5624a36c61f9SKrishna Gudipati bfa_trc(port->fcs, num_entries); 5625a36c61f9SKrishna Gudipati 5626a36c61f9SKrishna Gudipati port->stats.num_rscn++; 5627a36c61f9SKrishna Gudipati 5628a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(port, fchs); 5629a36c61f9SKrishna Gudipati 5630a36c61f9SKrishna Gudipati for (i = 0; i < num_entries; i++) { 5631a36c61f9SKrishna Gudipati rscn_pid = rscn->event[i].portid; 5632a36c61f9SKrishna Gudipati 5633a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn->event[i].format); 5634a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5635a36c61f9SKrishna Gudipati 5636a36c61f9SKrishna Gudipati /* check for duplicate entries in the list */ 5637a36c61f9SKrishna Gudipati found = BFA_FALSE; 5638a36c61f9SKrishna Gudipati for (j = 0; j < i; j++) { 5639a36c61f9SKrishna Gudipati if (rscn->event[j].portid == rscn_pid) { 5640a36c61f9SKrishna Gudipati found = BFA_TRUE; 5641a36c61f9SKrishna Gudipati break; 5642a36c61f9SKrishna Gudipati } 5643a36c61f9SKrishna Gudipati } 5644a36c61f9SKrishna Gudipati 5645a36c61f9SKrishna Gudipati /* if found in down the list, pid has been already processed */ 5646a36c61f9SKrishna Gudipati if (found) { 5647a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5648a36c61f9SKrishna Gudipati continue; 5649a36c61f9SKrishna Gudipati } 5650a36c61f9SKrishna Gudipati 5651a36c61f9SKrishna Gudipati switch (rscn->event[i].format) { 5652a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_PORTID: 5653a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) { 5654a36c61f9SKrishna Gudipati /* 5655a36c61f9SKrishna Gudipati * Ignore this event. 5656a36c61f9SKrishna Gudipati * f/w would have processed it 5657a36c61f9SKrishna Gudipati */ 5658a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 5659a36c61f9SKrishna Gudipati } else { 5660a36c61f9SKrishna Gudipati port->stats.num_portid_rscn++; 5661a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(port, rscn_pid); 5662a36c61f9SKrishna Gudipati } 5663a36c61f9SKrishna Gudipati break; 5664a36c61f9SKrishna Gudipati 5665a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_FABRIC: 5666a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == 5667a36c61f9SKrishna Gudipati FC_FABRIC_NAME_RSCN_EVENT) { 5668a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(port); 5669a36c61f9SKrishna Gudipati break; 5670a36c61f9SKrishna Gudipati } 5671a36c61f9SKrishna Gudipati /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */ 5672a36c61f9SKrishna Gudipati 5673a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_AREA: 5674a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_DOMAIN: 5675a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 5676a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(port, 5677a36c61f9SKrishna Gudipati rscn->event[i].format, 5678a36c61f9SKrishna Gudipati rscn_pid); 5679a36c61f9SKrishna Gudipati break; 5680a36c61f9SKrishna Gudipati 5681a36c61f9SKrishna Gudipati 5682a36c61f9SKrishna Gudipati default: 5683d4b671c5SJing Huang WARN_ON(1); 5684a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 5685a36c61f9SKrishna Gudipati } 5686a36c61f9SKrishna Gudipati } 5687a36c61f9SKrishna Gudipati 56885fbe25c7SJing Huang /* 56895fbe25c7SJing Huang * If any of area, domain or fabric RSCN is received, do a fresh 56905fbe25c7SJing Huang * discovery to find new devices. 5691a36c61f9SKrishna Gudipati */ 5692a36c61f9SKrishna Gudipati if (nsquery) 5693a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(port); 5694a36c61f9SKrishna Gudipati } 5695a36c61f9SKrishna Gudipati 56965fbe25c7SJing Huang /* 5697a36c61f9SKrishna Gudipati * BFA FCS port 5698a36c61f9SKrishna Gudipati */ 56995fbe25c7SJing Huang /* 5700a36c61f9SKrishna Gudipati * fcs_port_api BFA FCS port API 5701a36c61f9SKrishna Gudipati */ 5702a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 5703a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs) 5704a36c61f9SKrishna Gudipati { 5705a36c61f9SKrishna Gudipati return &fcs->fabric.bport; 5706a36c61f9SKrishna Gudipati } 5707a36c61f9SKrishna Gudipati 5708a36c61f9SKrishna Gudipati wwn_t 5709a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, 5710a36c61f9SKrishna Gudipati int nrports, bfa_boolean_t bwwn) 5711a36c61f9SKrishna Gudipati { 5712a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5713a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5714a36c61f9SKrishna Gudipati int i; 5715a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5716a36c61f9SKrishna Gudipati 5717a36c61f9SKrishna Gudipati if (port == NULL || nrports == 0) 5718a36c61f9SKrishna Gudipati return (wwn_t) 0; 5719a36c61f9SKrishna Gudipati 5720a36c61f9SKrishna Gudipati fcs = port->fcs; 5721a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) nrports); 5722a36c61f9SKrishna Gudipati 5723a36c61f9SKrishna Gudipati i = 0; 5724a36c61f9SKrishna Gudipati qh = &port->rport_q; 5725a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5726a36c61f9SKrishna Gudipati 5727a36c61f9SKrishna Gudipati while ((qe != qh) && (i < nrports)) { 5728a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5729f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 5730a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5731a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 5732a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 5733a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5734a36c61f9SKrishna Gudipati continue; 5735a36c61f9SKrishna Gudipati } 5736a36c61f9SKrishna Gudipati 5737a36c61f9SKrishna Gudipati if (bwwn) { 5738a36c61f9SKrishna Gudipati if (!memcmp(&wwn, &rport->pwwn, 8)) 5739a36c61f9SKrishna Gudipati break; 5740a36c61f9SKrishna Gudipati } else { 5741a36c61f9SKrishna Gudipati if (i == index) 5742a36c61f9SKrishna Gudipati break; 5743a36c61f9SKrishna Gudipati } 5744a36c61f9SKrishna Gudipati 5745a36c61f9SKrishna Gudipati i++; 5746a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5747a36c61f9SKrishna Gudipati } 5748a36c61f9SKrishna Gudipati 5749a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5750a36c61f9SKrishna Gudipati if (rport) 5751a36c61f9SKrishna Gudipati return rport->pwwn; 5752a36c61f9SKrishna Gudipati else 5753a36c61f9SKrishna Gudipati return (wwn_t) 0; 5754a36c61f9SKrishna Gudipati } 5755a36c61f9SKrishna Gudipati 5756a36c61f9SKrishna Gudipati void 5757ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port, 5758ee1a4a42SKrishna Gudipati struct bfa_rport_qualifier_s rports[], int *nrports) 5759a36c61f9SKrishna Gudipati { 5760a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5761a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5762a36c61f9SKrishna Gudipati int i; 5763a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5764a36c61f9SKrishna Gudipati 5765ee1a4a42SKrishna Gudipati if (port == NULL || rports == NULL || *nrports == 0) 5766a36c61f9SKrishna Gudipati return; 5767a36c61f9SKrishna Gudipati 5768a36c61f9SKrishna Gudipati fcs = port->fcs; 5769a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) *nrports); 5770a36c61f9SKrishna Gudipati 5771a36c61f9SKrishna Gudipati i = 0; 5772a36c61f9SKrishna Gudipati qh = &port->rport_q; 5773a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5774a36c61f9SKrishna Gudipati 5775a36c61f9SKrishna Gudipati while ((qe != qh) && (i < *nrports)) { 5776a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5777f16a1750SMaggie Zhang if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 5778a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5779a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 5780a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 5781a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5782a36c61f9SKrishna Gudipati continue; 5783a36c61f9SKrishna Gudipati } 5784a36c61f9SKrishna Gudipati 5785ee1a4a42SKrishna Gudipati if (!rport->pwwn && !rport->pid) { 5786ee1a4a42SKrishna Gudipati qe = bfa_q_next(qe); 5787ee1a4a42SKrishna Gudipati continue; 5788ee1a4a42SKrishna Gudipati } 5789ee1a4a42SKrishna Gudipati 5790ee1a4a42SKrishna Gudipati rports[i].pwwn = rport->pwwn; 5791ee1a4a42SKrishna Gudipati rports[i].pid = rport->pid; 5792a36c61f9SKrishna Gudipati 5793a36c61f9SKrishna Gudipati i++; 5794a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5795a36c61f9SKrishna Gudipati } 5796a36c61f9SKrishna Gudipati 5797a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 5798a36c61f9SKrishna Gudipati *nrports = i; 5799a36c61f9SKrishna Gudipati } 5800a36c61f9SKrishna Gudipati 5801a36c61f9SKrishna Gudipati /* 5802a36c61f9SKrishna Gudipati * Iterate's through all the rport's in the given port to 5803a36c61f9SKrishna Gudipati * determine the maximum operating speed. 5804a36c61f9SKrishna Gudipati * 5805a36c61f9SKrishna Gudipati * !!!! To be used in TRL Functionality only !!!! 5806a36c61f9SKrishna Gudipati */ 5807a36c61f9SKrishna Gudipati bfa_port_speed_t 5808a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) 5809a36c61f9SKrishna Gudipati { 5810a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 5811a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 5812a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 5813a36c61f9SKrishna Gudipati bfa_port_speed_t max_speed = 0; 5814a36c61f9SKrishna Gudipati struct bfa_port_attr_s port_attr; 5815a36c61f9SKrishna Gudipati bfa_port_speed_t port_speed, rport_speed; 5816a36c61f9SKrishna Gudipati bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa); 5817a36c61f9SKrishna Gudipati 5818a36c61f9SKrishna Gudipati 5819a36c61f9SKrishna Gudipati if (port == NULL) 5820a36c61f9SKrishna Gudipati return 0; 5821a36c61f9SKrishna Gudipati 5822a36c61f9SKrishna Gudipati fcs = port->fcs; 5823a36c61f9SKrishna Gudipati 5824a36c61f9SKrishna Gudipati /* Get Physical port's current speed */ 5825a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &port_attr); 5826a36c61f9SKrishna Gudipati port_speed = port_attr.speed; 5827a36c61f9SKrishna Gudipati bfa_trc(fcs, port_speed); 5828a36c61f9SKrishna Gudipati 5829a36c61f9SKrishna Gudipati qh = &port->rport_q; 5830a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 5831a36c61f9SKrishna Gudipati 5832a36c61f9SKrishna Gudipati while (qe != qh) { 5833a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 5834f16a1750SMaggie Zhang if ((bfa_ntoh3b(rport->pid) > 0xFFF000) || 5835d7be54ccSKrishna Gudipati (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) || 5836d7be54ccSKrishna Gudipati (rport->scsi_function != BFA_RPORT_TARGET)) { 5837a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5838a36c61f9SKrishna Gudipati continue; 5839a36c61f9SKrishna Gudipati } 5840a36c61f9SKrishna Gudipati 5841a36c61f9SKrishna Gudipati rport_speed = rport->rpf.rpsc_speed; 5842a36c61f9SKrishna Gudipati if ((trl_enabled) && (rport_speed == 5843a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN)) { 5844a36c61f9SKrishna Gudipati /* Use default ratelim speed setting */ 5845a36c61f9SKrishna Gudipati rport_speed = 5846a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(port->fcs->bfa); 5847a36c61f9SKrishna Gudipati } 5848a36c61f9SKrishna Gudipati 5849d7be54ccSKrishna Gudipati if (rport_speed > max_speed) 5850a36c61f9SKrishna Gudipati max_speed = rport_speed; 5851a36c61f9SKrishna Gudipati 5852a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 5853a36c61f9SKrishna Gudipati } 5854a36c61f9SKrishna Gudipati 5855d7be54ccSKrishna Gudipati if (max_speed > port_speed) 5856d7be54ccSKrishna Gudipati max_speed = port_speed; 5857d7be54ccSKrishna Gudipati 5858a36c61f9SKrishna Gudipati bfa_trc(fcs, max_speed); 5859a36c61f9SKrishna Gudipati return max_speed; 5860a36c61f9SKrishna Gudipati } 5861a36c61f9SKrishna Gudipati 5862a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 5863a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn) 5864a36c61f9SKrishna Gudipati { 5865a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 5866a36c61f9SKrishna Gudipati bfa_fcs_vf_t *vf; 5867a36c61f9SKrishna Gudipati 5868d4b671c5SJing Huang WARN_ON(fcs == NULL); 5869a36c61f9SKrishna Gudipati 5870a36c61f9SKrishna Gudipati vf = bfa_fcs_vf_lookup(fcs, vf_id); 5871a36c61f9SKrishna Gudipati if (vf == NULL) { 5872a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5873a36c61f9SKrishna Gudipati return NULL; 5874a36c61f9SKrishna Gudipati } 5875a36c61f9SKrishna Gudipati 5876a36c61f9SKrishna Gudipati if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn)) 5877a36c61f9SKrishna Gudipati return &vf->bport; 5878a36c61f9SKrishna Gudipati 5879a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn); 5880a36c61f9SKrishna Gudipati if (vport) 5881a36c61f9SKrishna Gudipati return &vport->lport; 5882a36c61f9SKrishna Gudipati 5883a36c61f9SKrishna Gudipati return NULL; 5884a36c61f9SKrishna Gudipati } 5885a36c61f9SKrishna Gudipati 5886a36c61f9SKrishna Gudipati /* 5887a36c61f9SKrishna Gudipati * API corresponding to NPIV_VPORT_GETINFO. 5888a36c61f9SKrishna Gudipati */ 5889a36c61f9SKrishna Gudipati void 5890a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port, 5891a36c61f9SKrishna Gudipati struct bfa_lport_info_s *port_info) 5892a36c61f9SKrishna Gudipati { 5893a36c61f9SKrishna Gudipati 5894a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->fabric->fabric_name); 5895a36c61f9SKrishna Gudipati 5896a36c61f9SKrishna Gudipati if (port->vport == NULL) { 5897a36c61f9SKrishna Gudipati /* 5898a36c61f9SKrishna Gudipati * This is a Physical port 5899a36c61f9SKrishna Gudipati */ 5900a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_PHYSICAL; 5901a36c61f9SKrishna Gudipati 5902a36c61f9SKrishna Gudipati /* 5903a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5904a36c61f9SKrishna Gudipati */ 5905a36c61f9SKrishna Gudipati port_info->port_state = 0; 5906a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5907a36c61f9SKrishna Gudipati 5908a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5909a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5910a36c61f9SKrishna Gudipati 5911a36c61f9SKrishna Gudipati port_info->max_vports_supp = 5912a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(port->fcs->bfa); 5913a36c61f9SKrishna Gudipati port_info->num_vports_inuse = 5914f7f73812SMaggie Zhang port->fabric->num_vports; 5915a36c61f9SKrishna Gudipati port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; 5916a36c61f9SKrishna Gudipati port_info->num_rports_inuse = port->num_rports; 5917a36c61f9SKrishna Gudipati } else { 5918a36c61f9SKrishna Gudipati /* 5919a36c61f9SKrishna Gudipati * This is a virtual port 5920a36c61f9SKrishna Gudipati */ 5921a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_VIRTUAL; 5922a36c61f9SKrishna Gudipati 5923a36c61f9SKrishna Gudipati /* 5924a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 5925a36c61f9SKrishna Gudipati */ 5926a36c61f9SKrishna Gudipati port_info->port_state = 0; 5927a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 5928a36c61f9SKrishna Gudipati 5929a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5930a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5931a36c61f9SKrishna Gudipati } 5932a36c61f9SKrishna Gudipati } 5933a36c61f9SKrishna Gudipati 5934a36c61f9SKrishna Gudipati void 5935a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port, 5936a36c61f9SKrishna Gudipati struct bfa_lport_stats_s *port_stats) 5937a36c61f9SKrishna Gudipati { 5938a36c61f9SKrishna Gudipati *port_stats = fcs_port->stats; 5939a36c61f9SKrishna Gudipati } 5940a36c61f9SKrishna Gudipati 5941a36c61f9SKrishna Gudipati void 5942a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) 5943a36c61f9SKrishna Gudipati { 59446a18b167SJing Huang memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s)); 5945a36c61f9SKrishna Gudipati } 5946a36c61f9SKrishna Gudipati 59475fbe25c7SJing Huang /* 5948bc0e2c2aSKrishna Gudipati * Let new loop map create missing rports 5949bc0e2c2aSKrishna Gudipati */ 5950bc0e2c2aSKrishna Gudipati void 5951bc0e2c2aSKrishna Gudipati bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port) 5952bc0e2c2aSKrishna Gudipati { 5953bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_online(port); 5954bc0e2c2aSKrishna Gudipati } 5955bc0e2c2aSKrishna Gudipati 5956bc0e2c2aSKrishna Gudipati /* 5957a36c61f9SKrishna Gudipati * FCS virtual port state machine 5958a36c61f9SKrishna Gudipati */ 5959a36c61f9SKrishna Gudipati 5960a36c61f9SKrishna Gudipati #define __vport_fcs(__vp) ((__vp)->lport.fcs) 5961a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn) 5962a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn) 5963a36c61f9SKrishna Gudipati #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa) 5964a36c61f9SKrishna Gudipati #define __vport_fcid(__vp) ((__vp)->lport.pid) 5965a36c61f9SKrishna Gudipati #define __vport_fabric(__vp) ((__vp)->lport.fabric) 5966a36c61f9SKrishna Gudipati #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id) 5967a36c61f9SKrishna Gudipati 5968a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES 5 5969a36c61f9SKrishna Gudipati /* 5970a36c61f9SKrishna Gudipati * Forward declarations 5971a36c61f9SKrishna Gudipati */ 5972a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport); 5973a36c61f9SKrishna Gudipati static void bfa_fcs_vport_timeout(void *vport_arg); 5974a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport); 5975a36c61f9SKrishna Gudipati static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport); 5976a36c61f9SKrishna Gudipati 59775fbe25c7SJing Huang /* 5978a36c61f9SKrishna Gudipati * fcs_vport_sm FCS virtual port state machine 5979a36c61f9SKrishna Gudipati */ 5980a36c61f9SKrishna Gudipati 59815fbe25c7SJing Huang /* 5982a36c61f9SKrishna Gudipati * VPort State Machine events 5983a36c61f9SKrishna Gudipati */ 5984a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event { 5985a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */ 5986a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */ 5987a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_START = 3, /* vport start request */ 5988a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */ 5989a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */ 5990a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */ 5991a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */ 5992a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */ 5993a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */ 5994a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */ 5995a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ 5996a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ 5997a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ 5998dd5aaf45SKrishna Gudipati BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ 5999f2a0cc3fSVijaya Mohan Guvva BFA_FCS_VPORT_SM_FABRIC_MAX = 15, /* max vports on fabric */ 6000a36c61f9SKrishna Gudipati }; 6001a36c61f9SKrishna Gudipati 6002a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 6003a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6004a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 6005a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6006a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 6007a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6008a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 6009a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6010a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 6011a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6012d7be54ccSKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 6013d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event); 6014a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 6015a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6016a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 6017a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6018a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 6019a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6020a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 6021a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6022a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 6023a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 6024dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 6025dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 6026dd5aaf45SKrishna Gudipati static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 6027dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event); 6028a36c61f9SKrishna Gudipati 6029a36c61f9SKrishna Gudipati static struct bfa_sm_table_s vport_sm_table[] = { 6030a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, 6031a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED}, 6032a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, 6033a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, 6034a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, 6035d7be54ccSKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT}, 6036a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, 6037a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, 6038a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, 6039a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO}, 6040a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR} 6041a36c61f9SKrishna Gudipati }; 6042a36c61f9SKrishna Gudipati 60435fbe25c7SJing Huang /* 6044a36c61f9SKrishna Gudipati * Beginning state. 6045a36c61f9SKrishna Gudipati */ 6046a36c61f9SKrishna Gudipati static void 6047a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 6048a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6049a36c61f9SKrishna Gudipati { 6050a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6051a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6052a36c61f9SKrishna Gudipati 6053a36c61f9SKrishna Gudipati switch (event) { 6054a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_CREATE: 6055a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 6056a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(__vport_fabric(vport), vport); 6057a36c61f9SKrishna Gudipati break; 6058a36c61f9SKrishna Gudipati 6059a36c61f9SKrishna Gudipati default: 6060a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6061a36c61f9SKrishna Gudipati } 6062a36c61f9SKrishna Gudipati } 6063a36c61f9SKrishna Gudipati 60645fbe25c7SJing Huang /* 6065a36c61f9SKrishna Gudipati * Created state - a start event is required to start up the state machine. 6066a36c61f9SKrishna Gudipati */ 6067a36c61f9SKrishna Gudipati static void 6068a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 6069a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6070a36c61f9SKrishna Gudipati { 6071a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6072a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6073a36c61f9SKrishna Gudipati 6074a36c61f9SKrishna Gudipati switch (event) { 6075a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_START: 6076f7f73812SMaggie Zhang if (bfa_sm_cmp_state(__vport_fabric(vport), 6077f7f73812SMaggie Zhang bfa_fcs_fabric_sm_online) 6078a36c61f9SKrishna Gudipati && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) { 6079a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 6080a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 6081a36c61f9SKrishna Gudipati } else { 60825fbe25c7SJing Huang /* 6083a36c61f9SKrishna Gudipati * Fabric is offline or not NPIV capable, stay in 6084a36c61f9SKrishna Gudipati * offline state. 6085a36c61f9SKrishna Gudipati */ 6086a36c61f9SKrishna Gudipati vport->vport_stats.fab_no_npiv++; 6087a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6088a36c61f9SKrishna Gudipati } 6089a36c61f9SKrishna Gudipati break; 6090a36c61f9SKrishna Gudipati 6091a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6092a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6093a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6094a36c61f9SKrishna Gudipati break; 6095a36c61f9SKrishna Gudipati 6096a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 6097a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 60985fbe25c7SJing Huang /* 6099a36c61f9SKrishna Gudipati * Ignore ONLINE/OFFLINE events from fabric 6100a36c61f9SKrishna Gudipati * till vport is started. 6101a36c61f9SKrishna Gudipati */ 6102a36c61f9SKrishna Gudipati break; 6103a36c61f9SKrishna Gudipati 6104a36c61f9SKrishna Gudipati default: 6105a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6106a36c61f9SKrishna Gudipati } 6107a36c61f9SKrishna Gudipati } 6108a36c61f9SKrishna Gudipati 61095fbe25c7SJing Huang /* 6110a36c61f9SKrishna Gudipati * Offline state - awaiting ONLINE event from fabric SM. 6111a36c61f9SKrishna Gudipati */ 6112a36c61f9SKrishna Gudipati static void 6113a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 6114a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6115a36c61f9SKrishna Gudipati { 6116a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6117a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6118a36c61f9SKrishna Gudipati 6119a36c61f9SKrishna Gudipati switch (event) { 6120a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6121a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6122a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6123a36c61f9SKrishna Gudipati break; 6124a36c61f9SKrishna Gudipati 6125a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 6126a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 6127a36c61f9SKrishna Gudipati vport->fdisc_retries = 0; 6128a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 6129a36c61f9SKrishna Gudipati break; 6130a36c61f9SKrishna Gudipati 6131dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 6132dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6133dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 6134dd5aaf45SKrishna Gudipati break; 6135dd5aaf45SKrishna Gudipati 6136a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6137a36c61f9SKrishna Gudipati /* 6138a36c61f9SKrishna Gudipati * This can happen if the vport couldn't be initialzied 6139a36c61f9SKrishna Gudipati * due the fact that the npiv was not enabled on the switch. 6140a36c61f9SKrishna Gudipati * In that case we will put the vport in offline state. 6141a36c61f9SKrishna Gudipati * However, the link can go down and cause the this event to 6142a36c61f9SKrishna Gudipati * be sent when we are already offline. Ignore it. 6143a36c61f9SKrishna Gudipati */ 6144a36c61f9SKrishna Gudipati break; 6145a36c61f9SKrishna Gudipati 6146a36c61f9SKrishna Gudipati default: 6147a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6148a36c61f9SKrishna Gudipati } 6149a36c61f9SKrishna Gudipati } 6150a36c61f9SKrishna Gudipati 6151a36c61f9SKrishna Gudipati 61525fbe25c7SJing Huang /* 6153a36c61f9SKrishna Gudipati * FDISC is sent and awaiting reply from fabric. 6154a36c61f9SKrishna Gudipati */ 6155a36c61f9SKrishna Gudipati static void 6156a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 6157a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6158a36c61f9SKrishna Gudipati { 6159a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6160a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6161a36c61f9SKrishna Gudipati 6162a36c61f9SKrishna Gudipati switch (event) { 6163a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6164d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait); 6165a36c61f9SKrishna Gudipati break; 6166a36c61f9SKrishna Gudipati 6167a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6168a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6169f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6170a36c61f9SKrishna Gudipati break; 6171a36c61f9SKrishna Gudipati 6172a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6173a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_online); 6174a36c61f9SKrishna Gudipati bfa_fcs_lport_online(&vport->lport); 6175a36c61f9SKrishna Gudipati break; 6176a36c61f9SKrishna Gudipati 6177a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6178a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry); 6179a36c61f9SKrishna Gudipati bfa_timer_start(__vport_bfa(vport), &vport->timer, 6180a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout, vport, 6181a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 6182a36c61f9SKrishna Gudipati break; 6183a36c61f9SKrishna Gudipati 6184a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 6185f2a0cc3fSVijaya Mohan Guvva case BFA_FCS_VPORT_SM_FABRIC_MAX: 6186a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6187a36c61f9SKrishna Gudipati break; 6188a36c61f9SKrishna Gudipati 6189a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 6190a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_error); 6191a36c61f9SKrishna Gudipati break; 6192a36c61f9SKrishna Gudipati 6193a36c61f9SKrishna Gudipati default: 6194a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6195a36c61f9SKrishna Gudipati } 6196a36c61f9SKrishna Gudipati } 6197a36c61f9SKrishna Gudipati 61985fbe25c7SJing Huang /* 6199a36c61f9SKrishna Gudipati * FDISC attempt failed - a timer is active to retry FDISC. 6200a36c61f9SKrishna Gudipati */ 6201a36c61f9SKrishna Gudipati static void 6202a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 6203a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6204a36c61f9SKrishna Gudipati { 6205a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6206a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6207a36c61f9SKrishna Gudipati 6208a36c61f9SKrishna Gudipati switch (event) { 6209a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6210a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6211a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 6212a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6213a36c61f9SKrishna Gudipati break; 6214a36c61f9SKrishna Gudipati 6215a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6216a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6217a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 6218a36c61f9SKrishna Gudipati break; 6219a36c61f9SKrishna Gudipati 6220a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_TIMEOUT: 6221a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 6222a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_retries++; 6223a36c61f9SKrishna Gudipati vport->fdisc_retries++; 6224a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 6225a36c61f9SKrishna Gudipati break; 6226a36c61f9SKrishna Gudipati 6227a36c61f9SKrishna Gudipati default: 6228a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6229a36c61f9SKrishna Gudipati } 6230a36c61f9SKrishna Gudipati } 6231a36c61f9SKrishna Gudipati 62325fbe25c7SJing Huang /* 6233d7be54ccSKrishna Gudipati * FDISC is in progress and we got a vport delete request - 6234d7be54ccSKrishna Gudipati * this is a wait state while we wait for fdisc response and 6235d7be54ccSKrishna Gudipati * we will transition to the appropriate state - on rsp status. 6236d7be54ccSKrishna Gudipati */ 6237d7be54ccSKrishna Gudipati static void 6238d7be54ccSKrishna Gudipati bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 6239d7be54ccSKrishna Gudipati enum bfa_fcs_vport_event event) 6240d7be54ccSKrishna Gudipati { 6241d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6242d7be54ccSKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6243d7be54ccSKrishna Gudipati 6244d7be54ccSKrishna Gudipati switch (event) { 6245d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6246d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 6247d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6248d7be54ccSKrishna Gudipati break; 6249d7be54ccSKrishna Gudipati 6250d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6251d7be54ccSKrishna Gudipati break; 6252d7be54ccSKrishna Gudipati 6253d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6254d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6255d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 6256f2a0cc3fSVijaya Mohan Guvva case BFA_FCS_VPORT_SM_FABRIC_MAX: 6257d7be54ccSKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 6258d7be54ccSKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6259d7be54ccSKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6260d7be54ccSKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6261d7be54ccSKrishna Gudipati break; 6262d7be54ccSKrishna Gudipati 6263d7be54ccSKrishna Gudipati default: 6264d7be54ccSKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6265d7be54ccSKrishna Gudipati } 6266d7be54ccSKrishna Gudipati } 6267d7be54ccSKrishna Gudipati 6268d7be54ccSKrishna Gudipati /* 6269a36c61f9SKrishna Gudipati * Vport is online (FDISC is complete). 6270a36c61f9SKrishna Gudipati */ 6271a36c61f9SKrishna Gudipati static void 6272a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 6273a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6274a36c61f9SKrishna Gudipati { 6275a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6276a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6277a36c61f9SKrishna Gudipati 6278a36c61f9SKrishna Gudipati switch (event) { 6279a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6280a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 6281a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6282a36c61f9SKrishna Gudipati break; 6283a36c61f9SKrishna Gudipati 6284dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOP: 6285dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping); 6286dd5aaf45SKrishna Gudipati bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 6287dd5aaf45SKrishna Gudipati break; 6288dd5aaf45SKrishna Gudipati 6289a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6290a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 6291f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6292a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(&vport->lport); 6293a36c61f9SKrishna Gudipati break; 6294a36c61f9SKrishna Gudipati 6295a36c61f9SKrishna Gudipati default: 6296a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6297a36c61f9SKrishna Gudipati } 6298a36c61f9SKrishna Gudipati } 6299a36c61f9SKrishna Gudipati 63005fbe25c7SJing Huang /* 6301dd5aaf45SKrishna Gudipati * Vport is being stopped - awaiting lport stop completion to send 6302dd5aaf45SKrishna Gudipati * LOGO to fabric. 6303dd5aaf45SKrishna Gudipati */ 6304dd5aaf45SKrishna Gudipati static void 6305dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 6306dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 6307dd5aaf45SKrishna Gudipati { 6308dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6309dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6310dd5aaf45SKrishna Gudipati 6311dd5aaf45SKrishna Gudipati switch (event) { 6312dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 6313dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop); 6314dd5aaf45SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 6315dd5aaf45SKrishna Gudipati break; 6316dd5aaf45SKrishna Gudipati 6317dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6318dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6319dd5aaf45SKrishna Gudipati break; 6320dd5aaf45SKrishna Gudipati 6321dd5aaf45SKrishna Gudipati default: 6322dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6323dd5aaf45SKrishna Gudipati } 6324dd5aaf45SKrishna Gudipati } 6325dd5aaf45SKrishna Gudipati 6326dd5aaf45SKrishna Gudipati /* 6327a36c61f9SKrishna Gudipati * Vport is being deleted - awaiting lport delete completion to send 6328a36c61f9SKrishna Gudipati * LOGO to fabric. 6329a36c61f9SKrishna Gudipati */ 6330a36c61f9SKrishna Gudipati static void 6331a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 6332a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6333a36c61f9SKrishna Gudipati { 6334a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6335a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6336a36c61f9SKrishna Gudipati 6337a36c61f9SKrishna Gudipati switch (event) { 6338a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6339a36c61f9SKrishna Gudipati break; 6340a36c61f9SKrishna Gudipati 6341a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 6342a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); 6343a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 6344a36c61f9SKrishna Gudipati break; 6345a36c61f9SKrishna Gudipati 6346a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6347a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6348a36c61f9SKrishna Gudipati break; 6349a36c61f9SKrishna Gudipati 6350a36c61f9SKrishna Gudipati default: 6351a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6352a36c61f9SKrishna Gudipati } 6353a36c61f9SKrishna Gudipati } 6354a36c61f9SKrishna Gudipati 63555fbe25c7SJing Huang /* 6356a36c61f9SKrishna Gudipati * Error State. 6357a36c61f9SKrishna Gudipati * This state will be set when the Vport Creation fails due 6358a36c61f9SKrishna Gudipati * to errors like Dup WWN. In this state only operation allowed 6359a36c61f9SKrishna Gudipati * is a Vport Delete. 6360a36c61f9SKrishna Gudipati */ 6361a36c61f9SKrishna Gudipati static void 6362a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 6363a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6364a36c61f9SKrishna Gudipati { 6365a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6366a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6367a36c61f9SKrishna Gudipati 6368a36c61f9SKrishna Gudipati switch (event) { 6369a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6370a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 6371a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 6372a36c61f9SKrishna Gudipati break; 6373a36c61f9SKrishna Gudipati 6374a36c61f9SKrishna Gudipati default: 6375a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6376a36c61f9SKrishna Gudipati } 6377a36c61f9SKrishna Gudipati } 6378a36c61f9SKrishna Gudipati 63795fbe25c7SJing Huang /* 6380a36c61f9SKrishna Gudipati * Lport cleanup is in progress since vport is being deleted. Fabric is 6381a36c61f9SKrishna Gudipati * offline, so no LOGO is needed to complete vport deletion. 6382a36c61f9SKrishna Gudipati */ 6383a36c61f9SKrishna Gudipati static void 6384a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 6385a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6386a36c61f9SKrishna Gudipati { 6387a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6388a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6389a36c61f9SKrishna Gudipati 6390a36c61f9SKrishna Gudipati switch (event) { 6391a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 6392a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 6393a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 6394a36c61f9SKrishna Gudipati break; 6395a36c61f9SKrishna Gudipati 6396dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_STOPCOMP: 6397dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 6398dd5aaf45SKrishna Gudipati break; 6399dd5aaf45SKrishna Gudipati 6400a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6401a36c61f9SKrishna Gudipati break; 6402a36c61f9SKrishna Gudipati 6403a36c61f9SKrishna Gudipati default: 6404a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6405a36c61f9SKrishna Gudipati } 6406a36c61f9SKrishna Gudipati } 6407a36c61f9SKrishna Gudipati 64085fbe25c7SJing Huang /* 6409dd5aaf45SKrishna Gudipati * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup 6410dd5aaf45SKrishna Gudipati * is done. 6411dd5aaf45SKrishna Gudipati */ 6412dd5aaf45SKrishna Gudipati static void 6413dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 6414dd5aaf45SKrishna Gudipati enum bfa_fcs_vport_event event) 6415dd5aaf45SKrishna Gudipati { 6416dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6417dd5aaf45SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6418dd5aaf45SKrishna Gudipati 6419dd5aaf45SKrishna Gudipati switch (event) { 6420dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6421dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6422dd5aaf45SKrishna Gudipati /* 6423dd5aaf45SKrishna Gudipati * !!! fall through !!! 6424dd5aaf45SKrishna Gudipati */ 6425dd5aaf45SKrishna Gudipati 6426dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6427dd5aaf45SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6428dd5aaf45SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 6429dd5aaf45SKrishna Gudipati break; 6430dd5aaf45SKrishna Gudipati 6431dd5aaf45SKrishna Gudipati default: 6432dd5aaf45SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6433dd5aaf45SKrishna Gudipati } 6434dd5aaf45SKrishna Gudipati } 6435dd5aaf45SKrishna Gudipati 6436dd5aaf45SKrishna Gudipati /* 6437a36c61f9SKrishna Gudipati * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup 6438a36c61f9SKrishna Gudipati * is done. 6439a36c61f9SKrishna Gudipati */ 6440a36c61f9SKrishna Gudipati static void 6441a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 6442a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 6443a36c61f9SKrishna Gudipati { 6444a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6445a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 6446a36c61f9SKrishna Gudipati 6447a36c61f9SKrishna Gudipati switch (event) { 6448a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 6449f7f73812SMaggie Zhang bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 6450a36c61f9SKrishna Gudipati /* 6451a36c61f9SKrishna Gudipati * !!! fall through !!! 6452a36c61f9SKrishna Gudipati */ 6453a36c61f9SKrishna Gudipati 6454a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 6455a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 6456a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 6457a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 6458a36c61f9SKrishna Gudipati break; 6459a36c61f9SKrishna Gudipati 6460a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 6461a36c61f9SKrishna Gudipati break; 6462a36c61f9SKrishna Gudipati 6463a36c61f9SKrishna Gudipati default: 6464a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 6465a36c61f9SKrishna Gudipati } 6466a36c61f9SKrishna Gudipati } 6467a36c61f9SKrishna Gudipati 6468a36c61f9SKrishna Gudipati 6469a36c61f9SKrishna Gudipati 64705fbe25c7SJing Huang /* 6471a36c61f9SKrishna Gudipati * fcs_vport_private FCS virtual port private functions 6472a36c61f9SKrishna Gudipati */ 64735fbe25c7SJing Huang /* 64747826f304SKrishna Gudipati * Send AEN notification 64757826f304SKrishna Gudipati */ 64767826f304SKrishna Gudipati static void 64777826f304SKrishna Gudipati bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port, 64787826f304SKrishna Gudipati enum bfa_lport_aen_event event) 64797826f304SKrishna Gudipati { 64807826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad; 64817826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 64827826f304SKrishna Gudipati 64837826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 64847826f304SKrishna Gudipati if (!aen_entry) 64857826f304SKrishna Gudipati return; 64867826f304SKrishna Gudipati 64877826f304SKrishna Gudipati aen_entry->aen_data.lport.vf_id = port->fabric->vf_id; 64887826f304SKrishna Gudipati aen_entry->aen_data.lport.roles = port->port_cfg.roles; 64897826f304SKrishna Gudipati aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn( 64907826f304SKrishna Gudipati bfa_fcs_get_base_port(port->fcs)); 64917826f304SKrishna Gudipati aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port); 64927826f304SKrishna Gudipati 64937826f304SKrishna Gudipati /* Send the AEN notification */ 64947826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq, 64957826f304SKrishna Gudipati BFA_AEN_CAT_LPORT, event); 64967826f304SKrishna Gudipati } 64977826f304SKrishna Gudipati 64987826f304SKrishna Gudipati /* 6499a36c61f9SKrishna Gudipati * This routine will be called to send a FDISC command. 6500a36c61f9SKrishna Gudipati */ 6501a36c61f9SKrishna Gudipati static void 6502a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) 6503a36c61f9SKrishna Gudipati { 6504a36c61f9SKrishna Gudipati bfa_lps_fdisc(vport->lps, vport, 6505a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(__vport_bfa(vport)), 6506a36c61f9SKrishna Gudipati __vport_pwwn(vport), __vport_nwwn(vport)); 6507a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_sent++; 6508a36c61f9SKrishna Gudipati } 6509a36c61f9SKrishna Gudipati 6510a36c61f9SKrishna Gudipati static void 6511a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) 6512a36c61f9SKrishna Gudipati { 6513f7f73812SMaggie Zhang u8 lsrjt_rsn = vport->lps->lsrjt_rsn; 6514f7f73812SMaggie Zhang u8 lsrjt_expl = vport->lps->lsrjt_expl; 6515a36c61f9SKrishna Gudipati 6516a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_rsn); 6517a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_expl); 6518a36c61f9SKrishna Gudipati 6519a36c61f9SKrishna Gudipati /* For certain reason codes, we don't want to retry. */ 6520f7f73812SMaggie Zhang switch (vport->lps->lsrjt_expl) { 6521a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */ 6522a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ 6523a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6524a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 65257826f304SKrishna Gudipati else { 65267826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 65277826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_DUP_WWN); 6528a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); 65297826f304SKrishna Gudipati } 6530a36c61f9SKrishna Gudipati break; 6531a36c61f9SKrishna Gudipati 6532a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INSUFF_RES: 6533a36c61f9SKrishna Gudipati /* 6534a36c61f9SKrishna Gudipati * This means max logins per port/switch setting on the 6535a36c61f9SKrishna Gudipati * switch was exceeded. 6536a36c61f9SKrishna Gudipati */ 6537a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6538a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 65397826f304SKrishna Gudipati else { 65407826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 65417826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_FABRIC_MAX); 6542f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_FABRIC_MAX); 65437826f304SKrishna Gudipati } 6544a36c61f9SKrishna Gudipati break; 6545a36c61f9SKrishna Gudipati 6546a36c61f9SKrishna Gudipati default: 65477826f304SKrishna Gudipati if (vport->fdisc_retries == 0) 65487826f304SKrishna Gudipati bfa_fcs_vport_aen_post(&vport->lport, 65497826f304SKrishna Gudipati BFA_LPORT_AEN_NPIV_UNKNOWN); 6550a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6551a36c61f9SKrishna Gudipati } 6552a36c61f9SKrishna Gudipati } 6553a36c61f9SKrishna Gudipati 65545fbe25c7SJing Huang /* 6555a36c61f9SKrishna Gudipati * Called to send a logout to the fabric. Used when a V-Port is 6556a36c61f9SKrishna Gudipati * deleted/stopped. 6557a36c61f9SKrishna Gudipati */ 6558a36c61f9SKrishna Gudipati static void 6559a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport) 6560a36c61f9SKrishna Gudipati { 6561a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6562a36c61f9SKrishna Gudipati 6563a36c61f9SKrishna Gudipati vport->vport_stats.logo_sent++; 6564a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(vport->lps); 6565a36c61f9SKrishna Gudipati } 6566a36c61f9SKrishna Gudipati 6567a36c61f9SKrishna Gudipati 65685fbe25c7SJing Huang /* 6569a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 6570a36c61f9SKrishna Gudipati * 6571a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6572a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 6573a36c61f9SKrishna Gudipati * 6574a36c61f9SKrishna Gudipati * return 6575a36c61f9SKrishna Gudipati * void 6576a36c61f9SKrishna Gudipati * 6577a36c61f9SKrishna Gudipati * Special Considerations: 6578a36c61f9SKrishna Gudipati * 6579a36c61f9SKrishna Gudipati * note 6580a36c61f9SKrishna Gudipati */ 6581a36c61f9SKrishna Gudipati static void 6582a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg) 6583a36c61f9SKrishna Gudipati { 6584a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg; 6585a36c61f9SKrishna Gudipati 6586a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_timeouts++; 6587a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT); 6588a36c61f9SKrishna Gudipati } 6589a36c61f9SKrishna Gudipati 6590a36c61f9SKrishna Gudipati static void 6591a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) 6592a36c61f9SKrishna Gudipati { 6593a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv = 6594a36c61f9SKrishna Gudipati (struct bfad_vport_s *)vport->vport_drv; 6595a36c61f9SKrishna Gudipati 6596a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); 6597a36c61f9SKrishna Gudipati bfa_lps_delete(vport->lps); 659817c201b3SKrishna Gudipati 659917c201b3SKrishna Gudipati if (vport_drv->comp_del) { 660017c201b3SKrishna Gudipati complete(vport_drv->comp_del); 660117c201b3SKrishna Gudipati return; 6602a36c61f9SKrishna Gudipati } 6603a36c61f9SKrishna Gudipati 660417c201b3SKrishna Gudipati /* 660517c201b3SKrishna Gudipati * We queue the vport delete work to the IM work_q from here. 660617c201b3SKrishna Gudipati * The memory for the bfad_vport_s is freed from the FC function 660717c201b3SKrishna Gudipati * template vport_delete entry point. 660817c201b3SKrishna Gudipati */ 6609529f9a76SKrishna Gudipati bfad_im_port_delete(vport_drv->drv_port.bfad, &vport_drv->drv_port); 661017c201b3SKrishna Gudipati } 6611a36c61f9SKrishna Gudipati 66125fbe25c7SJing Huang /* 6613a36c61f9SKrishna Gudipati * fcs_vport_public FCS virtual port public interfaces 6614a36c61f9SKrishna Gudipati */ 6615a36c61f9SKrishna Gudipati 66165fbe25c7SJing Huang /* 6617a36c61f9SKrishna Gudipati * Online notification from fabric SM. 6618a36c61f9SKrishna Gudipati */ 6619a36c61f9SKrishna Gudipati void 6620a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) 6621a36c61f9SKrishna Gudipati { 6622a36c61f9SKrishna Gudipati vport->vport_stats.fab_online++; 6623d7be54ccSKrishna Gudipati if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) 6624a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 6625d7be54ccSKrishna Gudipati else 6626d7be54ccSKrishna Gudipati vport->vport_stats.fab_no_npiv++; 6627a36c61f9SKrishna Gudipati } 6628a36c61f9SKrishna Gudipati 66295fbe25c7SJing Huang /* 6630a36c61f9SKrishna Gudipati * Offline notification from fabric SM. 6631a36c61f9SKrishna Gudipati */ 6632a36c61f9SKrishna Gudipati void 6633a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport) 6634a36c61f9SKrishna Gudipati { 6635a36c61f9SKrishna Gudipati vport->vport_stats.fab_offline++; 6636a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 6637a36c61f9SKrishna Gudipati } 6638a36c61f9SKrishna Gudipati 66395fbe25c7SJing Huang /* 6640a36c61f9SKrishna Gudipati * Cleanup notification from fabric SM on link timer expiry. 6641a36c61f9SKrishna Gudipati */ 6642a36c61f9SKrishna Gudipati void 6643a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) 6644a36c61f9SKrishna Gudipati { 6645a36c61f9SKrishna Gudipati vport->vport_stats.fab_cleanup++; 6646a36c61f9SKrishna Gudipati } 6647881c1b3cSKrishna Gudipati 6648881c1b3cSKrishna Gudipati /* 6649881c1b3cSKrishna Gudipati * Stop notification from fabric SM. To be invoked from within FCS. 6650881c1b3cSKrishna Gudipati */ 6651881c1b3cSKrishna Gudipati void 6652881c1b3cSKrishna Gudipati bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport) 6653881c1b3cSKrishna Gudipati { 6654881c1b3cSKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 6655881c1b3cSKrishna Gudipati } 6656881c1b3cSKrishna Gudipati 66575fbe25c7SJing Huang /* 6658a36c61f9SKrishna Gudipati * delete notification from fabric SM. To be invoked from within FCS. 6659a36c61f9SKrishna Gudipati */ 6660a36c61f9SKrishna Gudipati void 6661a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) 6662a36c61f9SKrishna Gudipati { 6663a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 6664a36c61f9SKrishna Gudipati } 6665a36c61f9SKrishna Gudipati 66665fbe25c7SJing Huang /* 6667dd5aaf45SKrishna Gudipati * Stop completion callback from associated lport 6668dd5aaf45SKrishna Gudipati */ 6669dd5aaf45SKrishna Gudipati void 6670dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport) 6671dd5aaf45SKrishna Gudipati { 6672dd5aaf45SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP); 6673dd5aaf45SKrishna Gudipati } 6674dd5aaf45SKrishna Gudipati 6675dd5aaf45SKrishna Gudipati /* 6676a36c61f9SKrishna Gudipati * Delete completion callback from associated lport 6677a36c61f9SKrishna Gudipati */ 6678a36c61f9SKrishna Gudipati void 6679a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) 6680a36c61f9SKrishna Gudipati { 6681a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); 6682a36c61f9SKrishna Gudipati } 6683a36c61f9SKrishna Gudipati 6684a36c61f9SKrishna Gudipati 6685a36c61f9SKrishna Gudipati 66865fbe25c7SJing Huang /* 6687a36c61f9SKrishna Gudipati * fcs_vport_api Virtual port API 6688a36c61f9SKrishna Gudipati */ 6689a36c61f9SKrishna Gudipati 66905fbe25c7SJing Huang /* 6691a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS vport object. This 6692a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 6693a36c61f9SKrishna Gudipati * done in vport_start() call) 6694a36c61f9SKrishna Gudipati * 6695a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 6696a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 6697a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 6698a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 6699a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 6700a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 6701a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 6702a36c61f9SKrishna Gudipati * structure 6703a36c61f9SKrishna Gudipati * 6704a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 6705a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 6706a36c61f9SKrishna Gudipati */ 6707a36c61f9SKrishna Gudipati bfa_status_t 6708a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 6709a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 6710a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 6711a36c61f9SKrishna Gudipati { 6712a36c61f9SKrishna Gudipati if (vport_cfg->pwwn == 0) 6713a36c61f9SKrishna Gudipati return BFA_STATUS_INVALID_WWN; 6714a36c61f9SKrishna Gudipati 6715a36c61f9SKrishna Gudipati if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn) 6716a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_WWN_BP; 6717a36c61f9SKrishna Gudipati 6718a36c61f9SKrishna Gudipati if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL) 6719a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_EXISTS; 6720a36c61f9SKrishna Gudipati 6721f7f73812SMaggie Zhang if (fcs->fabric.num_vports == 6722a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(fcs->bfa)) 6723a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 6724a36c61f9SKrishna Gudipati 6725a36c61f9SKrishna Gudipati vport->lps = bfa_lps_alloc(fcs->bfa); 6726a36c61f9SKrishna Gudipati if (!vport->lps) 6727a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 6728a36c61f9SKrishna Gudipati 6729a36c61f9SKrishna Gudipati vport->vport_drv = vport_drv; 6730a36c61f9SKrishna Gudipati vport_cfg->preboot_vp = BFA_FALSE; 6731a36c61f9SKrishna Gudipati 6732a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 6733a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); 6734a36c61f9SKrishna Gudipati bfa_fcs_lport_init(&vport->lport, vport_cfg); 6735a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); 6736a36c61f9SKrishna Gudipati 6737a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6738a36c61f9SKrishna Gudipati } 6739a36c61f9SKrishna Gudipati 67405fbe25c7SJing Huang /* 6741a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS PBC vport object. This 6742a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 6743a36c61f9SKrishna Gudipati * done in vport_start() call) 6744a36c61f9SKrishna Gudipati * 6745a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 6746a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 6747a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 6748a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 6749a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 6750a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 6751a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 6752a36c61f9SKrishna Gudipati * structure 6753a36c61f9SKrishna Gudipati * 6754a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 6755a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 6756a36c61f9SKrishna Gudipati */ 6757a36c61f9SKrishna Gudipati bfa_status_t 6758a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 6759a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 6760a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 6761a36c61f9SKrishna Gudipati { 6762a36c61f9SKrishna Gudipati bfa_status_t rc; 6763a36c61f9SKrishna Gudipati 6764a36c61f9SKrishna Gudipati rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv); 6765a36c61f9SKrishna Gudipati vport->lport.port_cfg.preboot_vp = BFA_TRUE; 6766a36c61f9SKrishna Gudipati 6767a36c61f9SKrishna Gudipati return rc; 6768a36c61f9SKrishna Gudipati } 6769a36c61f9SKrishna Gudipati 67705fbe25c7SJing Huang /* 6771a36c61f9SKrishna Gudipati * Use this function to findout if this is a pbc vport or not. 6772a36c61f9SKrishna Gudipati * 6773a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 6774a36c61f9SKrishna Gudipati * 6775a36c61f9SKrishna Gudipati * @returns None 6776a36c61f9SKrishna Gudipati */ 6777a36c61f9SKrishna Gudipati bfa_boolean_t 6778a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport) 6779a36c61f9SKrishna Gudipati { 6780a36c61f9SKrishna Gudipati 6781a36c61f9SKrishna Gudipati if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE)) 6782a36c61f9SKrishna Gudipati return BFA_TRUE; 6783a36c61f9SKrishna Gudipati else 6784a36c61f9SKrishna Gudipati return BFA_FALSE; 6785a36c61f9SKrishna Gudipati 6786a36c61f9SKrishna Gudipati } 6787a36c61f9SKrishna Gudipati 67885fbe25c7SJing Huang /* 6789a36c61f9SKrishna Gudipati * Use this function initialize the vport. 6790a36c61f9SKrishna Gudipati * 6791a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 6792a36c61f9SKrishna Gudipati * 6793a36c61f9SKrishna Gudipati * @returns None 6794a36c61f9SKrishna Gudipati */ 6795a36c61f9SKrishna Gudipati bfa_status_t 6796a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport) 6797a36c61f9SKrishna Gudipati { 6798a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START); 6799a36c61f9SKrishna Gudipati 6800a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6801a36c61f9SKrishna Gudipati } 6802a36c61f9SKrishna Gudipati 68035fbe25c7SJing Huang /* 6804a36c61f9SKrishna Gudipati * Use this function quiese the vport object. This function will return 6805a36c61f9SKrishna Gudipati * immediately, when the vport is actually stopped, the 6806a36c61f9SKrishna Gudipati * bfa_drv_vport_stop_cb() will be called. 6807a36c61f9SKrishna Gudipati * 6808a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6809a36c61f9SKrishna Gudipati * 6810a36c61f9SKrishna Gudipati * return None 6811a36c61f9SKrishna Gudipati */ 6812a36c61f9SKrishna Gudipati bfa_status_t 6813a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) 6814a36c61f9SKrishna Gudipati { 6815a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 6816a36c61f9SKrishna Gudipati 6817a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6818a36c61f9SKrishna Gudipati } 6819a36c61f9SKrishna Gudipati 68205fbe25c7SJing Huang /* 6821a36c61f9SKrishna Gudipati * Use this function to delete a vport object. Fabric object should 6822a36c61f9SKrishna Gudipati * be stopped before this function call. 6823a36c61f9SKrishna Gudipati * 6824a36c61f9SKrishna Gudipati * !!!!!!! Donot invoke this from within FCS !!!!!!! 6825a36c61f9SKrishna Gudipati * 6826a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 6827a36c61f9SKrishna Gudipati * 6828a36c61f9SKrishna Gudipati * return None 6829a36c61f9SKrishna Gudipati */ 6830a36c61f9SKrishna Gudipati bfa_status_t 6831a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) 6832a36c61f9SKrishna Gudipati { 6833a36c61f9SKrishna Gudipati 6834a36c61f9SKrishna Gudipati if (vport->lport.port_cfg.preboot_vp) 6835a36c61f9SKrishna Gudipati return BFA_STATUS_PBC; 6836a36c61f9SKrishna Gudipati 6837a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 6838a36c61f9SKrishna Gudipati 6839a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 6840a36c61f9SKrishna Gudipati } 6841a36c61f9SKrishna Gudipati 68425fbe25c7SJing Huang /* 6843a36c61f9SKrishna Gudipati * Use this function to get vport's current status info. 6844a36c61f9SKrishna Gudipati * 6845a36c61f9SKrishna Gudipati * param[in] vport pointer to bfa_fcs_vport_t. 6846a36c61f9SKrishna Gudipati * param[out] attr pointer to return vport attributes 6847a36c61f9SKrishna Gudipati * 6848a36c61f9SKrishna Gudipati * return None 6849a36c61f9SKrishna Gudipati */ 6850a36c61f9SKrishna Gudipati void 6851a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, 6852a36c61f9SKrishna Gudipati struct bfa_vport_attr_s *attr) 6853a36c61f9SKrishna Gudipati { 6854a36c61f9SKrishna Gudipati if (vport == NULL || attr == NULL) 6855a36c61f9SKrishna Gudipati return; 6856a36c61f9SKrishna Gudipati 68576a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_vport_attr_s)); 6858a36c61f9SKrishna Gudipati 6859a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr); 6860a36c61f9SKrishna Gudipati attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm); 6861a36c61f9SKrishna Gudipati } 6862a36c61f9SKrishna Gudipati 6863a36c61f9SKrishna Gudipati 68645fbe25c7SJing Huang /* 6865a36c61f9SKrishna Gudipati * Lookup a virtual port. Excludes base port from lookup. 6866a36c61f9SKrishna Gudipati */ 6867a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s * 6868a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn) 6869a36c61f9SKrishna Gudipati { 6870a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 6871a36c61f9SKrishna Gudipati struct bfa_fcs_fabric_s *fabric; 6872a36c61f9SKrishna Gudipati 6873a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 6874a36c61f9SKrishna Gudipati bfa_trc(fcs, vpwwn); 6875a36c61f9SKrishna Gudipati 6876a36c61f9SKrishna Gudipati fabric = bfa_fcs_vf_lookup(fcs, vf_id); 6877a36c61f9SKrishna Gudipati if (!fabric) { 6878a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 6879a36c61f9SKrishna Gudipati return NULL; 6880a36c61f9SKrishna Gudipati } 6881a36c61f9SKrishna Gudipati 6882a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn); 6883a36c61f9SKrishna Gudipati return vport; 6884a36c61f9SKrishna Gudipati } 6885a36c61f9SKrishna Gudipati 68865fbe25c7SJing Huang /* 6887a36c61f9SKrishna Gudipati * FDISC Response 6888a36c61f9SKrishna Gudipati */ 6889a36c61f9SKrishna Gudipati void 6890a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) 6891a36c61f9SKrishna Gudipati { 6892a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6893a36c61f9SKrishna Gudipati 6894a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 6895a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), status); 6896a36c61f9SKrishna Gudipati 6897a36c61f9SKrishna Gudipati switch (status) { 6898a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 6899a36c61f9SKrishna Gudipati /* 6900b595076aSUwe Kleine-König * Initialize the V-Port fields 6901a36c61f9SKrishna Gudipati */ 6902f7f73812SMaggie Zhang __vport_fcid(vport) = vport->lps->lp_pid; 6903a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_accepts++; 6904a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6905a36c61f9SKrishna Gudipati break; 6906a36c61f9SKrishna Gudipati 6907a36c61f9SKrishna Gudipati case BFA_STATUS_INVALID_MAC: 6908a36c61f9SKrishna Gudipati /* Only for CNA */ 6909a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6910a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6911a36c61f9SKrishna Gudipati 6912a36c61f9SKrishna Gudipati break; 6913a36c61f9SKrishna Gudipati 6914a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 6915f7f73812SMaggie Zhang switch (vport->lps->ext_status) { 6916a36c61f9SKrishna Gudipati case BFA_EPROTO_BAD_ACCEPT: 6917a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 6918a36c61f9SKrishna Gudipati break; 6919a36c61f9SKrishna Gudipati 6920a36c61f9SKrishna Gudipati case BFA_EPROTO_UNKNOWN_RSP: 6921a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_unknown_rsp++; 6922a36c61f9SKrishna Gudipati break; 6923a36c61f9SKrishna Gudipati 6924a36c61f9SKrishna Gudipati default: 6925a36c61f9SKrishna Gudipati break; 6926a36c61f9SKrishna Gudipati } 6927a36c61f9SKrishna Gudipati 6928f2a0cc3fSVijaya Mohan Guvva if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6929a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6930f2a0cc3fSVijaya Mohan Guvva else 6931f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 6932f2a0cc3fSVijaya Mohan Guvva 6933f2a0cc3fSVijaya Mohan Guvva break; 6934f2a0cc3fSVijaya Mohan Guvva 6935f2a0cc3fSVijaya Mohan Guvva case BFA_STATUS_ETIMER: 6936f2a0cc3fSVijaya Mohan Guvva vport->vport_stats.fdisc_timeouts++; 6937f2a0cc3fSVijaya Mohan Guvva if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 6938f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6939f2a0cc3fSVijaya Mohan Guvva else 6940f2a0cc3fSVijaya Mohan Guvva bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 6941a36c61f9SKrishna Gudipati break; 6942a36c61f9SKrishna Gudipati 6943a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 6944a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rejects++; 6945a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(vport); 6946a36c61f9SKrishna Gudipati break; 6947a36c61f9SKrishna Gudipati 6948a36c61f9SKrishna Gudipati default: 6949a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rsp_err++; 6950a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 6951a36c61f9SKrishna Gudipati } 6952a36c61f9SKrishna Gudipati } 6953a36c61f9SKrishna Gudipati 69545fbe25c7SJing Huang /* 6955a36c61f9SKrishna Gudipati * LOGO response 6956a36c61f9SKrishna Gudipati */ 6957a36c61f9SKrishna Gudipati void 6958a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) 6959a36c61f9SKrishna Gudipati { 6960a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6961a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 6962a36c61f9SKrishna Gudipati } 6963a36c61f9SKrishna Gudipati 69645fbe25c7SJing Huang /* 6965a36c61f9SKrishna Gudipati * Received clear virtual link 6966a36c61f9SKrishna Gudipati */ 6967a36c61f9SKrishna Gudipati void 6968a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg) 6969a36c61f9SKrishna Gudipati { 6970a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 6971a36c61f9SKrishna Gudipati 6972a36c61f9SKrishna Gudipati /* Send an Offline followed by an ONLINE */ 6973a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 6974a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 6975a36c61f9SKrishna Gudipati } 6976