/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, v.1, (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://opensource.org/licenses/CDDL-1.0. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2014-2017 Cavium, Inc. * The contents of this file are subject to the terms of the Common Development * and Distribution License, v.1, (the "License"). * You may not use this file except in compliance with the License. * You can obtain a copy of the License at available * at http://opensource.org/licenses/CDDL-1.0 * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __ECORE_RDMA_H__ #define __ECORE_RDMA_H__ #include "ecore_status.h" #include "ecore.h" #include "ecore_hsi_common.h" #include "ecore_proto_if.h" #include "ecore_roce_api.h" #include "ecore_dev_api.h" /* Constants */ /* HW/FW RoCE Limitations (internal. For external see ecore_rdma_api.h) */ #define ECORE_RDMA_MAX_FMR (RDMA_MAX_TIDS) /* 2^17 - 1 */ #define ECORE_RDMA_MAX_P_KEY (1) #define ECORE_RDMA_MAX_WQE (0x7FFF) /* 2^15 -1 */ #define ECORE_RDMA_MAX_SRQ_WQE_ELEM (0x7FFF) /* 2^15 -1 */ #define ECORE_RDMA_PAGE_SIZE_CAPS (0xFFFFF000) /* TODO: > 4k?! */ #define ECORE_RDMA_ACK_DELAY (15) /* 131 milliseconds */ #define ECORE_RDMA_MAX_MR_SIZE (0x10000000000ULL) /* 2^40 */ #define ECORE_RDMA_MAX_CQS (RDMA_MAX_CQS) /* 64k */ #define ECORE_RDMA_MAX_MRS (RDMA_MAX_TIDS) /* 2^17 - 1 */ /* Add 1 for header element */ #define ECORE_RDMA_MAX_SRQ_ELEM_PER_WQE (RDMA_MAX_SGE_PER_RQ_WQE + 1) #define ECORE_RDMA_MAX_SGE_PER_SRQ_WQE (RDMA_MAX_SGE_PER_RQ_WQE) #define ECORE_RDMA_SRQ_WQE_ELEM_SIZE (16) #define ECORE_RDMA_MAX_SRQS (32 * 1024) /* 32k */ /* Configurable */ /* Max CQE is derived from u16/32 size, halved and decremented by 1 to handle * wrap properly and then decremented by 1 again. The latter decrement comes * from a requirement to create a chain that is bigger than what the user * requested by one: * The CQE size is 32 bytes but the FW writes in chunks of 64 * bytes, for performance purposes. Allocating an extra entry and telling the * FW we have less prevents overwriting the first entry in case of a wrap i.e. * when the FW writes the last entry and the application hasn't read the first * one. */ #define ECORE_RDMA_MAX_CQE_32_BIT (0x7FFFFFFF - 1) #define ECORE_RDMA_MAX_CQE_16_BIT (0x7FFF - 1) enum ecore_rdma_toggle_bit { ECORE_RDMA_TOGGLE_BIT_CLEAR = 0, ECORE_RDMA_TOGGLE_BIT_SET = 1 }; /* @@@TBD Currently we support only affilited events * enum ecore_rdma_unaffiliated_event_code { * ECORE_RDMA_PORT_ACTIVE, // Link Up * ECORE_RDMA_PORT_CHANGED, // SGID table has changed * ECORE_RDMA_LOCAL_CATASTROPHIC_ERR, // Fatal device error * ECORE_RDMA_PORT_ERR, // Link down * }; */ #define QEDR_MAX_BMAP_NAME (10) struct ecore_bmap { u32 max_count; unsigned long *bitmap; char name[QEDR_MAX_BMAP_NAME]; }; /* functions for enabling/disabling edpm in rdma PFs according to existence of * qps during DCBx update or bar size */ void ecore_roce_dpm_dcbx(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt); void ecore_rdma_dpm_bar(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt); #ifdef CONFIG_ECORE_IWARP #define ECORE_IWARP_PREALLOC_CNT (256) #define ECORE_IWARP_LL2_SYN_TX_SIZE (128) #define ECORE_IWARP_LL2_SYN_RX_SIZE (256) #define ECORE_IWARP_LL2_OOO_DEF_TX_SIZE (256) #define ECORE_IWARP_LL2_OOO_DEF_RX_SIZE (4096) #define ECORE_IWARP_LL2_OOO_MAX_RX_SIZE (16384) #define ECORE_IWARP_MAX_SYN_PKT_SIZE (128) #define ECORE_IWARP_HANDLE_INVAL (0xff) struct ecore_iwarp_ll2_buff { struct ecore_iwarp_ll2_buff *piggy_buf; void *data; dma_addr_t data_phys_addr; u32 buff_size; }; struct ecore_iwarp_ll2_mpa_buf { osal_list_entry_t list_entry; struct ecore_iwarp_ll2_buff *ll2_buf; struct unaligned_opaque_data data; u16 tcp_payload_len; u8 placement_offset; }; /* In some cases a fpdu will arrive with only one byte of the header, in this * case the fpdu_length will be partial ( contain only higher byte and * incomplete bytes will contain the invalid value */ #define ECORE_IWARP_INVALID_INCOMPLETE_BYTES 0xffff struct ecore_iwarp_fpdu { struct ecore_iwarp_ll2_buff *mpa_buf; dma_addr_t pkt_hdr; u8 pkt_hdr_size; dma_addr_t mpa_frag; void *mpa_frag_virt; u16 mpa_frag_len; u16 fpdu_length; u16 incomplete_bytes; }; struct ecore_iwarp_info { osal_list_t listen_list; /* ecore_iwarp_listener */ osal_list_t ep_list; /* ecore_iwarp_ep */ osal_list_t ep_free_list;/* pre-allocated ep's */ osal_list_t mpa_buf_list;/* list of mpa_bufs */ osal_list_t mpa_buf_pending_list; osal_spinlock_t iw_lock; osal_spinlock_t qp_lock; /* for teardown races */ struct iwarp_rxmit_stats_drv stats; u32 rcv_wnd_scale; u16 max_mtu; u16 num_ooo_rx_bufs; u8 mac_addr[ETH_ALEN]; u8 crc_needed; u8 tcp_flags; u8 ll2_syn_handle; u8 ll2_ooo_handle; u8 ll2_mpa_handle; u8 peer2peer; u8 _pad; enum mpa_negotiation_mode mpa_rev; enum mpa_rtr_type rtr_type; struct ecore_iwarp_fpdu *partial_fpdus; struct ecore_iwarp_ll2_mpa_buf *mpa_bufs; u8 *mpa_intermediate_buf; u16 max_num_partial_fpdus; /* MPA statistics */ u64 unalign_rx_comp; }; #endif #define IS_ECORE_DCQCN(p_hwfn) \ (!!(p_hwfn->pf_params.rdma_pf_params.enable_dcqcn)) struct ecore_roce_info { struct roce_events_stats event_stats; u8 dcqcn_enabled; u8 dcqcn_reaction_point; }; struct ecore_rdma_info { osal_spinlock_t lock; struct ecore_bmap cq_map; struct ecore_bmap pd_map; struct ecore_bmap tid_map; struct ecore_bmap srq_map; struct ecore_bmap cid_map; struct ecore_bmap tcp_cid_map; struct ecore_bmap real_cid_map; struct ecore_bmap dpi_map; struct ecore_bmap toggle_bits; struct ecore_rdma_events events; struct ecore_rdma_device *dev; struct ecore_rdma_port *port; u32 last_tid; u8 num_cnqs; struct rdma_sent_stats rdma_sent_pstats; struct rdma_rcv_stats rdma_rcv_tstats; u32 num_qps; u32 num_mrs; u32 num_srqs; u16 queue_zone_base; u16 max_queue_zones; enum protocol_type proto; struct ecore_roce_info roce; #ifdef CONFIG_ECORE_IWARP struct ecore_iwarp_info iwarp; #endif bool active; int ref_cnt; }; #ifdef CONFIG_ECORE_IWARP enum ecore_iwarp_qp_state { ECORE_IWARP_QP_STATE_IDLE, ECORE_IWARP_QP_STATE_RTS, ECORE_IWARP_QP_STATE_TERMINATE, ECORE_IWARP_QP_STATE_CLOSING, ECORE_IWARP_QP_STATE_ERROR, }; #endif struct ecore_rdma_qp { struct regpair qp_handle; struct regpair qp_handle_async; u32 qpid; /* iwarp: may differ from icid */ u16 icid; enum ecore_roce_qp_state cur_state; #ifdef CONFIG_ECORE_IWARP enum ecore_iwarp_qp_state iwarp_state; #endif bool use_srq; bool signal_all; bool fmr_and_reserved_lkey; bool incoming_rdma_read_en; bool incoming_rdma_write_en; bool incoming_atomic_en; bool e2e_flow_control_en; u16 pd; /* Protection domain */ u16 pkey; /* Primary P_key index */ u32 dest_qp; u16 mtu; u16 srq_id; u8 traffic_class_tos; /* IPv6/GRH traffic class; IPv4 TOS */ u8 hop_limit_ttl; /* IPv6/GRH hop limit; IPv4 TTL */ u16 dpi; u32 flow_label; /* ignored in IPv4 */ u16 vlan_id; u32 ack_timeout; u8 retry_cnt; u8 rnr_retry_cnt; u8 min_rnr_nak_timer; bool sqd_async; union ecore_gid sgid; /* GRH SGID; IPv4/6 Source IP */ union ecore_gid dgid; /* GRH DGID; IPv4/6 Destination IP */ enum roce_mode roce_mode; u16 udp_src_port; /* RoCEv2 only */ u8 stats_queue; /* requeseter */ u8 max_rd_atomic_req; u32 sq_psn; u16 sq_cq_id; /* The cq to be associated with the send queue*/ u16 sq_num_pages; dma_addr_t sq_pbl_ptr; void *orq; dma_addr_t orq_phys_addr; u8 orq_num_pages; bool req_offloaded; /* responder */ u8 max_rd_atomic_resp; u32 rq_psn; u16 rq_cq_id; /* The cq to be associated with the receive queue */ u16 rq_num_pages; dma_addr_t rq_pbl_ptr; void *irq; dma_addr_t irq_phys_addr; u8 irq_num_pages; bool resp_offloaded; u32 cq_prod; u8 remote_mac_addr[6]; u8 local_mac_addr[6]; void *shared_queue; dma_addr_t shared_queue_phys_addr; #ifdef CONFIG_ECORE_IWARP struct ecore_iwarp_ep *ep; #endif }; #ifdef CONFIG_ECORE_IWARP enum ecore_iwarp_ep_state { ECORE_IWARP_EP_INIT, ECORE_IWARP_EP_MPA_REQ_RCVD, ECORE_IWARP_EP_MPA_OFFLOADED, ECORE_IWARP_EP_ESTABLISHED, ECORE_IWARP_EP_CLOSED }; union async_output { struct iwarp_eqe_data_mpa_async_completion mpa_response; struct iwarp_eqe_data_tcp_async_completion mpa_request; }; /* Endpoint structure represents a TCP connection. This connection can be * associated with a QP or not (in which case QP==NULL) */ struct ecore_iwarp_ep { osal_list_entry_t list_entry; int sig; struct ecore_rdma_qp *qp; enum ecore_iwarp_ep_state state; /* This contains entire buffer required for ep memories. This is the * only one actually allocated and freed. The rest are pointers into * this buffer */ void *ep_buffer_virt; dma_addr_t ep_buffer_phys; /* Asynce EQE events contain only the ep pointer on the completion. The * rest of the data is written to an output buffer pre-allocated by * the driver. This buffer points to a location in the ep_buffer. */ union async_output *async_output_virt; dma_addr_t async_output_phys; struct ecore_iwarp_cm_info cm_info; enum tcp_connect_mode connect_mode; enum mpa_rtr_type rtr_type; enum mpa_negotiation_mode mpa_rev; u32 tcp_cid; u32 cid; u8 remote_mac_addr[6]; u8 local_mac_addr[6]; u16 mss; bool mpa_reply_processed; /* The event_cb function is called for asynchrounous events associated * with the ep. It is initialized at different entry points depending * on whether the ep is the tcp connection active side or passive side * The cb_context is passed to the event_cb function. */ iwarp_event_handler event_cb; void *cb_context; /* For Passive side - syn packet related data */ struct ecore_iwarp_ll2_buff *syn; u16 syn_ip_payload_length; dma_addr_t syn_phy_addr; }; struct ecore_iwarp_listener { osal_list_entry_t list_entry; /* The event_cb function is called for connection requests. * The cb_context is passed to the event_cb function. */ iwarp_event_handler event_cb; void *cb_context; u32 max_backlog; u8 ip_version; u32 ip_addr[4]; u16 port; u16 vlan; }; void ecore_iwarp_async_event(struct ecore_hwfn *p_hwfn, u8 fw_event_code, struct regpair *fw_handle, u8 fw_return_code); #endif /* CONFIG_ECORE_IWARP */ void ecore_roce_async_event(struct ecore_hwfn *p_hwfn, u8 fw_event_code, union rdma_eqe_data *rdma_data); enum _ecore_status_t ecore_rdma_info_alloc(struct ecore_hwfn *p_hwfn); void ecore_rdma_info_free(struct ecore_hwfn *p_hwfn); #endif /*__ECORE_RDMA_H__*/