19087SZhong.Wang@Sun.COM /* 29087SZhong.Wang@Sun.COM * CDDL HEADER START 39087SZhong.Wang@Sun.COM * 49087SZhong.Wang@Sun.COM * The contents of this file are subject to the terms of the 59087SZhong.Wang@Sun.COM * Common Development and Distribution License (the "License"). 69087SZhong.Wang@Sun.COM * You may not use this file except in compliance with the License. 79087SZhong.Wang@Sun.COM * 89087SZhong.Wang@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 99087SZhong.Wang@Sun.COM * or http://www.opensolaris.org/os/licensing. 109087SZhong.Wang@Sun.COM * See the License for the specific language governing permissions 119087SZhong.Wang@Sun.COM * and limitations under the License. 129087SZhong.Wang@Sun.COM * 139087SZhong.Wang@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 149087SZhong.Wang@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 159087SZhong.Wang@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 169087SZhong.Wang@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 179087SZhong.Wang@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 189087SZhong.Wang@Sun.COM * 199087SZhong.Wang@Sun.COM * CDDL HEADER END 209087SZhong.Wang@Sun.COM */ 219087SZhong.Wang@Sun.COM /* 22*12571SViswanathan.Kannappan@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 239087SZhong.Wang@Sun.COM */ 249087SZhong.Wang@Sun.COM #ifndef _FCOET_H 259087SZhong.Wang@Sun.COM #define _FCOET_H 269087SZhong.Wang@Sun.COM 279087SZhong.Wang@Sun.COM #include <sys/stmf_defines.h> 289087SZhong.Wang@Sun.COM 299087SZhong.Wang@Sun.COM #ifdef __cplusplus 309087SZhong.Wang@Sun.COM extern "C" { 319087SZhong.Wang@Sun.COM #endif 329087SZhong.Wang@Sun.COM 339087SZhong.Wang@Sun.COM #ifdef _KERNEL 349087SZhong.Wang@Sun.COM 3511231SKevin.Yu@Sun.COM #define FCOET_VERSION "v20091123-1.02" 369087SZhong.Wang@Sun.COM #define FCOET_NAME "COMSTAR FCoET " 379087SZhong.Wang@Sun.COM #define FCOET_MOD_NAME FCOET_NAME FCOET_VERSION 389087SZhong.Wang@Sun.COM 39*12571SViswanathan.Kannappan@Sun.COM #define FCOET_TASKQ_NAME_LEN 32 40*12571SViswanathan.Kannappan@Sun.COM 419087SZhong.Wang@Sun.COM /* 429087SZhong.Wang@Sun.COM * FCOET logging 439087SZhong.Wang@Sun.COM */ 449087SZhong.Wang@Sun.COM extern int fcoet_use_ext_log; 459087SZhong.Wang@Sun.COM 469087SZhong.Wang@Sun.COM /* 479087SZhong.Wang@Sun.COM * Caution: 1) LOG will be available in debug/non-debug mode 489087SZhong.Wang@Sun.COM * 2) Anything which can potentially flood the log should be under 499087SZhong.Wang@Sun.COM * extended logging, and use FCOET_EXT_LOG. 509087SZhong.Wang@Sun.COM * 3) Don't use FCOET_EXT_LOG in performance-critical code path, such 519087SZhong.Wang@Sun.COM * as normal SCSI I/O code path. It could hurt system performance. 529087SZhong.Wang@Sun.COM * 4) Use kmdb to change focet_use_ext_log in the fly to adjust 539087SZhong.Wang@Sun.COM * tracing 549087SZhong.Wang@Sun.COM */ 559087SZhong.Wang@Sun.COM #define FCOET_EXT_LOG(log_ident, ...) \ 569087SZhong.Wang@Sun.COM { \ 579087SZhong.Wang@Sun.COM if (fcoet_use_ext_log) { \ 589087SZhong.Wang@Sun.COM fcoe_trace(log_ident, __VA_ARGS__); \ 599087SZhong.Wang@Sun.COM } \ 609087SZhong.Wang@Sun.COM } 619087SZhong.Wang@Sun.COM 629087SZhong.Wang@Sun.COM #define FCOET_LOG(log_ident, ...) \ 639087SZhong.Wang@Sun.COM fcoe_trace(log_ident, __VA_ARGS__) 649087SZhong.Wang@Sun.COM 659087SZhong.Wang@Sun.COM /* 669087SZhong.Wang@Sun.COM * define common-used constants 679087SZhong.Wang@Sun.COM */ 689087SZhong.Wang@Sun.COM #define FCOET_MAX_LOGINS 2048 699087SZhong.Wang@Sun.COM #define FCOET_MAX_XCHGES 2048 709087SZhong.Wang@Sun.COM #define FCOET_SOL_HASH_SIZE 128 719087SZhong.Wang@Sun.COM #define FCOET_UNSOL_HASH_SIZE 2048 729087SZhong.Wang@Sun.COM 739087SZhong.Wang@Sun.COM typedef enum fcoet_sol_flogi_state { 749087SZhong.Wang@Sun.COM SFS_WAIT_LINKUP = 0, 759087SZhong.Wang@Sun.COM SFS_FLOGI_INIT, 769087SZhong.Wang@Sun.COM SFS_FLOGI_CHECK_TIMEOUT, 779087SZhong.Wang@Sun.COM SFS_ABTS_INIT, 789087SZhong.Wang@Sun.COM SFS_CLEAR_FLOGI, 799087SZhong.Wang@Sun.COM SFS_FLOGI_ACC, 809087SZhong.Wang@Sun.COM SFS_FLOGI_DONE 819087SZhong.Wang@Sun.COM } fcoet_sol_flogi_state_t; 829087SZhong.Wang@Sun.COM 839087SZhong.Wang@Sun.COM /* 849087SZhong.Wang@Sun.COM * define data structures 859087SZhong.Wang@Sun.COM */ 869087SZhong.Wang@Sun.COM struct fcoet_exchange; 879087SZhong.Wang@Sun.COM typedef struct fcoet_soft_state { 889087SZhong.Wang@Sun.COM /* 899087SZhong.Wang@Sun.COM * basic information 909087SZhong.Wang@Sun.COM */ 919087SZhong.Wang@Sun.COM dev_info_t *ss_dip; 929087SZhong.Wang@Sun.COM int ss_instance; 939087SZhong.Wang@Sun.COM uint32_t ss_flags; 949087SZhong.Wang@Sun.COM fct_local_port_t *ss_port; 959087SZhong.Wang@Sun.COM fcoe_port_t *ss_eport; 969087SZhong.Wang@Sun.COM char ss_alias[32]; 979087SZhong.Wang@Sun.COM uint32_t ss_fcp_data_payload_size; 989087SZhong.Wang@Sun.COM 999087SZhong.Wang@Sun.COM /* 1009087SZhong.Wang@Sun.COM * support degregister remote port 1019087SZhong.Wang@Sun.COM */ 1029087SZhong.Wang@Sun.COM uint32_t ss_rportid_in_dereg; 1039087SZhong.Wang@Sun.COM uint32_t ss_rport_dereg_state; 1049087SZhong.Wang@Sun.COM 1059087SZhong.Wang@Sun.COM /* 1069087SZhong.Wang@Sun.COM * oxid/rxid 1079087SZhong.Wang@Sun.COM */ 1089087SZhong.Wang@Sun.COM mod_hash_t *ss_sol_oxid_hash; 1099087SZhong.Wang@Sun.COM mod_hash_t *ss_unsol_rxid_hash; 1109087SZhong.Wang@Sun.COM uint16_t ss_next_sol_oxid; 1119087SZhong.Wang@Sun.COM uint16_t ss_next_unsol_rxid; 1129087SZhong.Wang@Sun.COM int ss_sol_oxid_hash_empty; 1139087SZhong.Wang@Sun.COM int ss_unsol_rxid_hash_empty; 1149087SZhong.Wang@Sun.COM 1159087SZhong.Wang@Sun.COM /* 1169087SZhong.Wang@Sun.COM * watch thread related stuff 1179087SZhong.Wang@Sun.COM */ 1189087SZhong.Wang@Sun.COM ddi_taskq_t *ss_watchdog_taskq; 1199087SZhong.Wang@Sun.COM kcondvar_t ss_watch_cv; 1209087SZhong.Wang@Sun.COM kmutex_t ss_watch_mutex; 1219087SZhong.Wang@Sun.COM uint64_t ss_watch_count; 1229087SZhong.Wang@Sun.COM list_t ss_abort_xchg_list; 1239087SZhong.Wang@Sun.COM 1249087SZhong.Wang@Sun.COM /* 1259087SZhong.Wang@Sun.COM * topology discovery 1269087SZhong.Wang@Sun.COM */ 1279087SZhong.Wang@Sun.COM struct fcoet_exchange *ss_sol_flogi; 1289087SZhong.Wang@Sun.COM fcoet_sol_flogi_state_t ss_sol_flogi_state; 1299087SZhong.Wang@Sun.COM fct_link_info_t ss_link_info; 1309087SZhong.Wang@Sun.COM 1319087SZhong.Wang@Sun.COM /* 1329087SZhong.Wang@Sun.COM * ioctl related stuff 1339087SZhong.Wang@Sun.COM */ 1349087SZhong.Wang@Sun.COM uint32_t ss_ioctl_flags; 1359087SZhong.Wang@Sun.COM kmutex_t ss_ioctl_mutex; 1369087SZhong.Wang@Sun.COM 1379087SZhong.Wang@Sun.COM /* 1389087SZhong.Wang@Sun.COM * special stuff 1399087SZhong.Wang@Sun.COM */ 1409087SZhong.Wang@Sun.COM uint32_t ss_change_state_flags; 1419087SZhong.Wang@Sun.COM uint8_t ss_state:7, 1429087SZhong.Wang@Sun.COM ss_state_not_acked:1; 1439087SZhong.Wang@Sun.COM } fcoet_soft_state_t; 1449087SZhong.Wang@Sun.COM 1459087SZhong.Wang@Sun.COM #define SS_FLAG_UNSOL_FLOGI_DONE 0x0001 1469087SZhong.Wang@Sun.COM #define SS_FLAG_REPORT_TO_FCT 0x0002 1479087SZhong.Wang@Sun.COM #define SS_FLAG_PORT_DISABLED 0x0004 1489087SZhong.Wang@Sun.COM #define SS_FLAG_STOP_WATCH 0x0008 1499087SZhong.Wang@Sun.COM #define SS_FLAG_TERMINATE_WATCHDOG 0x0010 1509087SZhong.Wang@Sun.COM #define SS_FLAG_WATCHDOG_RUNNING 0x0020 1519087SZhong.Wang@Sun.COM #define SS_FLAG_DOG_WAITING 0x0040 1529087SZhong.Wang@Sun.COM #define SS_FLAG_DELAY_PLOGI 0x0080 1539087SZhong.Wang@Sun.COM 1549087SZhong.Wang@Sun.COM /* 1559087SZhong.Wang@Sun.COM * Sequence and frame are transient objects, so their definition is simple. 1569087SZhong.Wang@Sun.COM */ 1579087SZhong.Wang@Sun.COM 1589087SZhong.Wang@Sun.COM /* 1599087SZhong.Wang@Sun.COM * Sequence. 1609087SZhong.Wang@Sun.COM * we will not use sequence in current implementation 1619087SZhong.Wang@Sun.COM */ 1629087SZhong.Wang@Sun.COM typedef struct fcoet_sequence { 1639087SZhong.Wang@Sun.COM list_t seq_frame_list; 1649087SZhong.Wang@Sun.COM struct fcoet_exchange *seq_exchange; 1659087SZhong.Wang@Sun.COM } fcoet_sequence_t; 1669087SZhong.Wang@Sun.COM 1679087SZhong.Wang@Sun.COM /* 1689087SZhong.Wang@Sun.COM * Frame 1699087SZhong.Wang@Sun.COM */ 1709087SZhong.Wang@Sun.COM typedef struct fcoet_frame { 1719087SZhong.Wang@Sun.COM list_node_t tfm_seq_node; 1729087SZhong.Wang@Sun.COM fcoe_frame_t *tfm_fcoe_frame; 1739087SZhong.Wang@Sun.COM 1749087SZhong.Wang@Sun.COM struct fcoet_exchange *tfm_xch; 1759087SZhong.Wang@Sun.COM struct fcoet_sequence *tfm_seq; 1769087SZhong.Wang@Sun.COM uint8_t tfm_rctl; 1779087SZhong.Wang@Sun.COM uint8_t tfm_buf_idx; 1789087SZhong.Wang@Sun.COM } fcoet_frame_t; 1799087SZhong.Wang@Sun.COM 1809087SZhong.Wang@Sun.COM /* 1819087SZhong.Wang@Sun.COM * FCOET_MAX_DBUF_LEN should better be consistent with sbd_scsi.c. Since 1829087SZhong.Wang@Sun.COM * sbd_scsi.c use 128k as the max dbuf size, we'd better define this between 1839087SZhong.Wang@Sun.COM * 32k - 128k. 1849087SZhong.Wang@Sun.COM */ 1859087SZhong.Wang@Sun.COM #define FCOET_MAX_DBUF_LEN 0x20000 /* 128 * 1024 */ 1869087SZhong.Wang@Sun.COM /* 1879087SZhong.Wang@Sun.COM * exchange - cmd alias 1889087SZhong.Wang@Sun.COM */ 1899087SZhong.Wang@Sun.COM typedef struct fcoet_exchange { 1909087SZhong.Wang@Sun.COM /* 1919087SZhong.Wang@Sun.COM * it is only used for ss_abort_xchg_list 1929087SZhong.Wang@Sun.COM */ 1939087SZhong.Wang@Sun.COM list_node_t xch_abort_node; 1949087SZhong.Wang@Sun.COM 1959087SZhong.Wang@Sun.COM /* 1969087SZhong.Wang@Sun.COM * We don't believe oxid/rxid in fct_cmd_t 1979087SZhong.Wang@Sun.COM */ 1989087SZhong.Wang@Sun.COM uint16_t xch_oxid; 1999087SZhong.Wang@Sun.COM uint16_t xch_rxid; 2009087SZhong.Wang@Sun.COM 2019087SZhong.Wang@Sun.COM uint32_t xch_flags; 2029087SZhong.Wang@Sun.COM fcoet_soft_state_t *xch_ss; 2039087SZhong.Wang@Sun.COM fct_cmd_t *xch_cmd; 2049087SZhong.Wang@Sun.COM 2059087SZhong.Wang@Sun.COM fcoet_sequence_t *xch_current_seq; 2069087SZhong.Wang@Sun.COM clock_t xch_start_time; 2079087SZhong.Wang@Sun.COM 2089087SZhong.Wang@Sun.COM stmf_data_buf_t **xch_dbufs; 2099087SZhong.Wang@Sun.COM uint8_t xch_dbuf_num; 2109087SZhong.Wang@Sun.COM uint8_t xch_sequence_no; 2119087SZhong.Wang@Sun.COM uint8_t xch_ref; 2129087SZhong.Wang@Sun.COM 2139087SZhong.Wang@Sun.COM int xch_left_data_size; 2149087SZhong.Wang@Sun.COM } fcoet_exchange_t; 2159087SZhong.Wang@Sun.COM /* 2169087SZhong.Wang@Sun.COM * Add the reference to avoid such situation: 2179087SZhong.Wang@Sun.COM * 1, Frame received, then abort happen (maybe because local port offline, or 2189087SZhong.Wang@Sun.COM * remote port abort the cmd), cmd is aborted and then freed right after we 2199087SZhong.Wang@Sun.COM * get the exchange from hash table in fcoet_rx_frame. 2209087SZhong.Wang@Sun.COM * 2, Frame sent out, then queued in fcoe for release. then abort happen, cmd 2219087SZhong.Wang@Sun.COM * is aborted and then freed before fcoe_watchdog() call up to release the 2229087SZhong.Wang@Sun.COM * frame. 2239087SZhong.Wang@Sun.COM * These two situation should seldom happen. But just invoke this seems won't 2249087SZhong.Wang@Sun.COM * downgrade the performance too much, so we keep it. 2259087SZhong.Wang@Sun.COM */ 2269087SZhong.Wang@Sun.COM #define FCOET_BUSY_XCHG(xch) atomic_add_8(&(xch)->xch_ref, 1) 2279087SZhong.Wang@Sun.COM #define FCOET_RELE_XCHG(xch) atomic_add_8(&(xch)->xch_ref, -1) 2289087SZhong.Wang@Sun.COM 2299087SZhong.Wang@Sun.COM #define XCH_FLAG_NONFCP_REQ_SENT 0x0001 2309087SZhong.Wang@Sun.COM #define XCH_FLAG_NONFCP_RESP_SENT 0x0002 2319087SZhong.Wang@Sun.COM #define XCH_FLAG_FCP_CMD_RCVD 0x0004 2329087SZhong.Wang@Sun.COM #define XCH_FLAG_INI_ASKED_ABORT 0x0008 2339087SZhong.Wang@Sun.COM #define XCH_FLAG_FCT_CALLED_ABORT 0x0010 2349087SZhong.Wang@Sun.COM #define XCH_FLAG_IN_HASH_TABLE 0x0020 2359087SZhong.Wang@Sun.COM 2369087SZhong.Wang@Sun.COM /* 2379087SZhong.Wang@Sun.COM * IOCTL supporting stuff 2389087SZhong.Wang@Sun.COM */ 2399087SZhong.Wang@Sun.COM #define FCOET_IOCTL_FLAG_MASK 0xFF 2409087SZhong.Wang@Sun.COM #define FCOET_IOCTL_FLAG_IDLE 0x00 2419087SZhong.Wang@Sun.COM #define FCOET_IOCTL_FLAG_OPEN 0x01 2429087SZhong.Wang@Sun.COM #define FCOET_IOCTL_FLAG_EXCL 0x02 2439087SZhong.Wang@Sun.COM 2449087SZhong.Wang@Sun.COM /* 2459087SZhong.Wang@Sun.COM * define common-used conversion and calculation macros 2469087SZhong.Wang@Sun.COM */ 2479087SZhong.Wang@Sun.COM #define FRM2SS(x_frm) \ 2489087SZhong.Wang@Sun.COM ((fcoet_soft_state_t *)(x_frm)->frm_eport->eport_client_private) 2499087SZhong.Wang@Sun.COM #define FRM2TFM(x_frm) ((fcoet_frame_t *)(x_frm)->frm_client_private) 2509087SZhong.Wang@Sun.COM 2519087SZhong.Wang@Sun.COM #define PORT2SS(x_port) ((fcoet_soft_state_t *)(x_port)->port_fca_private) 2529087SZhong.Wang@Sun.COM #define EPORT2SS(x_port) ((fcoet_soft_state_t *)(x_port)->eport_client_private) 2539087SZhong.Wang@Sun.COM 2549087SZhong.Wang@Sun.COM #define XCH2ELS(x_xch) ((fct_els_t *)x_xch->xch_cmd->cmd_specific) 2559087SZhong.Wang@Sun.COM #define XCH2CT(x_xch) ((fct_ct_t *)x_xch->xch_cmd->cmd_specific) 2569087SZhong.Wang@Sun.COM #define XCH2TASK(x_xch) ((scsi_task_t *)x_xch->xch_cmd->cmd_specific) 2579087SZhong.Wang@Sun.COM 2589087SZhong.Wang@Sun.COM #define CMD2ELS(x_cmd) ((fct_els_t *)x_cmd->cmd_specific) 2599087SZhong.Wang@Sun.COM #define CMD2CT(x_cmd) ((fct_sol_ct_t *)x_cmd->cmd_specific) 2609087SZhong.Wang@Sun.COM #define CMD2TASK(x_cmd) ((scsi_task_t *)x_cmd->cmd_specific) 2619087SZhong.Wang@Sun.COM #define CMD2XCH(x_cmd) ((fcoet_exchange_t *)x_cmd->cmd_fca_private) 2629087SZhong.Wang@Sun.COM #define CMD2SS(x_cmd) \ 2639087SZhong.Wang@Sun.COM ((fcoet_soft_state_t *)(x_cmd)->cmd_port->port_fca_private) 2649087SZhong.Wang@Sun.COM 2659087SZhong.Wang@Sun.COM void fcoet_init_tfm(fcoe_frame_t *frm, fcoet_exchange_t *xch); 2669087SZhong.Wang@Sun.COM fct_status_t fcoet_send_status(fct_cmd_t *cmd); 2679087SZhong.Wang@Sun.COM void fcoet_modhash_find_cb(mod_hash_key_t, mod_hash_val_t); 2689087SZhong.Wang@Sun.COM 2699087SZhong.Wang@Sun.COM /* 2709087SZhong.Wang@Sun.COM * DBUF stuff 2719087SZhong.Wang@Sun.COM */ 2729087SZhong.Wang@Sun.COM #define FCOET_DB_SEG_NUM(x_db) (x_db->db_port_private) 2739087SZhong.Wang@Sun.COM #define FCOET_DB_NETB(x_db) \ 2749087SZhong.Wang@Sun.COM (((uintptr_t)FCOET_DB_SEG_NUM(x_db)) * \ 2759087SZhong.Wang@Sun.COM sizeof (struct stmf_sglist_ent) + (uintptr_t)(x_db)->db_sglist) 2769087SZhong.Wang@Sun.COM 2779087SZhong.Wang@Sun.COM #define FCOET_SET_SEG_NUM(x_db, x_num) \ 2789087SZhong.Wang@Sun.COM { \ 2799087SZhong.Wang@Sun.COM FCOET_DB_SEG_NUM(x_db) = (void *)(unsigned long)x_num; \ 2809087SZhong.Wang@Sun.COM } 2819087SZhong.Wang@Sun.COM 2829087SZhong.Wang@Sun.COM #define FCOET_GET_SEG_NUM(x_db) ((int)(unsigned long)FCOET_DB_SEG_NUM(x_db)) 2839087SZhong.Wang@Sun.COM 2849087SZhong.Wang@Sun.COM 2859087SZhong.Wang@Sun.COM #define FCOET_SET_NETB(x_db, x_idx, x_netb) \ 2869087SZhong.Wang@Sun.COM { \ 2879087SZhong.Wang@Sun.COM ((void **)FCOET_DB_NETB(x_db))[x_idx] = x_netb; \ 2889087SZhong.Wang@Sun.COM } 2899087SZhong.Wang@Sun.COM 2909087SZhong.Wang@Sun.COM #define FCOET_GET_NETB(x_db, x_idx) \ 2919087SZhong.Wang@Sun.COM (((void **)FCOET_DB_NETB(x_db))[x_idx]) 2929087SZhong.Wang@Sun.COM 2939087SZhong.Wang@Sun.COM #define PRT_FRM_HDR(x_p, x_f) \ 2949087SZhong.Wang@Sun.COM { \ 2959087SZhong.Wang@Sun.COM FCOET_LOG(x_p, "rctl/%x, type/%x, fctl/%x, oxid/%x", \ 2969087SZhong.Wang@Sun.COM FCOE_B2V_1((x_f)->frm_hdr->hdr_r_ctl), \ 2979087SZhong.Wang@Sun.COM FCOE_B2V_1((x_f)->frm_hdr->hdr_type), \ 2989087SZhong.Wang@Sun.COM FCOE_B2V_3((x_f)->frm_hdr->hdr_f_ctl), \ 2999087SZhong.Wang@Sun.COM FCOE_B2V_4((x_f)->frm_hdr->hdr_oxid)); \ 3009087SZhong.Wang@Sun.COM } 3019087SZhong.Wang@Sun.COM 3029087SZhong.Wang@Sun.COM #endif /* _KERNEL */ 3039087SZhong.Wang@Sun.COM 3049087SZhong.Wang@Sun.COM #ifdef __cplusplus 3059087SZhong.Wang@Sun.COM } 3069087SZhong.Wang@Sun.COM #endif 3079087SZhong.Wang@Sun.COM 3089087SZhong.Wang@Sun.COM #endif /* _FCOET_H */ 309