Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c
48524 views
1
/*
2
* Copyright 2008-2012 Freescale Semiconductor Inc.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
6
* * Redistributions of source code must retain the above copyright
7
* notice, this list of conditions and the following disclaimer.
8
* * Redistributions in binary form must reproduce the above copyright
9
* notice, this list of conditions and the following disclaimer in the
10
* documentation and/or other materials provided with the distribution.
11
* * Neither the name of Freescale Semiconductor nor the
12
* names of its contributors may be used to endorse or promote products
13
* derived from this software without specific prior written permission.
14
*
15
*
16
* ALTERNATIVELY, this software may be distributed under the terms of the
17
* GNU General Public License ("GPL") as published by the Free Software
18
* Foundation, either version 2 of that License or (at your option) any
19
* later version.
20
*
21
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
34
/******************************************************************************
35
@File fm_pcd.c
36
37
@Description FM PCD ...
38
*//***************************************************************************/
39
#include <linux/math64.h>
40
#include "std_ext.h"
41
#include "error_ext.h"
42
#include "string_ext.h"
43
#include "debug_ext.h"
44
#include "net_ext.h"
45
46
#include "fm_common.h"
47
#include "fm_pcd.h"
48
#include "fm_pcd_ipc.h"
49
#include "fm_prs.h"
50
#include "fsl_fman_prs.h"
51
52
53
static void PcdPrsErrorException(t_Handle h_FmPcd)
54
{
55
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
56
uint32_t event, ev_mask;
57
struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
58
59
ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
60
ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
61
62
event = fman_prs_get_err_event(PrsRegs, ev_mask);
63
64
fman_prs_ack_err_event(PrsRegs, event);
65
66
DBG(TRACE, ("parser error - 0x%08x\n",event));
67
68
if(event & FM_PCD_PRS_DOUBLE_ECC)
69
p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
70
}
71
72
static void PcdPrsException(t_Handle h_FmPcd)
73
{
74
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
75
uint32_t event, ev_mask;
76
struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
77
78
ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
79
ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
80
event = fman_prs_get_expt_event(PrsRegs, ev_mask);
81
82
ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
83
84
DBG(TRACE, ("parser event - 0x%08x\n",event));
85
86
fman_prs_ack_expt_event(PrsRegs, event);
87
88
p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
89
}
90
91
t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
92
{
93
t_FmPcdPrs *p_FmPcdPrs;
94
uintptr_t baseAddr;
95
96
UNUSED(p_FmPcd);
97
UNUSED(p_FmPcdParams);
98
99
p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
100
if (!p_FmPcdPrs)
101
{
102
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
103
return NULL;
104
}
105
memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
106
fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
107
108
if (p_FmPcd->guestId == NCSW_MASTER_ID)
109
{
110
baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
111
p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
112
p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
113
}
114
115
p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
116
p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
117
p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
118
119
return p_FmPcdPrs;
120
}
121
122
#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
123
static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
124
#else
125
static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
126
#endif /* FM_CAPWAP_SUPPORT */
127
128
t_Error PrsInit(t_FmPcd *p_FmPcd)
129
{
130
t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
131
uint32_t *p_TmpCode;
132
uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
133
FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
134
struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
135
uint32_t i;
136
137
ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
138
139
/* nothing to do in guest-partition */
140
if (p_FmPcd->guestId != NCSW_MASTER_ID)
141
return E_OK;
142
143
p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
144
if (!p_TmpCode)
145
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
146
memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
147
memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
148
149
fman_prs_init(PrsRegs, &p_Param->dfltCfg);
150
151
/* register even if no interrupts enabled, to allow future enablement */
152
FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
153
154
/* register even if no interrupts enabled, to allow future enablement */
155
FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
156
157
if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
158
FmEnableRamsEcc(p_FmPcd->h_Fm);
159
160
if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
161
FmEnableRamsEcc(p_FmPcd->h_Fm);
162
163
/* load sw parser Ip-Frag patch */
164
for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
165
WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
166
167
XX_FreeSmart(p_TmpCode);
168
169
return E_OK;
170
}
171
172
void PrsFree(t_FmPcd *p_FmPcd)
173
{
174
ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
175
FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
176
/* register even if no interrupts enabled, to allow future enablement */
177
FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
178
}
179
180
void PrsEnable(t_FmPcd *p_FmPcd)
181
{
182
struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
183
184
ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
185
fman_prs_enable(PrsRegs);
186
}
187
188
void PrsDisable(t_FmPcd *p_FmPcd)
189
{
190
struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
191
192
ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
193
fman_prs_disable(PrsRegs);
194
}
195
196
int PrsIsEnabled(t_FmPcd *p_FmPcd)
197
{
198
struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
199
200
ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
201
return fman_prs_is_enabled(PrsRegs);
202
}
203
204
t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
205
{
206
struct fman_prs_regs *PrsRegs;
207
uint32_t bitMask = 0;
208
uint8_t prsPortId;
209
210
SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
211
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
212
SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
213
214
PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
215
216
GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
217
GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
218
219
if (include)
220
p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
221
else
222
p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
223
224
fman_prs_set_stst_port_msk(PrsRegs,
225
p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
226
227
return E_OK;
228
}
229
230
t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
231
{
232
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
233
t_Error err;
234
235
SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
236
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
237
SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
238
239
if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
240
p_FmPcd->h_IpcSession)
241
{
242
t_FmPcdIpcPrsIncludePort prsIncludePortParams;
243
t_FmPcdIpcMsg msg;
244
245
prsIncludePortParams.hardwarePortId = hardwarePortId;
246
prsIncludePortParams.include = include;
247
memset(&msg, 0, sizeof(msg));
248
msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
249
memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
250
err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
251
(uint8_t*)&msg,
252
sizeof(msg.msgId) +sizeof(prsIncludePortParams),
253
NULL,
254
NULL,
255
NULL,
256
NULL);
257
if (err != E_OK)
258
RETURN_ERROR(MAJOR, err, NO_MSG);
259
return E_OK;
260
}
261
else if (p_FmPcd->guestId != NCSW_MASTER_ID)
262
RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
263
("running in guest-mode without IPC!"));
264
265
return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
266
}
267
268
uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
269
{
270
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
271
t_FmPcdPrsLabelParams *p_Label;
272
int i;
273
274
SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
275
SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
276
277
if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
278
p_FmPcd->h_IpcSession)
279
{
280
t_Error err = E_OK;
281
t_FmPcdIpcSwPrsLable labelParams;
282
t_FmPcdIpcMsg msg;
283
uint32_t prsOffset = 0;
284
t_FmPcdIpcReply reply;
285
uint32_t replyLength;
286
287
memset(&reply, 0, sizeof(reply));
288
memset(&msg, 0, sizeof(msg));
289
labelParams.enumHdr = (uint32_t)hdr;
290
labelParams.indexPerHdr = indexPerHdr;
291
msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
292
memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
293
replyLength = sizeof(uint32_t) + sizeof(uint32_t);
294
err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
295
(uint8_t*)&msg,
296
sizeof(msg.msgId) +sizeof(labelParams),
297
(uint8_t*)&reply,
298
&replyLength,
299
NULL,
300
NULL);
301
if (err != E_OK)
302
RETURN_ERROR(MAJOR, err, NO_MSG);
303
if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
304
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
305
306
memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
307
return prsOffset;
308
}
309
else if (p_FmPcd->guestId != NCSW_MASTER_ID)
310
RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
311
("running in guest-mode without IPC!"));
312
313
ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
314
315
for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
316
{
317
p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
318
319
if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
320
return p_Label->instructionOffset;
321
}
322
323
REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
324
return (uint32_t)ILLEGAL_BASE;
325
}
326
327
void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
328
{
329
t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
330
struct fman_prs_regs *PrsRegs;
331
332
SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
333
SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
334
335
PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
336
337
338
if(p_FmPcd->guestId != NCSW_MASTER_ID)
339
{
340
REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
341
return;
342
}
343
344
fman_prs_set_stst(PrsRegs, enable);
345
}
346
347
t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
348
{
349
t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
350
uint32_t *p_LoadTarget;
351
uint32_t *p_TmpCode;
352
int i;
353
354
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
355
SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
356
SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
357
SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
358
SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
359
360
if (p_FmPcd->guestId != NCSW_MASTER_ID)
361
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
362
363
if (!p_SwPrs->override)
364
{
365
if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
366
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
367
}
368
else
369
p_FmPcd->p_FmPcdPrs->currLabel = 0;
370
371
if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
372
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
373
374
if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
375
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
376
377
p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
378
if (!p_TmpCode)
379
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
380
memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
381
memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
382
383
/* save sw parser labels */
384
memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
385
p_SwPrs->labelsTable,
386
p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
387
p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
388
389
/* load sw parser code */
390
p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
391
392
for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
393
WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
394
395
p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
396
p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
397
398
/* copy data parameters */
399
for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
400
WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
401
402
/* Clear last 4 bytes */
403
WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
404
405
XX_FreeSmart(p_TmpCode);
406
407
return E_OK;
408
}
409
410
t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
411
{
412
t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
413
414
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
415
SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
416
417
if(p_FmPcd->guestId != NCSW_MASTER_ID)
418
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
419
420
p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
421
422
return E_OK;
423
}
424
425