|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_sender.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_transport.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_svc.h>
|
|
Packit |
13e616 |
#include <vendor/osm_pkt_randomizer.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
__osmv_rmpp_send_segment(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn, IN uint32_t seg_num);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****d* OSM Vendor/osmv_simple_send_madw
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osmv_simple_send_madw
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* Send a single MAD (256 bytes).
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* If this MAD requires a response, set the timeout event.
|
|
Packit |
13e616 |
* The function call returns when the MAD's send completion is received.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_simple_send_madw(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osm_madw_t * const p_madw,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn, IN boolean_t is_retry)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t ret;
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_mad_addr_t *p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
|
|
Packit |
13e616 |
uint8_t mad_buf[MAD_BLOCK_SIZE];
|
|
Packit |
13e616 |
ib_mad_t *p_mad = (ib_mad_t *) mad_buf;
|
|
Packit |
13e616 |
uint64_t key = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_madw->mad_size <= MAD_BLOCK_SIZE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_mad, 0, MAD_BLOCK_SIZE);
|
|
Packit |
13e616 |
memcpy(p_mad, osm_madw_get_mad_ptr(p_madw), p_madw->mad_size);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (NULL != p_txn) {
|
|
Packit |
13e616 |
/* Push a fake txn id to the MAD */
|
|
Packit |
13e616 |
key = osmv_txn_get_key(p_txn);
|
|
Packit |
13e616 |
p_mad->trans_id = cl_hton64(key);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Add call for packet drop randomizer.
|
|
Packit |
13e616 |
This is a testing feature. If run_randomizer flag is set to TRUE,
|
|
Packit |
13e616 |
the randomizer will be called, and randomally will drop
|
|
Packit |
13e616 |
a packet. This is used for simulating unstable fabric.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_bo->p_vendor->run_randomizer == TRUE) {
|
|
Packit |
13e616 |
/* Try the randomizer */
|
|
Packit |
13e616 |
if (osm_pkt_randomizer_mad_drop(p_bo->p_vendor->p_log,
|
|
Packit |
13e616 |
p_bo->p_vendor->
|
|
Packit |
13e616 |
p_pkt_randomizer,
|
|
Packit |
13e616 |
p_mad) == TRUE) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"The MAD will not be sent. \n");
|
|
Packit |
13e616 |
ret = IB_SUCCESS;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
osmv_transport_mad_send(h_bind, p_mad, p_mad_addr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
ret = osmv_transport_mad_send(h_bind, p_mad, p_mad_addr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if ((IB_SUCCESS == ret) && (NULL != p_txn) && (!is_retry)) {
|
|
Packit |
13e616 |
/* Set the timeout for receiving the response MAD */
|
|
Packit |
13e616 |
ret = osmv_txn_set_timeout_ev(h_bind, key,
|
|
Packit |
13e616 |
p_bo->p_vendor->resp_timeout);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***** OSM Vendor/osmv_rmpp_send_madw
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osmv_rmpp_send_madw
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* Send a single message (MAD wrapper of arbitrary length).
|
|
Packit |
13e616 |
* Follow the RMPP semantics
|
|
Packit |
13e616 |
* (segmentation, send window, timeouts etc).
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* The function call returns either when the whole message
|
|
Packit |
13e616 |
* has been acknowledged, or upon error.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* ASSUMPTIONS
|
|
Packit |
13e616 |
* The RMPP sender context is set up
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_rmpp_send_madw(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osm_madw_t * const p_madw,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn, IN boolean_t is_rmpp_ds)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t ret = IB_SUCCESS;
|
|
Packit |
13e616 |
uint32_t i, total_segs;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_rmpp_send_ctx_t *p_send_ctx = osmv_txn_get_rmpp_send_ctx(p_txn);
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
total_segs = osmv_rmpp_send_ctx_get_num_segs(p_send_ctx);
|
|
Packit |
13e616 |
CL_ASSERT(total_segs >= 1);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* In the double-sided transfer, wait for ACK 0 */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (;;) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_send_ctx->window_first > total_segs) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Every segment is acknowledged */
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Send the next burst. */
|
|
Packit |
13e616 |
for (i = p_send_ctx->window_first; i <= p_send_ctx->window_last;
|
|
Packit |
13e616 |
i++) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Send a segment and setup a timeout timer */
|
|
Packit |
13e616 |
ret = __osmv_rmpp_send_segment(h_bind, p_txn, i);
|
|
Packit |
13e616 |
if (IB_SUCCESS != ret) {
|
|
Packit |
13e616 |
goto send_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Set the Response Timeout for the ACK on the last DATA segment */
|
|
Packit |
13e616 |
ret = osmv_txn_set_timeout_ev(h_bind, osmv_txn_get_key(p_txn),
|
|
Packit |
13e616 |
p_bo->p_vendor->resp_timeout);
|
|
Packit |
13e616 |
if (IB_SUCCESS != ret) {
|
|
Packit |
13e616 |
goto send_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Going to sleep. Let the others access the transaction DB */
|
|
Packit |
13e616 |
osmv_txn_unlock(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"RMPP Sender thread (madw=%p) going to sleep ...\n",
|
|
Packit |
13e616 |
p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Await the next event to happen */
|
|
Packit |
13e616 |
cl_event_wait_on(&p_send_ctx->event,
|
|
Packit |
13e616 |
EVENT_NO_TIMEOUT, TRUE /* interruptible */ );
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Got a signal from the MAD dispatcher/timeout handler */
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"RMPP Sender thread (madw=%p) waking up on a signal ...\n",
|
|
Packit |
13e616 |
p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Let's see what changed... Make this atomic - re-acquire the lock. */
|
|
Packit |
13e616 |
osmv_txn_lock(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == p_bo->is_closing) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_rmpp_send_madw: ERR 6601: "
|
|
Packit |
13e616 |
"The bind handle %p is being closed. "
|
|
Packit |
13e616 |
"Stopping the RMPP Send of MADW %p\n",
|
|
Packit |
13e616 |
h_bind, p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_TIMEOUT;
|
|
Packit |
13e616 |
return IB_INTERRUPTED;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* STOP? ABORT? TIMEOUT? */
|
|
Packit |
13e616 |
if (IB_SUCCESS != p_send_ctx->status) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_rmpp_send_madw: ERR 6602: "
|
|
Packit |
13e616 |
"An error (%s) happened during the RMPP send of %p. Bailing out.\n",
|
|
Packit |
13e616 |
ib_get_err_str(p_send_ctx->status), p_madw);
|
|
Packit |
13e616 |
ret = p_send_ctx->status;
|
|
Packit |
13e616 |
goto send_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == is_rmpp_ds) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Double-sided RMPP - switching to be the receiver.\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = osmv_txn_init_rmpp_receiver(h_bind, p_txn, FALSE
|
|
Packit |
13e616 |
/*Send was initiated by me */
|
|
Packit |
13e616 |
);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (IB_SUCCESS == ret) {
|
|
Packit |
13e616 |
/* Send ACK on the 0 segment */
|
|
Packit |
13e616 |
ret = __osmv_rmpp_send_segment(h_bind, p_txn, 0);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
send_done:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osmv_rmpp_send_ack
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_rmpp_send_ack(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN const ib_mad_t * p_req_mad,
|
|
Packit |
13e616 |
IN uint32_t seg_num,
|
|
Packit |
13e616 |
IN uint32_t nwl, IN const osm_mad_addr_t * p_mad_addr)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
uint8_t resp_mad[MAD_BLOCK_SIZE];
|
|
Packit |
13e616 |
ib_rmpp_mad_t *p_resp_mad = (ib_rmpp_mad_t *) resp_mad;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef OSMV_RANDOM_DROP
|
|
Packit |
13e616 |
if (TRUE == osmv_random_drop()) {
|
|
Packit |
13e616 |
osm_log(((osmv_bind_obj_t *) h_bind)->p_vendor->p_log,
|
|
Packit |
13e616 |
OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Error injection - dropping the RMPP ACK\n");
|
|
Packit |
13e616 |
return IB_SUCCESS;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memcpy(p_resp_mad, p_req_mad, MAD_BLOCK_SIZE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_resp_mad->common_hdr.method = osmv_invert_method(p_req_mad->method);
|
|
Packit |
13e616 |
p_resp_mad->rmpp_type = IB_RMPP_TYPE_ACK;
|
|
Packit |
13e616 |
p_resp_mad->seg_num = cl_hton32(seg_num);
|
|
Packit |
13e616 |
p_resp_mad->paylen_newwin = cl_hton32(nwl);
|
|
Packit |
13e616 |
p_resp_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return osmv_transport_mad_send(h_bind, p_resp_mad, p_mad_addr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osmv_rmpp_send_nak
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Send the RMPP ABORT or STOP packet
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_rmpp_send_nak(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN const ib_mad_t * p_req_mad,
|
|
Packit |
13e616 |
IN const osm_mad_addr_t * p_mad_addr,
|
|
Packit |
13e616 |
IN uint8_t nak_type, IN uint8_t status)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
uint8_t resp_mad[MAD_BLOCK_SIZE];
|
|
Packit |
13e616 |
ib_rmpp_mad_t *p_resp_mad = (ib_rmpp_mad_t *) resp_mad;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memcpy(p_resp_mad, p_req_mad, MAD_BLOCK_SIZE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_resp_mad->common_hdr.method = osmv_invert_method(p_req_mad->method);
|
|
Packit |
13e616 |
p_resp_mad->rmpp_type = nak_type;
|
|
Packit |
13e616 |
p_resp_mad->rmpp_status = status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return osmv_transport_mad_send(h_bind, p_resp_mad, p_mad_addr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME __osmv_rmpp_send_segment
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Build a MAD for a specific segment and send it
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
__osmv_rmpp_send_segment(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn, IN uint32_t seg_num)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t ret;
|
|
Packit |
13e616 |
osmv_rmpp_send_ctx_t *p_send_ctx;
|
|
Packit |
13e616 |
uint8_t mad_buf[MAD_BLOCK_SIZE];
|
|
Packit |
13e616 |
ib_mad_t *p_mad = (ib_mad_t *) mad_buf;
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_mad_addr_t *p_mad_addr =
|
|
Packit |
13e616 |
osm_madw_get_mad_addr_ptr(osmv_txn_get_madw(p_txn));
|
|
Packit |
13e616 |
uint32_t timeout = p_bo->p_vendor->resp_timeout;
|
|
Packit |
13e616 |
uint64_t key;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef OSMV_RANDOM_DROP
|
|
Packit |
13e616 |
if (TRUE == osmv_random_drop()) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Error injection - simulating the RMPP segment drop\n");
|
|
Packit |
13e616 |
return IB_SUCCESS;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_send_ctx = osmv_txn_get_rmpp_send_ctx(p_txn);
|
|
Packit |
13e616 |
key = osmv_txn_get_key(p_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (0 != seg_num) {
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
osmv_rmpp_send_ctx_get_seg(p_send_ctx, seg_num, timeout,
|
|
Packit |
13e616 |
p_mad);
|
|
Packit |
13e616 |
CL_ASSERT(IB_SUCCESS == ret);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Put the segment to the wire ! */
|
|
Packit |
13e616 |
p_mad->trans_id = cl_hton64(key);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Sending RMPP segment #%d, on-wire TID=0x%" PRIx64 "\n",
|
|
Packit |
13e616 |
seg_num, p_mad->trans_id);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Add call for packet drop randomizer.
|
|
Packit |
13e616 |
This is a testing feature. If run_randomizer flag is set to TRUE,
|
|
Packit |
13e616 |
the randomizer will be called, and randomally will drop
|
|
Packit |
13e616 |
a packet. This is used for simulating unstable fabric.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_bo->p_vendor->run_randomizer == TRUE) {
|
|
Packit |
13e616 |
/* Try the randomizer */
|
|
Packit |
13e616 |
if (osm_pkt_randomizer_mad_drop(p_bo->p_vendor->p_log,
|
|
Packit |
13e616 |
p_bo->p_vendor->
|
|
Packit |
13e616 |
p_pkt_randomizer,
|
|
Packit |
13e616 |
p_mad) == TRUE) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"The MAD will not be sent. \n");
|
|
Packit |
13e616 |
ret = IB_SUCCESS;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
osmv_transport_mad_send((osm_bind_handle_t)
|
|
Packit |
13e616 |
p_bo, p_mad,
|
|
Packit |
13e616 |
p_mad_addr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
osmv_transport_mad_send((osm_bind_handle_t) p_bo,
|
|
Packit |
13e616 |
p_mad, p_mad_addr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* This is an ACK for double-sided handshake. Give it a special treatment. */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* It doesn't really matter which data to put. Only the header matters. */
|
|
Packit |
13e616 |
ret = osmv_rmpp_send_ctx_get_seg(p_send_ctx, 1, timeout, p_mad);
|
|
Packit |
13e616 |
CL_ASSERT(IB_SUCCESS == ret);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mad->trans_id = cl_hton64(key);
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
osmv_rmpp_send_ack((osm_bind_handle_t) p_bo, p_mad,
|
|
Packit |
13e616 |
0 /* segnum */ ,
|
|
Packit |
13e616 |
OSMV_RMPP_RECV_WIN /* NWL */ ,
|
|
Packit |
13e616 |
p_mad_addr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|