]> Git Repo - J-linux.git/blob - drivers/net/ethernet/freescale/fman/fman_sp.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / ethernet / freescale / fman / fman_sp.c
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
This page took 0.034552 seconds and 4 git commands to generate.