new file mode 100644
@@ -0,0 +1,555 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2007 Nuova Systems, Inc. All rights reserved.
+ */
+
+#ifndef _FDLS_FC_H_
+#define _FDLS_FC_H_
+
+/* This file contains the declarations for FC fabric services
+ * and target discovery
+ *
+ * Request and Response for
+ * 1. FLOGI
+ * 2. PLOGI to Fabric Controller
+ * 3. GPN_ID, GPN_FT
+ * 4. RSCN
+ * 5. PLOGI to Target
+ * 6. PRLI to Target
+ */
+
+#include <scsi/scsi.h>
+#include <scsi/fc/fc_els.h>
+
+#define MIN(x, y) (x < y ? x : y)
+
+#define FNIC_FCP_SP_RD_XRDY_DIS 0x00000002
+#define FNIC_FCP_SP_TARGET 0x00000010
+#define FNIC_FCP_SP_INITIATOR 0x00000020
+#define FNIC_FCP_SP_CONF_CMPL 0x00000080
+#define FNIC_FCP_SP_RETRY 0x00000100
+
+#ifdef _BIG_ENDIAN
+
+#define FNIC_FLOGI_OXID (0x1001)
+#define FNIC_PLOGI_FABRIC_OXID (0x1002)
+#define FNIC_RPN_REQ_OXID (0x1003)
+#define FNIC_GPN_FT_OXID (0x1004)
+#define FNIC_SCR_REQ_OXID (0x1005)
+#define FNIC_RSCN_RESP_OXID (0x1006)
+#define FNIC_LOGO_REQ_OXID (0x1007)
+#define FNIC_LOGO_RESP_OXID (0x1008)
+#define FNIC_RFT_REQ_OXID (0x100a)
+#define FNIC_RFF_REQ_OXID (0x100b)
+#define FNIC_ECHO_RESP_OXID (0x100c)
+#define FNIC_ADISC_RESP_OXID (0x100d)
+#define FNIC_FDMI_PLOGI_OXID (0x100e)
+#define FNIC_FDMI_REG_HBA_OXID (0X100f)
+#define FNIC_FDMI_RPA_OXID (0X1010)
+#define FNIC_ELS_REQ_FCTL (0x290000)
+#define FNIC_ELS_REP_FCTL (0x990000)
+
+#define FNIC_FC_PH_VER (0x2020)
+#define FNIC_FC_B2B_CREDIT (0x000A)
+#define FNIC_FC_B2B_RDF_SZ (0x0800)
+
+#define FNIC_REQ_ABTS_FCTL (0x090000)
+
+#define FNIC_FC_FEATURES (0x8000)
+
+#define FNIC_FC_CONCUR_SEQS (0x00FF)
+
+#define FNIC_FC_RO_INFO (0x001F)
+#define FNIC_E_D_TOV (0x07D0)
+
+#define FC_CT_RPN_CMD (0x0212)
+#define FC_CT_GPN_FT_CMD (0x0172)
+#define FC_CT_ACC (0x8002)
+#define FC_CT_REJ (0x8001)
+#define FC_CT_RFT_CMD (0x1702)
+#define FC_CT_RFF_CMD (0x1F02)
+
+#define FNIC_FCP_RSP_FCTL (0x990000)
+
+#else /* _LITTLE_ENDIAN */
+
+#define FNIC_FLOGI_OXID (0x0110)
+#define FNIC_PLOGI_FABRIC_OXID (0x0210)
+#define FNIC_RPN_REQ_OXID (0x0310)
+#define FNIC_GPN_FT_OXID (0x0410)
+#define FNIC_SCR_REQ_OXID (0x0510)
+#define FNIC_RSCN_RESP_OXID (0x0610)
+#define FNIC_TLOGO_REQ_OXID (0x0710)
+#define FNIC_FLOGO_REQ_OXID (0x0711)
+#define FNIC_LOGO_RESP_OXID (0x0810)
+#define FNIC_PLOGI_RESP_OXID (0x0910)
+#define FNIC_RFT_REQ_OXID (0x0a10)
+#define FNIC_RFF_REQ_OXID (0x0b10)
+#define FNIC_ECHO_RESP_OXID (0x0c10)
+#define FNIC_UNSUPPORTED_RESP_OXID (0xffff)
+#define FNIC_ADISC_RESP_OXID (0x0d10)
+#define FNIC_PLOGI_FDMI_OXID (0x0e10)
+#define FNIC_FDMI_REG_HBA_OXID (0X0f10)
+#define FNIC_FDMI_RPA_OXID (0X1010)
+#define FNIC_ELS_REQ_FCTL (0x000029)
+#define FNIC_ELS_REP_FCTL (0x000099)
+
+#define FNIC_FCP_RSP_FCTL (0x000099)
+#define FNIC_REQ_ABTS_FCTL (0x000009)
+
+#define FNIC_FC_PH_VER (0x2020)
+#define FNIC_FC_B2B_CREDIT (0x0A00)
+#define FNIC_FC_B2B_RDF_SZ (0x0008)
+
+#define FNIC_FC_FEATURES (0x0080)
+
+#define FNIC_FC_CONCUR_SEQS (0xFF00)
+#define FNIC_FC_RO_INFO (0x1F00)
+#define FNIC_E_D_TOV (0xD0070000)
+
+#define FC_CT_RPN_CMD (0x1202)
+#define FC_CT_GPN_FT_CMD (0x7201)
+#define FC_CT_ACC (0x0280)
+#define FC_CT_REJ (0x0180)
+#define FC_CT_RFT_CMD (0x1702)
+#define FC_CT_RFF_CMD (0x1F02)
+
+#endif
+
+#define ETH_TYPE_FCOE 0x8906
+#define ETH_TYPE_FIP 0x8914
+
+#define FC_DIR_SERVER 0xFFFFFC
+#define FC_FABRIC_CONTROLLER 0xFFFFFD
+#define FC_DOMAIN_CONTR 0xFFFFFE
+
+#define FNIC_FC_GPN_LAST_ENTRY (0x80)
+
+#define FNIC_BA_ACC_RCTL 0x84
+#define FNIC_BA_RJT_RCTL 0x85
+#define FC_ABTS_RCTL 0x81
+#define FC_ELS_RJT_LOGICAL_BUSY 0x05
+#define FC_ELS_RJT_BUSY 0x09
+
+/* FNIC FDMI Register HBA Macros */
+#define FNIC_FDMI_TYPE_NODE_NAME 0X100
+#define FNIC_FDMI_TYPE_MANUFACTURER 0X200
+#define FNIC_FDMI_MANUFACTURER "Cisco Systems"
+#define FNIC_FDMI_TYPE_SERIAL_NUMBER 0X300
+#define FNIC_FDMI_TYPE_MODEL 0X400
+#define FNIC_FDMI_TYPE_MODEL_DES 0X500
+#define FNIC_FDMI_MODEL_DESCRIPTION "Cisco Virtual Interface Card"
+#define FNIC_FDMI_TYPE_HARDWARE_VERSION 0X600
+#define FNIC_FDMI_TYPE_DRIVER_VERSION 0X700
+#define FNIC_FDMI_TYPE_ROM_VERSION 0X800
+#define FNIC_FDMI_TYPE_FIRMWARE_VERSION 0X900
+
+/* FNIC FDMI Register PA Macros */
+#define FNIC_FDMI_TYPE_FC4_TYPES 0X100
+#define FNIC_FDMI_TYPE_SUPPORTED_SPEEDS 0X200
+#define FNIC_FDMI_TYPE_CURRENT_SPEED 0X300
+#define FNIC_FDMI_TYPE_MAX_FRAME_SIZE 0X400
+#define FNIC_FDMI_TYPE_OS_NAME 0X500
+#define FNIC_FDMI_TYPE_HOST_NAME 0X600
+
+#define FNIC_SET_S_ID(_fchdr, _sid) memcpy(_fchdr->sid, _sid, 3)
+#define FNIC_SET_NPORT_NAME(_req, _pName) (_req.nport_name = get_unaligned_be64(&_pName))
+#define FNIC_SET_NODE_NAME(_req, _pName) (_req.node_name = get_unaligned_be64(&_pName))
+#define FNIC_SET_RDF_SIZE(_req, _rdf_size) \
+ (_req.b2b_rdf_size = htons(_rdf_size))
+#define FNIC_SET_R_A_TOV(_req, _r_a_tov) (_req.r_a_tov = htonl(_r_a_tov))
+#define FNIC_SET_E_D_TOV(_req, _e_d_tov) (_req.e_d_tov = htonl(_e_d_tov))
+#define FNIC_SET_D_ID(_fchdr, _did) memcpy(_fchdr->did, _did, 3)
+#define FNIC_SET_OX_ID(_fchdr, _oxid) (_fchdr->ox_id = _oxid)
+#define FNIC_SET_RX_ID(_fchdr, _rxid) (_fchdr->rx_id = _rxid)
+
+#define FNIC_SET_PORT_ID(__req, __portid) \
+ memcpy(__req->port_id, __portid, 3)
+#define FNIC_SET_RPN_PORT_ID(__req, __portid) \
+ memcpy(__req->port_id, __portid, 3)
+#define FNIC_SET_RPN_PORT_NAME(_req, _pName) \
+ (_req->port_name = get_unaligned_be64(&_pName))
+
+#define FNIC_GET_S_ID(_fchdr) (_fchdr->sid)
+#define FNIC_GET_D_ID(_fchdr) (_fchdr->did)
+#define FNIC_GET_OX_ID(_fchdr) (_fchdr->ox_id)
+
+#define FNIC_GET_FC_CT_CMD(__fcct_hdr) (__fcct_hdr->command)
+
+#define FNIC_FCOE_SOF (0x2E)
+#define FNIC_FCOE_EOF (0x42)
+
+#define FNIC_GET_FC_TYPE(_fchdr) (_fchdr->type)
+#define FNIC_GET_FC_RCTL(_fchdr) (_fchdr->r_ctl)
+
+#define FNIC_FC_TYPE_ELS (0x01)
+#define FNIC_FC_R_ELS_REQ (0x22)
+#define FNIC_FC_R_ELS_RSP (0x23)
+
+#define FNIC_FCOE_MAX_FRAME_SZ (2048)
+#define FNIC_FCOE_MIN_FRAME_SZ (280)
+#define FNIC_FC_MAX_PAYLOAD_LEN (2048)
+#define FNIC_MIN_DATA_FIELD_SIZE (256)
+#define FNIC_R_A_TOV_DEF (10 * 1000) /* msec */
+#define FNIC_E_D_TOV_DEF (2 * 1000) /* msec */
+
+#define FNIC_FC_EDTOV_NSEC (0x400)
+#define FNIC_NSEC_TO_MSEC (0x1000000)
+#define FCP_PRLI_FUNC_TARGET (0x0010)
+#define FC_CT_RJT_LOGICAL_BUSY 0x5
+#define FC_CT_RJT_BUSY 0x9
+
+#define FNIC_FC_R_CTL_UNSOLICITED (0x22)
+#define FNIC_FC_R_CTL_SOLICITED_DATA (0x21)
+#define FNIC_FC_R_CTL_SOLICITED_CTRL_REPLY (0x23)
+#define FNIC_FC_F_CTL_LAST_END_SEQ (0x98)
+#define FNIC_FC_F_CTL_LAST_END_SEQ_INT (0x99)
+#define FNIC_FC_F_CTL_FIRST_LAST_SEQINIT (0x29)
+#define FNIC_FC_R_CTL_FC4_SCTL (0x03)
+#define FNIC_FC_TYPE_BLS (0x00)
+#define FNIC_FC_TYPE_ELS (0x01)
+#define FNIC_FC_TYPE_FC_GS (0x20)
+#define FNIC_FC_CS_CTL (0x00)
+
+#define FNIC_FC_FRAME_UNSOLICITED(_fchdr) \
+ (_fchdr->r_ctl == FNIC_FC_R_CTL_UNSOLICITED)
+#define FNIC_FC_FRAME_SOLICITED_DATA(_fchdr) \
+ (_fchdr->r_ctl == FNIC_FC_R_CTL_SOLICITED_DATA)
+#define FNIC_FC_FRAME_SOLICITED_CTRL_REPLY(_fchdr) \
+ (_fchdr->r_ctl == FNIC_FC_R_CTL_SOLICITED_CTRL_REPLY)
+#define FNIC_FC_FRAME_FCTL_LAST_END_SEQ(_fchdr) \
+ (_fchdr->f_ctl == FNIC_FC_F_CTL_LAST_END_SEQ)
+#define FNIC_FC_FRAME_FCTL_LAST_END_SEQ_INT(_fchdr) \
+ (_fchdr->f_ctl == FNIC_FC_F_CTL_LAST_END_SEQ_INT)
+#define FNIC_FC_FRAME_FCTL_FIRST_LAST_SEQINIT(_fchdr) \
+ (_fchdr->f_ctl == FNIC_FC_F_CTL_FIRST_LAST_SEQINIT)
+#define FNIC_FC_FRAME_FC4_SCTL(_fchdr) \
+ (_fchdr->r_ctl == FNIC_FC_R_CTL_FC4_SCTL)
+#define FNIC_FC_FRAME_TYPE_BLS(_fchdr) (_fchdr->type == FNIC_FC_TYPE_BLS)
+#define FNIC_FC_FRAME_TYPE_ELS(_fchdr) (_fchdr->type == FNIC_FC_TYPE_ELS)
+#define FNIC_FC_FRAME_TYPE_FC_GS(_fchdr) (_fchdr->type == FNIC_FC_TYPE_FC_GS)
+#define FNIC_FC_FRAME_CS_CTL(_fchdr) (_fchdr->cs_ctl == FNIC_FC_CS_CTL)
+
+#define FNIC_FC_C3_RDF (0xfff)
+#define FNIC_FC_PLOGI_RSP_RDF(_plogi_rsp) \
+ (MIN(_plogi_rsp->u.csp_plogi.b2b_rdf_size, \
+ (_plogi_rsp->spc3[4] & FNIC_FC_C3_RDF)))
+#define FNIC_FC_PLOGI_RSP_CONCUR_SEQ(_plogi_rsp) \
+ (MIN(_plogi_rsp->u.csp_plogi.total_concur_seqs, \
+ (uint8_t)(_plogi_rsp->spc3[10] & 0xff)))
+
+/* Frame header */
+
+struct fnic_eth_hdr_s {
+ uint8_t dst_mac[6];
+ uint8_t src_mac[6];
+ uint16_t ether_type;
+} __packed;
+
+struct fnic_fcoe_hdr_s {
+ uint8_t ver;
+ uint8_t rsvd[12];
+ uint8_t sof;
+} __packed;
+
+/* Big endian */
+struct fc_hdr_s {
+ uint8_t r_ctl;
+ uint8_t did[3];
+ uint8_t cs_ctl:8;
+ uint8_t sid[3];
+ uint32_t type:8;
+ uint32_t f_ctl:24;
+ uint8_t seq_id;
+ uint8_t df_ctl;
+ uint16_t seq_cnt;
+ uint16_t ox_id;
+ uint16_t rx_id;
+ uint32_t param;
+} __packed;
+
+struct fc_csp_flogi_s {
+ uint16_t fc_ph_ver;
+ uint16_t b2b_credits;
+ uint16_t features;
+ uint16_t b2b_rdf_size;
+ uint32_t r_a_tov;
+ uint32_t e_d_tov;
+} __packed;
+
+struct fc_csp_plogi_s {
+ uint16_t fc_ph_ver;
+ uint16_t b2b_credits;
+ uint16_t features;
+ uint16_t b2b_rdf_size;
+ uint16_t total_concur_seqs;
+ uint16_t ro_info;
+ uint32_t e_d_tov;
+} __packed;
+
+struct fc_els_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t rsvd[3];
+ union {
+ struct fc_csp_flogi_s csp_flogi;
+ struct fc_csp_plogi_s csp_plogi;
+ } u;
+ uint64_t nport_name;
+ uint64_t node_name;
+ uint8_t spc1[16];
+ uint8_t spc2[16];
+ uint8_t spc3[16];
+ uint8_t spc4[16];
+ uint8_t vendor_ver_level[16];
+} __packed;
+
+struct fc_els_acc_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t rsvd[3];
+} __packed;
+
+struct fc_els_reject_s {
+ struct fc_hdr_s fchdr;
+ uint32_t command;
+ uint8_t reserved;
+ uint8_t reason_code;
+ uint8_t reason_expl;
+ uint8_t vendor_specific;
+} __packed;
+
+struct fc_els_adisc_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t zeros[3];
+ uint32_t unused;
+ uint64_t nport_name;
+ uint64_t node_name;
+ uint8_t reserved;
+ uint8_t fcid[3];
+} __packed;
+
+struct fc_els_rls_ls_acc_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t reserved[3];
+ uint32_t link_fail_count; /* link failure count */
+ uint32_t sync_loss_count; /* loss of synchronization count */
+ uint32_t sig_loss_count; /* loss of signal count */
+ uint32_t prim_err_count; /* primitive sequence error count */
+ uint32_t inv_word_count; /* invalid transmission word count */
+ uint32_t inv_crc_count; /* invalid CRC count */
+} __packed;
+
+struct fc_els_adisc_ls_acc_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t zeros[3];
+ uint32_t unused;
+ uint64_t nport_name;
+ uint64_t node_name;
+ uint8_t reserved;
+ uint8_t fcid[3];
+} __packed;
+
+struct fc_abts_ba_acc_s {
+ struct fc_hdr_s fchdr;
+ uint8_t seq_id_validity;
+ uint8_t seq_id;
+ uint16_t reserved;
+ uint16_t ox_id;
+ uint16_t rx_id;
+ uint16_t low_seq_cnt;
+ uint16_t high_seq_cnt;
+} __packed;
+
+struct fc_abts_ba_rjt_s {
+ struct fc_hdr_s fchdr;
+ uint8_t vend_uniq;
+ uint8_t reason_explanation;
+ uint8_t reason_code;
+ uint8_t reserved;
+} __packed;
+
+struct fc_prli_sp_s {
+ uint8_t type;
+ uint8_t type_ext;
+ uint16_t flags;
+
+ uint32_t ox_proc_assoc;
+ uint32_t rx_proc_assoc;
+ uint32_t csp;
+} __packed;
+
+struct fc_els_prli_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t page_len;
+ uint16_t payload_len;
+ struct fc_prli_sp_s sp;
+} __packed;
+
+struct fc_ct_hdr_s {
+ uint32_t rev: 8;
+ uint32_t in_id: 24;
+ uint8_t fs_type;
+ uint8_t fs_subtype;
+ uint8_t options;
+ uint8_t rsvd;
+ uint16_t command;
+ uint16_t max_res_size;
+ uint8_t rsvd1;
+ uint8_t reason_code;
+ uint8_t reason_expl;
+ uint8_t vendor_specific;
+} __packed;
+
+struct fc_rpn_id_s {
+ struct fc_hdr_s fchdr;
+ struct fc_ct_hdr_s fc_ct_hdr;
+ uint8_t rsvd;
+ uint8_t port_id[3];
+ uint64_t port_name;
+} __packed;
+
+struct fc_fdmi_rhba_s {
+ struct fc_hdr_s fchdr;
+ struct fc_ct_hdr_s fc_ct_hdr;
+ uint64_t hba_identifier;
+ uint32_t num_ports;
+ uint64_t port_name;
+ uint32_t num_hba_attributes;
+ uint16_t type_nn;
+ uint16_t length_nn;
+ uint64_t node_name;
+ uint16_t type_manu;
+ uint16_t length_manu;
+ uint8_t manufacturer[20];
+ uint16_t type_serial;
+ uint16_t length_serial;
+ uint8_t serial_num[16];
+ uint16_t type_model;
+ uint16_t length_model;
+ uint8_t model[12];
+ uint16_t type_model_des;
+ uint16_t length_model_des;
+ uint8_t model_description[56];
+ uint16_t type_hw_ver;
+ uint16_t length_hw_ver;
+ uint8_t hardware_ver[16];
+ uint16_t type_dr_ver;
+ uint16_t length_dr_ver;
+ uint8_t driver_ver[28];
+ uint16_t type_rom_ver;
+ uint16_t length_rom_ver;
+ uint8_t rom_ver[8];
+ uint16_t type_fw_ver;
+ uint16_t length_fw_ver;
+ uint8_t firmware_ver[16];
+} __packed;
+
+struct fc_fdmi_rpa_s {
+ struct fc_hdr_s fchdr;
+ struct fc_ct_hdr_s fc_ct_hdr;
+ uint64_t port_name;
+ uint32_t num_port_attributes;
+ uint16_t type_fc4;
+ uint16_t length_fc4;
+ uint8_t fc4_type[32];
+ uint16_t type_supp_speed;
+ uint16_t length_supp_speed;
+ uint32_t supported_speed;
+ uint16_t type_cur_speed;
+ uint16_t length_cur_speed;
+ uint32_t current_speed;
+ uint16_t type_max_frame_size;
+ uint16_t length_max_frame_size;
+ uint32_t max_frame_size;
+ uint16_t type_os_name;
+ uint16_t length_os_name;
+ uint8_t os_name[16];
+ uint16_t type_host_name;
+ uint16_t length_host_name;
+ uint8_t host_name[12];
+} __packed;
+
+struct fc_rft_id {
+ struct fc_hdr_s fchdr;
+ struct fc_ct_hdr_s fc_ct_hdr;
+ uint8_t rsvd;
+ uint8_t port_id[3];
+ uint8_t fc4_types[32];
+} __packed;
+
+struct fc_rff_id {
+ struct fc_hdr_s fchdr;
+ struct fc_ct_hdr_s fc_ct_hdr;
+ uint8_t rsvd;
+ uint8_t port_id[3];
+ uint8_t rsvd1;
+ uint8_t rsvd2;
+ uint8_t tgt;
+ uint8_t fc4_type;
+} __packed;
+
+/*
+ * Variables:
+ * sid
+ */
+struct fc_gpn_ft_s {
+ struct fc_hdr_s fchdr;
+ struct fc_ct_hdr_s fc_ct_hdr;
+ uint8_t rsvd[3];
+ uint8_t fc4_type;
+} __packed;
+
+/* Accept CT_IU for GPN_FT */
+struct fc_gpn_ft_rsp_iu_s {
+ uint8_t ctrl;
+ uint8_t fcid[3];
+ uint32_t rsvd;
+ uint64_t wwpn;
+} __packed;
+
+/*
+ * Variables:
+ * sid
+ */
+struct fc_scr_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t rsvd[3];
+ uint8_t rsvd1[3];
+ uint8_t reg_func;
+} __packed;
+
+struct fc_rscn_hdr_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t page_len;
+ uint16_t payload_len;
+} __packed;
+
+
+struct fc_rscn_port_s {
+ uint8_t addr_format:2;
+ uint8_t rscn_evt_q:4;
+ uint8_t reserved:2;
+ uint8_t port_id[3];
+} __packed;
+
+struct fc_logo_req_s {
+ struct fc_hdr_s fchdr;
+ uint8_t command;
+ uint8_t rsvd[3];
+ uint8_t rsvd1;
+ uint8_t fcid[3];
+ uint64_t wwpn;
+} __packed;
+
+#define FNIC_FCOE_FCHDR_OFFSET \
+ (sizeof(struct fnic_eth_hdr_s) + sizeof(struct fnic_fcoe_hdr_s))
+
+#endif /* _FDLS_FC_H */
new file mode 100644
@@ -0,0 +1,350 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2007 Nuova Systems, Inc. All rights reserved.
+ */
+
+#ifndef _FNIC_FDLS_H_
+#define _FNIC_FDLS_H_
+
+#include "fnic_stats.h"
+#include "fdls_fc.h"
+
+/* FDLS - Fabric discovery and login services
+ * -> VLAN discovery
+ * -> retry every retry delay seconds until it succeeds.
+ * <- List of VLANs
+ *
+ * -> Solicitation
+ * <- Solicitation response (Advertisement)
+ *
+ * -> FCF selection & FLOGI ( FLOGI timeout - 2 * E_D_TOV)
+ * <- FLOGI response
+ *
+ * -> FCF keep alive
+ * <- FCF keep alive
+ *
+ * -> PLOGI to FFFFFC (DNS) (PLOGI timeout - 2 * R_A_TOV)
+ * -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
+ * <- PLOGI response
+ * -> Retry PLOGI to FFFFFC (DNS) - Number of retries from vnic.cfg
+ *
+ * -> SCR to FFFFFC (DNS) (SCR timeout - 2 * R_A_TOV)
+ * -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
+ * <- SCR response
+ * -> Retry SCR - Number of retries 2
+ *
+ * -> GPN_FT to FFFFFC (GPN_FT timeout - 2 * R_A_TOV)a
+ * -> Retry on BUSY until it succeeds
+ * -> Retry on BUSY until it succeeds
+ * -> 2 retries on timeout
+ *
+ * -> RFT_ID to FFFFFC (DNS) (RFT_ID timeout - 3 * R_A_TOV)
+ * -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
+ * -> Retry RFT_ID to FFFFFC (DNS) (Number of retries 2 )
+ * -> Ignore if both retires fail.
+ *
+ * Session establishment with targets
+ * For each PWWN
+ * -> PLOGI to FCID of that PWWN (PLOGI timeout 2 * R_A_TOV)
+ * -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
+ * <- PLOGI response
+ * -> Retry PLOGI. Num retries using vnic.cfg
+ *
+ * -> PRLI to FCID of that PWWN (PRLI timeout 2 * R_A_TOV)
+ * -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
+ * <- PRLI response
+ * -> Retry PRLI. Num retries using vnic.cfg
+ *
+ */
+
+#define FDLS_RETRY_COUNT 2
+
+#define FDLS_TGT_OXID_BLOCK_SZ (0x200)
+#define FDLS_PLOGI_OXID_BASE (0x2000)
+#define FDLS_PRLI_OXID_BASE (0x2200)
+#define FDLS_ADISC_OXID_BASE (0x2400)
+#define FDLS_TGT_OXID_POOL_END (FDLS_PLOGI_OXID_BASE + FDLS_TGT_OXID_POOL_SZ)
+#define FDLS_TGT_OXID_POOL_SZ (0x800)
+
+#define FNIC_FDLS_FABRIC_ABORT_ISSUED 0x1
+#define FNIC_FDLS_FPMA_LEARNT 0x2
+
+/* tport flags */
+#define FNIC_FDLS_TPORT_IN_GPN_FT_LIST 0x1
+#define FNIC_FDLS_TGT_ABORT_ISSUED 0x2
+#define FNIC_FDLS_TPORT_SEND_ADISC 0x4
+#define FNIC_FDLS_RETRY_FRAME 0x8
+#define FNIC_FDLS_TPORT_BUSY 0x10
+#define FNIC_FDLS_TPORT_TERMINATING 0x20
+#define FNIC_FDLS_TPORT_DELETED 0x40
+#define FNIC_FDLS_SCSI_REGISTERED 0x200
+#define FNIC_TPORT_CAN_BE_FREED 0x400
+
+/* Retry supported by rport(returned by prli service parameters) */
+#define FDLS_FC_RP_FLAGS_RETRY 0x1
+
+#define fdls_set_state(_fdls_fabric, _state) ((_fdls_fabric)->state = _state)
+#define fdls_get_state(_fdls_fabric) ((_fdls_fabric)->state)
+
+#define FNIC_FDMI_ACTIVE 0x8
+#define FNIC_FIRST_LINK_UP 0x2
+
+#define fdls_set_tport_state(_tport, _state) (_tport->state = _state)
+#define fdls_get_tport_state(_tport) (_tport->state)
+
+#define FNIC_PORTSPEED_10GBIT 1
+#define FNIC_FRAME_HT_ROOM (2148)
+#define FNIC_FCOE_FRAME_MAXSZ (2112)
+
+struct fnic_fip_fcf_s {
+ uint16_t vlan_id;
+ uint8_t fcf_mac[6];
+ uint8_t fcf_priority;
+ uint32_t fka_adv_period;
+ uint8_t ka_disabled;
+};
+
+enum fnic_fdls_state_e {
+ FDLS_STATE_INIT = 0,
+ FDLS_STATE_LINKDOWN,
+ FDLS_STATE_FABRIC_LOGO,
+ FDLS_STATE_FLOGO_DONE,
+ FDLS_STATE_FABRIC_FLOGI,
+ FDLS_STATE_FABRIC_PLOGI,
+ FDLS_STATE_RPN_ID,
+ FDLS_STATE_REGISTER_FC4_TYPES,
+ FDLS_STATE_REGISTER_FC4_FEATURES,
+ FDLS_STATE_SCR,
+ FDLS_STATE_GPN_FT,
+ FDLS_STATE_TGT_DISCOVERY,
+ FDLS_STATE_RSCN_GPN_FT,
+ FDLS_STATE_SEND_GPNFT
+};
+
+struct fnic_fdls_fabric_s {
+ enum fnic_fdls_state_e state;
+ uint32_t flags;
+ struct list_head tport_list; /* List of discovered tports */
+ struct timer_list retry_timer;
+ int del_timer_inprogress;
+ int del_fdmi_timer_inprogress;
+ int retry_counter;
+ int timer_pending;
+ int fdmi_retry;
+ struct timer_list fdmi_timer;
+ int fdmi_pending;
+};
+
+struct fnic_fdls_fip_s {
+ uint32_t state;
+ uint32_t flogi_retry;
+};
+
+/* Message to tport_event_handler */
+enum fnic_tgt_msg_id {
+ TGT_EV_NONE = 0,
+ TGT_EV_RPORT_ADD,
+ TGT_EV_RPORT_DEL,
+ TGT_EV_TPORT_DELETE,
+ TGT_EV_REMOVE
+};
+
+struct fnic_tport_event_s {
+ struct list_head links;
+ enum fnic_tgt_msg_id event;
+ void *arg1;
+};
+
+enum fdls_tgt_state_e {
+ FDLS_TGT_STATE_INIT = 0,
+ FDLS_TGT_STATE_PLOGI,
+ FDLS_TGT_STATE_PRLI,
+ FDLS_TGT_STATE_READY,
+ FDLS_TGT_STATE_LOGO_RECEIVED,
+ FDLS_TGT_STATE_ADISC,
+ FDL_TGT_STATE_PLOGO,
+ FDLS_TGT_STATE_OFFLINING,
+ FDLS_TGT_STATE_OFFLINE
+};
+
+struct fnic_tport_s {
+ struct list_head links; /* To link the tports */
+ enum fdls_tgt_state_e state;
+ uint32_t flags;
+ uint32_t fcid;
+ uint64_t wwpn;
+ uint64_t wwnn;
+ uint16_t oxid_used;
+ uint16_t tgt_flags;
+ atomic_t in_flight; /* io counter */
+ uint16_t max_payload_size;
+ uint16_t r_a_tov;
+ uint16_t e_d_tov;
+ uint16_t lun0_delay;
+ int max_concur_seqs;
+ uint32_t fcp_csp;
+ struct timer_list retry_timer;
+ int del_timer_inprogress;
+ int retry_counter;
+ int timer_pending;
+ unsigned int num_pending_cmds;
+ int nexus_restart_count;
+ int exch_reset_in_progress;
+ void *iport;
+ struct work_struct tport_del_work;
+ struct completion *tport_del_done;
+ struct delayed_work tport_scan_work;
+ struct fc_rport *rport;
+ char str_wwpn[20];
+ char str_wwnn[20];
+};
+
+/* iport */
+enum fnic_iport_state_e {
+ FNIC_IPORT_STATE_INIT = 0,
+ FNIC_IPORT_STATE_LINK_WAIT,
+ FNIC_IPORT_STATE_FIP,
+ FNIC_IPORT_STATE_FABRIC_DISC,
+ FNIC_IPORT_STATE_READY
+};
+
+struct fnic_iport_s {
+ enum fnic_iport_state_e state;
+ struct fnic *fnic;
+ uint64_t boot_time;
+ uint32_t flags;
+ int usefip;
+ uint8_t hwmac[6]; /* HW MAC Addr */
+ uint8_t fpma[6]; /* Fabric Provided MA */
+ uint8_t fcfmac[6]; /* MAC addr of Fabric */
+ uint16_t vlan_id;
+ uint32_t fcid;
+ uint8_t tgt_oxid_pool[FDLS_TGT_OXID_POOL_SZ];
+ struct fnic_fip_fcf_s selected_fcf;
+ struct fnic_fdls_fip_s fip;
+ struct fnic_fdls_fabric_s fabric;
+ struct list_head tport_list;
+ struct list_head tport_list_pending_del;
+ /* list of tports for which we are yet to send PLOGO */
+ struct list_head inprocess_tport_list;
+ struct list_head deleted_tport_list;
+ struct work_struct tport_event_work;
+ uint32_t e_d_tov; /* msec */
+ uint32_t r_a_tov; /* msec */
+ uint32_t link_supported_speeds;
+ uint32_t max_flogi_retries;
+ uint32_t max_plogi_retries;
+ uint32_t plogi_timeout;
+ uint32_t service_params;
+ uint64_t wwpn;
+ uint64_t wwnn;
+ uint16_t max_payload_size;
+ spinlock_t deleted_tport_lst_lock;
+ struct completion *flogi_reg_done;
+ char str_wwpn[20];
+ char str_wwnn[20];
+ };
+ struct rport_dd_data_s {
+ struct fnic_tport_s *tport;
+ struct fnic_iport_s *iport;
+};
+
+enum fnic_recv_frame_type_e {
+ FNIC_FABRIC_FLOGI_RSP = 0,
+ FNIC_FABRIC_PLOGI_RSP,
+ FNIC_FDMI_PLOGI_RSP,
+ FNIC_FABRIC_RPN_RSP,
+ FNIC_FABRIC_RFT_RSP,
+ FNIC_FABRIC_RFF_RSP,
+ FNIC_FABRIC_SCR_RSP,
+ FNIC_FABRIC_GPN_FT_RSP,
+ FNIC_TPORT_PLOGI_RSP,
+ FNIC_TPORT_PRLI_RSP,
+ FNIC_TPORT_ADISC_RSP,
+ FNIC_TPORT_LOGO_RSP,
+ FNIC_BLS_ABTS_REQ,
+ FNIC_FABRIC_LOGO_RSP,
+ FNIC_BLS_ABTS_RSP,
+ FNIC_ELS_PLOGI_REQ,
+ FNIC_ELS_RSCN_REQ,
+ FNIC_ELS_LOGO_REQ,
+ FNIC_ELS_ECHO_REQ,
+ FNIC_ELS_ADISC,
+ FNIC_ELS_RLS,
+ FNIC_ELS_UNSUPPORTED_REQ,
+ FNIC_ELS_RRQ,
+ FNIC_FDMI_RSP,
+};
+
+enum fnic_port_speeds {
+ DCEM_PORTSPEED_NONE = 0,
+ DCEM_PORTSPEED_1G = 1000,
+ DCEM_PORTSPEED_2G = 2000,
+ DCEM_PORTSPEED_4G = 4000,
+ DCEM_PORTSPEED_8G = 8000,
+ DCEM_PORTSPEED_10G = 10000,
+ DCEM_PORTSPEED_16G = 16000,
+ DCEM_PORTSPEED_20G = 20000,
+ DCEM_PORTSPEED_25G = 25000,
+ DCEM_PORTSPEED_32G = 32000,
+ DCEM_PORTSPEED_40G = 40000,
+ DCEM_PORTSPEED_4x10G = 41000,
+ DCEM_PORTSPEED_50G = 50000,
+ DCEM_PORTSPEED_64G = 64000,
+ DCEM_PORTSPEED_100G = 100000,
+ DCEM_PORTSPEED_128G = 128000,
+};
+
+/* Function Declarations */
+/* fdls_disc.c */
+void fnic_fdls_disc_init(struct fnic_iport_s *iport);
+void fnic_fdls_disc_start(struct fnic_iport_s *iport);
+void fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame, int len,
+ int fchdr_offset);
+void fnic_fdls_link_down(struct fnic_iport_s *iport);
+void fdls_init_tgt_oxid_pool(struct fnic_iport_s *iport);
+void fdls_tgt_logout(struct fnic_iport_s *iport, struct fnic_tport_s *tport);
+inline void fnic_del_fabric_timer_sync(struct fnic *fnic);
+inline void fnic_del_tport_timer_sync(struct fnic *fnic,
+ struct fnic_tport_s *tport);
+void fdls_fdmi_timer_callback(struct timer_list *t);
+
+/* fnic_fcs.c */
+void fnic_fdls_init(struct fnic *fnic, int usefip);
+void fnic_send_fcoe_frame(struct fnic_iport_s *iport, void *payload,
+ int payload_sz);
+
+int fnic_send_fip_frame(struct fnic_iport_s *iport,
+ void *payload, int payload_sz);
+void fnic_fdls_learn_fcoe_macs(struct fnic_iport_s *iport, void *rx_frame,
+ uint8_t *fcid);
+
+void fnic_fdls_add_tport(struct fnic_iport_s *iport,
+ struct fnic_tport_s *tport, unsigned long flags);
+void fnic_fdls_remove_tport(struct fnic_iport_s *iport,
+ struct fnic_tport_s *tport, unsigned long flags);
+
+/* fip.c */
+void fnic_fcoe_send_vlan_req(struct fnic *fnic);
+void fnic_common_fip_cleanup(struct fnic *fnic);
+int fdls_fip_recv_frame(struct fnic *fnic, void *frame);
+void fnic_handle_fcs_ka_timer(struct timer_list *t);
+void fnic_handle_enode_ka_timer(struct timer_list *t);
+void fnic_handle_vn_ka_timer(struct timer_list *t);
+void fnic_handle_fip_timer(struct timer_list *t);
+extern void fdls_fabric_timer_callback(struct timer_list *t);
+
+/* fnic_scsi.c */
+void fnic_scsi_fcpio_reset(struct fnic *fnic);
+extern void fdls_fabric_timer_callback(struct timer_list *t);
+void fnic_rport_exch_reset(struct fnic *fnic, u32 fcid);
+int fnic_fdls_register_portid(struct fnic_iport_s *iport, u32 port_id,
+ void *fp);
+struct fnic_tport_s *fnic_find_tport_by_fcid(struct fnic_iport_s *iport,
+ uint32_t fcid);
+struct fnic_tport_s *fnic_find_tport_by_wwpn(struct fnic_iport_s *iport,
+ uint64_t wwpn);
+
+#endif /* _FNIC_FDLS_H_ */
+