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 _FCOEI_H 26 #define _FCOEI_H 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #ifdef _KERNEL 33 34 /* 35 * FCOEI logging 36 */ 37 extern int fcoei_use_ext_log; 38 extern void *fcoei_state; 39 40 #define FCOEI_EXT_LOG(log_ident, ...) \ 41 { \ 42 if (fcoei_use_ext_log) { \ 43 fcoe_trace(log_ident, __VA_ARGS__); \ 44 } \ 45 } 46 47 #define FCOEI_LOG(log_ident, ...) \ 48 fcoe_trace(log_ident, __VA_ARGS__) 49 50 /* 51 * IOCTL supporting stuff 52 */ 53 #define FCOEI_IOCTL_FLAG_MASK 0xFF 54 #define FCOEI_IOCTL_FLAG_IDLE 0x00 55 #define FCOEI_IOCTL_FLAG_OPEN 0x01 56 #define FCOEI_IOCTL_FLAG_EXCL 0x02 57 58 /* 59 * define common constants 60 */ 61 #define FCOEI_MAX_OPEN_XCHS 2048 62 #define FCOEI_SOL_HASH_SIZE 2048 63 #define FCOEI_UNSOL_HASH_SIZE 128 64 #define FCOEI_VERSION "20090729-1.00" 65 #define FCOEI_NAME_VERSION "SunFC FCoEI v" FCOEI_VERSION 66 67 /* 68 * define RNID Management Info 69 */ 70 #define FCOEI_RNID_HBA 0x7 71 #define FCOEI_RNID_IPV4 0x1 72 #define FCOEI_RNID_IPV6 0x2 73 74 typedef enum event_type { 75 AE_EVENT_NONE = 0, 76 AE_EVENT_EXCHANGE, 77 AE_EVENT_SOL_FRAME, 78 AE_EVENT_UNSOL_FRAME, 79 AE_EVENT_PORT, 80 AE_EVENT_ABORT, 81 AE_EVENT_RESET, 82 } event_type_e; 83 84 typedef struct fcoei_event { 85 list_node_t ae_node; 86 event_type_e ae_type; 87 88 /* 89 * event specific 90 */ 91 uint64_t ae_specific; 92 93 /* 94 * event related object 95 */ 96 void *ae_obj; 97 } fcoei_event_t; 98 99 typedef struct fcoei_soft_state { 100 dev_info_t *ss_dip; 101 uint32_t ss_flags; 102 uint32_t ss_fcp_data_payload_size; 103 list_t ss_comp_xch_list; 104 105 /* 106 * common data structure (fc_local_port_t) between leadville and fcoei 107 */ 108 void *ss_port; 109 110 /* 111 * common data structure between fcoei and fcoe module 112 */ 113 fcoe_port_t *ss_eport; 114 115 mod_hash_t *ss_sol_oxid_hash; 116 mod_hash_t *ss_unsol_rxid_hash; 117 uint16_t ss_next_sol_oxid; 118 uint16_t ss_next_unsol_rxid; 119 120 /* 121 * We will use ss_taskq to dispatch watchdog and other tasks 122 */ 123 ddi_taskq_t *ss_taskq; 124 125 kcondvar_t ss_watchdog_cv; 126 kmutex_t ss_watchdog_mutex; 127 128 /* 129 * current port state, speed. see fctl.h 130 */ 131 uint16_t ss_link_state; 132 uint16_t ss_link_speed; 133 134 /* 135 * # of unprocessed port/link change 136 */ 137 uint32_t ss_port_event_counter; 138 list_t ss_event_list; 139 140 /* 141 * solicited and unsolicited exchanges timing checking 142 */ 143 uint32_t ss_sol_cnt1; 144 uint32_t ss_sol_cnt2; 145 uint32_t *ss_sol_cnt; 146 uint32_t ss_unsol_cnt1; 147 uint32_t ss_unsol_cnt2; 148 uint32_t *ss_unsol_cnt; 149 150 /* 151 * ioctl related stuff 152 */ 153 uint32_t ss_ioctl_flags; 154 kmutex_t ss_ioctl_mutex; 155 156 /* 157 * fp-defined routines that fcoei will call 158 */ 159 fc_fca_bind_info_t ss_bind_info; 160 161 /* 162 * fcoei-defined plogi response that fp will use 163 */ 164 la_els_logi_t ss_els_logi; 165 166 /* 167 * fcoei-defined routines that fp will call 168 */ 169 fc_fca_tran_t ss_fca_tran; 170 171 /* 172 * Direct p2p information, and ss's fcid will be stored here 173 */ 174 fc_fca_p2p_info_t ss_p2p_info; 175 176 /* 177 * RNID Management Information 178 */ 179 fc_rnid_t ss_rnid; 180 } fcoei_soft_state_t; 181 182 #define SS_FLAG_LV_NONE 0x0000 183 #define SS_FLAG_LV_BOUND 0x0001 184 #define SS_FLAG_PORT_DISABLED 0x0002 185 #define SS_FLAG_TERMINATE_WATCHDOG 0x0004 186 #define SS_FLAG_WATCHDOG_RUNNING 0x0008 187 #define SS_FLAG_WATCHDOG_IDLE 0x0010 188 #define SS_FLAG_TRIGGER_FP_ATTACH 0x0020 189 #define SS_FLAG_FLOGI_FAILED 0x0040 190 191 /* 192 * fcoei_frame - corresponding data structure to fcoe_frame/fc_frame 193 */ 194 typedef struct fcoei_frame { 195 fcoei_event_t ifm_ae; 196 fcoe_frame_t *ifm_frm; 197 uint32_t ifm_flags; 198 struct fcoei_exchange *ifm_xch; 199 200 /* 201 * will be used after the relevant frame mblk was released by ETH layer 202 */ 203 uint8_t ifm_rctl; 204 } fcoei_frame_t; 205 206 #define IFM_FLAG_NONE 0x0000 207 #define IFM_FLAG_FREE_NETB 0x0001 208 209 /* 210 * fcoei_exchange - corresponding data structure to leadville fc_packet 211 */ 212 typedef struct fcoei_exchange { 213 list_node_t xch_comp_node; 214 fcoei_event_t xch_ae; 215 uint32_t xch_flags; 216 fcoei_soft_state_t *xch_ss; 217 clock_t xch_start_tick; 218 clock_t xch_end_tick; 219 int xch_resid; 220 ksema_t xch_sema; 221 222 /* 223 * current cnt for timing check, when the exchange is created 224 */ 225 uint32_t *xch_cnt; 226 227 /* 228 * leadville fc_packet will not maintain oxid/rxid, 229 * so fcoei exchange need do it 230 */ 231 uint16_t xch_oxid; 232 uint16_t xch_rxid; 233 234 /* 235 * to link leadville's stuff 236 */ 237 fc_packet_t *xch_fpkt; 238 fc_unsol_buf_t *xch_ub; 239 } fcoei_exchange_t; 240 241 #define XCH_FLAG_NONE 0x00000000 242 #define XCH_FLAG_TMOUT 0x00000001 243 #define XCH_FLAG_ABORT 0x00000002 244 #define XCH_FLAG_IN_SOL_HASH 0x00000004 245 #define XCH_FLAG_IN_UNSOL_HASH 0x00000008 246 247 typedef struct fcoei_walk_arg 248 { 249 fcoei_exchange_t *wa_xch; 250 uint16_t wa_oxid; 251 } fcoei_walk_arg_t; 252 253 /* 254 * Define conversion and calculation macros 255 */ 256 #define FRM2IFM(x_frm) ((fcoei_frame_t *)(x_frm)->frm_client_private) 257 #define FRM2SS(x_frm) \ 258 ((fcoei_soft_state_t *)(x_frm)->frm_eport->eport_client_private) 259 260 #define PORT2SS(x_port) ((fcoei_soft_state_t *)(x_port)->port_fca_private) 261 #define EPORT2SS(x_eport) \ 262 ((fcoei_soft_state_t *)(x_eport)->eport_client_private) 263 264 #define FPKT2XCH(x_fpkt) ((fcoei_exchange_t *)x_fpkt->pkt_fca_private) 265 #define FRM2FPKT(x_fpkt) (FRM2IFM(frm)->ifm_xch->xch_fpkt) 266 267 #define HANDLE2SS(x_handle) ((fcoei_soft_state_t *)fca_handle) 268 269 #define FPLD frm->frm_payload 270 271 #define FCOEI_FRM2FHDR(x_frm, x_fhdr) \ 272 { \ 273 (x_fhdr)->r_ctl = FRM_R_CTL(x_frm); \ 274 (x_fhdr)->d_id = FRM_D_ID(x_frm); \ 275 (x_fhdr)->s_id = FRM_S_ID(x_frm); \ 276 (x_fhdr)->type = FRM_TYPE(x_frm); \ 277 (x_fhdr)->f_ctl = FRM_F_CTL(x_frm); \ 278 (x_fhdr)->seq_id = FRM_SEQ_ID(x_frm); \ 279 (x_fhdr)->df_ctl = FRM_DF_CTL(x_frm); \ 280 (x_fhdr)->seq_cnt = FRM_SEQ_CNT(x_frm); \ 281 (x_fhdr)->ox_id = FRM_OXID(x_frm); \ 282 (x_fhdr)->rx_id = FRM_RXID(x_frm); \ 283 (x_fhdr)->ro = FRM_PARAM(x_frm); \ 284 } 285 286 #define FCOEI_PARTIAL_FHDR2FRM(x_fhdr, x_frm) \ 287 { \ 288 FFM_R_CTL((x_fhdr)->r_ctl, x_frm); \ 289 FFM_D_ID((x_fhdr)->d_id, x_frm); \ 290 FFM_S_ID((x_fhdr)->s_id, x_frm); \ 291 FFM_TYPE((x_fhdr)->type, x_frm); \ 292 FFM_F_CTL((x_fhdr)->f_ctl, x_frm); \ 293 } 294 295 #define PRT_FRM_HDR(x_p, x_f) \ 296 { \ 297 FCOEI_LOG(x_p, "rctl/%x, fctl/%x, type/%x, oxid/%x", \ 298 FCOE_B2V_1((x_f)->frm_hdr->hdr_r_ctl), \ 299 FCOE_B2V_3((x_f)->frm_hdr->hdr_f_ctl), \ 300 FCOE_B2V_1((x_f)->frm_hdr->hdr_type), \ 301 FCOE_B2V_2((x_f)->frm_hdr->hdr_oxid)); \ 302 } 303 304 #define FCOEI_INIT_SOL_ID_HASH(xch, xch_tmp) \ 305 { \ 306 do { \ 307 if (++xch->xch_ss->ss_next_sol_oxid == 0xFFFF) { \ 308 ++xch->xch_ss->ss_next_sol_oxid; \ 309 } \ 310 } while (mod_hash_find(xch->xch_ss->ss_sol_oxid_hash, \ 311 (mod_hash_key_t)(intptr_t)xch->xch_ss->ss_next_sol_oxid, \ 312 (mod_hash_val_t)&xch_tmp) == 0); \ 313 xch->xch_oxid = xch->xch_ss->ss_next_sol_oxid; \ 314 xch->xch_rxid = 0xFFFF; \ 315 (void) mod_hash_insert(xch->xch_ss->ss_sol_oxid_hash, \ 316 FMHK(xch->xch_oxid), (mod_hash_val_t)xch); \ 317 xch->xch_flags |= XCH_FLAG_IN_SOL_HASH; \ 318 } 319 320 #define FCOEI_SET_UNSOL_FRM_RXID(frm, xch_tmp) \ 321 { \ 322 do { \ 323 if (++FRM2SS(frm)->ss_next_unsol_rxid == 0xFFFF) { \ 324 ++FRM2SS(frm)->ss_next_unsol_rxid; \ 325 } \ 326 } while (mod_hash_find(FRM2SS(frm)->ss_unsol_rxid_hash, \ 327 (mod_hash_key_t)(intptr_t)FRM2SS(frm)->ss_next_unsol_rxid, \ 328 (mod_hash_val_t)&xch_tmp) == 0); \ 329 FFM_RXID(FRM2SS(frm)->ss_next_unsol_rxid, frm); \ 330 } 331 332 #define FCOEI_INIT_UNSOL_ID_HASH(xch) \ 333 { \ 334 xch->xch_oxid = fpkt->pkt_cmd_fhdr.ox_id; \ 335 xch->xch_rxid = fpkt->pkt_cmd_fhdr.rx_id; \ 336 (void) mod_hash_insert(xch->xch_ss->ss_unsol_rxid_hash, \ 337 FMHK(xch->xch_rxid), (mod_hash_val_t)xch); \ 338 xch->xch_flags |= XCH_FLAG_IN_UNSOL_HASH; \ 339 } 340 341 /* 342 * Common functions defined in fcoei.c 343 */ 344 void fcoei_complete_xch(fcoei_exchange_t *xch, fcoe_frame_t *frm, 345 uint8_t pkt_state, uint8_t pkt_reason); 346 void fcoei_init_ifm(fcoe_frame_t *frm, fcoei_exchange_t *xch); 347 void fcoei_handle_comp_xch_list(fcoei_soft_state_t *ss); 348 349 /* 350 * Common functions defined in fcoei_lv.c 351 */ 352 void fcoei_init_fcatran_vectors(fc_fca_tran_t *fcatran); 353 void fcoei_process_event_exchange(fcoei_event_t *ae); 354 void fcoei_process_event_reset(fcoei_event_t *ae); 355 356 /* 357 * Common functions defined in fcoei_eth.c 358 */ 359 void fcoei_init_ect_vectors(fcoe_client_t *ect); 360 void fcoei_process_unsol_frame(fcoe_frame_t *frm); 361 void fcoei_handle_sol_frame_done(fcoe_frame_t *frm); 362 void fcoei_process_event_port(fcoei_event_t *ae); 363 void fcoei_port_event(fcoe_port_t *eport, uint32_t event); 364 365 #endif /* _KERNEL */ 366 367 #ifdef __cplusplus 368 } 369 #endif 370 371 #endif /* _FCOEI_H */ 372