1a36c61f9SKrishna Gudipati /* 2a36c61f9SKrishna Gudipati * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 3a36c61f9SKrishna Gudipati * All rights reserved 4a36c61f9SKrishna Gudipati * www.brocade.com 5a36c61f9SKrishna Gudipati * 6a36c61f9SKrishna Gudipati * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7a36c61f9SKrishna Gudipati * 8a36c61f9SKrishna Gudipati * This program is free software; you can redistribute it and/or modify it 9a36c61f9SKrishna Gudipati * under the terms of the GNU General Public License (GPL) Version 2 as 10a36c61f9SKrishna Gudipati * published by the Free Software Foundation 11a36c61f9SKrishna Gudipati * 12a36c61f9SKrishna Gudipati * This program is distributed in the hope that it will be useful, but 13a36c61f9SKrishna Gudipati * WITHOUT ANY WARRANTY; without even the implied warranty of 14a36c61f9SKrishna Gudipati * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15a36c61f9SKrishna Gudipati * General Public License for more details. 16a36c61f9SKrishna Gudipati */ 17a36c61f9SKrishna Gudipati /* 18a36c61f9SKrishna Gudipati * fcbuild.c - FC link service frame building and parsing routines 19a36c61f9SKrishna Gudipati */ 20a36c61f9SKrishna Gudipati 21f16a1750SMaggie Zhang #include "bfad_drv.h" 22a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h" 23a36c61f9SKrishna Gudipati 24a36c61f9SKrishna Gudipati /* 25a36c61f9SKrishna Gudipati * static build functions 26a36c61f9SKrishna Gudipati */ 27a36c61f9SKrishna Gudipati static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 2850444a34SMaggie __be16 ox_id); 29a36c61f9SKrishna Gudipati static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, 3050444a34SMaggie __be16 ox_id); 31a36c61f9SKrishna Gudipati static struct fchs_s fc_els_req_tmpl; 32a36c61f9SKrishna Gudipati static struct fchs_s fc_els_rsp_tmpl; 33a36c61f9SKrishna Gudipati static struct fchs_s fc_bls_req_tmpl; 34a36c61f9SKrishna Gudipati static struct fchs_s fc_bls_rsp_tmpl; 35a36c61f9SKrishna Gudipati static struct fc_ba_acc_s ba_acc_tmpl; 36a36c61f9SKrishna Gudipati static struct fc_logi_s plogi_tmpl; 37a36c61f9SKrishna Gudipati static struct fc_prli_s prli_tmpl; 38a36c61f9SKrishna Gudipati static struct fc_rrq_s rrq_tmpl; 39a36c61f9SKrishna Gudipati static struct fchs_s fcp_fchs_tmpl; 40a36c61f9SKrishna Gudipati 41a36c61f9SKrishna Gudipati void 42a36c61f9SKrishna Gudipati fcbuild_init(void) 43a36c61f9SKrishna Gudipati { 44a36c61f9SKrishna Gudipati /* 45a36c61f9SKrishna Gudipati * fc_els_req_tmpl 46a36c61f9SKrishna Gudipati */ 47a36c61f9SKrishna Gudipati fc_els_req_tmpl.routing = FC_RTG_EXT_LINK; 48a36c61f9SKrishna Gudipati fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST; 49a36c61f9SKrishna Gudipati fc_els_req_tmpl.type = FC_TYPE_ELS; 50a36c61f9SKrishna Gudipati fc_els_req_tmpl.f_ctl = 51f16a1750SMaggie Zhang bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | 52a36c61f9SKrishna Gudipati FCTL_SI_XFER); 53a36c61f9SKrishna Gudipati fc_els_req_tmpl.rx_id = FC_RXID_ANY; 54a36c61f9SKrishna Gudipati 55a36c61f9SKrishna Gudipati /* 56a36c61f9SKrishna Gudipati * fc_els_rsp_tmpl 57a36c61f9SKrishna Gudipati */ 58a36c61f9SKrishna Gudipati fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK; 59a36c61f9SKrishna Gudipati fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY; 60a36c61f9SKrishna Gudipati fc_els_rsp_tmpl.type = FC_TYPE_ELS; 61a36c61f9SKrishna Gudipati fc_els_rsp_tmpl.f_ctl = 62f16a1750SMaggie Zhang bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | 63a36c61f9SKrishna Gudipati FCTL_END_SEQ | FCTL_SI_XFER); 64a36c61f9SKrishna Gudipati fc_els_rsp_tmpl.rx_id = FC_RXID_ANY; 65a36c61f9SKrishna Gudipati 66a36c61f9SKrishna Gudipati /* 67a36c61f9SKrishna Gudipati * fc_bls_req_tmpl 68a36c61f9SKrishna Gudipati */ 69a36c61f9SKrishna Gudipati fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK; 70a36c61f9SKrishna Gudipati fc_bls_req_tmpl.type = FC_TYPE_BLS; 71f16a1750SMaggie Zhang fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER); 72a36c61f9SKrishna Gudipati fc_bls_req_tmpl.rx_id = FC_RXID_ANY; 73a36c61f9SKrishna Gudipati 74a36c61f9SKrishna Gudipati /* 75a36c61f9SKrishna Gudipati * fc_bls_rsp_tmpl 76a36c61f9SKrishna Gudipati */ 77a36c61f9SKrishna Gudipati fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK; 78a36c61f9SKrishna Gudipati fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC; 79a36c61f9SKrishna Gudipati fc_bls_rsp_tmpl.type = FC_TYPE_BLS; 80a36c61f9SKrishna Gudipati fc_bls_rsp_tmpl.f_ctl = 81f16a1750SMaggie Zhang bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | 82a36c61f9SKrishna Gudipati FCTL_END_SEQ | FCTL_SI_XFER); 83a36c61f9SKrishna Gudipati fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY; 84a36c61f9SKrishna Gudipati 85a36c61f9SKrishna Gudipati /* 86a36c61f9SKrishna Gudipati * ba_acc_tmpl 87a36c61f9SKrishna Gudipati */ 88a36c61f9SKrishna Gudipati ba_acc_tmpl.seq_id_valid = 0; 89a36c61f9SKrishna Gudipati ba_acc_tmpl.low_seq_cnt = 0; 90a36c61f9SKrishna Gudipati ba_acc_tmpl.high_seq_cnt = 0xFFFF; 91a36c61f9SKrishna Gudipati 92a36c61f9SKrishna Gudipati /* 93a36c61f9SKrishna Gudipati * plogi_tmpl 94a36c61f9SKrishna Gudipati */ 95a36c61f9SKrishna Gudipati plogi_tmpl.csp.verhi = FC_PH_VER_PH_3; 96a36c61f9SKrishna Gudipati plogi_tmpl.csp.verlo = FC_PH_VER_4_3; 97a36c61f9SKrishna Gudipati plogi_tmpl.csp.ciro = 0x1; 98a36c61f9SKrishna Gudipati plogi_tmpl.csp.cisc = 0x0; 99a36c61f9SKrishna Gudipati plogi_tmpl.csp.altbbcred = 0x0; 100ba816ea8SJing Huang plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF); 101ba816ea8SJing Huang plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002); 102ba816ea8SJing Huang plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000); 103a36c61f9SKrishna Gudipati 104a36c61f9SKrishna Gudipati plogi_tmpl.class3.class_valid = 1; 105a36c61f9SKrishna Gudipati plogi_tmpl.class3.sequential = 1; 106a36c61f9SKrishna Gudipati plogi_tmpl.class3.conseq = 0xFF; 107a36c61f9SKrishna Gudipati plogi_tmpl.class3.ospx = 1; 108a36c61f9SKrishna Gudipati 109a36c61f9SKrishna Gudipati /* 110a36c61f9SKrishna Gudipati * prli_tmpl 111a36c61f9SKrishna Gudipati */ 112a36c61f9SKrishna Gudipati prli_tmpl.command = FC_ELS_PRLI; 113a36c61f9SKrishna Gudipati prli_tmpl.pglen = 0x10; 114ba816ea8SJing Huang prli_tmpl.pagebytes = cpu_to_be16(0x0014); 115a36c61f9SKrishna Gudipati prli_tmpl.parampage.type = FC_TYPE_FCP; 116a36c61f9SKrishna Gudipati prli_tmpl.parampage.imagepair = 1; 117a36c61f9SKrishna Gudipati prli_tmpl.parampage.servparams.rxrdisab = 1; 118a36c61f9SKrishna Gudipati 119a36c61f9SKrishna Gudipati /* 120a36c61f9SKrishna Gudipati * rrq_tmpl 121a36c61f9SKrishna Gudipati */ 122a36c61f9SKrishna Gudipati rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ; 123a36c61f9SKrishna Gudipati 124a36c61f9SKrishna Gudipati /* 125a36c61f9SKrishna Gudipati * fcp_struct fchs_s mpl 126a36c61f9SKrishna Gudipati */ 127a36c61f9SKrishna Gudipati fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA; 128a36c61f9SKrishna Gudipati fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD; 129a36c61f9SKrishna Gudipati fcp_fchs_tmpl.type = FC_TYPE_FCP; 130a36c61f9SKrishna Gudipati fcp_fchs_tmpl.f_ctl = 131f16a1750SMaggie Zhang bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER); 132a36c61f9SKrishna Gudipati fcp_fchs_tmpl.seq_id = 1; 133a36c61f9SKrishna Gudipati fcp_fchs_tmpl.rx_id = FC_RXID_ANY; 134a36c61f9SKrishna Gudipati } 135a36c61f9SKrishna Gudipati 136a36c61f9SKrishna Gudipati static void 137a36c61f9SKrishna Gudipati fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id) 138a36c61f9SKrishna Gudipati { 1396a18b167SJing Huang memset(fchs, 0, sizeof(struct fchs_s)); 140a36c61f9SKrishna Gudipati 141a36c61f9SKrishna Gudipati fchs->routing = FC_RTG_FC4_DEV_DATA; 142a36c61f9SKrishna Gudipati fchs->cat_info = FC_CAT_UNSOLICIT_CTRL; 143a36c61f9SKrishna Gudipati fchs->type = FC_TYPE_SERVICES; 144a36c61f9SKrishna Gudipati fchs->f_ctl = 145f16a1750SMaggie Zhang bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | 146a36c61f9SKrishna Gudipati FCTL_SI_XFER); 147a36c61f9SKrishna Gudipati fchs->rx_id = FC_RXID_ANY; 148a36c61f9SKrishna Gudipati fchs->d_id = (d_id); 149a36c61f9SKrishna Gudipati fchs->s_id = (s_id); 150ba816ea8SJing Huang fchs->ox_id = cpu_to_be16(ox_id); 151a36c61f9SKrishna Gudipati 1525fbe25c7SJing Huang /* 153a36c61f9SKrishna Gudipati * @todo no need to set ox_id for request 154a36c61f9SKrishna Gudipati * no need to set rx_id for response 155a36c61f9SKrishna Gudipati */ 156a36c61f9SKrishna Gudipati } 157a36c61f9SKrishna Gudipati 158d7be54ccSKrishna Gudipati static void 159d7be54ccSKrishna Gudipati fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) 160d7be54ccSKrishna Gudipati { 161d7be54ccSKrishna Gudipati memset(fchs, 0, sizeof(struct fchs_s)); 162d7be54ccSKrishna Gudipati 163d7be54ccSKrishna Gudipati fchs->routing = FC_RTG_FC4_DEV_DATA; 164d7be54ccSKrishna Gudipati fchs->cat_info = FC_CAT_SOLICIT_CTRL; 165d7be54ccSKrishna Gudipati fchs->type = FC_TYPE_SERVICES; 166d7be54ccSKrishna Gudipati fchs->f_ctl = 167d7be54ccSKrishna Gudipati bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | 168d7be54ccSKrishna Gudipati FCTL_END_SEQ | FCTL_SI_XFER); 169d7be54ccSKrishna Gudipati fchs->d_id = d_id; 170d7be54ccSKrishna Gudipati fchs->s_id = s_id; 171d7be54ccSKrishna Gudipati fchs->ox_id = ox_id; 172d7be54ccSKrishna Gudipati } 173d7be54ccSKrishna Gudipati 174a36c61f9SKrishna Gudipati void 17550444a34SMaggie fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) 176a36c61f9SKrishna Gudipati { 1776a18b167SJing Huang memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s)); 178a36c61f9SKrishna Gudipati fchs->d_id = (d_id); 179a36c61f9SKrishna Gudipati fchs->s_id = (s_id); 180ba816ea8SJing Huang fchs->ox_id = cpu_to_be16(ox_id); 181a36c61f9SKrishna Gudipati } 182a36c61f9SKrishna Gudipati 183a36c61f9SKrishna Gudipati static void 18450444a34SMaggie fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) 185a36c61f9SKrishna Gudipati { 1866a18b167SJing Huang memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s)); 187a36c61f9SKrishna Gudipati fchs->d_id = d_id; 188a36c61f9SKrishna Gudipati fchs->s_id = s_id; 189a36c61f9SKrishna Gudipati fchs->ox_id = ox_id; 190a36c61f9SKrishna Gudipati } 191a36c61f9SKrishna Gudipati 192a36c61f9SKrishna Gudipati enum fc_parse_status 193a36c61f9SKrishna Gudipati fc_els_rsp_parse(struct fchs_s *fchs, int len) 194a36c61f9SKrishna Gudipati { 195a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 196a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt = (struct fc_ls_rjt_s *) els_cmd; 197a36c61f9SKrishna Gudipati 198a36c61f9SKrishna Gudipati len = len; 199a36c61f9SKrishna Gudipati 200a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 201a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 202a36c61f9SKrishna Gudipati if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) 203a36c61f9SKrishna Gudipati return FC_PARSE_BUSY; 204a36c61f9SKrishna Gudipati else 205a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 206a36c61f9SKrishna Gudipati 207a36c61f9SKrishna Gudipati case FC_ELS_ACC: 208a36c61f9SKrishna Gudipati return FC_PARSE_OK; 209a36c61f9SKrishna Gudipati } 210a36c61f9SKrishna Gudipati return FC_PARSE_OK; 211a36c61f9SKrishna Gudipati } 212a36c61f9SKrishna Gudipati 213a36c61f9SKrishna Gudipati static void 21450444a34SMaggie fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) 215a36c61f9SKrishna Gudipati { 2166a18b167SJing Huang memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s)); 217a36c61f9SKrishna Gudipati fchs->d_id = d_id; 218a36c61f9SKrishna Gudipati fchs->s_id = s_id; 219a36c61f9SKrishna Gudipati fchs->ox_id = ox_id; 220a36c61f9SKrishna Gudipati } 221a36c61f9SKrishna Gudipati 222a36c61f9SKrishna Gudipati static u16 223a36c61f9SKrishna Gudipati fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 22450444a34SMaggie __be16 ox_id, wwn_t port_name, wwn_t node_name, 225be540a99SKrishna Gudipati u16 pdu_size, u16 bb_cr, u8 els_code) 226a36c61f9SKrishna Gudipati { 227a36c61f9SKrishna Gudipati struct fc_logi_s *plogi = (struct fc_logi_s *) (pld); 228a36c61f9SKrishna Gudipati 2296a18b167SJing Huang memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 230a36c61f9SKrishna Gudipati 231*bc0e2c2aSKrishna Gudipati /* For FC AL bb_cr is 0 and altbbcred is 1 */ 232*bc0e2c2aSKrishna Gudipati if (!bb_cr) 233*bc0e2c2aSKrishna Gudipati plogi->csp.altbbcred = 1; 234*bc0e2c2aSKrishna Gudipati 235a36c61f9SKrishna Gudipati plogi->els_cmd.els_code = els_code; 236a36c61f9SKrishna Gudipati if (els_code == FC_ELS_PLOGI) 237a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 238a36c61f9SKrishna Gudipati else 239a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 240a36c61f9SKrishna Gudipati 241ba816ea8SJing Huang plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size); 242be540a99SKrishna Gudipati plogi->csp.bbcred = cpu_to_be16(bb_cr); 243a36c61f9SKrishna Gudipati 2446a18b167SJing Huang memcpy(&plogi->port_name, &port_name, sizeof(wwn_t)); 2456a18b167SJing Huang memcpy(&plogi->node_name, &node_name, sizeof(wwn_t)); 246a36c61f9SKrishna Gudipati 247a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 248a36c61f9SKrishna Gudipati } 249a36c61f9SKrishna Gudipati 250a36c61f9SKrishna Gudipati u16 251a36c61f9SKrishna Gudipati fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 252a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size, 253a36c61f9SKrishna Gudipati u8 set_npiv, u8 set_auth, u16 local_bb_credits) 254a36c61f9SKrishna Gudipati { 255f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_PORT); 25650444a34SMaggie __be32 *vvl_info; 257a36c61f9SKrishna Gudipati 2586a18b167SJing Huang memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 259a36c61f9SKrishna Gudipati 260a36c61f9SKrishna Gudipati flogi->els_cmd.els_code = FC_ELS_FLOGI; 261a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 262a36c61f9SKrishna Gudipati 263ba816ea8SJing Huang flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size); 264a36c61f9SKrishna Gudipati flogi->port_name = port_name; 265a36c61f9SKrishna Gudipati flogi->node_name = node_name; 266a36c61f9SKrishna Gudipati 267a36c61f9SKrishna Gudipati /* 268a36c61f9SKrishna Gudipati * Set the NPIV Capability Bit ( word 1, bit 31) of Common 269a36c61f9SKrishna Gudipati * Service Parameters. 270a36c61f9SKrishna Gudipati */ 271a36c61f9SKrishna Gudipati flogi->csp.ciro = set_npiv; 272a36c61f9SKrishna Gudipati 273a36c61f9SKrishna Gudipati /* set AUTH capability */ 274a36c61f9SKrishna Gudipati flogi->csp.security = set_auth; 275a36c61f9SKrishna Gudipati 276ba816ea8SJing Huang flogi->csp.bbcred = cpu_to_be16(local_bb_credits); 277a36c61f9SKrishna Gudipati 278a36c61f9SKrishna Gudipati /* Set brcd token in VVL */ 279a36c61f9SKrishna Gudipati vvl_info = (u32 *)&flogi->vvl[0]; 280a36c61f9SKrishna Gudipati 281a36c61f9SKrishna Gudipati /* set the flag to indicate the presence of VVL */ 282a36c61f9SKrishna Gudipati flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */ 283ba816ea8SJing Huang vvl_info[0] = cpu_to_be32(FLOGI_VVL_BRCD); 284a36c61f9SKrishna Gudipati 285a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 286a36c61f9SKrishna Gudipati } 287a36c61f9SKrishna Gudipati 288a36c61f9SKrishna Gudipati u16 289a36c61f9SKrishna Gudipati fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 29050444a34SMaggie __be16 ox_id, wwn_t port_name, wwn_t node_name, 291be540a99SKrishna Gudipati u16 pdu_size, u16 local_bb_credits, u8 bb_scn) 292a36c61f9SKrishna Gudipati { 293a36c61f9SKrishna Gudipati u32 d_id = 0; 294be540a99SKrishna Gudipati u16 bbscn_rxsz = (bb_scn << 12) | pdu_size; 295a36c61f9SKrishna Gudipati 2966a18b167SJing Huang memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 297a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 298a36c61f9SKrishna Gudipati 299a36c61f9SKrishna Gudipati flogi->els_cmd.els_code = FC_ELS_ACC; 300be540a99SKrishna Gudipati flogi->class3.rxsz = cpu_to_be16(pdu_size); 301be540a99SKrishna Gudipati flogi->csp.rxsz = cpu_to_be16(bbscn_rxsz); /* bb_scn/rxsz */ 302a36c61f9SKrishna Gudipati flogi->port_name = port_name; 303a36c61f9SKrishna Gudipati flogi->node_name = node_name; 304a36c61f9SKrishna Gudipati 305ba816ea8SJing Huang flogi->csp.bbcred = cpu_to_be16(local_bb_credits); 306a36c61f9SKrishna Gudipati 307a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 308a36c61f9SKrishna Gudipati } 309a36c61f9SKrishna Gudipati 310a36c61f9SKrishna Gudipati u16 311a36c61f9SKrishna Gudipati fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 312a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size) 313a36c61f9SKrishna Gudipati { 314f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_PORT); 315a36c61f9SKrishna Gudipati 3166a18b167SJing Huang memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 317a36c61f9SKrishna Gudipati 318a36c61f9SKrishna Gudipati flogi->els_cmd.els_code = FC_ELS_FDISC; 319a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 320a36c61f9SKrishna Gudipati 321ba816ea8SJing Huang flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size); 322a36c61f9SKrishna Gudipati flogi->port_name = port_name; 323a36c61f9SKrishna Gudipati flogi->node_name = node_name; 324a36c61f9SKrishna Gudipati 325a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 326a36c61f9SKrishna Gudipati } 327a36c61f9SKrishna Gudipati 328a36c61f9SKrishna Gudipati u16 329a36c61f9SKrishna Gudipati fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 330a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, 331be540a99SKrishna Gudipati u16 pdu_size, u16 bb_cr) 332a36c61f9SKrishna Gudipati { 333a36c61f9SKrishna Gudipati return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, 334be540a99SKrishna Gudipati node_name, pdu_size, bb_cr, FC_ELS_PLOGI); 335a36c61f9SKrishna Gudipati } 336a36c61f9SKrishna Gudipati 337a36c61f9SKrishna Gudipati u16 338a36c61f9SKrishna Gudipati fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 339a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, 340be540a99SKrishna Gudipati u16 pdu_size, u16 bb_cr) 341a36c61f9SKrishna Gudipati { 342a36c61f9SKrishna Gudipati return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, 343be540a99SKrishna Gudipati node_name, pdu_size, bb_cr, FC_ELS_ACC); 344a36c61f9SKrishna Gudipati } 345a36c61f9SKrishna Gudipati 346a36c61f9SKrishna Gudipati enum fc_parse_status 347a36c61f9SKrishna Gudipati fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) 348a36c61f9SKrishna Gudipati { 349a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 350a36c61f9SKrishna Gudipati struct fc_logi_s *plogi; 351a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 352a36c61f9SKrishna Gudipati 353a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 354a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 355a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1); 356a36c61f9SKrishna Gudipati if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) 357a36c61f9SKrishna Gudipati return FC_PARSE_BUSY; 358a36c61f9SKrishna Gudipati else 359a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 360a36c61f9SKrishna Gudipati case FC_ELS_ACC: 361a36c61f9SKrishna Gudipati plogi = (struct fc_logi_s *) (fchs + 1); 362a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_logi_s)) 363a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 364a36c61f9SKrishna Gudipati 365a36c61f9SKrishna Gudipati if (!wwn_is_equal(plogi->port_name, port_name)) 366a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 367a36c61f9SKrishna Gudipati 368a36c61f9SKrishna Gudipati if (!plogi->class3.class_valid) 369a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 370a36c61f9SKrishna Gudipati 371ba816ea8SJing Huang if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ)) 372a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 373a36c61f9SKrishna Gudipati 374a36c61f9SKrishna Gudipati return FC_PARSE_OK; 375a36c61f9SKrishna Gudipati default: 376a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 377a36c61f9SKrishna Gudipati } 378a36c61f9SKrishna Gudipati } 379a36c61f9SKrishna Gudipati 380a36c61f9SKrishna Gudipati enum fc_parse_status 381a36c61f9SKrishna Gudipati fc_plogi_parse(struct fchs_s *fchs) 382a36c61f9SKrishna Gudipati { 383a36c61f9SKrishna Gudipati struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1); 384a36c61f9SKrishna Gudipati 385a36c61f9SKrishna Gudipati if (plogi->class3.class_valid != 1) 386a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 387a36c61f9SKrishna Gudipati 388ba816ea8SJing Huang if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ) 389ba816ea8SJing Huang || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ) 390a36c61f9SKrishna Gudipati || (plogi->class3.rxsz == 0)) 391a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 392a36c61f9SKrishna Gudipati 393a36c61f9SKrishna Gudipati return FC_PARSE_OK; 394a36c61f9SKrishna Gudipati } 395a36c61f9SKrishna Gudipati 396a36c61f9SKrishna Gudipati u16 397a36c61f9SKrishna Gudipati fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 398a36c61f9SKrishna Gudipati u16 ox_id) 399a36c61f9SKrishna Gudipati { 400a36c61f9SKrishna Gudipati struct fc_prli_s *prli = (struct fc_prli_s *) (pld); 401a36c61f9SKrishna Gudipati 402a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 4036a18b167SJing Huang memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); 404a36c61f9SKrishna Gudipati 405a36c61f9SKrishna Gudipati prli->command = FC_ELS_PRLI; 406a36c61f9SKrishna Gudipati prli->parampage.servparams.initiator = 1; 407a36c61f9SKrishna Gudipati prli->parampage.servparams.retry = 1; 408a36c61f9SKrishna Gudipati prli->parampage.servparams.rec_support = 1; 409a36c61f9SKrishna Gudipati prli->parampage.servparams.task_retry_id = 0; 410a36c61f9SKrishna Gudipati prli->parampage.servparams.confirm = 1; 411a36c61f9SKrishna Gudipati 412a36c61f9SKrishna Gudipati return sizeof(struct fc_prli_s); 413a36c61f9SKrishna Gudipati } 414a36c61f9SKrishna Gudipati 415a36c61f9SKrishna Gudipati u16 416a36c61f9SKrishna Gudipati fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 41750444a34SMaggie __be16 ox_id, enum bfa_lport_role role) 418a36c61f9SKrishna Gudipati { 419a36c61f9SKrishna Gudipati struct fc_prli_s *prli = (struct fc_prli_s *) (pld); 420a36c61f9SKrishna Gudipati 421a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 4226a18b167SJing Huang memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); 423a36c61f9SKrishna Gudipati 424a36c61f9SKrishna Gudipati prli->command = FC_ELS_ACC; 425a36c61f9SKrishna Gudipati 426a36c61f9SKrishna Gudipati prli->parampage.servparams.initiator = 1; 427a36c61f9SKrishna Gudipati 428a36c61f9SKrishna Gudipati prli->parampage.rspcode = FC_PRLI_ACC_XQTD; 429a36c61f9SKrishna Gudipati 430a36c61f9SKrishna Gudipati return sizeof(struct fc_prli_s); 431a36c61f9SKrishna Gudipati } 432a36c61f9SKrishna Gudipati 433a36c61f9SKrishna Gudipati enum fc_parse_status 434a36c61f9SKrishna Gudipati fc_prli_rsp_parse(struct fc_prli_s *prli, int len) 435a36c61f9SKrishna Gudipati { 436a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_prli_s)) 437a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 438a36c61f9SKrishna Gudipati 439a36c61f9SKrishna Gudipati if (prli->command != FC_ELS_ACC) 440a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 441a36c61f9SKrishna Gudipati 442a36c61f9SKrishna Gudipati if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD) 443a36c61f9SKrishna Gudipati && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG)) 444a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 445a36c61f9SKrishna Gudipati 446a36c61f9SKrishna Gudipati if (prli->parampage.servparams.target != 1) 447a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 448a36c61f9SKrishna Gudipati 449a36c61f9SKrishna Gudipati return FC_PARSE_OK; 450a36c61f9SKrishna Gudipati } 451a36c61f9SKrishna Gudipati 452a36c61f9SKrishna Gudipati enum fc_parse_status 453a36c61f9SKrishna Gudipati fc_prli_parse(struct fc_prli_s *prli) 454a36c61f9SKrishna Gudipati { 455a36c61f9SKrishna Gudipati if (prli->parampage.type != FC_TYPE_FCP) 456a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 457a36c61f9SKrishna Gudipati 458a36c61f9SKrishna Gudipati if (!prli->parampage.imagepair) 459a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 460a36c61f9SKrishna Gudipati 461a36c61f9SKrishna Gudipati if (!prli->parampage.servparams.initiator) 462a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 463a36c61f9SKrishna Gudipati 464a36c61f9SKrishna Gudipati return FC_PARSE_OK; 465a36c61f9SKrishna Gudipati } 466a36c61f9SKrishna Gudipati 467a36c61f9SKrishna Gudipati u16 468a36c61f9SKrishna Gudipati fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id, 469a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name) 470a36c61f9SKrishna Gudipati { 471a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 472a36c61f9SKrishna Gudipati 4736a18b167SJing Huang memset(logo, '\0', sizeof(struct fc_logo_s)); 474a36c61f9SKrishna Gudipati logo->els_cmd.els_code = FC_ELS_LOGO; 475a36c61f9SKrishna Gudipati logo->nport_id = (s_id); 476a36c61f9SKrishna Gudipati logo->orig_port_name = port_name; 477a36c61f9SKrishna Gudipati 478a36c61f9SKrishna Gudipati return sizeof(struct fc_logo_s); 479a36c61f9SKrishna Gudipati } 480a36c61f9SKrishna Gudipati 481a36c61f9SKrishna Gudipati static u16 482a36c61f9SKrishna Gudipati fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 48350444a34SMaggie u32 s_id, __be16 ox_id, wwn_t port_name, 484a36c61f9SKrishna Gudipati wwn_t node_name, u8 els_code) 485a36c61f9SKrishna Gudipati { 4866a18b167SJing Huang memset(adisc, '\0', sizeof(struct fc_adisc_s)); 487a36c61f9SKrishna Gudipati 488a36c61f9SKrishna Gudipati adisc->els_cmd.els_code = els_code; 489a36c61f9SKrishna Gudipati 490a36c61f9SKrishna Gudipati if (els_code == FC_ELS_ADISC) 491a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 492a36c61f9SKrishna Gudipati else 493a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 494a36c61f9SKrishna Gudipati 495a36c61f9SKrishna Gudipati adisc->orig_HA = 0; 496a36c61f9SKrishna Gudipati adisc->orig_port_name = port_name; 497a36c61f9SKrishna Gudipati adisc->orig_node_name = node_name; 498a36c61f9SKrishna Gudipati adisc->nport_id = (s_id); 499a36c61f9SKrishna Gudipati 500a36c61f9SKrishna Gudipati return sizeof(struct fc_adisc_s); 501a36c61f9SKrishna Gudipati } 502a36c61f9SKrishna Gudipati 503a36c61f9SKrishna Gudipati u16 504a36c61f9SKrishna Gudipati fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 50550444a34SMaggie u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name) 506a36c61f9SKrishna Gudipati { 507a36c61f9SKrishna Gudipati return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, 508a36c61f9SKrishna Gudipati node_name, FC_ELS_ADISC); 509a36c61f9SKrishna Gudipati } 510a36c61f9SKrishna Gudipati 511a36c61f9SKrishna Gudipati u16 512a36c61f9SKrishna Gudipati fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 51350444a34SMaggie u32 s_id, __be16 ox_id, wwn_t port_name, 514a36c61f9SKrishna Gudipati wwn_t node_name) 515a36c61f9SKrishna Gudipati { 516a36c61f9SKrishna Gudipati return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, 517a36c61f9SKrishna Gudipati node_name, FC_ELS_ACC); 518a36c61f9SKrishna Gudipati } 519a36c61f9SKrishna Gudipati 520a36c61f9SKrishna Gudipati enum fc_parse_status 521a36c61f9SKrishna Gudipati fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name, 522a36c61f9SKrishna Gudipati wwn_t node_name) 523a36c61f9SKrishna Gudipati { 524a36c61f9SKrishna Gudipati 525a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_adisc_s)) 526a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 527a36c61f9SKrishna Gudipati 528a36c61f9SKrishna Gudipati if (adisc->els_cmd.els_code != FC_ELS_ACC) 529a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 530a36c61f9SKrishna Gudipati 531a36c61f9SKrishna Gudipati if (!wwn_is_equal(adisc->orig_port_name, port_name)) 532a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 533a36c61f9SKrishna Gudipati 534a36c61f9SKrishna Gudipati return FC_PARSE_OK; 535a36c61f9SKrishna Gudipati } 536a36c61f9SKrishna Gudipati 537a36c61f9SKrishna Gudipati enum fc_parse_status 538a36c61f9SKrishna Gudipati fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name, 539a36c61f9SKrishna Gudipati wwn_t port_name) 540a36c61f9SKrishna Gudipati { 541a36c61f9SKrishna Gudipati struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld; 542a36c61f9SKrishna Gudipati 543a36c61f9SKrishna Gudipati if (adisc->els_cmd.els_code != FC_ELS_ACC) 544a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 545a36c61f9SKrishna Gudipati 546a36c61f9SKrishna Gudipati if ((adisc->nport_id == (host_dap)) 547a36c61f9SKrishna Gudipati && wwn_is_equal(adisc->orig_port_name, port_name) 548a36c61f9SKrishna Gudipati && wwn_is_equal(adisc->orig_node_name, node_name)) 549a36c61f9SKrishna Gudipati return FC_PARSE_OK; 550a36c61f9SKrishna Gudipati 551a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 552a36c61f9SKrishna Gudipati } 553a36c61f9SKrishna Gudipati 554a36c61f9SKrishna Gudipati enum fc_parse_status 555a36c61f9SKrishna Gudipati fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name) 556a36c61f9SKrishna Gudipati { 557a36c61f9SKrishna Gudipati struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 558a36c61f9SKrishna Gudipati 559a36c61f9SKrishna Gudipati if (pdisc->class3.class_valid != 1) 560a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 561a36c61f9SKrishna Gudipati 562ba816ea8SJing Huang if ((be16_to_cpu(pdisc->class3.rxsz) < 563a36c61f9SKrishna Gudipati (FC_MIN_PDUSZ - sizeof(struct fchs_s))) 564a36c61f9SKrishna Gudipati || (pdisc->class3.rxsz == 0)) 565a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 566a36c61f9SKrishna Gudipati 567a36c61f9SKrishna Gudipati if (!wwn_is_equal(pdisc->port_name, port_name)) 568a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 569a36c61f9SKrishna Gudipati 570a36c61f9SKrishna Gudipati if (!wwn_is_equal(pdisc->node_name, node_name)) 571a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 572a36c61f9SKrishna Gudipati 573a36c61f9SKrishna Gudipati return FC_PARSE_OK; 574a36c61f9SKrishna Gudipati } 575a36c61f9SKrishna Gudipati 576a36c61f9SKrishna Gudipati u16 577a36c61f9SKrishna Gudipati fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) 578a36c61f9SKrishna Gudipati { 5796a18b167SJing Huang memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s)); 580a36c61f9SKrishna Gudipati fchs->cat_info = FC_CAT_ABTS; 581a36c61f9SKrishna Gudipati fchs->d_id = (d_id); 582a36c61f9SKrishna Gudipati fchs->s_id = (s_id); 583ba816ea8SJing Huang fchs->ox_id = cpu_to_be16(ox_id); 584a36c61f9SKrishna Gudipati 585a36c61f9SKrishna Gudipati return sizeof(struct fchs_s); 586a36c61f9SKrishna Gudipati } 587a36c61f9SKrishna Gudipati 588a36c61f9SKrishna Gudipati enum fc_parse_status 589a36c61f9SKrishna Gudipati fc_abts_rsp_parse(struct fchs_s *fchs, int len) 590a36c61f9SKrishna Gudipati { 591a36c61f9SKrishna Gudipati if ((fchs->cat_info == FC_CAT_BA_ACC) 592a36c61f9SKrishna Gudipati || (fchs->cat_info == FC_CAT_BA_RJT)) 593a36c61f9SKrishna Gudipati return FC_PARSE_OK; 594a36c61f9SKrishna Gudipati 595a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 596a36c61f9SKrishna Gudipati } 597a36c61f9SKrishna Gudipati 598a36c61f9SKrishna Gudipati u16 599a36c61f9SKrishna Gudipati fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id, 600a36c61f9SKrishna Gudipati u16 ox_id, u16 rrq_oxid) 601a36c61f9SKrishna Gudipati { 602a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 603a36c61f9SKrishna Gudipati 604a36c61f9SKrishna Gudipati /* 605a36c61f9SKrishna Gudipati * build rrq payload 606a36c61f9SKrishna Gudipati */ 6076a18b167SJing Huang memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s)); 608a36c61f9SKrishna Gudipati rrq->s_id = (s_id); 609ba816ea8SJing Huang rrq->ox_id = cpu_to_be16(rrq_oxid); 610a36c61f9SKrishna Gudipati rrq->rx_id = FC_RXID_ANY; 611a36c61f9SKrishna Gudipati 612a36c61f9SKrishna Gudipati return sizeof(struct fc_rrq_s); 613a36c61f9SKrishna Gudipati } 614a36c61f9SKrishna Gudipati 615a36c61f9SKrishna Gudipati u16 616a36c61f9SKrishna Gudipati fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 61750444a34SMaggie __be16 ox_id) 618a36c61f9SKrishna Gudipati { 619a36c61f9SKrishna Gudipati struct fc_els_cmd_s *acc = pld; 620a36c61f9SKrishna Gudipati 621a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 622a36c61f9SKrishna Gudipati 6236a18b167SJing Huang memset(acc, 0, sizeof(struct fc_els_cmd_s)); 624a36c61f9SKrishna Gudipati acc->els_code = FC_ELS_ACC; 625a36c61f9SKrishna Gudipati 626a36c61f9SKrishna Gudipati return sizeof(struct fc_els_cmd_s); 627a36c61f9SKrishna Gudipati } 628a36c61f9SKrishna Gudipati 629a36c61f9SKrishna Gudipati u16 630a36c61f9SKrishna Gudipati fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id, 63150444a34SMaggie u32 s_id, __be16 ox_id, u8 reason_code, 632a36c61f9SKrishna Gudipati u8 reason_code_expl) 633a36c61f9SKrishna Gudipati { 634a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 6356a18b167SJing Huang memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s)); 636a36c61f9SKrishna Gudipati 637a36c61f9SKrishna Gudipati ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT; 638a36c61f9SKrishna Gudipati ls_rjt->reason_code = reason_code; 639a36c61f9SKrishna Gudipati ls_rjt->reason_code_expl = reason_code_expl; 640a36c61f9SKrishna Gudipati ls_rjt->vendor_unique = 0x00; 641a36c61f9SKrishna Gudipati 642a36c61f9SKrishna Gudipati return sizeof(struct fc_ls_rjt_s); 643a36c61f9SKrishna Gudipati } 644a36c61f9SKrishna Gudipati 645a36c61f9SKrishna Gudipati u16 646a36c61f9SKrishna Gudipati fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id, 64750444a34SMaggie u32 s_id, __be16 ox_id, u16 rx_id) 648a36c61f9SKrishna Gudipati { 649a36c61f9SKrishna Gudipati fc_bls_rsp_build(fchs, d_id, s_id, ox_id); 650a36c61f9SKrishna Gudipati 6516a18b167SJing Huang memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s)); 652a36c61f9SKrishna Gudipati 653a36c61f9SKrishna Gudipati fchs->rx_id = rx_id; 654a36c61f9SKrishna Gudipati 655a36c61f9SKrishna Gudipati ba_acc->ox_id = fchs->ox_id; 656a36c61f9SKrishna Gudipati ba_acc->rx_id = fchs->rx_id; 657a36c61f9SKrishna Gudipati 658a36c61f9SKrishna Gudipati return sizeof(struct fc_ba_acc_s); 659a36c61f9SKrishna Gudipati } 660a36c61f9SKrishna Gudipati 661a36c61f9SKrishna Gudipati u16 662a36c61f9SKrishna Gudipati fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id, 66350444a34SMaggie u32 s_id, __be16 ox_id) 664a36c61f9SKrishna Gudipati { 665a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 6666a18b167SJing Huang memset(els_cmd, 0, sizeof(struct fc_els_cmd_s)); 667a36c61f9SKrishna Gudipati els_cmd->els_code = FC_ELS_ACC; 668a36c61f9SKrishna Gudipati 669a36c61f9SKrishna Gudipati return sizeof(struct fc_els_cmd_s); 670a36c61f9SKrishna Gudipati } 671a36c61f9SKrishna Gudipati 672a36c61f9SKrishna Gudipati int 673a36c61f9SKrishna Gudipati fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code) 674a36c61f9SKrishna Gudipati { 675a36c61f9SKrishna Gudipati int num_pages = 0; 676a36c61f9SKrishna Gudipati struct fc_prlo_s *prlo; 677a36c61f9SKrishna Gudipati struct fc_tprlo_s *tprlo; 678a36c61f9SKrishna Gudipati 679a36c61f9SKrishna Gudipati if (els_code == FC_ELS_PRLO) { 680a36c61f9SKrishna Gudipati prlo = (struct fc_prlo_s *) (fc_frame + 1); 681ba816ea8SJing Huang num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16; 682a36c61f9SKrishna Gudipati } else { 683a36c61f9SKrishna Gudipati tprlo = (struct fc_tprlo_s *) (fc_frame + 1); 684ba816ea8SJing Huang num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16; 685a36c61f9SKrishna Gudipati } 686a36c61f9SKrishna Gudipati return num_pages; 687a36c61f9SKrishna Gudipati } 688a36c61f9SKrishna Gudipati 689a36c61f9SKrishna Gudipati u16 690a36c61f9SKrishna Gudipati fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc, 69150444a34SMaggie u32 d_id, u32 s_id, __be16 ox_id, int num_pages) 692a36c61f9SKrishna Gudipati { 693a36c61f9SKrishna Gudipati int page; 694a36c61f9SKrishna Gudipati 695a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 696a36c61f9SKrishna Gudipati 6976a18b167SJing Huang memset(tprlo_acc, 0, (num_pages * 16) + 4); 698a36c61f9SKrishna Gudipati tprlo_acc->command = FC_ELS_ACC; 699a36c61f9SKrishna Gudipati 700a36c61f9SKrishna Gudipati tprlo_acc->page_len = 0x10; 701ba816ea8SJing Huang tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4); 702a36c61f9SKrishna Gudipati 703a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 704a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].opa_valid = 0; 705a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].rpa_valid = 0; 706a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; 707a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0; 708a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0; 709a36c61f9SKrishna Gudipati } 710ba816ea8SJing Huang return be16_to_cpu(tprlo_acc->payload_len); 711a36c61f9SKrishna Gudipati } 712a36c61f9SKrishna Gudipati 713a36c61f9SKrishna Gudipati u16 714a36c61f9SKrishna Gudipati fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id, 71550444a34SMaggie u32 s_id, __be16 ox_id, int num_pages) 716a36c61f9SKrishna Gudipati { 717a36c61f9SKrishna Gudipati int page; 718a36c61f9SKrishna Gudipati 719a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 720a36c61f9SKrishna Gudipati 7216a18b167SJing Huang memset(prlo_acc, 0, (num_pages * 16) + 4); 722a36c61f9SKrishna Gudipati prlo_acc->command = FC_ELS_ACC; 723a36c61f9SKrishna Gudipati prlo_acc->page_len = 0x10; 724ba816ea8SJing Huang prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4); 725a36c61f9SKrishna Gudipati 726a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 727a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].opa_valid = 0; 728a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].rpa_valid = 0; 729a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; 730a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].orig_process_assc = 0; 731a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].resp_process_assc = 0; 732a36c61f9SKrishna Gudipati } 733a36c61f9SKrishna Gudipati 734ba816ea8SJing Huang return be16_to_cpu(prlo_acc->payload_len); 735a36c61f9SKrishna Gudipati } 736a36c61f9SKrishna Gudipati 737a36c61f9SKrishna Gudipati u16 738a36c61f9SKrishna Gudipati fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id, 739a36c61f9SKrishna Gudipati u32 s_id, u16 ox_id, u32 data_format) 740a36c61f9SKrishna Gudipati { 741a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 742a36c61f9SKrishna Gudipati 7436a18b167SJing Huang memset(rnid, 0, sizeof(struct fc_rnid_cmd_s)); 744a36c61f9SKrishna Gudipati 745a36c61f9SKrishna Gudipati rnid->els_cmd.els_code = FC_ELS_RNID; 746a36c61f9SKrishna Gudipati rnid->node_id_data_format = data_format; 747a36c61f9SKrishna Gudipati 748a36c61f9SKrishna Gudipati return sizeof(struct fc_rnid_cmd_s); 749a36c61f9SKrishna Gudipati } 750a36c61f9SKrishna Gudipati 751a36c61f9SKrishna Gudipati u16 752a36c61f9SKrishna Gudipati fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id, 75350444a34SMaggie u32 s_id, __be16 ox_id, u32 data_format, 754a36c61f9SKrishna Gudipati struct fc_rnid_common_id_data_s *common_id_data, 755a36c61f9SKrishna Gudipati struct fc_rnid_general_topology_data_s *gen_topo_data) 756a36c61f9SKrishna Gudipati { 7576a18b167SJing Huang memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s)); 758a36c61f9SKrishna Gudipati 759a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 760a36c61f9SKrishna Gudipati 761a36c61f9SKrishna Gudipati rnid_acc->els_cmd.els_code = FC_ELS_ACC; 762a36c61f9SKrishna Gudipati rnid_acc->node_id_data_format = data_format; 763a36c61f9SKrishna Gudipati rnid_acc->common_id_data_length = 764a36c61f9SKrishna Gudipati sizeof(struct fc_rnid_common_id_data_s); 765a36c61f9SKrishna Gudipati rnid_acc->common_id_data = *common_id_data; 766a36c61f9SKrishna Gudipati 767a36c61f9SKrishna Gudipati if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 768a36c61f9SKrishna Gudipati rnid_acc->specific_id_data_length = 769a36c61f9SKrishna Gudipati sizeof(struct fc_rnid_general_topology_data_s); 7706a18b167SJing Huang rnid_acc->gen_topology_data = *gen_topo_data; 771a36c61f9SKrishna Gudipati return sizeof(struct fc_rnid_acc_s); 772a36c61f9SKrishna Gudipati } else { 773a36c61f9SKrishna Gudipati return sizeof(struct fc_rnid_acc_s) - 774a36c61f9SKrishna Gudipati sizeof(struct fc_rnid_general_topology_data_s); 775a36c61f9SKrishna Gudipati } 776a36c61f9SKrishna Gudipati 777a36c61f9SKrishna Gudipati } 778a36c61f9SKrishna Gudipati 779a36c61f9SKrishna Gudipati u16 780a36c61f9SKrishna Gudipati fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id, 781a36c61f9SKrishna Gudipati u32 s_id, u16 ox_id) 782a36c61f9SKrishna Gudipati { 783a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 784a36c61f9SKrishna Gudipati 7856a18b167SJing Huang memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s)); 786a36c61f9SKrishna Gudipati 787a36c61f9SKrishna Gudipati rpsc->els_cmd.els_code = FC_ELS_RPSC; 788a36c61f9SKrishna Gudipati return sizeof(struct fc_rpsc_cmd_s); 789a36c61f9SKrishna Gudipati } 790a36c61f9SKrishna Gudipati 791a36c61f9SKrishna Gudipati u16 792a36c61f9SKrishna Gudipati fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id, 793a36c61f9SKrishna Gudipati u32 s_id, u32 *pid_list, u16 npids) 794a36c61f9SKrishna Gudipati { 795f16a1750SMaggie Zhang u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id)); 796a36c61f9SKrishna Gudipati int i = 0; 797a36c61f9SKrishna Gudipati 798f16a1750SMaggie Zhang fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0); 799a36c61f9SKrishna Gudipati 8006a18b167SJing Huang memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s)); 801a36c61f9SKrishna Gudipati 802a36c61f9SKrishna Gudipati rpsc2->els_cmd.els_code = FC_ELS_RPSC; 803ba816ea8SJing Huang rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN); 804ba816ea8SJing Huang rpsc2->num_pids = cpu_to_be16(npids); 805a36c61f9SKrishna Gudipati for (i = 0; i < npids; i++) 806a36c61f9SKrishna Gudipati rpsc2->pid_list[i].pid = pid_list[i]; 807a36c61f9SKrishna Gudipati 808a36c61f9SKrishna Gudipati return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32))); 809a36c61f9SKrishna Gudipati } 810a36c61f9SKrishna Gudipati 811a36c61f9SKrishna Gudipati u16 812a36c61f9SKrishna Gudipati fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc, 81350444a34SMaggie u32 d_id, u32 s_id, __be16 ox_id, 814a36c61f9SKrishna Gudipati struct fc_rpsc_speed_info_s *oper_speed) 815a36c61f9SKrishna Gudipati { 8166a18b167SJing Huang memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s)); 817a36c61f9SKrishna Gudipati 818a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 819a36c61f9SKrishna Gudipati 820a36c61f9SKrishna Gudipati rpsc_acc->command = FC_ELS_ACC; 821ba816ea8SJing Huang rpsc_acc->num_entries = cpu_to_be16(1); 822a36c61f9SKrishna Gudipati 823a36c61f9SKrishna Gudipati rpsc_acc->speed_info[0].port_speed_cap = 824ba816ea8SJing Huang cpu_to_be16(oper_speed->port_speed_cap); 825a36c61f9SKrishna Gudipati 826a36c61f9SKrishna Gudipati rpsc_acc->speed_info[0].port_op_speed = 827ba816ea8SJing Huang cpu_to_be16(oper_speed->port_op_speed); 828a36c61f9SKrishna Gudipati 829a36c61f9SKrishna Gudipati return sizeof(struct fc_rpsc_acc_s); 830a36c61f9SKrishna Gudipati } 831a36c61f9SKrishna Gudipati 832a36c61f9SKrishna Gudipati u16 833a36c61f9SKrishna Gudipati fc_logo_rsp_parse(struct fchs_s *fchs, int len) 834a36c61f9SKrishna Gudipati { 835a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 836a36c61f9SKrishna Gudipati 837a36c61f9SKrishna Gudipati len = len; 838a36c61f9SKrishna Gudipati if (els_cmd->els_code != FC_ELS_ACC) 839a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 840a36c61f9SKrishna Gudipati 841a36c61f9SKrishna Gudipati return FC_PARSE_OK; 842a36c61f9SKrishna Gudipati } 843a36c61f9SKrishna Gudipati 844a36c61f9SKrishna Gudipati u16 845a36c61f9SKrishna Gudipati fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, 846a36c61f9SKrishna Gudipati wwn_t port_name, wwn_t node_name, u16 pdu_size) 847a36c61f9SKrishna Gudipati { 848a36c61f9SKrishna Gudipati struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 849a36c61f9SKrishna Gudipati 8506a18b167SJing Huang memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s)); 851a36c61f9SKrishna Gudipati 852a36c61f9SKrishna Gudipati pdisc->els_cmd.els_code = FC_ELS_PDISC; 853a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 854a36c61f9SKrishna Gudipati 855ba816ea8SJing Huang pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size); 856a36c61f9SKrishna Gudipati pdisc->port_name = port_name; 857a36c61f9SKrishna Gudipati pdisc->node_name = node_name; 858a36c61f9SKrishna Gudipati 859a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 860a36c61f9SKrishna Gudipati } 861a36c61f9SKrishna Gudipati 862a36c61f9SKrishna Gudipati u16 863a36c61f9SKrishna Gudipati fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) 864a36c61f9SKrishna Gudipati { 865a36c61f9SKrishna Gudipati struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 866a36c61f9SKrishna Gudipati 867a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_logi_s)) 868a36c61f9SKrishna Gudipati return FC_PARSE_LEN_INVAL; 869a36c61f9SKrishna Gudipati 870a36c61f9SKrishna Gudipati if (pdisc->els_cmd.els_code != FC_ELS_ACC) 871a36c61f9SKrishna Gudipati return FC_PARSE_ACC_INVAL; 872a36c61f9SKrishna Gudipati 873a36c61f9SKrishna Gudipati if (!wwn_is_equal(pdisc->port_name, port_name)) 874a36c61f9SKrishna Gudipati return FC_PARSE_PWWN_NOT_EQUAL; 875a36c61f9SKrishna Gudipati 876a36c61f9SKrishna Gudipati if (!pdisc->class3.class_valid) 877a36c61f9SKrishna Gudipati return FC_PARSE_NWWN_NOT_EQUAL; 878a36c61f9SKrishna Gudipati 879ba816ea8SJing Huang if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ)) 880a36c61f9SKrishna Gudipati return FC_PARSE_RXSZ_INVAL; 881a36c61f9SKrishna Gudipati 882a36c61f9SKrishna Gudipati return FC_PARSE_OK; 883a36c61f9SKrishna Gudipati } 884a36c61f9SKrishna Gudipati 885a36c61f9SKrishna Gudipati u16 886a36c61f9SKrishna Gudipati fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, 887a36c61f9SKrishna Gudipati int num_pages) 888a36c61f9SKrishna Gudipati { 889a36c61f9SKrishna Gudipati struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1); 890a36c61f9SKrishna Gudipati int page; 891a36c61f9SKrishna Gudipati 892a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 8936a18b167SJing Huang memset(prlo, 0, (num_pages * 16) + 4); 894a36c61f9SKrishna Gudipati prlo->command = FC_ELS_PRLO; 895a36c61f9SKrishna Gudipati prlo->page_len = 0x10; 896ba816ea8SJing Huang prlo->payload_len = cpu_to_be16((num_pages * 16) + 4); 897a36c61f9SKrishna Gudipati 898a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 899a36c61f9SKrishna Gudipati prlo->prlo_params[page].type = FC_TYPE_FCP; 900a36c61f9SKrishna Gudipati prlo->prlo_params[page].opa_valid = 0; 901a36c61f9SKrishna Gudipati prlo->prlo_params[page].rpa_valid = 0; 902a36c61f9SKrishna Gudipati prlo->prlo_params[page].orig_process_assc = 0; 903a36c61f9SKrishna Gudipati prlo->prlo_params[page].resp_process_assc = 0; 904a36c61f9SKrishna Gudipati } 905a36c61f9SKrishna Gudipati 906ba816ea8SJing Huang return be16_to_cpu(prlo->payload_len); 907a36c61f9SKrishna Gudipati } 908a36c61f9SKrishna Gudipati 909a36c61f9SKrishna Gudipati u16 910a36c61f9SKrishna Gudipati fc_prlo_rsp_parse(struct fchs_s *fchs, int len) 911a36c61f9SKrishna Gudipati { 912a36c61f9SKrishna Gudipati struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1); 913a36c61f9SKrishna Gudipati int num_pages = 0; 914a36c61f9SKrishna Gudipati int page = 0; 915a36c61f9SKrishna Gudipati 916a36c61f9SKrishna Gudipati len = len; 917a36c61f9SKrishna Gudipati 918a36c61f9SKrishna Gudipati if (prlo->command != FC_ELS_ACC) 919a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 920a36c61f9SKrishna Gudipati 921ba816ea8SJing Huang num_pages = ((be16_to_cpu(prlo->payload_len)) - 4) / 16; 922a36c61f9SKrishna Gudipati 923a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 924a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP) 925a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 926a36c61f9SKrishna Gudipati 927a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].opa_valid != 0) 928a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 929a36c61f9SKrishna Gudipati 930a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].rpa_valid != 0) 931a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 932a36c61f9SKrishna Gudipati 933a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].orig_process_assc != 0) 934a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 935a36c61f9SKrishna Gudipati 936a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].resp_process_assc != 0) 937a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 938a36c61f9SKrishna Gudipati } 939a36c61f9SKrishna Gudipati return FC_PARSE_OK; 940a36c61f9SKrishna Gudipati 941a36c61f9SKrishna Gudipati } 942a36c61f9SKrishna Gudipati 943a36c61f9SKrishna Gudipati u16 944a36c61f9SKrishna Gudipati fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, 945a36c61f9SKrishna Gudipati int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id) 946a36c61f9SKrishna Gudipati { 947a36c61f9SKrishna Gudipati struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1); 948a36c61f9SKrishna Gudipati int page; 949a36c61f9SKrishna Gudipati 950a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 9516a18b167SJing Huang memset(tprlo, 0, (num_pages * 16) + 4); 952a36c61f9SKrishna Gudipati tprlo->command = FC_ELS_TPRLO; 953a36c61f9SKrishna Gudipati tprlo->page_len = 0x10; 954ba816ea8SJing Huang tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4); 955a36c61f9SKrishna Gudipati 956a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 957a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].type = FC_TYPE_FCP; 958a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].opa_valid = 0; 959a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].rpa_valid = 0; 960a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].orig_process_assc = 0; 961a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].resp_process_assc = 0; 962a36c61f9SKrishna Gudipati if (tprlo_type == FC_GLOBAL_LOGO) { 963a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].global_process_logout = 1; 964a36c61f9SKrishna Gudipati } else if (tprlo_type == FC_TPR_LOGO) { 965a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].tpo_nport_valid = 1; 966a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].tpo_nport_id = (tpr_id); 967a36c61f9SKrishna Gudipati } 968a36c61f9SKrishna Gudipati } 969a36c61f9SKrishna Gudipati 970ba816ea8SJing Huang return be16_to_cpu(tprlo->payload_len); 971a36c61f9SKrishna Gudipati } 972a36c61f9SKrishna Gudipati 973a36c61f9SKrishna Gudipati u16 974a36c61f9SKrishna Gudipati fc_tprlo_rsp_parse(struct fchs_s *fchs, int len) 975a36c61f9SKrishna Gudipati { 976a36c61f9SKrishna Gudipati struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1); 977a36c61f9SKrishna Gudipati int num_pages = 0; 978a36c61f9SKrishna Gudipati int page = 0; 979a36c61f9SKrishna Gudipati 980a36c61f9SKrishna Gudipati len = len; 981a36c61f9SKrishna Gudipati 982a36c61f9SKrishna Gudipati if (tprlo->command != FC_ELS_ACC) 983a36c61f9SKrishna Gudipati return FC_PARSE_ACC_INVAL; 984a36c61f9SKrishna Gudipati 985ba816ea8SJing Huang num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16; 986a36c61f9SKrishna Gudipati 987a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 988a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP) 989a36c61f9SKrishna Gudipati return FC_PARSE_NOT_FCP; 990a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].opa_valid != 0) 991a36c61f9SKrishna Gudipati return FC_PARSE_OPAFLAG_INVAL; 992a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].rpa_valid != 0) 993a36c61f9SKrishna Gudipati return FC_PARSE_RPAFLAG_INVAL; 994a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].orig_process_assc != 0) 995a36c61f9SKrishna Gudipati return FC_PARSE_OPA_INVAL; 996a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].resp_process_assc != 0) 997a36c61f9SKrishna Gudipati return FC_PARSE_RPA_INVAL; 998a36c61f9SKrishna Gudipati } 999a36c61f9SKrishna Gudipati return FC_PARSE_OK; 1000a36c61f9SKrishna Gudipati } 1001a36c61f9SKrishna Gudipati 1002a36c61f9SKrishna Gudipati enum fc_parse_status 1003a36c61f9SKrishna Gudipati fc_rrq_rsp_parse(struct fchs_s *fchs, int len) 1004a36c61f9SKrishna Gudipati { 1005a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 1006a36c61f9SKrishna Gudipati 1007a36c61f9SKrishna Gudipati len = len; 1008a36c61f9SKrishna Gudipati if (els_cmd->els_code != FC_ELS_ACC) 1009a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 1010a36c61f9SKrishna Gudipati 1011a36c61f9SKrishna Gudipati return FC_PARSE_OK; 1012a36c61f9SKrishna Gudipati } 1013a36c61f9SKrishna Gudipati 1014a36c61f9SKrishna Gudipati u16 101550444a34SMaggie fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id, 1016a36c61f9SKrishna Gudipati u32 reason_code, u32 reason_expl) 1017a36c61f9SKrishna Gudipati { 1018a36c61f9SKrishna Gudipati struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1); 1019a36c61f9SKrishna Gudipati 1020a36c61f9SKrishna Gudipati fc_bls_rsp_build(fchs, d_id, s_id, ox_id); 1021a36c61f9SKrishna Gudipati 1022a36c61f9SKrishna Gudipati fchs->cat_info = FC_CAT_BA_RJT; 1023a36c61f9SKrishna Gudipati ba_rjt->reason_code = reason_code; 1024a36c61f9SKrishna Gudipati ba_rjt->reason_expl = reason_expl; 1025a36c61f9SKrishna Gudipati return sizeof(struct fc_ba_rjt_s); 1026a36c61f9SKrishna Gudipati } 1027a36c61f9SKrishna Gudipati 1028a36c61f9SKrishna Gudipati static void 1029a36c61f9SKrishna Gudipati fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) 1030a36c61f9SKrishna Gudipati { 10316a18b167SJing Huang memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1032a36c61f9SKrishna Gudipati cthdr->rev_id = CT_GS3_REVISION; 1033a36c61f9SKrishna Gudipati cthdr->gs_type = CT_GSTYPE_DIRSERVICE; 1034a36c61f9SKrishna Gudipati cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER; 1035ba816ea8SJing Huang cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); 1036a36c61f9SKrishna Gudipati } 1037a36c61f9SKrishna Gudipati 1038a36c61f9SKrishna Gudipati static void 1039a36c61f9SKrishna Gudipati fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) 1040a36c61f9SKrishna Gudipati { 10416a18b167SJing Huang memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1042a36c61f9SKrishna Gudipati cthdr->rev_id = CT_GS3_REVISION; 1043a36c61f9SKrishna Gudipati cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; 1044a36c61f9SKrishna Gudipati cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER; 1045ba816ea8SJing Huang cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); 1046a36c61f9SKrishna Gudipati } 1047a36c61f9SKrishna Gudipati 1048a36c61f9SKrishna Gudipati static void 1049a36c61f9SKrishna Gudipati fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code, 1050a36c61f9SKrishna Gudipati u8 sub_type) 1051a36c61f9SKrishna Gudipati { 10526a18b167SJing Huang memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1053a36c61f9SKrishna Gudipati cthdr->rev_id = CT_GS3_REVISION; 1054a36c61f9SKrishna Gudipati cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; 1055a36c61f9SKrishna Gudipati cthdr->gs_sub_type = sub_type; 1056ba816ea8SJing Huang cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); 1057a36c61f9SKrishna Gudipati } 1058a36c61f9SKrishna Gudipati 1059a36c61f9SKrishna Gudipati u16 1060a36c61f9SKrishna Gudipati fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1061a36c61f9SKrishna Gudipati wwn_t port_name) 1062a36c61f9SKrishna Gudipati { 1063a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1064a36c61f9SKrishna Gudipati struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1); 1065f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1066a36c61f9SKrishna Gudipati 1067a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1068a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN); 1069a36c61f9SKrishna Gudipati 10706a18b167SJing Huang memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s)); 1071a36c61f9SKrishna Gudipati gidpn->port_name = port_name; 1072a36c61f9SKrishna Gudipati return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s); 1073a36c61f9SKrishna Gudipati } 1074a36c61f9SKrishna Gudipati 1075a36c61f9SKrishna Gudipati u16 1076a36c61f9SKrishna Gudipati fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1077a36c61f9SKrishna Gudipati u32 port_id) 1078a36c61f9SKrishna Gudipati { 1079a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1080a36c61f9SKrishna Gudipati fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1); 1081f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1082a36c61f9SKrishna Gudipati 1083a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1084a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID); 1085a36c61f9SKrishna Gudipati 10866a18b167SJing Huang memset(gpnid, 0, sizeof(fcgs_gpnid_req_t)); 1087a36c61f9SKrishna Gudipati gpnid->dap = port_id; 1088a36c61f9SKrishna Gudipati return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s); 1089a36c61f9SKrishna Gudipati } 1090a36c61f9SKrishna Gudipati 1091a36c61f9SKrishna Gudipati u16 1092a36c61f9SKrishna Gudipati fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1093a36c61f9SKrishna Gudipati u32 port_id) 1094a36c61f9SKrishna Gudipati { 1095a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1096a36c61f9SKrishna Gudipati fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1); 1097f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1098a36c61f9SKrishna Gudipati 1099a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1100a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID); 1101a36c61f9SKrishna Gudipati 11026a18b167SJing Huang memset(gnnid, 0, sizeof(fcgs_gnnid_req_t)); 1103a36c61f9SKrishna Gudipati gnnid->dap = port_id; 1104a36c61f9SKrishna Gudipati return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s); 1105a36c61f9SKrishna Gudipati } 1106a36c61f9SKrishna Gudipati 1107a36c61f9SKrishna Gudipati u16 1108a36c61f9SKrishna Gudipati fc_ct_rsp_parse(struct ct_hdr_s *cthdr) 1109a36c61f9SKrishna Gudipati { 1110ba816ea8SJing Huang if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) { 1111a36c61f9SKrishna Gudipati if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY) 1112a36c61f9SKrishna Gudipati return FC_PARSE_BUSY; 1113a36c61f9SKrishna Gudipati else 1114a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 1115a36c61f9SKrishna Gudipati } 1116a36c61f9SKrishna Gudipati 1117a36c61f9SKrishna Gudipati return FC_PARSE_OK; 1118a36c61f9SKrishna Gudipati } 1119a36c61f9SKrishna Gudipati 1120a36c61f9SKrishna Gudipati u16 1121d7be54ccSKrishna Gudipati fc_gs_rjt_build(struct fchs_s *fchs, struct ct_hdr_s *cthdr, 1122d7be54ccSKrishna Gudipati u32 d_id, u32 s_id, u16 ox_id, u8 reason_code, 1123d7be54ccSKrishna Gudipati u8 reason_code_expl) 1124d7be54ccSKrishna Gudipati { 1125d7be54ccSKrishna Gudipati fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id); 1126d7be54ccSKrishna Gudipati 1127d7be54ccSKrishna Gudipati cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT); 1128d7be54ccSKrishna Gudipati cthdr->rev_id = CT_GS3_REVISION; 1129d7be54ccSKrishna Gudipati 1130d7be54ccSKrishna Gudipati cthdr->reason_code = reason_code; 1131d7be54ccSKrishna Gudipati cthdr->exp_code = reason_code_expl; 1132d7be54ccSKrishna Gudipati return sizeof(struct ct_hdr_s); 1133d7be54ccSKrishna Gudipati } 1134d7be54ccSKrishna Gudipati 1135d7be54ccSKrishna Gudipati u16 1136a36c61f9SKrishna Gudipati fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, 1137a36c61f9SKrishna Gudipati u8 set_br_reg, u32 s_id, u16 ox_id) 1138a36c61f9SKrishna Gudipati { 1139f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER); 1140a36c61f9SKrishna Gudipati 1141a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 1142a36c61f9SKrishna Gudipati 11436a18b167SJing Huang memset(scr, 0, sizeof(struct fc_scr_s)); 1144a36c61f9SKrishna Gudipati scr->command = FC_ELS_SCR; 1145a36c61f9SKrishna Gudipati scr->reg_func = FC_SCR_REG_FUNC_FULL; 1146a36c61f9SKrishna Gudipati if (set_br_reg) 1147a36c61f9SKrishna Gudipati scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE; 1148a36c61f9SKrishna Gudipati 1149a36c61f9SKrishna Gudipati return sizeof(struct fc_scr_s); 1150a36c61f9SKrishna Gudipati } 1151a36c61f9SKrishna Gudipati 1152a36c61f9SKrishna Gudipati u16 1153a36c61f9SKrishna Gudipati fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, 1154a36c61f9SKrishna Gudipati u32 s_id, u16 ox_id) 1155a36c61f9SKrishna Gudipati { 1156f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER); 1157a36c61f9SKrishna Gudipati u16 payldlen; 1158a36c61f9SKrishna Gudipati 1159a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 1160a36c61f9SKrishna Gudipati rscn->command = FC_ELS_RSCN; 1161a36c61f9SKrishna Gudipati rscn->pagelen = sizeof(rscn->event[0]); 1162a36c61f9SKrishna Gudipati 1163a36c61f9SKrishna Gudipati payldlen = sizeof(u32) + rscn->pagelen; 1164ba816ea8SJing Huang rscn->payldlen = cpu_to_be16(payldlen); 1165a36c61f9SKrishna Gudipati 1166a36c61f9SKrishna Gudipati rscn->event[0].format = FC_RSCN_FORMAT_PORTID; 1167a36c61f9SKrishna Gudipati rscn->event[0].portid = s_id; 1168a36c61f9SKrishna Gudipati 1169a36c61f9SKrishna Gudipati return sizeof(struct fc_rscn_pl_s); 1170a36c61f9SKrishna Gudipati } 1171a36c61f9SKrishna Gudipati 1172a36c61f9SKrishna Gudipati u16 1173a36c61f9SKrishna Gudipati fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1174a36c61f9SKrishna Gudipati enum bfa_lport_role roles) 1175a36c61f9SKrishna Gudipati { 1176a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1177a36c61f9SKrishna Gudipati struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1); 1178f16a1750SMaggie Zhang u32 type_value, d_id = bfa_hton3b(FC_NAME_SERVER); 1179a36c61f9SKrishna Gudipati u8 index; 1180a36c61f9SKrishna Gudipati 1181a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1182a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); 1183a36c61f9SKrishna Gudipati 11846a18b167SJing Huang memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); 1185a36c61f9SKrishna Gudipati 1186a36c61f9SKrishna Gudipati rftid->dap = s_id; 1187a36c61f9SKrishna Gudipati 1188a36c61f9SKrishna Gudipati /* By default, FCP FC4 Type is registered */ 1189a36c61f9SKrishna Gudipati index = FC_TYPE_FCP >> 5; 1190a36c61f9SKrishna Gudipati type_value = 1 << (FC_TYPE_FCP % 32); 1191ba816ea8SJing Huang rftid->fc4_type[index] = cpu_to_be32(type_value); 1192a36c61f9SKrishna Gudipati 1193a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); 1194a36c61f9SKrishna Gudipati } 1195a36c61f9SKrishna Gudipati 1196a36c61f9SKrishna Gudipati u16 1197a36c61f9SKrishna Gudipati fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1198a36c61f9SKrishna Gudipati u8 *fc4_bitmap, u32 bitmap_size) 1199a36c61f9SKrishna Gudipati { 1200a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1201a36c61f9SKrishna Gudipati struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1); 1202f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1203a36c61f9SKrishna Gudipati 1204a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1205a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); 1206a36c61f9SKrishna Gudipati 12076a18b167SJing Huang memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); 1208a36c61f9SKrishna Gudipati 1209a36c61f9SKrishna Gudipati rftid->dap = s_id; 12106a18b167SJing Huang memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap, 1211a36c61f9SKrishna Gudipati (bitmap_size < 32 ? bitmap_size : 32)); 1212a36c61f9SKrishna Gudipati 1213a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); 1214a36c61f9SKrishna Gudipati } 1215a36c61f9SKrishna Gudipati 1216a36c61f9SKrishna Gudipati u16 1217a36c61f9SKrishna Gudipati fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1218a36c61f9SKrishna Gudipati u8 fc4_type, u8 fc4_ftrs) 1219a36c61f9SKrishna Gudipati { 1220a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1221a36c61f9SKrishna Gudipati struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1); 1222f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1223a36c61f9SKrishna Gudipati 1224a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1225a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID); 1226a36c61f9SKrishna Gudipati 12276a18b167SJing Huang memset(rffid, 0, sizeof(struct fcgs_rffid_req_s)); 1228a36c61f9SKrishna Gudipati 1229a36c61f9SKrishna Gudipati rffid->dap = s_id; 1230a36c61f9SKrishna Gudipati rffid->fc4ftr_bits = fc4_ftrs; 1231a36c61f9SKrishna Gudipati rffid->fc4_type = fc4_type; 1232a36c61f9SKrishna Gudipati 1233a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s); 1234a36c61f9SKrishna Gudipati } 1235a36c61f9SKrishna Gudipati 1236a36c61f9SKrishna Gudipati u16 1237a36c61f9SKrishna Gudipati fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1238a36c61f9SKrishna Gudipati u8 *name) 1239a36c61f9SKrishna Gudipati { 1240a36c61f9SKrishna Gudipati 1241a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1242a36c61f9SKrishna Gudipati struct fcgs_rspnid_req_s *rspnid = 1243a36c61f9SKrishna Gudipati (struct fcgs_rspnid_req_s *)(cthdr + 1); 1244f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1245a36c61f9SKrishna Gudipati 1246a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1247a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID); 1248a36c61f9SKrishna Gudipati 12496a18b167SJing Huang memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s)); 1250a36c61f9SKrishna Gudipati 1251a36c61f9SKrishna Gudipati rspnid->dap = s_id; 1252a36c61f9SKrishna Gudipati rspnid->spn_len = (u8) strlen((char *)name); 1253a36c61f9SKrishna Gudipati strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len); 1254a36c61f9SKrishna Gudipati 1255a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s); 1256a36c61f9SKrishna Gudipati } 1257a36c61f9SKrishna Gudipati 1258a36c61f9SKrishna Gudipati u16 1259ce7242b8SKrishna Gudipati fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id, 1260ce7242b8SKrishna Gudipati wwn_t node_name, u8 *name) 1261ce7242b8SKrishna Gudipati { 1262ce7242b8SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1263ce7242b8SKrishna Gudipati struct fcgs_rsnn_nn_req_s *rsnn_nn = 1264ce7242b8SKrishna Gudipati (struct fcgs_rsnn_nn_req_s *) (cthdr + 1); 1265ce7242b8SKrishna Gudipati u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1266ce7242b8SKrishna Gudipati 1267ce7242b8SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1268ce7242b8SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RSNN_NN); 1269ce7242b8SKrishna Gudipati 1270ce7242b8SKrishna Gudipati memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s)); 1271ce7242b8SKrishna Gudipati 1272ce7242b8SKrishna Gudipati rsnn_nn->node_name = node_name; 1273ce7242b8SKrishna Gudipati rsnn_nn->snn_len = (u8) strlen((char *)name); 1274ce7242b8SKrishna Gudipati strncpy((char *)rsnn_nn->snn, (char *)name, rsnn_nn->snn_len); 1275ce7242b8SKrishna Gudipati 1276ce7242b8SKrishna Gudipati return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s); 1277ce7242b8SKrishna Gudipati } 1278ce7242b8SKrishna Gudipati 1279ce7242b8SKrishna Gudipati u16 1280a36c61f9SKrishna Gudipati fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type) 1281a36c61f9SKrishna Gudipati { 1282a36c61f9SKrishna Gudipati 1283a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1284a36c61f9SKrishna Gudipati struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1); 1285f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1286a36c61f9SKrishna Gudipati 1287a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1288a36c61f9SKrishna Gudipati 1289a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT); 1290a36c61f9SKrishna Gudipati 12916a18b167SJing Huang memset(gidft, 0, sizeof(struct fcgs_gidft_req_s)); 1292a36c61f9SKrishna Gudipati gidft->fc4_type = fc4_type; 1293a36c61f9SKrishna Gudipati gidft->domain_id = 0; 1294a36c61f9SKrishna Gudipati gidft->area_id = 0; 1295a36c61f9SKrishna Gudipati 1296a36c61f9SKrishna Gudipati return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s); 1297a36c61f9SKrishna Gudipati } 1298a36c61f9SKrishna Gudipati 1299a36c61f9SKrishna Gudipati u16 1300a36c61f9SKrishna Gudipati fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1301a36c61f9SKrishna Gudipati wwn_t port_name) 1302a36c61f9SKrishna Gudipati { 1303a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1304a36c61f9SKrishna Gudipati struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1); 1305f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1306a36c61f9SKrishna Gudipati 1307a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1308a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID); 1309a36c61f9SKrishna Gudipati 13106a18b167SJing Huang memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s)); 1311a36c61f9SKrishna Gudipati rpnid->port_id = port_id; 1312a36c61f9SKrishna Gudipati rpnid->port_name = port_name; 1313a36c61f9SKrishna Gudipati 1314a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s); 1315a36c61f9SKrishna Gudipati } 1316a36c61f9SKrishna Gudipati 1317a36c61f9SKrishna Gudipati u16 1318a36c61f9SKrishna Gudipati fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1319a36c61f9SKrishna Gudipati wwn_t node_name) 1320a36c61f9SKrishna Gudipati { 1321a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1322a36c61f9SKrishna Gudipati struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1); 1323f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1324a36c61f9SKrishna Gudipati 1325a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1326a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID); 1327a36c61f9SKrishna Gudipati 13286a18b167SJing Huang memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s)); 1329a36c61f9SKrishna Gudipati rnnid->port_id = port_id; 1330a36c61f9SKrishna Gudipati rnnid->node_name = node_name; 1331a36c61f9SKrishna Gudipati 1332a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s); 1333a36c61f9SKrishna Gudipati } 1334a36c61f9SKrishna Gudipati 1335a36c61f9SKrishna Gudipati u16 1336a36c61f9SKrishna Gudipati fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1337a36c61f9SKrishna Gudipati u32 cos) 1338a36c61f9SKrishna Gudipati { 1339a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1340a36c61f9SKrishna Gudipati struct fcgs_rcsid_req_s *rcsid = 1341a36c61f9SKrishna Gudipati (struct fcgs_rcsid_req_s *) (cthdr + 1); 1342f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1343a36c61f9SKrishna Gudipati 1344a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1345a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID); 1346a36c61f9SKrishna Gudipati 13476a18b167SJing Huang memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s)); 1348a36c61f9SKrishna Gudipati rcsid->port_id = port_id; 1349a36c61f9SKrishna Gudipati rcsid->cos = cos; 1350a36c61f9SKrishna Gudipati 1351a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s); 1352a36c61f9SKrishna Gudipati } 1353a36c61f9SKrishna Gudipati 1354a36c61f9SKrishna Gudipati u16 1355a36c61f9SKrishna Gudipati fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1356a36c61f9SKrishna Gudipati u8 port_type) 1357a36c61f9SKrishna Gudipati { 1358a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1359a36c61f9SKrishna Gudipati struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1); 1360f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1361a36c61f9SKrishna Gudipati 1362a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1363a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID); 1364a36c61f9SKrishna Gudipati 13656a18b167SJing Huang memset(rptid, 0, sizeof(struct fcgs_rptid_req_s)); 1366a36c61f9SKrishna Gudipati rptid->port_id = port_id; 1367a36c61f9SKrishna Gudipati rptid->port_type = port_type; 1368a36c61f9SKrishna Gudipati 1369a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s); 1370a36c61f9SKrishna Gudipati } 1371a36c61f9SKrishna Gudipati 1372a36c61f9SKrishna Gudipati u16 1373a36c61f9SKrishna Gudipati fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id) 1374a36c61f9SKrishna Gudipati { 1375a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1376a36c61f9SKrishna Gudipati struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1); 1377f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1378a36c61f9SKrishna Gudipati 1379a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1380a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT); 1381a36c61f9SKrishna Gudipati 13826a18b167SJing Huang memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s)); 1383a36c61f9SKrishna Gudipati ganxt->port_id = port_id; 1384a36c61f9SKrishna Gudipati 1385a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s); 1386a36c61f9SKrishna Gudipati } 1387a36c61f9SKrishna Gudipati 1388a36c61f9SKrishna Gudipati /* 1389a36c61f9SKrishna Gudipati * Builds fc hdr and ct hdr for FDMI requests. 1390a36c61f9SKrishna Gudipati */ 1391a36c61f9SKrishna Gudipati u16 1392a36c61f9SKrishna Gudipati fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id, 1393a36c61f9SKrishna Gudipati u16 cmd_code) 1394a36c61f9SKrishna Gudipati { 1395a36c61f9SKrishna Gudipati 1396a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1397f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_MGMT_SERVER); 1398a36c61f9SKrishna Gudipati 1399a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1400a36c61f9SKrishna Gudipati fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code); 1401a36c61f9SKrishna Gudipati 1402a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s); 1403a36c61f9SKrishna Gudipati } 1404a36c61f9SKrishna Gudipati 1405a36c61f9SKrishna Gudipati /* 1406a36c61f9SKrishna Gudipati * Given a FC4 Type, this function returns a fc4 type bitmask 1407a36c61f9SKrishna Gudipati */ 1408a36c61f9SKrishna Gudipati void 1409a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask) 1410a36c61f9SKrishna Gudipati { 1411a36c61f9SKrishna Gudipati u8 index; 141250444a34SMaggie __be32 *ptr = (__be32 *) bit_mask; 1413a36c61f9SKrishna Gudipati u32 type_value; 1414a36c61f9SKrishna Gudipati 1415a36c61f9SKrishna Gudipati /* 1416a36c61f9SKrishna Gudipati * @todo : Check for bitmask size 1417a36c61f9SKrishna Gudipati */ 1418a36c61f9SKrishna Gudipati 1419a36c61f9SKrishna Gudipati index = fc4_type >> 5; 1420a36c61f9SKrishna Gudipati type_value = 1 << (fc4_type % 32); 1421ba816ea8SJing Huang ptr[index] = cpu_to_be32(type_value); 1422a36c61f9SKrishna Gudipati 1423a36c61f9SKrishna Gudipati } 1424a36c61f9SKrishna Gudipati 1425a36c61f9SKrishna Gudipati /* 1426a36c61f9SKrishna Gudipati * GMAL Request 1427a36c61f9SKrishna Gudipati */ 1428a36c61f9SKrishna Gudipati u16 1429a36c61f9SKrishna Gudipati fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) 1430a36c61f9SKrishna Gudipati { 1431a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1432a36c61f9SKrishna Gudipati fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1); 1433f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_MGMT_SERVER); 1434a36c61f9SKrishna Gudipati 1435a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1436a36c61f9SKrishna Gudipati fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD, 1437a36c61f9SKrishna Gudipati CT_GSSUBTYPE_CFGSERVER); 1438a36c61f9SKrishna Gudipati 14396a18b167SJing Huang memset(gmal, 0, sizeof(fcgs_gmal_req_t)); 1440a36c61f9SKrishna Gudipati gmal->wwn = wwn; 1441a36c61f9SKrishna Gudipati 1442a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t); 1443a36c61f9SKrishna Gudipati } 1444a36c61f9SKrishna Gudipati 1445a36c61f9SKrishna Gudipati /* 1446a36c61f9SKrishna Gudipati * GFN (Get Fabric Name) Request 1447a36c61f9SKrishna Gudipati */ 1448a36c61f9SKrishna Gudipati u16 1449a36c61f9SKrishna Gudipati fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) 1450a36c61f9SKrishna Gudipati { 1451a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1452a36c61f9SKrishna Gudipati fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1); 1453f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_MGMT_SERVER); 1454a36c61f9SKrishna Gudipati 1455a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1456a36c61f9SKrishna Gudipati fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD, 1457a36c61f9SKrishna Gudipati CT_GSSUBTYPE_CFGSERVER); 1458a36c61f9SKrishna Gudipati 14596a18b167SJing Huang memset(gfn, 0, sizeof(fcgs_gfn_req_t)); 1460a36c61f9SKrishna Gudipati gfn->wwn = wwn; 1461a36c61f9SKrishna Gudipati 1462a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t); 1463a36c61f9SKrishna Gudipati } 1464