blob: 249950a89752337e241eda4ebf29acc3bd322271 [file] [log] [blame]
developer02e65912023-08-17 16:33:10 +08001/* adapter_pcl_dtl.c
2 *
3 * Packet Classification (PCL) DTL API implementation.
4 */
5
6/*****************************************************************************
7* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
8*
9* This program is free software: you can redistribute it and/or modify
10* it under the terms of the GNU General Public License as published by
11* the Free Software Foundation, either version 2 of the License, or
12* any later version.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License
20* along with this program. If not, see <http://www.gnu.org/licenses/>.
21******************************************************************************/
22
23/*----------------------------------------------------------------------------
24 * This module implements (provides) the following interface(s):
25 */
26
27// PCL API
28#include "api_pcl.h" // PCL_*
29
30// PCL DTL API
31#include "api_pcl_dtl.h" // PCL_DTL_*
32
33
34/*----------------------------------------------------------------------------
35 * This module uses (requires) the following interface(s):
36 */
37
38// Default Adapter configuration
39#include "c_adapter_pcl.h"
40
41// DMABuf API
42#include "api_dmabuf.h" // DMABuf_*
43
44// Adapter DMABuf internal API
45#include "adapter_dmabuf.h"
46
47// Convert address to pair of 32-bit words.
48#include "adapter_addrpair.h"
49
50// Buffer allocation (non-DMA) API
51#include "adapter_alloc.h"
52
53// Adapter PCL Internal API
54#include "adapter_pcl.h"
55
56// Adapter Locking internal API
57#include "adapter_lock.h" // Adapter_Lock_*
58
59// EIP-207 Driver Library Flow Control Generic API
60#include "eip207_flow_generic.h"
61
62// EIP-207 Driver Library Flow Control DTL API
63#include "eip207_flow_dtl.h"
64
65// Driver Framework Device API
66#include "device_types.h" // Device_Handle_t
67#include "device_mgmt.h" // Device_find
68
69// Driver Framework DMAResource API
70#include "dmares_types.h" // DMAResource_Handle_t
71#include "dmares_mgmt.h" // DMAResource management functions
72#include "dmares_rw.h" // DMAResource buffer access.
73#include "dmares_addr.h" // DMAResource addr translation functions.
74#include "dmares_buf.h" // DMAResource buffer allocations
75
76// List API
77#include "list.h" // List_*
78
79// Runtime Power Management Device Macros API
80#include "rpm_device_macros.h" // RPM_*
81
82// Logging API
83#include "log.h"
84
85// Driver Framework C Run-Time Library API
86#include "clib.h" // memcpy, memset
87
88// Driver Framework Basic Definitions API
89#include "basic_defs.h" // bool, uint32_t
90
91
92/*----------------------------------------------------------------------------
93 * Definitions and macros
94 */
95
96// this implementation requires DMA resource banks
97#ifndef ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
98#error "Adapter DTL: ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE not defined"
99#endif
100
101// Bit to indicate whether transformr record is large.
102#define ADAPTER_PCL_TR_ISLARGE BIT_4
103
104
105/*----------------------------------------------------------------------------
106 * Global constants
107 */
108
109
110/*----------------------------------------------------------------------------
111 * PCL_DTL_NULLHandle
112 *
113 */
114const PCL_DTL_Hash_Handle_t PCL_DTL_NULLHandle = { NULL };
115
116
117/*----------------------------------------------------------------------------
118 * Local variables
119 */
120
121
122/*----------------------------------------------------------------------------
123 * Local prototypes
124 */
125
126
127/*-----------------------------------------------------------------------------
128 * PCL API functions implementation
129 *
130 */
131
132/*-----------------------------------------------------------------------------
133 * PCL_Flow_Remove
134 */
135PCL_Status_t
136PCL_Flow_Remove(
137 const unsigned int InterfaceId,
138 const unsigned int FlowHashTableId,
139 const PCL_FlowHandle_t FlowHandle)
140{
141 PCL_Status_t PCL_Rc = PCL_STATUS_OK;
142 EIP207_Flow_Error_t EIP207_Rc;
143 EIP207_Flow_IOArea_t * ioarea_p;
144 List_Element_t * Element_p = (List_Element_t*)FlowHandle;
145 EIP207_Flow_FR_Dscr_t * FlowDescriptor_p;
146 AdapterPCL_Device_Instance_Data_t * Dev_p;
147
148 LOG_INFO("\n\t PCL_Flow_Remove \n");
149
150 // validate input parameters
151 if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
152 FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE ||
153 Element_p == NULL)
154 {
155 return PCL_INVALID_PARAMETER;
156 }
157
158 FlowDescriptor_p = (EIP207_Flow_FR_Dscr_t *)Element_p->DataObject_p;
159
160 if (FlowDescriptor_p == NULL)
161 {
162 LOG_CRIT("PCL_Flow_Remove: failed, invalid flow handle\n");
163 return PCL_INVALID_PARAMETER;
164 }
165
166 // get interface ioarea
167 Dev_p = AdapterPCL_Device_Get(InterfaceId);
168 ioarea_p = Dev_p->EIP207_IOArea_p;
169
170 if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
171 {
172 LOG_CRIT("PCL_Flow_Add: no device lock, not initialized?\n");
173 return PCL_ERROR;
174 }
175
176 if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
177 return PCL_STATUS_BUSY;
178
179 if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID,
180 RPM_FLAG_SYNC) != RPM_SUCCESS)
181 {
182 Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
183 return PCL_ERROR;
184 }
185
186 LOG_INFO("\n\t\t EIP207_Flow_DTL_FR_Remove \n");
187
188 EIP207_Rc = EIP207_Flow_DTL_FR_Remove(ioarea_p,
189 FlowHashTableId,
190 FlowDescriptor_p);
191 if (EIP207_Rc != EIP207_FLOW_NO_ERROR)
192 {
193 LOG_CRIT("PCL_Flow_Remove: failed to remove FR, err=%d\n", EIP207_Rc);
194 PCL_Rc = PCL_ERROR;
195 }
196
197 (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID,
198 RPM_FLAG_ASYNC);
199
200 Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
201
202 return PCL_Rc;
203}
204
205
206/*-----------------------------------------------------------------------------
207 * PCL_Transform_Register
208 */
209PCL_Status_t
210PCL_Transform_Register(
211 const DMABuf_Handle_t TransformHandle)
212{
213 unsigned int TR_WordCount;
214 DMAResource_Handle_t DMAHandle =
215 Adapter_DMABuf_Handle2DMAResourceHandle(TransformHandle);
216 DMAResource_Record_t * const Rec_p =
217 DMAResource_Handle2RecordPtr(DMAHandle);
218
219 LOG_INFO("\n\t PCL_Transform_Register \n");
220
221 // validate parameter
222 if (Rec_p == NULL)
223 return PCL_INVALID_PARAMETER;
224
225 {
226#ifndef ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
227 uint32_t *TR_p = (uint32_t*)Adapter_DMAResource_HostAddr(DMAHandle);
228
229 Rec_p->fIsLargeTransform = false;
230
231 // Check whether the transform record is large.
232 // Register that in the DMA resource record.
233 if ((*TR_p & ADAPTER_PCL_TR_ISLARGE) != 0)
234 {
235 Rec_p->fIsLargeTransform = true;
236
237 TR_WordCount = EIP207_Flow_DTL_TR_Large_WordCount_Get();
238 *TR_p = *TR_p & ~ADAPTER_PCL_TR_ISLARGE;
239 // Clear that bit in the transform record.
240 }
241 else
242#endif // !ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
243 {
244 TR_WordCount = EIP207_Flow_TR_WordCount_Get();
245 }
246 }
247
248#ifdef ADAPTER_PEC_ARMRING_ENABLE_SWAP
249 DMAResource_SwapEndianness_Set(DMAHandle, true);
250#endif
251
252#ifdef ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
253 if (Rec_p->Props.Bank != ADAPTER_PCL_BANK_TRANSFORM)
254 {
255 LOG_CRIT("PCL Adapter: Invalid bank for Transform\n");
256 return PCL_ERROR;
257 }
258#endif
259
260 if (Rec_p->Props.Size < (sizeof(uint32_t) * TR_WordCount))
261 {
262 LOG_CRIT("PCL_Transform_Register: supplied buffer too small\n");
263 return PCL_ERROR;
264 }
265
266 DMAResource_Write32Array(
267 DMAHandle,
268 0,
269 TR_WordCount,
270 Adapter_DMAResource_HostAddr(DMAHandle));
271
272 DMAResource_PreDMA(DMAHandle, 0, sizeof(uint32_t) * TR_WordCount);
273
274 return PCL_STATUS_OK;
275}
276
277
278/*-----------------------------------------------------------------------------
279 * PCL_Transform_UnRegister
280 */
281PCL_Status_t
282PCL_Transform_UnRegister(
283 const DMABuf_Handle_t TransformHandle)
284{
285 IDENTIFIER_NOT_USED(TransformHandle.p);
286
287 LOG_INFO("\n\t PCL_Transform_UnRegister \n");
288
289 // Kept for backwards-compatibility, nothing to do here
290
291 return PCL_STATUS_OK;
292}
293
294/*-----------------------------------------------------------------------------
295 * PCL_Transform_Get_ReadOnly
296 */
297PCL_Status_t
298PCL_Transform_Get_ReadOnly(
299 const DMABuf_Handle_t TransformHandle,
300 PCL_TransformParams_t * const TransformParams_p)
301{
302 EIP207_Flow_TR_Dscr_t TransformDescriptor;
303 EIP207_Flow_TR_OutputData_t TransformData;
304 EIP207_Flow_Error_t res;
305 EIP207_Flow_IOArea_t * ioarea_p;
306 AdapterPCL_Device_Instance_Data_t * Dev_p;
307 DMAResource_Record_t * Rec_p = NULL;
308
309 LOG_INFO("\n\t PCL_Transform_Get_ReadOnly \n");
310
311 if( AdapterPCL_DMABuf_To_TRDscr(
312 TransformHandle, &TransformDescriptor, &Rec_p) != PCL_STATUS_OK)
313 return PCL_ERROR;
314
315 // get interface ioarea
316 Dev_p = AdapterPCL_Device_Get(0);
317 ioarea_p = Dev_p->EIP207_IOArea_p;
318 if (ioarea_p == NULL)
319 {
320 LOG_CRIT("PCL_Transform_Get_ReadOnly: failed, not initialized\n");
321 return PCL_ERROR;
322 }
323
324 {
325#ifndef ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
326 if (Rec_p->fIsLargeTransform)
327 {
328 res = EIP207_Flow_DTL_TR_Large_Read(
329 ioarea_p,
330 0,
331 &TransformDescriptor,
332 &TransformData);
333 }
334 else
335#else
336 IDENTIFIER_NOT_USED(Rec_p);
337#endif // !ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
338 {
339 res = EIP207_Flow_TR_Read(
340 ioarea_p,
341 0,
342 &TransformDescriptor,
343 &TransformData);
344 }
345 if (res != EIP207_FLOW_NO_ERROR)
346 {
347 LOG_CRIT("PCL_Transform_Get_ReadOnly: "
348 "Failed to remove transform record\n");
349 return PCL_ERROR;
350 }
351 }
352
353 TransformParams_p->SequenceNumber = TransformData.SequenceNumber;
354 TransformParams_p->PacketsCounterLo = TransformData.PacketsCounter;
355 TransformParams_p->PacketsCounterHi = 0;
356 TransformParams_p->OctetsCounterLo = TransformData.OctetsCounterLo;
357 TransformParams_p->OctetsCounterHi = TransformData.OctetsCounterHi;
358
359 return PCL_STATUS_OK;
360}
361
362
363/*-----------------------------------------------------------------------------
364 * PCL DTL API functions implementation
365 *
366 */
367
368
369/*-----------------------------------------------------------------------------
370 * PCL_DTL_Transform_Add
371 */
372PCL_Status_t
373PCL_DTL_Transform_Add(
374 const unsigned int InterfaceId,
375 const unsigned int FlowHashTableId,
376 const PCL_DTL_TransformParams_t * const TransformParams,
377 const DMABuf_Handle_t XformDMAHandle,
378 PCL_DTL_Hash_Handle_t * const HashHandle_p)
379{
380 PCL_Status_t PCL_Rc = PCL_ERROR;
381 PCL_Status_t PCL_Rc2;
382 EIP207_Flow_Error_t EIP207_Rc;
383 EIP207_Flow_IOArea_t * ioarea_p;
384 EIP207_Flow_TR_Dscr_t * TR_Dscr_p;
385 EIP207_Flow_TR_InputData_t TR_inputdata;
386 AdapterPCL_Device_Instance_Data_t * Dev_p;
387 void * HashList_p = NULL;
388 List_Status_t List_Rc;
389 DMAResource_Record_t * Rec_p = NULL;
390 List_Element_t * Element_p = NULL;
391
392 LOG_INFO("\n\t %s \n", __func__);
393
394 // Validate input parameters
395 if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
396 FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE)
397 return PCL_INVALID_PARAMETER;
398
399 // Get interface ioarea
400 Dev_p = AdapterPCL_Device_Get(InterfaceId);
401 ioarea_p = Dev_p->EIP207_IOArea_p;
402
403 if (Dev_p->List_p == NULL)
404 {
405 LOG_CRIT("%s: failed, not initialized\n", __func__);
406 return PCL_ERROR;
407 }
408
409 if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
410 {
411 LOG_CRIT("%s: failed, no device lock, not initialized?\n", __func__);
412 return PCL_ERROR;
413 }
414
415 if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
416 return PCL_STATUS_BUSY;
417
418 // Try to add new hash value to Flow Hash Table
419 {
420 unsigned int ListID;
421
422 PCL_Rc2 = AdapterPCL_ListID_Get(InterfaceId, &ListID);
423 if (PCL_Rc2 != PCL_STATUS_OK)
424 {
425 LOG_CRIT("%s: failed to get free list\n", __func__);
426 goto error_exit;
427 }
428
429 List_Rc = List_RemoveFromTail(ListID, NULL, &Element_p);
430 if (List_Rc != LIST_STATUS_OK)
431 {
432 LOG_CRIT(
433 "%s: failed to get free element from list\n", __func__);
434 goto error_exit;
435 }
436
437 // Note: Element_p and TR_Dscr_p must be valid by implementation!
438 TR_Dscr_p = (EIP207_Flow_TR_Dscr_t*)Element_p->DataObject_p;
439
440 // Set list element with the transform record descriptor data
441 PCL_Rc2 = AdapterPCL_DMABuf_To_TRDscr(XformDMAHandle, TR_Dscr_p, &Rec_p);
442 if (PCL_Rc2 != PCL_STATUS_OK)
443 {
444 LOG_CRIT("%s: failed, invalid transform\n", __func__);
445 PCL_Rc = PCL_INVALID_PARAMETER;
446 goto error_exit;
447 }
448
449 // Convert transform parameters into EIP-207 transform parameters
450 ZEROINIT(TR_inputdata);
451 TR_inputdata.HashID.Word32[0] = TransformParams->HashID[0];
452 TR_inputdata.HashID.Word32[1] = TransformParams->HashID[1];
453 TR_inputdata.HashID.Word32[2] = TransformParams->HashID[2];
454 TR_inputdata.HashID.Word32[3] = TransformParams->HashID[3];
455
456#ifndef ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
457 TR_inputdata.fLarge = Rec_p->fIsLargeTransform;
458#else
459 TR_inputdata.fLarge = false;
460#endif
461
462 LOG_INFO("\n\t\t EIP207_Flow_DTL_TR_Add \n");
463
464 // Add new hash value for this transform record to Flow Hash Table
465 EIP207_Rc = EIP207_Flow_DTL_TR_Add(ioarea_p,
466 FlowHashTableId,
467 TR_Dscr_p,
468 &TR_inputdata);
469 if (EIP207_Rc == EIP207_FLOW_OUT_OF_MEMORY_ERROR)
470 {
471 LOG_CRIT("%s: failed to install transform, "
472 "out of memory\n", __func__);
473 PCL_Rc = PCL_OUT_OF_MEMORY_ERROR;
474 }
475 else if (EIP207_Rc == EIP207_FLOW_NO_ERROR)
476 {
477 PCL_Rc = PCL_STATUS_OK;
478 }
479 else
480 {
481 LOG_CRIT("%s: failed to install transform, "
482 "EIP207_Flow_DTL_TR_Add() error %d\n",
483 __func__,
484 EIP207_Rc);
485 }
486
487 if (PCL_Rc != PCL_STATUS_OK)
488 {
489 LOG_CRIT("%s: failed to add hash value for transform record\n",
490 __func__);
491
492 // Return not added element to free list
493 List_Rc = List_AddToHead(ListID, NULL, Element_p);
494 if (List_Rc != LIST_STATUS_OK)
495 {
496 LOG_CRIT("%s: failed to update free list\n", __func__);
497 }
498
499 PCL_Rc = PCL_INVALID_PARAMETER;
500 goto error_exit;
501 }
502 } // Done adding new hash value to Flow Hash Table
503
504 if (Rec_p->Context_p)
505 {
506 // Get list element
507 List_Element_t * TmpElement_p = Rec_p->Context_p;
508
509 // Get hash list that contains all transform record descriptors
510 HashList_p = TmpElement_p->DataObject_p;
511 }
512
513 if(HashList_p == NULL)
514 {
515 // Create hash list for transform record
516
517 List_Element_t * TmpElement_p = NULL;
518
519 // Get a free list from pool of lists
520 List_Rc = List_RemoveFromTail(LIST_DUMMY_LIST_ID,
521 Dev_p->List_p,
522 &TmpElement_p);
523 if (List_Rc != LIST_STATUS_OK)
524 {
525 LOG_CRIT("%s: failed to get free element from pool list\n",
526 __func__);
527 goto error_exit;
528 }
529
530 // Note: TmpElement_p must be valid by implementation!
531 HashList_p = TmpElement_p->DataObject_p;
532
533 // Initialize list instance
534 if (List_Init(LIST_DUMMY_LIST_ID, HashList_p) != LIST_STATUS_OK)
535 {
536 LOG_CRIT("%s: list initialization failed\n", __func__);
537 goto error_exit;
538 }
539
540 // Store list element in the transform record descriptor
541 Rec_p->Context_p = TmpElement_p;
542 } // Created hash list for transform record
543
544 // Add new hash value to list of hash values for this transform record
545 List_Rc = List_AddToHead(LIST_DUMMY_LIST_ID, HashList_p, Element_p);
546 if (List_Rc != LIST_STATUS_OK)
547 {
548 LOG_CRIT("%s: failed to update hash list for transform record\n",
549 __func__);
550 }
551
552 HashHandle_p->p = Element_p;
553
554error_exit:
555
556 Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
557 return PCL_Rc;
558}
559
560
561/*-----------------------------------------------------------------------------
562 * PCL_DTL_Transform_Remove
563 */
564PCL_Status_t
565PCL_DTL_Transform_Remove(
566 const unsigned int InterfaceId,
567 const unsigned int FlowHashTableId,
568 const DMABuf_Handle_t XformDMAHandle)
569{
570 PCL_Status_t PCL_Rc = PCL_ERROR;
571 PCL_Status_t PCL_Rc2;
572 AdapterPCL_Device_Instance_Data_t * Dev_p;
573 EIP207_Flow_Error_t EIP207_Rc;
574 EIP207_Flow_IOArea_t * ioarea_p;
575 EIP207_Flow_TR_Dscr_t * TR_Dscr_p;
576 List_Status_t List_Rc;
577 List_Element_t * Element_p;
578 List_Element_t * ListElement_p;
579 unsigned int ListID;
580 void * HashList_p;
581
582 DMAResource_Handle_t DMAHandle =
583 Adapter_DMABuf_Handle2DMAResourceHandle(XformDMAHandle);
584
585 DMAResource_Record_t * Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
586
587 LOG_INFO("\n\t %s \n", __func__);
588
589 // Validate input parameters
590 if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
591 FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE ||
592 Rec_p == NULL)
593 return PCL_INVALID_PARAMETER;
594
595 // Get interface ioarea
596 Dev_p = AdapterPCL_Device_Get(InterfaceId);
597 ioarea_p = Dev_p->EIP207_IOArea_p;
598
599 if (Dev_p->List_p == NULL)
600 {
601 LOG_CRIT("%s: failed, not initialized\n", __func__);
602 return PCL_ERROR;
603 }
604
605 if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
606 {
607 LOG_CRIT("%s: no device lock, not initialized?\n", __func__);
608 return PCL_ERROR;
609 }
610
611 if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
612 return PCL_STATUS_BUSY;
613
614 PCL_Rc2 = AdapterPCL_ListID_Get(InterfaceId, &ListID);
615 if (PCL_Rc2 != PCL_STATUS_OK)
616 {
617 LOG_CRIT("%s: failed to get free list\n", __func__);
618 goto error_exit;
619 }
620
621 // Get list element
622 ListElement_p = Rec_p->Context_p;
623 if (ListElement_p == NULL || ListElement_p->DataObject_p == NULL)
624 {
625 PCL_Rc = PCL_INVALID_PARAMETER;
626 goto error_exit;
627 }
628
629 // Get hash list that contains all transform record descriptors
630 // for this transform
631 HashList_p = ListElement_p->DataObject_p;
632
633 while (HashList_p)
634 {
635 // Get the element from hash list that references record descriptor
636 List_Rc = List_RemoveFromTail(LIST_DUMMY_LIST_ID,
637 HashList_p,
638 &Element_p);
639 if (List_Rc != LIST_STATUS_OK || Element_p == NULL)
640 {
641 LOG_CRIT(
642 "%s: failed to get element from hash list\n", __func__);
643 goto error_exit;
644 }
645
646 // Retrieve transform record descriptor
647 TR_Dscr_p = Element_p->DataObject_p;
648 if (TR_Dscr_p == NULL)
649 {
650 LOG_CRIT("%s: failed, invalid transform handle\n", __func__);
651 PCL_Rc = PCL_INVALID_PARAMETER;
652 goto error_exit;
653 }
654
655 if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
656 RPM_FLAG_SYNC) != RPM_SUCCESS)
657 {
658 PCL_Rc = PCL_ERROR;
659 goto error_exit;
660 }
661
662 LOG_INFO("\n\t\t EIP207_Flow_DTL_TR_Remove \n");
663
664 EIP207_Rc = EIP207_Flow_DTL_TR_Remove(ioarea_p,
665 FlowHashTableId,
666 TR_Dscr_p);
667
668 (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
669 RPM_FLAG_ASYNC);
670
671 if (EIP207_Rc != EIP207_FLOW_NO_ERROR)
672 {
673 LOG_CRIT("%s: failed to remove TR, "
674 "EIP207_Flow_DTL_TR_Remove() error %d\n",
675 __func__,
676 EIP207_Rc);
677 // Return element to hash list
678 List_AddToHead(LIST_DUMMY_LIST_ID, HashList_p, Element_p);
679 goto error_exit;
680 }
681
682 {
683 unsigned int Count;
684
685 // Return the element to the free list
686 List_Rc = List_AddToHead(ListID, NULL, Element_p);
687 if (List_Rc != LIST_STATUS_OK)
688 {
689 LOG_CRIT(
690 "%s: failed to get free element from list\n", __func__);
691 goto error_exit;
692 }
693
694 // Check if transform record has any hash values still referencing it
695 List_GetListElementCount(LIST_DUMMY_LIST_ID, HashList_p, &Count);
696 if (Count == 0)
697 {
698 // Return the element to the free list
699 List_Rc = List_AddToHead(LIST_DUMMY_LIST_ID,
700 Dev_p->List_p,
701 ListElement_p);
702 if (List_Rc != LIST_STATUS_OK)
703 {
704 LOG_CRIT("%s: failed to return element to pool list\n",
705 __func__);
706 goto error_exit;
707 }
708
709 Rec_p->Context_p = HashList_p = NULL;
710 }
711 }
712 } // while
713
714 PCL_Rc = PCL_STATUS_OK;
715
716error_exit:
717 Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
718 return PCL_Rc;
719}
720
721
722/*-----------------------------------------------------------------------------
723 * PCL_DTL_Hash_Remove
724 */
725PCL_Status_t
726PCL_DTL_Hash_Remove(
727 const unsigned int InterfaceId,
728 const unsigned int FlowHashTableId,
729 PCL_DTL_Hash_Handle_t * const HashHandle_p)
730{
731 PCL_Status_t PCL_Rc = PCL_ERROR;
732 PCL_Status_t PCL_Rc2;
733 EIP207_Flow_Error_t EIP207_Rc;
734 EIP207_Flow_IOArea_t * ioarea_p;
735 EIP207_Flow_TR_Dscr_t * TR_Dscr_p;
736 List_Element_t * Element_p;
737 AdapterPCL_Device_Instance_Data_t * Dev_p;
738 DMAResource_Record_t * Rec_p;
739
740 LOG_INFO("\n\t %s \n", __func__);
741
742 // Validate input parameters
743 if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
744 FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE)
745 return PCL_INVALID_PARAMETER;
746
747 // Get interface ioarea
748 Dev_p = AdapterPCL_Device_Get(InterfaceId);
749 ioarea_p = Dev_p->EIP207_IOArea_p;
750
751 if (Dev_p->List_p == NULL)
752 {
753 LOG_CRIT("%s: failed, not initialized\n", __func__);
754 return PCL_ERROR;
755 }
756
757 if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
758 {
759 LOG_CRIT("%s: no device lock, not initialized?\n", __func__);
760 return PCL_ERROR;
761 }
762
763 if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
764 return PCL_STATUS_BUSY;
765
766 // Retrieve transform record descriptor
767 Element_p = HashHandle_p->p;
768 if (Element_p == NULL)
769 {
770 LOG_CRIT("%s: failed, invalid hash handle\n", __func__);
771 PCL_Rc = PCL_INVALID_PARAMETER;
772 goto error_exit;
773 }
774
775 TR_Dscr_p = Element_p->DataObject_p;
776 if (TR_Dscr_p == NULL)
777 {
778 LOG_CRIT("%s: failed, invalid hash handle for transform descriptor\n",
779 __func__);
780 PCL_Rc = PCL_INVALID_PARAMETER;
781 goto error_exit;
782 }
783
784 Rec_p = DMAResource_Handle2RecordPtr(TR_Dscr_p->DMA_Handle);
785 if (Rec_p == NULL || Rec_p->Context_p == NULL)
786 {
787 LOG_CRIT("%s: failed, invalid hash handle for DMA resource\n",
788 __func__);
789 PCL_Rc = PCL_INVALID_PARAMETER;
790 goto error_exit;
791 }
792
793 if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
794 RPM_FLAG_SYNC) != RPM_SUCCESS)
795 {
796 PCL_Rc = PCL_ERROR;
797 goto error_exit;
798 }
799
800 LOG_INFO("\n\t\t EIP207_Flow_DTL_TR_Remove \n");
801
802 EIP207_Rc = EIP207_Flow_DTL_TR_Remove(ioarea_p, FlowHashTableId, TR_Dscr_p);
803
804 (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
805 RPM_FLAG_ASYNC);
806
807 if (EIP207_Rc != EIP207_FLOW_NO_ERROR)
808 {
809 LOG_CRIT("%s: failed to remove TR, "
810 "EIP207_Flow_DTL_TR_Remove() error %d\n",
811 __func__,
812 EIP207_Rc);
813 goto error_exit;
814 }
815
816 {
817 unsigned int ListID, Count;
818 List_Status_t List_Rc;
819 List_Element_t * ListElement_p = Rec_p->Context_p;
820 void * HashList_p = ListElement_p->DataObject_p;
821
822 // Remove the hash value from the transform record list
823 List_Rc = List_RemoveAnywhere(LIST_DUMMY_LIST_ID,
824 HashList_p,
825 Element_p);
826 if (List_Rc != LIST_STATUS_OK)
827 {
828 LOG_CRIT("%s: failed to remove hash from record list\n", __func__);
829 }
830
831 PCL_Rc2 = AdapterPCL_ListID_Get(InterfaceId, &ListID);
832 if (PCL_Rc2 != PCL_STATUS_OK)
833 {
834 LOG_CRIT("%s: failed to get free list\n", __func__);
835 goto error_exit;
836 }
837
838 // Return the element to the free list
839 List_Rc = List_AddToHead(ListID, NULL, Element_p);
840 if (List_Rc != LIST_STATUS_OK)
841 {
842 LOG_CRIT(
843 "%s: failed to get free element from list\n", __func__);
844 goto error_exit;
845 }
846
847 // Check if transform record has any hash values still referencing it
848 List_GetListElementCount(LIST_DUMMY_LIST_ID, HashList_p, &Count);
849 if (Count == 0)
850 {
851 // Return the element to the free list
852 List_Rc = List_AddToHead(LIST_DUMMY_LIST_ID,
853 Dev_p->List_p,
854 ListElement_p);
855 if (List_Rc != LIST_STATUS_OK)
856 {
857 LOG_CRIT("%s: failed to return element to pool list\n",
858 __func__);
859 goto error_exit;
860 }
861
862 Rec_p->Context_p = NULL;
863 }
864 }
865
866 // Invalidate hash handle
867 HashHandle_p->p = NULL;
868
869 PCL_Rc = PCL_STATUS_OK;
870
871error_exit:
872 Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
873 return PCL_Rc;
874}
875
876
877/*-----------------------------------------------------------------------------
878 * PCL_DTL_Init
879 */
880PCL_Status_t
881PCL_DTL_Init(
882 const unsigned int InterfaceId)
883{
884 PCL_Status_t PCL_Rc = PCL_ERROR;
885 AdapterPCL_Device_Instance_Data_t * Dev_p;
886
887 LOG_INFO("\n\t %s \n", __func__);
888
889 // Validate input parameters.
890 if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES)
891 return PCL_INVALID_PARAMETER;
892
893 // Get interface ioarea
894 Dev_p = AdapterPCL_Device_Get(InterfaceId);
895
896 if (Dev_p->List_p != NULL)
897 {
898 LOG_CRIT("%s: failed, already initialized\n", __func__);
899 return PCL_ERROR;
900 }
901
902 if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
903 {
904 LOG_CRIT("%s: failed, no device lock, not initialized?\n", __func__);
905 return PCL_ERROR;
906 }
907
908 if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
909 return PCL_STATUS_BUSY;
910
911 // Create pool of lists for record descriptors
912 {
913 unsigned int i;
914 void * List_p;
915 List_Element_t * ListElementPool_p;
916 List_Element_t * Element_p;
917 unsigned char * ListPool_p;
918 unsigned int ListInstanceByteCount = List_GetInstanceByteCount();
919
920 // Allocate PCL DTL list instance that will chain other lists
921 List_p = Adapter_Alloc(ListInstanceByteCount);
922 if (List_p == NULL)
923 {
924 LOG_CRIT("%s: list pool allocation failed\n", __func__);
925 goto error_exit;
926 }
927 memset(List_p, 0, ListInstanceByteCount);
928
929 // Initialize PCL DTL list instance
930 if (List_Init(LIST_DUMMY_LIST_ID,
931 List_p) != LIST_STATUS_OK)
932 {
933 LOG_CRIT("%s: list pool initialization failed\n", __func__);
934 goto error_exit;
935 }
936
937 // Allocate a pool of list elements
938 ListElementPool_p = Adapter_Alloc(sizeof(List_Element_t) *
939 ADAPTER_PCL_FLOW_RECORD_COUNT);
940 if (ListElementPool_p == NULL)
941 {
942 LOG_CRIT("%s: pool elements allocation failed\n", __func__);
943 Adapter_Free(List_p);
944 goto error_exit;
945 }
946
947 // Allocate a pool of lists,
948 // one list for one transform record
949 ListPool_p = Adapter_Alloc(ListInstanceByteCount *
950 ADAPTER_PCL_FLOW_RECORD_COUNT);
951 if (ListPool_p == NULL)
952 {
953 LOG_CRIT("%s: pool lists allocation failed\n", __func__);
954 Adapter_Free(List_p);
955 Adapter_Free(ListElementPool_p);
956 goto error_exit;
957 }
958 memset(ListPool_p,
959 0,
960 ListInstanceByteCount * ADAPTER_PCL_FLOW_RECORD_COUNT);
961 Dev_p->ListPool_p = ListPool_p;
962
963 // Populate the pool list with the elements (lists)
964 Element_p = ListElementPool_p;
965 Element_p->DataObject_p = ListPool_p;
966 for (i = 0; i < ADAPTER_PCL_FLOW_RECORD_COUNT; i++)
967 {
968 if (List_AddToHead(LIST_DUMMY_LIST_ID,
969 List_p,
970 Element_p) == LIST_STATUS_OK)
971 {
972 if (i + 1 < ADAPTER_PCL_FLOW_RECORD_COUNT)
973 {
974 Element_p++;
975 ListPool_p += ListInstanceByteCount;
976 Element_p->DataObject_p = ListPool_p;
977 }
978 }
979 else
980 {
981 LOG_CRIT("%s: pool list population failed\n", __func__);
982 Dev_p->ListPool_p = NULL;
983 Adapter_Free(List_p);
984 Adapter_Free(ListElementPool_p);
985 Adapter_Free(ListPool_p);
986 goto error_exit;
987 }
988 } // for
989
990 Dev_p->List_p = List_p;
991 Dev_p->ListElementPool_p = ListElementPool_p;
992
993 PCL_Rc = PCL_STATUS_OK;
994 } // Created pool of lists for record descriptors
995
996error_exit:
997
998 Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
999 return PCL_Rc;
1000}
1001
1002
1003/*-----------------------------------------------------------------------------
1004 * PCL_DTL_UnInit
1005 */
1006PCL_Status_t
1007PCL_DTL_UnInit(
1008 const unsigned int InterfaceId)
1009{
1010 AdapterPCL_Device_Instance_Data_t * Dev_p;
1011
1012 LOG_INFO("\n\t %s \n", __func__);
1013
1014 // Validate input parameters.
1015 if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES)
1016 return PCL_INVALID_PARAMETER;
1017
1018 // Get interface ioarea
1019 Dev_p = AdapterPCL_Device_Get(InterfaceId);
1020 if (Dev_p->List_p == NULL)
1021 {
1022 LOG_CRIT("%s: failed, not initialized\n", __func__);
1023 return PCL_ERROR;
1024 }
1025
1026 if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
1027 {
1028 LOG_CRIT("%s: failed, no device lock, not initialized?\n", __func__);
1029 return PCL_ERROR;
1030 }
1031
1032 if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
1033 return PCL_STATUS_BUSY;
1034
1035 // pool list data structures
1036 Adapter_Free(Dev_p->ListElementPool_p);
1037 Adapter_Free(Dev_p->ListPool_p);
1038 List_Uninit(LIST_DUMMY_LIST_ID, Dev_p->List_p);
1039 Adapter_Free(Dev_p->List_p);
1040
1041 Dev_p->List_p = NULL;
1042 Dev_p->ListElementPool_p = NULL;
1043 Dev_p->ListPool_p = NULL;
1044
1045 Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
1046
1047 return PCL_STATUS_OK;
1048}
1049
1050
1051/* end of file adapter_pcl_dtl.c */