18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2008 - 2015 Freescale Semiconductor Inc.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
58c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions are met:
68c2ecf20Sopenharmony_ci *     * Redistributions of source code must retain the above copyright
78c2ecf20Sopenharmony_ci *       notice, this list of conditions and the following disclaimer.
88c2ecf20Sopenharmony_ci *     * Redistributions in binary form must reproduce the above copyright
98c2ecf20Sopenharmony_ci *       notice, this list of conditions and the following disclaimer in the
108c2ecf20Sopenharmony_ci *       documentation and/or other materials provided with the distribution.
118c2ecf20Sopenharmony_ci *     * Neither the name of Freescale Semiconductor nor the
128c2ecf20Sopenharmony_ci *       names of its contributors may be used to endorse or promote products
138c2ecf20Sopenharmony_ci *       derived from this software without specific prior written permission.
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * ALTERNATIVELY, this software may be distributed under the terms of the
178c2ecf20Sopenharmony_ci * GNU General Public License ("GPL") as published by the Free Software
188c2ecf20Sopenharmony_ci * Foundation, either version 2 of that License or (at your option) any
198c2ecf20Sopenharmony_ci * later version.
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
228c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
238c2ecf20Sopenharmony_ci * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
248c2ecf20Sopenharmony_ci * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
258c2ecf20Sopenharmony_ci * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
268c2ecf20Sopenharmony_ci * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
278c2ecf20Sopenharmony_ci * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
288c2ecf20Sopenharmony_ci * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
298c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
308c2ecf20Sopenharmony_ci * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#include "fman_sp.h"
348c2ecf20Sopenharmony_ci#include "fman.h"
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_civoid fman_sp_set_buf_pools_in_asc_order_of_buf_sizes(struct fman_ext_pools
378c2ecf20Sopenharmony_ci						     *fm_ext_pools,
388c2ecf20Sopenharmony_ci						     u8 *ordered_array,
398c2ecf20Sopenharmony_ci						     u16 *sizes_array)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	u16 buf_size = 0;
428c2ecf20Sopenharmony_ci	int i = 0, j = 0, k = 0;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	/* First we copy the external buffers pools information
458c2ecf20Sopenharmony_ci	 * to an ordered local array
468c2ecf20Sopenharmony_ci	 */
478c2ecf20Sopenharmony_ci	for (i = 0; i < fm_ext_pools->num_of_pools_used; i++) {
488c2ecf20Sopenharmony_ci		/* get pool size */
498c2ecf20Sopenharmony_ci		buf_size = fm_ext_pools->ext_buf_pool[i].size;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci		/* keep sizes in an array according to poolId
528c2ecf20Sopenharmony_ci		 * for direct access
538c2ecf20Sopenharmony_ci		 */
548c2ecf20Sopenharmony_ci		sizes_array[fm_ext_pools->ext_buf_pool[i].id] = buf_size;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci		/* save poolId in an ordered array according to size */
578c2ecf20Sopenharmony_ci		for (j = 0; j <= i; j++) {
588c2ecf20Sopenharmony_ci			/* this is the next free place in the array */
598c2ecf20Sopenharmony_ci			if (j == i)
608c2ecf20Sopenharmony_ci				ordered_array[i] =
618c2ecf20Sopenharmony_ci				    fm_ext_pools->ext_buf_pool[i].id;
628c2ecf20Sopenharmony_ci			else {
638c2ecf20Sopenharmony_ci				/* find the right place for this poolId */
648c2ecf20Sopenharmony_ci				if (buf_size < sizes_array[ordered_array[j]]) {
658c2ecf20Sopenharmony_ci					/* move the pool_ids one place ahead
668c2ecf20Sopenharmony_ci					 * to make room for this poolId
678c2ecf20Sopenharmony_ci					 */
688c2ecf20Sopenharmony_ci					for (k = i; k > j; k--)
698c2ecf20Sopenharmony_ci						ordered_array[k] =
708c2ecf20Sopenharmony_ci						    ordered_array[k - 1];
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci					/* now k==j, this is the place for
738c2ecf20Sopenharmony_ci					 * the new size
748c2ecf20Sopenharmony_ci					 */
758c2ecf20Sopenharmony_ci					ordered_array[k] =
768c2ecf20Sopenharmony_ci					    fm_ext_pools->ext_buf_pool[i].id;
778c2ecf20Sopenharmony_ci					break;
788c2ecf20Sopenharmony_ci				}
798c2ecf20Sopenharmony_ci			}
808c2ecf20Sopenharmony_ci		}
818c2ecf20Sopenharmony_ci	}
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fman_sp_set_buf_pools_in_asc_order_of_buf_sizes);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciint fman_sp_build_buffer_struct(struct fman_sp_int_context_data_copy *
868c2ecf20Sopenharmony_ci				int_context_data_copy,
878c2ecf20Sopenharmony_ci				struct fman_buffer_prefix_content *
888c2ecf20Sopenharmony_ci				buffer_prefix_content,
898c2ecf20Sopenharmony_ci				struct fman_sp_buf_margins *buf_margins,
908c2ecf20Sopenharmony_ci				struct fman_sp_buffer_offsets *buffer_offsets,
918c2ecf20Sopenharmony_ci				u8 *internal_buf_offset)
928c2ecf20Sopenharmony_ci{
938c2ecf20Sopenharmony_ci	u32 tmp;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	/* Align start of internal context data to 16 byte */
968c2ecf20Sopenharmony_ci	int_context_data_copy->ext_buf_offset = (u16)
978c2ecf20Sopenharmony_ci		((buffer_prefix_content->priv_data_size & (OFFSET_UNITS - 1)) ?
988c2ecf20Sopenharmony_ci		((buffer_prefix_content->priv_data_size + OFFSET_UNITS) &
998c2ecf20Sopenharmony_ci			~(u16)(OFFSET_UNITS - 1)) :
1008c2ecf20Sopenharmony_ci		buffer_prefix_content->priv_data_size);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	/* Translate margin and int_context params to FM parameters */
1038c2ecf20Sopenharmony_ci	/* Initialize with illegal value. Later we'll set legal values. */
1048c2ecf20Sopenharmony_ci	buffer_offsets->prs_result_offset = (u32)ILLEGAL_BASE;
1058c2ecf20Sopenharmony_ci	buffer_offsets->time_stamp_offset = (u32)ILLEGAL_BASE;
1068c2ecf20Sopenharmony_ci	buffer_offsets->hash_result_offset = (u32)ILLEGAL_BASE;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	/* Internally the driver supports 4 options
1098c2ecf20Sopenharmony_ci	 * 1. prsResult/timestamp/hashResult selection (in fact 8 options,
1108c2ecf20Sopenharmony_ci	 * but for simplicity we'll
1118c2ecf20Sopenharmony_ci	 * relate to it as 1).
1128c2ecf20Sopenharmony_ci	 * 2. All IC context (from AD) not including debug.
1138c2ecf20Sopenharmony_ci	 */
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	/* This case covers the options under 1 */
1168c2ecf20Sopenharmony_ci	/* Copy size must be in 16-byte granularity. */
1178c2ecf20Sopenharmony_ci	int_context_data_copy->size =
1188c2ecf20Sopenharmony_ci	    (u16)((buffer_prefix_content->pass_prs_result ? 32 : 0) +
1198c2ecf20Sopenharmony_ci		  ((buffer_prefix_content->pass_time_stamp ||
1208c2ecf20Sopenharmony_ci		  buffer_prefix_content->pass_hash_result) ? 16 : 0));
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	/* Align start of internal context data to 16 byte */
1238c2ecf20Sopenharmony_ci	int_context_data_copy->int_context_offset =
1248c2ecf20Sopenharmony_ci	    (u8)(buffer_prefix_content->pass_prs_result ? 32 :
1258c2ecf20Sopenharmony_ci		 ((buffer_prefix_content->pass_time_stamp ||
1268c2ecf20Sopenharmony_ci		 buffer_prefix_content->pass_hash_result) ? 64 : 0));
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	if (buffer_prefix_content->pass_prs_result)
1298c2ecf20Sopenharmony_ci		buffer_offsets->prs_result_offset =
1308c2ecf20Sopenharmony_ci		    int_context_data_copy->ext_buf_offset;
1318c2ecf20Sopenharmony_ci	if (buffer_prefix_content->pass_time_stamp)
1328c2ecf20Sopenharmony_ci		buffer_offsets->time_stamp_offset =
1338c2ecf20Sopenharmony_ci		    buffer_prefix_content->pass_prs_result ?
1348c2ecf20Sopenharmony_ci		    (int_context_data_copy->ext_buf_offset +
1358c2ecf20Sopenharmony_ci			sizeof(struct fman_prs_result)) :
1368c2ecf20Sopenharmony_ci		    int_context_data_copy->ext_buf_offset;
1378c2ecf20Sopenharmony_ci	if (buffer_prefix_content->pass_hash_result)
1388c2ecf20Sopenharmony_ci		/* If PR is not requested, whether TS is
1398c2ecf20Sopenharmony_ci		 * requested or not, IC will be copied from TS
1408c2ecf20Sopenharmony_ci			 */
1418c2ecf20Sopenharmony_ci		buffer_offsets->hash_result_offset =
1428c2ecf20Sopenharmony_ci		buffer_prefix_content->pass_prs_result ?
1438c2ecf20Sopenharmony_ci			(int_context_data_copy->ext_buf_offset +
1448c2ecf20Sopenharmony_ci				sizeof(struct fman_prs_result) + 8) :
1458c2ecf20Sopenharmony_ci			int_context_data_copy->ext_buf_offset + 8;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	if (int_context_data_copy->size)
1488c2ecf20Sopenharmony_ci		buf_margins->start_margins =
1498c2ecf20Sopenharmony_ci		    (u16)(int_context_data_copy->ext_buf_offset +
1508c2ecf20Sopenharmony_ci			  int_context_data_copy->size);
1518c2ecf20Sopenharmony_ci	else
1528c2ecf20Sopenharmony_ci		/* No Internal Context passing, STartMargin is
1538c2ecf20Sopenharmony_ci		 * immediately after private_info
1548c2ecf20Sopenharmony_ci		 */
1558c2ecf20Sopenharmony_ci		buf_margins->start_margins =
1568c2ecf20Sopenharmony_ci		    buffer_prefix_content->priv_data_size;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	/* align data start */
1598c2ecf20Sopenharmony_ci	tmp = (u32)(buf_margins->start_margins %
1608c2ecf20Sopenharmony_ci		    buffer_prefix_content->data_align);
1618c2ecf20Sopenharmony_ci	if (tmp)
1628c2ecf20Sopenharmony_ci		buf_margins->start_margins +=
1638c2ecf20Sopenharmony_ci		    (buffer_prefix_content->data_align - tmp);
1648c2ecf20Sopenharmony_ci	buffer_offsets->data_offset = buf_margins->start_margins;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	return 0;
1678c2ecf20Sopenharmony_ci}
1688c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fman_sp_build_buffer_struct);
1698c2ecf20Sopenharmony_ci
170