1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later |
2 | /* |
3 | * Copyright 2008 - 2015 Freescale Semiconductor Inc. |
4 | */ |
5 | |
6 | #include "fman_sp.h" |
7 | #include "fman.h" |
8 | |
9 | void fman_sp_set_buf_pools_in_asc_order_of_buf_sizes(struct fman_ext_pools |
10 | *fm_ext_pools, |
11 | u8 *ordered_array, |
12 | u16 *sizes_array) |
13 | { |
14 | u16 buf_size = 0; |
15 | int i = 0, j = 0, k = 0; |
16 | |
17 | /* First we copy the external buffers pools information |
18 | * to an ordered local array |
19 | */ |
20 | for (i = 0; i < fm_ext_pools->num_of_pools_used; i++) { |
21 | /* get pool size */ |
22 | buf_size = fm_ext_pools->ext_buf_pool[i].size; |
23 | |
24 | /* keep sizes in an array according to poolId |
25 | * for direct access |
26 | */ |
27 | sizes_array[fm_ext_pools->ext_buf_pool[i].id] = buf_size; |
28 | |
29 | /* save poolId in an ordered array according to size */ |
30 | for (j = 0; j <= i; j++) { |
31 | /* this is the next free place in the array */ |
32 | if (j == i) |
33 | ordered_array[i] = |
34 | fm_ext_pools->ext_buf_pool[i].id; |
35 | else { |
36 | /* find the right place for this poolId */ |
37 | if (buf_size < sizes_array[ordered_array[j]]) { |
38 | /* move the pool_ids one place ahead |
39 | * to make room for this poolId |
40 | */ |
41 | for (k = i; k > j; k--) |
42 | ordered_array[k] = |
43 | ordered_array[k - 1]; |
44 | |
45 | /* now k==j, this is the place for |
46 | * the new size |
47 | */ |
48 | ordered_array[k] = |
49 | fm_ext_pools->ext_buf_pool[i].id; |
50 | break; |
51 | } |
52 | } |
53 | } |
54 | } |
55 | } |
56 | EXPORT_SYMBOL(fman_sp_set_buf_pools_in_asc_order_of_buf_sizes); |
57 | |
58 | int fman_sp_build_buffer_struct(struct fman_sp_int_context_data_copy * |
59 | int_context_data_copy, |
60 | struct fman_buffer_prefix_content * |
61 | buffer_prefix_content, |
62 | struct fman_sp_buf_margins *buf_margins, |
63 | struct fman_sp_buffer_offsets *buffer_offsets, |
64 | u8 *internal_buf_offset) |
65 | { |
66 | u32 tmp; |
67 | |
68 | /* Align start of internal context data to 16 byte */ |
69 | int_context_data_copy->ext_buf_offset = (u16) |
70 | ((buffer_prefix_content->priv_data_size & (OFFSET_UNITS - 1)) ? |
71 | ((buffer_prefix_content->priv_data_size + OFFSET_UNITS) & |
72 | ~(u16)(OFFSET_UNITS - 1)) : |
73 | buffer_prefix_content->priv_data_size); |
74 | |
75 | /* Translate margin and int_context params to FM parameters */ |
76 | /* Initialize with illegal value. Later we'll set legal values. */ |
77 | buffer_offsets->prs_result_offset = (u32)ILLEGAL_BASE; |
78 | buffer_offsets->time_stamp_offset = (u32)ILLEGAL_BASE; |
79 | buffer_offsets->hash_result_offset = (u32)ILLEGAL_BASE; |
80 | |
81 | /* Internally the driver supports 4 options |
82 | * 1. prsResult/timestamp/hashResult selection (in fact 8 options, |
83 | * but for simplicity we'll |
84 | * relate to it as 1). |
85 | * 2. All IC context (from AD) not including debug. |
86 | */ |
87 | |
88 | /* This case covers the options under 1 */ |
89 | /* Copy size must be in 16-byte granularity. */ |
90 | int_context_data_copy->size = |
91 | (u16)((buffer_prefix_content->pass_prs_result ? 32 : 0) + |
92 | ((buffer_prefix_content->pass_time_stamp || |
93 | buffer_prefix_content->pass_hash_result) ? 16 : 0)); |
94 | |
95 | /* Align start of internal context data to 16 byte */ |
96 | int_context_data_copy->int_context_offset = |
97 | (u8)(buffer_prefix_content->pass_prs_result ? 32 : |
98 | ((buffer_prefix_content->pass_time_stamp || |
99 | buffer_prefix_content->pass_hash_result) ? 64 : 0)); |
100 | |
101 | if (buffer_prefix_content->pass_prs_result) |
102 | buffer_offsets->prs_result_offset = |
103 | int_context_data_copy->ext_buf_offset; |
104 | if (buffer_prefix_content->pass_time_stamp) |
105 | buffer_offsets->time_stamp_offset = |
106 | buffer_prefix_content->pass_prs_result ? |
107 | (int_context_data_copy->ext_buf_offset + |
108 | sizeof(struct fman_prs_result)) : |
109 | int_context_data_copy->ext_buf_offset; |
110 | if (buffer_prefix_content->pass_hash_result) |
111 | /* If PR is not requested, whether TS is |
112 | * requested or not, IC will be copied from TS |
113 | */ |
114 | buffer_offsets->hash_result_offset = |
115 | buffer_prefix_content->pass_prs_result ? |
116 | (int_context_data_copy->ext_buf_offset + |
117 | sizeof(struct fman_prs_result) + 8) : |
118 | int_context_data_copy->ext_buf_offset + 8; |
119 | |
120 | if (int_context_data_copy->size) |
121 | buf_margins->start_margins = |
122 | (u16)(int_context_data_copy->ext_buf_offset + |
123 | int_context_data_copy->size); |
124 | else |
125 | /* No Internal Context passing, STartMargin is |
126 | * immediately after private_info |
127 | */ |
128 | buf_margins->start_margins = |
129 | buffer_prefix_content->priv_data_size; |
130 | |
131 | /* align data start */ |
132 | tmp = (u32)(buf_margins->start_margins % |
133 | buffer_prefix_content->data_align); |
134 | if (tmp) |
135 | buf_margins->start_margins += |
136 | (buffer_prefix_content->data_align - tmp); |
137 | buffer_offsets->data_offset = buf_margins->start_margins; |
138 | |
139 | return 0; |
140 | } |
141 | EXPORT_SYMBOL(fman_sp_build_buffer_struct); |
142 | |
143 | |