On 12/23/2016 08:17 PM, Dupuis, Chad wrote: > From: Arun Easi <arun.easi@xxxxxxxxxx> > > This adds the backbone required for the various HW initalizations > which are necessary for the FCoE driver (qedf) for QLogic FastLinQ > 4xxxx line of adapters - FW notification, resource initializations, etc. > > Signed-off-by: Arun Easi <arun.easi@xxxxxxxxxx> > Signed-off-by: Yuval Mintz <yuval.mintz@xxxxxxxxxx> > --- > drivers/net/ethernet/qlogic/Kconfig | 3 + > drivers/net/ethernet/qlogic/qed/Makefile | 1 + > drivers/net/ethernet/qlogic/qed/qed.h | 11 + > drivers/net/ethernet/qlogic/qed/qed_cxt.c | 98 ++- > drivers/net/ethernet/qlogic/qed/qed_cxt.h | 3 + > drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 11 + > drivers/net/ethernet/qlogic/qed/qed_dcbx.h | 1 + > drivers/net/ethernet/qlogic/qed/qed_dev.c | 205 ++++- > drivers/net/ethernet/qlogic/qed/qed_dev_api.h | 42 + > drivers/net/ethernet/qlogic/qed/qed_fcoe.c | 990 ++++++++++++++++++++++ > drivers/net/ethernet/qlogic/qed/qed_fcoe.h | 52 ++ > drivers/net/ethernet/qlogic/qed/qed_hsi.h | 781 ++++++++++++++++- > drivers/net/ethernet/qlogic/qed/qed_hw.c | 3 + > drivers/net/ethernet/qlogic/qed/qed_ll2.c | 25 + > drivers/net/ethernet/qlogic/qed/qed_ll2.h | 2 +- > drivers/net/ethernet/qlogic/qed/qed_main.c | 7 + > drivers/net/ethernet/qlogic/qed/qed_mcp.c | 3 + > drivers/net/ethernet/qlogic/qed/qed_mcp.h | 1 + > drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 8 + > drivers/net/ethernet/qlogic/qed/qed_sp.h | 4 + > drivers/net/ethernet/qlogic/qed/qed_sp_commands.c | 3 + > include/linux/qed/common_hsi.h | 10 +- > include/linux/qed/fcoe_common.h | 715 ++++++++++++++++ > include/linux/qed/qed_fcoe_if.h | 145 ++++ > include/linux/qed/qed_if.h | 39 + > 25 files changed, 3152 insertions(+), 11 deletions(-) > create mode 100644 drivers/net/ethernet/qlogic/qed/qed_fcoe.c > create mode 100644 drivers/net/ethernet/qlogic/qed/qed_fcoe.h > create mode 100644 include/linux/qed/fcoe_common.h > create mode 100644 include/linux/qed/qed_fcoe_if.h > > diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig > index 3cfd105..737b303 100644 > --- a/drivers/net/ethernet/qlogic/Kconfig > +++ b/drivers/net/ethernet/qlogic/Kconfig > @@ -113,4 +113,7 @@ config QED_RDMA > config QED_ISCSI > bool > > +config QED_FCOE > + bool > + > endif # NET_VENDOR_QLOGIC > diff --git a/drivers/net/ethernet/qlogic/qed/Makefile b/drivers/net/ethernet/qlogic/qed/Makefile > index 729e437..e234083 100644 > --- a/drivers/net/ethernet/qlogic/qed/Makefile > +++ b/drivers/net/ethernet/qlogic/qed/Makefile > @@ -7,3 +7,4 @@ qed-$(CONFIG_QED_SRIOV) += qed_sriov.o qed_vf.o > qed-$(CONFIG_QED_LL2) += qed_ll2.o > qed-$(CONFIG_QED_RDMA) += qed_roce.o > qed-$(CONFIG_QED_ISCSI) += qed_iscsi.o qed_ooo.o > +qed-$(CONFIG_QED_FCOE) += qed_fcoe.o > diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h > index 44c184e..cbb4ebc 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed.h > +++ b/drivers/net/ethernet/qlogic/qed/qed.h > @@ -36,6 +36,7 @@ > #define QED_WFQ_UNIT 100 > > #define ISCSI_BDQ_ID(_port_id) (_port_id) > +#define FCOE_BDQ_ID(_port_id) ((_port_id) + 2) > #define QED_WID_SIZE (1024) > #define QED_PF_DEMS_SIZE (4) > > @@ -143,6 +144,7 @@ struct qed_tunn_update_params { > */ > enum qed_pci_personality { > QED_PCI_ETH, > + QED_PCI_FCOE, > QED_PCI_ISCSI, > QED_PCI_ETH_ROCE, > QED_PCI_DEFAULT /* default in shmem */ > @@ -180,6 +182,7 @@ enum QED_FEATURE { > QED_VF, > QED_RDMA_CNQ, > QED_VF_L2_QUE, > + QED_FCOE_CQ, > QED_MAX_FEATURES, > }; > > @@ -197,6 +200,7 @@ enum QED_PORT_MODE { > > enum qed_dev_cap { > QED_DEV_CAP_ETH, > + QED_DEV_CAP_FCOE, > QED_DEV_CAP_ISCSI, > QED_DEV_CAP_ROCE, > }; > @@ -231,6 +235,10 @@ struct qed_hw_info { > u32 part_num[4]; > > unsigned char hw_mac_addr[ETH_ALEN]; > + u64 node_wwn; > + u64 port_wwn; > + > + u16 num_fcoe_conns; > > struct qed_igu_info *p_igu_info; > > @@ -386,6 +394,7 @@ struct qed_hwfn { > struct qed_ooo_info *p_ooo_info; > struct qed_rdma_info *p_rdma_info; > struct qed_iscsi_info *p_iscsi_info; > + struct qed_fcoe_info *p_fcoe_info; > struct qed_pf_params pf_params; > > bool b_rdma_enabled_in_prs; > @@ -594,11 +603,13 @@ struct qed_dev { > > u8 protocol; > #define IS_QED_ETH_IF(cdev) ((cdev)->protocol == QED_PROTOCOL_ETH) > +#define IS_QED_FCOE_IF(cdev) ((cdev)->protocol == QED_PROTOCOL_FCOE) > > /* Callbacks to protocol driver */ > union { > struct qed_common_cb_ops *common; > struct qed_eth_cb_ops *eth; > + struct qed_fcoe_cb_ops *fcoe; > struct qed_iscsi_cb_ops *iscsi; > } protocol_ops; > void *ops_cookie; > diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c > index 0c42c24..749bff4 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c > @@ -66,12 +66,14 @@ > struct core_conn_context core_ctx; > struct eth_conn_context eth_ctx; > struct iscsi_conn_context iscsi_ctx; > + struct fcoe_conn_context fcoe_ctx; > struct roce_conn_context roce_ctx; > }; > > -/* TYPE-0 task context - iSCSI */ > +/* TYPE-0 task context - iSCSI, FCOE */ > union type0_task_context { > struct iscsi_task_context iscsi_ctx; > + struct fcoe_task_context fcoe_ctx; > }; > > /* TYPE-1 task context - ROCE */ > @@ -216,15 +218,22 @@ struct qed_cxt_mngr { > static bool src_proto(enum protocol_type type) > { > return type == PROTOCOLID_ISCSI || > + type == PROTOCOLID_FCOE || > type == PROTOCOLID_ROCE; > } > > static bool tm_cid_proto(enum protocol_type type) > { > return type == PROTOCOLID_ISCSI || > + type == PROTOCOLID_FCOE || > type == PROTOCOLID_ROCE; > } > > +static bool tm_tid_proto(enum protocol_type type) > +{ > + return type == PROTOCOLID_FCOE; > +} > + > /* counts the iids for the CDU/CDUC ILT client configuration */ > struct qed_cdu_iids { > u32 pf_cids; > @@ -283,6 +292,22 @@ static void qed_cxt_tm_iids(struct qed_cxt_mngr *p_mngr, > iids->pf_cids += p_cfg->cid_count; > iids->per_vf_cids += p_cfg->cids_per_vf; > } > + > + if (tm_tid_proto(i)) { > + struct qed_tid_seg *segs = p_cfg->tid_seg; > + > + /* for each segment there is at most one > + * protocol for which count is not 0. > + */ > + for (j = 0; j < NUM_TASK_PF_SEGMENTS; j++) > + iids->pf_tids[j] += segs[j].count; > + > + /* The last array elelment is for the VFs. As for PF > + * segments there can be only one protocol for > + * which this value is not 0. > + */ > + iids->per_vf_tids += segs[NUM_TASK_PF_SEGMENTS].count; > + } > } > > iids->pf_cids = roundup(iids->pf_cids, TM_ALIGN); > @@ -1670,9 +1695,42 @@ static void qed_tm_init_pf(struct qed_hwfn *p_hwfn) > /* @@@TBD how to enable the scan for the VFs */ > } > > +static void qed_prs_init_common(struct qed_hwfn *p_hwfn) > +{ > + if ((p_hwfn->hw_info.personality == QED_PCI_FCOE) && > + p_hwfn->pf_params.fcoe_pf_params.is_target) > + STORE_RT_REG(p_hwfn, > + PRS_REG_SEARCH_RESP_INITIATOR_TYPE_RT_OFFSET, 0); > +} > + > +static void qed_prs_init_pf(struct qed_hwfn *p_hwfn) > +{ > + struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr; > + struct qed_conn_type_cfg *p_fcoe; > + struct qed_tid_seg *p_tid; > + > + p_fcoe = &p_mngr->conn_cfg[PROTOCOLID_FCOE]; > + > + /* If FCoE is active set the MAX OX_ID (tid) in the Parser */ > + if (!p_fcoe->cid_count) > + return; > + > + p_tid = &p_fcoe->tid_seg[QED_CXT_FCOE_TID_SEG]; > + if (p_hwfn->pf_params.fcoe_pf_params.is_target) { > + STORE_RT_REG_AGG(p_hwfn, > + PRS_REG_TASK_ID_MAX_TARGET_PF_RT_OFFSET, > + p_tid->count); > + } else { > + STORE_RT_REG_AGG(p_hwfn, > + PRS_REG_TASK_ID_MAX_INITIATOR_PF_RT_OFFSET, > + p_tid->count); > + } > +} > + > void qed_cxt_hw_init_common(struct qed_hwfn *p_hwfn) > { > qed_cdu_init_common(p_hwfn); > + qed_prs_init_common(p_hwfn); > } > > void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn) > @@ -1684,6 +1742,7 @@ void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn) > qed_ilt_init_pf(p_hwfn); > qed_src_init_pf(p_hwfn); > qed_tm_init_pf(p_hwfn); > + qed_prs_init_pf(p_hwfn); > } > > int qed_cxt_acquire_cid(struct qed_hwfn *p_hwfn, > @@ -1861,6 +1920,27 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn) > p_params->num_cons, 1); > break; > } > + case QED_PCI_FCOE: > + { > + struct qed_fcoe_pf_params *p_params; > + > + p_params = &p_hwfn->pf_params.fcoe_pf_params; > + > + if (p_params->num_cons && p_params->num_tasks) { > + qed_cxt_set_proto_cid_count(p_hwfn, > + PROTOCOLID_FCOE, > + p_params->num_cons, > + 0); > + > + qed_cxt_set_proto_tid_count(p_hwfn, PROTOCOLID_FCOE, > + QED_CXT_FCOE_TID_SEG, 0, > + p_params->num_tasks, true); > + } else { > + DP_INFO(p_hwfn->cdev, > + "Fcoe personality used without setting params!\n"); > + } > + break; > + } > case QED_PCI_ISCSI: > { > struct qed_iscsi_pf_params *p_params; > @@ -1903,6 +1983,10 @@ int qed_cxt_get_tid_mem_info(struct qed_hwfn *p_hwfn, > > /* Verify the personality */ > switch (p_hwfn->hw_info.personality) { > + case QED_PCI_FCOE: > + proto = PROTOCOLID_FCOE; > + seg = QED_CXT_FCOE_TID_SEG; > + break; > case QED_PCI_ISCSI: > proto = PROTOCOLID_ISCSI; > seg = QED_CXT_ISCSI_TID_SEG; > @@ -2191,15 +2275,19 @@ int qed_cxt_get_task_ctx(struct qed_hwfn *p_hwfn, > { > struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr; > struct qed_ilt_client_cfg *p_cli; > - struct qed_ilt_cli_blk *p_seg; > struct qed_tid_seg *p_seg_info; > - u32 proto, seg; > - u32 total_lines; > - u32 tid_size, ilt_idx; > + struct qed_ilt_cli_blk *p_seg; > u32 num_tids_per_block; > + u32 tid_size, ilt_idx; > + u32 total_lines; > + u32 proto, seg; > > /* Verify the personality */ > switch (p_hwfn->hw_info.personality) { > + case QED_PCI_FCOE: > + proto = PROTOCOLID_FCOE; > + seg = QED_CXT_FCOE_TID_SEG; > + break; > case QED_PCI_ISCSI: > proto = PROTOCOLID_ISCSI; > seg = QED_CXT_ISCSI_TID_SEG; > diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.h b/drivers/net/ethernet/qlogic/qed/qed_cxt.h > index 2b8bdaa..b45d9b0 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.h > @@ -67,6 +67,7 @@ int qed_cxt_get_tid_mem_info(struct qed_hwfn *p_hwfn, > > #define QED_CXT_ISCSI_TID_SEG PROTOCOLID_ISCSI > #define QED_CXT_ROCE_TID_SEG PROTOCOLID_ROCE > +#define QED_CXT_FCOE_TID_SEG PROTOCOLID_FCOE > enum qed_cxt_elem_type { > QED_ELEM_CXT, > QED_ELEM_SRQ, > @@ -180,4 +181,6 @@ u32 qed_cxt_get_proto_cid_start(struct qed_hwfn *p_hwfn, > > #define QED_CTX_WORKING_MEM 0 > #define QED_CTX_FL_MEM 1 > +int qed_cxt_get_task_ctx(struct qed_hwfn *p_hwfn, > + u32 tid, u8 ctx_type, void **task_ctx); > #endif > diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c > index a4789a9..965fe20 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c > @@ -840,6 +840,15 @@ static int qed_dcbx_read_mib(struct qed_hwfn *p_hwfn, > return rc; > } > > +void qed_dcbx_aen(struct qed_hwfn *hwfn, u32 mib_type) > +{ > + struct qed_common_cb_ops *op = hwfn->cdev->protocol_ops.common; > + void *cookie = hwfn->cdev->ops_cookie; > + > + if (cookie && op->dcbx_aen) > + op->dcbx_aen(cookie, &hwfn->p_dcbx_info->get, mib_type); > +} > + > /* Read updated MIB. > * Reconfigure QM and invoke PF update ramrod command if operational MIB > * change is detected. > @@ -866,6 +875,8 @@ static int qed_dcbx_read_mib(struct qed_hwfn *p_hwfn, > qed_sp_pf_update(p_hwfn); > } > } > + qed_dcbx_get_params(p_hwfn, p_ptt, &p_hwfn->p_dcbx_info->get, type); > + qed_dcbx_aen(p_hwfn, type); > > return rc; > } > diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h > index 9ba6816..511113c 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h > @@ -75,6 +75,7 @@ struct qed_dcbx_info { > struct dcbx_mib remote; > #ifdef CONFIG_DCB > struct qed_dcbx_set set; > + struct qed_dcbx_get get; > #endif > u8 dcbx_cap; > }; > diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c > index 3b22500..4218ddf 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c > @@ -25,6 +25,7 @@ > #include "qed_cxt.h" > #include "qed_dcbx.h" > #include "qed_dev_api.h" > +#include "qed_fcoe.h" > #include "qed_hsi.h" > #include "qed_hw.h" > #include "qed_init_ops.h" > @@ -148,6 +149,9 @@ void qed_resc_free(struct qed_dev *cdev) > #ifdef CONFIG_QED_LL2 > qed_ll2_free(p_hwfn, p_hwfn->p_ll2_info); > #endif > + if (p_hwfn->hw_info.personality == QED_PCI_FCOE) > + qed_fcoe_free(p_hwfn, p_hwfn->p_fcoe_info); > + > if (p_hwfn->hw_info.personality == QED_PCI_ISCSI) { > qed_iscsi_free(p_hwfn, p_hwfn->p_iscsi_info); > qed_ooo_free(p_hwfn, p_hwfn->p_ooo_info); > @@ -409,6 +413,7 @@ int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) > int qed_resc_alloc(struct qed_dev *cdev) > { > struct qed_iscsi_info *p_iscsi_info; > + struct qed_fcoe_info *p_fcoe_info; > struct qed_ooo_info *p_ooo_info; > #ifdef CONFIG_QED_LL2 > struct qed_ll2_info *p_ll2_info; > @@ -515,6 +520,14 @@ int qed_resc_alloc(struct qed_dev *cdev) > p_hwfn->p_ll2_info = p_ll2_info; > } > #endif > + > + if (p_hwfn->hw_info.personality == QED_PCI_FCOE) { > + p_fcoe_info = qed_fcoe_alloc(p_hwfn); > + if (!p_fcoe_info) > + goto alloc_no_mem; > + p_hwfn->p_fcoe_info = p_fcoe_info; > + } > + > if (p_hwfn->hw_info.personality == QED_PCI_ISCSI) { > p_iscsi_info = qed_iscsi_alloc(p_hwfn); > if (!p_iscsi_info) > @@ -578,6 +591,9 @@ void qed_resc_setup(struct qed_dev *cdev) > if (p_hwfn->using_ll2) > qed_ll2_setup(p_hwfn, p_hwfn->p_ll2_info); > #endif > + if (p_hwfn->hw_info.personality == QED_PCI_FCOE) > + qed_fcoe_setup(p_hwfn, p_hwfn->p_fcoe_info); > + > if (p_hwfn->hw_info.personality == QED_PCI_ISCSI) { > qed_iscsi_setup(p_hwfn, p_hwfn->p_iscsi_info); > qed_ooo_setup(p_hwfn, p_hwfn->p_ooo_info); > @@ -970,7 +986,8 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn, > /* Protocl Configuration */ > STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_TCP_RT_OFFSET, > (p_hwfn->hw_info.personality == QED_PCI_ISCSI) ? 1 : 0); > - STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_FCOE_RT_OFFSET, 0); > + STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_FCOE_RT_OFFSET, > + (p_hwfn->hw_info.personality == QED_PCI_FCOE) ? 1 : 0); > STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_ROCE_RT_OFFSET, 0); > > /* Cleanup chip from previous driver if such remains exist */ > @@ -1002,8 +1019,16 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn, > /* send function start command */ > rc = qed_sp_pf_start(p_hwfn, p_tunn, p_hwfn->cdev->mf_mode, > allow_npar_tx_switch); > - if (rc) > + if (rc) { > DP_NOTICE(p_hwfn, "Function start ramrod failed\n"); > + return rc; > + } > + if (p_hwfn->hw_info.personality == QED_PCI_FCOE) { > + qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_TAG1, BIT(2)); > + qed_wr(p_hwfn, p_ptt, > + PRS_REG_PKT_LEN_STAT_TAGS_NOT_COUNTED_FIRST, > + 0x100); > + } > } > return rc; > } > @@ -1763,8 +1788,8 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn) > > static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) > { > - u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg; > u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities; > + u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg; > struct qed_mcp_link_params *link; > > /* Read global nvm_cfg address */ > @@ -1910,6 +1935,9 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) > if (device_capabilities & NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ETHERNET) > __set_bit(QED_DEV_CAP_ETH, > &p_hwfn->hw_info.device_capabilities); > + if (device_capabilities & NVM_CFG1_GLOB_DEVICE_CAPABILITIES_FCOE) > + __set_bit(QED_DEV_CAP_FCOE, > + &p_hwfn->hw_info.device_capabilities); > if (device_capabilities & NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ISCSI) > __set_bit(QED_DEV_CAP_ISCSI, > &p_hwfn->hw_info.device_capabilities); > @@ -2647,6 +2675,177 @@ void qed_llh_remove_mac_filter(struct qed_hwfn *p_hwfn, > DP_NOTICE(p_hwfn, "Tried to remove a non-configured filter\n"); > } > > +int > +qed_llh_add_protocol_filter(struct qed_hwfn *p_hwfn, > + struct qed_ptt *p_ptt, > + u16 source_port_or_eth_type, > + u16 dest_port, enum qed_llh_port_filter_type_t type) > +{ > + u32 high = 0, low = 0, en; > + int i; > + > + if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn))) > + return 0; > + > + switch (type) { > + case QED_LLH_FILTER_ETHERTYPE: > + high = source_port_or_eth_type; > + break; > + case QED_LLH_FILTER_TCP_SRC_PORT: > + case QED_LLH_FILTER_UDP_SRC_PORT: > + low = source_port_or_eth_type << 16; > + break; > + case QED_LLH_FILTER_TCP_DEST_PORT: > + case QED_LLH_FILTER_UDP_DEST_PORT: > + low = dest_port; > + break; > + case QED_LLH_FILTER_TCP_SRC_AND_DEST_PORT: > + case QED_LLH_FILTER_UDP_SRC_AND_DEST_PORT: > + low = (source_port_or_eth_type << 16) | dest_port; > + break; > + default: > + DP_NOTICE(p_hwfn, > + "Non valid LLH protocol filter type %d\n", type); > + return -EINVAL; > + } > + /* Find a free entry and utilize it */ > + for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) { > + en = qed_rd(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32)); > + if (en) > + continue; > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_VALUE + > + 2 * i * sizeof(u32), low); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_VALUE + > + (2 * i + 1) * sizeof(u32), high); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32), 1); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE + > + i * sizeof(u32), 1 << type); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 1); > + break; > + } > + if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE) { > + DP_NOTICE(p_hwfn, > + "Failed to find an empty LLH filter to utilize\n"); > + return -EINVAL; > + } > + switch (type) { > + case QED_LLH_FILTER_ETHERTYPE: > + DP_VERBOSE(p_hwfn, NETIF_MSG_HW, > + "ETH type %x is added at %d\n", > + source_port_or_eth_type, i); > + break; > + case QED_LLH_FILTER_TCP_SRC_PORT: > + DP_VERBOSE(p_hwfn, NETIF_MSG_HW, > + "TCP src port %x is added at %d\n", > + source_port_or_eth_type, i); > + break; > + case QED_LLH_FILTER_UDP_SRC_PORT: > + DP_VERBOSE(p_hwfn, NETIF_MSG_HW, > + "UDP src port %x is added at %d\n", > + source_port_or_eth_type, i); > + break; > + case QED_LLH_FILTER_TCP_DEST_PORT: > + DP_VERBOSE(p_hwfn, NETIF_MSG_HW, > + "TCP dst port %x is added at %d\n", dest_port, i); > + break; > + case QED_LLH_FILTER_UDP_DEST_PORT: > + DP_VERBOSE(p_hwfn, NETIF_MSG_HW, > + "UDP dst port %x is added at %d\n", dest_port, i); > + break; > + case QED_LLH_FILTER_TCP_SRC_AND_DEST_PORT: > + DP_VERBOSE(p_hwfn, NETIF_MSG_HW, > + "TCP src/dst ports %x/%x are added at %d\n", > + source_port_or_eth_type, dest_port, i); > + break; > + case QED_LLH_FILTER_UDP_SRC_AND_DEST_PORT: > + DP_VERBOSE(p_hwfn, NETIF_MSG_HW, > + "UDP src/dst ports %x/%x are added at %d\n", > + source_port_or_eth_type, dest_port, i); > + break; > + } > + return 0; > +} > + > +void > +qed_llh_remove_protocol_filter(struct qed_hwfn *p_hwfn, > + struct qed_ptt *p_ptt, > + u16 source_port_or_eth_type, > + u16 dest_port, > + enum qed_llh_port_filter_type_t type) > +{ > + u32 high = 0, low = 0; > + int i; > + > + if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn))) > + return; > + > + switch (type) { > + case QED_LLH_FILTER_ETHERTYPE: > + high = source_port_or_eth_type; > + break; > + case QED_LLH_FILTER_TCP_SRC_PORT: > + case QED_LLH_FILTER_UDP_SRC_PORT: > + low = source_port_or_eth_type << 16; > + break; > + case QED_LLH_FILTER_TCP_DEST_PORT: > + case QED_LLH_FILTER_UDP_DEST_PORT: > + low = dest_port; > + break; > + case QED_LLH_FILTER_TCP_SRC_AND_DEST_PORT: > + case QED_LLH_FILTER_UDP_SRC_AND_DEST_PORT: > + low = (source_port_or_eth_type << 16) | dest_port; > + break; > + default: > + DP_NOTICE(p_hwfn, > + "Non valid LLH protocol filter type %d\n", type); > + return; > + } > + > + for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) { > + if (!qed_rd(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32))) > + continue; > + if (!qed_rd(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32))) > + continue; > + if (!(qed_rd(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE + > + i * sizeof(u32)) & BIT(type))) > + continue; > + if (qed_rd(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_VALUE + > + 2 * i * sizeof(u32)) != low) > + continue; > + if (qed_rd(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_VALUE + > + (2 * i + 1) * sizeof(u32)) != high) > + continue; > + > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 0); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32), 0); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE + > + i * sizeof(u32), 0); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_VALUE + 2 * i * sizeof(u32), 0); > + qed_wr(p_hwfn, p_ptt, > + NIG_REG_LLH_FUNC_FILTER_VALUE + > + (2 * i + 1) * sizeof(u32), 0); > + break; > + } > + > + if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE) > + DP_NOTICE(p_hwfn, "Tried to remove a non-configured filter\n"); > +} > + > static int qed_set_coalesce(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, > u32 hw_addr, void *p_eth_qzone, > size_t eth_qzone_size, u8 timeset) > diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h > index b6711c1..e3affbc 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h > @@ -329,6 +329,48 @@ int qed_llh_add_mac_filter(struct qed_hwfn *p_hwfn, > void qed_llh_remove_mac_filter(struct qed_hwfn *p_hwfn, > struct qed_ptt *p_ptt, u8 *p_filter); > > +enum qed_llh_port_filter_type_t { > + QED_LLH_FILTER_ETHERTYPE, > + QED_LLH_FILTER_TCP_SRC_PORT, > + QED_LLH_FILTER_TCP_DEST_PORT, > + QED_LLH_FILTER_TCP_SRC_AND_DEST_PORT, > + QED_LLH_FILTER_UDP_SRC_PORT, > + QED_LLH_FILTER_UDP_DEST_PORT, > + QED_LLH_FILTER_UDP_SRC_AND_DEST_PORT > +}; > + > +/** > + * @brief qed_llh_add_protocol_filter - configures a protocol filter in llh > + * > + * @param p_hwfn > + * @param p_ptt > + * @param source_port_or_eth_type - source port or ethertype to add > + * @param dest_port - destination port to add > + * @param type - type of filters and comparing > + */ > +int > +qed_llh_add_protocol_filter(struct qed_hwfn *p_hwfn, > + struct qed_ptt *p_ptt, > + u16 source_port_or_eth_type, > + u16 dest_port, > + enum qed_llh_port_filter_type_t type); > + > +/** > + * @brief qed_llh_remove_protocol_filter - remove a protocol filter in llh > + * > + * @param p_hwfn > + * @param p_ptt > + * @param source_port_or_eth_type - source port or ethertype to add > + * @param dest_port - destination port to add > + * @param type - type of filters and comparing > + */ > +void > +qed_llh_remove_protocol_filter(struct qed_hwfn *p_hwfn, > + struct qed_ptt *p_ptt, > + u16 source_port_or_eth_type, > + u16 dest_port, > + enum qed_llh_port_filter_type_t type); > + > /** > * *@brief Cleanup of previous driver remains prior to load > * > diff --git a/drivers/net/ethernet/qlogic/qed/qed_fcoe.c b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c > new file mode 100644 > index 0000000..5118fcaf > --- /dev/null > +++ b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c > @@ -0,0 +1,990 @@ > +/* QLogic qed NIC Driver > + * Copyright (c) 2016 QLogic Corporation > + * > + * This software is available under the terms of the GNU General Public License > + * (GPL) Version 2, available from the file COPYING in the main directory of > + * this source tree. > + */ > + > +#include <linux/types.h> > +#include <asm/byteorder.h> > +#include <asm/param.h> > +#include <linux/delay.h> > +#include <linux/dma-mapping.h> > +#include <linux/interrupt.h> > +#include <linux/kernel.h> > +#include <linux/log2.h> > +#include <linux/module.h> > +#include <linux/pci.h> > +#include <linux/slab.h> > +#include <linux/stddef.h> > +#include <linux/string.h> > +#include <linux/version.h> > +#include <linux/workqueue.h> > +#include <linux/errno.h> > +#include <linux/list.h> > +#include <linux/spinlock.h> > +#define __PREVENT_DUMP_MEM_ARR__ > +#define __PREVENT_PXP_GLOBAL_WIN__ > +#include "qed.h" > +#include "qed_cxt.h" > +#include "qed_dev_api.h" > +#include "qed_fcoe.h" > +#include "qed_hsi.h" > +#include "qed_hw.h" > +#include "qed_int.h" > +#include "qed_ll2.h" > +#include "qed_mcp.h" > +#include "qed_reg_addr.h" > +#include "qed_sp.h" > +#include "qed_sriov.h" > +#include <linux/qed/qed_fcoe_if.h> > + > +struct qed_fcoe_conn { > + struct list_head list_entry; > + bool free_on_delete; > + > + u16 conn_id; > + u32 icid; > + u32 fw_cid; > + u8 layer_code; > + > + dma_addr_t sq_pbl_addr; > + dma_addr_t sq_curr_page_addr; > + dma_addr_t sq_next_page_addr; > + dma_addr_t xferq_pbl_addr; > + void *xferq_pbl_addr_virt_addr; > + dma_addr_t xferq_addr[4]; > + void *xferq_addr_virt_addr[4]; > + dma_addr_t confq_pbl_addr; > + void *confq_pbl_addr_virt_addr; > + dma_addr_t confq_addr[2]; > + void *confq_addr_virt_addr[2]; > + > + dma_addr_t terminate_params; > + > + u16 dst_mac_addr_lo; > + u16 dst_mac_addr_mid; > + u16 dst_mac_addr_hi; > + u16 src_mac_addr_lo; > + u16 src_mac_addr_mid; > + u16 src_mac_addr_hi; > + > + u16 tx_max_fc_pay_len; > + u16 e_d_tov_timer_val; > + u16 rec_tov_timer_val; > + u16 rx_max_fc_pay_len; > + u16 vlan_tag; > + u16 physical_q0; > + > + struct fc_addr_nw s_id; > + u8 max_conc_seqs_c3; > + struct fc_addr_nw d_id; > + u8 flags; > + u8 def_q_idx; > +}; > + > +static int > +qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn, > + enum spq_mode comp_mode, > + struct qed_spq_comp_cb *p_comp_addr) > +{ > + struct qed_fcoe_pf_params *fcoe_pf_params = NULL; > + struct fcoe_init_ramrod_params *p_ramrod = NULL; > + struct fcoe_conn_context *p_cxt = NULL; > + struct qed_spq_entry *p_ent = NULL; > + struct fcoe_init_func_ramrod_data *p_data; > + int rc = 0; > + struct qed_sp_init_data init_data; > + struct qed_cxt_info cxt_info; > + u32 dummy_cid; > + u16 tmp; > + u8 i; > + > + /* Get SPQ entry */ > + memset(&init_data, 0, sizeof(init_data)); > + init_data.cid = qed_spq_get_cid(p_hwfn); > + init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; > + init_data.comp_mode = comp_mode; > + init_data.p_comp_data = p_comp_addr; > + > + rc = qed_sp_init_request(p_hwfn, &p_ent, > + FCOE_RAMROD_CMD_ID_INIT_FUNC, > + PROTOCOLID_FCOE, &init_data); > + if (rc) > + return rc; > + > + p_ramrod = &p_ent->ramrod.fcoe_init; > + p_data = &p_ramrod->init_ramrod_data; > + fcoe_pf_params = &p_hwfn->pf_params.fcoe_pf_params; > + > + p_data->mtu = cpu_to_le16(fcoe_pf_params->mtu); > + tmp = cpu_to_le16(fcoe_pf_params->sq_num_pbl_pages); > + p_data->sq_num_pages_in_pbl = tmp; > + > + rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &dummy_cid); > + if (rc) > + return rc; > + > + cxt_info.iid = dummy_cid; > + rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info); > + if (rc) { > + DP_NOTICE(p_hwfn, "Cannot find context info for dummy cid=%d\n", > + dummy_cid); > + return rc; > + } > + p_cxt = cxt_info.p_cxt; > + SET_FIELD(p_cxt->tstorm_ag_context.flags3, > + TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN, 1); > + > + fcoe_pf_params->dummy_icid = (u16)dummy_cid; > + > + tmp = cpu_to_le16(fcoe_pf_params->num_tasks); > + p_data->func_params.num_tasks = tmp; > + p_data->func_params.log_page_size = fcoe_pf_params->log_page_size; > + p_data->func_params.debug_mode = fcoe_pf_params->debug_mode; > + > + DMA_REGPAIR_LE(p_data->q_params.glbl_q_params_addr, > + fcoe_pf_params->glbl_q_params_addr); > + > + tmp = cpu_to_le16(fcoe_pf_params->cq_num_entries); > + p_data->q_params.cq_num_entries = tmp; > + > + tmp = cpu_to_le16(fcoe_pf_params->cmdq_num_entries); > + p_data->q_params.cmdq_num_entries = tmp; > + > + tmp = fcoe_pf_params->num_cqs; > + p_data->q_params.num_queues = (u8)tmp; > + > + tmp = (u16)p_hwfn->hw_info.resc_start[QED_CMDQS_CQS]; > + p_data->q_params.queue_relative_offset = (u8)tmp; > + > + for (i = 0; i < fcoe_pf_params->num_cqs; i++) { > + tmp = cpu_to_le16(p_hwfn->sbs_info[i]->igu_sb_id); > + p_data->q_params.cq_cmdq_sb_num_arr[i] = tmp; > + } > + > + p_data->q_params.cq_sb_pi = fcoe_pf_params->gl_rq_pi; > + p_data->q_params.cmdq_sb_pi = fcoe_pf_params->gl_cmd_pi; > + > + p_data->q_params.bdq_resource_id = FCOE_BDQ_ID(p_hwfn->port_id); > + > + DMA_REGPAIR_LE(p_data->q_params.bdq_pbl_base_address[BDQ_ID_RQ], > + fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_RQ]); > + p_data->q_params.bdq_pbl_num_entries[BDQ_ID_RQ] = > + fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_RQ]; > + tmp = fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_RQ]; > + p_data->q_params.bdq_xoff_threshold[BDQ_ID_RQ] = cpu_to_le16(tmp); > + tmp = fcoe_pf_params->bdq_xon_threshold[BDQ_ID_RQ]; > + p_data->q_params.bdq_xon_threshold[BDQ_ID_RQ] = cpu_to_le16(tmp); > + > + DMA_REGPAIR_LE(p_data->q_params.bdq_pbl_base_address[BDQ_ID_IMM_DATA], > + fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_IMM_DATA]); > + p_data->q_params.bdq_pbl_num_entries[BDQ_ID_IMM_DATA] = > + fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_IMM_DATA]; > + tmp = fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_IMM_DATA]; > + p_data->q_params.bdq_xoff_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(tmp); > + tmp = fcoe_pf_params->bdq_xon_threshold[BDQ_ID_IMM_DATA]; > + p_data->q_params.bdq_xon_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(tmp); > + tmp = fcoe_pf_params->rq_buffer_size; > + p_data->q_params.rq_buffer_size = cpu_to_le16(tmp); > + > + if (fcoe_pf_params->is_target) { > + SET_FIELD(p_data->q_params.q_validity, > + SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1); > + if (p_data->q_params.bdq_pbl_num_entries[BDQ_ID_IMM_DATA]) > + SET_FIELD(p_data->q_params.q_validity, > + SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID, 1); > + SET_FIELD(p_data->q_params.q_validity, > + SCSI_INIT_FUNC_QUEUES_CMD_VALID, 1); > + } else { > + SET_FIELD(p_data->q_params.q_validity, > + SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1); > + } > + > + rc = qed_spq_post(p_hwfn, p_ent, NULL); > + > + return rc; > +} > + > +static int > +qed_sp_fcoe_conn_offload(struct qed_hwfn *p_hwfn, > + struct qed_fcoe_conn *p_conn, > + enum spq_mode comp_mode, > + struct qed_spq_comp_cb *p_comp_addr) > +{ > + struct fcoe_conn_offload_ramrod_params *p_ramrod = NULL; > + struct fcoe_conn_offload_ramrod_data *p_data; > + struct qed_spq_entry *p_ent = NULL; > + struct qed_sp_init_data init_data; > + u16 pq_id = 0, tmp; > + int rc; > + > + /* Get SPQ entry */ > + memset(&init_data, 0, sizeof(init_data)); > + init_data.cid = p_conn->icid; > + init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; > + init_data.comp_mode = comp_mode; > + init_data.p_comp_data = p_comp_addr; > + > + rc = qed_sp_init_request(p_hwfn, &p_ent, > + FCOE_RAMROD_CMD_ID_OFFLOAD_CONN, > + PROTOCOLID_FCOE, &init_data); > + if (rc) > + return rc; > + > + p_ramrod = &p_ent->ramrod.fcoe_conn_ofld; > + p_data = &p_ramrod->offload_ramrod_data; > + > + /* Transmission PQ is the first of the PF */ > + pq_id = qed_get_qm_pq(p_hwfn, PROTOCOLID_FCOE, NULL); > + p_conn->physical_q0 = cpu_to_le16(pq_id); > + p_data->physical_q0 = cpu_to_le16(pq_id); > + > + p_data->conn_id = cpu_to_le16(p_conn->conn_id); > + DMA_REGPAIR_LE(p_data->sq_pbl_addr, p_conn->sq_pbl_addr); > + DMA_REGPAIR_LE(p_data->sq_curr_page_addr, p_conn->sq_curr_page_addr); > + DMA_REGPAIR_LE(p_data->sq_next_page_addr, p_conn->sq_next_page_addr); > + DMA_REGPAIR_LE(p_data->xferq_pbl_addr, p_conn->xferq_pbl_addr); > + DMA_REGPAIR_LE(p_data->xferq_curr_page_addr, p_conn->xferq_addr[0]); > + DMA_REGPAIR_LE(p_data->xferq_next_page_addr, p_conn->xferq_addr[1]); > + > + DMA_REGPAIR_LE(p_data->respq_pbl_addr, p_conn->confq_pbl_addr); > + DMA_REGPAIR_LE(p_data->respq_curr_page_addr, p_conn->confq_addr[0]); > + DMA_REGPAIR_LE(p_data->respq_next_page_addr, p_conn->confq_addr[1]); > + > + p_data->dst_mac_addr_lo = cpu_to_le16(p_conn->dst_mac_addr_lo); > + p_data->dst_mac_addr_mid = cpu_to_le16(p_conn->dst_mac_addr_mid); > + p_data->dst_mac_addr_hi = cpu_to_le16(p_conn->dst_mac_addr_hi); > + p_data->src_mac_addr_lo = cpu_to_le16(p_conn->src_mac_addr_lo); > + p_data->src_mac_addr_mid = cpu_to_le16(p_conn->src_mac_addr_mid); > + p_data->src_mac_addr_hi = cpu_to_le16(p_conn->src_mac_addr_hi); > + > + tmp = cpu_to_le16(p_conn->tx_max_fc_pay_len); > + p_data->tx_max_fc_pay_len = tmp; > + tmp = cpu_to_le16(p_conn->e_d_tov_timer_val); > + p_data->e_d_tov_timer_val = tmp; > + tmp = cpu_to_le16(p_conn->rec_tov_timer_val); > + p_data->rec_rr_tov_timer_val = tmp; > + tmp = cpu_to_le16(p_conn->rx_max_fc_pay_len); > + p_data->rx_max_fc_pay_len = tmp; > + > + p_data->vlan_tag = cpu_to_le16(p_conn->vlan_tag); > + p_data->s_id.addr_hi = p_conn->s_id.addr_hi; > + p_data->s_id.addr_mid = p_conn->s_id.addr_mid; > + p_data->s_id.addr_lo = p_conn->s_id.addr_lo; > + p_data->max_conc_seqs_c3 = p_conn->max_conc_seqs_c3; > + p_data->d_id.addr_hi = p_conn->d_id.addr_hi; > + p_data->d_id.addr_mid = p_conn->d_id.addr_mid; > + p_data->d_id.addr_lo = p_conn->d_id.addr_lo; > + p_data->flags = p_conn->flags; > + p_data->def_q_idx = p_conn->def_q_idx; > + > + return qed_spq_post(p_hwfn, p_ent, NULL); > +} > + > +static int > +qed_sp_fcoe_conn_destroy(struct qed_hwfn *p_hwfn, > + struct qed_fcoe_conn *p_conn, > + enum spq_mode comp_mode, > + struct qed_spq_comp_cb *p_comp_addr) > +{ > + struct fcoe_conn_terminate_ramrod_params *p_ramrod = NULL; > + struct qed_spq_entry *p_ent = NULL; > + struct qed_sp_init_data init_data; > + int rc = 0; > + > + /* Get SPQ entry */ > + memset(&init_data, 0, sizeof(init_data)); > + init_data.cid = p_conn->icid; > + init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; > + init_data.comp_mode = comp_mode; > + init_data.p_comp_data = p_comp_addr; > + > + rc = qed_sp_init_request(p_hwfn, &p_ent, > + FCOE_RAMROD_CMD_ID_TERMINATE_CONN, > + PROTOCOLID_FCOE, &init_data); > + if (rc) > + return rc; > + > + p_ramrod = &p_ent->ramrod.fcoe_conn_terminate; > + DMA_REGPAIR_LE(p_ramrod->terminate_ramrod_data.terminate_params_addr, > + p_conn->terminate_params); > + > + return qed_spq_post(p_hwfn, p_ent, NULL); > +} > + > +static int > +qed_sp_fcoe_func_stop(struct qed_hwfn *p_hwfn, > + enum spq_mode comp_mode, > + struct qed_spq_comp_cb *p_comp_addr) > +{ > + struct qed_ptt *p_ptt = p_hwfn->p_main_ptt; > + struct qed_spq_entry *p_ent = NULL; > + struct qed_sp_init_data init_data; > + u32 active_segs = 0; > + int rc = 0; > + > + /* Get SPQ entry */ > + memset(&init_data, 0, sizeof(init_data)); > + init_data.cid = p_hwfn->pf_params.fcoe_pf_params.dummy_icid; > + init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; > + init_data.comp_mode = comp_mode; > + init_data.p_comp_data = p_comp_addr; > + > + rc = qed_sp_init_request(p_hwfn, &p_ent, > + FCOE_RAMROD_CMD_ID_DESTROY_FUNC, > + PROTOCOLID_FCOE, &init_data); > + if (rc) > + return rc; > + > + active_segs = qed_rd(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK); > + active_segs &= ~BIT(QED_CXT_FCOE_TID_SEG); > + qed_wr(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK, active_segs); > + > + return qed_spq_post(p_hwfn, p_ent, NULL); > +} > + > +static int > +qed_fcoe_allocate_connection(struct qed_hwfn *p_hwfn, > + struct qed_fcoe_conn **p_out_conn) > +{ > + struct qed_fcoe_conn *p_conn = NULL; > + void *p_addr; > + u32 i; > + > + spin_lock_bh(&p_hwfn->p_fcoe_info->lock); > + if (!list_empty(&p_hwfn->p_fcoe_info->free_list)) > + p_conn = > + list_first_entry(&p_hwfn->p_fcoe_info->free_list, > + struct qed_fcoe_conn, list_entry); > + if (p_conn) { > + list_del(&p_conn->list_entry); > + spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); > + *p_out_conn = p_conn; > + return 0; > + } > + spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); > + > + p_conn = kzalloc(sizeof(*p_conn), GFP_KERNEL); > + if (!p_conn) > + return -ENOMEM; > + > + p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + &p_conn->xferq_pbl_addr, GFP_KERNEL); > + if (!p_addr) > + goto nomem_pbl_xferq; > + p_conn->xferq_pbl_addr_virt_addr = p_addr; > + > + for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) { > + p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + &p_conn->xferq_addr[i], GFP_KERNEL); > + if (!p_addr) > + goto nomem_xferq; > + p_conn->xferq_addr_virt_addr[i] = p_addr; > + > + p_addr = p_conn->xferq_pbl_addr_virt_addr; > + ((dma_addr_t *)p_addr)[i] = p_conn->xferq_addr[i]; > + } > + > + p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + &p_conn->confq_pbl_addr, GFP_KERNEL); > + if (!p_addr) > + goto nomem_xferq; > + p_conn->confq_pbl_addr_virt_addr = p_addr; > + > + for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) { > + p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + &p_conn->confq_addr[i], GFP_KERNEL); > + if (!p_addr) > + goto nomem_confq; > + p_conn->confq_addr_virt_addr[i] = p_addr; > + > + p_addr = p_conn->confq_pbl_addr_virt_addr; > + ((dma_addr_t *)p_addr)[i] = p_conn->confq_addr[i]; > + } > + > + p_conn->free_on_delete = true; > + *p_out_conn = p_conn; > + return 0; > + > +nomem_confq: > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->confq_pbl_addr_virt_addr, > + p_conn->confq_pbl_addr); > + for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) > + if (p_conn->confq_addr_virt_addr[i]) > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->confq_addr_virt_addr[i], > + p_conn->confq_addr[i]); > +nomem_xferq: > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->xferq_pbl_addr_virt_addr, > + p_conn->xferq_pbl_addr); > + for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) > + if (p_conn->xferq_addr_virt_addr[i]) > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->xferq_addr_virt_addr[i], > + p_conn->xferq_addr[i]); > +nomem_pbl_xferq: > + kfree(p_conn); > + return -ENOMEM; > +} > + > +static void qed_fcoe_free_connection(struct qed_hwfn *p_hwfn, > + struct qed_fcoe_conn *p_conn) > +{ > + u32 i; > + > + if (!p_conn) > + return; > + > + if (p_conn->confq_pbl_addr_virt_addr) > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->confq_pbl_addr_virt_addr, > + p_conn->confq_pbl_addr); > + > + for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) { > + if (!p_conn->confq_addr_virt_addr[i]) > + continue; > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->confq_addr_virt_addr[i], > + p_conn->confq_addr[i]); > + } > + > + if (p_conn->xferq_pbl_addr_virt_addr) > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->xferq_pbl_addr_virt_addr, > + p_conn->xferq_pbl_addr); > + > + for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) { > + if (!p_conn->xferq_addr_virt_addr[i]) > + continue; > + dma_free_coherent(&p_hwfn->cdev->pdev->dev, > + QED_CHAIN_PAGE_SIZE, > + p_conn->xferq_addr_virt_addr[i], > + p_conn->xferq_addr[i]); > + } > + kfree(p_conn); > +} > + > +static void __iomem *qed_fcoe_get_db_addr(struct qed_hwfn *p_hwfn, u32 cid) > +{ > + return (u8 __iomem *)p_hwfn->doorbells + > + qed_db_addr(cid, DQ_DEMS_LEGACY); > +} > + > +static void __iomem *qed_fcoe_get_primary_bdq_prod(struct qed_hwfn *p_hwfn, > + u8 bdq_id) > +{ > + u8 bdq_function_id = FCOE_BDQ_ID(p_hwfn->port_id); > + > + return (u8 __iomem *)p_hwfn->regview + GTT_BAR0_MAP_REG_MSDM_RAM + > + MSTORM_SCSI_BDQ_EXT_PROD_OFFSET(bdq_function_id, bdq_id); > +} > + > +static void __iomem *qed_fcoe_get_secondary_bdq_prod(struct qed_hwfn *p_hwfn, > + u8 bdq_id) > +{ > + u8 bdq_function_id = FCOE_BDQ_ID(p_hwfn->port_id); > + > + return (u8 __iomem *)p_hwfn->regview + GTT_BAR0_MAP_REG_TSDM_RAM + > + TSTORM_SCSI_BDQ_EXT_PROD_OFFSET(bdq_function_id, bdq_id); > +} > + > +struct qed_fcoe_info *qed_fcoe_alloc(struct qed_hwfn *p_hwfn) > +{ > + struct qed_fcoe_info *p_fcoe_info; > + > + /* Allocate LL2's set struct */ > + p_fcoe_info = kzalloc(sizeof(*p_fcoe_info), GFP_KERNEL); > + if (!p_fcoe_info) { > + DP_NOTICE(p_hwfn, "Failed to allocate qed_fcoe_info'\n"); > + return NULL; > + } > + INIT_LIST_HEAD(&p_fcoe_info->free_list); > + return p_fcoe_info; > +} > + > +void qed_fcoe_setup(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info) > +{ > + struct fcoe_task_context *p_task_ctx = NULL; > + int rc; > + u32 i; > + > + spin_lock_init(&p_fcoe_info->lock); > + for (i = 0; i < p_hwfn->pf_params.fcoe_pf_params.num_tasks; i++) { > + rc = qed_cxt_get_task_ctx(p_hwfn, i, > + QED_CTX_WORKING_MEM, > + (void **)&p_task_ctx); > + if (rc) > + continue; > + > + memset(p_task_ctx, 0, sizeof(struct fcoe_task_context)); > + SET_FIELD(p_task_ctx->timer_context.logical_client_0, > + TIMERS_CONTEXT_VALIDLC0, 1); > + SET_FIELD(p_task_ctx->timer_context.logical_client_1, > + TIMERS_CONTEXT_VALIDLC1, 1); > + SET_FIELD(p_task_ctx->tstorm_ag_context.flags0, > + TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE, 1); > + } > +} > + > +void qed_fcoe_free(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info) > +{ > + struct qed_fcoe_conn *p_conn = NULL; > + > + if (!p_fcoe_info) > + return; > + > + while (!list_empty(&p_fcoe_info->free_list)) { > + p_conn = list_first_entry(&p_fcoe_info->free_list, > + struct qed_fcoe_conn, list_entry); > + if (!p_conn) > + break; > + list_del(&p_conn->list_entry); > + qed_fcoe_free_connection(p_hwfn, p_conn); > + } > + > + kfree(p_fcoe_info); > +} > + > +static int > +qed_fcoe_acquire_connection(struct qed_hwfn *p_hwfn, > + struct qed_fcoe_conn *p_in_conn, > + struct qed_fcoe_conn **p_out_conn) > +{ > + struct qed_fcoe_conn *p_conn = NULL; > + int rc = 0; > + u32 icid; > + > + spin_lock_bh(&p_hwfn->p_fcoe_info->lock); > + rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &icid); > + spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); > + if (rc) > + return rc; > + > + /* Use input connection [if provided] or allocate a new one */ > + if (p_in_conn) { > + p_conn = p_in_conn; > + } else { > + rc = qed_fcoe_allocate_connection(p_hwfn, &p_conn); > + if (rc) { > + spin_lock_bh(&p_hwfn->p_fcoe_info->lock); > + qed_cxt_release_cid(p_hwfn, icid); > + spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); > + return rc; > + } > + } > + > + p_conn->icid = icid; > + p_conn->fw_cid = (p_hwfn->hw_info.opaque_fid << 16) | icid; > + *p_out_conn = p_conn; > + > + return rc; > +} > + > +static void qed_fcoe_release_connection(struct qed_hwfn *p_hwfn, > + struct qed_fcoe_conn *p_conn) > +{ > + spin_lock_bh(&p_hwfn->p_fcoe_info->lock); > + list_add_tail(&p_conn->list_entry, &p_hwfn->p_fcoe_info->free_list); > + qed_cxt_release_cid(p_hwfn, p_conn->icid); > + spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); > +} > + > +static void _qed_fcoe_get_tstats(struct qed_hwfn *p_hwfn, > + struct qed_ptt *p_ptt, > + struct qed_fcoe_stats *p_stats) > +{ > + struct fcoe_rx_stat tstats; > + u32 tstats_addr; > + > + memset(&tstats, 0, sizeof(tstats)); > + tstats_addr = BAR0_MAP_REG_TSDM_RAM + > + TSTORM_FCOE_RX_STATS_OFFSET(p_hwfn->rel_pf_id); > + qed_memcpy_from(p_hwfn, p_ptt, &tstats, tstats_addr, sizeof(tstats)); > + > + p_stats->fcoe_rx_byte_cnt = HILO_64_REGPAIR(tstats.fcoe_rx_byte_cnt); > + p_stats->fcoe_rx_data_pkt_cnt = > + HILO_64_REGPAIR(tstats.fcoe_rx_data_pkt_cnt); > + p_stats->fcoe_rx_xfer_pkt_cnt = > + HILO_64_REGPAIR(tstats.fcoe_rx_xfer_pkt_cnt); > + p_stats->fcoe_rx_other_pkt_cnt = > + HILO_64_REGPAIR(tstats.fcoe_rx_other_pkt_cnt); > + > + p_stats->fcoe_silent_drop_pkt_cmdq_full_cnt = > + le32_to_cpu(tstats.fcoe_silent_drop_pkt_cmdq_full_cnt); > + p_stats->fcoe_silent_drop_pkt_rq_full_cnt = > + le32_to_cpu(tstats.fcoe_silent_drop_pkt_rq_full_cnt); > + p_stats->fcoe_silent_drop_pkt_crc_error_cnt = > + le32_to_cpu(tstats.fcoe_silent_drop_pkt_crc_error_cnt); > + p_stats->fcoe_silent_drop_pkt_task_invalid_cnt = > + le32_to_cpu(tstats.fcoe_silent_drop_pkt_task_invalid_cnt); > + p_stats->fcoe_silent_drop_total_pkt_cnt = > + le32_to_cpu(tstats.fcoe_silent_drop_total_pkt_cnt); > +} > + > +static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn, > + struct qed_ptt *p_ptt, > + struct qed_fcoe_stats *p_stats) > +{ > + struct fcoe_tx_stat pstats; > + u32 pstats_addr; > + > + memset(&pstats, 0, sizeof(pstats)); > + pstats_addr = BAR0_MAP_REG_PSDM_RAM + > + PSTORM_FCOE_TX_STATS_OFFSET(p_hwfn->rel_pf_id); > + qed_memcpy_from(p_hwfn, p_ptt, &pstats, pstats_addr, sizeof(pstats)); > + > + p_stats->fcoe_tx_byte_cnt = HILO_64_REGPAIR(pstats.fcoe_tx_byte_cnt); > + p_stats->fcoe_tx_data_pkt_cnt = > + HILO_64_REGPAIR(pstats.fcoe_tx_data_pkt_cnt); > + p_stats->fcoe_tx_xfer_pkt_cnt = > + HILO_64_REGPAIR(pstats.fcoe_tx_xfer_pkt_cnt); > + p_stats->fcoe_tx_other_pkt_cnt = > + HILO_64_REGPAIR(pstats.fcoe_tx_other_pkt_cnt); > +} > + > +static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn, > + struct qed_fcoe_stats *p_stats) > +{ > + struct qed_ptt *p_ptt; > + > + memset(p_stats, 0, sizeof(*p_stats)); > + > + p_ptt = qed_ptt_acquire(p_hwfn); > + > + if (!p_ptt) { > + DP_ERR(p_hwfn, "Failed to acquire ptt\n"); > + return -EINVAL; > + } > + > + _qed_fcoe_get_tstats(p_hwfn, p_ptt, p_stats); > + _qed_fcoe_get_pstats(p_hwfn, p_ptt, p_stats); > + > + qed_ptt_release(p_hwfn, p_ptt); > + > + return 0; > +} > + > +struct qed_hash_fcoe_con { > + struct hlist_node node; > + struct qed_fcoe_conn *con; > +}; > + > +static int qed_fill_fcoe_dev_info(struct qed_dev *cdev, > + struct qed_dev_fcoe_info *info) > +{ > + struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); > + int rc; > + > + memset(info, 0, sizeof(*info)); > + rc = qed_fill_dev_info(cdev, &info->common); > + > + info->primary_dbq_rq_addr = > + qed_fcoe_get_primary_bdq_prod(hwfn, BDQ_ID_RQ); > + info->secondary_bdq_rq_addr = > + qed_fcoe_get_secondary_bdq_prod(hwfn, BDQ_ID_RQ); > + > + return rc; > +} > + > +static void qed_register_fcoe_ops(struct qed_dev *cdev, > + struct qed_fcoe_cb_ops *ops, void *cookie) > +{ > + cdev->protocol_ops.fcoe = ops; > + cdev->ops_cookie = cookie; > +} > + > +static struct qed_hash_fcoe_con *qed_fcoe_get_hash(struct qed_dev *cdev, > + u32 handle) > +{ > + struct qed_hash_fcoe_con *hash_con = NULL; > + > + if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) > + return NULL; > + > + hash_for_each_possible(cdev->connections, hash_con, node, handle) { > + if (hash_con->con->icid == handle) > + break; > + } > + > + if (!hash_con || (hash_con->con->icid != handle)) > + return NULL; > + > + return hash_con; > +} > + > +static int qed_fcoe_stop(struct qed_dev *cdev) > +{ > + int rc; > + > + if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) { > + DP_NOTICE(cdev, "fcoe already stopped\n"); > + return 0; > + } > + > + if (!hash_empty(cdev->connections)) { > + DP_NOTICE(cdev, > + "Can't stop fcoe - not all connections were returned\n"); > + return -EINVAL; > + } > + > + /* Stop the fcoe */ > + rc = qed_sp_fcoe_func_stop(QED_LEADING_HWFN(cdev), > + QED_SPQ_MODE_EBLOCK, NULL); > + cdev->flags &= ~QED_FLAG_STORAGE_STARTED; > + > + return rc; > +} > + > +static int qed_fcoe_start(struct qed_dev *cdev, struct qed_fcoe_tid *tasks) > +{ > + int rc; > + > + if (cdev->flags & QED_FLAG_STORAGE_STARTED) { > + DP_NOTICE(cdev, "fcoe already started;\n"); > + return 0; > + } > + > + rc = qed_sp_fcoe_func_start(QED_LEADING_HWFN(cdev), > + QED_SPQ_MODE_EBLOCK, NULL); > + if (rc) { > + DP_NOTICE(cdev, "Failed to start fcoe\n"); > + return rc; > + } > + > + cdev->flags |= QED_FLAG_STORAGE_STARTED; > + hash_init(cdev->connections); > + > + if (tasks) { > + struct qed_tid_mem *tid_info = kzalloc(sizeof(*tid_info), > + GFP_ATOMIC); > + > + if (!tid_info) { > + DP_NOTICE(cdev, > + "Failed to allocate tasks information\n"); > + qed_fcoe_stop(cdev); > + return -ENOMEM; > + } > + > + rc = qed_cxt_get_tid_mem_info(QED_LEADING_HWFN(cdev), tid_info); > + if (rc) { > + DP_NOTICE(cdev, "Failed to gather task information\n"); > + qed_fcoe_stop(cdev); > + kfree(tid_info); > + return rc; > + } > + > + /* Fill task information */ > + tasks->size = tid_info->tid_size; > + tasks->num_tids_per_block = tid_info->num_tids_per_block; > + memcpy(tasks->blocks, tid_info->blocks, > + MAX_TID_BLOCKS_FCOE * sizeof(u8 *)); > + > + kfree(tid_info); > + } > + > + return 0; > +} > + > +static int qed_fcoe_acquire_conn(struct qed_dev *cdev, > + u32 *handle, > + u32 *fw_cid, void __iomem **p_doorbell) > +{ > + struct qed_hash_fcoe_con *hash_con; > + int rc; > + > + /* Allocate a hashed connection */ > + hash_con = kzalloc(sizeof(*hash_con), GFP_KERNEL); > + if (!hash_con) { > + DP_NOTICE(cdev, "Failed to allocate hashed connection\n"); > + return -ENOMEM; > + } > + > + /* Acquire the connection */ > + rc = qed_fcoe_acquire_connection(QED_LEADING_HWFN(cdev), NULL, > + &hash_con->con); > + if (rc) { > + DP_NOTICE(cdev, "Failed to acquire Connection\n"); > + kfree(hash_con); > + return rc; > + } > + > + /* Added the connection to hash table */ > + *handle = hash_con->con->icid; > + *fw_cid = hash_con->con->fw_cid; > + hash_add(cdev->connections, &hash_con->node, *handle); > + > + if (p_doorbell) > + *p_doorbell = qed_fcoe_get_db_addr(QED_LEADING_HWFN(cdev), > + *handle); > + > + return 0; > +} > + > +static int qed_fcoe_release_conn(struct qed_dev *cdev, u32 handle) > +{ > + struct qed_hash_fcoe_con *hash_con; > + > + hash_con = qed_fcoe_get_hash(cdev, handle); > + if (!hash_con) { > + DP_NOTICE(cdev, "Failed to find connection for handle %d\n", > + handle); > + return -EINVAL; > + } > + > + hlist_del(&hash_con->node); > + qed_fcoe_release_connection(QED_LEADING_HWFN(cdev), hash_con->con); > + kfree(hash_con); > + > + return 0; > +} > + > +static int qed_fcoe_offload_conn(struct qed_dev *cdev, > + u32 handle, > + struct qed_fcoe_params_offload *conn_info) > +{ > + struct qed_hash_fcoe_con *hash_con; > + struct qed_fcoe_conn *con; > + > + hash_con = qed_fcoe_get_hash(cdev, handle); > + if (!hash_con) { > + DP_NOTICE(cdev, "Failed to find connection for handle %d\n", > + handle); > + return -EINVAL; > + } > + > + /* Update the connection with information from the params */ > + con = hash_con->con; > + > + con->sq_pbl_addr = conn_info->sq_pbl_addr; > + con->sq_curr_page_addr = conn_info->sq_curr_page_addr; > + con->sq_next_page_addr = conn_info->sq_next_page_addr; > + con->tx_max_fc_pay_len = conn_info->tx_max_fc_pay_len; > + con->e_d_tov_timer_val = conn_info->e_d_tov_timer_val; > + con->rec_tov_timer_val = conn_info->rec_tov_timer_val; > + con->rx_max_fc_pay_len = conn_info->rx_max_fc_pay_len; > + con->vlan_tag = conn_info->vlan_tag; > + con->max_conc_seqs_c3 = conn_info->max_conc_seqs_c3; > + con->flags = conn_info->flags; > + con->def_q_idx = conn_info->def_q_idx; > + > + con->src_mac_addr_hi = (conn_info->src_mac[5] << 8) | > + conn_info->src_mac[4]; > + con->src_mac_addr_mid = (conn_info->src_mac[3] << 8) | > + conn_info->src_mac[2]; > + con->src_mac_addr_lo = (conn_info->src_mac[1] << 8) | > + conn_info->src_mac[0]; > + con->dst_mac_addr_hi = (conn_info->dst_mac[5] << 8) | > + conn_info->dst_mac[4]; > + con->dst_mac_addr_mid = (conn_info->dst_mac[3] << 8) | > + conn_info->dst_mac[2]; > + con->dst_mac_addr_lo = (conn_info->dst_mac[1] << 8) | > + conn_info->dst_mac[0]; > + > + con->s_id.addr_hi = conn_info->s_id.addr_hi; > + con->s_id.addr_mid = conn_info->s_id.addr_mid; > + con->s_id.addr_lo = conn_info->s_id.addr_lo; > + con->d_id.addr_hi = conn_info->d_id.addr_hi; > + con->d_id.addr_mid = conn_info->d_id.addr_mid; > + con->d_id.addr_lo = conn_info->d_id.addr_lo; > + > + return qed_sp_fcoe_conn_offload(QED_LEADING_HWFN(cdev), con, > + QED_SPQ_MODE_EBLOCK, NULL); > +} > + > +static int qed_fcoe_destroy_conn(struct qed_dev *cdev, > + u32 handle, dma_addr_t terminate_params) > +{ > + struct qed_hash_fcoe_con *hash_con; > + struct qed_fcoe_conn *con; > + > + hash_con = qed_fcoe_get_hash(cdev, handle); > + if (!hash_con) { > + DP_NOTICE(cdev, "Failed to find connection for handle %d\n", > + handle); > + return -EINVAL; > + } > + > + /* Update the connection with information from the params */ > + con = hash_con->con; > + con->terminate_params = terminate_params; > + > + return qed_sp_fcoe_conn_destroy(QED_LEADING_HWFN(cdev), con, > + QED_SPQ_MODE_EBLOCK, NULL); > +} > + > +static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats) > +{ > + return qed_fcoe_get_stats(QED_LEADING_HWFN(cdev), stats); > +} > + > +void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, > + struct qed_mcp_fcoe_stats *stats) > +{ > + struct qed_fcoe_stats proto_stats; > + > + /* Retrieve FW statistics */ > + memset(&proto_stats, 0, sizeof(proto_stats)); > + if (qed_fcoe_stats(cdev, &proto_stats)) { > + DP_VERBOSE(cdev, QED_MSG_STORAGE, > + "Failed to collect FCoE statistics\n"); > + return; > + } > + > + /* Translate FW statistics into struct */ > + stats->rx_pkts = proto_stats.fcoe_rx_data_pkt_cnt + > + proto_stats.fcoe_rx_xfer_pkt_cnt + > + proto_stats.fcoe_rx_other_pkt_cnt; > + stats->tx_pkts = proto_stats.fcoe_tx_data_pkt_cnt + > + proto_stats.fcoe_tx_xfer_pkt_cnt + > + proto_stats.fcoe_tx_other_pkt_cnt; > + stats->fcs_err = proto_stats.fcoe_silent_drop_pkt_crc_error_cnt; > + > + /* Request protocol driver to fill-in the rest */ > + if (cdev->protocol_ops.fcoe && cdev->ops_cookie) { > + struct qed_fcoe_cb_ops *ops = cdev->protocol_ops.fcoe; > + void *cookie = cdev->ops_cookie; > + > + if (ops->get_login_failures) > + stats->login_failure = ops->get_login_failures(cookie); > + } > +} > + > +static const struct qed_fcoe_ops qed_fcoe_ops_pass = { > + .common = &qed_common_ops_pass, > + .ll2 = &qed_ll2_ops_pass, > + .fill_dev_info = &qed_fill_fcoe_dev_info, > + .start = &qed_fcoe_start, > + .stop = &qed_fcoe_stop, > + .register_ops = &qed_register_fcoe_ops, > + .acquire_conn = &qed_fcoe_acquire_conn, > + .release_conn = &qed_fcoe_release_conn, > + .offload_conn = &qed_fcoe_offload_conn, > + .destroy_conn = &qed_fcoe_destroy_conn, > + .get_stats = &qed_fcoe_stats, > +}; > + > +const struct qed_fcoe_ops *qed_get_fcoe_ops(void) > +{ > + return &qed_fcoe_ops_pass; > +} > +EXPORT_SYMBOL(qed_get_fcoe_ops); > + > +void qed_put_fcoe_ops(void) > +{ > +} > +EXPORT_SYMBOL(qed_put_fcoe_ops); > diff --git a/drivers/net/ethernet/qlogic/qed/qed_fcoe.h b/drivers/net/ethernet/qlogic/qed/qed_fcoe.h > new file mode 100644 > index 0000000..72a3643 > --- /dev/null > +++ b/drivers/net/ethernet/qlogic/qed/qed_fcoe.h > @@ -0,0 +1,52 @@ > +/* QLogic qed NIC Driver > + * Copyright (c) 2016 QLogic Corporation > + * > + * This software is available under the terms of the GNU General Public License > + * (GPL) Version 2, available from the file COPYING in the main directory of > + * this source tree. > + */ > + > +#ifndef _QED_FCOE_H > +#define _QED_FCOE_H > +#include <linux/types.h> > +#include <linux/list.h> > +#include <linux/slab.h> > +#include <linux/spinlock.h> > +#include <linux/qed/qed_fcoe_if.h> > +#include <linux/qed/qed_chain.h> > +#include "qed.h" > +#include "qed_hsi.h" > +#include "qed_mcp.h" > +#include "qed_sp.h" > + > +struct qed_fcoe_info { > + spinlock_t lock; /* Connection resources. */ > + struct list_head free_list; > +}; > + > +#if IS_ENABLED(CONFIG_QED_FCOE) > +struct qed_fcoe_info *qed_fcoe_alloc(struct qed_hwfn *p_hwfn); > + > +void qed_fcoe_setup(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info); > + > +void qed_fcoe_free(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info); > +void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, > + struct qed_mcp_fcoe_stats *stats); > +#else /* CONFIG_QED_FCOE */ > +static inline struct qed_fcoe_info * > +qed_fcoe_alloc(struct qed_hwfn *p_hwfn) { return NULL; } > +static inline void > +qed_fcoe_setup(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info) {} > +static inline void > +qed_fcoe_free(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info) {} > +static inline void > +qed_get_protocol_stats_fcoe(struct qed_dev *cdev, > + struct qed_mcp_fcoe_stats *stats) {} > +#endif /* CONFIG_QED_FCOE */ > + > +#ifdef CONFIG_QED_LL2 > +extern const struct qed_common_ops qed_common_ops_pass; > +extern const struct qed_ll2_ops qed_ll2_ops_pass; > +#endif > + > +#endif /* _QED_FCOE_H */ > diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h > index 785ab03..a10f55e 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h > @@ -19,10 +19,12 @@ > #include <linux/qed/common_hsi.h> > #include <linux/qed/storage_common.h> > #include <linux/qed/tcp_common.h> > +#include <linux/qed/fcoe_common.h> > #include <linux/qed/eth_common.h> > #include <linux/qed/iscsi_common.h> > #include <linux/qed/rdma_common.h> > #include <linux/qed/roce_common.h> > +#include <linux/qed/qed_fcoe_if.h> > > struct qed_hwfn; > struct qed_ptt; > @@ -913,7 +915,7 @@ struct mstorm_vf_zone { > enum personality_type { > BAD_PERSONALITY_TYP, > PERSONALITY_ISCSI, > - PERSONALITY_RESERVED2, > + PERSONALITY_FCOE, > PERSONALITY_RDMA_AND_ETH, > PERSONALITY_RESERVED3, > PERSONALITY_CORE, > @@ -3449,6 +3451,10 @@ void qed_set_geneve_enable(struct qed_hwfn *p_hwfn, > #define TSTORM_RDMA_QUEUE_STAT_OFFSET(rdma_stat_counter_id) \ > (IRO[46].base + ((rdma_stat_counter_id) * IRO[46].m1)) > #define TSTORM_RDMA_QUEUE_STAT_SIZE (IRO[46].size) > +#define TSTORM_FCOE_RX_STATS_OFFSET(pf_id) \ > + (IRO[43].base + ((pf_id) * IRO[43].m1)) > +#define PSTORM_FCOE_TX_STATS_OFFSET(pf_id) \ > + (IRO[44].base + ((pf_id) * IRO[44].m1)) > > static const struct iro iro_arr[47] = { > {0x0, 0x0, 0x0, 0x0, 0x8}, > @@ -7383,6 +7389,769 @@ struct ystorm_roce_resp_conn_ag_ctx { > __le32 reg3; > }; > > +struct ystorm_fcoe_conn_st_ctx { > + u8 func_mode; > + u8 cos; > + u8 conf_version; > + u8 eth_hdr_size; > + __le16 stat_ram_addr; > + __le16 mtu; > + __le16 max_fc_payload_len; > + __le16 tx_max_fc_pay_len; > + u8 fcp_cmd_size; > + u8 fcp_rsp_size; > + __le16 mss; > + struct regpair reserved; > + u8 protection_info_flags; > +#define YSTORM_FCOE_CONN_ST_CTX_SUPPORT_PROTECTION_MASK 0x1 > +#define YSTORM_FCOE_CONN_ST_CTX_SUPPORT_PROTECTION_SHIFT 0 > +#define YSTORM_FCOE_CONN_ST_CTX_VALID_MASK 0x1 > +#define YSTORM_FCOE_CONN_ST_CTX_VALID_SHIFT 1 > +#define YSTORM_FCOE_CONN_ST_CTX_RESERVED1_MASK 0x3F > +#define YSTORM_FCOE_CONN_ST_CTX_RESERVED1_SHIFT 2 > + u8 dst_protection_per_mss; > + u8 src_protection_per_mss; > + u8 ptu_log_page_size; > + u8 flags; > +#define YSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_MASK 0x1 > +#define YSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_SHIFT 0 > +#define YSTORM_FCOE_CONN_ST_CTX_OUTER_VLAN_FLAG_MASK 0x1 > +#define YSTORM_FCOE_CONN_ST_CTX_OUTER_VLAN_FLAG_SHIFT 1 > +#define YSTORM_FCOE_CONN_ST_CTX_RSRV_MASK 0x3F > +#define YSTORM_FCOE_CONN_ST_CTX_RSRV_SHIFT 2 > + u8 fcp_xfer_size; > + u8 reserved3[2]; > +}; > + > +struct fcoe_vlan_fields { > + __le16 fields; > +#define FCOE_VLAN_FIELDS_VID_MASK 0xFFF > +#define FCOE_VLAN_FIELDS_VID_SHIFT 0 > +#define FCOE_VLAN_FIELDS_CLI_MASK 0x1 > +#define FCOE_VLAN_FIELDS_CLI_SHIFT 12 > +#define FCOE_VLAN_FIELDS_PRI_MASK 0x7 > +#define FCOE_VLAN_FIELDS_PRI_SHIFT 13 > +}; > + > +union fcoe_vlan_field_union { > + struct fcoe_vlan_fields fields; > + __le16 val; > +}; > + > +union fcoe_vlan_vif_field_union { > + union fcoe_vlan_field_union vlan; > + __le16 vif; > +}; > + > +struct pstorm_fcoe_eth_context_section { > + u8 remote_addr_3; > + u8 remote_addr_2; > + u8 remote_addr_1; > + u8 remote_addr_0; > + u8 local_addr_1; > + u8 local_addr_0; > + u8 remote_addr_5; > + u8 remote_addr_4; > + u8 local_addr_5; > + u8 local_addr_4; > + u8 local_addr_3; > + u8 local_addr_2; > + union fcoe_vlan_vif_field_union vif_outer_vlan; > + __le16 vif_outer_eth_type; > + union fcoe_vlan_vif_field_union inner_vlan; > + __le16 inner_eth_type; > +}; > + > +struct pstorm_fcoe_conn_st_ctx { > + u8 func_mode; > + u8 cos; > + u8 conf_version; > + u8 rsrv; > + __le16 stat_ram_addr; > + __le16 mss; > + struct regpair abts_cleanup_addr; > + struct pstorm_fcoe_eth_context_section eth; > + u8 sid_2; > + u8 sid_1; > + u8 sid_0; > + u8 flags; > +#define PSTORM_FCOE_CONN_ST_CTX_VNTAG_VLAN_MASK 0x1 > +#define PSTORM_FCOE_CONN_ST_CTX_VNTAG_VLAN_SHIFT 0 > +#define PSTORM_FCOE_CONN_ST_CTX_SUPPORT_REC_RR_TOV_MASK 0x1 > +#define PSTORM_FCOE_CONN_ST_CTX_SUPPORT_REC_RR_TOV_SHIFT 1 > +#define PSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_MASK 0x1 > +#define PSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_SHIFT 2 > +#define PSTORM_FCOE_CONN_ST_CTX_OUTER_VLAN_FLAG_MASK 0x1 > +#define PSTORM_FCOE_CONN_ST_CTX_OUTER_VLAN_FLAG_SHIFT 3 > +#define PSTORM_FCOE_CONN_ST_CTX_RESERVED_MASK 0xF > +#define PSTORM_FCOE_CONN_ST_CTX_RESERVED_SHIFT 4 > + u8 did_2; > + u8 did_1; > + u8 did_0; > + u8 src_mac_index; > + __le16 rec_rr_tov_val; > + u8 q_relative_offset; > + u8 reserved1; > +}; > + > +struct xstorm_fcoe_conn_st_ctx { > + u8 func_mode; > + u8 src_mac_index; > + u8 conf_version; > + u8 cached_wqes_avail; > + __le16 stat_ram_addr; > + u8 flags; > +#define XSTORM_FCOE_CONN_ST_CTX_SQ_DEFERRED_MASK 0x1 > +#define XSTORM_FCOE_CONN_ST_CTX_SQ_DEFERRED_SHIFT 0 > +#define XSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_MASK 0x1 > +#define XSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_SHIFT 1 > +#define XSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_ORIG_MASK 0x1 > +#define XSTORM_FCOE_CONN_ST_CTX_INNER_VLAN_FLAG_ORIG_SHIFT 2 > +#define XSTORM_FCOE_CONN_ST_CTX_LAST_QUEUE_HANDLED_MASK 0x3 > +#define XSTORM_FCOE_CONN_ST_CTX_LAST_QUEUE_HANDLED_SHIFT 3 > +#define XSTORM_FCOE_CONN_ST_CTX_RSRV_MASK 0x7 > +#define XSTORM_FCOE_CONN_ST_CTX_RSRV_SHIFT 5 > + u8 cached_wqes_offset; > + u8 reserved2; > + u8 eth_hdr_size; > + u8 seq_id; > + u8 max_conc_seqs; > + __le16 num_pages_in_pbl; > + __le16 reserved; > + struct regpair sq_pbl_addr; > + struct regpair sq_curr_page_addr; > + struct regpair sq_next_page_addr; > + struct regpair xferq_pbl_addr; > + struct regpair xferq_curr_page_addr; > + struct regpair xferq_next_page_addr; > + struct regpair respq_pbl_addr; > + struct regpair respq_curr_page_addr; > + struct regpair respq_next_page_addr; > + __le16 mtu; > + __le16 tx_max_fc_pay_len; > + __le16 max_fc_payload_len; > + __le16 min_frame_size; > + __le16 sq_pbl_next_index; > + __le16 respq_pbl_next_index; > + u8 fcp_cmd_byte_credit; > + u8 fcp_rsp_byte_credit; > + __le16 protection_info; > +#define XSTORM_FCOE_CONN_ST_CTX_PROTECTION_PERF_MASK 0x1 > +#define XSTORM_FCOE_CONN_ST_CTX_PROTECTION_PERF_SHIFT 0 > +#define XSTORM_FCOE_CONN_ST_CTX_SUPPORT_PROTECTION_MASK 0x1 > +#define XSTORM_FCOE_CONN_ST_CTX_SUPPORT_PROTECTION_SHIFT 1 > +#define XSTORM_FCOE_CONN_ST_CTX_VALID_MASK 0x1 > +#define XSTORM_FCOE_CONN_ST_CTX_VALID_SHIFT 2 > +#define XSTORM_FCOE_CONN_ST_CTX_FRAME_PROT_ALIGNED_MASK 0x1 > +#define XSTORM_FCOE_CONN_ST_CTX_FRAME_PROT_ALIGNED_SHIFT 3 > +#define XSTORM_FCOE_CONN_ST_CTX_RESERVED3_MASK 0xF > +#define XSTORM_FCOE_CONN_ST_CTX_RESERVED3_SHIFT 4 > +#define XSTORM_FCOE_CONN_ST_CTX_DST_PROTECTION_PER_MSS_MASK 0xFF > +#define XSTORM_FCOE_CONN_ST_CTX_DST_PROTECTION_PER_MSS_SHIFT 8 > + __le16 xferq_pbl_next_index; > + __le16 page_size; > + u8 mid_seq; > + u8 fcp_xfer_byte_credit; > + u8 reserved1[2]; > + struct fcoe_wqe cached_wqes[16]; > +}; > + > +struct xstorm_fcoe_conn_ag_ctx { > + u8 reserved0; > + u8 fcoe_state; > + u8 flags0; > +#define XSTORM_FCOE_CONN_AG_CTX_EXIST_IN_QM0_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_EXIST_IN_QM0_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED1_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED1_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED2_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED2_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_EXIST_IN_QM3_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_EXIST_IN_QM3_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED3_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED3_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED4_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED4_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED5_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED5_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED6_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED6_SHIFT 7 > + u8 flags1; > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED7_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED7_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED8_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED8_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED9_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED9_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT11_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT11_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT12_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT12_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT13_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT13_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT14_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT14_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT15_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT15_SHIFT 7 > + u8 flags2; > +#define XSTORM_FCOE_CONN_AG_CTX_CF0_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF0_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_CF1_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF1_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_CF2_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF2_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF3_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF3_SHIFT 6 > + u8 flags3; > +#define XSTORM_FCOE_CONN_AG_CTX_CF4_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF4_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_CF5_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF5_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_CF6_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF6_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF7_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF7_SHIFT 6 > + u8 flags4; > +#define XSTORM_FCOE_CONN_AG_CTX_CF8_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF8_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_CF9_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF9_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_CF10_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF10_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF11_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF11_SHIFT 6 > + u8 flags5; > +#define XSTORM_FCOE_CONN_AG_CTX_CF12_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF12_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_CF13_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF13_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_CF14_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF14_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF15_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF15_SHIFT 6 > + u8 flags6; > +#define XSTORM_FCOE_CONN_AG_CTX_CF16_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF16_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_CF17_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF17_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_CF18_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF18_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_DQ_CF_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_DQ_CF_SHIFT 6 > + u8 flags7; > +#define XSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED10_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED10_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_SLOW_PATH_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_SLOW_PATH_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF0EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF0EN_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_CF1EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF1EN_SHIFT 7 > + u8 flags8; > +#define XSTORM_FCOE_CONN_AG_CTX_CF2EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF2EN_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_CF3EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF3EN_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF4EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF4EN_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_CF5EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF5EN_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF6EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF6EN_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF7EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF7EN_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_CF8EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF8EN_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_CF9EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF9EN_SHIFT 7 > + u8 flags9; > +#define XSTORM_FCOE_CONN_AG_CTX_CF10EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF10EN_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_CF11EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF11EN_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF12EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF12EN_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_CF13EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF13EN_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF14EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF14EN_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF15EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF15EN_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_CF16EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF16EN_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_CF17EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF17EN_SHIFT 7 > + u8 flags10; > +#define XSTORM_FCOE_CONN_AG_CTX_CF18EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF18EN_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_DQ_CF_EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_DQ_CF_EN_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_EN_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED11_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED11_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_SLOW_PATH_EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_SLOW_PATH_EN_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_CF23EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_CF23EN_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED12_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED12_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED13_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED13_SHIFT 7 > + u8 flags11; > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED14_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED14_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED15_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED15_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED16_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESERVED16_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE5EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE5EN_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE6EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE6EN_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE7EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE7EN_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED1_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED1_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_XFERQ_DECISION_EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_XFERQ_DECISION_EN_SHIFT 7 > + u8 flags12; > +#define XSTORM_FCOE_CONN_AG_CTX_SQ_DECISION_EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_SQ_DECISION_EN_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE11EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE11EN_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED2_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED2_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED3_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED3_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE14EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE14EN_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE15EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE15EN_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE16EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE16EN_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE17EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE17EN_SHIFT 7 > + u8 flags13; > +#define XSTORM_FCOE_CONN_AG_CTX_RESPQ_DECISION_EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RESPQ_DECISION_EN_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE19EN_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_RULE19EN_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED4_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED4_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED5_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED5_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED6_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED6_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED7_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED7_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED8_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED8_SHIFT 6 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED9_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_A0_RESERVED9_SHIFT 7 > + u8 flags14; > +#define XSTORM_FCOE_CONN_AG_CTX_BIT16_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT16_SHIFT 0 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT17_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT17_SHIFT 1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT18_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT18_SHIFT 2 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT19_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT19_SHIFT 3 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT20_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT20_SHIFT 4 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT21_MASK 0x1 > +#define XSTORM_FCOE_CONN_AG_CTX_BIT21_SHIFT 5 > +#define XSTORM_FCOE_CONN_AG_CTX_CF23_MASK 0x3 > +#define XSTORM_FCOE_CONN_AG_CTX_CF23_SHIFT 6 > + u8 byte2; > + __le16 physical_q0; > + __le16 word1; > + __le16 word2; > + __le16 sq_cons; > + __le16 sq_prod; > + __le16 xferq_prod; > + __le16 xferq_cons; > + u8 byte3; > + u8 byte4; > + u8 byte5; > + u8 byte6; > + __le32 remain_io; > + __le32 reg1; > + __le32 reg2; > + __le32 reg3; > + __le32 reg4; > + __le32 reg5; > + __le32 reg6; > + __le16 respq_prod; > + __le16 respq_cons; > + __le16 word9; > + __le16 word10; > + __le32 reg7; > + __le32 reg8; > +}; > + > +struct ustorm_fcoe_conn_st_ctx { > + struct regpair respq_pbl_addr; > + __le16 num_pages_in_pbl; > + u8 ptu_log_page_size; > + u8 log_page_size; > + __le16 respq_prod; > + u8 reserved[2]; > +}; > + > +struct tstorm_fcoe_conn_ag_ctx { > + u8 reserved0; > + u8 fcoe_state; > + u8 flags0; > +#define TSTORM_FCOE_CONN_AG_CTX_EXIST_IN_QM0_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_EXIST_IN_QM0_SHIFT 0 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT1_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT1_SHIFT 1 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT2_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT2_SHIFT 2 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT3_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT3_SHIFT 3 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT4_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT4_SHIFT 4 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT5_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_BIT5_SHIFT 5 > +#define TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_SHIFT 6 > + u8 flags1; > +#define TSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_CF_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_CF_SHIFT 0 > +#define TSTORM_FCOE_CONN_AG_CTX_CF2_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF2_SHIFT 2 > +#define TSTORM_FCOE_CONN_AG_CTX_TIMER_STOP_ALL_CF_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_TIMER_STOP_ALL_CF_SHIFT 4 > +#define TSTORM_FCOE_CONN_AG_CTX_CF4_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF4_SHIFT 6 > + u8 flags2; > +#define TSTORM_FCOE_CONN_AG_CTX_CF5_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF5_SHIFT 0 > +#define TSTORM_FCOE_CONN_AG_CTX_CF6_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF6_SHIFT 2 > +#define TSTORM_FCOE_CONN_AG_CTX_CF7_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF7_SHIFT 4 > +#define TSTORM_FCOE_CONN_AG_CTX_CF8_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF8_SHIFT 6 > + u8 flags3; > +#define TSTORM_FCOE_CONN_AG_CTX_CF9_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF9_SHIFT 0 > +#define TSTORM_FCOE_CONN_AG_CTX_CF10_MASK 0x3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF10_SHIFT 2 > +#define TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN_SHIFT 4 > +#define TSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_FLUSH_Q0_CF_EN_SHIFT 5 > +#define TSTORM_FCOE_CONN_AG_CTX_CF2EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF2EN_SHIFT 6 > +#define TSTORM_FCOE_CONN_AG_CTX_TIMER_STOP_ALL_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_TIMER_STOP_ALL_CF_EN_SHIFT 7 > + u8 flags4; > +#define TSTORM_FCOE_CONN_AG_CTX_CF4EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF4EN_SHIFT 0 > +#define TSTORM_FCOE_CONN_AG_CTX_CF5EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF5EN_SHIFT 1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF6EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF6EN_SHIFT 2 > +#define TSTORM_FCOE_CONN_AG_CTX_CF7EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF7EN_SHIFT 3 > +#define TSTORM_FCOE_CONN_AG_CTX_CF8EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF8EN_SHIFT 4 > +#define TSTORM_FCOE_CONN_AG_CTX_CF9EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF9EN_SHIFT 5 > +#define TSTORM_FCOE_CONN_AG_CTX_CF10EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_CF10EN_SHIFT 6 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE0EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE0EN_SHIFT 7 > + u8 flags5; > +#define TSTORM_FCOE_CONN_AG_CTX_RULE1EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE1EN_SHIFT 0 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE2EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE2EN_SHIFT 1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE3EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE3EN_SHIFT 2 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE4EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE4EN_SHIFT 3 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE5EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE5EN_SHIFT 4 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE6EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE6EN_SHIFT 5 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE7EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE7EN_SHIFT 6 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE8EN_MASK 0x1 > +#define TSTORM_FCOE_CONN_AG_CTX_RULE8EN_SHIFT 7 > + __le32 reg0; > + __le32 reg1; > +}; > + > +struct ustorm_fcoe_conn_ag_ctx { > + u8 byte0; > + u8 byte1; > + u8 flags0; > +#define USTORM_FCOE_CONN_AG_CTX_BIT0_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_BIT0_SHIFT 0 > +#define USTORM_FCOE_CONN_AG_CTX_BIT1_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_BIT1_SHIFT 1 > +#define USTORM_FCOE_CONN_AG_CTX_CF0_MASK 0x3 > +#define USTORM_FCOE_CONN_AG_CTX_CF0_SHIFT 2 > +#define USTORM_FCOE_CONN_AG_CTX_CF1_MASK 0x3 > +#define USTORM_FCOE_CONN_AG_CTX_CF1_SHIFT 4 > +#define USTORM_FCOE_CONN_AG_CTX_CF2_MASK 0x3 > +#define USTORM_FCOE_CONN_AG_CTX_CF2_SHIFT 6 > + u8 flags1; > +#define USTORM_FCOE_CONN_AG_CTX_CF3_MASK 0x3 > +#define USTORM_FCOE_CONN_AG_CTX_CF3_SHIFT 0 > +#define USTORM_FCOE_CONN_AG_CTX_CF4_MASK 0x3 > +#define USTORM_FCOE_CONN_AG_CTX_CF4_SHIFT 2 > +#define USTORM_FCOE_CONN_AG_CTX_CF5_MASK 0x3 > +#define USTORM_FCOE_CONN_AG_CTX_CF5_SHIFT 4 > +#define USTORM_FCOE_CONN_AG_CTX_CF6_MASK 0x3 > +#define USTORM_FCOE_CONN_AG_CTX_CF6_SHIFT 6 > + u8 flags2; > +#define USTORM_FCOE_CONN_AG_CTX_CF0EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_CF0EN_SHIFT 0 > +#define USTORM_FCOE_CONN_AG_CTX_CF1EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_CF1EN_SHIFT 1 > +#define USTORM_FCOE_CONN_AG_CTX_CF2EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_CF2EN_SHIFT 2 > +#define USTORM_FCOE_CONN_AG_CTX_CF3EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_CF3EN_SHIFT 3 > +#define USTORM_FCOE_CONN_AG_CTX_CF4EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_CF4EN_SHIFT 4 > +#define USTORM_FCOE_CONN_AG_CTX_CF5EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_CF5EN_SHIFT 5 > +#define USTORM_FCOE_CONN_AG_CTX_CF6EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_CF6EN_SHIFT 6 > +#define USTORM_FCOE_CONN_AG_CTX_RULE0EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE0EN_SHIFT 7 > + u8 flags3; > +#define USTORM_FCOE_CONN_AG_CTX_RULE1EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE1EN_SHIFT 0 > +#define USTORM_FCOE_CONN_AG_CTX_RULE2EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE2EN_SHIFT 1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE3EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE3EN_SHIFT 2 > +#define USTORM_FCOE_CONN_AG_CTX_RULE4EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE4EN_SHIFT 3 > +#define USTORM_FCOE_CONN_AG_CTX_RULE5EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE5EN_SHIFT 4 > +#define USTORM_FCOE_CONN_AG_CTX_RULE6EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE6EN_SHIFT 5 > +#define USTORM_FCOE_CONN_AG_CTX_RULE7EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE7EN_SHIFT 6 > +#define USTORM_FCOE_CONN_AG_CTX_RULE8EN_MASK 0x1 > +#define USTORM_FCOE_CONN_AG_CTX_RULE8EN_SHIFT 7 > + u8 byte2; > + u8 byte3; > + __le16 word0; > + __le16 word1; > + __le32 reg0; > + __le32 reg1; > + __le32 reg2; > + __le32 reg3; > + __le16 word2; > + __le16 word3; > +}; > + > +struct tstorm_fcoe_conn_st_ctx { > + __le16 stat_ram_addr; > + __le16 rx_max_fc_payload_len; > + __le16 e_d_tov_val; > + u8 flags; > +#define TSTORM_FCOE_CONN_ST_CTX_INC_SEQ_CNT_MASK 0x1 > +#define TSTORM_FCOE_CONN_ST_CTX_INC_SEQ_CNT_SHIFT 0 > +#define TSTORM_FCOE_CONN_ST_CTX_SUPPORT_CONF_MASK 0x1 > +#define TSTORM_FCOE_CONN_ST_CTX_SUPPORT_CONF_SHIFT 1 > +#define TSTORM_FCOE_CONN_ST_CTX_DEF_Q_IDX_MASK 0x3F > +#define TSTORM_FCOE_CONN_ST_CTX_DEF_Q_IDX_SHIFT 2 > + u8 timers_cleanup_invocation_cnt; > + __le32 reserved1[2]; > + __le32 dst_mac_address_bytes0to3; > + __le16 dst_mac_address_bytes4to5; > + __le16 ramrod_echo; > + u8 flags1; > +#define TSTORM_FCOE_CONN_ST_CTX_MODE_MASK 0x3 > +#define TSTORM_FCOE_CONN_ST_CTX_MODE_SHIFT 0 > +#define TSTORM_FCOE_CONN_ST_CTX_RESERVED_MASK 0x3F > +#define TSTORM_FCOE_CONN_ST_CTX_RESERVED_SHIFT 2 > + u8 q_relative_offset; > + u8 bdq_resource_id; > + u8 reserved0[5]; > +}; > + > +struct mstorm_fcoe_conn_ag_ctx { > + u8 byte0; > + u8 byte1; > + u8 flags0; > +#define MSTORM_FCOE_CONN_AG_CTX_BIT0_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_BIT0_SHIFT 0 > +#define MSTORM_FCOE_CONN_AG_CTX_BIT1_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_BIT1_SHIFT 1 > +#define MSTORM_FCOE_CONN_AG_CTX_CF0_MASK 0x3 > +#define MSTORM_FCOE_CONN_AG_CTX_CF0_SHIFT 2 > +#define MSTORM_FCOE_CONN_AG_CTX_CF1_MASK 0x3 > +#define MSTORM_FCOE_CONN_AG_CTX_CF1_SHIFT 4 > +#define MSTORM_FCOE_CONN_AG_CTX_CF2_MASK 0x3 > +#define MSTORM_FCOE_CONN_AG_CTX_CF2_SHIFT 6 > + u8 flags1; > +#define MSTORM_FCOE_CONN_AG_CTX_CF0EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_CF0EN_SHIFT 0 > +#define MSTORM_FCOE_CONN_AG_CTX_CF1EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_CF1EN_SHIFT 1 > +#define MSTORM_FCOE_CONN_AG_CTX_CF2EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_CF2EN_SHIFT 2 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE0EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE0EN_SHIFT 3 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE1EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE1EN_SHIFT 4 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE2EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE2EN_SHIFT 5 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE3EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE3EN_SHIFT 6 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE4EN_MASK 0x1 > +#define MSTORM_FCOE_CONN_AG_CTX_RULE4EN_SHIFT 7 > + __le16 word0; > + __le16 word1; > + __le32 reg0; > + __le32 reg1; > +}; > + > +struct fcoe_mstorm_fcoe_conn_st_ctx_fp { > + __le16 xfer_prod; > + __le16 reserved1; > + u8 protection_info; > +#define FCOE_MSTORM_FCOE_CONN_ST_CTX_FP_SUPPORT_PROTECTION_MASK 0x1 > +#define FCOE_MSTORM_FCOE_CONN_ST_CTX_FP_SUPPORT_PROTECTION_SHIFT 0 > +#define FCOE_MSTORM_FCOE_CONN_ST_CTX_FP_VALID_MASK 0x1 > +#define FCOE_MSTORM_FCOE_CONN_ST_CTX_FP_VALID_SHIFT 1 > +#define FCOE_MSTORM_FCOE_CONN_ST_CTX_FP_RESERVED0_MASK 0x3F > +#define FCOE_MSTORM_FCOE_CONN_ST_CTX_FP_RESERVED0_SHIFT 2 > + u8 q_relative_offset; > + u8 reserved2[2]; > +}; > + > +struct fcoe_mstorm_fcoe_conn_st_ctx_non_fp { > + __le16 conn_id; > + __le16 stat_ram_addr; > + __le16 num_pages_in_pbl; > + u8 ptu_log_page_size; > + u8 log_page_size; > + __le16 unsolicited_cq_count; > + __le16 cmdq_count; > + u8 bdq_resource_id; > + u8 reserved0[3]; > + struct regpair xferq_pbl_addr; > + struct regpair reserved1; > + struct regpair reserved2[3]; > +}; > + > +struct mstorm_fcoe_conn_st_ctx { > + struct fcoe_mstorm_fcoe_conn_st_ctx_fp fp; > + struct fcoe_mstorm_fcoe_conn_st_ctx_non_fp non_fp; > +}; > + > +struct fcoe_conn_context { > + struct ystorm_fcoe_conn_st_ctx ystorm_st_context; > + struct pstorm_fcoe_conn_st_ctx pstorm_st_context; > + struct regpair pstorm_st_padding[2]; > + struct xstorm_fcoe_conn_st_ctx xstorm_st_context; > + struct xstorm_fcoe_conn_ag_ctx xstorm_ag_context; > + struct regpair xstorm_ag_padding[6]; > + struct ustorm_fcoe_conn_st_ctx ustorm_st_context; > + struct regpair ustorm_st_padding[2]; > + struct tstorm_fcoe_conn_ag_ctx tstorm_ag_context; > + struct regpair tstorm_ag_padding[2]; > + struct timers_context timer_context; > + struct ustorm_fcoe_conn_ag_ctx ustorm_ag_context; > + struct tstorm_fcoe_conn_st_ctx tstorm_st_context; > + struct mstorm_fcoe_conn_ag_ctx mstorm_ag_context; > + struct mstorm_fcoe_conn_st_ctx mstorm_st_context; > +}; > + > +struct fcoe_conn_offload_ramrod_params { > + struct fcoe_conn_offload_ramrod_data offload_ramrod_data; > +}; > + > +struct fcoe_conn_terminate_ramrod_params { > + struct fcoe_conn_terminate_ramrod_data terminate_ramrod_data; > +}; > + > +enum fcoe_event_type { > + FCOE_EVENT_INIT_FUNC, > + FCOE_EVENT_DESTROY_FUNC, > + FCOE_EVENT_STAT_FUNC, > + FCOE_EVENT_OFFLOAD_CONN, > + FCOE_EVENT_TERMINATE_CONN, > + FCOE_EVENT_ERROR, > + MAX_FCOE_EVENT_TYPE > +}; > + > +struct fcoe_init_ramrod_params { > + struct fcoe_init_func_ramrod_data init_ramrod_data; > +}; > + > +enum fcoe_ramrod_cmd_id { > + FCOE_RAMROD_CMD_ID_INIT_FUNC, > + FCOE_RAMROD_CMD_ID_DESTROY_FUNC, > + FCOE_RAMROD_CMD_ID_STAT_FUNC, > + FCOE_RAMROD_CMD_ID_OFFLOAD_CONN, > + FCOE_RAMROD_CMD_ID_TERMINATE_CONN, > + MAX_FCOE_RAMROD_CMD_ID > +}; > + > +struct fcoe_stat_ramrod_params { > + struct fcoe_stat_ramrod_data stat_ramrod_data; > +}; > + > +struct ystorm_fcoe_conn_ag_ctx { > + u8 byte0; > + u8 byte1; > + u8 flags0; > +#define YSTORM_FCOE_CONN_AG_CTX_BIT0_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_BIT0_SHIFT 0 > +#define YSTORM_FCOE_CONN_AG_CTX_BIT1_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_BIT1_SHIFT 1 > +#define YSTORM_FCOE_CONN_AG_CTX_CF0_MASK 0x3 > +#define YSTORM_FCOE_CONN_AG_CTX_CF0_SHIFT 2 > +#define YSTORM_FCOE_CONN_AG_CTX_CF1_MASK 0x3 > +#define YSTORM_FCOE_CONN_AG_CTX_CF1_SHIFT 4 > +#define YSTORM_FCOE_CONN_AG_CTX_CF2_MASK 0x3 > +#define YSTORM_FCOE_CONN_AG_CTX_CF2_SHIFT 6 > + u8 flags1; > +#define YSTORM_FCOE_CONN_AG_CTX_CF0EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_CF0EN_SHIFT 0 > +#define YSTORM_FCOE_CONN_AG_CTX_CF1EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_CF1EN_SHIFT 1 > +#define YSTORM_FCOE_CONN_AG_CTX_CF2EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_CF2EN_SHIFT 2 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE0EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE0EN_SHIFT 3 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE1EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE1EN_SHIFT 4 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE2EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE2EN_SHIFT 5 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE3EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE3EN_SHIFT 6 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE4EN_MASK 0x1 > +#define YSTORM_FCOE_CONN_AG_CTX_RULE4EN_SHIFT 7 > + u8 byte2; > + u8 byte3; > + __le16 word0; > + __le32 reg0; > + __le32 reg1; > + __le16 word1; > + __le16 word2; > + __le16 word3; > + __le16 word4; > + __le32 reg2; > + __le32 reg3; > +}; > + > struct ystorm_iscsi_conn_st_ctx { > __le32 reserved[4]; > }; > @@ -8411,6 +9180,7 @@ struct public_func { > #define FUNC_MF_CFG_PROTOCOL_SHIFT 4 > #define FUNC_MF_CFG_PROTOCOL_ETHERNET 0x00000000 > #define FUNC_MF_CFG_PROTOCOL_ISCSI 0x00000010 > +#define FUNC_MF_CFG_PROTOCOL_FCOE 0x00000020 > #define FUNC_MF_CFG_PROTOCOL_ROCE 0x00000030 > #define FUNC_MF_CFG_PROTOCOL_MAX 0x00000030 > > @@ -8505,6 +9275,13 @@ struct lan_stats_stc { > u32 rserved; > }; > > +struct fcoe_stats_stc { > + u64 rx_pkts; > + u64 tx_pkts; > + u32 fcs_err; > + u32 login_failure; > +}; > + > struct ocbb_data_stc { > u32 ocbb_host_addr; > u32 ocsd_host_addr; > @@ -8578,6 +9355,7 @@ struct resource_info { > struct drv_version_stc drv_version; > > struct lan_stats_stc lan_stats; > + struct fcoe_stats_stc fcoe_stats; > struct ocbb_data_stc ocbb_info; > struct temperature_status_stc temp_info; > struct resource_info resource; > @@ -8881,6 +9659,7 @@ struct nvm_cfg1_glob { > u32 misc_sig; > u32 device_capabilities; > #define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ETHERNET 0x1 > +#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_FCOE 0x2 > #define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ISCSI 0x4 > #define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ROCE 0x8 > u32 power_dissipated; > diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.c b/drivers/net/ethernet/qlogic/qed/qed_hw.c > index 6e4fae9..25b17ac 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_hw.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c > @@ -817,6 +817,9 @@ u16 qed_get_qm_pq(struct qed_hwfn *p_hwfn, > if (pq_id > p_hwfn->qm_info.num_pf_rls) > pq_id = p_hwfn->qm_info.offload_pq; > break; > + case PROTOCOLID_FCOE: > + pq_id = p_hwfn->qm_info.offload_pq; > + break; > default: > pq_id = 0; > } > diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c > index 8e5cb76..ab68455 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c > @@ -1111,6 +1111,9 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn, > p_ramrod->qm_pq_id = cpu_to_le16(pq_id); > > switch (conn_type) { > + case QED_LL2_TYPE_FCOE: > + p_ramrod->conn_type = PROTOCOLID_FCOE; > + break; > case QED_LL2_TYPE_ISCSI: > case QED_LL2_TYPE_ISCSI_OOO: > p_ramrod->conn_type = PROTOCOLID_ISCSI; > @@ -1447,6 +1450,15 @@ int qed_ll2_establish_connection(struct qed_hwfn *p_hwfn, u8 connection_handle) > > qed_ll2_establish_connection_ooo(p_hwfn, p_ll2_conn); > > + if (p_ll2_conn->conn_type == QED_LL2_TYPE_FCOE) { > + qed_llh_add_protocol_filter(p_hwfn, p_hwfn->p_main_ptt, > + 0x8906, 0, > + QED_LLH_FILTER_ETHERTYPE); > + qed_llh_add_protocol_filter(p_hwfn, p_hwfn->p_main_ptt, > + 0x8914, 0, > + QED_LLH_FILTER_ETHERTYPE); > + } > + > return rc; > } > > @@ -1820,6 +1832,15 @@ int qed_ll2_terminate_connection(struct qed_hwfn *p_hwfn, u8 connection_handle) > if (p_ll2_conn->conn_type == QED_LL2_TYPE_ISCSI_OOO) > qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info); > > + if (p_ll2_conn->conn_type == QED_LL2_TYPE_FCOE) { > + qed_llh_remove_protocol_filter(p_hwfn, p_hwfn->p_main_ptt, > + 0x8906, 0, > + QED_LLH_FILTER_ETHERTYPE); > + qed_llh_remove_protocol_filter(p_hwfn, p_hwfn->p_main_ptt, > + 0x8914, 0, > + QED_LLH_FILTER_ETHERTYPE); > + } > + > return rc; > } > > @@ -2028,6 +2049,10 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) > } > > switch (QED_LEADING_HWFN(cdev)->hw_info.personality) { > + case QED_PCI_FCOE: > + conn_type = QED_LL2_TYPE_FCOE; > + gsi_enable = 0; > + break; > case QED_PCI_ISCSI: > conn_type = QED_LL2_TYPE_ISCSI; > gsi_enable = 0; > diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h > index 6625a3a..cee357b 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h > @@ -31,7 +31,7 @@ enum qed_ll2_roce_flavor_type { > }; > > enum qed_ll2_conn_type { > - QED_LL2_TYPE_RESERVED, > + QED_LL2_TYPE_FCOE, > QED_LL2_TYPE_ISCSI, > QED_LL2_TYPE_TEST, > QED_LL2_TYPE_ISCSI_OOO, > diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c > index aeb98d8..4401147 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_main.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c > @@ -29,9 +29,11 @@ > #include "qed_sp.h" > #include "qed_dev_api.h" > #include "qed_ll2.h" > +#include "qed_fcoe.h" > #include "qed_mcp.h" > #include "qed_hw.h" > #include "qed_selftest.h" > +#include "qed_debug.h" > > #define QED_ROCE_QPS (8192) > #define QED_ROCE_DPIS (8) > @@ -1553,6 +1555,8 @@ static int qed_update_mtu(struct qed_dev *cdev, u16 mtu) > .sb_release = &qed_sb_release, > .simd_handler_config = &qed_simd_handler_config, > .simd_handler_clean = &qed_simd_handler_clean, > + .dbg_grc = &qed_dbg_grc, > + .dbg_grc_size = &qed_dbg_grc_size, > .can_link_change = &qed_can_link_change, > .set_link = &qed_set_link, > .get_link = &qed_get_current_link, > @@ -1586,6 +1590,9 @@ void qed_get_protocol_stats(struct qed_dev *cdev, > stats->lan_stats.ucast_tx_pkts = eth_stats.tx_ucast_pkts; > stats->lan_stats.fcs_err = -1; > break; > + case QED_MCP_FCOE_STATS: > + qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats); > + break; > default: > DP_ERR(cdev, "Invalid protocol type = %d\n", type); > return; > diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c > index 6dd3ce4..f8a467e 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c > @@ -1104,6 +1104,9 @@ int qed_mcp_get_media_type(struct qed_dev *cdev, u32 *p_media_type) > case FUNC_MF_CFG_PROTOCOL_ISCSI: > *p_proto = QED_PCI_ISCSI; > break; > + case FUNC_MF_CFG_PROTOCOL_FCOE: > + *p_proto = QED_PCI_FCOE; > + break; > case FUNC_MF_CFG_PROTOCOL_ROCE: > DP_NOTICE(p_hwfn, "RoCE personality is not a valid value!\n"); > /* Fallthrough */ > diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h > index 407a2c1..863b9dd 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h > @@ -13,6 +13,7 @@ > #include <linux/delay.h> > #include <linux/slab.h> > #include <linux/spinlock.h> > +#include <linux/qed/qed_fcoe_if.h> > #include "qed_hsi.h" > > struct qed_mcp_link_speed_params { > diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h > index 9754420..4890652 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h > @@ -86,6 +86,8 @@ > 0x1e80000UL > #define NIG_REG_RX_LLH_BRB_GATE_DNTFWD_PERPF \ > 0x5011f4UL > +#define PRS_REG_SEARCH_RESP_INITIATOR_TYPE \ > + 0x1f0164UL > #define PRS_REG_SEARCH_TCP \ > 0x1f0400UL > #define PRS_REG_SEARCH_UDP \ > @@ -96,6 +98,12 @@ > 0x1f040cUL > #define PRS_REG_SEARCH_OPENFLOW \ > 0x1f0434UL > +#define PRS_REG_SEARCH_TAG1 \ > + 0x1f0444UL > +#define PRS_REG_PKT_LEN_STAT_TAGS_NOT_COUNTED_FIRST \ > + 0x1f0a0cUL > +#define PRS_REG_SEARCH_TCP_FIRST_FRAG \ > + 0x1f0410UL > #define TM_REG_PF_ENABLE_CONN \ > 0x2c043cUL > #define TM_REG_PF_ENABLE_TASK \ > diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h b/drivers/net/ethernet/qlogic/qed/qed_sp.h > index 9c897bc..72454c9 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_sp.h > +++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h > @@ -85,6 +85,10 @@ int qed_eth_cqe_completion(struct qed_hwfn *p_hwfn, > struct rdma_srq_destroy_ramrod_data rdma_destroy_srq; > struct rdma_srq_modify_ramrod_data rdma_modify_srq; > struct roce_init_func_ramrod_data roce_init_func; > + struct fcoe_init_ramrod_params fcoe_init; > + struct fcoe_conn_offload_ramrod_params fcoe_conn_ofld; > + struct fcoe_conn_terminate_ramrod_params fcoe_conn_terminate; > + struct fcoe_stat_ramrod_params fcoe_stat; > > struct iscsi_slow_path_hdr iscsi_empty; > struct iscsi_init_ramrod_params iscsi_init; > diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c > index a39ef2e..8b5489b 100644 > --- a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c > +++ b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c > @@ -362,6 +362,9 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn, > case QED_PCI_ETH: > p_ramrod->personality = PERSONALITY_ETH; > break; > + case QED_PCI_FCOE: > + p_ramrod->personality = PERSONALITY_FCOE; > + break; > case QED_PCI_ISCSI: > p_ramrod->personality = PERSONALITY_ISCSI; > break; > diff --git a/include/linux/qed/common_hsi.h b/include/linux/qed/common_hsi.h > index 734deb0..729a882 100644 > --- a/include/linux/qed/common_hsi.h > +++ b/include/linux/qed/common_hsi.h > @@ -37,6 +37,7 @@ > #define COMMON_QUEUE_ENTRY_MAX_BYTE_SIZE 64 > > #define ISCSI_CDU_TASK_SEG_TYPE 0 > +#define FCOE_CDU_TASK_SEG_TYPE 0 > #define RDMA_CDU_TASK_SEG_TYPE 1 > > #define FW_ASSERT_GENERAL_ATTN_IDX 32 > @@ -180,6 +181,9 @@ > #define DQ_XCM_ETH_TX_BD_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD3 > #define DQ_XCM_ETH_TX_BD_PROD_CMD DQ_XCM_AGG_VAL_SEL_WORD4 > #define DQ_XCM_ETH_GO_TO_BD_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD5 > +#define DQ_XCM_FCOE_SQ_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD3 > +#define DQ_XCM_FCOE_SQ_PROD_CMD DQ_XCM_AGG_VAL_SEL_WORD4 > +#define DQ_XCM_FCOE_X_FERQ_PROD_CMD DQ_XCM_AGG_VAL_SEL_WORD5 > #define DQ_XCM_ISCSI_SQ_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD3 > #define DQ_XCM_ISCSI_SQ_PROD_CMD DQ_XCM_AGG_VAL_SEL_WORD4 > #define DQ_XCM_ISCSI_MORE_TO_SEND_SEQ_CMD DQ_XCM_AGG_VAL_SEL_REG3 > @@ -236,6 +240,7 @@ > #define DQ_XCM_ETH_TERMINATE_CMD BIT(DQ_XCM_AGG_FLG_SHIFT_CF19) > #define DQ_XCM_ETH_SLOW_PATH_CMD BIT(DQ_XCM_AGG_FLG_SHIFT_CF22) > #define DQ_XCM_ETH_TPH_EN_CMD BIT(DQ_XCM_AGG_FLG_SHIFT_CF23) > +#define DQ_XCM_FCOE_SLOW_PATH_CMD BIT(DQ_XCM_AGG_FLG_SHIFT_CF22) > #define DQ_XCM_ISCSI_DQ_FLUSH_CMD BIT(DQ_XCM_AGG_FLG_SHIFT_CF19) > #define DQ_XCM_ISCSI_SLOW_PATH_CMD BIT(DQ_XCM_AGG_FLG_SHIFT_CF22) > #define DQ_XCM_ISCSI_PROC_ONLY_CLEANUP_CMD BIT(DQ_XCM_AGG_FLG_SHIFT_CF23) > @@ -266,6 +271,9 @@ > #define DQ_TCM_AGG_FLG_SHIFT_CF6 6 > #define DQ_TCM_AGG_FLG_SHIFT_CF7 7 > /* TCM agg counter flag selection (FW) */ > +#define DQ_TCM_FCOE_FLUSH_Q0_CMD BIT(DQ_TCM_AGG_FLG_SHIFT_CF1) > +#define DQ_TCM_FCOE_DUMMY_TIMER_CMD BIT(DQ_TCM_AGG_FLG_SHIFT_CF2) > +#define DQ_TCM_FCOE_TIMER_STOP_ALL_CMD BIT(DQ_TCM_AGG_FLG_SHIFT_CF3) > #define DQ_TCM_ISCSI_FLUSH_Q0_CMD BIT(DQ_TCM_AGG_FLG_SHIFT_CF1) > #define DQ_TCM_ISCSI_TIMER_STOP_ALL_CMD BIT(DQ_TCM_AGG_FLG_SHIFT_CF3) > > @@ -703,7 +711,7 @@ enum mf_mode { > /* Per-protocol connection types */ > enum protocol_type { > PROTOCOLID_ISCSI, > - PROTOCOLID_RESERVED2, > + PROTOCOLID_FCOE, > PROTOCOLID_ROCE, > PROTOCOLID_CORE, > PROTOCOLID_ETH, > diff --git a/include/linux/qed/fcoe_common.h b/include/linux/qed/fcoe_common.h > new file mode 100644 > index 0000000..2e417a4 > --- /dev/null > +++ b/include/linux/qed/fcoe_common.h > @@ -0,0 +1,715 @@ > +/* QLogic qed NIC Driver > + * Copyright (c) 2015 QLogic Corporation > + * > + * This software is available under the terms of the GNU General Public License > + * (GPL) Version 2, available from the file COPYING in the main directory of > + * this source tree. > + */ > + > +#ifndef __FCOE_COMMON__ > +#define __FCOE_COMMON__ > +/*********************/ > +/* FCOE FW CONSTANTS */ > +/*********************/ > + > +#define FC_ABTS_REPLY_MAX_PAYLOAD_LEN 12 > +#define FCOE_MAX_SIZE_FCP_DATA_SUPER (8600) > + > +struct fcoe_abts_pkt { > + __le32 abts_rsp_fc_payload_lo; > + __le16 abts_rsp_rx_id; > + u8 abts_rsp_rctl; > + u8 reserved2; > +}; > + > +/* FCoE additional WQE (Sq/XferQ) information */ > +union fcoe_additional_info_union { > + __le32 previous_tid; > + __le32 parent_tid; > + __le32 burst_length; > + __le32 seq_rec_updated_offset; > +}; > + > +struct fcoe_exp_ro { > + __le32 data_offset; > + __le32 reserved; > +}; > + > +union fcoe_cleanup_addr_exp_ro_union { > + struct regpair abts_rsp_fc_payload_hi; > + struct fcoe_exp_ro exp_ro; > +}; > + > +/* FCoE Ramrod Command IDs */ > +enum fcoe_completion_status { > + FCOE_COMPLETION_STATUS_SUCCESS, > + FCOE_COMPLETION_STATUS_FCOE_VER_ERR, > + FCOE_COMPLETION_STATUS_SRC_MAC_ADD_ARR_ERR, > + MAX_FCOE_COMPLETION_STATUS > +}; > + > +struct fc_addr_nw { > + u8 addr_lo; > + u8 addr_mid; > + u8 addr_hi; > +}; > + > +/* FCoE connection offload */ > +struct fcoe_conn_offload_ramrod_data { > + struct regpair sq_pbl_addr; > + struct regpair sq_curr_page_addr; > + struct regpair sq_next_page_addr; > + struct regpair xferq_pbl_addr; > + struct regpair xferq_curr_page_addr; > + struct regpair xferq_next_page_addr; > + struct regpair respq_pbl_addr; > + struct regpair respq_curr_page_addr; > + struct regpair respq_next_page_addr; > + __le16 dst_mac_addr_lo; > + __le16 dst_mac_addr_mid; > + __le16 dst_mac_addr_hi; > + __le16 src_mac_addr_lo; > + __le16 src_mac_addr_mid; > + __le16 src_mac_addr_hi; > + __le16 tx_max_fc_pay_len; > + __le16 e_d_tov_timer_val; > + __le16 rx_max_fc_pay_len; > + __le16 vlan_tag; > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_VLAN_ID_MASK 0xFFF > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_VLAN_ID_SHIFT 0 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_CFI_MASK 0x1 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_CFI_SHIFT 12 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_PRIORITY_MASK 0x7 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_PRIORITY_SHIFT 13 > + __le16 physical_q0; > + __le16 rec_rr_tov_timer_val; > + struct fc_addr_nw s_id; > + u8 max_conc_seqs_c3; > + struct fc_addr_nw d_id; > + u8 flags; > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_CONT_INCR_SEQ_CNT_MASK 0x1 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_CONT_INCR_SEQ_CNT_SHIFT 0 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_CONF_REQ_MASK 0x1 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_CONF_REQ_SHIFT 1 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_REC_VALID_MASK 0x1 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_REC_VALID_SHIFT 2 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_VLAN_FLAG_MASK 0x1 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_B_VLAN_FLAG_SHIFT 3 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_MODE_MASK 0x3 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_MODE_SHIFT 4 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_RESERVED0_MASK 0x3 > +#define FCOE_CONN_OFFLOAD_RAMROD_DATA_RESERVED0_SHIFT 6 > + __le16 conn_id; > + u8 def_q_idx; > + u8 reserved[5]; > +}; > + > +/* FCoE terminate connection request */ > +struct fcoe_conn_terminate_ramrod_data { > + struct regpair terminate_params_addr; > +}; > + > +struct fcoe_fast_sgl_ctx { > + struct regpair sgl_start_addr; > + __le32 sgl_byte_offset; > + __le16 task_reuse_cnt; > + __le16 init_offset_in_first_sge; > +}; > + > +struct fcoe_slow_sgl_ctx { > + struct regpair base_sgl_addr; > + __le16 curr_sge_off; > + __le16 remainder_num_sges; > + __le16 curr_sgl_index; > + __le16 reserved; > +}; > + > +struct fcoe_sge { > + struct regpair sge_addr; > + __le16 size; > + __le16 reserved0; > + u8 reserved1[3]; > + u8 is_valid_sge; > +}; > + > +union fcoe_data_desc_ctx { > + struct fcoe_fast_sgl_ctx fast; > + struct fcoe_slow_sgl_ctx slow; > + struct fcoe_sge single_sge; > +}; > + > +union fcoe_dix_desc_ctx { > + struct fcoe_slow_sgl_ctx dix_sgl; > + struct fcoe_sge cached_dix_sge; > +}; > + > +struct fcoe_fcp_cmd_payload { > + __le32 opaque[8]; > +}; > + > +struct fcoe_fcp_rsp_payload { > + __le32 opaque[6]; > +}; > + > +struct fcoe_fcp_xfer_payload { > + __le32 opaque[3]; > +}; > + > +/* FCoE firmware function init */ > +struct fcoe_init_func_ramrod_data { > + struct scsi_init_func_params func_params; > + struct scsi_init_func_queues q_params; > + __le16 mtu; > + __le16 sq_num_pages_in_pbl; > + __le32 reserved; > +}; > + > +/* FCoE: Mode of the connection: Target or Initiator or both */ > +enum fcoe_mode_type { > + FCOE_INITIATOR_MODE = 0x0, > + FCOE_TARGET_MODE = 0x1, > + FCOE_BOTH_OR_NOT_CHOSEN = 0x3, > + MAX_FCOE_MODE_TYPE > +}; > + > +struct fcoe_mstorm_fcoe_task_st_ctx_fp { > + __le16 flags; > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_FP_RSRV0_MASK 0x7FFF > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_FP_RSRV0_SHIFT 0 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_FP_MP_INCLUDE_FC_HEADER_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_FP_MP_INCLUDE_FC_HEADER_SHIFT 15 > + __le16 difDataResidue; > + __le16 parent_id; > + __le16 single_sge_saved_offset; > + __le32 data_2_trns_rem; > + __le32 offset_in_io; > + union fcoe_dix_desc_ctx dix_desc; > + union fcoe_data_desc_ctx data_desc; > +}; > + > +struct fcoe_mstorm_fcoe_task_st_ctx_non_fp { > + __le16 flags; > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_HOST_INTERFACE_MASK 0x3 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_HOST_INTERFACE_SHIFT 0 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIF_TO_PEER_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIF_TO_PEER_SHIFT 2 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_VALIDATE_DIX_APP_TAG_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_VALIDATE_DIX_APP_TAG_SHIFT 3 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_INTERVAL_SIZE_LOG_MASK 0xF > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_INTERVAL_SIZE_LOG_SHIFT 4 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIX_BLOCK_SIZE_MASK 0x3 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIX_BLOCK_SIZE_SHIFT 8 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_RESERVED_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_RESERVED_SHIFT 10 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_HAS_FIRST_PACKET_ARRIVED_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_HAS_FIRST_PACKET_ARRIVED_SHIFT 11 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_VALIDATE_DIX_REF_TAG_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_VALIDATE_DIX_REF_TAG_SHIFT 12 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIX_CACHED_SGE_FLG_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIX_CACHED_SGE_FLG_SHIFT 13 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_OFFSET_IN_IO_VALID_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_OFFSET_IN_IO_VALID_SHIFT 14 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIF_SUPPORTED_MASK 0x1 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_DIF_SUPPORTED_SHIFT 15 > + u8 tx_rx_sgl_mode; > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_TX_SGL_MODE_MASK 0x7 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_TX_SGL_MODE_SHIFT 0 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_RX_SGL_MODE_MASK 0x7 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_RX_SGL_MODE_SHIFT 3 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_RSRV1_MASK 0x3 > +#define FCOE_MSTORM_FCOE_TASK_ST_CTX_NON_FP_RSRV1_SHIFT 6 > + u8 rsrv2; > + __le32 num_prm_zero_read; > + struct regpair rsp_buf_addr; > +}; > + > +struct fcoe_rx_stat { > + struct regpair fcoe_rx_byte_cnt; > + struct regpair fcoe_rx_data_pkt_cnt; > + struct regpair fcoe_rx_xfer_pkt_cnt; > + struct regpair fcoe_rx_other_pkt_cnt; > + __le32 fcoe_silent_drop_pkt_cmdq_full_cnt; > + __le32 fcoe_silent_drop_pkt_rq_full_cnt; > + __le32 fcoe_silent_drop_pkt_crc_error_cnt; > + __le32 fcoe_silent_drop_pkt_task_invalid_cnt; > + __le32 fcoe_silent_drop_total_pkt_cnt; > + __le32 rsrv; > +}; > + > +enum fcoe_sgl_mode { > + FCOE_SLOW_SGL, > + FCOE_SINGLE_FAST_SGE, > + FCOE_2_FAST_SGE, > + FCOE_3_FAST_SGE, > + FCOE_4_FAST_SGE, > + FCOE_MUL_FAST_SGES, > + MAX_FCOE_SGL_MODE > +}; > + > +struct fcoe_stat_ramrod_data { > + struct regpair stat_params_addr; > +}; > + > +struct protection_info_ctx { > + __le16 flags; > +#define PROTECTION_INFO_CTX_HOST_INTERFACE_MASK 0x3 > +#define PROTECTION_INFO_CTX_HOST_INTERFACE_SHIFT 0 > +#define PROTECTION_INFO_CTX_DIF_TO_PEER_MASK 0x1 > +#define PROTECTION_INFO_CTX_DIF_TO_PEER_SHIFT 2 > +#define PROTECTION_INFO_CTX_VALIDATE_DIX_APP_TAG_MASK 0x1 > +#define PROTECTION_INFO_CTX_VALIDATE_DIX_APP_TAG_SHIFT 3 > +#define PROTECTION_INFO_CTX_INTERVAL_SIZE_LOG_MASK 0xF > +#define PROTECTION_INFO_CTX_INTERVAL_SIZE_LOG_SHIFT 4 > +#define PROTECTION_INFO_CTX_VALIDATE_DIX_REF_TAG_MASK 0x1 > +#define PROTECTION_INFO_CTX_VALIDATE_DIX_REF_TAG_SHIFT 8 > +#define PROTECTION_INFO_CTX_RESERVED0_MASK 0x7F > +#define PROTECTION_INFO_CTX_RESERVED0_SHIFT 9 > + u8 dix_block_size; > + u8 dst_size; > +}; > + > +union protection_info_union_ctx { > + struct protection_info_ctx info; > + __le32 value; > +}; > + > +struct fcp_rsp_payload_padded { > + struct fcoe_fcp_rsp_payload rsp_payload; > + __le32 reserved[2]; > +}; > + > +struct fcp_xfer_payload_padded { > + struct fcoe_fcp_xfer_payload xfer_payload; > + __le32 reserved[5]; > +}; > + > +struct fcoe_tx_data_params { > + __le32 data_offset; > + __le32 offset_in_io; > + u8 flags; > +#define FCOE_TX_DATA_PARAMS_OFFSET_IN_IO_VALID_MASK 0x1 > +#define FCOE_TX_DATA_PARAMS_OFFSET_IN_IO_VALID_SHIFT 0 > +#define FCOE_TX_DATA_PARAMS_DROP_DATA_MASK 0x1 > +#define FCOE_TX_DATA_PARAMS_DROP_DATA_SHIFT 1 > +#define FCOE_TX_DATA_PARAMS_AFTER_SEQ_REC_MASK 0x1 > +#define FCOE_TX_DATA_PARAMS_AFTER_SEQ_REC_SHIFT 2 > +#define FCOE_TX_DATA_PARAMS_RESERVED0_MASK 0x1F > +#define FCOE_TX_DATA_PARAMS_RESERVED0_SHIFT 3 > + u8 dif_residual; > + __le16 seq_cnt; > + __le16 single_sge_saved_offset; > + __le16 next_dif_offset; > + __le16 seq_id; > + __le16 reserved3; > +}; > + > +struct fcoe_tx_mid_path_params { > + __le32 parameter; > + u8 r_ctl; > + u8 type; > + u8 cs_ctl; > + u8 df_ctl; > + __le16 rx_id; > + __le16 ox_id; > +}; > + > +struct fcoe_tx_params { > + struct fcoe_tx_data_params data; > + struct fcoe_tx_mid_path_params mid_path; > +}; > + > +union fcoe_tx_info_union_ctx { > + struct fcoe_fcp_cmd_payload fcp_cmd_payload; > + struct fcp_rsp_payload_padded fcp_rsp_payload; > + struct fcp_xfer_payload_padded fcp_xfer_payload; > + struct fcoe_tx_params tx_params; > +}; > + > +struct ystorm_fcoe_task_st_ctx { > + u8 task_type; > + u8 sgl_mode; > +#define YSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE_MASK 0x7 > +#define YSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE_SHIFT 0 > +#define YSTORM_FCOE_TASK_ST_CTX_RSRV_MASK 0x1F > +#define YSTORM_FCOE_TASK_ST_CTX_RSRV_SHIFT 3 > + u8 cached_dix_sge; > + u8 expect_first_xfer; > + __le32 num_pbf_zero_write; > + union protection_info_union_ctx protection_info_union; > + __le32 data_2_trns_rem; > + union fcoe_tx_info_union_ctx tx_info_union; > + union fcoe_dix_desc_ctx dix_desc; > + union fcoe_data_desc_ctx data_desc; > + __le16 ox_id; > + __le16 rx_id; > + __le32 task_rety_identifier; > + __le32 reserved1[2]; > +}; > + > +struct ystorm_fcoe_task_ag_ctx { > + u8 byte0; > + u8 byte1; > + __le16 word0; > + u8 flags0; > +#define YSTORM_FCOE_TASK_AG_CTX_NIBBLE0_MASK 0xF > +#define YSTORM_FCOE_TASK_AG_CTX_NIBBLE0_SHIFT 0 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT0_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT0_SHIFT 4 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT1_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT1_SHIFT 5 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT2_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT2_SHIFT 6 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT3_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT3_SHIFT 7 > + u8 flags1; > +#define YSTORM_FCOE_TASK_AG_CTX_CF0_MASK 0x3 > +#define YSTORM_FCOE_TASK_AG_CTX_CF0_SHIFT 0 > +#define YSTORM_FCOE_TASK_AG_CTX_CF1_MASK 0x3 > +#define YSTORM_FCOE_TASK_AG_CTX_CF1_SHIFT 2 > +#define YSTORM_FCOE_TASK_AG_CTX_CF2SPECIAL_MASK 0x3 > +#define YSTORM_FCOE_TASK_AG_CTX_CF2SPECIAL_SHIFT 4 > +#define YSTORM_FCOE_TASK_AG_CTX_CF0EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_CF0EN_SHIFT 6 > +#define YSTORM_FCOE_TASK_AG_CTX_CF1EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_CF1EN_SHIFT 7 > + u8 flags2; > +#define YSTORM_FCOE_TASK_AG_CTX_BIT4_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_BIT4_SHIFT 0 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE0EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE0EN_SHIFT 1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE1EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE1EN_SHIFT 2 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE2EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE2EN_SHIFT 3 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE3EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE3EN_SHIFT 4 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE4EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE4EN_SHIFT 5 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE5EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE5EN_SHIFT 6 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE6EN_MASK 0x1 > +#define YSTORM_FCOE_TASK_AG_CTX_RULE6EN_SHIFT 7 > + u8 byte2; > + __le32 reg0; > + u8 byte3; > + u8 byte4; > + __le16 rx_id; > + __le16 word2; > + __le16 word3; > + __le16 word4; > + __le16 word5; > + __le32 reg1; > + __le32 reg2; > +}; > + > +struct tstorm_fcoe_task_ag_ctx { > + u8 reserved; > + u8 byte1; > + __le16 icid; > + u8 flags0; > +#define TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE_MASK 0xF > +#define TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE_SHIFT 0 > +#define TSTORM_FCOE_TASK_AG_CTX_EXIST_IN_QM0_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_EXIST_IN_QM0_SHIFT 4 > +#define TSTORM_FCOE_TASK_AG_CTX_BIT1_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_BIT1_SHIFT 5 > +#define TSTORM_FCOE_TASK_AG_CTX_WAIT_ABTS_RSP_F_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_WAIT_ABTS_RSP_F_SHIFT 6 > +#define TSTORM_FCOE_TASK_AG_CTX_VALID_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_VALID_SHIFT 7 > + u8 flags1; > +#define TSTORM_FCOE_TASK_AG_CTX_FALSE_RR_TOV_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_FALSE_RR_TOV_SHIFT 0 > +#define TSTORM_FCOE_TASK_AG_CTX_BIT5_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_BIT5_SHIFT 1 > +#define TSTORM_FCOE_TASK_AG_CTX_REC_RR_TOV_CF_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_REC_RR_TOV_CF_SHIFT 2 > +#define TSTORM_FCOE_TASK_AG_CTX_ED_TOV_CF_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_ED_TOV_CF_SHIFT 4 > +#define TSTORM_FCOE_TASK_AG_CTX_CF2_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_CF2_SHIFT 6 > + u8 flags2; > +#define TSTORM_FCOE_TASK_AG_CTX_TIMER_STOP_ALL_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_TIMER_STOP_ALL_SHIFT 0 > +#define TSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_SHIFT 2 > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_INIT_CF_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_INIT_CF_SHIFT 4 > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_RECOVERY_CF_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_RECOVERY_CF_SHIFT 6 > + u8 flags3; > +#define TSTORM_FCOE_TASK_AG_CTX_UNSOL_COMP_CF_MASK 0x3 > +#define TSTORM_FCOE_TASK_AG_CTX_UNSOL_COMP_CF_SHIFT 0 > +#define TSTORM_FCOE_TASK_AG_CTX_REC_RR_TOV_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_REC_RR_TOV_CF_EN_SHIFT 2 > +#define TSTORM_FCOE_TASK_AG_CTX_ED_TOV_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_ED_TOV_CF_EN_SHIFT 3 > +#define TSTORM_FCOE_TASK_AG_CTX_CF2EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_CF2EN_SHIFT 4 > +#define TSTORM_FCOE_TASK_AG_CTX_TIMER_STOP_ALL_EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_TIMER_STOP_ALL_EN_SHIFT 5 > +#define TSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_EN_SHIFT 6 > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_INIT_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_INIT_CF_EN_SHIFT 7 > + u8 flags4; > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_RECOVERY_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_SEQ_RECOVERY_CF_EN_SHIFT 0 > +#define TSTORM_FCOE_TASK_AG_CTX_UNSOL_COMP_CF_EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_UNSOL_COMP_CF_EN_SHIFT 1 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE0EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE0EN_SHIFT 2 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE1EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE1EN_SHIFT 3 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE2EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE2EN_SHIFT 4 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE3EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE3EN_SHIFT 5 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE4EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE4EN_SHIFT 6 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE5EN_MASK 0x1 > +#define TSTORM_FCOE_TASK_AG_CTX_RULE5EN_SHIFT 7 > + u8 cleanup_state; > + __le16 last_sent_tid; > + __le32 rec_rr_tov_exp_timeout; > + u8 byte3; > + u8 byte4; > + __le16 word2; > + __le16 word3; > + __le16 word4; > + __le32 data_offset_end_of_seq; > + __le32 data_offset_next; > +}; > + > +struct fcoe_tstorm_fcoe_task_st_ctx_read_write { > + union fcoe_cleanup_addr_exp_ro_union cleanup_addr_exp_ro_union; > + __le16 flags; > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_RX_SGL_MODE_MASK 0x7 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_RX_SGL_MODE_SHIFT 0 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_EXP_FIRST_FRAME_MASK 0x1 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_EXP_FIRST_FRAME_SHIFT 3 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_SEQ_ACTIVE_MASK 0x1 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_SEQ_ACTIVE_SHIFT 4 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_SEQ_TIMEOUT_MASK 0x1 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_SEQ_TIMEOUT_SHIFT 5 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_SINGLE_PKT_IN_EX_MASK 0x1 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_SINGLE_PKT_IN_EX_SHIFT 6 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_OOO_RX_SEQ_STAT_MASK 0x1 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_OOO_RX_SEQ_STAT_SHIFT 7 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_CQ_ADD_ADV_MASK 0x3 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_CQ_ADD_ADV_SHIFT 8 > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_RSRV1_MASK 0x3F > +#define FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_RSRV1_SHIFT 10 A very odd way of defining a bitfield ... Why not use a 'normal' bitfield here? > + __le16 seq_cnt; > + u8 seq_id; > + u8 ooo_rx_seq_id; > + __le16 rx_id; > + struct fcoe_abts_pkt abts_data; > + __le32 e_d_tov_exp_timeout_val; > + __le16 ooo_rx_seq_cnt; > + __le16 reserved1; > +}; > + > +struct fcoe_tstorm_fcoe_task_st_ctx_read_only { > + u8 task_type; > + u8 dev_type; > + u8 conf_supported; > + u8 glbl_q_num; > + __le32 cid; > + __le32 fcp_cmd_trns_size; > + __le32 rsrv; > +}; > + > +struct tstorm_fcoe_task_st_ctx { > + struct fcoe_tstorm_fcoe_task_st_ctx_read_write read_write; > + struct fcoe_tstorm_fcoe_task_st_ctx_read_only read_only; > +}; > + > +struct mstorm_fcoe_task_ag_ctx { > + u8 byte0; > + u8 byte1; > + __le16 icid; > + u8 flags0; > +#define MSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE_MASK 0xF > +#define MSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE_SHIFT 0 > +#define MSTORM_FCOE_TASK_AG_CTX_EXIST_IN_QM0_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_EXIST_IN_QM0_SHIFT 4 > +#define MSTORM_FCOE_TASK_AG_CTX_CQE_PLACED_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_CQE_PLACED_SHIFT 5 > +#define MSTORM_FCOE_TASK_AG_CTX_BIT2_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_BIT2_SHIFT 6 > +#define MSTORM_FCOE_TASK_AG_CTX_BIT3_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_BIT3_SHIFT 7 > + u8 flags1; > +#define MSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_MASK 0x3 > +#define MSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_SHIFT 0 > +#define MSTORM_FCOE_TASK_AG_CTX_CF1_MASK 0x3 > +#define MSTORM_FCOE_TASK_AG_CTX_CF1_SHIFT 2 > +#define MSTORM_FCOE_TASK_AG_CTX_CF2_MASK 0x3 > +#define MSTORM_FCOE_TASK_AG_CTX_CF2_SHIFT 4 > +#define MSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_EX_CLEANUP_CF_EN_SHIFT 6 > +#define MSTORM_FCOE_TASK_AG_CTX_CF1EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_CF1EN_SHIFT 7 > + u8 flags2; > +#define MSTORM_FCOE_TASK_AG_CTX_CF2EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_CF2EN_SHIFT 0 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE0EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE0EN_SHIFT 1 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE1EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE1EN_SHIFT 2 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE2EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE2EN_SHIFT 3 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE3EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE3EN_SHIFT 4 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE4EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE4EN_SHIFT 5 > +#define MSTORM_FCOE_TASK_AG_CTX_XFER_PLACEMENT_EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_XFER_PLACEMENT_EN_SHIFT 6 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE6EN_MASK 0x1 > +#define MSTORM_FCOE_TASK_AG_CTX_RULE6EN_SHIFT 7 Bitfield again ... > + u8 cleanup_state; > + __le32 received_bytes; > + u8 byte3; > + u8 glbl_q_num; > + __le16 word1; > + __le16 tid_to_xfer; > + __le16 word3; > + __le16 word4; > + __le16 word5; > + __le32 expected_bytes; > + __le32 reg2; > +}; > + > +struct mstorm_fcoe_task_st_ctx { > + struct fcoe_mstorm_fcoe_task_st_ctx_non_fp non_fp; > + struct fcoe_mstorm_fcoe_task_st_ctx_fp fp; > +}; > + > +struct ustorm_fcoe_task_ag_ctx { > + u8 reserved; > + u8 byte1; > + __le16 icid; > + u8 flags0; > +#define USTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE_MASK 0xF > +#define USTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE_SHIFT 0 > +#define USTORM_FCOE_TASK_AG_CTX_EXIST_IN_QM0_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_EXIST_IN_QM0_SHIFT 4 > +#define USTORM_FCOE_TASK_AG_CTX_BIT1_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_BIT1_SHIFT 5 > +#define USTORM_FCOE_TASK_AG_CTX_CF0_MASK 0x3 > +#define USTORM_FCOE_TASK_AG_CTX_CF0_SHIFT 6 > + u8 flags1; > +#define USTORM_FCOE_TASK_AG_CTX_CF1_MASK 0x3 > +#define USTORM_FCOE_TASK_AG_CTX_CF1_SHIFT 0 > +#define USTORM_FCOE_TASK_AG_CTX_CF2_MASK 0x3 > +#define USTORM_FCOE_TASK_AG_CTX_CF2_SHIFT 2 > +#define USTORM_FCOE_TASK_AG_CTX_CF3_MASK 0x3 > +#define USTORM_FCOE_TASK_AG_CTX_CF3_SHIFT 4 > +#define USTORM_FCOE_TASK_AG_CTX_DIF_ERROR_CF_MASK 0x3 > +#define USTORM_FCOE_TASK_AG_CTX_DIF_ERROR_CF_SHIFT 6 > + u8 flags2; > +#define USTORM_FCOE_TASK_AG_CTX_CF0EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_CF0EN_SHIFT 0 > +#define USTORM_FCOE_TASK_AG_CTX_CF1EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_CF1EN_SHIFT 1 > +#define USTORM_FCOE_TASK_AG_CTX_CF2EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_CF2EN_SHIFT 2 > +#define USTORM_FCOE_TASK_AG_CTX_CF3EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_CF3EN_SHIFT 3 > +#define USTORM_FCOE_TASK_AG_CTX_DIF_ERROR_CF_EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_DIF_ERROR_CF_EN_SHIFT 4 > +#define USTORM_FCOE_TASK_AG_CTX_RULE0EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE0EN_SHIFT 5 > +#define USTORM_FCOE_TASK_AG_CTX_RULE1EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE1EN_SHIFT 6 > +#define USTORM_FCOE_TASK_AG_CTX_RULE2EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE2EN_SHIFT 7 > + u8 flags3; > +#define USTORM_FCOE_TASK_AG_CTX_RULE3EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE3EN_SHIFT 0 > +#define USTORM_FCOE_TASK_AG_CTX_RULE4EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE4EN_SHIFT 1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE5EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE5EN_SHIFT 2 > +#define USTORM_FCOE_TASK_AG_CTX_RULE6EN_MASK 0x1 > +#define USTORM_FCOE_TASK_AG_CTX_RULE6EN_SHIFT 3 > +#define USTORM_FCOE_TASK_AG_CTX_DIF_ERROR_TYPE_MASK 0xF > +#define USTORM_FCOE_TASK_AG_CTX_DIF_ERROR_TYPE_SHIFT 4 My, you really like these definition thingies ... > + __le32 dif_err_intervals; > + __le32 dif_error_1st_interval; > + __le32 global_cq_num; > + __le32 reg3; > + __le32 reg4; > + __le32 reg5; > +}; > + > +struct fcoe_task_context { > + struct ystorm_fcoe_task_st_ctx ystorm_st_context; > + struct tdif_task_context tdif_context; > + struct ystorm_fcoe_task_ag_ctx ystorm_ag_context; > + struct tstorm_fcoe_task_ag_ctx tstorm_ag_context; > + struct timers_context timer_context; > + struct tstorm_fcoe_task_st_ctx tstorm_st_context; > + struct regpair tstorm_st_padding[2]; > + struct mstorm_fcoe_task_ag_ctx mstorm_ag_context; > + struct mstorm_fcoe_task_st_ctx mstorm_st_context; > + struct ustorm_fcoe_task_ag_ctx ustorm_ag_context; > + struct rdif_task_context rdif_context; > +}; > + > +struct fcoe_tx_stat { > + struct regpair fcoe_tx_byte_cnt; > + struct regpair fcoe_tx_data_pkt_cnt; > + struct regpair fcoe_tx_xfer_pkt_cnt; > + struct regpair fcoe_tx_other_pkt_cnt; > +}; > + > +struct fcoe_wqe { > + __le16 task_id; > + __le16 flags; > +#define FCOE_WQE_REQ_TYPE_MASK 0xF > +#define FCOE_WQE_REQ_TYPE_SHIFT 0 > +#define FCOE_WQE_SGL_MODE_MASK 0x7 > +#define FCOE_WQE_SGL_MODE_SHIFT 4 > +#define FCOE_WQE_CONTINUATION_MASK 0x1 > +#define FCOE_WQE_CONTINUATION_SHIFT 7 > +#define FCOE_WQE_INVALIDATE_PTU_MASK 0x1 > +#define FCOE_WQE_INVALIDATE_PTU_SHIFT 8 > +#define FCOE_WQE_SUPER_IO_MASK 0x1 > +#define FCOE_WQE_SUPER_IO_SHIFT 9 > +#define FCOE_WQE_SEND_AUTO_RSP_MASK 0x1 > +#define FCOE_WQE_SEND_AUTO_RSP_SHIFT 10 > +#define FCOE_WQE_RESERVED0_MASK 0x1F > +#define FCOE_WQE_RESERVED0_SHIFT 11 > + union fcoe_additional_info_union additional_info_union; > +}; > + And here... > +struct xfrqe_prot_flags { > + u8 flags; > +#define XFRQE_PROT_FLAGS_PROT_INTERVAL_SIZE_LOG_MASK 0xF > +#define XFRQE_PROT_FLAGS_PROT_INTERVAL_SIZE_LOG_SHIFT 0 > +#define XFRQE_PROT_FLAGS_DIF_TO_PEER_MASK 0x1 > +#define XFRQE_PROT_FLAGS_DIF_TO_PEER_SHIFT 4 > +#define XFRQE_PROT_FLAGS_HOST_INTERFACE_MASK 0x3 > +#define XFRQE_PROT_FLAGS_HOST_INTERFACE_SHIFT 5 > +#define XFRQE_PROT_FLAGS_RESERVED_MASK 0x1 > +#define XFRQE_PROT_FLAGS_RESERVED_SHIFT 7 > +}; > + > +struct fcoe_db_data { > + u8 params; > +#define FCOE_DB_DATA_DEST_MASK 0x3 > +#define FCOE_DB_DATA_DEST_SHIFT 0 > +#define FCOE_DB_DATA_AGG_CMD_MASK 0x3 > +#define FCOE_DB_DATA_AGG_CMD_SHIFT 2 > +#define FCOE_DB_DATA_BYPASS_EN_MASK 0x1 > +#define FCOE_DB_DATA_BYPASS_EN_SHIFT 4 > +#define FCOE_DB_DATA_RESERVED_MASK 0x1 > +#define FCOE_DB_DATA_RESERVED_SHIFT 5 > +#define FCOE_DB_DATA_AGG_VAL_SEL_MASK 0x3 > +#define FCOE_DB_DATA_AGG_VAL_SEL_SHIFT 6 > + u8 agg_flags; > + __le16 sq_prod; > +}; > +#endif /* __FCOE_COMMON__ */ > diff --git a/include/linux/qed/qed_fcoe_if.h b/include/linux/qed/qed_fcoe_if.h > new file mode 100644 > index 0000000..bd6bcb8 > --- /dev/null > +++ b/include/linux/qed/qed_fcoe_if.h > @@ -0,0 +1,145 @@ > +#ifndef _QED_FCOE_IF_H > +#define _QED_FCOE_IF_H > +#include <linux/types.h> > +#include <linux/qed/qed_if.h> > +struct qed_fcoe_stats { > + u64 fcoe_rx_byte_cnt; > + u64 fcoe_rx_data_pkt_cnt; > + u64 fcoe_rx_xfer_pkt_cnt; > + u64 fcoe_rx_other_pkt_cnt; > + u32 fcoe_silent_drop_pkt_cmdq_full_cnt; > + u32 fcoe_silent_drop_pkt_rq_full_cnt; > + u32 fcoe_silent_drop_pkt_crc_error_cnt; > + u32 fcoe_silent_drop_pkt_task_invalid_cnt; > + u32 fcoe_silent_drop_total_pkt_cnt; > + > + u64 fcoe_tx_byte_cnt; > + u64 fcoe_tx_data_pkt_cnt; > + u64 fcoe_tx_xfer_pkt_cnt; > + u64 fcoe_tx_other_pkt_cnt; > +}; > + > +struct qed_dev_fcoe_info { > + struct qed_dev_info common; > + > + void __iomem *primary_dbq_rq_addr; > + void __iomem *secondary_bdq_rq_addr; > +}; > + > +struct qed_fcoe_params_offload { > + dma_addr_t sq_pbl_addr; > + dma_addr_t sq_curr_page_addr; > + dma_addr_t sq_next_page_addr; > + > + u8 src_mac[ETH_ALEN]; > + u8 dst_mac[ETH_ALEN]; > + > + u16 tx_max_fc_pay_len; > + u16 e_d_tov_timer_val; > + u16 rec_tov_timer_val; > + u16 rx_max_fc_pay_len; > + u16 vlan_tag; > + > + struct fc_addr_nw s_id; > + u8 max_conc_seqs_c3; > + struct fc_addr_nw d_id; > + u8 flags; > + u8 def_q_idx; > +}; > + > +#define MAX_TID_BLOCKS_FCOE (512) > +struct qed_fcoe_tid { > + u32 size; /* In bytes per task */ > + u32 num_tids_per_block; > + u8 *blocks[MAX_TID_BLOCKS_FCOE]; > +}; > + > +struct qed_fcoe_cb_ops { > + struct qed_common_cb_ops common; > + u32 (*get_login_failures)(void *cookie); > +}; > + > +void qed_fcoe_set_pf_params(struct qed_dev *cdev, > + struct qed_fcoe_pf_params *params); > + > +/** > + * struct qed_fcoe_ops - qed FCoE operations. > + * @common: common operations pointer > + * @fill_dev_info: fills FCoE specific information > + * @param cdev > + * @param info > + * @return 0 on sucesss, otherwise error value. > + * @register_ops: register FCoE operations > + * @param cdev > + * @param ops - specified using qed_iscsi_cb_ops > + * @param cookie - driver private > + * @ll2: light L2 operations pointer > + * @start: fcoe in FW > + * @param cdev > + * @param tasks - qed will fill information about tasks > + * return 0 on success, otherwise error value. > + * @stop: stops fcoe in FW > + * @param cdev > + * return 0 on success, otherwise error value. > + * @acquire_conn: acquire a new fcoe connection > + * @param cdev > + * @param handle - qed will fill handle that should be > + * used henceforth as identifier of the > + * connection. > + * @param p_doorbell - qed will fill the address of the > + * doorbell. > + * return 0 on sucesss, otherwise error value. > + * @release_conn: release a previously acquired fcoe connection > + * @param cdev > + * @param handle - the connection handle. > + * return 0 on success, otherwise error value. > + * @offload_conn: configures an offloaded connection > + * @param cdev > + * @param handle - the connection handle. > + * @param conn_info - the configuration to use for the > + * offload. > + * return 0 on success, otherwise error value. > + * @destroy_conn: stops an offloaded connection > + * @param cdev > + * @param handle - the connection handle. > + * @param terminate_params > + * return 0 on success, otherwise error value. > + * @get_stats: gets FCoE related statistics > + * @param cdev > + * @param stats - pointer to struck that would be filled > + * we stats > + * return 0 on success, error otherwise. > + */ > +struct qed_fcoe_ops { > + const struct qed_common_ops *common; > + > + int (*fill_dev_info)(struct qed_dev *cdev, > + struct qed_dev_fcoe_info *info); > + > + void (*register_ops)(struct qed_dev *cdev, > + struct qed_fcoe_cb_ops *ops, void *cookie); > + > + const struct qed_ll2_ops *ll2; > + > + int (*start)(struct qed_dev *cdev, struct qed_fcoe_tid *tasks); > + > + int (*stop)(struct qed_dev *cdev); > + > + int (*acquire_conn)(struct qed_dev *cdev, > + u32 *handle, > + u32 *fw_cid, void __iomem **p_doorbell); > + > + int (*release_conn)(struct qed_dev *cdev, u32 handle); > + > + int (*offload_conn)(struct qed_dev *cdev, > + u32 handle, > + struct qed_fcoe_params_offload *conn_info); > + int (*destroy_conn)(struct qed_dev *cdev, > + u32 handle, dma_addr_t terminate_params); > + > + int (*get_stats)(struct qed_dev *cdev, struct qed_fcoe_stats *stats); > +}; > + I prefer to have to comments directly above the function prototypes; that is easier to read and requires editing in one place only; this way there's a higher likelyhood of both getting out of sync. But that may be personal preference only. > +const struct qed_fcoe_ops *qed_get_fcoe_ops(void); > +void qed_put_fcoe_ops(void); > +#endif > diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h > index 4b454f4..ecdcfec 100644 > --- a/include/linux/qed/qed_if.h > +++ b/include/linux/qed/qed_if.h > @@ -159,6 +159,38 @@ struct qed_eth_pf_params { > u16 num_cons; > }; > > +struct qed_fcoe_pf_params { > + /* The following parameters are used during protocol-init */ > + u64 glbl_q_params_addr; > + u64 bdq_pbl_base_addr[2]; > + > + /* The following parameters are used during HW-init > + * and these parameters need to be passed as arguments > + * to update_pf_params routine invoked before slowpath start > + */ > + u16 num_cons; > + u16 num_tasks; > + > + /* The following parameters are used during protocol-init */ > + u16 sq_num_pbl_pages; > + > + u16 cq_num_entries; > + u16 cmdq_num_entries; > + u16 rq_buffer_log_size; > + u16 mtu; > + u16 dummy_icid; > + u16 bdq_xoff_threshold[2]; > + u16 bdq_xon_threshold[2]; > + u16 rq_buffer_size; > + u8 num_cqs; /* num of global CQs */ > + u8 log_page_size; > + u8 gl_rq_pi; > + u8 gl_cmd_pi; > + u8 debug_mode; > + u8 is_target; > + u8 bdq_pbl_num_entries[2]; > +}; > + > /* Most of the the parameters below are described in the FW iSCSI / TCP HSI */ > struct qed_iscsi_pf_params { > u64 glbl_q_params_addr; > @@ -222,6 +254,7 @@ struct qed_rdma_pf_params { > > struct qed_pf_params { > struct qed_eth_pf_params eth_pf_params; > + struct qed_fcoe_pf_params fcoe_pf_params; > struct qed_iscsi_pf_params iscsi_pf_params; > struct qed_rdma_pf_params rdma_pf_params; > }; > @@ -282,6 +315,7 @@ enum qed_sb_type { > enum qed_protocol { > QED_PROTOCOL_ETH, > QED_PROTOCOL_ISCSI, > + QED_PROTOCOL_FCOE, > }; > > enum qed_link_mode_bits { > @@ -368,6 +402,7 @@ struct qed_int_info { > struct qed_common_cb_ops { > void (*link_update)(void *dev, > struct qed_link_output *link); > + void (*dcbx_aen)(void *dev, struct qed_dcbx_get *get, u32 mib_type); > }; > > struct qed_selftest_ops { > @@ -471,6 +506,10 @@ struct qed_common_ops { > > void (*simd_handler_clean)(struct qed_dev *cdev, > int index); > + int (*dbg_grc)(struct qed_dev *cdev, > + void *buffer, u32 *num_dumped_bytes); > + > + int (*dbg_grc_size)(struct qed_dev *cdev); > > int (*dbg_all_data) (struct qed_dev *cdev, void *buffer); > > Cheers, Hannes -- Dr. Hannes Reinecke zSeries & Storage hare@xxxxxxx +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html