162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2021 Broadcom. All Rights Reserved. The term 462306a36Sopenharmony_ci * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#if !defined(__EFC_NODE_H__) 862306a36Sopenharmony_ci#define __EFC_NODE_H__ 962306a36Sopenharmony_ci#include "scsi/fc/fc_ns.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#define EFC_NODEDB_PAUSE_FABRIC_LOGIN (1 << 0) 1262306a36Sopenharmony_ci#define EFC_NODEDB_PAUSE_NAMESERVER (1 << 1) 1362306a36Sopenharmony_ci#define EFC_NODEDB_PAUSE_NEW_NODES (1 << 2) 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define MAX_ACC_REJECT_PAYLOAD sizeof(struct fc_els_ls_rjt) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define scsi_io_printf(io, fmt, ...) \ 1862306a36Sopenharmony_ci efc_log_debug(io->efc, "[%s] [%04x][i:%04x t:%04x h:%04x]" fmt, \ 1962306a36Sopenharmony_ci io->node->display_name, io->instance_index, io->init_task_tag, \ 2062306a36Sopenharmony_ci io->tgt_task_tag, io->hw_tag, ##__VA_ARGS__) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistatic inline void 2362306a36Sopenharmony_ciefc_node_evt_set(struct efc_sm_ctx *ctx, enum efc_sm_event evt, 2462306a36Sopenharmony_ci const char *handler) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci struct efc_node *node = ctx->app; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci if (evt == EFC_EVT_ENTER) { 2962306a36Sopenharmony_ci strncpy(node->current_state_name, handler, 3062306a36Sopenharmony_ci sizeof(node->current_state_name)); 3162306a36Sopenharmony_ci } else if (evt == EFC_EVT_EXIT) { 3262306a36Sopenharmony_ci strncpy(node->prev_state_name, node->current_state_name, 3362306a36Sopenharmony_ci sizeof(node->prev_state_name)); 3462306a36Sopenharmony_ci strncpy(node->current_state_name, "invalid", 3562306a36Sopenharmony_ci sizeof(node->current_state_name)); 3662306a36Sopenharmony_ci } 3762306a36Sopenharmony_ci node->prev_evt = node->current_evt; 3862306a36Sopenharmony_ci node->current_evt = evt; 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/** 4262306a36Sopenharmony_ci * hold frames in pending frame list 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * Unsolicited receive frames are held on the node pending frame list, 4562306a36Sopenharmony_ci * rather than being processed. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic inline void 4962306a36Sopenharmony_ciefc_node_hold_frames(struct efc_node *node) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci node->hold_frames = true; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/** 5562306a36Sopenharmony_ci * accept frames 5662306a36Sopenharmony_ci * 5762306a36Sopenharmony_ci * Unsolicited receive frames processed rather than being held on the node 5862306a36Sopenharmony_ci * pending frame list. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic inline void 6262306a36Sopenharmony_ciefc_node_accept_frames(struct efc_node *node) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci node->hold_frames = false; 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* 6862306a36Sopenharmony_ci * Node initiator/target enable defines 6962306a36Sopenharmony_ci * All combinations of the SLI port (nport) initiator/target enable, 7062306a36Sopenharmony_ci * and remote node initiator/target enable are enumerated. 7162306a36Sopenharmony_ci * ex: EFC_NODE_ENABLE_T_TO_IT decodes to target mode is enabled on SLI port 7262306a36Sopenharmony_ci * and I+T is enabled on remote node. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_cienum efc_node_enable { 7562306a36Sopenharmony_ci EFC_NODE_ENABLE_x_TO_x, 7662306a36Sopenharmony_ci EFC_NODE_ENABLE_x_TO_T, 7762306a36Sopenharmony_ci EFC_NODE_ENABLE_x_TO_I, 7862306a36Sopenharmony_ci EFC_NODE_ENABLE_x_TO_IT, 7962306a36Sopenharmony_ci EFC_NODE_ENABLE_T_TO_x, 8062306a36Sopenharmony_ci EFC_NODE_ENABLE_T_TO_T, 8162306a36Sopenharmony_ci EFC_NODE_ENABLE_T_TO_I, 8262306a36Sopenharmony_ci EFC_NODE_ENABLE_T_TO_IT, 8362306a36Sopenharmony_ci EFC_NODE_ENABLE_I_TO_x, 8462306a36Sopenharmony_ci EFC_NODE_ENABLE_I_TO_T, 8562306a36Sopenharmony_ci EFC_NODE_ENABLE_I_TO_I, 8662306a36Sopenharmony_ci EFC_NODE_ENABLE_I_TO_IT, 8762306a36Sopenharmony_ci EFC_NODE_ENABLE_IT_TO_x, 8862306a36Sopenharmony_ci EFC_NODE_ENABLE_IT_TO_T, 8962306a36Sopenharmony_ci EFC_NODE_ENABLE_IT_TO_I, 9062306a36Sopenharmony_ci EFC_NODE_ENABLE_IT_TO_IT, 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic inline enum efc_node_enable 9462306a36Sopenharmony_ciefc_node_get_enable(struct efc_node *node) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci u32 retval = 0; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci if (node->nport->enable_ini) 9962306a36Sopenharmony_ci retval |= (1U << 3); 10062306a36Sopenharmony_ci if (node->nport->enable_tgt) 10162306a36Sopenharmony_ci retval |= (1U << 2); 10262306a36Sopenharmony_ci if (node->init) 10362306a36Sopenharmony_ci retval |= (1U << 1); 10462306a36Sopenharmony_ci if (node->targ) 10562306a36Sopenharmony_ci retval |= (1U << 0); 10662306a36Sopenharmony_ci return (enum efc_node_enable)retval; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ciint 11062306a36Sopenharmony_ciefc_node_check_els_req(struct efc_sm_ctx *ctx, 11162306a36Sopenharmony_ci enum efc_sm_event evt, void *arg, 11262306a36Sopenharmony_ci u8 cmd, void (*efc_node_common_func)(const char *, 11362306a36Sopenharmony_ci struct efc_sm_ctx *, enum efc_sm_event, void *), 11462306a36Sopenharmony_ci const char *funcname); 11562306a36Sopenharmony_ciint 11662306a36Sopenharmony_ciefc_node_check_ns_req(struct efc_sm_ctx *ctx, 11762306a36Sopenharmony_ci enum efc_sm_event evt, void *arg, 11862306a36Sopenharmony_ci u16 cmd, void (*efc_node_common_func)(const char *, 11962306a36Sopenharmony_ci struct efc_sm_ctx *, enum efc_sm_event, void *), 12062306a36Sopenharmony_ci const char *funcname); 12162306a36Sopenharmony_ciint 12262306a36Sopenharmony_ciefc_node_attach(struct efc_node *node); 12362306a36Sopenharmony_cistruct efc_node * 12462306a36Sopenharmony_ciefc_node_alloc(struct efc_nport *nport, u32 port_id, 12562306a36Sopenharmony_ci bool init, bool targ); 12662306a36Sopenharmony_civoid 12762306a36Sopenharmony_ciefc_node_free(struct efc_node *efc); 12862306a36Sopenharmony_civoid 12962306a36Sopenharmony_ciefc_node_update_display_name(struct efc_node *node); 13062306a36Sopenharmony_civoid efc_node_post_event(struct efc_node *node, enum efc_sm_event evt, 13162306a36Sopenharmony_ci void *arg); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_civoid 13462306a36Sopenharmony_ci__efc_node_shutdown(struct efc_sm_ctx *ctx, 13562306a36Sopenharmony_ci enum efc_sm_event evt, void *arg); 13662306a36Sopenharmony_civoid 13762306a36Sopenharmony_ci__efc_node_wait_node_free(struct efc_sm_ctx *ctx, 13862306a36Sopenharmony_ci enum efc_sm_event evt, void *arg); 13962306a36Sopenharmony_civoid 14062306a36Sopenharmony_ci__efc_node_wait_els_shutdown(struct efc_sm_ctx *ctx, 14162306a36Sopenharmony_ci enum efc_sm_event evt, void *arg); 14262306a36Sopenharmony_civoid 14362306a36Sopenharmony_ci__efc_node_wait_ios_shutdown(struct efc_sm_ctx *ctx, 14462306a36Sopenharmony_ci enum efc_sm_event evt, void *arg); 14562306a36Sopenharmony_civoid 14662306a36Sopenharmony_ciefc_node_save_sparms(struct efc_node *node, void *payload); 14762306a36Sopenharmony_civoid 14862306a36Sopenharmony_ciefc_node_transition(struct efc_node *node, 14962306a36Sopenharmony_ci void (*state)(struct efc_sm_ctx *, enum efc_sm_event, 15062306a36Sopenharmony_ci void *), void *data); 15162306a36Sopenharmony_civoid 15262306a36Sopenharmony_ci__efc_node_common(const char *funcname, struct efc_sm_ctx *ctx, 15362306a36Sopenharmony_ci enum efc_sm_event evt, void *arg); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_civoid 15662306a36Sopenharmony_ciefc_node_initiate_cleanup(struct efc_node *node); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_civoid 15962306a36Sopenharmony_ciefc_node_build_eui_name(char *buf, u32 buf_len, uint64_t eui_name); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_civoid 16262306a36Sopenharmony_ciefc_node_pause(struct efc_node *node, 16362306a36Sopenharmony_ci void (*state)(struct efc_sm_ctx *ctx, 16462306a36Sopenharmony_ci enum efc_sm_event evt, void *arg)); 16562306a36Sopenharmony_civoid 16662306a36Sopenharmony_ci__efc_node_paused(struct efc_sm_ctx *ctx, 16762306a36Sopenharmony_ci enum efc_sm_event evt, void *arg); 16862306a36Sopenharmony_ciint 16962306a36Sopenharmony_ciefc_node_active_ios_empty(struct efc_node *node); 17062306a36Sopenharmony_civoid 17162306a36Sopenharmony_ciefc_node_send_ls_io_cleanup(struct efc_node *node); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ciint 17462306a36Sopenharmony_ciefc_els_io_list_empty(struct efc_node *node, struct list_head *list); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_civoid 17762306a36Sopenharmony_ciefc_process_node_pending(struct efc_node *domain); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ciu64 efc_node_get_wwnn(struct efc_node *node); 18062306a36Sopenharmony_cistruct efc_node * 18162306a36Sopenharmony_ciefc_node_find(struct efc_nport *nport, u32 id); 18262306a36Sopenharmony_civoid 18362306a36Sopenharmony_ciefc_node_post_els_resp(struct efc_node *node, u32 evt, void *arg); 18462306a36Sopenharmony_civoid 18562306a36Sopenharmony_ciefc_node_recv_els_frame(struct efc_node *node, struct efc_hw_sequence *s); 18662306a36Sopenharmony_civoid 18762306a36Sopenharmony_ciefc_node_recv_ct_frame(struct efc_node *node, struct efc_hw_sequence *seq); 18862306a36Sopenharmony_civoid 18962306a36Sopenharmony_ciefc_node_recv_fcp_cmd(struct efc_node *node, struct efc_hw_sequence *seq); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci#endif /* __EFC_NODE_H__ */ 192