248 lines
9.8 KiB
C
248 lines
9.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Huawei Hifc PCI Express Linux driver
|
|
* Copyright(c) 2017 Huawei Technologies Co., Ltd
|
|
*
|
|
*/
|
|
|
|
#ifndef __HIFC_SERVICE_H__
|
|
#define __HIFC_SERVICE_H__
|
|
|
|
/* Send ElsCmnd or ElsRsp */
|
|
unsigned int hifc_send_els_cmnd(void *phba, struct unf_frame_pkg_s *v_pkg);
|
|
|
|
/* Send GsCmnd */
|
|
unsigned int hifc_send_gs_cmnd(void *v_hba, struct unf_frame_pkg_s *v_pkg);
|
|
|
|
/* Send BlsCmnd */
|
|
unsigned int hifc_send_bls_cmnd(void *v_hba, struct unf_frame_pkg_s *v_pkg);
|
|
|
|
/* Receive Frame from Root RQ */
|
|
unsigned int hifc_rcv_service_frame_from_rq(
|
|
struct hifc_hba_s *v_hba,
|
|
struct hifc_root_rq_info_s *rq_info,
|
|
struct hifc_root_rq_complet_info_s *v_complet_info,
|
|
unsigned short v_rcv_buf_num);
|
|
|
|
unsigned int hifc_rq_rcv_srv_err(struct hifc_hba_s *v_hba,
|
|
struct hifc_root_rq_complet_info_s *v_info);
|
|
|
|
unsigned int hifc_rq_rcv_els_rsp_sts(
|
|
struct hifc_hba_s *v_hba,
|
|
struct hifc_root_rq_complet_info_s *v_info);
|
|
|
|
/* Receive Frame from SCQ */
|
|
unsigned int hifc_rcv_scqe_entry_from_scq(void *v_hba, void *v_scqe,
|
|
unsigned int scq_idx);
|
|
|
|
/* FC txmfs */
|
|
#define HIFC_DEFAULT_TX_MAX_FREAM_SIZE 256
|
|
|
|
#define HIFC_FIRST_PKG_FLAG (1 << 0)
|
|
#define HIFC_LAST_PKG_FLAG (1 << 1)
|
|
|
|
#define HIFC_CHECK_IF_FIRST_PKG(pkg_flag) ((pkg_flag) & HIFC_FIRST_PKG_FLAG)
|
|
#define HIFC_CHECK_IF_LAST_PKG(pkg_flag) ((pkg_flag) & HIFC_LAST_PKG_FLAG)
|
|
|
|
#define HIFC_GET_SERVICE_TYPE(v_hba) 12
|
|
#define HIFC_GET_PACKET_TYPE(v_service_type) 1
|
|
#define HIFC_GET_PACKET_COS(v_service_type) 1
|
|
#define HIFC_GET_PRLI_PAYLOAD_LEN \
|
|
(UNF_PRLI_PAYLOAD_LEN - UNF_PRLI_SIRT_EXTRA_SIZE)
|
|
/* Start addr of the header/payloed of the cmnd buffer in the pkg */
|
|
#define HIFC_FC_HEAD_LEN (sizeof(struct unf_fchead_s))
|
|
#define HIFC_PAYLOAD_OFFSET (sizeof(struct unf_fchead_s))
|
|
#define HIFC_GET_CMND_PAYLOAD_ADDR(v_pkg) \
|
|
UNF_GET_FLOGI_PAYLOAD(v_pkg)
|
|
#define HIFC_GET_CMND_HEADER_ADDR(v_pkg) \
|
|
((v_pkg)->unf_cmnd_pload_bl.buffer_ptr)
|
|
#define HIFC_GET_RSP_HEADER_ADDR(v_pkg) \
|
|
((v_pkg)->unf_rsp_pload_bl.buffer_ptr)
|
|
#define HIFC_GET_RSP_PAYLOAD_ADDR(v_pkg) \
|
|
((v_pkg)->unf_rsp_pload_bl.buffer_ptr + HIFC_PAYLOAD_OFFSET)
|
|
#define HIFC_GET_CMND_FC_HEADER(v_pkg) \
|
|
(&(UNF_GET_SFS_ENTRY(v_pkg)->sfs_common.frame_head))
|
|
#define HIFC_PKG_IS_ELS_RSP(els_cmnd_type) \
|
|
(((els_cmnd_type) == ELS_ACC) || ((els_cmnd_type) == ELS_RJT))
|
|
#define HIFC_XID_IS_VALID(xid, exi_base, exi_count) \
|
|
(((xid) >= (exi_base)) && ((xid) < ((exi_base) + (exi_count))))
|
|
|
|
#define UNF_FC_PAYLOAD_ELS_MASK 0xFF000000
|
|
#define UNF_FC_PAYLOAD_ELS_SHIFT 24
|
|
#define UNF_FC_PAYLOAD_ELS_DWORD 0
|
|
|
|
/* Note: this pfcpayload is little endian */
|
|
#define UNF_GET_FC_PAYLOAD_ELS_CMND(pfcpayload) \
|
|
UNF_GET_SHIFTMASK(((unsigned int *)(void *)pfcpayload)\
|
|
[UNF_FC_PAYLOAD_ELS_DWORD], \
|
|
UNF_FC_PAYLOAD_ELS_SHIFT, UNF_FC_PAYLOAD_ELS_MASK)
|
|
|
|
#define HIFC_ELS_CMND_MASK 0xffff
|
|
#define HIFC_ELS_CMND__RELEVANT_SHIFT 16UL
|
|
#define HIFC_GET_ELS_CMND_CODE(__cmnd) \
|
|
((unsigned short)((__cmnd) & HIFC_ELS_CMND_MASK))
|
|
#define HIFC_GET_ELS_RSP_TYPE(__cmnd) \
|
|
((unsigned short)((__cmnd) & HIFC_ELS_CMND_MASK))
|
|
#define HIFC_GET_ELS_RSP_CODE(__cmnd) \
|
|
((unsigned short)((__cmnd) >> HIFC_ELS_CMND__RELEVANT_SHIFT & \
|
|
HIFC_ELS_CMND_MASK))
|
|
#define HIFC_GET_GS_CMND_CODE(__cmnd) \
|
|
((unsigned short)((__cmnd) & HIFC_ELS_CMND_MASK))
|
|
|
|
/* ELS CMND Request */
|
|
#define ELS_CMND 0
|
|
|
|
/* fh_f_ctl - Frame control flags. */
|
|
#define HIFC_FC_EX_CTX (1 << 23) /* sent by responder to exchange */
|
|
#define HIFC_FC_SEQ_CTX (1 << 22) /* sent by responder to sequence */
|
|
#define HIFC_FC_FIRST_SEQ (1 << 21) /* first sequence of this exchange */
|
|
#define HIFC_FC_LAST_SEQ (1 << 20) /* last sequence of this exchange */
|
|
#define HIFC_FC_END_SEQ (1 << 19) /* last frame of sequence */
|
|
#define HIFC_FC_END_CONN (1 << 18) /* end of class 1 connection pending */
|
|
#define HIFC_FC_RES_B17 (1 << 17) /* reserved */
|
|
#define HIFC_FC_SEQ_INIT (1 << 16) /* transfer of sequence initiative */
|
|
#define HIFC_FC_X_ID_REASS (1 << 15) /* exchange ID has been changed */
|
|
#define HIFC_FC_X_ID_INVAL (1 << 14) /* exchange ID invalidated */
|
|
#define HIFC_FC_ACK_1 (1 << 12) /* 13:12 = 1: ACK_1 expected */
|
|
#define HIFC_FC_ACK_N (2 << 12) /* 13:12 = 2: ACK_N expected */
|
|
#define HIFC_FC_ACK_0 (3 << 12) /* 13:12 = 3: ACK_0 expected */
|
|
#define HIFC_FC_RES_B11 (1 << 11) /* reserved */
|
|
#define HIFC_FC_RES_B10 (1 << 10) /* reserved */
|
|
#define HIFC_FC_RETX_SEQ (1 << 9) /* retransmitted sequence */
|
|
#define HIFC_FC_UNI_TX (1 << 8) /* unidirectional transmit (class 1) */
|
|
#define HIFC_FC_CONT_SEQ(i) ((i) << 6)
|
|
#define HIFC_FC_ABT_SEQ(i) ((i) << 4)
|
|
#define HIFC_FC_REL_OFF (1 << 3) /* parameter is relative offset */
|
|
#define HIFC_FC_RES2 (1 << 2) /* reserved */
|
|
#define HIFC_FC_FILL(i) ((i) & 3) /* 1:0: bytes of trailing fill */
|
|
|
|
#define HIFC_FCTL_REQ (HIFC_FC_FIRST_SEQ | HIFC_FC_END_SEQ |\
|
|
HIFC_FC_SEQ_INIT)
|
|
#define HIFC_FCTL_RESP (HIFC_FC_EX_CTX | HIFC_FC_LAST_SEQ | \
|
|
HIFC_FC_END_SEQ | HIFC_FC_SEQ_INIT)
|
|
#define HIFC_RCTL_BLS_REQ 0x81
|
|
#define HIFC_RCTL_BLS_ACC 0x84
|
|
#define HIFC_RCTL_BLS_RJT 0x85
|
|
|
|
#define UNF_IO_STATE_NEW 0
|
|
#define TGT_IO_STATE_SEND_XFERRDY (1 << 2)
|
|
#define TGT_IO_STATE_RSP (1 << 5)
|
|
#define TGT_IO_STATE_ABORT (1 << 7)
|
|
|
|
enum HIFC_FC_FH_TYPE_E {
|
|
HIFC_FC_TYPE_BLS = 0x00, /* basic link service */
|
|
HIFC_FC_TYPE_ELS = 0x01, /* extended link service */
|
|
HIFC_FC_TYPE_IP = 0x05, /* IP over FC, RFC 4338 */
|
|
HIFC_FC_TYPE_FCP = 0x08, /* SCSI FCP */
|
|
HIFC_FC_TYPE_CT = 0x20, /* Fibre Channel Services (FC-CT) */
|
|
HIFC_FC_TYPE_ILS = 0x22 /* internal link service */
|
|
};
|
|
|
|
enum HIFC_FC_FH_RCTL_E {
|
|
HIFC_FC_RCTL_DD_UNCAT = 0x00, /* uncategorized information */
|
|
HIFC_FC_RCTL_DD_SOL_DATA = 0x01, /* solicited data */
|
|
HIFC_FC_RCTL_DD_UNSOL_CTL = 0x02, /* unsolicited control */
|
|
HIFC_FC_RCTL_DD_SOL_CTL = 0x03, /* solicited control or reply */
|
|
HIFC_FC_RCTL_DD_UNSOL_DATA = 0x04, /* unsolicited data */
|
|
HIFC_FC_RCTL_DD_DATA_DESC = 0x05, /* data descriptor */
|
|
HIFC_FC_RCTL_DD_UNSOL_CMD = 0x06, /* unsolicited command */
|
|
HIFC_FC_RCTL_DD_CMD_STATUS = 0x07, /* command status */
|
|
|
|
#define HIFC_FC_RCTL_ILS_REQ HIFC_FC_RCTL_DD_UNSOL_CTL /* ILS request */
|
|
#define HIFC_FC_RCTL_ILS_REP HIFC_FC_RCTL_DD_SOL_CTL /* ILS reply */
|
|
|
|
/*
|
|
* Extended Link_Data
|
|
*/
|
|
HIFC_FC_RCTL_ELS_REQ = 0x22, /* extended link services request */
|
|
HIFC_FC_RCTL_ELS_RSP = 0x23, /* extended link services reply */
|
|
HIFC_FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */
|
|
HIFC_FC_RCTL_ELS4_RSP = 0x33, /* FC-4 ELS reply */
|
|
/*
|
|
* Optional Extended Headers
|
|
*/
|
|
HIFC_FC_RCTL_VFTH = 0x50, /* virtual fabric tagging header */
|
|
HIFC_FC_RCTL_IFRH = 0x51, /* inter-fabric routing header */
|
|
HIFC_FC_RCTL_ENCH = 0x52, /* encapsulation header */
|
|
/*
|
|
* Basic Link Services fh_r_ctl values.
|
|
*/
|
|
HIFC_FC_RCTL_BA_NOP = 0x80, /* basic link service NOP */
|
|
HIFC_FC_RCTL_BA_ABTS = 0x81, /* basic link service abort */
|
|
HIFC_FC_RCTL_BA_RMC = 0x82, /* remove connection */
|
|
HIFC_FC_RCTL_BA_ACC = 0x84, /* basic accept */
|
|
HIFC_FC_RCTL_BA_RJT = 0x85, /* basic reject */
|
|
HIFC_FC_RCTL_BA_PRMT = 0x86, /* dedicated connection preempted */
|
|
/*
|
|
* Link Control Information.
|
|
*/
|
|
HIFC_FC_RCTL_ACK_1 = 0xc0, /* acknowledge_1 */
|
|
HIFC_FC_RCTL_ACK_0 = 0xc1, /* acknowledge_0 */
|
|
HIFC_FC_RCTL_P_RJT = 0xc2, /* port reject */
|
|
HIFC_FC_RCTL_F_RJT = 0xc3, /* fabric reject */
|
|
HIFC_FC_RCTL_P_BSY = 0xc4, /* port busy */
|
|
HIFC_FC_RCTL_F_BSY = 0xc5, /* fabric busy to data frame */
|
|
HIFC_FC_RCTL_F_BSYL = 0xc6, /* fabric busy to link control frame */
|
|
HIFC_FC_RCTL_LCR = 0xc7, /* link credit reset */
|
|
HIFC_FC_RCTL_END = 0xc9 /* end */
|
|
};
|
|
|
|
struct hifc_fc_frame_header {
|
|
unsigned char rctl; /* routing control */
|
|
unsigned char did[3]; /* Destination ID */
|
|
|
|
unsigned char cs_ctl; /* class of service control / pri */
|
|
unsigned char sid[3]; /* Source ID */
|
|
|
|
unsigned char type; /* see enum fc_fh_type below */
|
|
unsigned char frame_ctl[3]; /* frame control */
|
|
|
|
unsigned char seq_id; /* sequence ID */
|
|
unsigned char df_ctl; /* data field control */
|
|
unsigned short seq_cnt; /* sequence count */
|
|
|
|
unsigned short ox_id; /* originator exchange ID */
|
|
unsigned short rx_id; /* responder exchange ID */
|
|
unsigned int parm_offset; /* parameter or relative offset */
|
|
};
|
|
|
|
unsigned int hifc_rcv_els_cmnd(const struct hifc_hba_s *v_hba,
|
|
struct unf_frame_pkg_s *v_pkg,
|
|
unsigned char *v_pld,
|
|
unsigned int pld_len,
|
|
int first_frame);
|
|
unsigned int hifc_rcv_els_rsp(const struct hifc_hba_s *v_hba,
|
|
struct unf_frame_pkg_s *v_pkg,
|
|
unsigned int ox_id);
|
|
unsigned int hifc_rcv_els_rsp_sts(const struct hifc_hba_s *v_hba,
|
|
struct unf_frame_pkg_s *v_pkg,
|
|
unsigned int rx_id);
|
|
unsigned int hifc_rcv_gs_rsp(const struct hifc_hba_s *v_hba,
|
|
struct unf_frame_pkg_s *v_pkg,
|
|
unsigned int ox_id);
|
|
unsigned int hifc_rcv_bls_rsp(const struct hifc_hba_s *v_hba,
|
|
struct unf_frame_pkg_s *v_pkg,
|
|
unsigned int ox_id);
|
|
|
|
void hifc_save_login_para_in_sq_info(
|
|
struct hifc_hba_s *v_hba,
|
|
struct unf_port_login_parms_s *v_login_coparms);
|
|
unsigned int hifc_handle_aeq_offload_err(struct hifc_hba_s *v_hba,
|
|
struct hifcoe_aqe_data_s *v_aeg_msg);
|
|
|
|
#define HIFC_CHECK_PKG_ALLOCTIME(v_pkg) \
|
|
do { \
|
|
if (unlikely(UNF_GETXCHGALLOCTIME(v_pkg) == 0)) { \
|
|
HIFC_TRACE(UNF_EVTLOG_DRIVER_WARN, UNF_LOG_NORMAL, \
|
|
UNF_WARN, \
|
|
"[warn]Invalid MagicNum,S_ID(0x%x) D_ID(0x%x) OXID(0x%x) RX_ID(0x%x) pkg type(0x%x) hot pooltag(0x%x)", \
|
|
UNF_GET_SID(v_pkg), \
|
|
UNF_GET_DID(v_pkg), \
|
|
UNF_GET_OXID(v_pkg), \
|
|
UNF_GET_RXID(v_pkg), \
|
|
((struct unf_frame_pkg_s *)v_pkg)->type, \
|
|
UNF_GET_XCHG_TAG(v_pkg)); \
|
|
} \
|
|
} while (0)
|
|
|
|
#endif
|