1 /**************************************************************************
3 Copyright (c) 2007, 2008 Chelsio Inc.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
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.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
30 ***************************************************************************/
34 #include <contrib/rdma/ib_verbs.h>
35 #include <contrib/rdma/iw_cm.h>
36 #include <sys/refcount.h>
37 #include <sys/condvar.h>
41 #define MPA_KEY_REQ "MPA ID Req Frame"
42 #define MPA_KEY_REP "MPA ID Rep Frame"
44 #define MPA_MAX_PRIVATE_DATA 256
45 #define MPA_REV o0 /* XXX - amso1100 uses rev 0 ! */
46 #define MPA_REJECT 0x20
48 #define MPA_MARKERS 0x80
49 #define MPA_FLAGS_MASK 0xE0
51 #define put_ep(ep) { \
52 CTR4(KTR_IW_CXGB, "put_ep (via %s:%u) ep %p refcnt %d\n", __FUNCTION__, __LINE__, \
53 ep, atomic_load_acq_int(&((ep)->refcount))); \
54 if (refcount_release(&((ep)->refcount))) \
58 #define get_ep(ep) { \
59 CTR4(KTR_IW_CXGB, "get_ep (via %s:%u) ep %p, refcnt %d\n", __FUNCTION__, __LINE__, \
60 ep, atomic_load_acq_int(&((ep)->refcount))); \
61 refcount_acquire(&((ep)->refcount)); \
68 __be16 private_data_size;
72 struct terminate_message {
79 #define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28)
81 enum iwch_layers_types {
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,
94 enum iwch_rdma_ecodes {
95 RDMAP_INV_STAG = 0x00,
96 RDMAP_BASE_BOUNDS = 0x01,
97 RDMAP_ACC_VIOL = 0x02,
98 RDMAP_STAG_NOT_ASSOC = 0x03,
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
108 enum iwch_ddp_ecodes {
109 DDPT_INV_STAG = 0x00,
110 DDPT_BASE_BOUNDS = 0x01,
111 DDPT_STAG_NOT_ASSOC = 0x02,
113 DDPT_INV_VERS = 0x04,
115 DDPU_INV_MSN_NOBUF = 0x02,
116 DDPU_INV_MSN_RANGE = 0x03,
118 DDPU_MSG_TOOBIG = 0x05,
122 enum iwch_mpa_ecodes {
124 MPA_MARKER_ERR = 0x03
143 PEER_ABORT_IN_PROGRESS = (1 << 0),
144 ABORT_REQ_IN_PROGRESS = (1 << 1),
147 struct iwch_ep_common {
148 TAILQ_ENTRY(iwch_ep_common) entry;
149 struct iw_cm_id *cm_id;
152 enum iwch_ep_state state;
156 struct sockaddr_in local_addr;
157 struct sockaddr_in remote_addr;
160 struct thread *thread;
164 struct iwch_listen_ep {
165 struct iwch_ep_common com;
171 struct iwch_ep_common com;
172 struct iwch_ep *parent_ep;
173 struct callout timer;
178 struct l2t_entry *l2t;
180 struct mbuf *mpa_mbuf;
181 struct iwch_mpa_attributes mpa_attr;
182 unsigned int mpa_pkt_len;
183 u8 mpa_pkt[sizeof(struct mpa_message) + MPA_MAX_PRIVATE_DATA];
192 static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
194 return cm_id->provider_data;
197 static inline struct iwch_listen_ep *to_listen_ep(struct iw_cm_id *cm_id)
199 return cm_id->provider_data;
202 static inline int compute_wscale(int win)
206 while (wscale < 14 && (65535<<wscale) < win)
212 iwch_wait(struct cv *cv, struct mtx *lock, int *rpl_done)
216 CTR0(KTR_IW_CXGB, "sleeping for rpl_done\n");
217 cv_wait_unlock(cv, lock);
219 CTR1(KTR_IW_CXGB, "*rpl_done=%d\n", *rpl_done);
223 iwch_wakeup(struct cv *cv, struct mtx *lock, int *rpl_done)
227 CTR0(KTR_IW_CXGB, "wakeup for rpl_done\n");
234 int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
235 int iwch_create_listen(struct iw_cm_id *cm_id, int backlog);
236 int iwch_destroy_listen(struct iw_cm_id *cm_id);
237 int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
238 int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
239 int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, int flags);
240 int iwch_quiesce_tid(struct iwch_ep *ep);
241 int iwch_resume_tid(struct iwch_ep *ep);
242 void __free_ep(struct iwch_ep_common *ep);
243 void iwch_rearp(struct iwch_ep *ep);
244 int iwch_ep_redirect(void *ctx, struct rtentry *old, struct rtentry *new, struct l2t_entry *l2t);
246 int iwch_cm_init(void);
247 void iwch_cm_term(void);
249 #endif /* _IWCH_CM_H_ */