blob: d0eec296f852f7ed30f05c99d2af99a3ce037475 [file] [log] [blame]
developer02e65912023-08-17 16:33:10 +08001/* adapter_pec_pktbuf.c
2 *
3 * Helper functions to access packet data via DMABuf handles, possibly
4 * in scatter-gather lists.
5 */
6
7/*****************************************************************************
8* Copyright (c) 2020-2021 by Rambus, Inc. and/or its subsidiaries.
9*
10* This program is free software: you can redistribute it and/or modify
11* it under the terms of the GNU General Public License as published by
12* the Free Software Foundation, either version 2 of the License, or
13* any later version.
14*
15* This program is distributed in the hope that it will be useful,
16* but WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18* GNU General Public License for more details.
19*
20* You should have received a copy of the GNU General Public License
21* along with this program. If not, see <http://www.gnu.org/licenses/>.
22*****************************************************************************/
23
24
25/*----------------------------------------------------------------------------
26 * This module implements (provides) the following interface(s):
27 */
28
29#include "adapter_pec_pktbuf.h"
30
31/*----------------------------------------------------------------------------
32 * This module uses (requires) the following interface(s):
33 */
34
35// Default Adapter PEC configuration
36#include "c_adapter_pec.h"
37
38#include "api_pec_sg.h" // PEC_SG_* (the API we implement here)
39
40
41// DMABuf API
42#include "api_dmabuf.h" // DMABuf_*
43
44// Adapter DMABuf internal API
45#include "adapter_dmabuf.h"
46
47// Logging API
48#include "log.h"
49
50// Driver Framework DMAResource API
51#include "dmares_types.h" // DMAResource_Handle_t
52#include "dmares_mgmt.h" // DMAResource management functions
53#include "dmares_rw.h" // DMAResource buffer access.
54#include "dmares_addr.h" // DMAResource addr translation functions.
55#include "dmares_buf.h" // DMAResource buffer allocations
56
57// Driver Framework C Run-Time Library API
58#include "clib.h" // memcpy, memset
59
60// Driver Framework Basic Definitions API
61#include "basic_defs.h" // bool, uint32_t
62
63
64/*----------------------------------------------------------------------------
65 * Definitions and macros
66 */
67
68/*----------------------------------------------------------------------------
69 * Adapter_PEC_PktData_Get
70 */
71uint8_t *
72Adapter_PEC_PktData_Get(
73 DMABuf_Handle_t PacketHandle,
74 uint8_t *CopyBuffer_p,
75 unsigned int StartOffs,
76 unsigned int ByteCount)
77{
78#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
79 unsigned int NofParticles;
80 PEC_SGList_GetCapacity(PacketHandle, &NofParticles);
81 if (NofParticles != 0)
82 {
83 unsigned int TotalByteCount = 0;
84 unsigned int BytesCopied = 0;
85 unsigned int BytesSkip;
86 unsigned int i;
87 unsigned int FragmentByteCount;
88 DMABuf_Handle_t FragmentHandle;
89 uint8_t *FragmentPtr;
90 for (i=0; i<NofParticles; i++)
91 {
92 PEC_SGList_Read(PacketHandle, i, &FragmentHandle,
93 &FragmentByteCount, &FragmentPtr);
94 if (TotalByteCount + FragmentByteCount >=
95 StartOffs + ByteCount)
96 {
97 // This is the last fragment to visit (possibly the first).
98 if (BytesCopied == 0)
99 {
100 // No need to copy everything is in single fragment.
101 return FragmentPtr + StartOffs - TotalByteCount;
102 }
103 else
104 {
105 // Copy the final fragment.
106 memcpy(CopyBuffer_p + BytesCopied,
107 FragmentPtr, ByteCount - BytesCopied);
108 return CopyBuffer_p;
109 }
110 }
111 else if (TotalByteCount + FragmentByteCount >
112 StartOffs)
113 {
114 // This fragment contains data that must be copied
115 if (BytesCopied == 0)
116 {
117 // First fragment containing data to copy, may need to skip
118 // bytes at start of fragment.
119 BytesSkip = StartOffs - TotalByteCount;
120 }
121 else
122 { // Later fragments, copy from start of fragment.
123 BytesSkip = 0;
124 }
125 if (CopyBuffer_p == NULL)
126 return NULL; // Skip copying altogether.
127 memcpy(CopyBuffer_p + BytesCopied,
128 FragmentPtr + BytesSkip,
129 FragmentByteCount - BytesSkip);
130 BytesCopied += FragmentByteCount - BytesSkip;
131 }
132 TotalByteCount += FragmentByteCount;
133 }
134 // We haven't collected enough data here, return NULL pointer.
135 return NULL;
136 }
137 else
138#endif
139 {
140 DMAResource_Handle_t DMAHandle =
141 Adapter_DMABuf_Handle2DMAResourceHandle(PacketHandle);
142 uint8_t *Packet_p;
143 IDENTIFIER_NOT_USED(CopyBuffer_p);
144 IDENTIFIER_NOT_USED(ByteCount);
145 if (DMAResource_IsValidHandle(DMAHandle))
146 {
147 Packet_p = (uint8_t *)Adapter_DMAResource_HostAddr(DMAHandle) + StartOffs;
148 }
149 else
150 {
151 Packet_p = NULL;
152 }
153 return Packet_p;
154 }
155}
156
157/*----------------------------------------------------------------------------
158 * Adapter_PEC_PktByte_Put
159 */
160void
161Adapter_PEC_PktByte_Put(
162 DMABuf_Handle_t PacketHandle,
163 unsigned int Offset,
164 unsigned int Byte)
165{
166#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
167 unsigned int NofParticles;
168 PEC_SGList_GetCapacity(PacketHandle, &NofParticles);
169 if (NofParticles != 0)
170 {
171 unsigned int TotalByteCount = 0;
172 unsigned int i;
173 unsigned int FragmentByteCount;
174 DMABuf_Handle_t FragmentHandle;
175 uint8_t *FragmentPtr;
176 for (i=0; i<NofParticles; i++)
177 {
178 PEC_SGList_Read(PacketHandle, i, &FragmentHandle,
179 &FragmentByteCount, &FragmentPtr);
180 if (TotalByteCount + FragmentByteCount > Offset)
181 {
182 // Found the fragment where the byte must be changed..
183 FragmentPtr[Offset - TotalByteCount] = Byte;
184 return;
185 }
186 TotalByteCount += FragmentByteCount;
187 }
188 }
189 else
190#endif
191 {
192 DMAResource_Handle_t DMAHandle =
193 Adapter_DMABuf_Handle2DMAResourceHandle(PacketHandle);
194 uint8_t *Packet_p;
195 if (DMAResource_IsValidHandle(DMAHandle))
196 {
197 Packet_p = (uint8_t *)Adapter_DMAResource_HostAddr(DMAHandle) + Offset;
198 Packet_p[0] = Byte;
199 }
200 }
201}
202
203
204
205
206/* end of file adapter_pec_dmabuf.c */