1/************************************************************************** 2 3Copyright (c) 2007, 2008 Chelsio Inc. 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Neither the name of the Chelsio Corporation nor the names of its 13 contributors may be used to endorse or promote products derived from 14 this software without specific prior written permission. 15 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26POSSIBILITY OF SUCH DAMAGE. 27 28$FreeBSD: stable/10/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h 309378 2016-12-01 23:38:52Z jhb $ 29 30***************************************************************************/ 31 32#ifndef _IWCH_CM_H_ 33#define _IWCH_CM_H_ 34#include <rdma/ib_verbs.h> 35#include <rdma/iw_cm.h> 36#include <sys/refcount.h> 37#include <sys/condvar.h> 38#include <sys/proc.h> 39 40 41#define MPA_KEY_REQ "MPA ID Req Frame" 42#define MPA_KEY_REP "MPA ID Rep Frame" 43 44#define MPA_MAX_PRIVATE_DATA 256 45#define MPA_REV 0 /* XXX - amso1100 uses rev 0 ! */ 46#define MPA_REJECT 0x20 47#define MPA_CRC 0x40 48#define MPA_MARKERS 0x80 49#define MPA_FLAGS_MASK 0xE0 50 51#define put_ep(ep) { \ 52 CTR4(KTR_IW_CXGB, "put_ep (via %s:%u) ep %p refcnt %d", __FUNCTION__, __LINE__, \ 53 ep, atomic_load_acq_int(&((ep)->refcount))); \ 54 if (refcount_release(&((ep)->refcount))) \ 55 __free_ep(ep); \ 56} 57 58#define get_ep(ep) { \ 59 CTR4(KTR_IW_CXGB, "get_ep (via %s:%u) ep %p, refcnt %d", __FUNCTION__, __LINE__, \ 60 ep, atomic_load_acq_int(&((ep)->refcount))); \ 61 refcount_acquire(&((ep)->refcount)); \ 62} 63 64struct mpa_message { 65 u8 key[16]; 66 u8 flags; 67 u8 revision; 68 __be16 private_data_size; 69 u8 private_data[0]; 70}; 71 72struct terminate_message { 73 u8 layer_etype; 74 u8 ecode; 75 __be16 hdrct_rsvd; 76 u8 len_hdrs[0]; 77}; 78 79#define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28) 80 81enum iwch_layers_types { 82 LAYER_RDMAP = 0x00, 83 LAYER_DDP = 0x10, 84 LAYER_MPA = 0x20, 85 RDMAP_LOCAL_CATA = 0x00, 86 RDMAP_REMOTE_PROT = 0x01, 87 RDMAP_REMOTE_OP = 0x02, 88 DDP_LOCAL_CATA = 0x00, 89 DDP_TAGGED_ERR = 0x01, 90 DDP_UNTAGGED_ERR = 0x02, 91 DDP_LLP = 0x03 92}; 93 94enum iwch_rdma_ecodes { 95 RDMAP_INV_STAG = 0x00, 96 RDMAP_BASE_BOUNDS = 0x01, 97 RDMAP_ACC_VIOL = 0x02, 98 RDMAP_STAG_NOT_ASSOC = 0x03, 99 RDMAP_TO_WRAP = 0x04, 100 RDMAP_INV_VERS = 0x05, 101 RDMAP_INV_OPCODE = 0x06, 102 RDMAP_STREAM_CATA = 0x07, 103 RDMAP_GLOBAL_CATA = 0x08, 104 RDMAP_CANT_INV_STAG = 0x09, 105 RDMAP_UNSPECIFIED = 0xff 106}; 107 108enum iwch_ddp_ecodes { 109 DDPT_INV_STAG = 0x00, 110 DDPT_BASE_BOUNDS = 0x01, 111 DDPT_STAG_NOT_ASSOC = 0x02, 112 DDPT_TO_WRAP = 0x03, 113 DDPT_INV_VERS = 0x04, 114 DDPU_INV_QN = 0x01, 115 DDPU_INV_MSN_NOBUF = 0x02, 116 DDPU_INV_MSN_RANGE = 0x03, 117 DDPU_INV_MO = 0x04, 118 DDPU_MSG_TOOBIG = 0x05, 119 DDPU_INV_VERS = 0x06 120}; 121 122enum iwch_mpa_ecodes { 123 MPA_CRC_ERR = 0x02, 124 MPA_MARKER_ERR = 0x03 125}; 126 127enum iwch_ep_state { 128 IDLE = 0, 129 LISTEN, 130 CONNECTING, 131 MPA_REQ_WAIT, 132 MPA_REQ_SENT, 133 MPA_REQ_RCVD, 134 MPA_REP_SENT, 135 FPDU_MODE, 136 ABORTING, 137 CLOSING, 138 MORIBUND, 139 DEAD, 140}; 141 142enum iwch_ep_flags { 143 PEER_ABORT_IN_PROGRESS = (1 << 0), 144 ABORT_REQ_IN_PROGRESS = (1 << 1), 145}; 146 147struct iwch_ep_common { 148 TAILQ_ENTRY(iwch_ep_common) entry; 149 struct iw_cm_id *cm_id; 150 struct iwch_qp *qp; 151 struct toedev *tdev; 152 enum iwch_ep_state state; 153 u_int refcount; 154 struct cv waitq; 155 struct mtx lock; 156 struct sockaddr_in local_addr; 157 struct sockaddr_in remote_addr; 158 int rpl_err; 159 int rpl_done; 160 struct thread *thread; 161 struct socket *so; 162}; 163 164struct iwch_listen_ep { 165 struct iwch_ep_common com; 166 unsigned int stid; 167 int backlog; 168}; 169 170struct iwch_ep { 171 struct iwch_ep_common com; 172 struct iwch_ep *parent_ep; 173 struct callout timer; 174 unsigned int atid; 175 u32 hwtid; 176 u32 snd_seq; 177 u32 rcv_seq; 178 struct l2t_entry *l2t; 179 struct mbuf *mpa_mbuf; 180 struct iwch_mpa_attributes mpa_attr; 181 unsigned int mpa_pkt_len; 182 u8 mpa_pkt[sizeof(struct mpa_message) + MPA_MAX_PRIVATE_DATA]; 183 u8 tos; 184 u16 emss; 185 u16 plen; 186 u32 ird; 187 u32 ord; 188 u32 flags; 189}; 190 191static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id) 192{ 193 return cm_id->provider_data; 194} 195 196static inline struct iwch_listen_ep *to_listen_ep(struct iw_cm_id *cm_id) 197{ 198 return cm_id->provider_data; 199} 200 201static inline int compute_wscale(int win) 202{ 203 int wscale = 0; 204 205 while (wscale < 14 && (65535<<wscale) < win) 206 wscale++; 207 return wscale; 208} 209 210static __inline void 211iwch_wait(struct cv *cv, struct mtx *lock, int *rpl_done) 212{ 213 mtx_lock(lock); 214 if (!*rpl_done) { 215 CTR0(KTR_IW_CXGB, "sleeping for rpl_done\n"); 216 cv_wait_unlock(cv, lock); 217 } 218 CTR1(KTR_IW_CXGB, "*rpl_done=%d\n", *rpl_done); 219} 220 221static __inline void 222iwch_wakeup(struct cv *cv, struct mtx *lock, int *rpl_done) 223{ 224 mtx_lock(lock); 225 *rpl_done=1; 226 CTR0(KTR_IW_CXGB, "wakeup for rpl_done\n"); 227 cv_broadcast(cv); 228 mtx_unlock(lock); 229} 230 231/* CM prototypes */ 232 233int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param); 234int iwch_create_listen_ep(struct iw_cm_id *cm_id, int backlog); 235void iwch_destroy_listen_ep(struct iw_cm_id *cm_id); 236int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len); 237int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param); 238int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, int flags); 239void __free_ep(struct iwch_ep_common *ep); 240void iwch_rearp(struct iwch_ep *ep); 241int iwch_ep_redirect(void *ctx, struct rtentry *old, struct rtentry *new, struct l2t_entry *l2t); 242 243int iwch_cm_init(void); 244void iwch_cm_term(void); 245void iwch_cm_init_cpl(struct adapter *); 246void iwch_cm_term_cpl(struct adapter *); 247 248#endif /* _IWCH_CM_H_ */ 249