1/* 2 * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 * 34 */ 35 36#if HAVE_CONFIG_H 37# include <config.h> 38#endif /* HAVE_CONFIG_H */ 39 40#include <stdlib.h> 41#include <string.h> 42#include <stdio.h> 43#include <vendor/osm_vendor_mlx_sar.h> 44 45ib_api_status_t 46osmv_rmpp_sar_init(osmv_rmpp_sar_t * p_sar, void *p_arbt_mad, 47 uint32_t mad_size, boolean_t is_sa_mad) 48{ 49 CL_ASSERT(p_sar); 50 p_sar->p_arbt_mad = p_arbt_mad; 51 if (is_sa_mad) { 52 p_sar->data_len = mad_size - IB_SA_MAD_HDR_SIZE; 53 p_sar->hdr_sz = IB_SA_MAD_HDR_SIZE; 54 p_sar->data_sz = IB_SA_DATA_SIZE; 55 } else { 56 p_sar->data_len = mad_size - MAD_RMPP_HDR_SIZE; 57 p_sar->hdr_sz = MAD_RMPP_HDR_SIZE; 58 p_sar->data_sz = MAD_RMPP_DATA_SIZE; 59 } 60 return IB_SUCCESS; 61} 62 63void osmv_rmpp_sar_done(osmv_rmpp_sar_t * p_sar) 64{ 65 p_sar->p_arbt_mad = NULL; 66} 67 68/* the big mad should be with mad header, rmpp header ( &sa hdr) space */ 69ib_api_status_t 70osmv_rmpp_sar_get_mad_seg(IN osmv_rmpp_sar_t * p_sar, 71 IN uint32_t seg_idx, OUT void *p_buf) 72{ 73 void *p_seg; 74 uint32_t sz_left; 75 uint32_t num_segs; 76 77 CL_ASSERT(p_sar); 78 79 num_segs = p_sar->data_len / p_sar->data_sz; 80 if ((p_sar->data_len % p_sar->data_sz) > 0) { 81 num_segs++; 82 } 83 84 if ((seg_idx > num_segs) && (seg_idx != 1)) { 85 return IB_NOT_FOUND; 86 } 87 88 /* cleanup */ 89 memset(p_buf, 0, MAD_BLOCK_SIZE); 90 91 /* attach header */ 92 memcpy(p_buf, p_sar->p_arbt_mad, p_sar->hdr_sz); 93 94 /* fill data */ 95 p_seg = 96 (char *)p_sar->p_arbt_mad + p_sar->hdr_sz + 97 ((seg_idx - 1) * p_sar->data_sz); 98 sz_left = p_sar->data_len - ((seg_idx - 1) * p_sar->data_sz); 99 if (sz_left > p_sar->data_sz) 100 memcpy((char *)p_buf + p_sar->hdr_sz, (char *)p_seg, 101 p_sar->data_sz); 102 else 103 memcpy((char *)p_buf + p_sar->hdr_sz, (char *)p_seg, sz_left); 104 105 return IB_SUCCESS; 106} 107 108/* turns a list of mads to one big mad - including header */ 109/* ALSO - deallocates the list */ 110ib_api_status_t 111osmv_rmpp_sar_reassemble_arbt_mad(osmv_rmpp_sar_t * p_sar, cl_qlist_t * p_bufs) 112{ 113 void *buf_tmp, *p_mad; 114 cl_list_item_t *p_item; 115 cl_list_obj_t *p_obj; 116 uint32_t space_left = p_sar->data_len + p_sar->hdr_sz; 117 118 CL_ASSERT(p_sar); 119 CL_ASSERT(FALSE == cl_is_qlist_empty(p_bufs)); 120 121 /* attach header */ 122 p_mad = p_sar->p_arbt_mad; 123 p_item = cl_qlist_head(p_bufs); 124 p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item); 125 buf_tmp = cl_qlist_obj(p_obj); 126 memcpy(p_mad, buf_tmp, p_sar->hdr_sz); 127 p_mad = (char *)p_mad + p_sar->hdr_sz; 128 space_left -= p_sar->hdr_sz; 129 130 /* reassemble data */ 131 while (FALSE == cl_is_qlist_empty(p_bufs)) { 132 133 p_item = cl_qlist_remove_head(p_bufs); 134 p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item); 135 buf_tmp = cl_qlist_obj(p_obj); 136 137 if (FALSE == cl_is_qlist_empty(p_bufs)) { 138 memcpy((char *)p_mad, (char *)buf_tmp + p_sar->hdr_sz, 139 p_sar->data_sz); 140 p_mad = (char *)p_mad + p_sar->data_sz; 141 space_left -= p_sar->data_sz; 142 } else { 143 /* the last mad on the list */ 144 memcpy((char *)p_mad, (char *)buf_tmp + p_sar->hdr_sz, 145 space_left); 146 p_mad = (char *)p_mad + space_left; 147 } 148 149 free(buf_tmp); 150 free(p_obj); 151 } 152 153 return IB_SUCCESS; 154} 155