1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright(c) 2008 Intel Corporation. All rights reserved. 4 * 5 * Maintained at www.Open-FCoE.org 6 */ 7 8 #ifndef _FC_ENCODE_H_ 9 #define _FC_ENCODE_H_ 10 #include <linux/unaligned.h> 11 #include <linux/utsname.h> 12 #include <scsi/fc/fc_ms.h> 13 14 /* 15 * F_CTL values for simple requests and responses. 16 */ 17 #define FC_FCTL_REQ (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT) 18 #define FC_FCTL_RESP (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \ 19 FC_FC_END_SEQ | FC_FC_SEQ_INIT) 20 21 struct fc_ns_rft { 22 struct fc_ns_fid fid; /* port ID object */ 23 struct fc_ns_fts fts; /* FC4-types object */ 24 }; 25 26 struct fc_ct_req { 27 struct fc_ct_hdr hdr; 28 union { 29 struct fc_ns_gid_ft gid; 30 struct fc_ns_rn_id rn; 31 struct fc_ns_rft rft; 32 struct fc_ns_rff_id rff; 33 struct fc_ns_fid fid; 34 struct fc_ns_rsnn snn; 35 struct fc_ns_rspn spn; 36 struct fc_fdmi_rhba rhba; 37 struct fc_fdmi_rpa rpa; 38 struct fc_fdmi_dprt dprt; 39 struct fc_fdmi_dhba dhba; 40 } payload; 41 }; 42 43 /** 44 * fc_adisc_fill() - Fill in adisc request frame 45 * @lport: local port. 46 * @fp: fc frame where payload will be placed. 47 */ 48 static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp) 49 { 50 struct fc_els_adisc *adisc; 51 52 adisc = fc_frame_payload_get(fp, sizeof(*adisc)); 53 memset(adisc, 0, sizeof(*adisc)); 54 adisc->adisc_cmd = ELS_ADISC; 55 put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn); 56 put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn); 57 hton24(adisc->adisc_port_id, lport->port_id); 58 } 59 60 /** 61 * fc_ct_hdr_fill- fills ct header and reset ct payload 62 * returns pointer to ct request. 63 */ 64 static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, 65 unsigned int op, size_t req_size, 66 enum fc_ct_fs_type fs_type, 67 u8 subtype) 68 { 69 struct fc_ct_req *ct; 70 size_t ct_plen; 71 72 ct_plen = sizeof(struct fc_ct_hdr) + req_size; 73 ct = fc_frame_payload_get(fp, ct_plen); 74 memset(ct, 0, ct_plen); 75 ct->hdr.ct_rev = FC_CT_REV; 76 ct->hdr.ct_fs_type = fs_type; 77 ct->hdr.ct_fs_subtype = subtype; 78 ct->hdr.ct_cmd = htons((u16) op); 79 return ct; 80 } 81 82 /** 83 * fc_ct_ns_fill() - Fill in a name service request frame 84 * @lport: local port. 85 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. 86 * @fp: frame to contain payload. 87 * @op: CT opcode. 88 * @r_ctl: pointer to FC header R_CTL. 89 * @fh_type: pointer to FC-4 type. 90 */ 91 static inline int fc_ct_ns_fill(struct fc_lport *lport, 92 u32 fc_id, struct fc_frame *fp, 93 unsigned int op, enum fc_rctl *r_ctl, 94 enum fc_fh_type *fh_type) 95 { 96 struct fc_ct_req *ct; 97 size_t len; 98 99 switch (op) { 100 case FC_NS_GPN_FT: 101 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft), 102 FC_FST_DIR, FC_NS_SUBTYPE); 103 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; 104 break; 105 106 case FC_NS_GPN_ID: 107 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid), 108 FC_FST_DIR, FC_NS_SUBTYPE); 109 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; 110 hton24(ct->payload.fid.fp_fid, fc_id); 111 break; 112 113 case FC_NS_RFT_ID: 114 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft), 115 FC_FST_DIR, FC_NS_SUBTYPE); 116 hton24(ct->payload.rft.fid.fp_fid, lport->port_id); 117 ct->payload.rft.fts = lport->fcts; 118 break; 119 120 case FC_NS_RFF_ID: 121 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id), 122 FC_FST_DIR, FC_NS_SUBTYPE); 123 hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id); 124 ct->payload.rff.fr_type = FC_TYPE_FCP; 125 if (lport->service_params & FCP_SPPF_INIT_FCN) 126 ct->payload.rff.fr_feat = FCP_FEAT_INIT; 127 if (lport->service_params & FCP_SPPF_TARG_FCN) 128 ct->payload.rff.fr_feat |= FCP_FEAT_TARG; 129 break; 130 131 case FC_NS_RNN_ID: 132 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id), 133 FC_FST_DIR, FC_NS_SUBTYPE); 134 hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id); 135 put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn); 136 break; 137 138 case FC_NS_RSPN_ID: 139 len = strnlen(fc_host_symbolic_name(lport->host), 140 FC_SYMBOLIC_NAME_SIZE); 141 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len, 142 FC_FST_DIR, FC_NS_SUBTYPE); 143 hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id); 144 memcpy(ct->payload.spn.fr_name, 145 fc_host_symbolic_name(lport->host), len); 146 ct->payload.spn.fr_name_len = len; 147 break; 148 149 case FC_NS_RSNN_NN: 150 len = strnlen(fc_host_symbolic_name(lport->host), 151 FC_SYMBOLIC_NAME_SIZE); 152 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len, 153 FC_FST_DIR, FC_NS_SUBTYPE); 154 put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn); 155 memcpy(ct->payload.snn.fr_name, 156 fc_host_symbolic_name(lport->host), len); 157 ct->payload.snn.fr_name_len = len; 158 break; 159 160 default: 161 return -EINVAL; 162 } 163 *r_ctl = FC_RCTL_DD_UNSOL_CTL; 164 *fh_type = FC_TYPE_CT; 165 return 0; 166 } 167 168 static inline void fc_ct_ms_fill_attr(struct fc_fdmi_attr_entry *entry, 169 const char *in, size_t len) 170 { 171 int copied; 172 173 copied = strscpy(entry->value, in, len); 174 if (copied > 0 && copied + 1 < len) 175 memset(entry->value + copied + 1, 0, len - copied - 1); 176 } 177 178 /** 179 * fc_ct_ms_fill() - Fill in a mgmt service request frame 180 * @lport: local port. 181 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. 182 * @fp: frame to contain payload. 183 * @op: CT opcode. 184 * @r_ctl: pointer to FC header R_CTL. 185 * @fh_type: pointer to FC-4 type. 186 */ 187 static inline int fc_ct_ms_fill(struct fc_lport *lport, 188 u32 fc_id, struct fc_frame *fp, 189 unsigned int op, enum fc_rctl *r_ctl, 190 enum fc_fh_type *fh_type) 191 { 192 struct fc_ct_req *ct; 193 size_t len; 194 struct fc_fdmi_attr_entry *entry; 195 struct fs_fdmi_attrs *hba_attrs; 196 int numattrs = 0; 197 struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host); 198 199 switch (op) { 200 case FC_FDMI_RHBA: 201 numattrs = 11; 202 len = sizeof(struct fc_fdmi_rhba); 203 len -= sizeof(struct fc_fdmi_attr_entry); 204 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); 205 len += FC_FDMI_HBA_ATTR_NODENAME_LEN; 206 len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN; 207 len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN; 208 len += FC_FDMI_HBA_ATTR_MODEL_LEN; 209 len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN; 210 len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN; 211 len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN; 212 len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN; 213 len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN; 214 len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN; 215 len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN; 216 217 if (fc_host->fdmi_version == FDMI_V2) { 218 numattrs += 7; 219 len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN; 220 len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN; 221 len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN; 222 len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN; 223 len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN; 224 len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN; 225 len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN; 226 } 227 228 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, 229 FC_FDMI_SUBTYPE); 230 231 /* HBA Identifier */ 232 put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id); 233 /* Number of Ports - always 1 */ 234 put_unaligned_be32(1, &ct->payload.rhba.port.numport); 235 /* Port Name */ 236 put_unaligned_be64(lport->wwpn, 237 &ct->payload.rhba.port.port[0].portname); 238 239 /* HBA Attributes */ 240 put_unaligned_be32(numattrs, 241 &ct->payload.rhba.hba_attrs.numattrs); 242 hba_attrs = &ct->payload.rhba.hba_attrs; 243 entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr; 244 /* NodeName*/ 245 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 246 len += FC_FDMI_HBA_ATTR_NODENAME_LEN; 247 put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME, 248 &entry->type); 249 put_unaligned_be16(len, &entry->len); 250 put_unaligned_be64(lport->wwnn, 251 (__be64 *)&entry->value); 252 253 /* Manufacturer */ 254 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 255 FC_FDMI_HBA_ATTR_NODENAME_LEN); 256 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 257 len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN; 258 put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER, 259 &entry->type); 260 put_unaligned_be16(len, &entry->len); 261 fc_ct_ms_fill_attr(entry, 262 fc_host_manufacturer(lport->host), 263 FC_FDMI_HBA_ATTR_MANUFACTURER_LEN); 264 265 /* SerialNumber */ 266 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 267 FC_FDMI_HBA_ATTR_MANUFACTURER_LEN); 268 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 269 len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN; 270 put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER, 271 &entry->type); 272 put_unaligned_be16(len, &entry->len); 273 fc_ct_ms_fill_attr(entry, 274 fc_host_serial_number(lport->host), 275 FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN); 276 277 /* Model */ 278 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 279 FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN); 280 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 281 len += FC_FDMI_HBA_ATTR_MODEL_LEN; 282 put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL, 283 &entry->type); 284 put_unaligned_be16(len, &entry->len); 285 fc_ct_ms_fill_attr(entry, 286 fc_host_model(lport->host), 287 FC_FDMI_HBA_ATTR_MODEL_LEN); 288 289 /* Model Description */ 290 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 291 FC_FDMI_HBA_ATTR_MODEL_LEN); 292 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 293 len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN; 294 put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION, 295 &entry->type); 296 put_unaligned_be16(len, &entry->len); 297 fc_ct_ms_fill_attr(entry, 298 fc_host_model_description(lport->host), 299 FC_FDMI_HBA_ATTR_MODELDESCR_LEN); 300 301 /* Hardware Version */ 302 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 303 FC_FDMI_HBA_ATTR_MODELDESCR_LEN); 304 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 305 len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN; 306 put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION, 307 &entry->type); 308 put_unaligned_be16(len, &entry->len); 309 fc_ct_ms_fill_attr(entry, 310 fc_host_hardware_version(lport->host), 311 FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN); 312 313 /* Driver Version */ 314 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 315 FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN); 316 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 317 len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN; 318 put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION, 319 &entry->type); 320 put_unaligned_be16(len, &entry->len); 321 fc_ct_ms_fill_attr(entry, 322 fc_host_driver_version(lport->host), 323 FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN); 324 325 /* OptionROM Version */ 326 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 327 FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN); 328 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 329 len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN; 330 put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION, 331 &entry->type); 332 put_unaligned_be16(len, &entry->len); 333 fc_ct_ms_fill_attr(entry, 334 "unknown", 335 FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN); 336 337 /* Firmware Version */ 338 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 339 FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN); 340 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 341 len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN; 342 put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION, 343 &entry->type); 344 put_unaligned_be16(len, &entry->len); 345 fc_ct_ms_fill_attr(entry, 346 fc_host_firmware_version(lport->host), 347 FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN); 348 349 /* OS Name and Version */ 350 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 351 FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN); 352 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 353 len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN; 354 put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION, 355 &entry->type); 356 put_unaligned_be16(len, &entry->len); 357 snprintf((char *)&entry->value, 358 FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN, 359 "%s v%s", 360 init_utsname()->sysname, 361 init_utsname()->release); 362 363 /* Max CT payload */ 364 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 365 FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN); 366 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 367 len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN; 368 put_unaligned_be16(FC_FDMI_HBA_ATTR_MAXCTPAYLOAD, 369 &entry->type); 370 put_unaligned_be16(len, &entry->len); 371 put_unaligned_be32(fc_host_max_ct_payload(lport->host), 372 &entry->value); 373 374 if (fc_host->fdmi_version == FDMI_V2) { 375 /* Node symbolic name */ 376 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 377 FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN); 378 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 379 len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN; 380 put_unaligned_be16(FC_FDMI_HBA_ATTR_NODESYMBLNAME, 381 &entry->type); 382 put_unaligned_be16(len, &entry->len); 383 fc_ct_ms_fill_attr(entry, 384 fc_host_symbolic_name(lport->host), 385 FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN); 386 387 /* Vendor specific info */ 388 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 389 FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN); 390 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 391 len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN; 392 put_unaligned_be16(FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO, 393 &entry->type); 394 put_unaligned_be16(len, &entry->len); 395 put_unaligned_be32(0, 396 &entry->value); 397 398 /* Number of ports */ 399 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 400 FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN); 401 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 402 len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN; 403 put_unaligned_be16(FC_FDMI_HBA_ATTR_NUMBEROFPORTS, 404 &entry->type); 405 put_unaligned_be16(len, &entry->len); 406 put_unaligned_be32(fc_host_num_ports(lport->host), 407 &entry->value); 408 409 /* Fabric name */ 410 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 411 FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN); 412 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 413 len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN; 414 put_unaligned_be16(FC_FDMI_HBA_ATTR_FABRICNAME, 415 &entry->type); 416 put_unaligned_be16(len, &entry->len); 417 put_unaligned_be64(fc_host_fabric_name(lport->host), 418 &entry->value); 419 420 /* BIOS version */ 421 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 422 FC_FDMI_HBA_ATTR_FABRICNAME_LEN); 423 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 424 len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN; 425 put_unaligned_be16(FC_FDMI_HBA_ATTR_BIOSVERSION, 426 &entry->type); 427 put_unaligned_be16(len, &entry->len); 428 fc_ct_ms_fill_attr(entry, 429 fc_host_bootbios_version(lport->host), 430 FC_FDMI_HBA_ATTR_BIOSVERSION_LEN); 431 432 /* BIOS state */ 433 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 434 FC_FDMI_HBA_ATTR_BIOSVERSION_LEN); 435 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 436 len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN; 437 put_unaligned_be16(FC_FDMI_HBA_ATTR_BIOSSTATE, 438 &entry->type); 439 put_unaligned_be16(len, &entry->len); 440 put_unaligned_be32(fc_host_bootbios_state(lport->host), 441 &entry->value); 442 443 /* Vendor identifier */ 444 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 445 FC_FDMI_HBA_ATTR_BIOSSTATE_LEN); 446 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 447 len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN; 448 put_unaligned_be16(FC_FDMI_HBA_ATTR_VENDORIDENTIFIER, 449 &entry->type); 450 put_unaligned_be16(len, &entry->len); 451 fc_ct_ms_fill_attr(entry, 452 fc_host_vendor_identifier(lport->host), 453 FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN); 454 } 455 456 break; 457 case FC_FDMI_RPA: 458 numattrs = 6; 459 len = sizeof(struct fc_fdmi_rpa); 460 len -= sizeof(struct fc_fdmi_attr_entry); 461 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); 462 len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN; 463 len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN; 464 len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN; 465 len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN; 466 len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN; 467 len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN; 468 469 470 if (fc_host->fdmi_version == FDMI_V2) { 471 numattrs += 10; 472 473 len += FC_FDMI_PORT_ATTR_NODENAME_LEN; 474 len += FC_FDMI_PORT_ATTR_PORTNAME_LEN; 475 len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN; 476 len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN; 477 len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN; 478 len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN; 479 len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN; 480 len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN; 481 len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN; 482 len += FC_FDMI_PORT_ATTR_PORTID_LEN; 483 484 } 485 486 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, 487 FC_FDMI_SUBTYPE); 488 489 /* Port Name */ 490 put_unaligned_be64(lport->wwpn, 491 &ct->payload.rpa.port.portname); 492 493 /* Port Attributes */ 494 put_unaligned_be32(numattrs, 495 &ct->payload.rpa.hba_attrs.numattrs); 496 497 hba_attrs = &ct->payload.rpa.hba_attrs; 498 entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr; 499 500 /* FC4 types */ 501 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 502 len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN; 503 put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES, 504 &entry->type); 505 put_unaligned_be16(len, &entry->len); 506 memcpy(&entry->value, fc_host_supported_fc4s(lport->host), 507 FC_FDMI_PORT_ATTR_FC4TYPES_LEN); 508 509 /* Supported Speed */ 510 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 511 FC_FDMI_PORT_ATTR_FC4TYPES_LEN); 512 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 513 len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN; 514 put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED, 515 &entry->type); 516 put_unaligned_be16(len, &entry->len); 517 518 put_unaligned_be32(fc_host_supported_speeds(lport->host), 519 &entry->value); 520 521 /* Current Port Speed */ 522 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 523 FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN); 524 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 525 len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN; 526 put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED, 527 &entry->type); 528 put_unaligned_be16(len, &entry->len); 529 put_unaligned_be32(lport->link_speed, 530 &entry->value); 531 532 /* Max Frame Size */ 533 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 534 FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN); 535 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 536 len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN; 537 put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE, 538 &entry->type); 539 put_unaligned_be16(len, &entry->len); 540 put_unaligned_be32(fc_host_maxframe_size(lport->host), 541 &entry->value); 542 543 /* OS Device Name */ 544 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 545 FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN); 546 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 547 len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN; 548 put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME, 549 &entry->type); 550 put_unaligned_be16(len, &entry->len); 551 /* Use the sysfs device name */ 552 fc_ct_ms_fill_attr(entry, 553 dev_name(&lport->host->shost_gendev), 554 strnlen(dev_name(&lport->host->shost_gendev), 555 FC_FDMI_PORT_ATTR_HOSTNAME_LEN)); 556 557 /* Host Name */ 558 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 559 FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN); 560 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 561 len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN; 562 put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME, 563 &entry->type); 564 put_unaligned_be16(len, &entry->len); 565 if (strlen(fc_host_system_hostname(lport->host))) 566 fc_ct_ms_fill_attr(entry, 567 fc_host_system_hostname(lport->host), 568 strnlen(fc_host_system_hostname(lport->host), 569 FC_FDMI_PORT_ATTR_HOSTNAME_LEN)); 570 else 571 fc_ct_ms_fill_attr(entry, 572 init_utsname()->nodename, 573 FC_FDMI_PORT_ATTR_HOSTNAME_LEN); 574 575 576 if (fc_host->fdmi_version == FDMI_V2) { 577 578 /* Node name */ 579 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 580 FC_FDMI_PORT_ATTR_HOSTNAME_LEN); 581 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 582 len += FC_FDMI_PORT_ATTR_NODENAME_LEN; 583 put_unaligned_be16(FC_FDMI_PORT_ATTR_NODENAME, 584 &entry->type); 585 put_unaligned_be16(len, &entry->len); 586 put_unaligned_be64(fc_host_node_name(lport->host), 587 &entry->value); 588 589 /* Port name */ 590 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 591 FC_FDMI_PORT_ATTR_NODENAME_LEN); 592 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 593 len += FC_FDMI_PORT_ATTR_PORTNAME_LEN; 594 put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTNAME, 595 &entry->type); 596 put_unaligned_be16(len, &entry->len); 597 put_unaligned_be64(lport->wwpn, 598 &entry->value); 599 600 /* Port symbolic name */ 601 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 602 FC_FDMI_PORT_ATTR_PORTNAME_LEN); 603 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 604 len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN; 605 put_unaligned_be16(FC_FDMI_PORT_ATTR_SYMBOLICNAME, 606 &entry->type); 607 put_unaligned_be16(len, &entry->len); 608 fc_ct_ms_fill_attr(entry, 609 fc_host_symbolic_name(lport->host), 610 FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN); 611 612 /* Port type */ 613 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 614 FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN); 615 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 616 len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN; 617 put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTTYPE, 618 &entry->type); 619 put_unaligned_be16(len, &entry->len); 620 put_unaligned_be32(fc_host_port_type(lport->host), 621 &entry->value); 622 623 /* Supported class of service */ 624 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 625 FC_FDMI_PORT_ATTR_PORTTYPE_LEN); 626 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 627 len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN; 628 put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC, 629 &entry->type); 630 put_unaligned_be16(len, &entry->len); 631 put_unaligned_be32(fc_host_supported_classes(lport->host), 632 &entry->value); 633 634 /* Port Fabric name */ 635 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 636 FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN); 637 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 638 len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN; 639 put_unaligned_be16(FC_FDMI_PORT_ATTR_FABRICNAME, 640 &entry->type); 641 put_unaligned_be16(len, &entry->len); 642 put_unaligned_be64(fc_host_fabric_name(lport->host), 643 &entry->value); 644 645 /* Port active FC-4 */ 646 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 647 FC_FDMI_PORT_ATTR_FABRICNAME_LEN); 648 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 649 len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN; 650 put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTFC4TYPE, 651 &entry->type); 652 put_unaligned_be16(len, &entry->len); 653 memcpy(&entry->value, fc_host_active_fc4s(lport->host), 654 FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN); 655 656 /* Port state */ 657 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 658 FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN); 659 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 660 len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN; 661 put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTSTATE, 662 &entry->type); 663 put_unaligned_be16(len, &entry->len); 664 put_unaligned_be32(fc_host_port_state(lport->host), 665 &entry->value); 666 667 /* Discovered ports */ 668 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 669 FC_FDMI_PORT_ATTR_PORTSTATE_LEN); 670 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 671 len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN; 672 put_unaligned_be16(FC_FDMI_PORT_ATTR_DISCOVEREDPORTS, 673 &entry->type); 674 put_unaligned_be16(len, &entry->len); 675 put_unaligned_be32(fc_host_num_discovered_ports(lport->host), 676 &entry->value); 677 678 /* Port ID */ 679 entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + 680 FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN); 681 len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; 682 len += FC_FDMI_PORT_ATTR_PORTID_LEN; 683 put_unaligned_be16(FC_FDMI_PORT_ATTR_PORTID, 684 &entry->type); 685 put_unaligned_be16(len, &entry->len); 686 put_unaligned_be32(fc_host_port_id(lport->host), 687 &entry->value); 688 } 689 690 break; 691 case FC_FDMI_DPRT: 692 len = sizeof(struct fc_fdmi_dprt); 693 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, 694 FC_FDMI_SUBTYPE); 695 /* Port Name */ 696 put_unaligned_be64(lport->wwpn, 697 &ct->payload.dprt.port.portname); 698 break; 699 case FC_FDMI_DHBA: 700 len = sizeof(struct fc_fdmi_dhba); 701 ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, 702 FC_FDMI_SUBTYPE); 703 /* HBA Identifier */ 704 put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id); 705 break; 706 default: 707 return -EINVAL; 708 } 709 *r_ctl = FC_RCTL_DD_UNSOL_CTL; 710 *fh_type = FC_TYPE_CT; 711 return 0; 712 } 713 714 /** 715 * fc_ct_fill() - Fill in a common transport service request frame 716 * @lport: local port. 717 * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. 718 * @fp: frame to contain payload. 719 * @op: CT opcode. 720 * @r_ctl: pointer to FC header R_CTL. 721 * @fh_type: pointer to FC-4 type. 722 */ 723 static inline int fc_ct_fill(struct fc_lport *lport, 724 u32 fc_id, struct fc_frame *fp, 725 unsigned int op, enum fc_rctl *r_ctl, 726 enum fc_fh_type *fh_type, u32 *did) 727 { 728 int rc = -EINVAL; 729 730 switch (fc_id) { 731 case FC_FID_MGMT_SERV: 732 rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type); 733 *did = FC_FID_MGMT_SERV; 734 break; 735 case FC_FID_DIR_SERV: 736 default: 737 rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type); 738 *did = FC_FID_DIR_SERV; 739 break; 740 } 741 742 return rc; 743 } 744 /** 745 * fc_plogi_fill - Fill in plogi request frame 746 */ 747 static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, 748 unsigned int op) 749 { 750 struct fc_els_flogi *plogi; 751 struct fc_els_csp *csp; 752 struct fc_els_cssp *cp; 753 754 plogi = fc_frame_payload_get(fp, sizeof(*plogi)); 755 memset(plogi, 0, sizeof(*plogi)); 756 plogi->fl_cmd = (u8) op; 757 put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn); 758 put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn); 759 760 csp = &plogi->fl_csp; 761 csp->sp_hi_ver = 0x20; 762 csp->sp_lo_ver = 0x20; 763 csp->sp_bb_cred = htons(10); /* this gets set by gateway */ 764 csp->sp_bb_data = htons((u16) lport->mfs); 765 cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */ 766 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 767 csp->sp_features = htons(FC_SP_FT_CIRO); 768 csp->sp_tot_seq = htons(255); /* seq. we accept */ 769 csp->sp_rel_off = htons(0x1f); 770 csp->sp_e_d_tov = htonl(lport->e_d_tov); 771 772 cp->cp_rdfs = htons((u16) lport->mfs); 773 cp->cp_con_seq = htons(255); 774 cp->cp_open_seq = 1; 775 } 776 777 /** 778 * fc_flogi_fill - Fill in a flogi request frame. 779 */ 780 static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) 781 { 782 struct fc_els_csp *sp; 783 struct fc_els_cssp *cp; 784 struct fc_els_flogi *flogi; 785 786 flogi = fc_frame_payload_get(fp, sizeof(*flogi)); 787 memset(flogi, 0, sizeof(*flogi)); 788 flogi->fl_cmd = (u8) ELS_FLOGI; 789 put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); 790 put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); 791 sp = &flogi->fl_csp; 792 sp->sp_hi_ver = 0x20; 793 sp->sp_lo_ver = 0x20; 794 sp->sp_bb_cred = htons(10); /* this gets set by gateway */ 795 sp->sp_bb_data = htons((u16) lport->mfs); 796 cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ 797 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 798 if (lport->does_npiv) 799 sp->sp_features = htons(FC_SP_FT_NPIV); 800 } 801 802 /** 803 * fc_fdisc_fill - Fill in a fdisc request frame. 804 */ 805 static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp) 806 { 807 struct fc_els_csp *sp; 808 struct fc_els_cssp *cp; 809 struct fc_els_flogi *fdisc; 810 811 fdisc = fc_frame_payload_get(fp, sizeof(*fdisc)); 812 memset(fdisc, 0, sizeof(*fdisc)); 813 fdisc->fl_cmd = (u8) ELS_FDISC; 814 put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn); 815 put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn); 816 sp = &fdisc->fl_csp; 817 sp->sp_hi_ver = 0x20; 818 sp->sp_lo_ver = 0x20; 819 sp->sp_bb_cred = htons(10); /* this gets set by gateway */ 820 sp->sp_bb_data = htons((u16) lport->mfs); 821 cp = &fdisc->fl_cssp[3 - 1]; /* class 3 parameters */ 822 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 823 } 824 825 /** 826 * fc_logo_fill - Fill in a logo request frame. 827 */ 828 static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp) 829 { 830 struct fc_els_logo *logo; 831 832 logo = fc_frame_payload_get(fp, sizeof(*logo)); 833 memset(logo, 0, sizeof(*logo)); 834 logo->fl_cmd = ELS_LOGO; 835 hton24(logo->fl_n_port_id, lport->port_id); 836 logo->fl_n_port_wwn = htonll(lport->wwpn); 837 } 838 839 /** 840 * fc_rtv_fill - Fill in RTV (read timeout value) request frame. 841 */ 842 static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp) 843 { 844 struct fc_els_rtv *rtv; 845 846 rtv = fc_frame_payload_get(fp, sizeof(*rtv)); 847 memset(rtv, 0, sizeof(*rtv)); 848 rtv->rtv_cmd = ELS_RTV; 849 } 850 851 /** 852 * fc_rec_fill - Fill in rec request frame 853 */ 854 static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp) 855 { 856 struct fc_els_rec *rec; 857 struct fc_exch *ep = fc_seq_exch(fr_seq(fp)); 858 859 rec = fc_frame_payload_get(fp, sizeof(*rec)); 860 memset(rec, 0, sizeof(*rec)); 861 rec->rec_cmd = ELS_REC; 862 hton24(rec->rec_s_id, lport->port_id); 863 rec->rec_ox_id = htons(ep->oxid); 864 rec->rec_rx_id = htons(ep->rxid); 865 } 866 867 /** 868 * fc_prli_fill - Fill in prli request frame 869 */ 870 static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp) 871 { 872 struct { 873 struct fc_els_prli prli; 874 struct fc_els_spp spp; 875 } *pp; 876 877 pp = fc_frame_payload_get(fp, sizeof(*pp)); 878 memset(pp, 0, sizeof(*pp)); 879 pp->prli.prli_cmd = ELS_PRLI; 880 pp->prli.prli_spp_len = sizeof(struct fc_els_spp); 881 pp->prli.prli_len = htons(sizeof(*pp)); 882 pp->spp.spp_type = FC_TYPE_FCP; 883 pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR; 884 pp->spp.spp_params = htonl(lport->service_params); 885 } 886 887 /** 888 * fc_scr_fill - Fill in a scr request frame. 889 */ 890 static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) 891 { 892 struct fc_els_scr *scr; 893 894 scr = fc_frame_payload_get(fp, sizeof(*scr)); 895 memset(scr, 0, sizeof(*scr)); 896 scr->scr_cmd = ELS_SCR; 897 scr->scr_reg_func = ELS_SCRF_FULL; 898 } 899 900 /** 901 * fc_els_fill - Fill in an ELS request frame 902 */ 903 static inline int fc_els_fill(struct fc_lport *lport, 904 u32 did, 905 struct fc_frame *fp, unsigned int op, 906 enum fc_rctl *r_ctl, enum fc_fh_type *fh_type) 907 { 908 switch (op) { 909 case ELS_ADISC: 910 fc_adisc_fill(lport, fp); 911 break; 912 913 case ELS_PLOGI: 914 fc_plogi_fill(lport, fp, ELS_PLOGI); 915 break; 916 917 case ELS_FLOGI: 918 fc_flogi_fill(lport, fp); 919 break; 920 921 case ELS_FDISC: 922 fc_fdisc_fill(lport, fp); 923 break; 924 925 case ELS_LOGO: 926 fc_logo_fill(lport, fp); 927 break; 928 929 case ELS_RTV: 930 fc_rtv_fill(lport, fp); 931 break; 932 933 case ELS_REC: 934 fc_rec_fill(lport, fp); 935 break; 936 937 case ELS_PRLI: 938 fc_prli_fill(lport, fp); 939 break; 940 941 case ELS_SCR: 942 fc_scr_fill(lport, fp); 943 break; 944 945 default: 946 return -EINVAL; 947 } 948 949 *r_ctl = FC_RCTL_ELS_REQ; 950 *fh_type = FC_TYPE_ELS; 951 return 0; 952 } 953 #endif /* _FC_ENCODE_H_ */ 954