624 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term4 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.5 */6 7#ifndef __EFCLIB_H__8#define __EFCLIB_H__9 10#include "scsi/fc/fc_els.h"11#include "scsi/fc/fc_fs.h"12#include "scsi/fc/fc_ns.h"13#include "scsi/fc/fc_gs.h"14#include "scsi/fc_frame.h"15#include "../include/efc_common.h"16#include "../libefc_sli/sli4.h"17 18#define EFC_SERVICE_PARMS_LENGTH 12019#define EFC_NAME_LENGTH 3220#define EFC_SM_NAME_LENGTH 6421#define EFC_DISPLAY_BUS_INFO_LENGTH 1622 23#define EFC_WWN_LENGTH 3224 25#define EFC_FC_ELS_DEFAULT_RETRIES 326 27/* Timeouts */28#define EFC_FC_ELS_SEND_DEFAULT_TIMEOUT 029#define EFC_FC_FLOGI_TIMEOUT_SEC 530#define EFC_SHUTDOWN_TIMEOUT_USEC 3000000031 32/* Return values for calls from base driver to libefc */33#define EFC_SCSI_CALL_COMPLETE 034#define EFC_SCSI_CALL_ASYNC 135 36/* Local port topology */37enum efc_nport_topology {38 EFC_NPORT_TOPO_UNKNOWN = 0,39 EFC_NPORT_TOPO_FABRIC,40 EFC_NPORT_TOPO_P2P,41 EFC_NPORT_TOPO_FC_AL,42};43 44#define enable_target_rscn(efc) 145 46enum efc_node_shutd_rsn {47 EFC_NODE_SHUTDOWN_DEFAULT = 0,48 EFC_NODE_SHUTDOWN_EXPLICIT_LOGO,49 EFC_NODE_SHUTDOWN_IMPLICIT_LOGO,50};51 52enum efc_node_send_ls_acc {53 EFC_NODE_SEND_LS_ACC_NONE = 0,54 EFC_NODE_SEND_LS_ACC_PLOGI,55 EFC_NODE_SEND_LS_ACC_PRLI,56};57 58#define EFC_LINK_STATUS_UP 059#define EFC_LINK_STATUS_DOWN 160 61enum efc_sm_event;62 63/* State machine context header */64struct efc_sm_ctx {65 void (*current_state)(struct efc_sm_ctx *ctx,66 enum efc_sm_event evt, void *arg);67 68 const char *description;69 void *app;70};71 72/* Description of discovered Fabric Domain */73struct efc_domain_record {74 u32 index;75 u32 priority;76 u8 address[6];77 u8 wwn[8];78 union {79 u8 vlan[512];80 u8 loop[128];81 } map;82 u32 speed;83 u32 fc_id;84 bool is_loop;85 bool is_nport;86};87 88/* Domain events */89enum efc_hw_domain_event {90 EFC_HW_DOMAIN_ALLOC_OK,91 EFC_HW_DOMAIN_ALLOC_FAIL,92 EFC_HW_DOMAIN_ATTACH_OK,93 EFC_HW_DOMAIN_ATTACH_FAIL,94 EFC_HW_DOMAIN_FREE_OK,95 EFC_HW_DOMAIN_FREE_FAIL,96 EFC_HW_DOMAIN_LOST,97 EFC_HW_DOMAIN_FOUND,98 EFC_HW_DOMAIN_CHANGED,99};100 101/**102 * Fibre Channel port object103 *104 * @list_entry: nport list entry105 * @ref: reference count, each node takes a reference106 * @release: function to free nport object107 * @efc: pointer back to efc108 * @instance_index: unique instance index value109 * @display_name: port display name110 * @is_vport: Is NPIV port111 * @free_req_pending: pending request to free resources112 * @attached: mark attached if reg VPI succeeds113 * @p2p_winner: TRUE if we're the point-to-point winner114 * @domain: pointer back to domain115 * @wwpn: port wwpn116 * @wwnn: port wwnn117 * @tgt_data: target backend private port data118 * @ini_data: initiator backend private port data119 * @indicator: VPI120 * @fc_id: port FC address121 * @dma: memory for Service Parameters122 * @wwnn_str: wwpn string123 * @sli_wwpn: SLI provided wwpn124 * @sli_wwnn: SLI provided wwnn125 * @sm: nport state machine context126 * @lookup: fc_id to node lookup object127 * @enable_ini: SCSI initiator enabled for this port128 * @enable_tgt: SCSI target enabled for this port129 * @enable_rscn: port will be expecting RSCN130 * @shutting_down: nport in process of shutting down131 * @p2p_port_id: our port id for point-to-point132 * @topology: topology: fabric/p2p/unknown133 * @service_params: login parameters134 * @p2p_remote_port_id: remote node's port id for point-to-point135 */136 137struct efc_nport {138 struct list_head list_entry;139 struct kref ref;140 void (*release)(struct kref *arg);141 struct efc *efc;142 u32 instance_index;143 char display_name[EFC_NAME_LENGTH];144 bool is_vport;145 bool free_req_pending;146 bool attached;147 bool attaching;148 bool p2p_winner;149 struct efc_domain *domain;150 u64 wwpn;151 u64 wwnn;152 void *tgt_data;153 void *ini_data;154 155 u32 indicator;156 u32 fc_id;157 struct efc_dma dma;158 159 u8 wwnn_str[EFC_WWN_LENGTH];160 __be64 sli_wwpn;161 __be64 sli_wwnn;162 163 struct efc_sm_ctx sm;164 struct xarray lookup;165 bool enable_ini;166 bool enable_tgt;167 bool enable_rscn;168 bool shutting_down;169 u32 p2p_port_id;170 enum efc_nport_topology topology;171 u8 service_params[EFC_SERVICE_PARMS_LENGTH];172 u32 p2p_remote_port_id;173};174 175/**176 * Fibre Channel domain object177 *178 * This object is a container for the various SLI components needed179 * to connect to the domain of a FC or FCoE switch180 * @efc: pointer back to efc181 * @instance_index: unique instance index value182 * @display_name: Node display name183 * @nport_list: linked list of nports associated with this domain184 * @ref: Reference count, each nport takes a reference185 * @release: Function to free domain object186 * @ini_domain: initiator backend private domain data187 * @tgt_domain: target backend private domain data188 * @sm: state machine context189 * @fcf: FC Forwarder table index190 * @fcf_indicator: FCFI191 * @indicator: VFI192 * @nport_count: Number of nports allocated193 * @dma: memory for Service Parameters194 * @fcf_wwn: WWN for FCF/switch195 * @drvsm: driver domain sm context196 * @attached: set true after attach completes197 * @is_fc: is FC198 * @is_loop: is loop topology199 * @is_nlport: is public loop200 * @domain_found_pending:A domain found is pending, drec is updated201 * @req_domain_free: True if domain object should be free'd202 * @req_accept_frames: set in domain state machine to enable frames203 * @domain_notify_pend: Set in domain SM to avoid duplicate node event post204 * @pending_drec: Pending drec if a domain found is pending205 * @service_params: any nports service parameters206 * @flogi_service_params:Fabric/P2p service parameters from FLOGI207 * @lookup: d_id to node lookup object208 * @nport: Pointer to first (physical) SLI port209 */210struct efc_domain {211 struct efc *efc;212 char display_name[EFC_NAME_LENGTH];213 struct list_head nport_list;214 struct kref ref;215 void (*release)(struct kref *arg);216 void *ini_domain;217 void *tgt_domain;218 219 /* Declarations private to HW/SLI */220 u32 fcf;221 u32 fcf_indicator;222 u32 indicator;223 u32 nport_count;224 struct efc_dma dma;225 226 /* Declarations private to FC trannport */227 u64 fcf_wwn;228 struct efc_sm_ctx drvsm;229 bool attached;230 bool is_fc;231 bool is_loop;232 bool is_nlport;233 bool domain_found_pending;234 bool req_domain_free;235 bool req_accept_frames;236 bool domain_notify_pend;237 238 struct efc_domain_record pending_drec;239 u8 service_params[EFC_SERVICE_PARMS_LENGTH];240 u8 flogi_service_params[EFC_SERVICE_PARMS_LENGTH];241 242 struct xarray lookup;243 244 struct efc_nport *nport;245};246 247/**248 * Remote Node object249 *250 * This object represents a connection between the SLI port and another251 * Nx_Port on the fabric. Note this can be either a well known port such252 * as a F_Port (i.e. ff:ff:fe) or another N_Port.253 * @indicator: RPI254 * @fc_id: FC address255 * @attached: true if attached256 * @nport: associated SLI port257 * @node: associated node258 */259struct efc_remote_node {260 u32 indicator;261 u32 index;262 u32 fc_id;263 264 bool attached;265 266 struct efc_nport *nport;267 void *node;268};269 270/**271 * FC Node object272 * @efc: pointer back to efc structure273 * @display_name: Node display name274 * @nort: Assosiated nport pointer.275 * @hold_frames: hold incoming frames if true276 * @els_io_enabled: Enable allocating els ios for this node277 * @els_ios_lock: lock to protect the els ios list278 * @els_ios_list: ELS I/O's for this node279 * @ini_node: backend initiator private node data280 * @tgt_node: backend target private node data281 * @rnode: Remote node282 * @sm: state machine context283 * @evtdepth: current event posting nesting depth284 * @req_free: this node is to be free'd285 * @attached: node is attached (REGLOGIN complete)286 * @fcp_enabled: node is enabled to handle FCP287 * @rscn_pending: for name server node RSCN is pending288 * @send_plogi: send PLOGI accept, upon completion of node attach289 * @send_plogi_acc: TRUE if io_alloc() is enabled.290 * @send_ls_acc: type of LS acc to send291 * @ls_acc_io: SCSI IO for LS acc292 * @ls_acc_oxid: OX_ID for pending accept293 * @ls_acc_did: D_ID for pending accept294 * @shutdown_reason: reason for node shutdown295 * @sparm_dma_buf: service parameters buffer296 * @service_params: plogi/acc frame from remote device297 * @pend_frames_lock: lock for inbound pending frames list298 * @pend_frames: inbound pending frames list299 * @pend_frames_processed:count of frames processed in hold frames interval300 * @ox_id_in_use: used to verify one at a time us of ox_id301 * @els_retries_remaining:for ELS, number of retries remaining302 * @els_req_cnt: number of outstanding ELS requests303 * @els_cmpl_cnt: number of outstanding ELS completions304 * @abort_cnt: Abort counter for debugging purpos305 * @current_state_name: current node state306 * @prev_state_name: previous node state307 * @current_evt: current event308 * @prev_evt: previous event309 * @targ: node is target capable310 * @init: node is init capable311 * @refound: Handle node refound case when node is being deleted312 * @els_io_pend_list: list of pending (not yet processed) ELS IOs313 * @els_io_active_list: list of active (processed) ELS IOs314 * @nodedb_state: Node debugging, saved state315 * @gidpt_delay_timer: GIDPT delay timer316 * @time_last_gidpt_msec:Start time of last target RSCN GIDPT317 * @wwnn: remote port WWNN318 * @wwpn: remote port WWPN319 */320struct efc_node {321 struct efc *efc;322 char display_name[EFC_NAME_LENGTH];323 struct efc_nport *nport;324 struct kref ref;325 void (*release)(struct kref *arg);326 bool hold_frames;327 bool els_io_enabled;328 bool send_plogi_acc;329 bool send_plogi;330 bool rscn_pending;331 bool fcp_enabled;332 bool attached;333 bool req_free;334 335 spinlock_t els_ios_lock;336 struct list_head els_ios_list;337 void *ini_node;338 void *tgt_node;339 340 struct efc_remote_node rnode;341 /* Declarations private to FC trannport */342 struct efc_sm_ctx sm;343 u32 evtdepth;344 345 enum efc_node_send_ls_acc send_ls_acc;346 void *ls_acc_io;347 u32 ls_acc_oxid;348 u32 ls_acc_did;349 enum efc_node_shutd_rsn shutdown_reason;350 bool targ;351 bool init;352 bool refound;353 struct efc_dma sparm_dma_buf;354 u8 service_params[EFC_SERVICE_PARMS_LENGTH];355 spinlock_t pend_frames_lock;356 struct list_head pend_frames;357 u32 pend_frames_processed;358 u32 ox_id_in_use;359 u32 els_retries_remaining;360 u32 els_req_cnt;361 u32 els_cmpl_cnt;362 u32 abort_cnt;363 364 char current_state_name[EFC_SM_NAME_LENGTH];365 char prev_state_name[EFC_SM_NAME_LENGTH];366 int current_evt;367 int prev_evt;368 369 void (*nodedb_state)(struct efc_sm_ctx *ctx,370 enum efc_sm_event evt, void *arg);371 struct timer_list gidpt_delay_timer;372 u64 time_last_gidpt_msec;373 374 char wwnn[EFC_WWN_LENGTH];375 char wwpn[EFC_WWN_LENGTH];376};377 378/**379 * NPIV port380 *381 * Collection of the information required to restore a virtual port across382 * link events383 * @wwnn: node name384 * @wwpn: port name385 * @fc_id: port id386 * @tgt_data: target backend pointer387 * @ini_data: initiator backend pointe388 * @nport: Used to match record after attaching for update389 *390 */391 392struct efc_vport {393 struct list_head list_entry;394 u64 wwnn;395 u64 wwpn;396 u32 fc_id;397 bool enable_tgt;398 bool enable_ini;399 void *tgt_data;400 void *ini_data;401 struct efc_nport *nport;402};403 404#define node_printf(node, fmt, args...) \405 efc_log_info(node->efc, "[%s] " fmt, node->display_name, ##args)406 407/* Node SM IO Context Callback structure */408struct efc_node_cb {409 int status;410 int ext_status;411 struct efc_hw_rq_buffer *header;412 struct efc_hw_rq_buffer *payload;413 struct efc_dma els_rsp;414 415 /* Actual length of data received */416 int rsp_len;417};418 419struct efc_hw_rq_buffer {420 u16 rqindex;421 struct efc_dma dma;422};423 424/**425 * FC sequence object426 *427 * Defines a general FC sequence object428 * @hw: HW that owns this sequence429 * @fcfi: FCFI associated with sequence430 * @header: Received frame header431 * @payload: Received frame header432 * @hw_priv: HW private context433 */434struct efc_hw_sequence {435 struct list_head list_entry;436 void *hw;437 u8 fcfi;438 struct efc_hw_rq_buffer *header;439 struct efc_hw_rq_buffer *payload;440 void *hw_priv;441};442 443enum efc_disc_io_type {444 EFC_DISC_IO_ELS_REQ,445 EFC_DISC_IO_ELS_RESP,446 EFC_DISC_IO_CT_REQ,447 EFC_DISC_IO_CT_RESP448};449 450struct efc_io_els_params {451 u32 s_id;452 u16 ox_id;453 u8 timeout;454};455 456struct efc_io_ct_params {457 u8 r_ctl;458 u8 type;459 u8 df_ctl;460 u8 timeout;461 u16 ox_id;462};463 464union efc_disc_io_param {465 struct efc_io_els_params els;466 struct efc_io_ct_params ct;467};468 469struct efc_disc_io {470 struct efc_dma req; /* send buffer */471 struct efc_dma rsp; /* receive buffer */472 enum efc_disc_io_type io_type; /* EFC_DISC_IO_TYPE enum*/473 u16 xmit_len; /* Length of els request*/474 u16 rsp_len; /* Max length of rsps to be rcvd */475 u32 rpi; /* Registered RPI */476 u32 vpi; /* VPI for this nport */477 u32 s_id;478 u32 d_id;479 bool rpi_registered; /* if false, use tmp RPI */480 union efc_disc_io_param iparam;481};482 483/* Return value indiacating the sequence can not be freed */484#define EFC_HW_SEQ_HOLD 0485/* Return value indiacating the sequence can be freed */486#define EFC_HW_SEQ_FREE 1487 488struct libefc_function_template {489 /*Sport*/490 int (*new_nport)(struct efc *efc, struct efc_nport *sp);491 void (*del_nport)(struct efc *efc, struct efc_nport *sp);492 493 /*Scsi Node*/494 int (*scsi_new_node)(struct efc *efc, struct efc_node *n);495 int (*scsi_del_node)(struct efc *efc, struct efc_node *n, int reason);496 497 int (*issue_mbox_rqst)(void *efct, void *buf, void *cb, void *arg);498 /*Send ELS IO*/499 int (*send_els)(struct efc *efc, struct efc_disc_io *io);500 /*Send BLS IO*/501 int (*send_bls)(struct efc *efc, u32 type, struct sli_bls_params *bls);502 /*Free HW frame*/503 int (*hw_seq_free)(struct efc *efc, struct efc_hw_sequence *seq);504};505 506#define EFC_LOG_LIB 0x01507#define EFC_LOG_NODE 0x02508#define EFC_LOG_PORT 0x04509#define EFC_LOG_DOMAIN 0x08510#define EFC_LOG_ELS 0x10511#define EFC_LOG_DOMAIN_SM 0x20512#define EFC_LOG_SM 0x40513 514/* efc library port structure */515struct efc {516 void *base;517 struct pci_dev *pci;518 struct sli4 *sli;519 u32 fcfi;520 u64 req_wwpn;521 u64 req_wwnn;522 523 u64 def_wwpn;524 u64 def_wwnn;525 u64 max_xfer_size;526 mempool_t *node_pool;527 struct dma_pool *node_dma_pool;528 u32 nodes_count;529 530 u32 link_status;531 532 struct list_head vport_list;533 /* lock to protect the vport list */534 spinlock_t vport_lock;535 536 struct libefc_function_template tt;537 /* lock to protect the discovery library.538 * Refer to efclib.c for more details.539 */540 spinlock_t lock;541 542 bool enable_ini;543 bool enable_tgt;544 545 u32 log_level;546 547 struct efc_domain *domain;548 void (*domain_free_cb)(struct efc *efc, void *arg);549 void *domain_free_cb_arg;550 551 u64 tgt_rscn_delay_msec;552 u64 tgt_rscn_period_msec;553 554 bool external_loopback;555 u32 nodedb_mask;556 u32 logmask;557 mempool_t *els_io_pool;558 atomic_t els_io_alloc_failed_count;559 560 /* hold pending frames */561 bool hold_frames;562 /* lock to protect pending frames list access */563 spinlock_t pend_frames_lock;564 struct list_head pend_frames;565 /* count of pending frames that were processed */566 u32 pend_frames_processed;567 568};569 570/*571 * EFC library registration572 * **********************************/573int efcport_init(struct efc *efc);574void efcport_destroy(struct efc *efc);575/*576 * EFC Domain577 * **********************************/578int efc_domain_cb(void *arg, int event, void *data);579void580efc_register_domain_free_cb(struct efc *efc,581 void (*callback)(struct efc *efc, void *arg),582 void *arg);583 584/*585 * EFC nport586 * **********************************/587void efc_nport_cb(void *arg, int event, void *data);588struct efc_vport *589efc_vport_create_spec(struct efc *efc, u64 wwnn, u64 wwpn, u32 fc_id,590 bool enable_ini, bool enable_tgt,591 void *tgt_data, void *ini_data);592int efc_nport_vport_new(struct efc_domain *domain, u64 wwpn,593 u64 wwnn, u32 fc_id, bool ini, bool tgt,594 void *tgt_data, void *ini_data);595int efc_nport_vport_del(struct efc *efc, struct efc_domain *domain,596 u64 wwpn, u64 wwnn);597 598void efc_vport_del_all(struct efc *efc);599 600/*601 * EFC Node602 * **********************************/603int efc_remote_node_cb(void *arg, int event, void *data);604void efc_node_fcid_display(u32 fc_id, char *buffer, u32 buf_len);605void efc_node_post_shutdown(struct efc_node *node, void *arg);606u64 efc_node_get_wwpn(struct efc_node *node);607 608/*609 * EFC FCP/ELS/CT interface610 * **********************************/611void efc_dispatch_frame(struct efc *efc, struct efc_hw_sequence *seq);612void efc_disc_io_complete(struct efc_disc_io *io, u32 len, u32 status,613 u32 ext_status);614 615/*616 * EFC SCSI INTERACTION LAYER617 * **********************************/618void efc_scsi_sess_reg_complete(struct efc_node *node, u32 status);619void efc_scsi_del_initiator_complete(struct efc *efc, struct efc_node *node);620void efc_scsi_del_target_complete(struct efc *efc, struct efc_node *node);621void efc_scsi_io_list_empty(struct efc *efc, struct efc_node *node);622 623#endif /* __EFCLIB_H__ */624