1321936Shselasky/* 2321936Shselasky * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved. 3321936Shselasky * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4321936Shselasky * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5321936Shselasky * 6321936Shselasky * This software is available to you under a choice of one of two 7321936Shselasky * licenses. You may choose to be licensed under the terms of the GNU 8321936Shselasky * General Public License (GPL) Version 2, available from the file 9321936Shselasky * COPYING in the main directory of this source tree, or the 10321936Shselasky * OpenIB.org BSD license below: 11321936Shselasky * 12321936Shselasky * Redistribution and use in source and binary forms, with or 13321936Shselasky * without modification, are permitted provided that the following 14321936Shselasky * conditions are met: 15321936Shselasky * 16321936Shselasky * - Redistributions of source code must retain the above 17321936Shselasky * copyright notice, this list of conditions and the following 18321936Shselasky * disclaimer. 19321936Shselasky * 20321936Shselasky * - Redistributions in binary form must reproduce the above 21321936Shselasky * copyright notice, this list of conditions and the following 22321936Shselasky * disclaimer in the documentation and/or other materials 23321936Shselasky * provided with the distribution. 24321936Shselasky * 25321936Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26321936Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27321936Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28321936Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29321936Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30321936Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31321936Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32321936Shselasky * SOFTWARE. 33321936Shselasky * 34321936Shselasky */ 35321936Shselasky 36321936Shselasky#if HAVE_CONFIG_H 37321936Shselasky# include <config.h> 38321936Shselasky#endif /* HAVE_CONFIG_H */ 39321936Shselasky 40321936Shselasky#include <stdlib.h> 41321936Shselasky#include <string.h> 42321936Shselasky#include <stdio.h> 43321936Shselasky#include <vendor/osm_vendor_mlx_sar.h> 44321936Shselasky 45321936Shselaskyib_api_status_t 46321936Shselaskyosmv_rmpp_sar_init(osmv_rmpp_sar_t * p_sar, void *p_arbt_mad, 47321936Shselasky uint32_t mad_size, boolean_t is_sa_mad) 48321936Shselasky{ 49321936Shselasky CL_ASSERT(p_sar); 50321936Shselasky p_sar->p_arbt_mad = p_arbt_mad; 51321936Shselasky if (is_sa_mad) { 52321936Shselasky p_sar->data_len = mad_size - IB_SA_MAD_HDR_SIZE; 53321936Shselasky p_sar->hdr_sz = IB_SA_MAD_HDR_SIZE; 54321936Shselasky p_sar->data_sz = IB_SA_DATA_SIZE; 55321936Shselasky } else { 56321936Shselasky p_sar->data_len = mad_size - MAD_RMPP_HDR_SIZE; 57321936Shselasky p_sar->hdr_sz = MAD_RMPP_HDR_SIZE; 58321936Shselasky p_sar->data_sz = MAD_RMPP_DATA_SIZE; 59321936Shselasky } 60321936Shselasky return IB_SUCCESS; 61321936Shselasky} 62321936Shselasky 63321936Shselaskyvoid osmv_rmpp_sar_done(osmv_rmpp_sar_t * p_sar) 64321936Shselasky{ 65321936Shselasky p_sar->p_arbt_mad = NULL; 66321936Shselasky} 67321936Shselasky 68321936Shselasky/* the big mad should be with mad header, rmpp header ( &sa hdr) space */ 69321936Shselaskyib_api_status_t 70321936Shselaskyosmv_rmpp_sar_get_mad_seg(IN osmv_rmpp_sar_t * p_sar, 71321936Shselasky IN uint32_t seg_idx, OUT void *p_buf) 72321936Shselasky{ 73321936Shselasky void *p_seg; 74321936Shselasky uint32_t sz_left; 75321936Shselasky uint32_t num_segs; 76321936Shselasky 77321936Shselasky CL_ASSERT(p_sar); 78321936Shselasky 79321936Shselasky num_segs = p_sar->data_len / p_sar->data_sz; 80321936Shselasky if ((p_sar->data_len % p_sar->data_sz) > 0) { 81321936Shselasky num_segs++; 82321936Shselasky } 83321936Shselasky 84321936Shselasky if ((seg_idx > num_segs) && (seg_idx != 1)) { 85321936Shselasky return IB_NOT_FOUND; 86321936Shselasky } 87321936Shselasky 88321936Shselasky /* cleanup */ 89321936Shselasky memset(p_buf, 0, MAD_BLOCK_SIZE); 90321936Shselasky 91321936Shselasky /* attach header */ 92321936Shselasky memcpy(p_buf, p_sar->p_arbt_mad, p_sar->hdr_sz); 93321936Shselasky 94321936Shselasky /* fill data */ 95321936Shselasky p_seg = 96321936Shselasky (char *)p_sar->p_arbt_mad + p_sar->hdr_sz + 97321936Shselasky ((seg_idx - 1) * p_sar->data_sz); 98321936Shselasky sz_left = p_sar->data_len - ((seg_idx - 1) * p_sar->data_sz); 99321936Shselasky if (sz_left > p_sar->data_sz) 100321936Shselasky memcpy((char *)p_buf + p_sar->hdr_sz, (char *)p_seg, 101321936Shselasky p_sar->data_sz); 102321936Shselasky else 103321936Shselasky memcpy((char *)p_buf + p_sar->hdr_sz, (char *)p_seg, sz_left); 104321936Shselasky 105321936Shselasky return IB_SUCCESS; 106321936Shselasky} 107321936Shselasky 108321936Shselasky/* turns a list of mads to one big mad - including header */ 109321936Shselasky/* ALSO - deallocates the list */ 110321936Shselaskyib_api_status_t 111321936Shselaskyosmv_rmpp_sar_reassemble_arbt_mad(osmv_rmpp_sar_t * p_sar, cl_qlist_t * p_bufs) 112321936Shselasky{ 113321936Shselasky void *buf_tmp, *p_mad; 114321936Shselasky cl_list_item_t *p_item; 115321936Shselasky cl_list_obj_t *p_obj; 116321936Shselasky uint32_t space_left = p_sar->data_len + p_sar->hdr_sz; 117321936Shselasky 118321936Shselasky CL_ASSERT(p_sar); 119321936Shselasky CL_ASSERT(FALSE == cl_is_qlist_empty(p_bufs)); 120321936Shselasky 121321936Shselasky /* attach header */ 122321936Shselasky p_mad = p_sar->p_arbt_mad; 123321936Shselasky p_item = cl_qlist_head(p_bufs); 124321936Shselasky p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item); 125321936Shselasky buf_tmp = cl_qlist_obj(p_obj); 126321936Shselasky memcpy(p_mad, buf_tmp, p_sar->hdr_sz); 127321936Shselasky p_mad = (char *)p_mad + p_sar->hdr_sz; 128321936Shselasky space_left -= p_sar->hdr_sz; 129321936Shselasky 130321936Shselasky /* reassemble data */ 131321936Shselasky while (FALSE == cl_is_qlist_empty(p_bufs)) { 132321936Shselasky 133321936Shselasky p_item = cl_qlist_remove_head(p_bufs); 134321936Shselasky p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item); 135321936Shselasky buf_tmp = cl_qlist_obj(p_obj); 136321936Shselasky 137321936Shselasky if (FALSE == cl_is_qlist_empty(p_bufs)) { 138321936Shselasky memcpy((char *)p_mad, (char *)buf_tmp + p_sar->hdr_sz, 139321936Shselasky p_sar->data_sz); 140321936Shselasky p_mad = (char *)p_mad + p_sar->data_sz; 141321936Shselasky space_left -= p_sar->data_sz; 142321936Shselasky } else { 143321936Shselasky /* the last mad on the list */ 144321936Shselasky memcpy((char *)p_mad, (char *)buf_tmp + p_sar->hdr_sz, 145321936Shselasky space_left); 146321936Shselasky p_mad = (char *)p_mad + space_left; 147321936Shselasky } 148321936Shselasky 149321936Shselasky free(buf_tmp); 150321936Shselasky free(p_obj); 151321936Shselasky } 152321936Shselasky 153321936Shselasky return IB_SUCCESS; 154321936Shselasky} 155