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