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 158a36c61f9SKrishna Gudipati void 15950444a34SMaggie fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) 160a36c61f9SKrishna Gudipati { 1616a18b167SJing Huang memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s)); 162a36c61f9SKrishna Gudipati fchs->d_id = (d_id); 163a36c61f9SKrishna Gudipati fchs->s_id = (s_id); 164ba816ea8SJing Huang fchs->ox_id = cpu_to_be16(ox_id); 165a36c61f9SKrishna Gudipati } 166a36c61f9SKrishna Gudipati 167a36c61f9SKrishna Gudipati static void 16850444a34SMaggie fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) 169a36c61f9SKrishna Gudipati { 1706a18b167SJing Huang memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s)); 171a36c61f9SKrishna Gudipati fchs->d_id = d_id; 172a36c61f9SKrishna Gudipati fchs->s_id = s_id; 173a36c61f9SKrishna Gudipati fchs->ox_id = ox_id; 174a36c61f9SKrishna Gudipati } 175a36c61f9SKrishna Gudipati 176a36c61f9SKrishna Gudipati enum fc_parse_status 177a36c61f9SKrishna Gudipati fc_els_rsp_parse(struct fchs_s *fchs, int len) 178a36c61f9SKrishna Gudipati { 179a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 180a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt = (struct fc_ls_rjt_s *) els_cmd; 181a36c61f9SKrishna Gudipati 182a36c61f9SKrishna Gudipati len = len; 183a36c61f9SKrishna Gudipati 184a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 185a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 186a36c61f9SKrishna Gudipati if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) 187a36c61f9SKrishna Gudipati return FC_PARSE_BUSY; 188a36c61f9SKrishna Gudipati else 189a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 190a36c61f9SKrishna Gudipati 191a36c61f9SKrishna Gudipati case FC_ELS_ACC: 192a36c61f9SKrishna Gudipati return FC_PARSE_OK; 193a36c61f9SKrishna Gudipati } 194a36c61f9SKrishna Gudipati return FC_PARSE_OK; 195a36c61f9SKrishna Gudipati } 196a36c61f9SKrishna Gudipati 197a36c61f9SKrishna Gudipati static void 19850444a34SMaggie fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) 199a36c61f9SKrishna Gudipati { 2006a18b167SJing Huang memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s)); 201a36c61f9SKrishna Gudipati fchs->d_id = d_id; 202a36c61f9SKrishna Gudipati fchs->s_id = s_id; 203a36c61f9SKrishna Gudipati fchs->ox_id = ox_id; 204a36c61f9SKrishna Gudipati } 205a36c61f9SKrishna Gudipati 206a36c61f9SKrishna Gudipati static u16 207a36c61f9SKrishna Gudipati fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 20850444a34SMaggie __be16 ox_id, wwn_t port_name, wwn_t node_name, 209*be540a99SKrishna Gudipati u16 pdu_size, u16 bb_cr, u8 els_code) 210a36c61f9SKrishna Gudipati { 211a36c61f9SKrishna Gudipati struct fc_logi_s *plogi = (struct fc_logi_s *) (pld); 212a36c61f9SKrishna Gudipati 2136a18b167SJing Huang memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 214a36c61f9SKrishna Gudipati 215a36c61f9SKrishna Gudipati plogi->els_cmd.els_code = els_code; 216a36c61f9SKrishna Gudipati if (els_code == FC_ELS_PLOGI) 217a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 218a36c61f9SKrishna Gudipati else 219a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 220a36c61f9SKrishna Gudipati 221ba816ea8SJing Huang plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size); 222*be540a99SKrishna Gudipati plogi->csp.bbcred = cpu_to_be16(bb_cr); 223a36c61f9SKrishna Gudipati 2246a18b167SJing Huang memcpy(&plogi->port_name, &port_name, sizeof(wwn_t)); 2256a18b167SJing Huang memcpy(&plogi->node_name, &node_name, sizeof(wwn_t)); 226a36c61f9SKrishna Gudipati 227a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 228a36c61f9SKrishna Gudipati } 229a36c61f9SKrishna Gudipati 230a36c61f9SKrishna Gudipati u16 231a36c61f9SKrishna Gudipati fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 232a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size, 233a36c61f9SKrishna Gudipati u8 set_npiv, u8 set_auth, u16 local_bb_credits) 234a36c61f9SKrishna Gudipati { 235f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_PORT); 23650444a34SMaggie __be32 *vvl_info; 237a36c61f9SKrishna Gudipati 2386a18b167SJing Huang memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 239a36c61f9SKrishna Gudipati 240a36c61f9SKrishna Gudipati flogi->els_cmd.els_code = FC_ELS_FLOGI; 241a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 242a36c61f9SKrishna Gudipati 243ba816ea8SJing Huang flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size); 244a36c61f9SKrishna Gudipati flogi->port_name = port_name; 245a36c61f9SKrishna Gudipati flogi->node_name = node_name; 246a36c61f9SKrishna Gudipati 247a36c61f9SKrishna Gudipati /* 248a36c61f9SKrishna Gudipati * Set the NPIV Capability Bit ( word 1, bit 31) of Common 249a36c61f9SKrishna Gudipati * Service Parameters. 250a36c61f9SKrishna Gudipati */ 251a36c61f9SKrishna Gudipati flogi->csp.ciro = set_npiv; 252a36c61f9SKrishna Gudipati 253a36c61f9SKrishna Gudipati /* set AUTH capability */ 254a36c61f9SKrishna Gudipati flogi->csp.security = set_auth; 255a36c61f9SKrishna Gudipati 256ba816ea8SJing Huang flogi->csp.bbcred = cpu_to_be16(local_bb_credits); 257a36c61f9SKrishna Gudipati 258a36c61f9SKrishna Gudipati /* Set brcd token in VVL */ 259a36c61f9SKrishna Gudipati vvl_info = (u32 *)&flogi->vvl[0]; 260a36c61f9SKrishna Gudipati 261a36c61f9SKrishna Gudipati /* set the flag to indicate the presence of VVL */ 262a36c61f9SKrishna Gudipati flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */ 263ba816ea8SJing Huang vvl_info[0] = cpu_to_be32(FLOGI_VVL_BRCD); 264a36c61f9SKrishna Gudipati 265a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 266a36c61f9SKrishna Gudipati } 267a36c61f9SKrishna Gudipati 268a36c61f9SKrishna Gudipati u16 269a36c61f9SKrishna Gudipati fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 27050444a34SMaggie __be16 ox_id, wwn_t port_name, wwn_t node_name, 271*be540a99SKrishna Gudipati u16 pdu_size, u16 local_bb_credits, u8 bb_scn) 272a36c61f9SKrishna Gudipati { 273a36c61f9SKrishna Gudipati u32 d_id = 0; 274*be540a99SKrishna Gudipati u16 bbscn_rxsz = (bb_scn << 12) | pdu_size; 275a36c61f9SKrishna Gudipati 2766a18b167SJing Huang memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 277a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 278a36c61f9SKrishna Gudipati 279a36c61f9SKrishna Gudipati flogi->els_cmd.els_code = FC_ELS_ACC; 280*be540a99SKrishna Gudipati flogi->class3.rxsz = cpu_to_be16(pdu_size); 281*be540a99SKrishna Gudipati flogi->csp.rxsz = cpu_to_be16(bbscn_rxsz); /* bb_scn/rxsz */ 282a36c61f9SKrishna Gudipati flogi->port_name = port_name; 283a36c61f9SKrishna Gudipati flogi->node_name = node_name; 284a36c61f9SKrishna Gudipati 285ba816ea8SJing Huang flogi->csp.bbcred = cpu_to_be16(local_bb_credits); 286a36c61f9SKrishna Gudipati 287a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 288a36c61f9SKrishna Gudipati } 289a36c61f9SKrishna Gudipati 290a36c61f9SKrishna Gudipati u16 291a36c61f9SKrishna Gudipati fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, 292a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size) 293a36c61f9SKrishna Gudipati { 294f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_PORT); 295a36c61f9SKrishna Gudipati 2966a18b167SJing Huang memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); 297a36c61f9SKrishna Gudipati 298a36c61f9SKrishna Gudipati flogi->els_cmd.els_code = FC_ELS_FDISC; 299a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 300a36c61f9SKrishna Gudipati 301ba816ea8SJing Huang flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size); 302a36c61f9SKrishna Gudipati flogi->port_name = port_name; 303a36c61f9SKrishna Gudipati flogi->node_name = node_name; 304a36c61f9SKrishna Gudipati 305a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 306a36c61f9SKrishna Gudipati } 307a36c61f9SKrishna Gudipati 308a36c61f9SKrishna Gudipati u16 309a36c61f9SKrishna Gudipati fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 310a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, 311*be540a99SKrishna Gudipati u16 pdu_size, u16 bb_cr) 312a36c61f9SKrishna Gudipati { 313a36c61f9SKrishna Gudipati return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, 314*be540a99SKrishna Gudipati node_name, pdu_size, bb_cr, FC_ELS_PLOGI); 315a36c61f9SKrishna Gudipati } 316a36c61f9SKrishna Gudipati 317a36c61f9SKrishna Gudipati u16 318a36c61f9SKrishna Gudipati fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 319a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name, wwn_t node_name, 320*be540a99SKrishna Gudipati u16 pdu_size, u16 bb_cr) 321a36c61f9SKrishna Gudipati { 322a36c61f9SKrishna Gudipati return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, 323*be540a99SKrishna Gudipati node_name, pdu_size, bb_cr, FC_ELS_ACC); 324a36c61f9SKrishna Gudipati } 325a36c61f9SKrishna Gudipati 326a36c61f9SKrishna Gudipati enum fc_parse_status 327a36c61f9SKrishna Gudipati fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) 328a36c61f9SKrishna Gudipati { 329a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 330a36c61f9SKrishna Gudipati struct fc_logi_s *plogi; 331a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 332a36c61f9SKrishna Gudipati 333a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 334a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 335a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1); 336a36c61f9SKrishna Gudipati if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) 337a36c61f9SKrishna Gudipati return FC_PARSE_BUSY; 338a36c61f9SKrishna Gudipati else 339a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 340a36c61f9SKrishna Gudipati case FC_ELS_ACC: 341a36c61f9SKrishna Gudipati plogi = (struct fc_logi_s *) (fchs + 1); 342a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_logi_s)) 343a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 344a36c61f9SKrishna Gudipati 345a36c61f9SKrishna Gudipati if (!wwn_is_equal(plogi->port_name, port_name)) 346a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 347a36c61f9SKrishna Gudipati 348a36c61f9SKrishna Gudipati if (!plogi->class3.class_valid) 349a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 350a36c61f9SKrishna Gudipati 351ba816ea8SJing Huang if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ)) 352a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 353a36c61f9SKrishna Gudipati 354a36c61f9SKrishna Gudipati return FC_PARSE_OK; 355a36c61f9SKrishna Gudipati default: 356a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 357a36c61f9SKrishna Gudipati } 358a36c61f9SKrishna Gudipati } 359a36c61f9SKrishna Gudipati 360a36c61f9SKrishna Gudipati enum fc_parse_status 361a36c61f9SKrishna Gudipati fc_plogi_parse(struct fchs_s *fchs) 362a36c61f9SKrishna Gudipati { 363a36c61f9SKrishna Gudipati struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1); 364a36c61f9SKrishna Gudipati 365a36c61f9SKrishna Gudipati if (plogi->class3.class_valid != 1) 366a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 367a36c61f9SKrishna Gudipati 368ba816ea8SJing Huang if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ) 369ba816ea8SJing Huang || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ) 370a36c61f9SKrishna Gudipati || (plogi->class3.rxsz == 0)) 371a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 372a36c61f9SKrishna Gudipati 373a36c61f9SKrishna Gudipati return FC_PARSE_OK; 374a36c61f9SKrishna Gudipati } 375a36c61f9SKrishna Gudipati 376a36c61f9SKrishna Gudipati u16 377a36c61f9SKrishna Gudipati fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 378a36c61f9SKrishna Gudipati u16 ox_id) 379a36c61f9SKrishna Gudipati { 380a36c61f9SKrishna Gudipati struct fc_prli_s *prli = (struct fc_prli_s *) (pld); 381a36c61f9SKrishna Gudipati 382a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 3836a18b167SJing Huang memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); 384a36c61f9SKrishna Gudipati 385a36c61f9SKrishna Gudipati prli->command = FC_ELS_PRLI; 386a36c61f9SKrishna Gudipati prli->parampage.servparams.initiator = 1; 387a36c61f9SKrishna Gudipati prli->parampage.servparams.retry = 1; 388a36c61f9SKrishna Gudipati prli->parampage.servparams.rec_support = 1; 389a36c61f9SKrishna Gudipati prli->parampage.servparams.task_retry_id = 0; 390a36c61f9SKrishna Gudipati prli->parampage.servparams.confirm = 1; 391a36c61f9SKrishna Gudipati 392a36c61f9SKrishna Gudipati return sizeof(struct fc_prli_s); 393a36c61f9SKrishna Gudipati } 394a36c61f9SKrishna Gudipati 395a36c61f9SKrishna Gudipati u16 396a36c61f9SKrishna Gudipati fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 39750444a34SMaggie __be16 ox_id, enum bfa_lport_role role) 398a36c61f9SKrishna Gudipati { 399a36c61f9SKrishna Gudipati struct fc_prli_s *prli = (struct fc_prli_s *) (pld); 400a36c61f9SKrishna Gudipati 401a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 4026a18b167SJing Huang memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); 403a36c61f9SKrishna Gudipati 404a36c61f9SKrishna Gudipati prli->command = FC_ELS_ACC; 405a36c61f9SKrishna Gudipati 406a36c61f9SKrishna Gudipati prli->parampage.servparams.initiator = 1; 407a36c61f9SKrishna Gudipati 408a36c61f9SKrishna Gudipati prli->parampage.rspcode = FC_PRLI_ACC_XQTD; 409a36c61f9SKrishna Gudipati 410a36c61f9SKrishna Gudipati return sizeof(struct fc_prli_s); 411a36c61f9SKrishna Gudipati } 412a36c61f9SKrishna Gudipati 413a36c61f9SKrishna Gudipati enum fc_parse_status 414a36c61f9SKrishna Gudipati fc_prli_rsp_parse(struct fc_prli_s *prli, int len) 415a36c61f9SKrishna Gudipati { 416a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_prli_s)) 417a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 418a36c61f9SKrishna Gudipati 419a36c61f9SKrishna Gudipati if (prli->command != FC_ELS_ACC) 420a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 421a36c61f9SKrishna Gudipati 422a36c61f9SKrishna Gudipati if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD) 423a36c61f9SKrishna Gudipati && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG)) 424a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 425a36c61f9SKrishna Gudipati 426a36c61f9SKrishna Gudipati if (prli->parampage.servparams.target != 1) 427a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 428a36c61f9SKrishna Gudipati 429a36c61f9SKrishna Gudipati return FC_PARSE_OK; 430a36c61f9SKrishna Gudipati } 431a36c61f9SKrishna Gudipati 432a36c61f9SKrishna Gudipati enum fc_parse_status 433a36c61f9SKrishna Gudipati fc_prli_parse(struct fc_prli_s *prli) 434a36c61f9SKrishna Gudipati { 435a36c61f9SKrishna Gudipati if (prli->parampage.type != FC_TYPE_FCP) 436a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 437a36c61f9SKrishna Gudipati 438a36c61f9SKrishna Gudipati if (!prli->parampage.imagepair) 439a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 440a36c61f9SKrishna Gudipati 441a36c61f9SKrishna Gudipati if (!prli->parampage.servparams.initiator) 442a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 443a36c61f9SKrishna Gudipati 444a36c61f9SKrishna Gudipati return FC_PARSE_OK; 445a36c61f9SKrishna Gudipati } 446a36c61f9SKrishna Gudipati 447a36c61f9SKrishna Gudipati u16 448a36c61f9SKrishna Gudipati fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id, 449a36c61f9SKrishna Gudipati u16 ox_id, wwn_t port_name) 450a36c61f9SKrishna Gudipati { 451a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 452a36c61f9SKrishna Gudipati 4536a18b167SJing Huang memset(logo, '\0', sizeof(struct fc_logo_s)); 454a36c61f9SKrishna Gudipati logo->els_cmd.els_code = FC_ELS_LOGO; 455a36c61f9SKrishna Gudipati logo->nport_id = (s_id); 456a36c61f9SKrishna Gudipati logo->orig_port_name = port_name; 457a36c61f9SKrishna Gudipati 458a36c61f9SKrishna Gudipati return sizeof(struct fc_logo_s); 459a36c61f9SKrishna Gudipati } 460a36c61f9SKrishna Gudipati 461a36c61f9SKrishna Gudipati static u16 462a36c61f9SKrishna Gudipati fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 46350444a34SMaggie u32 s_id, __be16 ox_id, wwn_t port_name, 464a36c61f9SKrishna Gudipati wwn_t node_name, u8 els_code) 465a36c61f9SKrishna Gudipati { 4666a18b167SJing Huang memset(adisc, '\0', sizeof(struct fc_adisc_s)); 467a36c61f9SKrishna Gudipati 468a36c61f9SKrishna Gudipati adisc->els_cmd.els_code = els_code; 469a36c61f9SKrishna Gudipati 470a36c61f9SKrishna Gudipati if (els_code == FC_ELS_ADISC) 471a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 472a36c61f9SKrishna Gudipati else 473a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 474a36c61f9SKrishna Gudipati 475a36c61f9SKrishna Gudipati adisc->orig_HA = 0; 476a36c61f9SKrishna Gudipati adisc->orig_port_name = port_name; 477a36c61f9SKrishna Gudipati adisc->orig_node_name = node_name; 478a36c61f9SKrishna Gudipati adisc->nport_id = (s_id); 479a36c61f9SKrishna Gudipati 480a36c61f9SKrishna Gudipati return sizeof(struct fc_adisc_s); 481a36c61f9SKrishna Gudipati } 482a36c61f9SKrishna Gudipati 483a36c61f9SKrishna Gudipati u16 484a36c61f9SKrishna Gudipati fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 48550444a34SMaggie u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name) 486a36c61f9SKrishna Gudipati { 487a36c61f9SKrishna Gudipati return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, 488a36c61f9SKrishna Gudipati node_name, FC_ELS_ADISC); 489a36c61f9SKrishna Gudipati } 490a36c61f9SKrishna Gudipati 491a36c61f9SKrishna Gudipati u16 492a36c61f9SKrishna Gudipati fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, 49350444a34SMaggie u32 s_id, __be16 ox_id, wwn_t port_name, 494a36c61f9SKrishna Gudipati wwn_t node_name) 495a36c61f9SKrishna Gudipati { 496a36c61f9SKrishna Gudipati return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, 497a36c61f9SKrishna Gudipati node_name, FC_ELS_ACC); 498a36c61f9SKrishna Gudipati } 499a36c61f9SKrishna Gudipati 500a36c61f9SKrishna Gudipati enum fc_parse_status 501a36c61f9SKrishna Gudipati fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name, 502a36c61f9SKrishna Gudipati wwn_t node_name) 503a36c61f9SKrishna Gudipati { 504a36c61f9SKrishna Gudipati 505a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_adisc_s)) 506a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 507a36c61f9SKrishna Gudipati 508a36c61f9SKrishna Gudipati if (adisc->els_cmd.els_code != FC_ELS_ACC) 509a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 510a36c61f9SKrishna Gudipati 511a36c61f9SKrishna Gudipati if (!wwn_is_equal(adisc->orig_port_name, port_name)) 512a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 513a36c61f9SKrishna Gudipati 514a36c61f9SKrishna Gudipati return FC_PARSE_OK; 515a36c61f9SKrishna Gudipati } 516a36c61f9SKrishna Gudipati 517a36c61f9SKrishna Gudipati enum fc_parse_status 518a36c61f9SKrishna Gudipati fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name, 519a36c61f9SKrishna Gudipati wwn_t port_name) 520a36c61f9SKrishna Gudipati { 521a36c61f9SKrishna Gudipati struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld; 522a36c61f9SKrishna Gudipati 523a36c61f9SKrishna Gudipati if (adisc->els_cmd.els_code != FC_ELS_ACC) 524a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 525a36c61f9SKrishna Gudipati 526a36c61f9SKrishna Gudipati if ((adisc->nport_id == (host_dap)) 527a36c61f9SKrishna Gudipati && wwn_is_equal(adisc->orig_port_name, port_name) 528a36c61f9SKrishna Gudipati && wwn_is_equal(adisc->orig_node_name, node_name)) 529a36c61f9SKrishna Gudipati return FC_PARSE_OK; 530a36c61f9SKrishna Gudipati 531a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 532a36c61f9SKrishna Gudipati } 533a36c61f9SKrishna Gudipati 534a36c61f9SKrishna Gudipati enum fc_parse_status 535a36c61f9SKrishna Gudipati fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name) 536a36c61f9SKrishna Gudipati { 537a36c61f9SKrishna Gudipati struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 538a36c61f9SKrishna Gudipati 539a36c61f9SKrishna Gudipati if (pdisc->class3.class_valid != 1) 540a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 541a36c61f9SKrishna Gudipati 542ba816ea8SJing Huang if ((be16_to_cpu(pdisc->class3.rxsz) < 543a36c61f9SKrishna Gudipati (FC_MIN_PDUSZ - sizeof(struct fchs_s))) 544a36c61f9SKrishna Gudipati || (pdisc->class3.rxsz == 0)) 545a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 546a36c61f9SKrishna Gudipati 547a36c61f9SKrishna Gudipati if (!wwn_is_equal(pdisc->port_name, port_name)) 548a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 549a36c61f9SKrishna Gudipati 550a36c61f9SKrishna Gudipati if (!wwn_is_equal(pdisc->node_name, node_name)) 551a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 552a36c61f9SKrishna Gudipati 553a36c61f9SKrishna Gudipati return FC_PARSE_OK; 554a36c61f9SKrishna Gudipati } 555a36c61f9SKrishna Gudipati 556a36c61f9SKrishna Gudipati u16 557a36c61f9SKrishna Gudipati fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) 558a36c61f9SKrishna Gudipati { 5596a18b167SJing Huang memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s)); 560a36c61f9SKrishna Gudipati fchs->cat_info = FC_CAT_ABTS; 561a36c61f9SKrishna Gudipati fchs->d_id = (d_id); 562a36c61f9SKrishna Gudipati fchs->s_id = (s_id); 563ba816ea8SJing Huang fchs->ox_id = cpu_to_be16(ox_id); 564a36c61f9SKrishna Gudipati 565a36c61f9SKrishna Gudipati return sizeof(struct fchs_s); 566a36c61f9SKrishna Gudipati } 567a36c61f9SKrishna Gudipati 568a36c61f9SKrishna Gudipati enum fc_parse_status 569a36c61f9SKrishna Gudipati fc_abts_rsp_parse(struct fchs_s *fchs, int len) 570a36c61f9SKrishna Gudipati { 571a36c61f9SKrishna Gudipati if ((fchs->cat_info == FC_CAT_BA_ACC) 572a36c61f9SKrishna Gudipati || (fchs->cat_info == FC_CAT_BA_RJT)) 573a36c61f9SKrishna Gudipati return FC_PARSE_OK; 574a36c61f9SKrishna Gudipati 575a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 576a36c61f9SKrishna Gudipati } 577a36c61f9SKrishna Gudipati 578a36c61f9SKrishna Gudipati u16 579a36c61f9SKrishna Gudipati fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id, 580a36c61f9SKrishna Gudipati u16 ox_id, u16 rrq_oxid) 581a36c61f9SKrishna Gudipati { 582a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 583a36c61f9SKrishna Gudipati 584a36c61f9SKrishna Gudipati /* 585a36c61f9SKrishna Gudipati * build rrq payload 586a36c61f9SKrishna Gudipati */ 5876a18b167SJing Huang memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s)); 588a36c61f9SKrishna Gudipati rrq->s_id = (s_id); 589ba816ea8SJing Huang rrq->ox_id = cpu_to_be16(rrq_oxid); 590a36c61f9SKrishna Gudipati rrq->rx_id = FC_RXID_ANY; 591a36c61f9SKrishna Gudipati 592a36c61f9SKrishna Gudipati return sizeof(struct fc_rrq_s); 593a36c61f9SKrishna Gudipati } 594a36c61f9SKrishna Gudipati 595a36c61f9SKrishna Gudipati u16 596a36c61f9SKrishna Gudipati fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, 59750444a34SMaggie __be16 ox_id) 598a36c61f9SKrishna Gudipati { 599a36c61f9SKrishna Gudipati struct fc_els_cmd_s *acc = pld; 600a36c61f9SKrishna Gudipati 601a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 602a36c61f9SKrishna Gudipati 6036a18b167SJing Huang memset(acc, 0, sizeof(struct fc_els_cmd_s)); 604a36c61f9SKrishna Gudipati acc->els_code = FC_ELS_ACC; 605a36c61f9SKrishna Gudipati 606a36c61f9SKrishna Gudipati return sizeof(struct fc_els_cmd_s); 607a36c61f9SKrishna Gudipati } 608a36c61f9SKrishna Gudipati 609a36c61f9SKrishna Gudipati u16 610a36c61f9SKrishna Gudipati fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id, 61150444a34SMaggie u32 s_id, __be16 ox_id, u8 reason_code, 612a36c61f9SKrishna Gudipati u8 reason_code_expl) 613a36c61f9SKrishna Gudipati { 614a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 6156a18b167SJing Huang memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s)); 616a36c61f9SKrishna Gudipati 617a36c61f9SKrishna Gudipati ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT; 618a36c61f9SKrishna Gudipati ls_rjt->reason_code = reason_code; 619a36c61f9SKrishna Gudipati ls_rjt->reason_code_expl = reason_code_expl; 620a36c61f9SKrishna Gudipati ls_rjt->vendor_unique = 0x00; 621a36c61f9SKrishna Gudipati 622a36c61f9SKrishna Gudipati return sizeof(struct fc_ls_rjt_s); 623a36c61f9SKrishna Gudipati } 624a36c61f9SKrishna Gudipati 625a36c61f9SKrishna Gudipati u16 626a36c61f9SKrishna Gudipati fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id, 62750444a34SMaggie u32 s_id, __be16 ox_id, u16 rx_id) 628a36c61f9SKrishna Gudipati { 629a36c61f9SKrishna Gudipati fc_bls_rsp_build(fchs, d_id, s_id, ox_id); 630a36c61f9SKrishna Gudipati 6316a18b167SJing Huang memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s)); 632a36c61f9SKrishna Gudipati 633a36c61f9SKrishna Gudipati fchs->rx_id = rx_id; 634a36c61f9SKrishna Gudipati 635a36c61f9SKrishna Gudipati ba_acc->ox_id = fchs->ox_id; 636a36c61f9SKrishna Gudipati ba_acc->rx_id = fchs->rx_id; 637a36c61f9SKrishna Gudipati 638a36c61f9SKrishna Gudipati return sizeof(struct fc_ba_acc_s); 639a36c61f9SKrishna Gudipati } 640a36c61f9SKrishna Gudipati 641a36c61f9SKrishna Gudipati u16 642a36c61f9SKrishna Gudipati fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id, 64350444a34SMaggie u32 s_id, __be16 ox_id) 644a36c61f9SKrishna Gudipati { 645a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 6466a18b167SJing Huang memset(els_cmd, 0, sizeof(struct fc_els_cmd_s)); 647a36c61f9SKrishna Gudipati els_cmd->els_code = FC_ELS_ACC; 648a36c61f9SKrishna Gudipati 649a36c61f9SKrishna Gudipati return sizeof(struct fc_els_cmd_s); 650a36c61f9SKrishna Gudipati } 651a36c61f9SKrishna Gudipati 652a36c61f9SKrishna Gudipati int 653a36c61f9SKrishna Gudipati fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code) 654a36c61f9SKrishna Gudipati { 655a36c61f9SKrishna Gudipati int num_pages = 0; 656a36c61f9SKrishna Gudipati struct fc_prlo_s *prlo; 657a36c61f9SKrishna Gudipati struct fc_tprlo_s *tprlo; 658a36c61f9SKrishna Gudipati 659a36c61f9SKrishna Gudipati if (els_code == FC_ELS_PRLO) { 660a36c61f9SKrishna Gudipati prlo = (struct fc_prlo_s *) (fc_frame + 1); 661ba816ea8SJing Huang num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16; 662a36c61f9SKrishna Gudipati } else { 663a36c61f9SKrishna Gudipati tprlo = (struct fc_tprlo_s *) (fc_frame + 1); 664ba816ea8SJing Huang num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16; 665a36c61f9SKrishna Gudipati } 666a36c61f9SKrishna Gudipati return num_pages; 667a36c61f9SKrishna Gudipati } 668a36c61f9SKrishna Gudipati 669a36c61f9SKrishna Gudipati u16 670a36c61f9SKrishna Gudipati fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc, 67150444a34SMaggie u32 d_id, u32 s_id, __be16 ox_id, int num_pages) 672a36c61f9SKrishna Gudipati { 673a36c61f9SKrishna Gudipati int page; 674a36c61f9SKrishna Gudipati 675a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 676a36c61f9SKrishna Gudipati 6776a18b167SJing Huang memset(tprlo_acc, 0, (num_pages * 16) + 4); 678a36c61f9SKrishna Gudipati tprlo_acc->command = FC_ELS_ACC; 679a36c61f9SKrishna Gudipati 680a36c61f9SKrishna Gudipati tprlo_acc->page_len = 0x10; 681ba816ea8SJing Huang tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4); 682a36c61f9SKrishna Gudipati 683a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 684a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].opa_valid = 0; 685a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].rpa_valid = 0; 686a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; 687a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0; 688a36c61f9SKrishna Gudipati tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0; 689a36c61f9SKrishna Gudipati } 690ba816ea8SJing Huang return be16_to_cpu(tprlo_acc->payload_len); 691a36c61f9SKrishna Gudipati } 692a36c61f9SKrishna Gudipati 693a36c61f9SKrishna Gudipati u16 694a36c61f9SKrishna Gudipati fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id, 69550444a34SMaggie u32 s_id, __be16 ox_id, int num_pages) 696a36c61f9SKrishna Gudipati { 697a36c61f9SKrishna Gudipati int page; 698a36c61f9SKrishna Gudipati 699a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 700a36c61f9SKrishna Gudipati 7016a18b167SJing Huang memset(prlo_acc, 0, (num_pages * 16) + 4); 702a36c61f9SKrishna Gudipati prlo_acc->command = FC_ELS_ACC; 703a36c61f9SKrishna Gudipati prlo_acc->page_len = 0x10; 704ba816ea8SJing Huang prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4); 705a36c61f9SKrishna Gudipati 706a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 707a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].opa_valid = 0; 708a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].rpa_valid = 0; 709a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; 710a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].orig_process_assc = 0; 711a36c61f9SKrishna Gudipati prlo_acc->prlo_acc_params[page].resp_process_assc = 0; 712a36c61f9SKrishna Gudipati } 713a36c61f9SKrishna Gudipati 714ba816ea8SJing Huang return be16_to_cpu(prlo_acc->payload_len); 715a36c61f9SKrishna Gudipati } 716a36c61f9SKrishna Gudipati 717a36c61f9SKrishna Gudipati u16 718a36c61f9SKrishna Gudipati fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id, 719a36c61f9SKrishna Gudipati u32 s_id, u16 ox_id, u32 data_format) 720a36c61f9SKrishna Gudipati { 721a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 722a36c61f9SKrishna Gudipati 7236a18b167SJing Huang memset(rnid, 0, sizeof(struct fc_rnid_cmd_s)); 724a36c61f9SKrishna Gudipati 725a36c61f9SKrishna Gudipati rnid->els_cmd.els_code = FC_ELS_RNID; 726a36c61f9SKrishna Gudipati rnid->node_id_data_format = data_format; 727a36c61f9SKrishna Gudipati 728a36c61f9SKrishna Gudipati return sizeof(struct fc_rnid_cmd_s); 729a36c61f9SKrishna Gudipati } 730a36c61f9SKrishna Gudipati 731a36c61f9SKrishna Gudipati u16 732a36c61f9SKrishna Gudipati fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id, 73350444a34SMaggie u32 s_id, __be16 ox_id, u32 data_format, 734a36c61f9SKrishna Gudipati struct fc_rnid_common_id_data_s *common_id_data, 735a36c61f9SKrishna Gudipati struct fc_rnid_general_topology_data_s *gen_topo_data) 736a36c61f9SKrishna Gudipati { 7376a18b167SJing Huang memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s)); 738a36c61f9SKrishna Gudipati 739a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 740a36c61f9SKrishna Gudipati 741a36c61f9SKrishna Gudipati rnid_acc->els_cmd.els_code = FC_ELS_ACC; 742a36c61f9SKrishna Gudipati rnid_acc->node_id_data_format = data_format; 743a36c61f9SKrishna Gudipati rnid_acc->common_id_data_length = 744a36c61f9SKrishna Gudipati sizeof(struct fc_rnid_common_id_data_s); 745a36c61f9SKrishna Gudipati rnid_acc->common_id_data = *common_id_data; 746a36c61f9SKrishna Gudipati 747a36c61f9SKrishna Gudipati if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 748a36c61f9SKrishna Gudipati rnid_acc->specific_id_data_length = 749a36c61f9SKrishna Gudipati sizeof(struct fc_rnid_general_topology_data_s); 7506a18b167SJing Huang rnid_acc->gen_topology_data = *gen_topo_data; 751a36c61f9SKrishna Gudipati return sizeof(struct fc_rnid_acc_s); 752a36c61f9SKrishna Gudipati } else { 753a36c61f9SKrishna Gudipati return sizeof(struct fc_rnid_acc_s) - 754a36c61f9SKrishna Gudipati sizeof(struct fc_rnid_general_topology_data_s); 755a36c61f9SKrishna Gudipati } 756a36c61f9SKrishna Gudipati 757a36c61f9SKrishna Gudipati } 758a36c61f9SKrishna Gudipati 759a36c61f9SKrishna Gudipati u16 760a36c61f9SKrishna Gudipati fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id, 761a36c61f9SKrishna Gudipati u32 s_id, u16 ox_id) 762a36c61f9SKrishna Gudipati { 763a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 764a36c61f9SKrishna Gudipati 7656a18b167SJing Huang memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s)); 766a36c61f9SKrishna Gudipati 767a36c61f9SKrishna Gudipati rpsc->els_cmd.els_code = FC_ELS_RPSC; 768a36c61f9SKrishna Gudipati return sizeof(struct fc_rpsc_cmd_s); 769a36c61f9SKrishna Gudipati } 770a36c61f9SKrishna Gudipati 771a36c61f9SKrishna Gudipati u16 772a36c61f9SKrishna Gudipati fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id, 773a36c61f9SKrishna Gudipati u32 s_id, u32 *pid_list, u16 npids) 774a36c61f9SKrishna Gudipati { 775f16a1750SMaggie Zhang u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id)); 776a36c61f9SKrishna Gudipati int i = 0; 777a36c61f9SKrishna Gudipati 778f16a1750SMaggie Zhang fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0); 779a36c61f9SKrishna Gudipati 7806a18b167SJing Huang memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s)); 781a36c61f9SKrishna Gudipati 782a36c61f9SKrishna Gudipati rpsc2->els_cmd.els_code = FC_ELS_RPSC; 783ba816ea8SJing Huang rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN); 784ba816ea8SJing Huang rpsc2->num_pids = cpu_to_be16(npids); 785a36c61f9SKrishna Gudipati for (i = 0; i < npids; i++) 786a36c61f9SKrishna Gudipati rpsc2->pid_list[i].pid = pid_list[i]; 787a36c61f9SKrishna Gudipati 788a36c61f9SKrishna Gudipati return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32))); 789a36c61f9SKrishna Gudipati } 790a36c61f9SKrishna Gudipati 791a36c61f9SKrishna Gudipati u16 792a36c61f9SKrishna Gudipati fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc, 79350444a34SMaggie u32 d_id, u32 s_id, __be16 ox_id, 794a36c61f9SKrishna Gudipati struct fc_rpsc_speed_info_s *oper_speed) 795a36c61f9SKrishna Gudipati { 7966a18b167SJing Huang memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s)); 797a36c61f9SKrishna Gudipati 798a36c61f9SKrishna Gudipati fc_els_rsp_build(fchs, d_id, s_id, ox_id); 799a36c61f9SKrishna Gudipati 800a36c61f9SKrishna Gudipati rpsc_acc->command = FC_ELS_ACC; 801ba816ea8SJing Huang rpsc_acc->num_entries = cpu_to_be16(1); 802a36c61f9SKrishna Gudipati 803a36c61f9SKrishna Gudipati rpsc_acc->speed_info[0].port_speed_cap = 804ba816ea8SJing Huang cpu_to_be16(oper_speed->port_speed_cap); 805a36c61f9SKrishna Gudipati 806a36c61f9SKrishna Gudipati rpsc_acc->speed_info[0].port_op_speed = 807ba816ea8SJing Huang cpu_to_be16(oper_speed->port_op_speed); 808a36c61f9SKrishna Gudipati 809a36c61f9SKrishna Gudipati return sizeof(struct fc_rpsc_acc_s); 810a36c61f9SKrishna Gudipati } 811a36c61f9SKrishna Gudipati 812a36c61f9SKrishna Gudipati u16 813a36c61f9SKrishna Gudipati fc_logo_rsp_parse(struct fchs_s *fchs, int len) 814a36c61f9SKrishna Gudipati { 815a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 816a36c61f9SKrishna Gudipati 817a36c61f9SKrishna Gudipati len = len; 818a36c61f9SKrishna Gudipati if (els_cmd->els_code != FC_ELS_ACC) 819a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 820a36c61f9SKrishna Gudipati 821a36c61f9SKrishna Gudipati return FC_PARSE_OK; 822a36c61f9SKrishna Gudipati } 823a36c61f9SKrishna Gudipati 824a36c61f9SKrishna Gudipati u16 825a36c61f9SKrishna Gudipati fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, 826a36c61f9SKrishna Gudipati wwn_t port_name, wwn_t node_name, u16 pdu_size) 827a36c61f9SKrishna Gudipati { 828a36c61f9SKrishna Gudipati struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 829a36c61f9SKrishna Gudipati 8306a18b167SJing Huang memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s)); 831a36c61f9SKrishna Gudipati 832a36c61f9SKrishna Gudipati pdisc->els_cmd.els_code = FC_ELS_PDISC; 833a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 834a36c61f9SKrishna Gudipati 835ba816ea8SJing Huang pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size); 836a36c61f9SKrishna Gudipati pdisc->port_name = port_name; 837a36c61f9SKrishna Gudipati pdisc->node_name = node_name; 838a36c61f9SKrishna Gudipati 839a36c61f9SKrishna Gudipati return sizeof(struct fc_logi_s); 840a36c61f9SKrishna Gudipati } 841a36c61f9SKrishna Gudipati 842a36c61f9SKrishna Gudipati u16 843a36c61f9SKrishna Gudipati fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) 844a36c61f9SKrishna Gudipati { 845a36c61f9SKrishna Gudipati struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); 846a36c61f9SKrishna Gudipati 847a36c61f9SKrishna Gudipati if (len < sizeof(struct fc_logi_s)) 848a36c61f9SKrishna Gudipati return FC_PARSE_LEN_INVAL; 849a36c61f9SKrishna Gudipati 850a36c61f9SKrishna Gudipati if (pdisc->els_cmd.els_code != FC_ELS_ACC) 851a36c61f9SKrishna Gudipati return FC_PARSE_ACC_INVAL; 852a36c61f9SKrishna Gudipati 853a36c61f9SKrishna Gudipati if (!wwn_is_equal(pdisc->port_name, port_name)) 854a36c61f9SKrishna Gudipati return FC_PARSE_PWWN_NOT_EQUAL; 855a36c61f9SKrishna Gudipati 856a36c61f9SKrishna Gudipati if (!pdisc->class3.class_valid) 857a36c61f9SKrishna Gudipati return FC_PARSE_NWWN_NOT_EQUAL; 858a36c61f9SKrishna Gudipati 859ba816ea8SJing Huang if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ)) 860a36c61f9SKrishna Gudipati return FC_PARSE_RXSZ_INVAL; 861a36c61f9SKrishna Gudipati 862a36c61f9SKrishna Gudipati return FC_PARSE_OK; 863a36c61f9SKrishna Gudipati } 864a36c61f9SKrishna Gudipati 865a36c61f9SKrishna Gudipati u16 866a36c61f9SKrishna Gudipati fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, 867a36c61f9SKrishna Gudipati int num_pages) 868a36c61f9SKrishna Gudipati { 869a36c61f9SKrishna Gudipati struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1); 870a36c61f9SKrishna Gudipati int page; 871a36c61f9SKrishna Gudipati 872a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 8736a18b167SJing Huang memset(prlo, 0, (num_pages * 16) + 4); 874a36c61f9SKrishna Gudipati prlo->command = FC_ELS_PRLO; 875a36c61f9SKrishna Gudipati prlo->page_len = 0x10; 876ba816ea8SJing Huang prlo->payload_len = cpu_to_be16((num_pages * 16) + 4); 877a36c61f9SKrishna Gudipati 878a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 879a36c61f9SKrishna Gudipati prlo->prlo_params[page].type = FC_TYPE_FCP; 880a36c61f9SKrishna Gudipati prlo->prlo_params[page].opa_valid = 0; 881a36c61f9SKrishna Gudipati prlo->prlo_params[page].rpa_valid = 0; 882a36c61f9SKrishna Gudipati prlo->prlo_params[page].orig_process_assc = 0; 883a36c61f9SKrishna Gudipati prlo->prlo_params[page].resp_process_assc = 0; 884a36c61f9SKrishna Gudipati } 885a36c61f9SKrishna Gudipati 886ba816ea8SJing Huang return be16_to_cpu(prlo->payload_len); 887a36c61f9SKrishna Gudipati } 888a36c61f9SKrishna Gudipati 889a36c61f9SKrishna Gudipati u16 890a36c61f9SKrishna Gudipati fc_prlo_rsp_parse(struct fchs_s *fchs, int len) 891a36c61f9SKrishna Gudipati { 892a36c61f9SKrishna Gudipati struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1); 893a36c61f9SKrishna Gudipati int num_pages = 0; 894a36c61f9SKrishna Gudipati int page = 0; 895a36c61f9SKrishna Gudipati 896a36c61f9SKrishna Gudipati len = len; 897a36c61f9SKrishna Gudipati 898a36c61f9SKrishna Gudipati if (prlo->command != FC_ELS_ACC) 899a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 900a36c61f9SKrishna Gudipati 901ba816ea8SJing Huang num_pages = ((be16_to_cpu(prlo->payload_len)) - 4) / 16; 902a36c61f9SKrishna Gudipati 903a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 904a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP) 905a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 906a36c61f9SKrishna Gudipati 907a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].opa_valid != 0) 908a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 909a36c61f9SKrishna Gudipati 910a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].rpa_valid != 0) 911a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 912a36c61f9SKrishna Gudipati 913a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].orig_process_assc != 0) 914a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 915a36c61f9SKrishna Gudipati 916a36c61f9SKrishna Gudipati if (prlo->prlo_acc_params[page].resp_process_assc != 0) 917a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 918a36c61f9SKrishna Gudipati } 919a36c61f9SKrishna Gudipati return FC_PARSE_OK; 920a36c61f9SKrishna Gudipati 921a36c61f9SKrishna Gudipati } 922a36c61f9SKrishna Gudipati 923a36c61f9SKrishna Gudipati u16 924a36c61f9SKrishna Gudipati fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, 925a36c61f9SKrishna Gudipati int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id) 926a36c61f9SKrishna Gudipati { 927a36c61f9SKrishna Gudipati struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1); 928a36c61f9SKrishna Gudipati int page; 929a36c61f9SKrishna Gudipati 930a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 9316a18b167SJing Huang memset(tprlo, 0, (num_pages * 16) + 4); 932a36c61f9SKrishna Gudipati tprlo->command = FC_ELS_TPRLO; 933a36c61f9SKrishna Gudipati tprlo->page_len = 0x10; 934ba816ea8SJing Huang tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4); 935a36c61f9SKrishna Gudipati 936a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 937a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].type = FC_TYPE_FCP; 938a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].opa_valid = 0; 939a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].rpa_valid = 0; 940a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].orig_process_assc = 0; 941a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].resp_process_assc = 0; 942a36c61f9SKrishna Gudipati if (tprlo_type == FC_GLOBAL_LOGO) { 943a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].global_process_logout = 1; 944a36c61f9SKrishna Gudipati } else if (tprlo_type == FC_TPR_LOGO) { 945a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].tpo_nport_valid = 1; 946a36c61f9SKrishna Gudipati tprlo->tprlo_params[page].tpo_nport_id = (tpr_id); 947a36c61f9SKrishna Gudipati } 948a36c61f9SKrishna Gudipati } 949a36c61f9SKrishna Gudipati 950ba816ea8SJing Huang return be16_to_cpu(tprlo->payload_len); 951a36c61f9SKrishna Gudipati } 952a36c61f9SKrishna Gudipati 953a36c61f9SKrishna Gudipati u16 954a36c61f9SKrishna Gudipati fc_tprlo_rsp_parse(struct fchs_s *fchs, int len) 955a36c61f9SKrishna Gudipati { 956a36c61f9SKrishna Gudipati struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1); 957a36c61f9SKrishna Gudipati int num_pages = 0; 958a36c61f9SKrishna Gudipati int page = 0; 959a36c61f9SKrishna Gudipati 960a36c61f9SKrishna Gudipati len = len; 961a36c61f9SKrishna Gudipati 962a36c61f9SKrishna Gudipati if (tprlo->command != FC_ELS_ACC) 963a36c61f9SKrishna Gudipati return FC_PARSE_ACC_INVAL; 964a36c61f9SKrishna Gudipati 965ba816ea8SJing Huang num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16; 966a36c61f9SKrishna Gudipati 967a36c61f9SKrishna Gudipati for (page = 0; page < num_pages; page++) { 968a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP) 969a36c61f9SKrishna Gudipati return FC_PARSE_NOT_FCP; 970a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].opa_valid != 0) 971a36c61f9SKrishna Gudipati return FC_PARSE_OPAFLAG_INVAL; 972a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].rpa_valid != 0) 973a36c61f9SKrishna Gudipati return FC_PARSE_RPAFLAG_INVAL; 974a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].orig_process_assc != 0) 975a36c61f9SKrishna Gudipati return FC_PARSE_OPA_INVAL; 976a36c61f9SKrishna Gudipati if (tprlo->tprlo_acc_params[page].resp_process_assc != 0) 977a36c61f9SKrishna Gudipati return FC_PARSE_RPA_INVAL; 978a36c61f9SKrishna Gudipati } 979a36c61f9SKrishna Gudipati return FC_PARSE_OK; 980a36c61f9SKrishna Gudipati } 981a36c61f9SKrishna Gudipati 982a36c61f9SKrishna Gudipati enum fc_parse_status 983a36c61f9SKrishna Gudipati fc_rrq_rsp_parse(struct fchs_s *fchs, int len) 984a36c61f9SKrishna Gudipati { 985a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 986a36c61f9SKrishna Gudipati 987a36c61f9SKrishna Gudipati len = len; 988a36c61f9SKrishna Gudipati if (els_cmd->els_code != FC_ELS_ACC) 989a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 990a36c61f9SKrishna Gudipati 991a36c61f9SKrishna Gudipati return FC_PARSE_OK; 992a36c61f9SKrishna Gudipati } 993a36c61f9SKrishna Gudipati 994a36c61f9SKrishna Gudipati u16 99550444a34SMaggie fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id, 996a36c61f9SKrishna Gudipati u32 reason_code, u32 reason_expl) 997a36c61f9SKrishna Gudipati { 998a36c61f9SKrishna Gudipati struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1); 999a36c61f9SKrishna Gudipati 1000a36c61f9SKrishna Gudipati fc_bls_rsp_build(fchs, d_id, s_id, ox_id); 1001a36c61f9SKrishna Gudipati 1002a36c61f9SKrishna Gudipati fchs->cat_info = FC_CAT_BA_RJT; 1003a36c61f9SKrishna Gudipati ba_rjt->reason_code = reason_code; 1004a36c61f9SKrishna Gudipati ba_rjt->reason_expl = reason_expl; 1005a36c61f9SKrishna Gudipati return sizeof(struct fc_ba_rjt_s); 1006a36c61f9SKrishna Gudipati } 1007a36c61f9SKrishna Gudipati 1008a36c61f9SKrishna Gudipati static void 1009a36c61f9SKrishna Gudipati fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) 1010a36c61f9SKrishna Gudipati { 10116a18b167SJing Huang memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1012a36c61f9SKrishna Gudipati cthdr->rev_id = CT_GS3_REVISION; 1013a36c61f9SKrishna Gudipati cthdr->gs_type = CT_GSTYPE_DIRSERVICE; 1014a36c61f9SKrishna Gudipati cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER; 1015ba816ea8SJing Huang cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); 1016a36c61f9SKrishna Gudipati } 1017a36c61f9SKrishna Gudipati 1018a36c61f9SKrishna Gudipati static void 1019a36c61f9SKrishna Gudipati fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) 1020a36c61f9SKrishna Gudipati { 10216a18b167SJing Huang memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1022a36c61f9SKrishna Gudipati cthdr->rev_id = CT_GS3_REVISION; 1023a36c61f9SKrishna Gudipati cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; 1024a36c61f9SKrishna Gudipati cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER; 1025ba816ea8SJing Huang cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); 1026a36c61f9SKrishna Gudipati } 1027a36c61f9SKrishna Gudipati 1028a36c61f9SKrishna Gudipati static void 1029a36c61f9SKrishna Gudipati fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code, 1030a36c61f9SKrishna Gudipati u8 sub_type) 1031a36c61f9SKrishna Gudipati { 10326a18b167SJing Huang memset(cthdr, 0, sizeof(struct ct_hdr_s)); 1033a36c61f9SKrishna Gudipati cthdr->rev_id = CT_GS3_REVISION; 1034a36c61f9SKrishna Gudipati cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; 1035a36c61f9SKrishna Gudipati cthdr->gs_sub_type = sub_type; 1036ba816ea8SJing Huang cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); 1037a36c61f9SKrishna Gudipati } 1038a36c61f9SKrishna Gudipati 1039a36c61f9SKrishna Gudipati u16 1040a36c61f9SKrishna Gudipati fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1041a36c61f9SKrishna Gudipati wwn_t port_name) 1042a36c61f9SKrishna Gudipati { 1043a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1044a36c61f9SKrishna Gudipati struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1); 1045f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1046a36c61f9SKrishna Gudipati 1047a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1048a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN); 1049a36c61f9SKrishna Gudipati 10506a18b167SJing Huang memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s)); 1051a36c61f9SKrishna Gudipati gidpn->port_name = port_name; 1052a36c61f9SKrishna Gudipati return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s); 1053a36c61f9SKrishna Gudipati } 1054a36c61f9SKrishna Gudipati 1055a36c61f9SKrishna Gudipati u16 1056a36c61f9SKrishna Gudipati fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1057a36c61f9SKrishna Gudipati u32 port_id) 1058a36c61f9SKrishna Gudipati { 1059a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1060a36c61f9SKrishna Gudipati fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1); 1061f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1062a36c61f9SKrishna Gudipati 1063a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1064a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID); 1065a36c61f9SKrishna Gudipati 10666a18b167SJing Huang memset(gpnid, 0, sizeof(fcgs_gpnid_req_t)); 1067a36c61f9SKrishna Gudipati gpnid->dap = port_id; 1068a36c61f9SKrishna Gudipati return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s); 1069a36c61f9SKrishna Gudipati } 1070a36c61f9SKrishna Gudipati 1071a36c61f9SKrishna Gudipati u16 1072a36c61f9SKrishna Gudipati fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1073a36c61f9SKrishna Gudipati u32 port_id) 1074a36c61f9SKrishna Gudipati { 1075a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1076a36c61f9SKrishna Gudipati fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1); 1077f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1078a36c61f9SKrishna Gudipati 1079a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1080a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID); 1081a36c61f9SKrishna Gudipati 10826a18b167SJing Huang memset(gnnid, 0, sizeof(fcgs_gnnid_req_t)); 1083a36c61f9SKrishna Gudipati gnnid->dap = port_id; 1084a36c61f9SKrishna Gudipati return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s); 1085a36c61f9SKrishna Gudipati } 1086a36c61f9SKrishna Gudipati 1087a36c61f9SKrishna Gudipati u16 1088a36c61f9SKrishna Gudipati fc_ct_rsp_parse(struct ct_hdr_s *cthdr) 1089a36c61f9SKrishna Gudipati { 1090ba816ea8SJing Huang if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) { 1091a36c61f9SKrishna Gudipati if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY) 1092a36c61f9SKrishna Gudipati return FC_PARSE_BUSY; 1093a36c61f9SKrishna Gudipati else 1094a36c61f9SKrishna Gudipati return FC_PARSE_FAILURE; 1095a36c61f9SKrishna Gudipati } 1096a36c61f9SKrishna Gudipati 1097a36c61f9SKrishna Gudipati return FC_PARSE_OK; 1098a36c61f9SKrishna Gudipati } 1099a36c61f9SKrishna Gudipati 1100a36c61f9SKrishna Gudipati u16 1101a36c61f9SKrishna Gudipati fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, 1102a36c61f9SKrishna Gudipati u8 set_br_reg, u32 s_id, u16 ox_id) 1103a36c61f9SKrishna Gudipati { 1104f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER); 1105a36c61f9SKrishna Gudipati 1106a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 1107a36c61f9SKrishna Gudipati 11086a18b167SJing Huang memset(scr, 0, sizeof(struct fc_scr_s)); 1109a36c61f9SKrishna Gudipati scr->command = FC_ELS_SCR; 1110a36c61f9SKrishna Gudipati scr->reg_func = FC_SCR_REG_FUNC_FULL; 1111a36c61f9SKrishna Gudipati if (set_br_reg) 1112a36c61f9SKrishna Gudipati scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE; 1113a36c61f9SKrishna Gudipati 1114a36c61f9SKrishna Gudipati return sizeof(struct fc_scr_s); 1115a36c61f9SKrishna Gudipati } 1116a36c61f9SKrishna Gudipati 1117a36c61f9SKrishna Gudipati u16 1118a36c61f9SKrishna Gudipati fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, 1119a36c61f9SKrishna Gudipati u32 s_id, u16 ox_id) 1120a36c61f9SKrishna Gudipati { 1121f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER); 1122a36c61f9SKrishna Gudipati u16 payldlen; 1123a36c61f9SKrishna Gudipati 1124a36c61f9SKrishna Gudipati fc_els_req_build(fchs, d_id, s_id, ox_id); 1125a36c61f9SKrishna Gudipati rscn->command = FC_ELS_RSCN; 1126a36c61f9SKrishna Gudipati rscn->pagelen = sizeof(rscn->event[0]); 1127a36c61f9SKrishna Gudipati 1128a36c61f9SKrishna Gudipati payldlen = sizeof(u32) + rscn->pagelen; 1129ba816ea8SJing Huang rscn->payldlen = cpu_to_be16(payldlen); 1130a36c61f9SKrishna Gudipati 1131a36c61f9SKrishna Gudipati rscn->event[0].format = FC_RSCN_FORMAT_PORTID; 1132a36c61f9SKrishna Gudipati rscn->event[0].portid = s_id; 1133a36c61f9SKrishna Gudipati 1134a36c61f9SKrishna Gudipati return sizeof(struct fc_rscn_pl_s); 1135a36c61f9SKrishna Gudipati } 1136a36c61f9SKrishna Gudipati 1137a36c61f9SKrishna Gudipati u16 1138a36c61f9SKrishna Gudipati fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1139a36c61f9SKrishna Gudipati enum bfa_lport_role roles) 1140a36c61f9SKrishna Gudipati { 1141a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1142a36c61f9SKrishna Gudipati struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1); 1143f16a1750SMaggie Zhang u32 type_value, d_id = bfa_hton3b(FC_NAME_SERVER); 1144a36c61f9SKrishna Gudipati u8 index; 1145a36c61f9SKrishna Gudipati 1146a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1147a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); 1148a36c61f9SKrishna Gudipati 11496a18b167SJing Huang memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); 1150a36c61f9SKrishna Gudipati 1151a36c61f9SKrishna Gudipati rftid->dap = s_id; 1152a36c61f9SKrishna Gudipati 1153a36c61f9SKrishna Gudipati /* By default, FCP FC4 Type is registered */ 1154a36c61f9SKrishna Gudipati index = FC_TYPE_FCP >> 5; 1155a36c61f9SKrishna Gudipati type_value = 1 << (FC_TYPE_FCP % 32); 1156ba816ea8SJing Huang rftid->fc4_type[index] = cpu_to_be32(type_value); 1157a36c61f9SKrishna Gudipati 1158a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); 1159a36c61f9SKrishna Gudipati } 1160a36c61f9SKrishna Gudipati 1161a36c61f9SKrishna Gudipati u16 1162a36c61f9SKrishna Gudipati fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1163a36c61f9SKrishna Gudipati u8 *fc4_bitmap, u32 bitmap_size) 1164a36c61f9SKrishna Gudipati { 1165a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1166a36c61f9SKrishna Gudipati struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1); 1167f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1168a36c61f9SKrishna Gudipati 1169a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1170a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); 1171a36c61f9SKrishna Gudipati 11726a18b167SJing Huang memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); 1173a36c61f9SKrishna Gudipati 1174a36c61f9SKrishna Gudipati rftid->dap = s_id; 11756a18b167SJing Huang memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap, 1176a36c61f9SKrishna Gudipati (bitmap_size < 32 ? bitmap_size : 32)); 1177a36c61f9SKrishna Gudipati 1178a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); 1179a36c61f9SKrishna Gudipati } 1180a36c61f9SKrishna Gudipati 1181a36c61f9SKrishna Gudipati u16 1182a36c61f9SKrishna Gudipati fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1183a36c61f9SKrishna Gudipati u8 fc4_type, u8 fc4_ftrs) 1184a36c61f9SKrishna Gudipati { 1185a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1186a36c61f9SKrishna Gudipati struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1); 1187f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1188a36c61f9SKrishna Gudipati 1189a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1190a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID); 1191a36c61f9SKrishna Gudipati 11926a18b167SJing Huang memset(rffid, 0, sizeof(struct fcgs_rffid_req_s)); 1193a36c61f9SKrishna Gudipati 1194a36c61f9SKrishna Gudipati rffid->dap = s_id; 1195a36c61f9SKrishna Gudipati rffid->fc4ftr_bits = fc4_ftrs; 1196a36c61f9SKrishna Gudipati rffid->fc4_type = fc4_type; 1197a36c61f9SKrishna Gudipati 1198a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s); 1199a36c61f9SKrishna Gudipati } 1200a36c61f9SKrishna Gudipati 1201a36c61f9SKrishna Gudipati u16 1202a36c61f9SKrishna Gudipati fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, 1203a36c61f9SKrishna Gudipati u8 *name) 1204a36c61f9SKrishna Gudipati { 1205a36c61f9SKrishna Gudipati 1206a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1207a36c61f9SKrishna Gudipati struct fcgs_rspnid_req_s *rspnid = 1208a36c61f9SKrishna Gudipati (struct fcgs_rspnid_req_s *)(cthdr + 1); 1209f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1210a36c61f9SKrishna Gudipati 1211a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); 1212a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID); 1213a36c61f9SKrishna Gudipati 12146a18b167SJing Huang memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s)); 1215a36c61f9SKrishna Gudipati 1216a36c61f9SKrishna Gudipati rspnid->dap = s_id; 1217a36c61f9SKrishna Gudipati rspnid->spn_len = (u8) strlen((char *)name); 1218a36c61f9SKrishna Gudipati strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len); 1219a36c61f9SKrishna Gudipati 1220a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s); 1221a36c61f9SKrishna Gudipati } 1222a36c61f9SKrishna Gudipati 1223a36c61f9SKrishna Gudipati u16 1224a36c61f9SKrishna Gudipati fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type) 1225a36c61f9SKrishna Gudipati { 1226a36c61f9SKrishna Gudipati 1227a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1228a36c61f9SKrishna Gudipati struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1); 1229f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1230a36c61f9SKrishna Gudipati 1231a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1232a36c61f9SKrishna Gudipati 1233a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT); 1234a36c61f9SKrishna Gudipati 12356a18b167SJing Huang memset(gidft, 0, sizeof(struct fcgs_gidft_req_s)); 1236a36c61f9SKrishna Gudipati gidft->fc4_type = fc4_type; 1237a36c61f9SKrishna Gudipati gidft->domain_id = 0; 1238a36c61f9SKrishna Gudipati gidft->area_id = 0; 1239a36c61f9SKrishna Gudipati 1240a36c61f9SKrishna Gudipati return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s); 1241a36c61f9SKrishna Gudipati } 1242a36c61f9SKrishna Gudipati 1243a36c61f9SKrishna Gudipati u16 1244a36c61f9SKrishna Gudipati fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1245a36c61f9SKrishna Gudipati wwn_t port_name) 1246a36c61f9SKrishna Gudipati { 1247a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1248a36c61f9SKrishna Gudipati struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1); 1249f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1250a36c61f9SKrishna Gudipati 1251a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1252a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID); 1253a36c61f9SKrishna Gudipati 12546a18b167SJing Huang memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s)); 1255a36c61f9SKrishna Gudipati rpnid->port_id = port_id; 1256a36c61f9SKrishna Gudipati rpnid->port_name = port_name; 1257a36c61f9SKrishna Gudipati 1258a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s); 1259a36c61f9SKrishna Gudipati } 1260a36c61f9SKrishna Gudipati 1261a36c61f9SKrishna Gudipati u16 1262a36c61f9SKrishna Gudipati fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1263a36c61f9SKrishna Gudipati wwn_t node_name) 1264a36c61f9SKrishna Gudipati { 1265a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1266a36c61f9SKrishna Gudipati struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1); 1267f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1268a36c61f9SKrishna Gudipati 1269a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1270a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID); 1271a36c61f9SKrishna Gudipati 12726a18b167SJing Huang memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s)); 1273a36c61f9SKrishna Gudipati rnnid->port_id = port_id; 1274a36c61f9SKrishna Gudipati rnnid->node_name = node_name; 1275a36c61f9SKrishna Gudipati 1276a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s); 1277a36c61f9SKrishna Gudipati } 1278a36c61f9SKrishna Gudipati 1279a36c61f9SKrishna Gudipati u16 1280a36c61f9SKrishna Gudipati fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1281a36c61f9SKrishna Gudipati u32 cos) 1282a36c61f9SKrishna Gudipati { 1283a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1284a36c61f9SKrishna Gudipati struct fcgs_rcsid_req_s *rcsid = 1285a36c61f9SKrishna Gudipati (struct fcgs_rcsid_req_s *) (cthdr + 1); 1286f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1287a36c61f9SKrishna Gudipati 1288a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1289a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID); 1290a36c61f9SKrishna Gudipati 12916a18b167SJing Huang memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s)); 1292a36c61f9SKrishna Gudipati rcsid->port_id = port_id; 1293a36c61f9SKrishna Gudipati rcsid->cos = cos; 1294a36c61f9SKrishna Gudipati 1295a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s); 1296a36c61f9SKrishna Gudipati } 1297a36c61f9SKrishna Gudipati 1298a36c61f9SKrishna Gudipati u16 1299a36c61f9SKrishna Gudipati fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, 1300a36c61f9SKrishna Gudipati u8 port_type) 1301a36c61f9SKrishna Gudipati { 1302a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1303a36c61f9SKrishna Gudipati struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1); 1304f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1305a36c61f9SKrishna Gudipati 1306a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1307a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID); 1308a36c61f9SKrishna Gudipati 13096a18b167SJing Huang memset(rptid, 0, sizeof(struct fcgs_rptid_req_s)); 1310a36c61f9SKrishna Gudipati rptid->port_id = port_id; 1311a36c61f9SKrishna Gudipati rptid->port_type = port_type; 1312a36c61f9SKrishna Gudipati 1313a36c61f9SKrishna Gudipati return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s); 1314a36c61f9SKrishna Gudipati } 1315a36c61f9SKrishna Gudipati 1316a36c61f9SKrishna Gudipati u16 1317a36c61f9SKrishna Gudipati fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id) 1318a36c61f9SKrishna Gudipati { 1319a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1320a36c61f9SKrishna Gudipati struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1); 1321f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_NAME_SERVER); 1322a36c61f9SKrishna Gudipati 1323a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1324a36c61f9SKrishna Gudipati fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT); 1325a36c61f9SKrishna Gudipati 13266a18b167SJing Huang memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s)); 1327a36c61f9SKrishna Gudipati ganxt->port_id = port_id; 1328a36c61f9SKrishna Gudipati 1329a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s); 1330a36c61f9SKrishna Gudipati } 1331a36c61f9SKrishna Gudipati 1332a36c61f9SKrishna Gudipati /* 1333a36c61f9SKrishna Gudipati * Builds fc hdr and ct hdr for FDMI requests. 1334a36c61f9SKrishna Gudipati */ 1335a36c61f9SKrishna Gudipati u16 1336a36c61f9SKrishna Gudipati fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id, 1337a36c61f9SKrishna Gudipati u16 cmd_code) 1338a36c61f9SKrishna Gudipati { 1339a36c61f9SKrishna Gudipati 1340a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1341f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_MGMT_SERVER); 1342a36c61f9SKrishna Gudipati 1343a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1344a36c61f9SKrishna Gudipati fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code); 1345a36c61f9SKrishna Gudipati 1346a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s); 1347a36c61f9SKrishna Gudipati } 1348a36c61f9SKrishna Gudipati 1349a36c61f9SKrishna Gudipati /* 1350a36c61f9SKrishna Gudipati * Given a FC4 Type, this function returns a fc4 type bitmask 1351a36c61f9SKrishna Gudipati */ 1352a36c61f9SKrishna Gudipati void 1353a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask) 1354a36c61f9SKrishna Gudipati { 1355a36c61f9SKrishna Gudipati u8 index; 135650444a34SMaggie __be32 *ptr = (__be32 *) bit_mask; 1357a36c61f9SKrishna Gudipati u32 type_value; 1358a36c61f9SKrishna Gudipati 1359a36c61f9SKrishna Gudipati /* 1360a36c61f9SKrishna Gudipati * @todo : Check for bitmask size 1361a36c61f9SKrishna Gudipati */ 1362a36c61f9SKrishna Gudipati 1363a36c61f9SKrishna Gudipati index = fc4_type >> 5; 1364a36c61f9SKrishna Gudipati type_value = 1 << (fc4_type % 32); 1365ba816ea8SJing Huang ptr[index] = cpu_to_be32(type_value); 1366a36c61f9SKrishna Gudipati 1367a36c61f9SKrishna Gudipati } 1368a36c61f9SKrishna Gudipati 1369a36c61f9SKrishna Gudipati /* 1370a36c61f9SKrishna Gudipati * GMAL Request 1371a36c61f9SKrishna Gudipati */ 1372a36c61f9SKrishna Gudipati u16 1373a36c61f9SKrishna Gudipati fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) 1374a36c61f9SKrishna Gudipati { 1375a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1376a36c61f9SKrishna Gudipati fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1); 1377f16a1750SMaggie Zhang u32 d_id = bfa_hton3b(FC_MGMT_SERVER); 1378a36c61f9SKrishna Gudipati 1379a36c61f9SKrishna Gudipati fc_gs_fchdr_build(fchs, d_id, s_id, 0); 1380a36c61f9SKrishna Gudipati fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD, 1381a36c61f9SKrishna Gudipati CT_GSSUBTYPE_CFGSERVER); 1382a36c61f9SKrishna Gudipati 13836a18b167SJing Huang memset(gmal, 0, sizeof(fcgs_gmal_req_t)); 1384a36c61f9SKrishna Gudipati gmal->wwn = wwn; 1385a36c61f9SKrishna Gudipati 1386a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t); 1387a36c61f9SKrishna Gudipati } 1388a36c61f9SKrishna Gudipati 1389a36c61f9SKrishna Gudipati /* 1390a36c61f9SKrishna Gudipati * GFN (Get Fabric Name) Request 1391a36c61f9SKrishna Gudipati */ 1392a36c61f9SKrishna Gudipati u16 1393a36c61f9SKrishna Gudipati fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) 1394a36c61f9SKrishna Gudipati { 1395a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; 1396a36c61f9SKrishna Gudipati fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1); 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_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD, 1401a36c61f9SKrishna Gudipati CT_GSSUBTYPE_CFGSERVER); 1402a36c61f9SKrishna Gudipati 14036a18b167SJing Huang memset(gfn, 0, sizeof(fcgs_gfn_req_t)); 1404a36c61f9SKrishna Gudipati gfn->wwn = wwn; 1405a36c61f9SKrishna Gudipati 1406a36c61f9SKrishna Gudipati return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t); 1407a36c61f9SKrishna Gudipati } 1408