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