^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright(c) 2008 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Maintained at www.Open-FCoE.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef _FC_ENCODE_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define _FC_ENCODE_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * F_CTL values for simple requests and responses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define FC_FCTL_REQ (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define FC_FCTL_RESP (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) FC_FC_END_SEQ | FC_FC_SEQ_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct fc_ns_rft {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct fc_ns_fid fid; /* port ID object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct fc_ns_fts fts; /* FC4-types object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct fc_ct_req {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct fc_ct_hdr hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct fc_ns_gid_ft gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct fc_ns_rn_id rn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct fc_ns_rft rft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct fc_ns_rff_id rff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct fc_ns_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct fc_ns_rsnn snn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct fc_ns_rspn spn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct fc_fdmi_rhba rhba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct fc_fdmi_rpa rpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct fc_fdmi_dprt dprt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct fc_fdmi_dhba dhba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) } payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static inline void __fc_fill_fc_hdr(struct fc_frame_header *fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) enum fc_rctl r_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u32 did, u32 sid, enum fc_fh_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u32 f_ctl, u32 parm_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) WARN_ON(r_ctl == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) fh->fh_r_ctl = r_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) hton24(fh->fh_d_id, did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) hton24(fh->fh_s_id, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) fh->fh_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) hton24(fh->fh_f_ctl, f_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) fh->fh_cs_ctl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) fh->fh_df_ctl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) fh->fh_parm_offset = htonl(parm_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * fill FC header fields in specified fc_frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 did, u32 sid, enum fc_fh_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 f_ctl, u32 parm_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) __fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * fc_adisc_fill() - Fill in adisc request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @lport: local port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @fp: fc frame where payload will be placed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct fc_els_adisc *adisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) adisc = fc_frame_payload_get(fp, sizeof(*adisc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) memset(adisc, 0, sizeof(*adisc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) adisc->adisc_cmd = ELS_ADISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) hton24(adisc->adisc_port_id, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * fc_ct_hdr_fill- fills ct header and reset ct payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * returns pointer to ct request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned int op, size_t req_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) enum fc_ct_fs_type fs_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 subtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct fc_ct_req *ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) size_t ct_plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ct_plen = sizeof(struct fc_ct_hdr) + req_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ct = fc_frame_payload_get(fp, ct_plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) memset(ct, 0, ct_plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ct->hdr.ct_rev = FC_CT_REV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ct->hdr.ct_fs_type = fs_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ct->hdr.ct_fs_subtype = subtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ct->hdr.ct_cmd = htons((u16) op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * fc_ct_ns_fill() - Fill in a name service request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @lport: local port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @fp: frame to contain payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @op: CT opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @r_ctl: pointer to FC header R_CTL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @fh_type: pointer to FC-4 type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static inline int fc_ct_ns_fill(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u32 fc_id, struct fc_frame *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int op, enum fc_rctl *r_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) enum fc_fh_type *fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct fc_ct_req *ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case FC_NS_GPN_FT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) FC_FST_DIR, FC_NS_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case FC_NS_GPN_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) FC_FST_DIR, FC_NS_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) hton24(ct->payload.fid.fp_fid, fc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case FC_NS_RFT_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) FC_FST_DIR, FC_NS_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ct->payload.rft.fts = lport->fcts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case FC_NS_RFF_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) FC_FST_DIR, FC_NS_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ct->payload.rff.fr_type = FC_TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (lport->service_params & FCP_SPPF_INIT_FCN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ct->payload.rff.fr_feat = FCP_FEAT_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (lport->service_params & FCP_SPPF_TARG_FCN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case FC_NS_RNN_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) FC_FST_DIR, FC_NS_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case FC_NS_RSPN_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) len = strnlen(fc_host_symbolic_name(lport->host), 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) FC_FST_DIR, FC_NS_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) strncpy(ct->payload.spn.fr_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) fc_host_symbolic_name(lport->host), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ct->payload.spn.fr_name_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case FC_NS_RSNN_NN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) len = strnlen(fc_host_symbolic_name(lport->host), 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) FC_FST_DIR, FC_NS_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) strncpy(ct->payload.snn.fr_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) fc_host_symbolic_name(lport->host), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ct->payload.snn.fr_name_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *r_ctl = FC_RCTL_DD_UNSOL_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *fh_type = FC_TYPE_CT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * fc_ct_ms_fill() - Fill in a mgmt service request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @lport: local port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @fp: frame to contain payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @op: CT opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @r_ctl: pointer to FC header R_CTL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * @fh_type: pointer to FC-4 type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static inline int fc_ct_ms_fill(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u32 fc_id, struct fc_frame *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned int op, enum fc_rctl *r_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) enum fc_fh_type *fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct fc_ct_req *ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct fc_fdmi_attr_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct fs_fdmi_attrs *hba_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int numattrs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case FC_FDMI_RHBA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) numattrs = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) len = sizeof(struct fc_fdmi_rhba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) len -= sizeof(struct fc_fdmi_attr_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) len += FC_FDMI_HBA_ATTR_MODEL_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) FC_FDMI_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* HBA Identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* Number of Ports - always 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) put_unaligned_be32(1, &ct->payload.rhba.port.numport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Port Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) put_unaligned_be64(lport->wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) &ct->payload.rhba.port.port[0].portname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* HBA Attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) put_unaligned_be32(numattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) &ct->payload.rhba.hba_attrs.numattrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) hba_attrs = &ct->payload.rhba.hba_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* NodeName*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) put_unaligned_be64(lport->wwnn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) (__be64 *)&entry->value[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* Manufacturer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) FC_FDMI_HBA_ATTR_NODENAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) fc_host_manufacturer(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* SerialNumber */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) fc_host_serial_number(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Model */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) len += FC_FDMI_HBA_ATTR_MODEL_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) fc_host_model(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) FC_FDMI_HBA_ATTR_MODEL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Model Description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) FC_FDMI_HBA_ATTR_MODEL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) fc_host_model_description(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* Hardware Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) fc_host_hardware_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Driver Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) fc_host_driver_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* OptionROM Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) fc_host_optionrom_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Firmware Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) fc_host_firmware_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* OS Name and Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) snprintf((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) "%s v%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) init_utsname()->sysname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) init_utsname()->release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case FC_FDMI_RPA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) numattrs = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) len = sizeof(struct fc_fdmi_rpa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) len -= sizeof(struct fc_fdmi_attr_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) FC_FDMI_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* Port Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) put_unaligned_be64(lport->wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) &ct->payload.rpa.port.portname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Port Attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) put_unaligned_be32(numattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) &ct->payload.rpa.hba_attrs.numattrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) hba_attrs = &ct->payload.rpa.hba_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* FC4 types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) memcpy(&entry->value, fc_host_supported_fc4s(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* Supported Speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) put_unaligned_be32(fc_host_supported_speeds(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) &entry->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Current Port Speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) put_unaligned_be32(lport->link_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) &entry->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Max Frame Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) put_unaligned_be32(fc_host_maxframe_size(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) &entry->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* OS Device Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* Use the sysfs device name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dev_name(&lport->host->shost_gendev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) strnlen(dev_name(&lport->host->shost_gendev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* Host Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) &entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) put_unaligned_be16(len, &entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (strlen(fc_host_system_hostname(lport->host)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) fc_host_system_hostname(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) strnlen(fc_host_system_hostname(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) strncpy((char *)&entry->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) init_utsname()->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case FC_FDMI_DPRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) len = sizeof(struct fc_fdmi_dprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) FC_FDMI_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* Port Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) put_unaligned_be64(lport->wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) &ct->payload.dprt.port.portname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) case FC_FDMI_DHBA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) len = sizeof(struct fc_fdmi_dhba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) FC_FDMI_SUBTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* HBA Identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) *r_ctl = FC_RCTL_DD_UNSOL_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) *fh_type = FC_TYPE_CT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * fc_ct_fill() - Fill in a common transport service request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * @lport: local port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * @fp: frame to contain payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * @op: CT opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * @r_ctl: pointer to FC header R_CTL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * @fh_type: pointer to FC-4 type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static inline int fc_ct_fill(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 fc_id, struct fc_frame *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) unsigned int op, enum fc_rctl *r_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) enum fc_fh_type *fh_type, u32 *did)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) switch (fc_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) case FC_FID_MGMT_SERV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) *did = FC_FID_MGMT_SERV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) case FC_FID_DIR_SERV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) *did = FC_FID_DIR_SERV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * fc_plogi_fill - Fill in plogi request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) unsigned int op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct fc_els_flogi *plogi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct fc_els_csp *csp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct fc_els_cssp *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) plogi = fc_frame_payload_get(fp, sizeof(*plogi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) memset(plogi, 0, sizeof(*plogi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) plogi->fl_cmd = (u8) op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) csp = &plogi->fl_csp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) csp->sp_hi_ver = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) csp->sp_lo_ver = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) csp->sp_bb_cred = htons(10); /* this gets set by gateway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) csp->sp_bb_data = htons((u16) lport->mfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) csp->sp_features = htons(FC_SP_FT_CIRO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) csp->sp_tot_seq = htons(255); /* seq. we accept */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) csp->sp_rel_off = htons(0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) csp->sp_e_d_tov = htonl(lport->e_d_tov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) cp->cp_rdfs = htons((u16) lport->mfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) cp->cp_con_seq = htons(255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) cp->cp_open_seq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * fc_flogi_fill - Fill in a flogi request frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct fc_els_csp *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct fc_els_cssp *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct fc_els_flogi *flogi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) flogi = fc_frame_payload_get(fp, sizeof(*flogi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) memset(flogi, 0, sizeof(*flogi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) flogi->fl_cmd = (u8) ELS_FLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) sp = &flogi->fl_csp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) sp->sp_hi_ver = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) sp->sp_lo_ver = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) sp->sp_bb_cred = htons(10); /* this gets set by gateway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) sp->sp_bb_data = htons((u16) lport->mfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (lport->does_npiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) sp->sp_features = htons(FC_SP_FT_NPIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * fc_fdisc_fill - Fill in a fdisc request frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct fc_els_csp *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct fc_els_cssp *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct fc_els_flogi *fdisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) memset(fdisc, 0, sizeof(*fdisc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) fdisc->fl_cmd = (u8) ELS_FDISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) sp = &fdisc->fl_csp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) sp->sp_hi_ver = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) sp->sp_lo_ver = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) sp->sp_bb_cred = htons(10); /* this gets set by gateway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) sp->sp_bb_data = htons((u16) lport->mfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) cp = &fdisc->fl_cssp[3 - 1]; /* class 3 parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * fc_logo_fill - Fill in a logo request frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct fc_els_logo *logo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) logo = fc_frame_payload_get(fp, sizeof(*logo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) memset(logo, 0, sizeof(*logo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) logo->fl_cmd = ELS_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) hton24(logo->fl_n_port_id, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) logo->fl_n_port_wwn = htonll(lport->wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct fc_els_rtv *rtv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) rtv = fc_frame_payload_get(fp, sizeof(*rtv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) memset(rtv, 0, sizeof(*rtv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) rtv->rtv_cmd = ELS_RTV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * fc_rec_fill - Fill in rec request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct fc_els_rec *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct fc_exch *ep = fc_seq_exch(fr_seq(fp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) rec = fc_frame_payload_get(fp, sizeof(*rec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) memset(rec, 0, sizeof(*rec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) rec->rec_cmd = ELS_REC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) hton24(rec->rec_s_id, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) rec->rec_ox_id = htons(ep->oxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) rec->rec_rx_id = htons(ep->rxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * fc_prli_fill - Fill in prli request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct fc_els_prli prli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct fc_els_spp spp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) } *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) pp = fc_frame_payload_get(fp, sizeof(*pp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) memset(pp, 0, sizeof(*pp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) pp->prli.prli_cmd = ELS_PRLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) pp->prli.prli_len = htons(sizeof(*pp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) pp->spp.spp_type = FC_TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) pp->spp.spp_params = htonl(lport->service_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * fc_scr_fill - Fill in a scr request frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct fc_els_scr *scr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) scr = fc_frame_payload_get(fp, sizeof(*scr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) memset(scr, 0, sizeof(*scr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) scr->scr_cmd = ELS_SCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) scr->scr_reg_func = ELS_SCRF_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * fc_els_fill - Fill in an ELS request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static inline int fc_els_fill(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) u32 did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct fc_frame *fp, unsigned int op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) case ELS_ADISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) fc_adisc_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case ELS_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) fc_plogi_fill(lport, fp, ELS_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case ELS_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) fc_flogi_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case ELS_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) fc_fdisc_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case ELS_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) fc_logo_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case ELS_RTV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) fc_rtv_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) case ELS_REC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) fc_rec_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case ELS_PRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) fc_prli_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case ELS_SCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) fc_scr_fill(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) *r_ctl = FC_RCTL_ELS_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) *fh_type = FC_TYPE_ELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) #endif /* _FC_ENCODE_H_ */