1/* 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32#ifndef _IWCH_CM_H_ 33#define _IWCH_CM_H_ 34 35#include <linux/inet.h> 36#include <linux/wait.h> 37#include <linux/spinlock.h> 38#include <linux/kref.h> 39 40#include <rdma/ib_verbs.h> 41#include <rdma/iw_cm.h> 42 43#include "cxgb3_offload.h" 44#include "iwch_provider.h" 45 46#define MPA_KEY_REQ "MPA ID Req Frame" 47#define MPA_KEY_REP "MPA ID Rep Frame" 48 49#define MPA_MAX_PRIVATE_DATA 256 50#define MPA_REV 0 /* XXX - amso1100 uses rev 0 ! */ 51#define MPA_REJECT 0x20 52#define MPA_CRC 0x40 53#define MPA_MARKERS 0x80 54#define MPA_FLAGS_MASK 0xE0 55 56#define put_ep(ep) { \ 57 PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ 58 ep, atomic_read(&((ep)->kref.refcount))); \ 59 WARN_ON(atomic_read(&((ep)->kref.refcount)) < 1); \ 60 kref_put(&((ep)->kref), __free_ep); \ 61} 62 63#define get_ep(ep) { \ 64 PDBG("get_ep (via %s:%u) ep %p, refcnt %d\n", __func__, __LINE__, \ 65 ep, atomic_read(&((ep)->kref.refcount))); \ 66 kref_get(&((ep)->kref)); \ 67} 68 69struct mpa_message { 70 u8 key[16]; 71 u8 flags; 72 u8 revision; 73 __be16 private_data_size; 74 u8 private_data[0]; 75}; 76 77struct terminate_message { 78 u8 layer_etype; 79 u8 ecode; 80 __be16 hdrct_rsvd; 81 u8 len_hdrs[0]; 82}; 83 84#define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28) 85 86enum iwch_layers_types { 87 LAYER_RDMAP = 0x00, 88 LAYER_DDP = 0x10, 89 LAYER_MPA = 0x20, 90 RDMAP_LOCAL_CATA = 0x00, 91 RDMAP_REMOTE_PROT = 0x01, 92 RDMAP_REMOTE_OP = 0x02, 93 DDP_LOCAL_CATA = 0x00, 94 DDP_TAGGED_ERR = 0x01, 95 DDP_UNTAGGED_ERR = 0x02, 96 DDP_LLP = 0x03 97}; 98 99enum iwch_rdma_ecodes { 100 RDMAP_INV_STAG = 0x00, 101 RDMAP_BASE_BOUNDS = 0x01, 102 RDMAP_ACC_VIOL = 0x02, 103 RDMAP_STAG_NOT_ASSOC = 0x03, 104 RDMAP_TO_WRAP = 0x04, 105 RDMAP_INV_VERS = 0x05, 106 RDMAP_INV_OPCODE = 0x06, 107 RDMAP_STREAM_CATA = 0x07, 108 RDMAP_GLOBAL_CATA = 0x08, 109 RDMAP_CANT_INV_STAG = 0x09, 110 RDMAP_UNSPECIFIED = 0xff 111}; 112 113enum iwch_ddp_ecodes { 114 DDPT_INV_STAG = 0x00, 115 DDPT_BASE_BOUNDS = 0x01, 116 DDPT_STAG_NOT_ASSOC = 0x02, 117 DDPT_TO_WRAP = 0x03, 118 DDPT_INV_VERS = 0x04, 119 DDPU_INV_QN = 0x01, 120 DDPU_INV_MSN_NOBUF = 0x02, 121 DDPU_INV_MSN_RANGE = 0x03, 122 DDPU_INV_MO = 0x04, 123 DDPU_MSG_TOOBIG = 0x05, 124 DDPU_INV_VERS = 0x06 125}; 126 127enum iwch_mpa_ecodes { 128 MPA_CRC_ERR = 0x02, 129 MPA_MARKER_ERR = 0x03 130}; 131 132enum iwch_ep_state { 133 IDLE = 0, 134 LISTEN, 135 CONNECTING, 136 MPA_REQ_WAIT, 137 MPA_REQ_SENT, 138 MPA_REQ_RCVD, 139 MPA_REP_SENT, 140 FPDU_MODE, 141 ABORTING, 142 CLOSING, 143 MORIBUND, 144 DEAD, 145}; 146 147enum iwch_ep_flags { 148 PEER_ABORT_IN_PROGRESS = 0, 149 ABORT_REQ_IN_PROGRESS = 1, 150 RELEASE_RESOURCES = 2, 151 CLOSE_SENT = 3, 152}; 153 154struct iwch_ep_common { 155 struct iw_cm_id *cm_id; 156 struct iwch_qp *qp; 157 struct t3cdev *tdev; 158 enum iwch_ep_state state; 159 struct kref kref; 160 spinlock_t lock; 161 struct sockaddr_in local_addr; 162 struct sockaddr_in remote_addr; 163 wait_queue_head_t waitq; 164 int rpl_done; 165 int rpl_err; 166 unsigned long flags; 167}; 168 169struct iwch_listen_ep { 170 struct iwch_ep_common com; 171 unsigned int stid; 172 int backlog; 173}; 174 175struct iwch_ep { 176 struct iwch_ep_common com; 177 struct iwch_ep *parent_ep; 178 struct timer_list timer; 179 unsigned int atid; 180 u32 hwtid; 181 u32 snd_seq; 182 u32 rcv_seq; 183 struct l2t_entry *l2t; 184 struct dst_entry *dst; 185 struct sk_buff *mpa_skb; 186 struct iwch_mpa_attributes mpa_attr; 187 unsigned int mpa_pkt_len; 188 u8 mpa_pkt[sizeof(struct mpa_message) + MPA_MAX_PRIVATE_DATA]; 189 u8 tos; 190 u16 emss; 191 u16 plen; 192 u32 ird; 193 u32 ord; 194}; 195 196static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id) 197{ 198 return cm_id->provider_data; 199} 200 201static inline struct iwch_listen_ep *to_listen_ep(struct iw_cm_id *cm_id) 202{ 203 return cm_id->provider_data; 204} 205 206static inline int compute_wscale(int win) 207{ 208 int wscale = 0; 209 210 while (wscale < 14 && (65535<<wscale) < win) 211 wscale++; 212 return wscale; 213} 214 215/* CM prototypes */ 216 217int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param); 218int iwch_create_listen(struct iw_cm_id *cm_id, int backlog); 219int iwch_destroy_listen(struct iw_cm_id *cm_id); 220int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len); 221int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param); 222int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp); 223int iwch_quiesce_tid(struct iwch_ep *ep); 224int iwch_resume_tid(struct iwch_ep *ep); 225void __free_ep(struct kref *kref); 226void iwch_rearp(struct iwch_ep *ep); 227int iwch_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new, struct l2t_entry *l2t); 228 229int __init iwch_cm_init(void); 230void __exit iwch_cm_term(void); 231extern int peer2peer; 232 233#endif /* _IWCH_CM_H_ */ 234