1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 #ifndef _FCOE_COMMON_H_ 26 #define _FCOE_COMMON_H_ 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #ifdef _KERNEL 33 34 /* 35 * Interface return value 36 */ 37 #define FCOE_SUCCESS 0 38 #define FCOE_FAILURE -1 39 #define FCOE_BUSY -2 40 #define FCOE_NOT_SUPPORTED -3 41 #define FCOE_BAD_FRAME -4 42 43 /* 44 * FCOE port speed 45 */ 46 #define FCOE_PORT_SPEED_1G 1000000000 47 #define FCOE_PORT_SPEED_10G 10000000000 48 49 /* 50 * FC Frame header size: 24 bytes 51 */ 52 #define FCFH_SIZE (sizeof (fcoe_fc_frame_header_t)) 53 54 /* 55 * FLOGI 56 */ 57 #define FLOGI_REQ_PAYLOAD_SIZE 116 58 #define FLOGI_ACC_PAYLOAD_SIZE 116 59 60 #define FCOE_MIN_MTU_SIZE 2500 61 #define FCOE_MAX_FC_FRAME_SIZE 2136 62 63 /* 64 * 24 byte FC frame header 65 * For all data structures that have endian problems, we will use only 66 * one type: uint8_t. We need associate the data structure pointer with 67 * one buffer directly. 68 */ 69 typedef struct fcoe_fc_frame_header { 70 uint8_t hdr_r_ctl[1]; 71 uint8_t hdr_d_id[3]; 72 73 uint8_t hdr_cs_ctl[1]; 74 uint8_t hdr_s_id[3]; 75 76 uint8_t hdr_type[1]; 77 uint8_t hdr_f_ctl[3]; 78 79 uint8_t hdr_seq_id[1]; 80 uint8_t hdr_df_ctl[1]; 81 uint8_t hdr_seq_cnt[2]; 82 83 uint8_t hdr_oxid[2]; 84 uint8_t hdr_rxid[2]; 85 86 uint8_t hdr_param[4]; 87 } fcoe_fc_frame_header_t; 88 89 /* 90 * Solicited frame: allocted by FCOET/FOCEI, free-ed by FCOE 91 * Unsolicited frame: allocated by FCOE, free-ed by FCOET/FCOEI 92 */ 93 struct fcoe_port; 94 typedef struct fcoe_frame { 95 uint32_t frm_flags; 96 void *frm_netb; 97 98 /* 99 * frm_hdr will be cleared by fcoe explicitly 100 */ 101 fcoe_fc_frame_header_t *frm_hdr; 102 uint8_t *frm_ofh1; 103 uint8_t *frm_ofh2; 104 uint8_t *frm_fc_frame; 105 106 /* 107 * fcoe client need clear FC payload explicitly, 108 * except for RD/WR data frames 109 */ 110 uint8_t *frm_payload; 111 uint32_t frm_fc_frame_size; 112 uint32_t frm_payload_size; 113 uint32_t frm_alloc_size; 114 struct fcoe_port *frm_eport; 115 void *frm_fcoe_private; 116 void *frm_client_private; 117 clock_t frm_clock; 118 } fcoe_frame_t; 119 120 /* 121 * FCOE HBA 122 */ 123 typedef struct fcoe_port { 124 uint32_t eport_flags; 125 void *eport_fcoe_private; 126 void *eport_client_private; 127 uint8_t eport_portwwn[8]; 128 uint8_t eport_nodewwn[8]; 129 uint32_t eport_max_fc_frame_size; 130 uint32_t eport_mtu; 131 uint64_t eport_link_speed; 132 uint8_t eport_efh_dst[ETHERADDRL]; 133 134 void (*eport_tx_frame)(fcoe_frame_t *frame); 135 fcoe_frame_t *(*eport_alloc_frame)(struct fcoe_port *eport, 136 uint32_t this_fc_frame_size, void *netb); 137 void (*eport_release_frame)(fcoe_frame_t *frame); 138 void *(*eport_alloc_netb)(struct fcoe_port *eport, 139 uint32_t this_fc_frame_size, uint8_t **ppfc); 140 void (*eport_free_netb)(void *netb); 141 void (*eport_deregister_client)(struct fcoe_port *eport); 142 int (*eport_ctl)(struct fcoe_port *eport, 143 int cmd, void *arg); 144 int (*eport_set_mac_address)(struct fcoe_port *eport, 145 uint8_t *addr, boolean_t fc_assigned); 146 } fcoe_port_t; 147 148 /* 149 * FCOE only supports two kinds of topology: direct P2P, fabric P2P. 150 */ 151 #define EPORT_FLAG_IS_DIRECT_P2P 0x01 152 #define EPORT_FLAG_TGT_MODE 0x02 153 #define EPORT_FLAG_INI_MODE 0x04 154 #define EPORT_FLAG_MAC_IN_USE 0x08 155 156 #define FCOE_NOTIFY_EPORT_LINK_UP 0x01 157 #define FCOE_NOTIFY_EPORT_LINK_DOWN 0x02 158 #define FCOE_NOTIFY_EPORT_ADDR_CHG 0x03 159 160 #define FCOE_PORT_CTL_CMDS 0x3000 161 #define FCOE_CMD_PORT_ONLINE (FCOE_PORT_CTL_CMDS | 0x01) 162 #define FCOE_CMD_PORT_OFFLINE (FCOE_PORT_CTL_CMDS | 0x02) 163 164 /* 165 * FCoE version control 166 */ 167 typedef enum fcoe_ver 168 { 169 FCOE_VER_1 = 0xAA01, 170 FCOE_VER_2, 171 FCOE_VER_3, 172 FCOE_VER_4, 173 FCOE_VER_5 174 } fcoe_ver_e; 175 176 #define FCOE_VER_NOW FCOE_VER_1 177 extern const fcoe_ver_e fcoe_ver_now; 178 179 typedef struct fcoe_client { 180 fcoe_ver_e ect_fcoe_ver; 181 uint32_t ect_eport_flags; 182 uint32_t ect_max_fc_frame_size; 183 uint32_t ect_private_frame_struct_size; 184 uint32_t ect_channelid; 185 void *ect_client_port_struct; 186 void (*ect_rx_frame)(fcoe_frame_t *frame); 187 void (*ect_port_event)(fcoe_port_t *eport, uint32_t event); 188 void (*ect_release_sol_frame)(fcoe_frame_t *frame); 189 } fcoe_client_t; 190 191 /* 192 * Define common-used conversion or calculation macros 193 */ 194 #define FCOE_V2B_1(x_v, x_b) \ 195 { \ 196 ((uint8_t *)(x_b))[0] = 0xFF & (x_v); \ 197 } 198 199 #define FCOE_V2B_2(x_v, x_b) \ 200 { \ 201 ((uint8_t *)(x_b))[1] = 0xFF & (x_v); \ 202 ((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 8); \ 203 } 204 205 #define FCOE_V2B_3(x_v, x_b) \ 206 { \ 207 ((uint8_t *)(x_b))[2] = 0xFF & (x_v); \ 208 ((uint8_t *)(x_b))[1] = 0xFF & ((x_v) >> 8); \ 209 ((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 16); \ 210 } 211 212 #define FCOE_V2B_4(x_v, x_b) \ 213 { \ 214 ((uint8_t *)(x_b))[3] = 0xFF & (x_v); \ 215 ((uint8_t *)(x_b))[2] = 0xFF & ((x_v) >> 8); \ 216 ((uint8_t *)(x_b))[1] = 0xFF & ((x_v) >> 16); \ 217 ((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 24); \ 218 } 219 220 #define FCOE_V2B_8(x_v, x_b) \ 221 { \ 222 ((uint8_t *)(x_b))[7] = 0xFF & (x_v); \ 223 ((uint8_t *)(x_b))[6] = 0xFF & ((x_v) >> 8); \ 224 ((uint8_t *)(x_b))[5] = 0xFF & ((x_v) >> 16); \ 225 ((uint8_t *)(x_b))[4] = 0xFF & ((x_v) >> 24); \ 226 ((uint8_t *)(x_b))[3] = 0xFF & ((x_v) >> 32); \ 227 ((uint8_t *)(x_b))[2] = 0xFF & ((x_v) >> 40); \ 228 ((uint8_t *)(x_b))[1] = 0xFF & ((x_v) >> 48); \ 229 ((uint8_t *)(x_b))[0] = 0xFF & ((x_v) >> 56); \ 230 } 231 232 #define FCOE_B2V_1(x_b) \ 233 ((((uint8_t *)(x_b))[0]) & 0xFF) 234 235 #define FCOE_B2V_2(x_b) \ 236 ((((uint8_t *)(x_b))[1] | ((uint8_t *)(x_b))[0] << 8) & 0xFFFF) 237 238 #define FCOE_B2V_3(x_b) \ 239 ((((uint8_t *)(x_b))[2] | ((uint8_t *)(x_b))[1] << 8 | \ 240 ((uint8_t *)(x_b))[0] << 16) & 0xFFFFFF) 241 242 #define FCOE_B2V_4(x_b) \ 243 ((((uint8_t *)(x_b))[3] | ((uint8_t *)(x_b))[2] << 8 | \ 244 ((uint8_t *)(x_b))[1] << 16 | \ 245 ((uint8_t *)(x_b))[0] << 24) & 0xFFFFFFFF) 246 247 #define FCOE_B2V_8(x_b) \ 248 ((((uint8_t *)(x_b))[7] | ((uint8_t *)(x_b))[6] << 8 | \ 249 ((uint8_t *)(x_b))[5] << 16 | \ 250 ((uint8_t *)(x_b))[4] << 24 | \ 251 ((uint8_t *)(x_b))[3] << 32 | \ 252 ((uint8_t *)(x_b))[2] << 40 | \ 253 ((uint8_t *)(x_b))[1] << 48 | \ 254 ((uint8_t *)(x_b))[0] << 56) & 0xFFFFFFFFFFFFFFFF) 255 256 /* 257 * Get FC frame header's element 258 */ 259 #define FRM_R_CTL(x_frm) (FCOE_B2V_1((x_frm)->frm_hdr->hdr_r_ctl)) 260 #define FRM_D_ID(x_frm) (FCOE_B2V_3((x_frm)->frm_hdr->hdr_d_id)) 261 #define FRM_S_ID(x_frm) (FCOE_B2V_3((x_frm)->frm_hdr->hdr_s_id)) 262 #define FRM_TYPE(x_frm) (FCOE_B2V_1((x_frm)->frm_hdr->hdr_type)) 263 #define FRM_F_CTL(x_frm) (FCOE_B2V_3((x_frm)->frm_hdr->hdr_f_ctl)) 264 #define FRM_SEQ_ID(x_frm) (FCOE_B2V_1((x_frm)->frm_hdr->hdr_seq_id)) 265 #define FRM_DF_CTL(x_frm) (FCOE_B2V_1((x_frm)->frm_hdr->hdr_df_ctl)) 266 #define FRM_SEQ_CNT(x_frm) (FCOE_B2V_2((x_frm)->frm_hdr->hdr_seq_cnt)) 267 #define FRM_OXID(x_frm) (FCOE_B2V_2((x_frm)->frm_hdr->hdr_oxid)) 268 #define FRM_RXID(x_frm) (FCOE_B2V_2((x_frm)->frm_hdr->hdr_rxid)) 269 #define FRM_PARAM(x_frm) (FCOE_B2V_4((x_frm)->frm_hdr->hdr_param)) 270 271 /* 272 * Set FC frame header's element 273 */ 274 #define FFM_R_CTL(x_v, x_frm) FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_r_ctl) 275 #define FFM_D_ID(x_v, x_frm) FCOE_V2B_3((x_v), (x_frm)->frm_hdr->hdr_d_id) 276 #define FFM_S_ID(x_v, x_frm) FCOE_V2B_3((x_v), (x_frm)->frm_hdr->hdr_s_id) 277 #define FFM_TYPE(x_v, x_frm) FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_type) 278 #define FFM_F_CTL(x_v, x_frm) FCOE_V2B_3((x_v), (x_frm)->frm_hdr->hdr_f_ctl) 279 #define FFM_SEQ_ID(x_v, x_frm) FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_seq_id) 280 #define FFM_DF_CTL(x_v, x_frm) FCOE_V2B_1((x_v), (x_frm)->frm_hdr->hdr_df_ctl) 281 #define FFM_SEQ_CNT(x_v, x_frm) FCOE_V2B_2((x_v), (x_frm)->frm_hdr->hdr_seq_cnt) 282 #define FFM_OXID(x_v, x_frm) FCOE_V2B_2((x_v), (x_frm)->frm_hdr->hdr_oxid) 283 #define FFM_RXID(x_v, x_frm) FCOE_V2B_2((x_v), (x_frm)->frm_hdr->hdr_rxid) 284 #define FFM_PARAM(x_v, x_frm) FCOE_V2B_4((x_v), (x_frm)->frm_hdr->hdr_param) 285 286 /* 287 * frame header checking 288 */ 289 #define FRM_IS_LAST_FRAME(x_frm) (FRM_F_CTL(x_frm) & (1 << 19)) 290 #define FRM_SENDER_IS_XCH_RESPONDER(x_frm) (FRM_F_CTL(x_frm) & (1 << 23)) 291 292 /* 293 * FCOET/FCOEI will only call this fcoe function explicitly, all others 294 * should be called through vectors in struct fcoe_port. 295 * FCOE client call this to register one port to FCOE, FCOE need initialize 296 * and return the corresponding fcoe_port. 297 */ 298 extern fcoe_port_t *fcoe_register_client(fcoe_client_t *client); 299 300 #define EPORT_CLT_TYPE(eport) \ 301 (((eport)->eport_flags & EPORT_FLAG_INI_MODE) ? \ 302 FCOE_CLIENT_INITIATOR : FCOE_CLIENT_TARGET) 303 304 #define FCOE_SET_DEFAULT_OUI(x_oui) \ 305 (x_oui)[0] = 0x0e; (x_oui)[1] = 0xfc; (x_oui)[2] = 0x00; 306 #define FCOE_SET_DEFAULT_FPORT_ADDR(x_addr) \ 307 FCOE_SET_DEFAULT_OUI(x_addr) \ 308 (x_addr)[3] = 0xff; (x_addr)[4] = 0xff; (x_addr)[5] = 0xfe; 309 310 /* 311 * FC payload size 312 */ 313 #define FCOE_DEFAULT_FCP_DATA_PAYLOAD_SIZE 2048 314 #define FCOE_MIN_FCP_DATA_PAYLOAD_SIZE 1024 315 316 typedef struct fcoe_fcp_cmnd { 317 uint8_t ffc_lun[8]; 318 uint8_t ffc_ref_num[1]; 319 320 /* 321 * least 3 bits 322 */ 323 uint8_t ffc_attribute[1]; 324 325 /* 326 * Magnagement flags 327 */ 328 uint8_t ffc_management_flags[1]; 329 330 /* 331 * additional cdb len and read/write flag 332 */ 333 uint8_t ffc_addlen_rdwr[1]; 334 335 uint8_t ffc_cdb[16]; 336 uint8_t ffc_fcp_dl[4]; 337 } fcoe_fcp_cmnd_t; 338 339 typedef struct fcoe_fcp_rsp { 340 uint8_t ffr_rsvd[8]; 341 342 /* 343 * see SAM-4 344 */ 345 uint8_t ffr_retry_delay_timer[2]; 346 uint8_t ffr_flags[1]; 347 uint8_t ffr_scsi_status[1]; 348 uint8_t ffr_resid[4]; 349 uint8_t ffr_sns_len[4]; 350 uint8_t ffr_rsp_len[4]; 351 /* 352 * Followed by sense data when available 353 */ 354 } fcoe_fcp_rsp_t; 355 356 typedef struct fcoe_fcp_xfer_rdy { 357 uint8_t fxr_data_ro[4]; 358 uint8_t fxr_burst_len[4]; 359 uint8_t fxr_rsvd[4]; 360 } fcoe_fcp_xfer_rdy_t; 361 362 /* 363 * FCOE project global functions 364 */ 365 #if !defined(__FUNCTION__) 366 #define __FUNCTION__ ((caddr_t)__func__) 367 #endif 368 369 #define FCOE_STR_LEN 32 370 371 /* 372 * timestamp (golbal variable in sys/systm.h) 373 */ 374 #define CURRENT_CLOCK (ddi_get_lbolt()) 375 #define FCOE_SEC2TICK(x_sec) (drv_usectohz((x_sec) * 1000000)) 376 377 /* 378 * Form/convert mod_hash_key from/to xch ID 379 */ 380 #define FMHK(x_xid) (mod_hash_key_t)(uintptr_t)(x_xid) 381 #define CMHK(x_key) (uint16_t)(uintptr_t)(x_key) 382 383 typedef void (*TQ_FUNC_P)(void *); 384 extern void fcoe_trace(caddr_t ident, const char *fmt, ...); 385 386 #endif 387 388 #ifdef __cplusplus 389 } 390 #endif 391 392 #endif /* _FCOE_COMMON_H_ */ 393