Listed below is a start at an updated CM API. Several details are missing, but there should be enough there to evaluate the direction of the CM. Some design notes:

* User's are responsible for destroying "connection identifiers". This was done to ensure that reference counting can be handled properly.
* The CM will allocate connection identifiers for clients upon receiving REQ or SIDR_REQ messages. The new identifiers are returned to clients via a callback. See below.
* QP transitions are expected to be done by the clients.
* The CM handles formatting CM MADs and tracking CM states.


Questions:

* Connection identifiers cannot be destroyed from within a CM callback. I think that we can support this by adding a flag (destroying within callback) to the destroy call. Is this worth adding?
* Should listening clients call an "accept" routine to wait for a connection request? Currently, the API operates asynchronously and inokves a CM event handler.
* Should we allow forcing a connection into the established state, regardless of its previous state? This would let the user connect without using the CM, and then give control of the connection to the CM.
* Should calls to send the LAP/APR set the QP's alternate path information? Related to this, should the CM support a call to force path migration on the QP.


- Sean

/*
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available at
 * <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
 * license, available in the LICENSE.TXT file accompanying this
 * software.  These details are also available at
 * <http://openib.org/license.html>.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Copyright (c) 2004 Intel Corporation.  All rights reserved.
 * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
 * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
 *
 * $Id$
 */
#if !defined(IB_CM_H)
#define IB_CM_H

#include <ib_mad.h>

struct ib_path_record; //*** TBD: define me somewhere else (ib_smi.h?)

enum ib_cm_state {
        IB_CM_IDLE,
        IB_CM_LISTEN,
        IB_CM_REQ_SENT,
        IB_CM_REQ_RCVD,
        IB_CM_MRA_REQ_SENT
        IB_CM_MRA_REQ_RCVD,
        IB_CM_REP_SENT,
        IB_CM_REP_RCVD,
        IB_CM_MRA_REP_SENT,
        IB_CM_MRA_REP_RCVD,
        IB_CM_ESTABLISHED,
        IB_CM_LAP_SENT,
        IB_CM_LAP_RCVD,
        IB_CM_MRA_LAP_SENT,
        IB_CM_MRA_LAP_RCVD,
        IB_CM_DREQ_SENT,
        IB_CM_DREQ_RCVD,
        IB_CM_TIMEWAIT,
        IB_CM_SIDR_REQ_SENT,
        IB_CM_SIDR_REQ_RCVD
};

enum ib_cm_event_type {
        IB_CM_REQ_TIMEOUT,
        IB_CM_REQ_RECEIVED,
        IB_CM_REP_TIMEOUT,
        IB_CM_REP_RECEIVED,
        IB_CM_RTU_RECEIVED,
        IB_CM_DREQ_TIMEOUT
        IB_CM_DREQ_RECEIVED,
        IB_CM_DREP_RECEIVED,
        IB_CM_MRA_RECEIVED,
        IB_CM_LAP_TIMEOUT,
        IB_CM_LAP_RECEIVED,
        IB_CM_APR_RECEIVED
};

struct ib_cm_event {
        /* a whole lot more stuff goes here */
        void                    *private_data;
        u8                      private_data_len;
        enum ib_cm_event_type   event;
};

typedef void (*ib_cm_handler)(struct ib_cm_id *, struct ib_cm_event *);

struct ib_cm_id {
        ib_cm_handler           cm_handler;
        void                    *context;
        u64                     service_id;
        enum ib_cm_state        state;
};

/**
 * ib_create_cm_id - Allocate a connection identifier.
 * @cm_handler: Callback invoked to notify the user of CM events.
 * @context: User specified context associated with the connection
 *   identifier.
 *
 * Connection identifiers are used to track connection states and
 * listen requests.
 */
struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
                                 void *context);

/**
 * ib_destroy_cm_id - Destroy a connection identifier.
 * @cm_id: Connection identifier to destroy.
 *
 * This call blocks until the connection identifier is destroyed.
 */
int ib_destroy_cm_id(struct ib_cm_id *cm_id);
//*** TBD : add flags to allow calling routine from CM callback...

/**
 * ib_cm_listen - Initiates listening on the specified service ID for
 *   connection and service ID resolution requests.
 * @cm_id: Connection identifier associated with the listen request.
 * @service_id: Service identifier matched against incoming connection
 *   and service ID resolution requests.
 */
int ib_cm_listen(struct ib_cm_id *cm_id,
                 u64 service_id);

struct ib_cm_req_param {
        struct ib_qp            *qp;
        struct ib_path_record   *primary_path;
        struct ib_path_record   *alternate_path;
        u64                     service_id;
        int                     timeout_ms;
        void                    *private_data;
        u8                      private_data_len;
        u8                      responder_resources;
        u8                      initiator_depth;
        u8                      remote_cm_response_timeout;
        u8                      flow_control;
        u8                      local_cm_response_timeout;
        u8                      retry_count;
        u8                      rnr_retry_count;
        u8                      max_cm_retries;
};

