linux/drivers/infiniband/hw/i40iw/i40iw_cm.h
<<
>>
Prefs
   1/*******************************************************************************
   2*
   3* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
   4*
   5* This software is available to you under a choice of one of two
   6* licenses.  You may choose to be licensed under the terms of the GNU
   7* General Public License (GPL) Version 2, available from the file
   8* COPYING in the main directory of this source tree, or the
   9* OpenFabrics.org BSD license below:
  10*
  11*   Redistribution and use in source and binary forms, with or
  12*   without modification, are permitted provided that the following
  13*   conditions are met:
  14*
  15*    - Redistributions of source code must retain the above
  16*       copyright notice, this list of conditions and the following
  17*       disclaimer.
  18*
  19*    - Redistributions in binary form must reproduce the above
  20*       copyright notice, this list of conditions and the following
  21*       disclaimer in the documentation and/or other materials
  22*       provided with the distribution.
  23*
  24* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  28* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  29* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  30* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  31* SOFTWARE.
  32*
  33*******************************************************************************/
  34
  35#ifndef I40IW_CM_H
  36#define I40IW_CM_H
  37
  38#define QUEUE_EVENTS
  39
  40#define I40IW_MANAGE_APBVT_DEL 0
  41#define I40IW_MANAGE_APBVT_ADD 1
  42
  43#define I40IW_MPA_REQUEST_ACCEPT  1
  44#define I40IW_MPA_REQUEST_REJECT  2
  45
  46/* IETF MPA -- defines, enums, structs */
  47#define IEFT_MPA_KEY_REQ  "MPA ID Req Frame"
  48#define IEFT_MPA_KEY_REP  "MPA ID Rep Frame"
  49#define IETF_MPA_KEY_SIZE 16
  50#define IETF_MPA_VERSION  1
  51#define IETF_MAX_PRIV_DATA_LEN 512
  52#define IETF_MPA_FRAME_SIZE    20
  53#define IETF_RTR_MSG_SIZE      4
  54#define IETF_MPA_V2_FLAG       0x10
  55#define SNDMARKER_SEQNMASK     0x000001FF
  56
  57#define I40IW_MAX_IETF_SIZE      32
  58
  59/* IETF RTR MSG Fields               */
  60#define IETF_PEER_TO_PEER       0x8000
  61#define IETF_FLPDU_ZERO_LEN     0x4000
  62#define IETF_RDMA0_WRITE        0x8000
  63#define IETF_RDMA0_READ         0x4000
  64#define IETF_NO_IRD_ORD         0x3FFF
  65
  66/* HW-supported IRD sizes*/
  67#define I40IW_HW_IRD_SETTING_2  2
  68#define I40IW_HW_IRD_SETTING_4  4
  69#define I40IW_HW_IRD_SETTING_8  8
  70#define I40IW_HW_IRD_SETTING_16 16
  71#define I40IW_HW_IRD_SETTING_32 32
  72#define I40IW_HW_IRD_SETTING_64 64
  73
  74#define MAX_PORTS               65536
  75#define I40IW_VLAN_PRIO_SHIFT   13
  76
  77enum ietf_mpa_flags {
  78        IETF_MPA_FLAGS_MARKERS = 0x80,  /* receive Markers */
  79        IETF_MPA_FLAGS_CRC = 0x40,      /* receive Markers */
  80        IETF_MPA_FLAGS_REJECT = 0x20,   /* Reject */
  81};
  82
  83struct ietf_mpa_v1 {
  84        u8 key[IETF_MPA_KEY_SIZE];
  85        u8 flags;
  86        u8 rev;
  87        __be16 priv_data_len;
  88        u8 priv_data[0];
  89};
  90
  91#define ietf_mpa_req_resp_frame ietf_mpa_frame
  92
  93struct ietf_rtr_msg {
  94        __be16 ctrl_ird;
  95        __be16 ctrl_ord;
  96};
  97
  98struct ietf_mpa_v2 {
  99        u8 key[IETF_MPA_KEY_SIZE];
 100        u8 flags;
 101        u8 rev;
 102        __be16 priv_data_len;
 103        struct ietf_rtr_msg rtr_msg;
 104        u8 priv_data[0];
 105};
 106
 107struct i40iw_cm_node;
 108enum i40iw_timer_type {
 109        I40IW_TIMER_TYPE_SEND,
 110        I40IW_TIMER_TYPE_RECV,
 111        I40IW_TIMER_NODE_CLEANUP,
 112        I40IW_TIMER_TYPE_CLOSE,
 113};
 114
 115#define I40IW_PASSIVE_STATE_INDICATED    0
 116#define I40IW_DO_NOT_SEND_RESET_EVENT    1
 117#define I40IW_SEND_RESET_EVENT           2
 118
 119#define MAX_I40IW_IFS 4
 120
 121#define SET_ACK 0x1
 122#define SET_SYN 0x2
 123#define SET_FIN 0x4
 124#define SET_RST 0x8
 125
 126#define TCP_OPTIONS_PADDING     3
 127
 128struct option_base {
 129        u8 optionnum;
 130        u8 length;
 131};
 132
 133enum option_numbers {
 134        OPTION_NUMBER_END,
 135        OPTION_NUMBER_NONE,
 136        OPTION_NUMBER_MSS,
 137        OPTION_NUMBER_WINDOW_SCALE,
 138        OPTION_NUMBER_SACK_PERM,
 139        OPTION_NUMBER_SACK,
 140        OPTION_NUMBER_WRITE0 = 0xbc
 141};
 142
 143struct option_mss {
 144        u8 optionnum;
 145        u8 length;
 146        __be16 mss;
 147};
 148
 149struct option_windowscale {
 150        u8 optionnum;
 151        u8 length;
 152        u8 shiftcount;
 153};
 154
 155union all_known_options {
 156        char as_end;
 157        struct option_base as_base;
 158        struct option_mss as_mss;
 159        struct option_windowscale as_windowscale;
 160};
 161
 162struct i40iw_timer_entry {
 163        struct list_head list;
 164        unsigned long timetosend;       /* jiffies */
 165        struct i40iw_puda_buf *sqbuf;
 166        u32 type;
 167        u32 retrycount;
 168        u32 retranscount;
 169        u32 context;
 170        u32 send_retrans;
 171        int close_when_complete;
 172};
 173
 174#define I40IW_DEFAULT_RETRYS    64
 175#define I40IW_DEFAULT_RETRANS   8
 176#define I40IW_DEFAULT_TTL       0x40
 177#define I40IW_DEFAULT_RTT_VAR   0x6
 178#define I40IW_DEFAULT_SS_THRESH 0x3FFFFFFF
 179#define I40IW_DEFAULT_REXMIT_THRESH 8
 180
 181#define I40IW_RETRY_TIMEOUT   HZ
 182#define I40IW_SHORT_TIME      10
 183#define I40IW_LONG_TIME       (2 * HZ)
 184#define I40IW_MAX_TIMEOUT     ((unsigned long)(12 * HZ))
 185
 186#define I40IW_CM_HASHTABLE_SIZE         1024
 187#define I40IW_CM_TCP_TIMER_INTERVAL     3000
 188#define I40IW_CM_DEFAULT_MTU            1540
 189#define I40IW_CM_DEFAULT_FRAME_CNT      10
 190#define I40IW_CM_THREAD_STACK_SIZE      256
 191#define I40IW_CM_DEFAULT_RCV_WND        64240
 192#define I40IW_CM_DEFAULT_RCV_WND_SCALED 0x3fffc
 193#define I40IW_CM_DEFAULT_RCV_WND_SCALE  2
 194#define I40IW_CM_DEFAULT_FREE_PKTS      0x000A
 195#define I40IW_CM_FREE_PKT_LO_WATERMARK  2
 196
 197#define I40IW_CM_DEFAULT_MSS   536
 198
 199#define I40IW_CM_DEF_SEQ       0x159bf75f
 200#define I40IW_CM_DEF_LOCAL_ID  0x3b47
 201
 202#define I40IW_CM_DEF_SEQ2      0x18ed5740
 203#define I40IW_CM_DEF_LOCAL_ID2 0xb807
 204#define MAX_CM_BUFFER   (I40IW_MAX_IETF_SIZE + IETF_MAX_PRIV_DATA_LEN)
 205
 206typedef u32 i40iw_addr_t;
 207
 208#define i40iw_cm_tsa_context i40iw_qp_context
 209
 210struct i40iw_qp;
 211
 212/* cm node transition states */
 213enum i40iw_cm_node_state {
 214        I40IW_CM_STATE_UNKNOWN,
 215        I40IW_CM_STATE_INITED,
 216        I40IW_CM_STATE_LISTENING,
 217        I40IW_CM_STATE_SYN_RCVD,
 218        I40IW_CM_STATE_SYN_SENT,
 219        I40IW_CM_STATE_ONE_SIDE_ESTABLISHED,
 220        I40IW_CM_STATE_ESTABLISHED,
 221        I40IW_CM_STATE_ACCEPTING,
 222        I40IW_CM_STATE_MPAREQ_SENT,
 223        I40IW_CM_STATE_MPAREQ_RCVD,
 224        I40IW_CM_STATE_MPAREJ_RCVD,
 225        I40IW_CM_STATE_OFFLOADED,
 226        I40IW_CM_STATE_FIN_WAIT1,
 227        I40IW_CM_STATE_FIN_WAIT2,
 228        I40IW_CM_STATE_CLOSE_WAIT,
 229        I40IW_CM_STATE_TIME_WAIT,
 230        I40IW_CM_STATE_LAST_ACK,
 231        I40IW_CM_STATE_CLOSING,
 232        I40IW_CM_STATE_LISTENER_DESTROYED,
 233        I40IW_CM_STATE_CLOSED
 234};
 235
 236enum mpa_frame_version {
 237        IETF_MPA_V1 = 1,
 238        IETF_MPA_V2 = 2
 239};
 240
 241enum mpa_frame_key {
 242        MPA_KEY_REQUEST,
 243        MPA_KEY_REPLY
 244};
 245
 246enum send_rdma0 {
 247        SEND_RDMA_READ_ZERO = 1,
 248        SEND_RDMA_WRITE_ZERO = 2
 249};
 250
 251enum i40iw_tcpip_pkt_type {
 252        I40IW_PKT_TYPE_UNKNOWN,
 253        I40IW_PKT_TYPE_SYN,
 254        I40IW_PKT_TYPE_SYNACK,
 255        I40IW_PKT_TYPE_ACK,
 256        I40IW_PKT_TYPE_FIN,
 257        I40IW_PKT_TYPE_RST
 258};
 259
 260/* CM context params */
 261struct i40iw_cm_tcp_context {
 262        u8 client;
 263
 264        u32 loc_seq_num;
 265        u32 loc_ack_num;
 266        u32 rem_ack_num;
 267        u32 rcv_nxt;
 268
 269        u32 loc_id;
 270        u32 rem_id;
 271
 272        u32 snd_wnd;
 273        u32 max_snd_wnd;
 274
 275        u32 rcv_wnd;
 276        u32 mss;
 277        u8 snd_wscale;
 278        u8 rcv_wscale;
 279};
 280
 281enum i40iw_cm_listener_state {
 282        I40IW_CM_LISTENER_PASSIVE_STATE = 1,
 283        I40IW_CM_LISTENER_ACTIVE_STATE = 2,
 284        I40IW_CM_LISTENER_EITHER_STATE = 3
 285};
 286
 287struct i40iw_cm_listener {
 288        struct list_head list;
 289        struct i40iw_cm_core *cm_core;
 290        u8 loc_mac[ETH_ALEN];
 291        u32 loc_addr[4];
 292        u16 loc_port;
 293        struct iw_cm_id *cm_id;
 294        atomic_t ref_count;
 295        struct i40iw_device *iwdev;
 296        atomic_t pend_accepts_cnt;
 297        int backlog;
 298        enum i40iw_cm_listener_state listener_state;
 299        u32 reused_node;
 300        u8 user_pri;
 301        u8 tos;
 302        u16 vlan_id;
 303        bool qhash_set;
 304        bool ipv4;
 305        struct list_head child_listen_list;
 306
 307};
 308
 309struct i40iw_kmem_info {
 310        void *addr;
 311        u32 size;
 312};
 313
 314/* per connection node and node state information */
 315struct i40iw_cm_node {
 316        u32 loc_addr[4], rem_addr[4];
 317        u16 loc_port, rem_port;
 318        u16 vlan_id;
 319        enum i40iw_cm_node_state state;
 320        u8 loc_mac[ETH_ALEN];
 321        u8 rem_mac[ETH_ALEN];
 322        atomic_t ref_count;
 323        struct i40iw_qp *iwqp;
 324        struct i40iw_device *iwdev;
 325        struct i40iw_sc_dev *dev;
 326        struct i40iw_cm_tcp_context tcp_cntxt;
 327        struct i40iw_cm_core *cm_core;
 328        struct i40iw_cm_node *loopbackpartner;
 329        struct i40iw_timer_entry *send_entry;
 330        struct i40iw_timer_entry *close_entry;
 331        spinlock_t retrans_list_lock; /* cm transmit packet */
 332        enum send_rdma0 send_rdma0_op;
 333        u16 ird_size;
 334        u16 ord_size;
 335        u16     mpav2_ird_ord;
 336        struct iw_cm_id *cm_id;
 337        struct list_head list;
 338        bool accelerated;
 339        struct i40iw_cm_listener *listener;
 340        int apbvt_set;
 341        int accept_pend;
 342        struct list_head timer_entry;
 343        struct list_head reset_entry;
 344        struct list_head teardown_entry;
 345        atomic_t passive_state;
 346        bool qhash_set;
 347        u8 user_pri;
 348        u8 tos;
 349        bool ipv4;
 350        bool snd_mark_en;
 351        u16 lsmm_size;
 352        enum mpa_frame_version mpa_frame_rev;
 353        struct i40iw_kmem_info pdata;
 354        union {
 355                struct ietf_mpa_v1 mpa_frame;
 356                struct ietf_mpa_v2 mpa_v2_frame;
 357        };
 358
 359        u8 pdata_buf[IETF_MAX_PRIV_DATA_LEN];
 360        struct i40iw_kmem_info mpa_hdr;
 361        bool ack_rcvd;
 362};
 363
 364/* structure for client or CM to fill when making CM api calls. */
 365/*      - only need to set relevant data, based on op. */
 366struct i40iw_cm_info {
 367        struct iw_cm_id *cm_id;
 368        u16 loc_port;
 369        u16 rem_port;
 370        u32 loc_addr[4];
 371        u32 rem_addr[4];
 372        u16 vlan_id;
 373        int backlog;
 374        u8 user_pri;
 375        u8 tos;
 376        bool ipv4;
 377};
 378
 379/* CM event codes */
 380enum i40iw_cm_event_type {
 381        I40IW_CM_EVENT_UNKNOWN,
 382        I40IW_CM_EVENT_ESTABLISHED,
 383        I40IW_CM_EVENT_MPA_REQ,
 384        I40IW_CM_EVENT_MPA_CONNECT,
 385        I40IW_CM_EVENT_MPA_ACCEPT,
 386        I40IW_CM_EVENT_MPA_REJECT,
 387        I40IW_CM_EVENT_MPA_ESTABLISHED,
 388        I40IW_CM_EVENT_CONNECTED,
 389        I40IW_CM_EVENT_RESET,
 390        I40IW_CM_EVENT_ABORTED
 391};
 392
 393/* event to post to CM event handler */
 394struct i40iw_cm_event {
 395        enum i40iw_cm_event_type type;
 396        struct i40iw_cm_info cm_info;
 397        struct work_struct event_work;
 398        struct i40iw_cm_node *cm_node;
 399};
 400
 401struct i40iw_cm_core {
 402        struct i40iw_device *iwdev;
 403        struct i40iw_sc_dev *dev;
 404
 405        struct list_head listen_nodes;
 406        struct list_head accelerated_list;
 407        struct list_head non_accelerated_list;
 408
 409        struct timer_list tcp_timer;
 410
 411        struct workqueue_struct *event_wq;
 412        struct workqueue_struct *disconn_wq;
 413
 414        spinlock_t ht_lock; /* manage hash table */
 415        spinlock_t listen_list_lock; /* listen list */
 416        spinlock_t apbvt_lock; /*manage apbvt entries*/
 417
 418        unsigned long ports_in_use[BITS_TO_LONGS(MAX_PORTS)];
 419
 420        u64     stats_nodes_created;
 421        u64     stats_nodes_destroyed;
 422        u64     stats_listen_created;
 423        u64     stats_listen_destroyed;
 424        u64     stats_listen_nodes_created;
 425        u64     stats_listen_nodes_destroyed;
 426        u64     stats_loopbacks;
 427        u64     stats_accepts;
 428        u64     stats_rejects;
 429        u64     stats_connect_errs;
 430        u64     stats_passive_errs;
 431        u64     stats_pkt_retrans;
 432        u64     stats_backlog_drops;
 433};
 434
 435int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
 436                            struct i40iw_puda_buf *sqbuf,
 437                            enum i40iw_timer_type type,
 438                            int send_retrans,
 439                            int close_when_complete);
 440
 441int i40iw_accept(struct iw_cm_id *, struct iw_cm_conn_param *);
 442int i40iw_reject(struct iw_cm_id *, const void *, u8);
 443int i40iw_connect(struct iw_cm_id *, struct iw_cm_conn_param *);
 444int i40iw_create_listen(struct iw_cm_id *, int);
 445int i40iw_destroy_listen(struct iw_cm_id *);
 446
 447int i40iw_cm_start(struct i40iw_device *);
 448int i40iw_cm_stop(struct i40iw_device *);
 449
 450int i40iw_arp_table(struct i40iw_device *iwdev,
 451                    u32 *ip_addr,
 452                    bool ipv4,
 453                    u8 *mac_addr,
 454                    u32 action);
 455
 456void i40iw_if_notify(struct i40iw_device *iwdev, struct net_device *netdev,
 457                     u32 *ipaddr, bool ipv4, bool ifup);
 458void i40iw_cm_teardown_connections(struct i40iw_device *iwdev, u32 *ipaddr,
 459                                   struct i40iw_cm_info *nfo,
 460                                   bool disconnect_all);
 461bool i40iw_port_in_use(struct i40iw_cm_core *cm_core, u16 port);
 462#endif /* I40IW_CM_H */
 463