fc_encode.h revision 059f04d4aa60f89b7ad6ca118856f4cb59d9257f
142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/* 242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * Copyright(c) 2008 Intel Corporation. All rights reserved. 342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * 442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * This program is free software; you can redistribute it and/or modify it 542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * under the terms and conditions of the GNU General Public License, 642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * version 2, as published by the Free Software Foundation. 742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * 842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * This program is distributed in the hope it will be useful, but WITHOUT 942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 1142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * more details. 1242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * 1342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * You should have received a copy of the GNU General Public License along with 1442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * this program; if not, write to the Free Software Foundation, Inc., 1542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 1642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * 1742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * Maintained at www.Open-FCoE.org 1842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 1942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 2042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love#ifndef _FC_ENCODE_H_ 2142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love#define _FC_ENCODE_H_ 2242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love#include <asm/unaligned.h> 2342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 2424f089e2f2c800f88039e9d536d558ec6e349fadJoe Eykholt/* 2524f089e2f2c800f88039e9d536d558ec6e349fadJoe Eykholt * F_CTL values for simple requests and responses. 2624f089e2f2c800f88039e9d536d558ec6e349fadJoe Eykholt */ 2724f089e2f2c800f88039e9d536d558ec6e349fadJoe Eykholt#define FC_FCTL_REQ (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT) 2824f089e2f2c800f88039e9d536d558ec6e349fadJoe Eykholt#define FC_FCTL_RESP (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \ 2924f089e2f2c800f88039e9d536d558ec6e349fadJoe Eykholt FC_FC_END_SEQ | FC_FC_SEQ_INIT) 3024f089e2f2c800f88039e9d536d558ec6e349fadJoe Eykholt 3142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestruct fc_ns_rft { 3242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ns_fid fid; /* port ID object */ 3342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ns_fts fts; /* FC4-types object */ 3442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love}; 3542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 3642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestruct fc_ct_req { 3742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ct_hdr hdr; 3842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love union { 3942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ns_gid_ft gid; 4042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ns_rn_id rn; 4142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ns_rft rft; 42ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt struct fc_ns_rff_id rff; 432ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt struct fc_ns_fid fid; 445baa17c3e66fc2e414f501b2dd59b962dfc64919Chris Leech struct fc_ns_rsnn snn; 45c9866a548024c33e30f35a14bbcb71ba78266383Chris Leech struct fc_ns_rspn spn; 4642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love } payload; 4742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love}; 4842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 49059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudistatic inline void __fc_fill_fc_hdr(struct fc_frame_header *fh, 50059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi enum fc_rctl r_ctl, 51059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi u32 did, u32 sid, enum fc_fh_type type, 52059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi u32 f_ctl, u32 parm_offset) 5342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 5442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love WARN_ON(r_ctl == 0); 5542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fh->fh_r_ctl = r_ctl; 5642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love hton24(fh->fh_d_id, did); 5742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love hton24(fh->fh_s_id, sid); 5842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fh->fh_type = type; 5942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love hton24(fh->fh_f_ctl, f_ctl); 6042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fh->fh_cs_ctl = 0; 6142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fh->fh_df_ctl = 0; 6242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fh->fh_parm_offset = htonl(parm_offset); 6342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 6442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 6542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 66059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi * fill FC header fields in specified fc_frame 67059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi */ 68059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudistatic inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, 69059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi u32 did, u32 sid, enum fc_fh_type type, 70059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi u32 f_ctl, u32 parm_offset) 71059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi{ 72059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi struct fc_frame_header *fh; 73059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi 74059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi fh = fc_frame_header_get(fp); 75059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi __fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset); 76059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi} 77059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi 78059f04d4aa60f89b7ad6ca118856f4cb59d9257fBhanu Prakash Gollapudi/** 79370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt * fc_adisc_fill() - Fill in adisc request frame 80370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt * @lport: local port. 81370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt * @fp: fc frame where payload will be placed. 82370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt */ 83370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholtstatic inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp) 84370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt{ 85370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt struct fc_els_adisc *adisc; 86370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt 87370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt adisc = fc_frame_payload_get(fp, sizeof(*adisc)); 88370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt memset(adisc, 0, sizeof(*adisc)); 89370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt adisc->adisc_cmd = ELS_ADISC; 90370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn); 91370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn); 927b2787ec15b9d1c2f716da61b0eec21a3f5e6520Robert Love hton24(adisc->adisc_port_id, lport->port_id); 93370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt} 94370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt 95370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt/** 9642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_ct_hdr_fill- fills ct header and reset ct payload 9742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * returns pointer to ct request. 9842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 9942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, 10042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love unsigned int op, size_t req_size) 10142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 10242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ct_req *ct; 10342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love size_t ct_plen; 10442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 10542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct_plen = sizeof(struct fc_ct_hdr) + req_size; 10642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct = fc_frame_payload_get(fp, ct_plen); 10742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(ct, 0, ct_plen); 10842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct->hdr.ct_rev = FC_CT_REV; 10942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct->hdr.ct_fs_type = FC_FST_DIR; 11042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; 11142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct->hdr.ct_cmd = htons((u16) op); 11242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love return ct; 11342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 11442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 11542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 1162ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt * fc_ct_fill() - Fill in a name service request frame 1172ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt * @lport: local port. 1182ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. 1192ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt * @fp: frame to contain payload. 1202ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt * @op: CT opcode. 1212ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt * @r_ctl: pointer to FC header R_CTL. 1222ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt * @fh_type: pointer to FC-4 type. 12342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 124a46f327aa5caf2cce138e98ddd863b6cca0e71e2Joe Eykholtstatic inline int fc_ct_fill(struct fc_lport *lport, 1252ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt u32 fc_id, struct fc_frame *fp, 126a46f327aa5caf2cce138e98ddd863b6cca0e71e2Joe Eykholt unsigned int op, enum fc_rctl *r_ctl, 12742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love enum fc_fh_type *fh_type) 12842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 12942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_ct_req *ct; 1305f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt size_t len; 13142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 13242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love switch (op) { 13342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case FC_NS_GPN_FT: 13442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); 13542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; 13642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 13742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 1382ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt case FC_NS_GPN_ID: 1392ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid)); 1402ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt hton24(ct->payload.fid.fp_fid, fc_id); 1412ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt break; 1422ab7e1ecb81ce35ed8e8df512e3fc6338a4c55bbJoe Eykholt 14342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case FC_NS_RFT_ID: 14442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); 1457b2787ec15b9d1c2f716da61b0eec21a3f5e6520Robert Love hton24(ct->payload.rft.fid.fp_fid, lport->port_id); 14642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct->payload.rft.fts = lport->fcts; 14742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 14842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 149ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt case FC_NS_RFF_ID: 150ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id)); 1517b2787ec15b9d1c2f716da61b0eec21a3f5e6520Robert Love hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id); 152ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt ct->payload.rff.fr_type = FC_TYPE_FCP; 153ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt if (lport->service_params & FCP_SPPF_INIT_FCN) 154ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt ct->payload.rff.fr_feat = FCP_FEAT_INIT; 155ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt if (lport->service_params & FCP_SPPF_TARG_FCN) 156ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt ct->payload.rff.fr_feat |= FCP_FEAT_TARG; 157ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt break; 158ab593b187391bdd03ccad2968972a2e118a88cd4Joe Eykholt 159c9c7bd7a5e7321aa96289c9b48fdbcc828c105e6Chris Leech case FC_NS_RNN_ID: 16042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); 1617b2787ec15b9d1c2f716da61b0eec21a3f5e6520Robert Love hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id); 162c9c7bd7a5e7321aa96289c9b48fdbcc828c105e6Chris Leech put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn); 16342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 16442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 165c9866a548024c33e30f35a14bbcb71ba78266383Chris Leech case FC_NS_RSPN_ID: 1665f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt len = strnlen(fc_host_symbolic_name(lport->host), 255); 1675f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len); 1687b2787ec15b9d1c2f716da61b0eec21a3f5e6520Robert Love hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id); 169c9866a548024c33e30f35a14bbcb71ba78266383Chris Leech strncpy(ct->payload.spn.fr_name, 1705f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt fc_host_symbolic_name(lport->host), len); 1715f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt ct->payload.spn.fr_name_len = len; 172c9866a548024c33e30f35a14bbcb71ba78266383Chris Leech break; 173c9866a548024c33e30f35a14bbcb71ba78266383Chris Leech 1745baa17c3e66fc2e414f501b2dd59b962dfc64919Chris Leech case FC_NS_RSNN_NN: 1755f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt len = strnlen(fc_host_symbolic_name(lport->host), 255); 1765f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len); 1775baa17c3e66fc2e414f501b2dd59b962dfc64919Chris Leech put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn); 1785baa17c3e66fc2e414f501b2dd59b962dfc64919Chris Leech strncpy(ct->payload.snn.fr_name, 1795f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt fc_host_symbolic_name(lport->host), len); 1805f9a056db9c7973c46337ec8d034323aa72bf206Joe Eykholt ct->payload.snn.fr_name_len = len; 1815baa17c3e66fc2e414f501b2dd59b962dfc64919Chris Leech break; 1825baa17c3e66fc2e414f501b2dd59b962dfc64919Chris Leech 18342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love default: 18442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love return -EINVAL; 18542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love } 18642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love *r_ctl = FC_RCTL_DD_UNSOL_CTL; 18742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love *fh_type = FC_TYPE_CT; 18842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love return 0; 18942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 19042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 19142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 19242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_plogi_fill - Fill in plogi request frame 19342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 19442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, 19542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love unsigned int op) 19642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 19742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_flogi *plogi; 19842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_csp *csp; 19942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_cssp *cp; 20042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 20142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love plogi = fc_frame_payload_get(fp, sizeof(*plogi)); 20242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(plogi, 0, sizeof(*plogi)); 20342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love plogi->fl_cmd = (u8) op; 20442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn); 20542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn); 20642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 20742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp = &plogi->fl_csp; 20842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_hi_ver = 0x20; 20942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_lo_ver = 0x20; 21042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_bb_cred = htons(10); /* this gets set by gateway */ 21142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_bb_data = htons((u16) lport->mfs); 21242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */ 21342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 21442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_features = htons(FC_SP_FT_CIRO); 21542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_tot_seq = htons(255); /* seq. we accept */ 21642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_rel_off = htons(0x1f); 21742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love csp->sp_e_d_tov = htonl(lport->e_d_tov); 21842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 21942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love cp->cp_rdfs = htons((u16) lport->mfs); 22042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love cp->cp_con_seq = htons(255); 22142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love cp->cp_open_seq = 1; 22242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 22342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 22442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 22542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_flogi_fill - Fill in a flogi request frame. 22642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 22742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) 22842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 22942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_csp *sp; 23042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_cssp *cp; 23142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_flogi *flogi; 23242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 23342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love flogi = fc_frame_payload_get(fp, sizeof(*flogi)); 23442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(flogi, 0, sizeof(*flogi)); 23542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love flogi->fl_cmd = (u8) ELS_FLOGI; 23642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); 23742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); 23842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love sp = &flogi->fl_csp; 23942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love sp->sp_hi_ver = 0x20; 24042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love sp->sp_lo_ver = 0x20; 24142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love sp->sp_bb_cred = htons(10); /* this gets set by gateway */ 24242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love sp->sp_bb_data = htons((u16) lport->mfs); 24342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ 24442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 245db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech if (lport->does_npiv) 246db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech sp->sp_features = htons(FC_SP_FT_NPIV); 247db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech} 248db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech 249db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech/** 250db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech * fc_fdisc_fill - Fill in a fdisc request frame. 251db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech */ 252db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leechstatic inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp) 253db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech{ 254db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech struct fc_els_csp *sp; 255db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech struct fc_els_cssp *cp; 256db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech struct fc_els_flogi *fdisc; 257db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech 258db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech fdisc = fc_frame_payload_get(fp, sizeof(*fdisc)); 259db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech memset(fdisc, 0, sizeof(*fdisc)); 260db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech fdisc->fl_cmd = (u8) ELS_FDISC; 261db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn); 262db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn); 263db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech sp = &fdisc->fl_csp; 264db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech sp->sp_hi_ver = 0x20; 265db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech sp->sp_lo_ver = 0x20; 266db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech sp->sp_bb_cred = htons(10); /* this gets set by gateway */ 267db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech sp->sp_bb_data = htons((u16) lport->mfs); 268db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech cp = &fdisc->fl_cssp[3 - 1]; /* class 3 parameters */ 269db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 27042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 27142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 27242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 27342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_logo_fill - Fill in a logo request frame. 27442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 27542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp) 27642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 27742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_logo *logo; 27842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 27942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love logo = fc_frame_payload_get(fp, sizeof(*logo)); 28042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(logo, 0, sizeof(*logo)); 28142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love logo->fl_cmd = ELS_LOGO; 2827b2787ec15b9d1c2f716da61b0eec21a3f5e6520Robert Love hton24(logo->fl_n_port_id, lport->port_id); 28342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love logo->fl_n_port_wwn = htonll(lport->wwpn); 28442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 28542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 28642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 28742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_rtv_fill - Fill in RTV (read timeout value) request frame. 28842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 28942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp) 29042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 29142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_rtv *rtv; 29242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 29342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love rtv = fc_frame_payload_get(fp, sizeof(*rtv)); 29442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(rtv, 0, sizeof(*rtv)); 29542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love rtv->rtv_cmd = ELS_RTV; 29642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 29742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 29842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 29942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_rec_fill - Fill in rec request frame 30042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 30142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp) 30242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 30342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_rec *rec; 30442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_exch *ep = fc_seq_exch(fr_seq(fp)); 30542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 30642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love rec = fc_frame_payload_get(fp, sizeof(*rec)); 30742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(rec, 0, sizeof(*rec)); 30842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love rec->rec_cmd = ELS_REC; 3097b2787ec15b9d1c2f716da61b0eec21a3f5e6520Robert Love hton24(rec->rec_s_id, lport->port_id); 31042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love rec->rec_ox_id = htons(ep->oxid); 31142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love rec->rec_rx_id = htons(ep->rxid); 31242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 31342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 31442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 31542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_prli_fill - Fill in prli request frame 31642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 31742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp) 31842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 31942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct { 32042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_prli prli; 32142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_spp spp; 32242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love } *pp; 32342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 32442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love pp = fc_frame_payload_get(fp, sizeof(*pp)); 32542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(pp, 0, sizeof(*pp)); 32642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love pp->prli.prli_cmd = ELS_PRLI; 32742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love pp->prli.prli_spp_len = sizeof(struct fc_els_spp); 32842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love pp->prli.prli_len = htons(sizeof(*pp)); 32942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love pp->spp.spp_type = FC_TYPE_FCP; 33042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR; 33142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love pp->spp.spp_params = htonl(lport->service_params); 33242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 33342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 33442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 33542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_scr_fill - Fill in a scr request frame. 33642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 33742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Lovestatic inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) 33842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 33942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_els_scr *scr; 34042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 34142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love scr = fc_frame_payload_get(fp, sizeof(*scr)); 34242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love memset(scr, 0, sizeof(*scr)); 34342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love scr->scr_cmd = ELS_SCR; 34442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love scr->scr_reg_func = ELS_SCRF_FULL; 34542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 34642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 34742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love/** 34842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love * fc_els_fill - Fill in an ELS request frame 34942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love */ 3509fb9d32831fd687e427ec5b147bb690f468b99a0Joe Eykholtstatic inline int fc_els_fill(struct fc_lport *lport, 351a46f327aa5caf2cce138e98ddd863b6cca0e71e2Joe Eykholt u32 did, 35242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love struct fc_frame *fp, unsigned int op, 353a46f327aa5caf2cce138e98ddd863b6cca0e71e2Joe Eykholt enum fc_rctl *r_ctl, enum fc_fh_type *fh_type) 35442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love{ 35542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love switch (op) { 356370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt case ELS_ADISC: 357370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt fc_adisc_fill(lport, fp); 358370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt break; 359370c3bd05cf02afabea9cd3f2de66202d6b516dcJoe Eykholt 36042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case ELS_PLOGI: 36142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fc_plogi_fill(lport, fp, ELS_PLOGI); 36242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 36342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 36442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case ELS_FLOGI: 36542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fc_flogi_fill(lport, fp); 36642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 36742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 368db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech case ELS_FDISC: 369db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech fc_fdisc_fill(lport, fp); 370db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech break; 371db36c06cc6802d03bcba08982377f7c03a3cda7fChris Leech 37242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case ELS_LOGO: 37342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fc_logo_fill(lport, fp); 37442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 37542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 37642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case ELS_RTV: 37742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fc_rtv_fill(lport, fp); 37842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 37942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 38042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case ELS_REC: 38142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fc_rec_fill(lport, fp); 38242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 38342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 38442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case ELS_PRLI: 38542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fc_prli_fill(lport, fp); 38642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 38742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 38842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love case ELS_SCR: 38942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love fc_scr_fill(lport, fp); 39042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love break; 39142e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 39242e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love default: 39342e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love return -EINVAL; 39442e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love } 39542e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love 39642e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love *r_ctl = FC_RCTL_ELS_REQ; 39742e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love *fh_type = FC_TYPE_ELS; 39842e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love return 0; 39942e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love} 40042e9a92fe6a9095bd68a379aaec7ad2be0337f7aRobert Love#endif /* _FC_ENCODE_H_ */ 401