/**
 * ib_send_cm_req - Sends a connection request to the remote node.
 * @cm_id: Connection identifier that will be associated with the
 *   connection request.
 * @param: Connection request information needed to establish the
 *   connection.
 */
int ib_send_cm_req(struct ib_cm_id *cm_id,
                   struct ib_cm_req_param *param);

struct ib_cm_rep_param {
        struct ib_qp    *qp;
        void            *private_data;
        u8              reply_private_data_len;
        u8              responder_resources;
        u8              initiator_depth;
        u8              target_ack_delay;
        u8              failover_accepted;
        u8              flow_control;
        u8              rnr_retry_count;
};

/**
 * ib_send_cm_rep - Sends a connection reply in response to a connection
 *   request.
 * @cm_id: Connection identifier that will be associated with the
 *   connection request.
 * @param: Connection reply information needed to establish the
 *   connection.
 */
int ib_send_cm_rep(struct ib_cm_id *cm_id,
                   struct ib_cm_req_param *param);

/**
 * ib_send_cm_rtu - Sends a connection ready to use message in response
 *   to a connection reply message.
 * @cm_id: Connection identifier associated with the connection request.
 * @private_data: Optional user-defined private data sent with the
 *   ready to use message.
 * @private_data_len: Size of the private data buffer, in bytes.
 */
int ib_send_cm_rtu(struct ib_cm_id *cm_id,
                   void *private_data,
                   u8 private_data_len);

/**
 * ib_send_cm_dreq - Sends a disconnection request for an existing
 *   connection.
 * @cm_id: Connection identifier associated with the connection being
 *   released.
 * @private_data: Optional user-defined private data sent with the
 *   disconnection request message.
 * @private_data_len: Size of the private data buffer, in bytes.
 */
int ib_send_cm_dreq(struct ib_cm_id *cm_id,
                    void *private_data,
                    u8 private_data_len);

/**
* ib_send_cm_drep - Sends a disconnection reply to a disconnection request.
* @cm_id: Connection identifier associated with the connection being
* released.
* @private_data: Optional user-defined private data sent with the
* disconnection reply message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_send_cm_drep(struct ib_cm_id *cm_id,
void *private_data,
u8 private_data_len);


/**
 * ib_cm_establish - Forces a connection state to established.
 * @cm_id: Connection identifier to transition to established.
 *
 * This routine should be invoked by users who receive messages on a
 * connected QP before an RTU has been received.
 */
int ib_cm_establish(struct ib_cm_id *id);
//*** TBD: should we allow a user for force any cm_id to established?

enum ib_cm_rej_reason {
        IB_CM_REJ_NO_QP                         = __constant_htons(1)
        IB_CM_REJ_NO_EEC                        = __constant_htons(2)
        IB_CM_REJ_NO_RESOURCES                  = __constant_htons(3)
        IB_CM_REJ_TIMEOUT                       = __constant_htons(4)
        IB_CM_REJ_UNSUPPORTED                   = __constant_htons(5)
        IB_CM_REJ_INVALID_COMM_ID               = __constant_htons(6)
        IB_CM_REJ_INVALID_COMM_INSTANCE         = __constant_htons(7)
        IB_CM_REJ_INVALID_SERVICE_ID            = __constant_htons(8)
        IB_CM_REJ_INVALID_TRANSPORT_TYPE        = __constant_htons(9)
        IB_CM_REJ_STALE_CONN                    = __constant_htons(10)
        IB_CM_REJ_RDC_NOT_EXIST                 = __constant_htons(11)
        IB_CM_REJ_INVALID_GID                   = __constant_htons(12)
        IB_CM_REJ_INVALID_LID                   = __constant_htons(13)
        IB_CM_REJ_INVALID_SL                    = __constant_htons(14)
        IB_CM_REJ_INVALID_TRAFFIC_CLASS         = __constant_htons(15)
        IB_CM_REJ_INVALID_HOP_LIMIT             = __constant_htons(16)
        IB_CM_REJ_INVALID_PACKET_RATE           = __constant_htons(17)
        IB_CM_REJ_INVALID_ALT_GID               = __constant_htons(18)
        IB_CM_REJ_INVALID_ALT_LID               = __constant_htons(19)
        IB_CM_REJ_INVALID_ALT_SL                = __constant_htons(20)
        IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS     = __constant_htons(21)
        IB_CM_REJ_INVALID_ALT_HOP_LIMIT         = __constant_htons(22)
        IB_CM_REJ_INVALID_ALT_PACKET_RATE       = __constant_htons(23)
        IB_CM_REJ_PORT_REDIRECT                 = __constant_htons(24)
        IB_CM_REJ_INVALID_MTU                   = __constant_htons(26)
        IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES   = __constant_htons(27)
        IB_CM_REJ_CONSUMER_DEFINED              = __constant_htons(28)
        IB_CM_REJ_INVALID_RNR_RETRY             = __constant_htons(29)
        IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID       = __constant_htons(30)
        IB_CM_REJ_INVALID_CLASS_VERSION         = __constant_htons(31)
        IB_CM_REJ_INVALID_FLOW_LABEL            = __constant_htons(32)
        IB_CM_REJ_INVALID_ALT_FLOW_LABEL        = __constant_htons(33)
};

/**
 * ib_send_cm_rej - Sends a connection rejection message to the
 *   remote node.
 * @cm_id: Connection identifier associated with the connection being
 *   rejected.
 * @reason: Reason for the connection request rejection.
 * @ari: Optional additional rejection information.
 * @ari_length: Size of the additional rejection information, in bytes.
 * @private_data: Optional user-defined private data sent with the
 *   rejection message.
 * @private_data_len: Size of the private data buffer, in bytes.
 */
int ib_send_cm_rej(struct ib_cm_id *cm_id,
                   enum ib_cm_rej_reason reason,
                   void *ari,
                   u8 ari_length,
                   void *private_data,
                   u8 private_data_len);

/**
* ib_send_cm_mra - Sends a message receipt acknowledgement to a connection
* message.
* @cm_id: Connection identifier associated with the connection message.
* @service_timeout: The maximum time required for the sender to reply to
* to the connection message.
* @private_data: Optional user-defined private data sent with the
* message receipt acknowledgement.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_send_cm_mra(struct ib_cm_id *cm_id,
u8 service_timeout,
void *private_data,
u8 private_data_len);


/**
 * ib_send_cm_lap - Sends a load alternate path request.
 * @cm_id: Connection identifier associated with the load alternate path
 *   message.
 * @alternate_path: A path record that identifies the alternate path to
 *   load.
 * @private_data: Optional user-defined private data sent with the
 *   load alternate path message.
 * @private_data_len: Size of the private data buffer, in bytes.
 */
int ib_send_cm_lap(struct ib_cm_id *cm_id,
                   struct ib_path_record *alternate_path,
                   void *private_data,
                   u8 private_data_len);
//*** TBD: should LAP/APR set the QP's alternate path information...

enum ib_cm_apr_status {
        IB_CM_APR_SUCCESS
        IB_CM_APR_INVALID_COMM_ID
        IB_CM_APR_UNSUPPORTED
        IB_CM_APR_REJECT
        IB_CM_APR_REDIRECT
        IB_CM_APR_IS_CURRENT
        IB_CM_APR_INVALID_QPN_EECN
        IB_CM_APR_INVALID_LID
        IB_CM_APR_INVALID_GID
        IB_CM_APR_INVALID_FLOW_LABEL
        IB_CM_APR_INVALID_TCLASS
        IB_CM_APR_INVALID_HOP_LIMIT
        IB_CM_APR_INVALID_PACKET_RATE
        IB_CM_APR_INVALID_SL
};

/**
* ib_send_cm_apr - Sends an alternate path response message in response to
* a load alternate path request.
* @cm_id: Connection identifier associated with the alternate path response.
* @status: Reply status sent with the alternate path response.
* @info: Optional additional information sent with the alternate path
* response.
* @info_length: Size of the additional information, in bytes.
* @private_data: Optional user-defined private data sent with the
* alternate path response message.
* @private_data_len: Size of the private data buffer, in bytes.
*/
int ib_send_cm_apr(struct ib_cm_id *cm_id,
enum ib_cm_apr_status status,
void *info,
u8 info_length,
void *private_data,
u8 private_data_len);


/**
* ib_cm_migrate_path - Forces a connected QP to use the loaded alternate
* path.
* @cm_id: Connection identifier associated with the alternate path response.
*/
//int ib_cm_migrate_path(struct ib_cm_id *cm_id);
//*** TBD: should this be part of CM, since it only modifies the QP state?


struct ib_cm_sidr_req_param {
        struct ib_path_record   *path;
        u64                     service_id;
        int                     timeout_ms;
        void                    *private_data;
        u8                      private_data_len;
        u16                     pkey;
};

/**
 * ib_send_cm_sidr_req - Sends a service ID resolution request to the
 *   remote node.
 * @cm_id: Communication identifier that will be associated with the
 *   service ID resolution request.
 * @param: Service ID resolution request information.
 */
int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
                        struct ib_cm_sidr_req_param *param);

enum ib_cm_sidr_status {
        IB_SIDR_SUCCESS,
        IB_SIDR_UNSUPPORTED,
        IB_SIDR_REJECT,
        IB_SIDR_NO_QP,
        IB_SIDR_REDIRECT,
        IB_SIDR_UNSUPPORTED_VERSION
};

struct ib_cm_sidr_rep_param {
        u32                     qp_num;
        u32                     qkey;
        enum ib_cm_sidr_status  status;
        void                    *info;
        u8                      info_length;
        void                    *private_data;
        u8                      private_data_len;
};

/**
* ib_send_cm_sidr_rep - Sends a service ID resolution request to the
* remote node.
* @cm_id: Communication identifier associated with the received service ID
* resolution request.
* @param: Service ID resolution reply information.
*/
int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
struct ib_cm_sidr_rep_param *param);


#endif /* IB_CM_H */

_______________________________________________
openib-general mailing list
[EMAIL PROTECTED]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to