blob: 470378a27767c83e97419903fe11e07706424826 [file] [log] [blame]
developer02e65912023-08-17 16:33:10 +08001/* adapter_ring_eip202.c
2 *
3 * Adapter EIP-202 implementation: EIP-202 specific layer.
4 */
5
6/*****************************************************************************
7* Copyright (c) 2011-2022 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// SLAD Adapter PEC Device-specific API
28#include "adapter_pecdev_dma.h"
29
30// Ring Control configuration API
31#include "adapter_ring_eip202.h"
32
33#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
34 defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
35// Record Cache configuration API
36#include "adapter_rc_eip207.h"
37#endif
38
39
40/*----------------------------------------------------------------------------
41 * This module uses (requires) the following interface(s):
42 */
43
44// Default configuration
45#include "c_adapter_eip202.h"
46
47// Driver Framework Basic Definitions API
48#include "basic_defs.h" // bool
49#include "api_pec.h"
50#include "api_dmabuf.h"
51
52// Adapter DMABuf internal API
53#include "adapter_dmabuf.h"
54
55// Convert address to pair of 32-bit words.
56#include "adapter_addrpair.h"
57
58// Adapter interrupts API
59#include "adapter_interrupts.h" // Adapter_Interrupt_*
60
61// Adapter memory allocation API
62#include "adapter_alloc.h" // Adapter_Alloc/Free
63
64// Driver Framework DMAResource API
65#include "dmares_addr.h" // AddrTrans_*
66#include "dmares_buf.h" // DMAResource_Alloc/Release
67#include "dmares_rw.h" // DMAResource_PreDMA/PostDMA
68#include "dmares_mgmt.h" // DMAResource_Alloc/Release
69
70#include "device_types.h" // Device_Handle_t
71#include "device_mgmt.h" // Device_find
72#include "device_rw.h" // Device register read/write
73
74#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
75#include "api_pec_sg.h" // PEC_SG_* (the API we implement here)
76#endif
77
78// EIP97 Ring Control
79#include "eip202_ring_types.h"
80#include "eip202_cdr.h"
81#include "eip202_rdr.h"
82
83// Standard IOToken API
84#include "iotoken.h"
85
86
87#ifdef ADAPTER_EIP202_USE_SHDEVXS
88#include "shdevxs_prng.h"
89#else
90#include "eip97_global_init.h"
91#endif
92
93#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
94 defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
95#ifdef ADAPTER_EIP202_USE_SHDEVXS
96// EIP-207 Record Cache (RC) interface
97#include "shdevxs_dmapool.h"
98#include "shdevxs_rc.h"
99#else
100// EIP-207 Record Cache (RC) interface
101#include "eip207_rc.h" // EIP207_RC_*
102#endif // ADAPTER_EIP202_USE_SHDEVXS
103#endif
104
105#include "clib.h" // memcpy, ZEROINIT
106
107// Log API
108#include "log.h"
109
110
111/*----------------------------------------------------------------------------
112 * Definitions and macros
113 */
114
115#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
116 defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
117#ifndef ADAPTER_EIP202_USE_SHDEVXS
118// The default Record Cache set number to be used
119// Note: Only one cache set is supported by this implementation!
120#define EIP207_RC_SET_NR_DEFAULT 0
121#endif
122#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT || ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
123
124#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
125 defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
126#ifdef ADAPTER_EIP202_USE_SHDEVXS
127#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO SHDevXS_RC_Record_Dummy_Addr_Get()
128#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI 0
129#else
130#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO EIP207_RC_Record_Dummy_Addr_Get()
131#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI 0
132#endif // ADAPTER_EIP202_USE_SHDEVXS
133#else
134
135#ifdef ADAPTER_EIP202_USE_POINTER_TYPES
136#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO 0xfffffffc
137#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI 0xffffffff
138#else
139#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO 3
140#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI 0
141#endif
142
143#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT || ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
144
145// Move bit position src in value v to dst.
146#define BIT_MOVE(v, src, dst) ( ((src) < (dst)) ? \
147 ((v) << ((dst) - (src))) & (1 << (dst)) : \
148 ((v) >> ((src) - (dst))) & (1 << (dst)))
149
150#ifndef ADAPTER_EIP202_SEPARATE_RINGS
151#define ADAPTER_EIP202_CDR_BYTE_OFFSET \
152 (EIP202_RD_CTRL_DATA_MAX_WORD_COUNT * sizeof(uint32_t))
153#endif
154
155
156typedef struct
157{
158 unsigned int CDR_IRQ_ID;
159
160 unsigned int CDR_IRQ_Flags;
161
162 const char * CDR_DeviceName_p;
163
164 unsigned int RDR_IRQ_ID;
165
166 unsigned int RDR_IRQ_Flags;
167
168 const char * RDR_DeviceName_p;
169
170} Adapter_Ring_EIP202_Device_t;
171
172
173#ifdef ADAPTER_EIP202_USE_POINTER_TYPES
174#define ADAPTER_EIP202_TR_ADDRESS 2
175#ifndef ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
176#define ADAPTER_EIP202_TR_LARGE_ADDRESS 3
177// Bit in first word of SA record to indicate it is large.
178#define ADAPTER_EIP202_TR_ISLARGE BIT_4
179#endif
180#endif
181
182
183/*----------------------------------------------------------------------------
184 * Local variables
185 */
186
187static const Adapter_Ring_EIP202_Device_t EIP202_Devices [] =
188{
189 ADAPTER_EIP202_DEVICES
190};
191
192// number of devices supported calculated on ADAPTER_EIP202_DEVICES defined
193// in c_adapter_eip202.h
194#define ADAPTER_EIP202_DEVICE_COUNT_ACTUAL \
195 (sizeof(EIP202_Devices) / sizeof(Adapter_Ring_EIP202_Device_t))
196
197static EIP202_CDR_Settings_t CDR_Settings;
198static EIP202_RDR_Settings_t RDR_Settings;
199
200#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
201static unsigned int EIP202_Interrupts[ADAPTER_EIP202_DEVICE_COUNT];
202#endif
203
204static EIP202_Ring_IOArea_t CDR_IOArea[ADAPTER_EIP202_DEVICE_COUNT];
205static EIP202_Ring_IOArea_t RDR_IOArea[ADAPTER_EIP202_DEVICE_COUNT];
206
207static DMAResource_Handle_t CDR_Handle[ADAPTER_EIP202_DEVICE_COUNT];
208static DMAResource_Handle_t RDR_Handle[ADAPTER_EIP202_DEVICE_COUNT];
209
210static EIP202_ARM_CommandDescriptor_t
211 EIP202_CDR_Entries[ADAPTER_EIP202_DEVICE_COUNT][ADAPTER_EIP202_MAX_LOGICDESCR];
212
213static EIP202_ARM_PreparedDescriptor_t
214 EIP202_RDR_Prepared[ADAPTER_EIP202_DEVICE_COUNT][ADAPTER_EIP202_MAX_LOGICDESCR];
215
216static EIP202_ARM_ResultDescriptor_t
217 EIP202_RDR_Entries[ADAPTER_EIP202_DEVICE_COUNT][ADAPTER_EIP202_MAX_LOGICDESCR];
218
219static bool EIP202_ContinuousScatter[ADAPTER_EIP202_DEVICE_COUNT];
220
221static const PEC_Capabilities_t CapabilitiesString =
222{
223 "EIP-202 Packet Engine rings=__ (ARM," // szTextDescription
224#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
225 "SG,"
226#endif
227#ifndef ADAPTER_EIP202_REMOVE_BOUNCEBUFFERS
228 "BB,"
229#endif
230#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
231 "Int)",
232#else
233 "Poll)",
234#endif
235 0
236};
237
238// Static variables used by the adapter_ring_eip202.h interface implementation
239static bool Adapter_Ring_EIP202_Configured;
240static uint8_t Adapter_Ring_EIP202_HDW;
241static uint8_t Adapter_Ring_EIP202_CFSize;
242static uint8_t Adapter_Ring_EIP202_RFSize;
243
244#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
245#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
246static uint32_t EIP202_SABaseAddr;
247static uint32_t EIP202_SABaseUpperAddr;
248#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
249#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
250
251#ifdef ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
252// Static variables used by the adapter_rc_eip207.h interface implementation
253static bool Adapter_RC_EIP207_Configured = true;
254static bool Adapter_RC_EIP207_TRC_Enabled = true;
255static bool Adapter_RC_EIP207_ARC4RC_Enabled;
256static bool Adapter_RC_EIP207_Combined;
257#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
258
259// DMA buffer allocation alignment in bytes
260static int Adapter_Ring_EIP202_DMA_Alignment_ByteCount =
261 ADAPTER_DMABUF_ALIGNMENT_INVALID;
262
263
264#ifdef ADAPTER_EIP202_ADD_INIT_DIAGNOSTICS
265static void
266Adapter_Register_Dump(void)
267{
268 Device_Handle_t Device=Device_Find("EIP197_GLOBAL");
269 unsigned int i,j,v[256];
270 LOG_CRIT("REGISTER DUMP\n");
271 for (i=0; i<0x100000; i+=1024)
272 {
273 Device_Read32Array(Device, i, v, 256);
274 for (j=0; j<256; j++)
275 {
276 if (v[j])
277 {
278 LOG_CRIT("Addr 0x%08x = 0x%08x\n",i+j*4,v[j]);
279 }
280 }
281 }
282 LOG_CRIT("END REGISTER DUMP\n");
283}
284#endif
285
286/*----------------------------------------------------------------------------
287 * AdapterLib_RD_OutTokens_Free
288 *
289 * Free Output Tokens in the EIP-202 result descriptors.
290 */
291static void
292AdapterLib_RD_OutTokens_Free(
293 const unsigned int InterfaceId)
294{
295 unsigned int i;
296
297 for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
298 Adapter_Free(EIP202_RDR_Entries[InterfaceId][i].Token_p);
299}
300
301
302/*----------------------------------------------------------------------------
303 * AdapterLib_RD_OutTokens_Alloc
304 *
305 * Allocate Output Tokens in the EIP-202 result descriptors.
306 */
307static bool
308AdapterLib_RD_OutTokens_Alloc(
309 const unsigned int InterfaceId)
310{
311 unsigned int i;
312
313 for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
314 {
315 uint32_t * p =
316 Adapter_Alloc(IOToken_OutWordCount_Get() * sizeof (uint32_t));
317
318 if (p)
319 EIP202_RDR_Entries[InterfaceId][i].Token_p = p;
320 else
321 goto exit_error;
322 }
323
324 return true;
325
326exit_error:
327 AdapterLib_RD_OutTokens_Free(InterfaceId);
328
329 return false;
330}
331
332
333/*----------------------------------------------------------------------------
334 * Adapter_GetPhysAddr
335 *
336 * Obtain the physical address from a DMABuf handle.
337 * Take the bounce handle into account.
338 *
339 */
340static void
341Adapter_GetPhysAddr(
342 const DMABuf_Handle_t Handle,
343 EIP202_DeviceAddress_t *PhysAddr_p)
344{
345 DMAResource_Handle_t DMAHandle =
346 Adapter_DMABuf_Handle2DMAResourceHandle(Handle);
347 DMAResource_Record_t * Rec_p = NULL;
348 DMAResource_AddrPair_t PhysAddr_Pair;
349
350 if (PhysAddr_p == NULL)
351 {
352 LOG_CRIT("Adapter_GetPhysAddr: PANIC\n");
353 return;
354 }
355
356 PhysAddr_p->Addr = ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO;
357 PhysAddr_p->UpperAddr = ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI;
358
359 // Note: this function is sometimes invoked with invalid DMA handle
360 // to obtain a dummy address, not an error.
361 if (!DMAResource_IsValidHandle(DMAHandle))
362 return; // success!
363
364 Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
365
366 if (Rec_p == NULL)
367 {
368 LOG_CRIT("Adapter_GetPhysAddr: failed\n");
369 return;
370 }
371
372#ifndef ADAPTER_EIP202_REMOVE_BOUNCEBUFFERS
373 if (Rec_p->bounce.Bounce_Handle != NULL)
374 DMAHandle = Rec_p->bounce.Bounce_Handle;
375#endif
376
377 if (DMAResource_Translate(DMAHandle, DMARES_DOMAIN_BUS,
378 &PhysAddr_Pair) == 0)
379 {
380 Adapter_AddrToWordPair(PhysAddr_Pair.Address_p, 0, &PhysAddr_p->Addr,
381 &PhysAddr_p->UpperAddr);
382 // success!
383 }
384 else
385 {
386 LOG_CRIT("Adapter_GetPhysAddr: failed\n");
387 }
388}
389
390
391/*----------------------------------------------------------------------------
392 * BoolToString()
393 *
394 * Convert boolean value to string.
395 */
396static const char *
397BoolToString(
398 bool b)
399{
400 if (b)
401 return "TRUE";
402 else
403 return "false";
404}
405
406
407/*----------------------------------------------------------------------------
408 * AdapterLib_Ring_EIP202_CDR_Status_Report
409 *
410 * Report the status of the CDR interface
411 *
412 */
413static void
414AdapterLib_Ring_EIP202_CDR_Status_Report(
415 unsigned int InterfaceId)
416{
417 EIP202_Ring_Error_t res;
418 EIP202_CDR_Status_t CDR_Status;
419
420 LOG_CRIT("Status of CDR interface %d\n",InterfaceId);
421
422 LOG_INFO("\n\t\t\t EIP202_CDR_Status_Get \n");
423
424 ZEROINIT(CDR_Status);
425 res = EIP202_CDR_Status_Get(CDR_IOArea + InterfaceId, &CDR_Status);
426 if (res != EIP202_RING_NO_ERROR)
427 {
428 LOG_CRIT("EIP202_CDR_Status_Get returned error\n");
429 return;
430 }
431
432 // Report CDR status
433 LOG_CRIT("CDR Status: CD prep/proc count %d/%d, proc pkt count %d\n",
434 CDR_Status.CDPrepWordCount,
435 CDR_Status.CDProcWordCount,
436 CDR_Status.CDProcPktWordCount);
437
438 if (CDR_Status.fDMAError ||
439 CDR_Status.fError ||
440 CDR_Status.fOUFlowError ||
441 CDR_Status.fTresholdInt ||
442 CDR_Status.fTimeoutInt)
443 {
444 // Report CDR errors
445 LOG_CRIT("CDR Status: error(s) detected\n");
446 LOG_CRIT("\tDMA err: %s\n"
447 "\tErr: %s\n"
448 "\tOvf/under err: %s\n"
449 "\tThreshold int: %s\n"
450 "\tTimeout int: %s\n"
451 "\tFIFO count: %d\n",
452 BoolToString(CDR_Status.fDMAError),
453 BoolToString(CDR_Status.fError),
454 BoolToString(CDR_Status.fOUFlowError),
455 BoolToString(CDR_Status.fTresholdInt),
456 BoolToString(CDR_Status.fTimeoutInt),
457 CDR_Status.CDFIFOWordCount);
458 }
459 else
460 LOG_CRIT("CDR Status: all OK, FIFO count: %d\n",
461 CDR_Status.CDFIFOWordCount);
462}
463
464
465/*----------------------------------------------------------------------------
466 * AdapterLib_Ring_EIP202_RDR_Status_Report
467 *
468 * Report the status of the RDR interface
469 *
470 */
471static void
472AdapterLib_Ring_EIP202_RDR_Status_Report(
473 unsigned int InterfaceId)
474{
475 EIP202_Ring_Error_t res;
476 EIP202_RDR_Status_t RDR_Status;
477
478 LOG_CRIT("Status of RDR interface %d\n",InterfaceId);
479 if (EIP202_ContinuousScatter[InterfaceId])
480 LOG_CRIT("Ring is in continuous scatter mode\n");
481
482 LOG_INFO("\n\t\t\t EIP202_RDR_Status_Get \n");
483
484 ZEROINIT(RDR_Status);
485 res = EIP202_RDR_Status_Get(RDR_IOArea + InterfaceId, &RDR_Status);
486 if (res != EIP202_RING_NO_ERROR)
487 {
488 LOG_CRIT("EIP202_RDR_Status_Get returned error\n");
489 return;
490 }
491
492 // Report RDR status
493 LOG_CRIT("RDR Status: RD prep/proc count %d/%d, proc pkt count %d\n",
494 RDR_Status.RDPrepWordCount,
495 RDR_Status.RDProcWordCount,
496 RDR_Status.RDProcPktWordCount);
497
498 if (RDR_Status.fDMAError ||
499 RDR_Status.fError ||
500 RDR_Status.fOUFlowError ||
501 RDR_Status.fRDBufOverflowInt ||
502 RDR_Status.fRDOverflowInt ||
503 RDR_Status.fTresholdInt ||
504 RDR_Status.fTimeoutInt)
505 {
506 // Report RDR errors
507 LOG_CRIT("RDR Status: error(s) detected\n");
508 LOG_CRIT("\tDMA err: %s\n"
509 "\tErr: %s\n"
510 "\tOvf/under err: %s\n"
511 "\tBuf ovf: %s\n"
512 "\tDescriptor ovf: %s\n"
513 "\tThreshold int: %s\n"
514 "\tTimeout int: %s\n"
515 "\tFIFO count: %d\n",
516 BoolToString(RDR_Status.fDMAError),
517 BoolToString(RDR_Status.fError),
518 BoolToString(RDR_Status.fOUFlowError),
519 BoolToString(RDR_Status.fRDBufOverflowInt),
520 BoolToString(RDR_Status.fRDOverflowInt),
521 BoolToString(RDR_Status.fTresholdInt),
522 BoolToString(RDR_Status.fTimeoutInt),
523 RDR_Status.RDFIFOWordCount);
524 }
525 else
526 LOG_CRIT("RDR Status: all OK, FIFO count: %d\n",
527 RDR_Status.RDFIFOWordCount);
528}
529
530
531/*----------------------------------------------------------------------------
532 * AdapterLib_Ring_EIP202_Status_Report
533 *
534 * Report the status of the CDR and RDR interface
535 *
536 */
537static void
538AdapterLib_Ring_EIP202_Status_Report(
539 unsigned int InterfaceId)
540{
541 AdapterLib_Ring_EIP202_CDR_Status_Report(InterfaceId);
542
543 AdapterLib_Ring_EIP202_RDR_Status_Report(InterfaceId);
544}
545
546
547/*----------------------------------------------------------------------------
548 * AdapterLib_Ring_EIP202_AlignForSize
549 */
550static unsigned int
551AdapterLib_Ring_EIP202_AlignForSize(
552 const unsigned int ByteCount,
553 const unsigned int AlignTo)
554{
555 unsigned int AlignedByteCount = ByteCount;
556
557 // Check if alignment and padding for length alignment is required
558 if (AlignTo > 1 && ByteCount % AlignTo)
559 AlignedByteCount = ByteCount / AlignTo * AlignTo + AlignTo;
560
561 return AlignedByteCount;
562}
563
564
565/*----------------------------------------------------------------------------
566 * AdapterLib_Ring_EIP202_DMA_Alignment_Determine
567 *
568 * Determine the required EIP-202 DMA alignment value
569 *
570 */
571static bool
572AdapterLib_Ring_EIP202_DMA_Alignment_Determine(void)
573{
574#ifdef ADAPTER_EIP202_ALLOW_UNALIGNED_DMA
575 Adapter_DMAResource_Alignment_Set(1);
576#else
577 // Default alignment value is invalid
578 Adapter_Ring_EIP202_DMA_Alignment_ByteCount =
579 ADAPTER_DMABUF_ALIGNMENT_INVALID;
580
581 if (Adapter_Ring_EIP202_Configured)
582 {
583 int AlignTo = Adapter_Ring_EIP202_HDW;
584
585 // Determine the EIP-202 master interface hardware data width
586 switch (AlignTo)
587 {
588 case EIP202_RING_DMA_ALIGNMENT_4_BYTES:
589 Adapter_DMAResource_Alignment_Set(4);
590 break;
591 case EIP202_RING_DMA_ALIGNMENT_8_BYTES:
592 Adapter_DMAResource_Alignment_Set(8);
593 break;
594 case EIP202_RING_DMA_ALIGNMENT_16_BYTES:
595 Adapter_DMAResource_Alignment_Set(16);
596 break;
597 case EIP202_RING_DMA_ALIGNMENT_32_BYTES:
598 Adapter_DMAResource_Alignment_Set(32);
599 break;
600 default:
601 // Not supported, the alignment value cannot be determined
602 LOG_CRIT("AdapterLib_Ring_EIP202_DMA_Alignment_Determine: "
603 "EIP-202 master interface HW data width "
604 "(%d) is unsupported\n",
605 AlignTo);
606 return false; // Error
607 } // switch
608 }
609 else
610 {
611#if ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT == 0
612 // The alignment value cannot be determined
613 return false; // Error
614#else
615 // Set the configured non-zero alignment value
616 Adapter_DMAResource_Alignment_Set(
617 ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT);
618#endif
619 }
620#endif
621
622 Adapter_Ring_EIP202_DMA_Alignment_ByteCount =
623 Adapter_DMAResource_Alignment_Get();
624
625 return true; // Success
626}
627
628
629/*----------------------------------------------------------------------------
630 * AdapterLib_Ring_EIP202_DMA_Alignment_Get
631 *
632 * Get the required EIP-202 DMA alignment value
633 *
634 */
635inline static int
636AdapterLib_Ring_EIP202_DMA_Alignment_Get(void)
637{
638 return Adapter_Ring_EIP202_DMA_Alignment_ByteCount;
639}
640
641
642/*----------------------------------------------------------------------------
643 * AdapterLib_Ring_EIP202_DMAAddr_IsSane
644 *
645 * Validate the DMA address for the EIP-202 device
646 *
647 */
648inline static bool
649AdapterLib_Ring_EIP202_DMAAddr_IsSane(
650 const EIP202_DeviceAddress_t * const DevAddr_p,
651 const char * BufferName_p)
652{
653#ifndef ADAPTER_EIP202_64BIT_DEVICE
654 // Check if 64-bit DMA address is used for EIP-202 configuration
655 // that supports 32-bit addresses only
656 if (DevAddr_p->UpperAddr)
657 {
658 LOG_CRIT("%s: failed, "
659 "%s bus address (low/high 32 bits 0x%08x/0x%08x) too big\n",
660 __func__,
661 BufferName_p,
662 DevAddr_p->Addr,
663 DevAddr_p->UpperAddr);
664 return false;
665 }
666 else
667 return true;
668#else
669 IDENTIFIER_NOT_USED(DevAddr_p);
670 IDENTIFIER_NOT_USED(BufferName_p);
671 return true;
672#endif
673}
674
675
676/*----------------------------------------------------------------------------
677 * Implementation of the adapter_ring_eip202.h interface
678 *
679 */
680
681/*----------------------------------------------------------------------------
682 * Adapter_Ring_EIP202_Configure
683 */
684void
685Adapter_Ring_EIP202_Configure(
686 const uint8_t HostDataWidth,
687 const uint8_t CF_Size,
688 const uint8_t RF_Size)
689{
690 Adapter_Ring_EIP202_HDW = HostDataWidth;
691 Adapter_Ring_EIP202_CFSize = CF_Size;
692 Adapter_Ring_EIP202_RFSize = RF_Size;
693
694 Adapter_Ring_EIP202_Configured = true;
695}
696
697/*----------------------------------------------------------------------------
698 * Implementation of the adapter_rc_eip207.h interface
699 *
700 */
701
702#ifdef ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
703/*----------------------------------------------------------------------------
704 * Adapter_RC_EIP207_Configure
705 */
706void
707Adapter_RC_EIP207_Configure(
708 const bool fEnabledTRC,
709 const bool fEnabledARC4RC,
710 const bool fCombined)
711{
712 Adapter_RC_EIP207_Combined = fCombined;
713 Adapter_RC_EIP207_TRC_Enabled = fEnabledTRC;
714 Adapter_RC_EIP207_ARC4RC_Enabled = fEnabledARC4RC;
715
716 Adapter_RC_EIP207_Configured = true;
717
718}
719#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
720
721
722/*----------------------------------------------------------------------------
723 * Implementation of the adapter_pecdev_dma.h interface
724 *
725 */
726
727/*----------------------------------------------------------------------------
728 * Adapter_PECDev_Capabilities_Get
729 */
730PEC_Status_t
731Adapter_PECDev_Capabilities_Get(
732 PEC_Capabilities_t * const Capabilities_p)
733{
734 uint8_t Versions[2];
735
736 if (Capabilities_p == NULL)
737 return PEC_ERROR_BAD_PARAMETER;
738
739 memcpy(Capabilities_p, &CapabilitiesString, sizeof(CapabilitiesString));
740
741 // now fill in the number of rings.
742 {
743 Versions[0] = ADAPTER_EIP202_DEVICE_COUNT / 10;
744 Versions[1] = ADAPTER_EIP202_DEVICE_COUNT % 10;
745 }
746
747 {
748 char * p = Capabilities_p->szTextDescription;
749 int VerIndex = 0;
750 int i = 0;
751
752 if (p[sizeof(CapabilitiesString)-1] != 0)
753 return PEC_ERROR_INTERNAL;
754
755 while(p[i])
756 {
757 if (p[i] == '_')
758 {
759 if (VerIndex == sizeof(Versions)/sizeof(Versions[0]))
760 return PEC_ERROR_INTERNAL;
761 if (Versions[VerIndex] > 9)
762 p[i] = '?';
763 else
764 p[i] = '0' + Versions[VerIndex++];
765 }
766
767 i++;
768 }
769 }
770#ifdef ADAPTER_EIP202_USE_SHDEVXS
771 Capabilities_p->SupportedFuncs = SHDevXS_SupportedFuncs_Get();
772#else
773 Capabilities_p->SupportedFuncs = EIP97_SupportedFuncs_Get();
774#endif
775 return PEC_STATUS_OK;
776}
777
778/*----------------------------------------------------------------------------
779 * Adapter_PECDev_Control_Write
780 */
781PEC_Status_t
782Adapter_PECDev_CD_Control_Write(
783 PEC_CommandDescriptor_t *Command_p,
784 const PEC_PacketParams_t *PacketParams_p)
785{
786 IDENTIFIER_NOT_USED(Command_p);
787 IDENTIFIER_NOT_USED(PacketParams_p);
788
789 return PEC_ERROR_NOT_IMPLEMENTED;
790}
791
792
793/*----------------------------------------------------------------------------
794 * Adapter_PECDev_RD_Status_Read
795 */
796PEC_Status_t
797Adapter_PECDev_RD_Status_Read(
798 const PEC_ResultDescriptor_t * const Result_p,
799 PEC_ResultStatus_t * const ResultStatus_p)
800{
801 unsigned int s;
802
803#ifdef ADAPTER_EIP202_STRICT_ARGS
804 if (ResultStatus_p == NULL)
805 return PEC_ERROR_BAD_PARAMETER;
806#endif
807
808 if (IOToken_ErrorCode_Get(Result_p->OutputToken_p, &s) < 0)
809 return PEC_ERROR_BAD_PARAMETER;
810
811 // Translate the EIP-96 error codes to the PEC error codes
812 ResultStatus_p->errors =
813 BIT_MOVE(s, 0, 11) | // EIP-96 Packet length error
814 BIT_MOVE(s, 1, 17) | // EIP-96 Token error
815 BIT_MOVE(s, 2, 18) | // EIP-96 Bypass error
816 BIT_MOVE(s, 3, 9) | // EIP-96 Block size error
817 BIT_MOVE(s, 4, 16) | // EIP-96 Hash block size error.
818 BIT_MOVE(s, 5, 10) | // EIP-96 Invalid combo
819 BIT_MOVE(s, 6, 5) | // EIP-96 Prohibited algo
820 BIT_MOVE(s, 7, 19) | // EIP-96 Hash overflow
821#ifndef ADAPTER_EIP202_RING_TTL_ERROR_WA
822 BIT_MOVE(s, 8, 20) | // EIP-96 TTL/Hop limit underflow.
823#endif
824 BIT_MOVE(s, 9, 0) | // EIP-96 Authentication failed
825 BIT_MOVE(s, 10, 2) | // EIP-96 Sequence number check failed.
826 BIT_MOVE(s, 11, 8) | // EIP-96 SPI check failed.
827 BIT_MOVE(s, 12, 21) | // EIP-96 Incorrect checksum
828 BIT_MOVE(s, 12, 1) | // EIP-96 Pad verification.
829 BIT_MOVE(s, 14, 22); // EIP-96 Timeout
830
831 // Translate the EIP-202 error codes to the PEC error codes
832 s = Result_p->Status1;
833 ResultStatus_p->errors |=
834 BIT_MOVE(s, 21, 26) | // EIP-202 Buffer overflow
835 BIT_MOVE(s, 20, 25); // EIP-202 Descriptor overflow
836
837 return PEC_STATUS_OK;
838}
839
840
841/*----------------------------------------------------------------------------
842 * Adapter_PECDev_Init
843 */
844PEC_Status_t
845Adapter_PECDev_Init(
846 const unsigned int InterfaceId,
847 const PEC_InitBlock_t * const InitBlock_p)
848{
849 Device_Handle_t CDR_Device, RDR_Device;
850 EIP202_Ring_Error_t res;
851 DMAResource_AddrPair_t PhysAddr_Pair;
852 unsigned int CDWordCount, RDWordCount; // Command and Result Descriptor size
853 unsigned int CDOffset, RDOffset; // Command and Result Descriptor Offsets
854 unsigned int RDTokenOffsWordCount;
855
856 IDENTIFIER_NOT_USED(InitBlock_p);
857
858 LOG_INFO("\n\t\t Adapter_PECDev_Init \n");
859
860 if (ADAPTER_EIP202_DEVICE_COUNT > ADAPTER_EIP202_DEVICE_COUNT_ACTUAL)
861 {
862 LOG_CRIT("Adapter_PECDev_Init: "
863 "Adapter EIP-202 devices configuration is invalid\n");
864 return PEC_ERROR_BAD_PARAMETER;
865 }
866
867 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
868 return PEC_ERROR_BAD_PARAMETER;
869
870 CDR_Device = Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p);
871 RDR_Device = Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p);
872
873 if (CDR_Device == NULL || RDR_Device == NULL)
874 return PEC_ERROR_INTERNAL;
875 EIP202_ContinuousScatter[InterfaceId] = InitBlock_p->fContinuousScatter;
876
877 LOG_INFO("\n\t\t\t EIP202_CDR_Reset \n");
878
879 // Reset both the CDR and RDR devives.
880 res = EIP202_CDR_Reset(CDR_IOArea + InterfaceId, CDR_Device);
881 if (res != EIP202_RING_NO_ERROR)
882 return PEC_ERROR_INTERNAL;
883
884 LOG_INFO("\n\t\t\t EIP202_RDR_Reset \n");
885
886 res = EIP202_RDR_Reset(RDR_IOArea + InterfaceId, RDR_Device);
887 if (res != EIP202_RING_NO_ERROR)
888 return PEC_ERROR_INTERNAL;
889
890 // Determine the DMA buffer allocation alignment
891 if (!AdapterLib_Ring_EIP202_DMA_Alignment_Determine())
892 return PEC_ERROR_INTERNAL;
893
894#ifdef ADAPTER_EIP202_RING_LOCAL_CONFIGURE
895 // Configure the EIP-202 Ring Managers with configuration
896 // parameters obtained from local CDR device.
897 {
898 EIP202_Ring_Options_t options;
899
900 res = EIP202_CDR_Options_Get(CDR_Device, &options);
901 if (res != EIP202_RING_NO_ERROR)
902 {
903 LOG_CRIT("%s: EIP202_CDR_Options_Get failed, error %d\n",
904 __func__,
905 res);
906 return PEC_ERROR_INTERNAL;
907 }
908 Adapter_Ring_EIP202_Configure(options.HDW,
909 options.CF_Size,
910 options.RF_Size);
911 }
912#endif
913 // Determine required command and result descriptor size and offset
914 {
915 unsigned int ByteCount;
916
917 CDWordCount = EIP202_CD_CTRL_DATA_MAX_WORD_COUNT +
918 IOToken_InWordCount_Get();
919 ByteCount = MAX(AdapterLib_Ring_EIP202_DMA_Alignment_Get(),
920 ADAPTER_EIP202_CD_OFFSET_BYTE_COUNT);
921 ByteCount = AdapterLib_Ring_EIP202_AlignForSize(
922 CDWordCount * sizeof(uint32_t),
923 ByteCount);
924 CDOffset = ByteCount / sizeof(uint32_t);
925
926 LOG_CRIT("%s: EIP-202 CD size/offset %d/%d (32-bit words)\n",
927 __func__,
928 CDWordCount,
929 CDOffset);
930
931 if (Adapter_Ring_EIP202_HDW == 3)
932 {
933 RDTokenOffsWordCount = 8;
934 }
935 else
936 {
937 RDTokenOffsWordCount = EIP202_RD_CTRL_DATA_MAX_WORD_COUNT;
938 }
939 RDWordCount = RDTokenOffsWordCount +
940 IOToken_OutWordCount_Get();
941 ByteCount = MAX(AdapterLib_Ring_EIP202_DMA_Alignment_Get(),
942 ADAPTER_EIP202_RD_OFFSET_BYTE_COUNT);
943 ByteCount = AdapterLib_Ring_EIP202_AlignForSize(
944 RDWordCount * sizeof(uint32_t),
945 ByteCount);
946 RDOffset = ByteCount / sizeof(uint32_t);
947
948 LOG_CRIT("%s: EIP-202 RD size/offset %d/%d (32-bit words)\n",
949 __func__,
950 RDWordCount,
951 RDOffset);
952
953#ifndef ADAPTER_EIP202_SEPARATE_RINGS
954 {
955 unsigned int RDMaxTokenWordCount = RDOffset -
956 EIP202_RD_CTRL_DATA_MAX_WORD_COUNT;
957
958 if (CDWordCount > RDMaxTokenWordCount)
959 {
960 LOG_CRIT("%s: failed, EIP-202 CD (%d 32-bit words) "
961 "exceeds max RD token space (%d 32-bit words)\n",
962 __func__,
963 CDWordCount,
964 RDMaxTokenWordCount);
965 return PEC_ERROR_INTERNAL;
966 }
967 }
968#endif
969 }
970
971#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
972#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
973#ifdef ADAPTER_EIP202_USE_SHDEVXS
974 {
975 void *SABaseAddr;
976
977 SHDevXS_DMAPool_GetBase(&SABaseAddr);
978
979 LOG_INFO("Adapter_PECDev_Init: got SA base %p\n",SABaseAddr);
980
981 Adapter_AddrToWordPair(SABaseAddr,
982 0,
983 &EIP202_SABaseAddr,
984 &EIP202_SABaseUpperAddr);
985 }
986#else
987 { // Set the SA pool base address.
988 int dmares;
989 Device_Handle_t Device;
990 DMAResource_Handle_t DMAHandle;
991 DMAResource_Properties_t DMAProperties;
992 DMAResource_AddrPair_t DMAAddr;
993
994 // Perform a dummy allocation in bank 1 to obtain the pool base
995 // address.
996 DMAProperties.Alignment = AdapterLib_Ring_EIP202_DMA_Alignment_Get();
997 DMAProperties.Bank = ADAPTER_EIP202_BANK_SA;
998 DMAProperties.fCached = false;
999 DMAProperties.Size = ADAPTER_EIP202_TRANSFORM_RECORD_COUNT *
1000 ADAPTER_EIP202_TRANSFORM_RECORD_BYTE_COUNT;
1001
1002 dmares = DMAResource_Alloc(DMAProperties, &DMAAddr, &DMAHandle);
1003 if (dmares != 0)
1004 return PEC_ERROR_INTERNAL;
1005
1006 // Derive the physical address from the DMA resource.
1007 if (DMAResource_Translate(DMAHandle,
1008 DMARES_DOMAIN_BUS,
1009 &DMAAddr) < 0)
1010 {
1011 DMAResource_Release(DMAHandle);
1012 return PEC_ERROR_INTERNAL;
1013 }
1014
1015 Adapter_AddrToWordPair(DMAAddr.Address_p,
1016 0,
1017 &EIP202_SABaseAddr,
1018 &EIP202_SABaseUpperAddr);
1019
1020 // Set the cache base address.
1021 Device = Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME);
1022 if (Device == NULL)
1023 {
1024 LOG_CRIT("Adapter_PECDev_UnInit: Could not find device\n");
1025 return PEC_ERROR_INTERNAL;
1026 }
1027
1028 LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
1029
1030 EIP207_RC_BaseAddr_Set(
1031 Device,
1032 EIP207_TRC_REG_BASE,
1033 EIP207_RC_SET_NR_DEFAULT,
1034 EIP202_SABaseAddr,
1035 EIP202_SABaseUpperAddr);
1036
1037 // Release the DMA resource.
1038 DMAResource_Release(DMAHandle);
1039 }
1040#endif // ADAPTER_EIP202_USE_SHDEVXS
1041#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
1042#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
1043
1044 // Allocate the ring buffers(s).
1045 {
1046 int dmares;
1047#ifdef ADAPTER_EIP202_SEPARATE_RINGS
1048 unsigned int CDRByteCount = 4 * ADAPTER_EIP202_MAX_PACKETS * CDOffset;
1049 unsigned int RDRByteCount = 4 * ADAPTER_EIP202_MAX_PACKETS * RDOffset;
1050#else
1051 unsigned int RDRByteCount = 4 * ADAPTER_EIP202_MAX_PACKETS * CDOffset +
1052 ADAPTER_EIP202_CDR_BYTE_OFFSET;
1053#endif
1054
1055 DMAResource_Properties_t RingProperties;
1056 DMAResource_AddrPair_t RingHostAddr;
1057
1058 // used as uint32_t array
1059 RingProperties.Alignment = AdapterLib_Ring_EIP202_DMA_Alignment_Get();
1060 RingProperties.Bank = ADAPTER_EIP202_BANK_RING;
1061 RingProperties.fCached = false;
1062 RingProperties.Size = RDRByteCount;
1063
1064 dmares = DMAResource_Alloc(RingProperties,
1065 &RingHostAddr,
1066 RDR_Handle + InterfaceId);
1067 if (dmares != 0)
1068 return PEC_ERROR_INTERNAL;
1069
1070#ifdef ADAPTER_EIP202_ARMRING_ENABLE_SWAP
1071 DMAResource_SwapEndianness_Set(RDR_Handle[InterfaceId],true);
1072#endif
1073
1074 memset (RingHostAddr.Address_p, 0, RDRByteCount);
1075
1076#ifdef ADAPTER_EIP202_SEPARATE_RINGS
1077
1078 RingProperties.Size = CDRByteCount;
1079
1080 dmares = DMAResource_Alloc(RingProperties,
1081 &RingHostAddr,
1082 CDR_Handle + InterfaceId);
1083 if (dmares != 0)
1084 {
1085 DMAResource_Release(RDR_Handle[InterfaceId]);
1086 return PEC_ERROR_INTERNAL;
1087 }
1088
1089#ifdef ADAPTER_EIP202_ARMRING_ENABLE_SWAP
1090 DMAResource_SwapEndianness_Set(CDR_Handle[InterfaceId], true);
1091#endif
1092
1093 memset (RingHostAddr.Address_p, 0, CDRByteCount);
1094
1095#else
1096 RingProperties.Size -= ADAPTER_EIP202_CDR_BYTE_OFFSET;
1097 RingProperties.fCached = false;
1098
1099 {
1100 uint8_t * Byte_p = (uint8_t*)RingHostAddr.Address_p;
1101
1102 Byte_p += ADAPTER_EIP202_CDR_BYTE_OFFSET;
1103
1104 RingHostAddr.Address_p = Byte_p;
1105 }
1106
1107 dmares = DMAResource_CheckAndRegister(RingProperties,
1108 RingHostAddr,
1109 'R',
1110 CDR_Handle + InterfaceId);
1111 if (dmares != 0)
1112 {
1113 DMAResource_Release(RDR_Handle[InterfaceId]);
1114 return PEC_ERROR_INTERNAL;
1115 }
1116
1117#ifdef ADAPTER_EIP202_ARMRING_ENABLE_SWAP
1118 DMAResource_SwapEndianness_Set(CDR_Handle[InterfaceId], true);
1119#endif
1120
1121#endif
1122
1123 LOG_CRIT("%s: CDR/RDR byte count %d/%d, %s, CDR offset %d bytes\n",
1124 __func__,
1125#ifdef ADAPTER_EIP202_SEPARATE_RINGS
1126 CDRByteCount,
1127 RDRByteCount,
1128 "non-overlapping",
1129 0);
1130#else
1131 0,
1132 RDRByteCount,
1133 "overlapping",
1134 (int)ADAPTER_EIP202_CDR_BYTE_OFFSET);
1135#endif
1136 }
1137
1138 // Initialize the CDR and RDR devices
1139 {
1140 ZEROINIT(CDR_Settings);
1141
1142#ifdef ADAPTER_EIP202_RING_MANUAL_CONFIGURE
1143 // Configure the EIP-202 Ring Managers with manually set
1144 // configuration parameters
1145 Adapter_Ring_EIP202_Configure(ADAPTER_EIP202_HOST_DATA_WIDTH,
1146 ADAPTER_EIP202_CF_SIZE,
1147 ADAPTER_EIP202_RF_SIZE);
1148#endif
1149
1150 CDR_Settings.fATP = (ADAPTER_EIP202_CDR_ATP_PRESENT > 0) ?
1151 true : false;
1152 CDR_Settings.fATPtoToken = false;
1153
1154 CDR_Settings.Params.DataBusWidthWordCount = 1;
1155
1156 // Not used for CDR
1157 CDR_Settings.Params.ByteSwap_DataType_Mask = 0;
1158 CDR_Settings.Params.ByteSwap_Packet_Mask = 0;
1159
1160 // Enable endianess conversion for the RDR master interface
1161 // if configured
1162#ifdef ADAPTER_EIP202_CDR_BYTE_SWAP_ENABLE
1163 CDR_Settings.Params.ByteSwap_Token_Mask =
1164 CDR_Settings.Params.ByteSwap_Descriptor_Mask =
1165 EIP202_RING_BYTE_SWAP_METHOD_32;
1166#else
1167 CDR_Settings.Params.ByteSwap_Token_Mask = 0;
1168 CDR_Settings.Params.ByteSwap_Descriptor_Mask = 0;
1169#endif
1170
1171 CDR_Settings.Params.Bufferability = 0;
1172#ifdef ADAPTER_EIP202_64BIT_DEVICE
1173 CDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DSCR_PTR;
1174#else
1175 CDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DISABLED;
1176#endif
1177 CDR_Settings.Params.RingSizeWordCount =
1178 CDOffset * ADAPTER_EIP202_MAX_PACKETS;
1179 CDR_Settings.Params.RingDMA_Handle = CDR_Handle[InterfaceId];
1180
1181#ifdef ADAPTER_EIP202_SEPARATE_RINGS
1182 if (DMAResource_Translate(CDR_Handle[InterfaceId], DMARES_DOMAIN_BUS,
1183 &PhysAddr_Pair) < 0)
1184 {
1185 Adapter_PECDev_UnInit(InterfaceId);
1186 return PEC_ERROR_INTERNAL;
1187 }
1188 Adapter_AddrToWordPair(PhysAddr_Pair.Address_p, 0,
1189 &CDR_Settings.Params.RingDMA_Address.Addr,
1190 &CDR_Settings.Params.RingDMA_Address.UpperAddr);
1191#else
1192 if (DMAResource_Translate(RDR_Handle[InterfaceId], DMARES_DOMAIN_BUS,
1193 &PhysAddr_Pair) < 0)
1194 {
1195 Adapter_PECDev_UnInit(InterfaceId);
1196 return PEC_ERROR_INTERNAL;
1197 }
1198 Adapter_AddrToWordPair(PhysAddr_Pair.Address_p,
1199 ADAPTER_EIP202_CDR_BYTE_OFFSET,
1200 &CDR_Settings.Params.RingDMA_Address.Addr,
1201 &CDR_Settings.Params.RingDMA_Address.UpperAddr);
1202#endif
1203
1204 CDR_Settings.Params.DscrSizeWordCount = CDWordCount;
1205 CDR_Settings.Params.DscrOffsWordCount = CDOffset;
1206
1207#ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
1208 if(Adapter_Ring_EIP202_Configured)
1209 {
1210 uint32_t cd_size_rndup;
1211 int cfcount;
1212
1213 // Use configuration parameters received via
1214 // the Ring 97 Configuration (adapter_ring_eip202.h) interface
1215 if(CDR_Settings.Params.DscrOffsWordCount &
1216 ((1 << Adapter_Ring_EIP202_HDW) - 1))
1217 {
1218 LOG_CRIT("Adapter_PECDev_Init: Error, "
1219 "Command Descriptor Offset %d"
1220 " is not an integer multiple of Host Data Width %d\n",
1221 CDR_Settings.Params.DscrOffsWordCount,
1222 Adapter_Ring_EIP202_HDW);
1223
1224 Adapter_PECDev_UnInit(InterfaceId);
1225 return PEC_ERROR_INTERNAL;
1226 }
1227
1228 // Round up to the next multiple of HDW words
1229 cd_size_rndup = (CDR_Settings.Params.DscrOffsWordCount +
1230 ((1 << Adapter_Ring_EIP202_HDW) - 1)) >>
1231 Adapter_Ring_EIP202_HDW;
1232
1233 // Half of number of full descriptors that fit FIFO
1234 // Note: Adapter_Ring_EIP202_CFSize is in HDW words
1235 cfcount = (1<<(Adapter_Ring_EIP202_CFSize-1)) / cd_size_rndup;
1236
1237 // Check if command descriptor fits in fetch FIFO
1238 if(cfcount <= 0)
1239 cfcount = 1; // does not fit, adjust the count
1240
1241 // Note: cfcount must be also checked for not exceeding
1242 // max DMA length
1243
1244 // Convert to 32-bits word counts
1245 CDR_Settings.Params.DscrFetchSizeWordCount =
1246 (cfcount-1)* (cd_size_rndup << Adapter_Ring_EIP202_HDW);
1247 CDR_Settings.Params.DscrThresholdWordCount =
1248 cfcount * (cd_size_rndup << Adapter_Ring_EIP202_HDW);
1249 }
1250 else
1251#endif // #ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
1252 {
1253 // Use default static (user-defined) configuration parameters
1254#ifdef ADAPTER_EIP202_CDR_DSCR_FETCH_WORD_COUNT
1255 CDR_Settings.Params.DscrFetchSizeWordCount =
1256 ADAPTER_EIP202_CDR_DSCR_FETCH_WORD_COUNT;
1257#else
1258 CDR_Settings.Params.DscrFetchSizeWordCount = CDOffset;
1259#endif
1260 CDR_Settings.Params.DscrThresholdWordCount =
1261 ADAPTER_EIP202_CDR_DSCR_THRESH_WORD_COUNT;
1262 }
1263
1264 LOG_CRIT("Adapter_PECDev_Init: CDR fetch size %d, threshold %d, "
1265 "HDW=%d, CFsize=%d\n",
1266 CDR_Settings.Params.DscrFetchSizeWordCount,
1267 CDR_Settings.Params.DscrThresholdWordCount,
1268 Adapter_Ring_EIP202_HDW,
1269 Adapter_Ring_EIP202_CFSize);
1270
1271 // CDR Interrupts will be enabled via the Event Mgmt API functions
1272 CDR_Settings.Params.IntThresholdDscrCount = 0;
1273 CDR_Settings.Params.IntTimeoutDscrCount = 0;
1274 if ((CDR_Settings.Params.DscrFetchSizeWordCount /
1275 CDR_Settings.Params.DscrOffsWordCount) >
1276 (CDR_Settings.Params.DscrThresholdWordCount /
1277 CDR_Settings.Params.DscrSizeWordCount))
1278 {
1279 LOG_CRIT("Adapter_PECDev_Init: CDR Threshold lower than fetch size"
1280 " incorrect setting\n");
1281 Adapter_PECDev_UnInit(InterfaceId);
1282 return PEC_ERROR_BAD_PARAMETER;
1283 }
1284
1285
1286 LOG_INFO("\n\t\t\t EIP202_CDR_Init \n");
1287
1288 res = EIP202_CDR_Init(CDR_IOArea + InterfaceId,
1289 CDR_Device,
1290 &CDR_Settings);
1291 if (res != EIP202_RING_NO_ERROR)
1292 {
1293 Adapter_PECDev_UnInit(InterfaceId);
1294 return PEC_ERROR_INTERNAL;
1295 }
1296 }
1297
1298 {
1299 ZEROINIT(RDR_Settings);
1300
1301 RDR_Settings.Params.DataBusWidthWordCount = 1;
1302
1303 // Not used for RDR
1304 RDR_Settings.Params.ByteSwap_DataType_Mask = 0;
1305 RDR_Settings.Params.ByteSwap_Token_Mask = 0;
1306
1307 RDR_Settings.fContinuousScatter = InitBlock_p->fContinuousScatter;
1308
1309 // Enable endianess conversion for the RDR master interface
1310 // if configured
1311 RDR_Settings.Params.ByteSwap_Packet_Mask = 0;
1312#ifdef ADAPTER_EIP202_RDR_BYTE_SWAP_ENABLE
1313 RDR_Settings.Params.ByteSwap_Descriptor_Mask =
1314 EIP202_RING_BYTE_SWAP_METHOD_32;
1315#else
1316 RDR_Settings.Params.ByteSwap_Descriptor_Mask = 0;
1317#endif
1318
1319 RDR_Settings.Params.Bufferability = 0;
1320
1321#ifdef ADAPTER_EIP202_64BIT_DEVICE
1322 RDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DSCR_PTR;
1323#else
1324 RDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DISABLED;
1325#endif
1326
1327 RDR_Settings.Params.RingSizeWordCount =
1328 RDOffset * ADAPTER_EIP202_MAX_PACKETS;
1329
1330 RDR_Settings.Params.RingDMA_Handle = RDR_Handle[InterfaceId];
1331
1332 if (DMAResource_Translate(RDR_Handle[InterfaceId], DMARES_DOMAIN_BUS,
1333 &PhysAddr_Pair) < 0)
1334 {
1335 Adapter_PECDev_UnInit(InterfaceId);
1336 return PEC_ERROR_INTERNAL;
1337 }
1338 Adapter_AddrToWordPair(PhysAddr_Pair.Address_p, 0,
1339 &RDR_Settings.Params.RingDMA_Address.Addr,
1340 &RDR_Settings.Params.RingDMA_Address.UpperAddr);
1341
1342 RDR_Settings.Params.DscrSizeWordCount = RDWordCount;
1343 RDR_Settings.Params.DscrOffsWordCount = RDOffset;
1344 RDR_Settings.Params.TokenOffsetWordCount = RDTokenOffsWordCount;
1345
1346#ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
1347 if(Adapter_Ring_EIP202_Configured)
1348 {
1349 uint32_t rd_size_rndup;
1350 int rfcount;
1351
1352 // Use configuration parameters received via
1353 // the Ring 97 Configuration (adapter_ring_eip202.h) interface
1354 if(RDR_Settings.Params.DscrOffsWordCount &
1355 ((1 << Adapter_Ring_EIP202_HDW) - 1))
1356 {
1357 LOG_CRIT("Adapter_PECDev_Init: Error, "
1358 "Result Descriptor Offset %d"
1359 " is not an integer multiple of Host Data Width %d\n",
1360 RDR_Settings.Params.DscrOffsWordCount,
1361 Adapter_Ring_EIP202_HDW);
1362
1363 Adapter_PECDev_UnInit(InterfaceId);
1364 return PEC_ERROR_INTERNAL;
1365 }
1366
1367 // Round up to the next multiple of HDW words
1368 rd_size_rndup = (RDR_Settings.Params.DscrOffsWordCount +
1369 ((1 << Adapter_Ring_EIP202_HDW) - 1)) >>
1370 Adapter_Ring_EIP202_HDW;
1371
1372 // Half of number of full descriptors that fit FIFO
1373 // Note: Adapter_Ring_EIP202_RFSize is in HDW words
1374 rfcount = (1 << (Adapter_Ring_EIP202_RFSize - 1)) / rd_size_rndup;
1375
1376 // Check if prepared result descriptor fits in fetch FIFO
1377 if(rfcount <= 0)
1378 rfcount = 1; // does not fit, adjust the count
1379
1380 // Note: rfcount must be also checked for not exceeding
1381 // max DMA length
1382
1383 // Convert to 32-bit words counts
1384 RDR_Settings.Params.DscrFetchSizeWordCount =
1385 (rfcount - 1) * (rd_size_rndup << Adapter_Ring_EIP202_HDW);
1386 RDR_Settings.Params.DscrThresholdWordCount =
1387 rfcount * (rd_size_rndup << Adapter_Ring_EIP202_HDW);
1388 }
1389 else
1390#endif // #ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
1391 {
1392 // Use default static (user-defined) configuration parameters
1393 RDR_Settings.Params.DscrFetchSizeWordCount =
1394 ADAPTER_EIP202_RDR_DSCR_FETCH_WORD_COUNT;
1395 RDR_Settings.Params.DscrThresholdWordCount =
1396 ADAPTER_EIP202_RDR_DSCR_THRESH_WORD_COUNT;
1397 }
1398
1399 LOG_CRIT("Adapter_PECDev_Init: RDR fetch size %d, threshold %d, "
1400 "RFsize=%d\n",
1401 RDR_Settings.Params.DscrFetchSizeWordCount,
1402 RDR_Settings.Params.DscrThresholdWordCount,
1403 Adapter_Ring_EIP202_RFSize);
1404
1405 // RDR Interrupts will be enabled via the Event Mgmt API functions
1406 RDR_Settings.Params.IntThresholdDscrCount = 0;
1407 RDR_Settings.Params.IntTimeoutDscrCount = 0;
1408
1409 if ((RDR_Settings.Params.DscrFetchSizeWordCount /
1410 RDR_Settings.Params.DscrOffsWordCount) >
1411 (RDR_Settings.Params.DscrThresholdWordCount /
1412#ifdef ADAPTER_EIP202_64BIT_DEVICE
1413 4 /* RDR prepared descriptor size for 64-bit */
1414#else
1415 2 /* RDR prepared descriptor size for 32-bit */
1416#endif
1417 ))
1418 {
1419 LOG_CRIT("Adapter_PECDev_Init: RDR Threshold lower than fetch size"
1420 " incorrect setting\n");
1421 Adapter_PECDev_UnInit(InterfaceId);
1422 return PEC_ERROR_BAD_PARAMETER;
1423 }
1424 LOG_INFO("\n\t\t\t EIP202_RDR_Init \n");
1425
1426 res = EIP202_RDR_Init(RDR_IOArea + InterfaceId,
1427 RDR_Device,
1428 &RDR_Settings);
1429 if (res != EIP202_RING_NO_ERROR)
1430 {
1431 Adapter_PECDev_UnInit(InterfaceId);
1432 return PEC_ERROR_INTERNAL;
1433 }
1434 }
1435
1436 if (!AdapterLib_RD_OutTokens_Alloc(InterfaceId))
1437 {
1438 LOG_CRIT("Adapter_PECDev_Init: failed to allocate output tokens\n");
1439 Adapter_PECDev_UnInit(InterfaceId);
1440 return PEC_ERROR_INTERNAL; // Out of memory
1441 }
1442
1443 AdapterLib_Ring_EIP202_Status_Report(InterfaceId);
1444
1445#ifdef ADAPTER_EIP202_ADD_INIT_DIAGNOSTICS
1446 Adapter_Register_Dump();
1447#endif
1448
1449 return PEC_STATUS_OK;
1450}
1451
1452
1453/*----------------------------------------------------------------------------
1454 * Adapter_PECDev_UnInit
1455 */
1456PEC_Status_t
1457Adapter_PECDev_UnInit(
1458 const unsigned int InterfaceId)
1459{
1460 Device_Handle_t CDR_Device, RDR_Device;
1461
1462 LOG_INFO("\n\t\t Adapter_PECDev_UnInit \n");
1463
1464 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
1465 return PEC_ERROR_BAD_PARAMETER;
1466
1467 AdapterLib_Ring_EIP202_Status_Report(InterfaceId);
1468
1469#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
1470 {
1471 // Make a last attempt to get rid of any remaining result descriptors
1472 // belonging to unused scatter particles.
1473 uint32_t DscrDoneCount,DscrCount;
1474
1475 LOG_INFO("\n\t\t\t EIP202_RDR_Descriptor_Get \n");
1476
1477 EIP202_RDR_Descriptor_Get(RDR_IOArea + InterfaceId,
1478 EIP202_RDR_Entries[InterfaceId],
1479 ADAPTER_EIP202_MAX_LOGICDESCR,
1480 ADAPTER_EIP202_MAX_LOGICDESCR,
1481 &DscrDoneCount,
1482 &DscrCount);
1483 }
1484#endif
1485
1486 AdapterLib_RD_OutTokens_Free(InterfaceId);
1487
1488#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
1489#ifndef ADAPTER_EIP202_USE_SHDEVXS
1490 {
1491 // Reset the TRC base address to 0.
1492 Device_Handle_t Device;
1493
1494 Device = Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME);
1495 if (Device == NULL)
1496 {
1497 LOG_CRIT("Adapter_PECDev_UnInit: Could not find device\n");
1498 return PEC_ERROR_INTERNAL;
1499 }
1500
1501 LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
1502
1503 EIP207_RC_BaseAddr_Set(
1504 Device,
1505 EIP207_TRC_REG_BASE,
1506 EIP207_RC_SET_NR_DEFAULT,
1507 0,
1508 0);
1509 }
1510#endif
1511#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
1512
1513 CDR_Device = Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p);
1514 RDR_Device = Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p);
1515
1516 if (CDR_Device == NULL || RDR_Device == NULL)
1517 return PEC_ERROR_INTERNAL;
1518
1519 LOG_INFO("\n\t\t\t EIP202_CDR_Reset \n");
1520
1521 EIP202_CDR_Reset(CDR_IOArea + InterfaceId,
1522 CDR_Device);
1523
1524 LOG_INFO("\n\t\t\t EIP202_RDR_Reset \n");
1525
1526 EIP202_RDR_Reset(RDR_IOArea + InterfaceId,
1527 RDR_Device);
1528
1529 if (RDR_Handle[InterfaceId] != NULL)
1530 {
1531 DMAResource_Release(RDR_Handle[InterfaceId]);
1532 RDR_Handle[InterfaceId] = NULL;
1533 }
1534
1535 if (CDR_Handle[InterfaceId] != NULL)
1536 {
1537 DMAResource_Release(CDR_Handle[InterfaceId]);
1538 CDR_Handle[InterfaceId] = NULL;
1539 }
1540
1541#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
1542 Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].RDR_IRQ_ID, NULL);
1543 Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].CDR_IRQ_ID, NULL);
1544#endif
1545
1546 return PEC_STATUS_OK;
1547}
1548
1549
1550/*----------------------------------------------------------------------------
1551 * Adapter_PECDev_Resume
1552 */
1553int
1554Adapter_PECDev_Resume(
1555 const unsigned int InterfaceId)
1556{
1557 EIP202_Ring_Error_t res;
1558
1559 LOG_INFO("\n\t\t %s \n", __func__);
1560
1561 LOG_INFO("\n\t\t\t EIP202_CDR_Init \n");
1562 // Restore EIP-202 CDR
1563 res = EIP202_CDR_Init(CDR_IOArea + InterfaceId,
1564 Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p),
1565 &CDR_Settings);
1566 if (res != EIP202_RING_NO_ERROR)
1567 {
1568 LOG_CRIT("%s: EIP202_CDR_Init() error %d", __func__, res);
1569 return -1;
1570 }
1571
1572 LOG_INFO("\n\t\t\t EIP202_RDR_Init \n");
1573 // Restore EIP-202 RDR
1574 res = EIP202_RDR_Init(RDR_IOArea + InterfaceId,
1575 Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p),
1576 &RDR_Settings);
1577 if (res != EIP202_RING_NO_ERROR)
1578 {
1579 LOG_CRIT("%s: EIP202_CDR_Init() error %d", __func__, res);
1580 return -2;
1581 }
1582
1583#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
1584#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
1585#ifndef ADAPTER_EIP202_USE_SHDEVXS
1586 LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
1587 // Restore EIP-207 Record Cache base address
1588 EIP207_RC_BaseAddr_Set(
1589 Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME),
1590 EIP207_TRC_REG_BASE,
1591 EIP207_RC_SET_NR_DEFAULT,
1592 EIP202_SABaseAddr,
1593 EIP202_SABaseUpperAddr);
1594#endif
1595#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
1596#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
1597
1598#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
1599#ifndef ADAPTER_EIP202_USE_SHDEVXS
1600 // Restore RDR interrupt
1601 if (EIP202_Interrupts[InterfaceId] & BIT_0)
1602 Adapter_PECDev_Enable_ResultIRQ(InterfaceId);
1603
1604 // Restore CDR interrupt
1605 if (EIP202_Interrupts[InterfaceId] & BIT_1)
1606 Adapter_PECDev_Enable_CommandIRQ(InterfaceId);
1607#endif // ADAPTER_EIP202_USE_SHDEVXS
1608#endif // ADAPTER_EIP202_INTERRUPTS_ENABLE
1609
1610 return 0; // success
1611}
1612
1613
1614/*----------------------------------------------------------------------------
1615 * Adapter_PECDev_Suspend
1616 */
1617int
1618Adapter_PECDev_Suspend(
1619 const unsigned int InterfaceId)
1620{
1621 LOG_INFO("\n\t\t %s \n", __func__);
1622
1623#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
1624#ifndef ADAPTER_EIP202_USE_SHDEVXS
1625 // Disable RDR interrupt
1626 if (EIP202_Interrupts[InterfaceId] & BIT_0)
1627 {
1628 Adapter_PECDev_Disable_ResultIRQ(InterfaceId);
1629
1630 // Remember that interrupt was enabled
1631 EIP202_Interrupts[InterfaceId] |= BIT_0;
1632 }
1633
1634 // Disable CDR interrupt
1635 if (EIP202_Interrupts[InterfaceId] & BIT_1)
1636 {
1637 Adapter_PECDev_Disable_CommandIRQ(InterfaceId);
1638
1639 // Remember that interrupt was enabled
1640 EIP202_Interrupts[InterfaceId] |= BIT_1;
1641 }
1642#endif // ADAPTER_EIP202_USE_SHDEVXS
1643#endif // ADAPTER_EIP202_INTERRUPTS_ENABLE
1644
1645#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
1646#ifndef ADAPTER_EIP202_USE_SHDEVXS
1647 {
1648 LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
1649
1650 // Reset the TRC base address to 0
1651 EIP207_RC_BaseAddr_Set(
1652 Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME),
1653 EIP207_TRC_REG_BASE,
1654 EIP207_RC_SET_NR_DEFAULT,
1655 0,
1656 0);
1657 }
1658#endif
1659#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
1660
1661 LOG_INFO("\n\t\t\t EIP202_CDR_Reset \n");
1662
1663 EIP202_CDR_Reset(CDR_IOArea + InterfaceId,
1664 Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p));
1665
1666 LOG_INFO("\n\t\t\t EIP202_RDR_Reset \n");
1667
1668 EIP202_RDR_Reset(RDR_IOArea + InterfaceId,
1669 Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p));
1670
1671 return 0; // success
1672}
1673
1674
1675/*----------------------------------------------------------------------------
1676 * Adapter_PECDev_SA_Prepare
1677 */
1678PEC_Status_t
1679Adapter_PECDev_SA_Prepare(
1680 const DMABuf_Handle_t SAHandle,
1681 const DMABuf_Handle_t StateHandle,
1682 const DMABuf_Handle_t ARC4Handle)
1683{
1684 DMAResource_Handle_t SA_DMAHandle;
1685
1686 IDENTIFIER_NOT_USED(StateHandle.p);
1687 IDENTIFIER_NOT_USED(ARC4Handle.p);
1688
1689 if (DMABuf_Handle_IsSame(&SAHandle, &DMABuf_NULLHandle))
1690 return PEC_ERROR_BAD_PARAMETER;
1691 else
1692 {
1693 DMAResource_Record_t * Rec_p;
1694
1695 SA_DMAHandle = Adapter_DMABuf_Handle2DMAResourceHandle(SAHandle);
1696 Rec_p = DMAResource_Handle2RecordPtr(SA_DMAHandle);
1697
1698 if (Rec_p == NULL)
1699 return PEC_ERROR_INTERNAL;
1700
1701#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
1702 if (Rec_p->Props.Bank != ADAPTER_EIP202_BANK_SA)
1703 {
1704 LOG_CRIT("PEC_SA_Register: Invalid bank for SA\n");
1705 return PEC_ERROR_BAD_PARAMETER;
1706 }
1707#endif
1708
1709#ifndef ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
1710 {
1711 uint32_t FirstWord = DMAResource_Read32(SA_DMAHandle, 0);
1712 // Register in the DMA resource record whether the transform
1713 // is large.
1714 if ( (FirstWord & ADAPTER_EIP202_TR_ISLARGE) != 0)
1715 {
1716 Rec_p->fIsLargeTransform = true;
1717 DMAResource_Write32(SA_DMAHandle,
1718 0,
1719 FirstWord & ~ADAPTER_EIP202_TR_ISLARGE);
1720 // Clear that bit in the SA record itself.
1721 }
1722 else
1723 {
1724 Rec_p->fIsLargeTransform = false;
1725 }
1726 }
1727#endif
1728
1729 Rec_p->fIsNewSA = true;
1730 }
1731
1732 return PEC_STATUS_OK;
1733}
1734
1735
1736/*----------------------------------------------------------------------------
1737 * Adapter_PECDev_SA_Remove
1738 */
1739PEC_Status_t
1740Adapter_PECDev_SA_Remove(
1741 const DMABuf_Handle_t SAHandle,
1742 const DMABuf_Handle_t StateHandle,
1743 const DMABuf_Handle_t ARC4Handle)
1744{
1745 IDENTIFIER_NOT_USED(StateHandle.p);
1746
1747 if (DMABuf_Handle_IsSame(&SAHandle, &DMABuf_NULLHandle))
1748 return PEC_ERROR_BAD_PARAMETER;
1749
1750#ifdef ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
1751 // Invalidate the record in the EIP-207 Transform Record Cache
1752 // or/and ARC4 State Record Cache
1753 // Not configured = disabled
1754 if (Adapter_RC_EIP207_Configured)
1755 {
1756#ifndef ADAPTER_EIP202_USE_SHDEVXS
1757 Device_Handle_t Device;
1758
1759 Device = Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME);
1760 if (Device == NULL)
1761 {
1762 LOG_CRIT("Adapter_PECDev_SA_Remove: Could not find device\n");
1763 return PEC_ERROR_INTERNAL;
1764 }
1765#endif
1766
1767 if (Adapter_RC_EIP207_TRC_Enabled)
1768 {
1769 EIP202_DeviceAddress_t DMA_Addr;
1770
1771 Adapter_GetPhysAddr(SAHandle, &DMA_Addr);
1772
1773#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
1774 DMA_Addr.Addr -= EIP202_SABaseAddr;
1775#endif
1776
1777 // Invalidate the SA Record in the TRC
1778#ifdef ADAPTER_EIP202_USE_SHDEVXS
1779 LOG_INFO("\n\t\t\t SHDevXS_TRC_Record_Invalidate \n");
1780
1781 SHDevXS_TRC_Record_Invalidate(DMA_Addr.Addr);
1782#else
1783 LOG_INFO("\n\t\t\t EIP207_RC_Record_Update \n");
1784
1785 EIP207_RC_Record_Update(
1786 Device,
1787 EIP207_TRC_REG_BASE,
1788 EIP207_RC_SET_NR_DEFAULT,
1789 DMA_Addr.Addr,
1790 EIP207_RC_CMD_SET_BITS,
1791 EIP207_RC_REG_DATA_BYTE_OFFSET - 3 * sizeof(uint32_t),
1792 EIP207_RC_HDR_WORD_3_RELOAD_BIT);
1793#endif // ADAPTER_EIP202_USE_SHDEVXS
1794 }
1795
1796 if (!DMABuf_Handle_IsSame(&ARC4Handle, &DMABuf_NULLHandle) &&
1797 Adapter_RC_EIP207_ARC4RC_Enabled)
1798 {
1799 EIP202_DeviceAddress_t DMA_Addr;
1800
1801 Adapter_GetPhysAddr(ARC4Handle, &DMA_Addr);
1802
1803 // Invalidate the ARC4 State record in the TRC or ARC4RC
1804#ifdef ADAPTER_EIP202_USE_SHDEVXS
1805 LOG_INFO("\n\t\t\t SHDevXS_ARC4RC_Record_Invalidate \n");
1806
1807 SHDevXS_ARC4RC_Record_Invalidate(DMA_Addr.Addr);
1808#else
1809 LOG_INFO("\n\t\t\t EIP207_RC_Record_Update \n");
1810
1811 EIP207_RC_Record_Update(
1812 Device,
1813 EIP207_ARC4RC_REG_BASE,
1814 EIP207_RC_SET_NR_DEFAULT,
1815 DMA_Addr.Addr,
1816 EIP207_RC_CMD_SET_BITS,
1817 EIP207_RC_REG_DATA_BYTE_OFFSET - 3 * sizeof(uint32_t),
1818 EIP207_RC_HDR_WORD_3_RELOAD_BIT);
1819#endif // ADAPTER_EIP202_USE_SHDEVXS
1820 }
1821 }
1822#else
1823 IDENTIFIER_NOT_USED(ARC4Handle.p);
1824#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
1825
1826 return PEC_STATUS_OK;
1827}
1828
1829
1830/*----------------------------------------------------------------------------
1831 * Adapter_PECDev_GetFreeSpace
1832 */
1833unsigned int
1834Adapter_PECDev_GetFreeSpace(
1835 const unsigned int InterfaceId)
1836{
1837 unsigned int FreeCDR, FreeRDR, FilledCDR, FilledRDR;
1838 EIP202_Ring_Error_t res;
1839
1840 LOG_INFO("\n\t\t Adapter_PECDev_GetFreeSpace \n");
1841
1842 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
1843 return PEC_ERROR_BAD_PARAMETER;
1844
1845 LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Get \n");
1846
1847 res = EIP202_CDR_FillLevel_Get(CDR_IOArea + InterfaceId,
1848 &FilledCDR);
1849 if (res != EIP202_RING_NO_ERROR)
1850 return 0;
1851
1852 if (FilledCDR > ADAPTER_EIP202_MAX_PACKETS)
1853 return 0;
1854
1855 FreeCDR = ADAPTER_EIP202_MAX_PACKETS - FilledCDR;
1856
1857 if (EIP202_ContinuousScatter[InterfaceId])
1858 {
1859 return FreeCDR;
1860 }
1861 else
1862 {
1863 LOG_INFO("\n\t\t\t EIP202_RDR_FillLevel_Get \n");
1864
1865 res = EIP202_RDR_FillLevel_Get(RDR_IOArea + InterfaceId,
1866 &FilledRDR);
1867 if (res != EIP202_RING_NO_ERROR)
1868 return 0;
1869
1870 if (FilledRDR > ADAPTER_EIP202_MAX_PACKETS)
1871 return 0;
1872
1873 FreeRDR = ADAPTER_EIP202_MAX_PACKETS - FilledRDR;
1874
1875 return MIN(FreeCDR, FreeRDR);
1876 }
1877}
1878
1879
1880/*----------------------------------------------------------------------------
1881 * Adapter_PECDev_PacketPut
1882 */
1883PEC_Status_t
1884Adapter_PECDev_Packet_Put(
1885 const unsigned int InterfaceId,
1886 const PEC_CommandDescriptor_t * Commands_p,
1887 const unsigned int CommandsCount,
1888 unsigned int * const PutCount_p)
1889{
1890 unsigned int CmdLp;
1891#ifdef ADAPTER_EIP202_STRICT_ARGS
1892 unsigned int FreeCDR,FreeRDR;
1893#endif
1894 unsigned int FilledCDR, FilledRDR, CDRIndex=0, RDRIndex=0;
1895 unsigned int Submitted = 0;
1896 EIP202_Ring_Error_t res;
1897 EIP202_CDR_Control_t CDR_Control;
1898 EIP202_RDR_Prepared_Control_t RDR_Control;
1899
1900 LOG_INFO("\n\t\t Adapter_PECDev_Packet_Put \n");
1901
1902 *PutCount_p = 0;
1903 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
1904 return PEC_ERROR_BAD_PARAMETER;
1905
1906#ifdef ADAPTER_EIP202_STRICT_ARGS
1907 LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Get \n");
1908
1909 res = EIP202_CDR_FillLevel_Get(CDR_IOArea + InterfaceId,
1910 &FilledCDR);
1911 if (res != EIP202_RING_NO_ERROR)
1912 return PEC_ERROR_INTERNAL;
1913
1914 if (FilledCDR > ADAPTER_EIP202_MAX_PACKETS)
1915 return PEC_ERROR_INTERNAL;
1916
1917 FreeCDR = ADAPTER_EIP202_MAX_PACKETS - FilledCDR;
1918
1919 LOG_INFO("\n\t\t\t EIP202_RDR_FillLevel_Get \n");
1920
1921 if (!EIP202_ContinuousScatter[InterfaceId])
1922 {
1923 res = EIP202_RDR_FillLevel_Get(RDR_IOArea + InterfaceId,
1924 &FilledRDR);
1925 if (res != EIP202_RING_NO_ERROR)
1926 return PEC_ERROR_INTERNAL;
1927
1928 if (FilledRDR > ADAPTER_EIP202_MAX_PACKETS)
1929 return PEC_ERROR_INTERNAL;
1930
1931 FreeRDR = ADAPTER_EIP202_MAX_PACKETS - FilledRDR;
1932 FreeRDR = MIN(ADAPTER_EIP202_MAX_LOGICDESCR, FreeRDR);
1933 }
1934 else
1935 {
1936 FreeRDR = 1;
1937 }
1938 FreeCDR = MIN(ADAPTER_EIP202_MAX_LOGICDESCR, FreeCDR);
1939#endif
1940
1941 for (CmdLp = 0; CmdLp < CommandsCount; CmdLp++)
1942 {
1943 uint8_t TokenWordCount;
1944 EIP202_DeviceAddress_t SA_PhysAddr;
1945
1946#ifdef ADAPTER_EIP202_STRICT_ARGS
1947 if (CDRIndex == FreeCDR || (!EIP202_ContinuousScatter[InterfaceId] && RDRIndex == FreeRDR))
1948 break; // Run out of free descriptors in any of the rings.
1949#endif
1950
1951 if (!Commands_p[CmdLp].InputToken_p)
1952 {
1953 LOG_CRIT("Adapter_PECDev_Packet_Put: failed, missing input token "
1954 "for command descriptor %d\n",
1955 CmdLp);
1956 return PEC_ERROR_BAD_PARAMETER;
1957 }
1958
1959 // Prepare (first) descriptor, except for source pointer/size.
1960 EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketByteCount =
1961 Commands_p[CmdLp].SrcPkt_ByteCount;
1962
1963 if (DMABuf_Handle_IsSame(&Commands_p[CmdLp].Token_Handle,
1964 &DMABuf_NULLHandle))
1965 {
1966 TokenWordCount = 0;
1967 }
1968 else
1969 {
1970 // Look-aside use case. token is created by the caller
1971 if (Commands_p[CmdLp].Token_WordCount > 255)
1972 return PEC_ERROR_INTERNAL;
1973
1974 TokenWordCount = (uint8_t)Commands_p[CmdLp].Token_WordCount;
1975 }
1976
1977 CDR_Control.TokenWordCount = TokenWordCount;
1978
1979 Adapter_GetPhysAddr(Commands_p[CmdLp].Token_Handle,
1980 &(EIP202_CDR_Entries[InterfaceId][CDRIndex].TokenDataAddr));
1981
1982 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
1983 &EIP202_CDR_Entries[InterfaceId][CDRIndex].TokenDataAddr,
1984 "token buffer"))
1985 return PEC_ERROR_INTERNAL;
1986
1987 CDR_Control.fFirstSegment = true;
1988 CDR_Control.fLastSegment = false;
1989 CDR_Control.fForceEngine = (Commands_p[CmdLp].Control2 & BIT_5) != 0;
1990 CDR_Control.EngineId = Commands_p[CmdLp].Control2 & MASK_5_BITS;
1991
1992 EIP202_CDR_Entries[InterfaceId][CDRIndex].Token_p =
1993 Commands_p[CmdLp].InputToken_p;
1994
1995 Adapter_GetPhysAddr(Commands_p[CmdLp].SA_Handle1, &SA_PhysAddr);
1996
1997 if (SA_PhysAddr.Addr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO ||
1998 SA_PhysAddr.UpperAddr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI)
1999 {
2000 DMAResource_Handle_t DMAHandle =
2001 Adapter_DMABuf_Handle2DMAResourceHandle(
2002 Commands_p[CmdLp].SA_Handle1);
2003 DMAResource_Record_t * Rec_p =
2004 DMAResource_Handle2RecordPtr(DMAHandle);
2005 if (Rec_p == NULL)
2006 return PEC_ERROR_INTERNAL;
2007
2008#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
2009 if (Rec_p->Props.Bank != ADAPTER_EIP202_BANK_SA)
2010 {
2011 LOG_CRIT("PEC_Packet_Put: Invalid bank for SA\n");
2012 return PEC_ERROR_BAD_PARAMETER;
2013 }
2014#endif
2015
2016 if (IOToken_SAReuse_Update(!Rec_p->fIsNewSA,
2017 Commands_p[CmdLp].InputToken_p) < 0)
2018 return PEC_ERROR_INTERNAL;
2019
2020 if (Rec_p->fIsNewSA)
2021 Rec_p->fIsNewSA = false;
2022 }
2023
2024#ifdef ADAPTER_EIP202_USE_POINTER_TYPES
2025 if (SA_PhysAddr.Addr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO ||
2026 SA_PhysAddr.UpperAddr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI)
2027 {
2028#ifndef ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
2029 DMAResource_Handle_t DMAHandle =
2030 Adapter_DMABuf_Handle2DMAResourceHandle(
2031 Commands_p[CmdLp].SA_Handle1);
2032 DMAResource_Record_t * Rec_p =
2033 DMAResource_Handle2RecordPtr(DMAHandle);
2034
2035 if (Rec_p->fIsLargeTransform)
2036 SA_PhysAddr.Addr |= ADAPTER_EIP202_TR_LARGE_ADDRESS;
2037 else
2038#endif
2039 SA_PhysAddr.Addr |= ADAPTER_EIP202_TR_ADDRESS;
2040 }
2041#endif
2042
2043#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
2044#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
2045 if (SA_PhysAddr.Addr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS ||
2046 SA_PhysAddr.UpperAddr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI)
2047 SA_PhysAddr.Addr -= EIP202_SABaseAddr;
2048
2049 SA_PhysAddr.UpperAddr = 0;
2050#endif // ADAPTER_EIP202_RC_DMA_BANKS_SUPPORT
2051#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
2052
2053 EIP202_CDR_Entries[InterfaceId][CDRIndex].ContextDataAddr = SA_PhysAddr;
2054
2055 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(&SA_PhysAddr, "SA buffer"))
2056 return PEC_ERROR_INTERNAL;
2057
2058 {
2059 IOToken_PhysAddr_t tkn_pa;
2060
2061 tkn_pa.Lo = SA_PhysAddr.Addr;
2062 tkn_pa.Hi = SA_PhysAddr.UpperAddr;
2063
2064 if (IOToken_SAAddr_Update(&tkn_pa,
2065 Commands_p[CmdLp].InputToken_p) < 0)
2066 return PEC_ERROR_INTERNAL;
2067 }
2068
2069 RDR_Control.fFirstSegment = true;
2070 RDR_Control.fLastSegment = false;
2071 RDR_Control.ExpectedResultWordCount = 0;
2072
2073#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
2074 {
2075 unsigned int GatherParticles;
2076 unsigned int ScatterParticles;
2077 unsigned int RequiredCDR, RequiredRDR;
2078 unsigned int i;
2079 unsigned int GatherByteCount;
2080
2081 PEC_SGList_GetCapacity(Commands_p[CmdLp].SrcPkt_Handle,
2082 &GatherParticles);
2083 if (EIP202_ContinuousScatter[InterfaceId])
2084 ScatterParticles = 1;
2085 else
2086 PEC_SGList_GetCapacity(Commands_p[CmdLp].DstPkt_Handle,
2087 &ScatterParticles);
2088
2089 if (GatherParticles == 0)
2090 RequiredCDR = 1;
2091 else
2092 RequiredCDR = GatherParticles;
2093
2094 if (ScatterParticles == 0)
2095 RequiredRDR = 1;
2096 else
2097 RequiredRDR = ScatterParticles;
2098
2099#ifndef ADAPTER_EIP202_SEPARATE_RINGS
2100 // If using overlapping rings, require an equal number of CDR
2101 // and RDR entries for the packet, the maximum of both.
2102 RequiredCDR = MAX(RequiredCDR,RequiredRDR);
2103 RequiredRDR = RequiredCDR;
2104#endif
2105 /* Check whether it will fit into the rings and the
2106 * prepared descriptor arrays.*/
2107#ifdef ADAPTER_EIP202_STRICT_ARGS
2108 if (CDRIndex + RequiredCDR > FreeCDR ||
2109 RDRIndex + RequiredRDR > FreeRDR)
2110 break;
2111#endif
2112
2113 if (GatherParticles > 0)
2114 {
2115 GatherByteCount = Commands_p[CmdLp].SrcPkt_ByteCount;
2116 for (i=0; i<GatherParticles; i++)
2117 {
2118 DMABuf_Handle_t ParticleHandle;
2119 uint8_t * DummyPtr;
2120 unsigned int ParticleSize;
2121
2122 PEC_SGList_Read(Commands_p[CmdLp].SrcPkt_Handle,
2123 i,
2124 &ParticleHandle,
2125 &ParticleSize,
2126 &DummyPtr);
2127
2128 Adapter_GetPhysAddr(ParticleHandle,
2129 &(EIP202_CDR_Entries[InterfaceId][CDRIndex+i].SrcPacketAddr));
2130
2131 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
2132 &EIP202_CDR_Entries[InterfaceId][CDRIndex+i].SrcPacketAddr,
2133 "source packet buffer"))
2134 return PEC_ERROR_INTERNAL;
2135
2136 if (ParticleSize > GatherByteCount)
2137 ParticleSize = GatherByteCount;
2138 GatherByteCount -= ParticleSize;
2139 // Limit the total size of the gather particles to the
2140 // actual packet length.
2141
2142 CDR_Control.fLastSegment = (RequiredCDR == i + 1);
2143 CDR_Control.SegmentByteCount = ParticleSize;
2144 EIP202_CDR_Entries[InterfaceId][CDRIndex+i].ControlWord =
2145 EIP202_CDR_Write_ControlWord(&CDR_Control);
2146 CDR_Control.fFirstSegment = false;
2147 CDR_Control.TokenWordCount = 0;
2148 }
2149 }
2150 else
2151 { /* No gather, use single source buffer */
2152
2153 Adapter_GetPhysAddr(Commands_p[CmdLp].SrcPkt_Handle,
2154 &(EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr));
2155
2156 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
2157 &EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr,
2158 "source packet buffer"))
2159 return PEC_ERROR_INTERNAL;
2160
2161 CDR_Control.fLastSegment = (RequiredCDR == 1);
2162 CDR_Control.SegmentByteCount =
2163 Commands_p[CmdLp].SrcPkt_ByteCount;
2164 EIP202_CDR_Entries[InterfaceId][CDRIndex].ControlWord =
2165 EIP202_CDR_Write_ControlWord(&CDR_Control);
2166
2167 CDR_Control.fFirstSegment = false;
2168 CDR_Control.TokenWordCount = 0;
2169 i = 1;
2170 }
2171
2172 /* Add any dummy segments for overlapping rings */
2173 for ( ; i<RequiredCDR; i++)
2174 {
2175
2176 CDR_Control.fLastSegment = (RequiredCDR == i + 1);
2177 CDR_Control.SegmentByteCount = 0;
2178 EIP202_CDR_Entries[InterfaceId][CDRIndex+i].ControlWord =
2179 EIP202_CDR_Write_ControlWord(&CDR_Control);
2180 }
2181
2182 if (!EIP202_ContinuousScatter[InterfaceId])
2183 {
2184 if (ScatterParticles > 0)
2185 {
2186 for (i=0; i<ScatterParticles; i++)
2187 {
2188 DMABuf_Handle_t ParticleHandle;
2189 uint8_t * DummyPtr;
2190 unsigned int ParticleSize;
2191
2192 PEC_SGList_Read(Commands_p[CmdLp].DstPkt_Handle,
2193 i,
2194 &ParticleHandle,
2195 &ParticleSize,
2196 &DummyPtr);
2197
2198 Adapter_GetPhysAddr(ParticleHandle,
2199 &(EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].DstPacketAddr));
2200
2201 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
2202 &EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].DstPacketAddr,
2203 "destination packet buffer"))
2204 return PEC_ERROR_INTERNAL;
2205
2206 RDR_Control.fLastSegment = (RequiredRDR == i + 1);
2207 RDR_Control.PrepSegmentByteCount = ParticleSize;
2208 EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].PrepControlWord =
2209 EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
2210
2211 RDR_Control.fFirstSegment = false;
2212 }
2213 }
2214 else
2215 { /* No scatter, use single destination buffer */
2216 DMAResource_Handle_t *DMAHandle =
2217 Adapter_DMABuf_Handle2DMAResourceHandle(
2218 Commands_p[CmdLp].DstPkt_Handle);
2219 DMAResource_Record_t * Rec_p;
2220
2221 if (DMAResource_IsValidHandle(DMAHandle))
2222 Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
2223 else
2224 Rec_p = NULL;
2225
2226 // Check if NULL packet pointers are allowed
2227 // for record invalidation commands
2228#ifndef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
2229 if (Rec_p == NULL)
2230 return PEC_ERROR_INTERNAL;
2231#endif
2232
2233 Adapter_GetPhysAddr(Commands_p[CmdLp].DstPkt_Handle,
2234 &(EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr));
2235
2236 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
2237 &EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr,
2238 "destination packet buffer"))
2239 return PEC_ERROR_INTERNAL;
2240
2241 RDR_Control.fLastSegment = (RequiredRDR==1);
2242
2243#ifdef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
2244 // For NULL packet pointers only, record cache invalidation
2245 if (Rec_p == NULL)
2246 RDR_Control.PrepSegmentByteCount = 0;
2247 else
2248#endif
2249 RDR_Control.PrepSegmentByteCount = Rec_p->Props.Size;
2250
2251 EIP202_RDR_Prepared[InterfaceId][RDRIndex].PrepControlWord =
2252 EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
2253
2254 RDR_Control.fFirstSegment = false;
2255 i = 1;
2256 }
2257
2258 /* Add any dummy segments for overlapping rings */
2259 for ( ; i<RequiredRDR; i++)
2260 {
2261 RDR_Control.fLastSegment = (RequiredRDR == i + 1);
2262 RDR_Control.PrepSegmentByteCount = 0;
2263 EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].PrepControlWord =
2264 EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
2265 }
2266 RDRIndex += RequiredRDR;
2267 }
2268 CDRIndex += RequiredCDR;
2269 }
2270#else
2271 {
2272 // Prepare source and destination buffer in non-SG case.
2273 DMAResource_Handle_t *DMAHandle =
2274 Adapter_DMABuf_Handle2DMAResourceHandle(
2275 Commands_p[CmdLp].DstPkt_Handle);
2276 DMAResource_Record_t * Rec_p;
2277
2278 if (DMAResource_IsValidHandle(DMAHandle))
2279 Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
2280 else
2281 Rec_p = NULL;
2282
2283 // Check if NULL packet pointers are allowed
2284 // for record invalidation commands
2285#ifndef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
2286 if (Rec_p == NULL)
2287 return PEC_ERROR_INTERNAL;
2288#endif
2289
2290 Adapter_GetPhysAddr(Commands_p[CmdLp].SrcPkt_Handle,
2291 &(EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr));
2292
2293 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
2294 &EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr,
2295 "source packet buffer"))
2296 return PEC_ERROR_INTERNAL;
2297
2298 CDR_Control.fLastSegment = true;
2299 CDR_Control.SegmentByteCount = Commands_p[CmdLp].SrcPkt_ByteCount;
2300
2301 EIP202_CDR_Entries[InterfaceId][CDRIndex].ControlWord =
2302 EIP202_CDR_Write_ControlWord(&CDR_Control);
2303
2304 if (!EIP202_ContinuousScatter[InterfaceId])
2305 {
2306 Adapter_GetPhysAddr(Commands_p[CmdLp].DstPkt_Handle,
2307 &(EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr));
2308
2309 if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
2310 &EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr,
2311 "destination packet buffer"))
2312 return PEC_ERROR_INTERNAL;
2313
2314 RDR_Control.fLastSegment = true;
2315
2316#ifdef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
2317 // For NULL packet pointers only, record cache invalidation
2318 if (Rec_p == NULL)
2319 RDR_Control.PrepSegmentByteCount = 0;
2320 else
2321#endif
2322 RDR_Control.PrepSegmentByteCount = Rec_p->Props.Size;
2323
2324 EIP202_RDR_Prepared[InterfaceId][RDRIndex].PrepControlWord =
2325 EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
2326
2327 RDRIndex +=1;
2328 }
2329 CDRIndex +=1;
2330 }
2331#endif
2332 *PutCount_p += 1;
2333 } // for, CommandsCount, CmdLp
2334
2335
2336 if (!EIP202_ContinuousScatter[InterfaceId])
2337 {
2338 LOG_INFO("\n\t\t\t EIP202_RDR_Descriptor_Prepare \n");
2339 res = EIP202_RDR_Descriptor_Prepare(RDR_IOArea + InterfaceId,
2340 EIP202_RDR_Prepared[InterfaceId],
2341 RDRIndex,
2342 &Submitted,
2343 &FilledRDR);
2344 if (res != EIP202_RING_NO_ERROR || Submitted != RDRIndex)
2345 {
2346 LOG_CRIT("Adapter_PECDev_Packet_Put: writing prepared descriptors"
2347 "error code %d count=%d expected=%d\n",
2348 res, Submitted, RDRIndex);
2349 return PEC_ERROR_INTERNAL;
2350 }
2351 }
2352 LOG_INFO("\n\t\t\t EIP202_CDR_Descriptor_Put \n");
2353
2354 res = EIP202_CDR_Descriptor_Put(CDR_IOArea + InterfaceId,
2355 EIP202_CDR_Entries[InterfaceId],
2356 CDRIndex,
2357 &Submitted,
2358 &FilledCDR);
2359 if (res != EIP202_RING_NO_ERROR || Submitted != CDRIndex)
2360 {
2361 LOG_CRIT("Adapter_PECDev_Packet_Put: writing command descriptors"
2362 "error code %d count=%d expected=%d\n",
2363 res, Submitted, CDRIndex);
2364 return PEC_ERROR_INTERNAL;
2365 }
2366
2367 return PEC_STATUS_OK;
2368}
2369
2370
2371/*----------------------------------------------------------------------------
2372 * Adapter_PECDev_Packet_Get
2373 */
2374PEC_Status_t
2375Adapter_PECDev_Packet_Get(
2376 const unsigned int InterfaceId,
2377 PEC_ResultDescriptor_t * Results_p,
2378 const unsigned int ResultsLimit,
2379 unsigned int * const GetCount_p)
2380{
2381 unsigned int ResLp;
2382 unsigned int DscrCount;
2383 unsigned int DscrDoneCount;
2384 unsigned int ResIndex;
2385
2386 EIP202_Ring_Error_t res;
2387
2388 LOG_INFO("\n\t\t Adapter_PECDev_Packet_Get \n");
2389
2390 *GetCount_p = 0;
2391
2392 if (ResultsLimit == 0)
2393 return PEC_STATUS_OK;
2394
2395 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2396 return PEC_ERROR_BAD_PARAMETER;
2397
2398 LOG_INFO("\n\t\t\t EIP202_RDR_Descriptor_Get \n");
2399
2400 // Assume that we do get the requested number of descriptors
2401 // as they were reported available.
2402 res = EIP202_RDR_Descriptor_Get(RDR_IOArea + InterfaceId,
2403 EIP202_RDR_Entries[InterfaceId],
2404 ResultsLimit, // Max number of packets.
2405 ADAPTER_EIP202_MAX_LOGICDESCR,
2406 &DscrDoneCount,
2407 &DscrCount);
2408 if (res != EIP202_RING_NO_ERROR)
2409 return PEC_ERROR_INTERNAL;
2410
2411 ResIndex = 0;
2412 for (ResLp = 0; ResLp < ResultsLimit; ResLp++)
2413 {
2414 EIP202_RDR_Result_Control_t ControlWord;
2415 bool fEncounteredFirst = false;
2416
2417 if (ResIndex >= DscrDoneCount)
2418 break;
2419
2420 for (;;)
2421 {
2422 LOG_INFO("\n\t\t\t EIP202_RDR_Read_Processed_ControlWord \n");
2423
2424 EIP202_RDR_Read_Processed_ControlWord(
2425 EIP202_RDR_Entries[InterfaceId] + ResIndex,
2426 &ControlWord,
2427 NULL);
2428
2429 if ( ControlWord.fFirstSegment)
2430 {
2431 fEncounteredFirst = true;
2432 Results_p[ResLp].NumParticles = 0;
2433 }
2434 Results_p[ResLp].NumParticles++;
2435
2436 if ( ControlWord.fLastSegment && fEncounteredFirst)
2437 break; // Last segment of packet, only valid when
2438 // first segment was encountered.
2439 ResIndex++;
2440
2441 // There may be unused scatter particles after the last segment
2442 // that must be skipped.
2443 if (ResIndex >= DscrDoneCount)
2444 return PEC_STATUS_OK;
2445 }
2446
2447 // Presence of Output Token placeholder is optional
2448 if (Results_p[ResLp].OutputToken_p)
2449 {
2450 // Copy Output Token from EIP-202 to PEC result descriptor
2451 memcpy(Results_p[ResLp].OutputToken_p,
2452 EIP202_RDR_Entries[InterfaceId][ResIndex].Token_p,
2453 IOToken_OutWordCount_Get() * sizeof (uint32_t));
2454
2455 IOToken_PacketLegth_Get(Results_p[ResLp].OutputToken_p,
2456 &Results_p[ResLp].DstPkt_ByteCount);
2457
2458 IOToken_BypassLegth_Get(Results_p[ResLp].OutputToken_p,
2459 &Results_p[ResLp].Bypass_WordCount);
2460 }
2461
2462 // Copy the first EIP-202 result descriptor word, contains
2463 // - Particle byte count,
2464 // - Buffer overflow (BIT_21) and Descriptor overflow (BIT_20) errors
2465 // - First segment (BIT_23) and Last segment (BIT_22) indicators
2466 // - Descriptor overflow word count if BIT_20 is set
2467 Results_p[ResLp].Status1 =
2468 EIP202_RDR_Entries[InterfaceId][ResIndex].ProcControlWord;
2469
2470 *GetCount_p += 1;
2471 ResIndex++;
2472 }
2473
2474 return PEC_STATUS_OK;
2475}
2476
2477
2478#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
2479/*----------------------------------------------------------------------------
2480 * Adapter_PECDev_TestSG
2481 */
2482bool
2483Adapter_PECDev_TestSG(
2484 const unsigned int InterfaceId,
2485 const unsigned int GatherParticleCount,
2486 const unsigned int ScatterParticleCount)
2487{
2488 unsigned int GCount = GatherParticleCount;
2489 unsigned int SCount = ScatterParticleCount;
2490 unsigned int FreeCDR, FreeRDR, FilledCDR, FilledRDR;
2491 EIP202_Ring_Error_t res;
2492
2493 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2494 return false;
2495
2496 if (GCount == 0)
2497 GCount = 1;
2498
2499 if (SCount == 0)
2500 SCount = 1;
2501
2502#ifndef ADAPTER_EIP202_SEPARATE_RINGS
2503 GCount = MAX(GCount, SCount);
2504 SCount = GCount;
2505#endif
2506
2507 if (GCount > ADAPTER_EIP202_MAX_LOGICDESCR ||
2508 SCount > ADAPTER_EIP202_MAX_LOGICDESCR)
2509 return false;
2510
2511 LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Get \n");
2512
2513 res = EIP202_CDR_FillLevel_Get(CDR_IOArea + InterfaceId,
2514 &FilledCDR);
2515 if (res != EIP202_RING_NO_ERROR)
2516 return false;
2517
2518 if (FilledCDR > ADAPTER_EIP202_MAX_PACKETS)
2519 return false;
2520
2521 FreeCDR = ADAPTER_EIP202_MAX_PACKETS - FilledCDR;
2522
2523 LOG_INFO("\n\t\t\t EIP202_RDR_FillLevel_Get \n");
2524
2525 if (EIP202_ContinuousScatter[InterfaceId])
2526 {
2527 return (FreeCDR >= GCount);
2528 }
2529 else
2530 {
2531 res = EIP202_RDR_FillLevel_Get(RDR_IOArea + InterfaceId,
2532 &FilledRDR);
2533 if (res != EIP202_RING_NO_ERROR)
2534 return false;
2535
2536 if (FilledRDR > ADAPTER_EIP202_MAX_PACKETS)
2537 return false;
2538
2539 FreeRDR = ADAPTER_EIP202_MAX_PACKETS - FilledRDR;
2540
2541 return (FreeCDR >= GCount && FreeRDR >= SCount);
2542 }
2543}
2544#endif // ADAPTER_EIP202_ENABLE_SCATTERGATHER
2545
2546
2547#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
2548/* Adapter_PECDev_IRQToInteraceID
2549 */
2550unsigned int
2551Adapter_PECDev_IRQToInferfaceId(
2552 const int nIRQ)
2553{
2554 unsigned int i, IRQ_Nr;
2555
2556 if (nIRQ < 0)
2557 return 0;
2558
2559 IRQ_Nr = (unsigned int)nIRQ;
2560
2561 for (i = 0; i < ADAPTER_EIP202_DEVICE_COUNT; i++)
2562 {
2563 if (IRQ_Nr == EIP202_Devices[i].RDR_IRQ_ID ||
2564 IRQ_Nr == EIP202_Devices[i].CDR_IRQ_ID)
2565 {
2566 return i;
2567 }
2568 }
2569
2570 LOG_CRIT("Adapter_PECDev_IRQToInterfaceId: unknown interrupt %d\n",nIRQ);
2571
2572 return 0;
2573}
2574
2575
2576/*----------------------------------------------------------------------------
2577 * Adapter_PECDev_Enable_ResultIRQ
2578 */
2579void
2580Adapter_PECDev_Enable_ResultIRQ(
2581 const unsigned int InterfaceId)
2582{
2583 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2584 return;
2585
2586 LOG_INFO(
2587 "\n\t\t\t EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable \n");
2588
2589 EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable (
2590 RDR_IOArea + InterfaceId,
2591 false);
2592
2593 LOG_INFO("\n\t\t\t EIP202_RDR_Processed_FillLevel_High_INT_Enable \n");
2594
2595 EIP202_RDR_Processed_FillLevel_High_INT_Enable(
2596 RDR_IOArea + InterfaceId,
2597 ADAPTER_EIP202_DESCRIPTORDONECOUNT,
2598 ADAPTER_EIP202_DESCRIPTORDONETIMEOUT,
2599 true);
2600
2601 Adapter_Interrupt_Enable(EIP202_Devices[InterfaceId].RDR_IRQ_ID,
2602 EIP202_Devices[InterfaceId].RDR_IRQ_Flags);
2603
2604 EIP202_Interrupts[InterfaceId] |= BIT_0;
2605}
2606
2607
2608/*----------------------------------------------------------------------------
2609 * Adapter_PECDev_Disable_ResultIRQ
2610 */
2611void
2612Adapter_PECDev_Disable_ResultIRQ(
2613 const unsigned int InterfaceId)
2614{
2615 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2616 return;
2617
2618 LOG_INFO(
2619 "\n\t\t\t EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable \n");
2620
2621 EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable (
2622 RDR_IOArea + InterfaceId,
2623 false);
2624
2625 Adapter_Interrupt_Disable(EIP202_Devices[InterfaceId].RDR_IRQ_ID,
2626 EIP202_Devices[InterfaceId].RDR_IRQ_Flags);
2627
2628 EIP202_Interrupts[InterfaceId] &= ~BIT_0;
2629}
2630
2631
2632/*----------------------------------------------------------------------------
2633 * Adapter_PECDev_Enable_CommandIRQ
2634 */
2635void
2636Adapter_PECDev_Enable_CommandIRQ(
2637 const unsigned int InterfaceId)
2638{
2639 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2640 return;
2641
2642 LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Low_INT_Enable \n");
2643
2644 EIP202_CDR_FillLevel_Low_INT_Enable(
2645 CDR_IOArea + InterfaceId,
2646 ADAPTER_EIP202_DESCRIPTORDONECOUNT,
2647 ADAPTER_EIP202_DESCRIPTORDONETIMEOUT);
2648
2649 Adapter_Interrupt_Enable(EIP202_Devices[InterfaceId].CDR_IRQ_ID,
2650 EIP202_Devices[InterfaceId].CDR_IRQ_Flags);
2651
2652 EIP202_Interrupts[InterfaceId] |= BIT_1;
2653}
2654
2655
2656/*----------------------------------------------------------------------------
2657 * Adapter_PECDev_Disable_CommandIRQ
2658 */
2659void
2660Adapter_PECDev_Disable_CommandIRQ(
2661 const unsigned int InterfaceId)
2662{
2663 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2664 return;
2665
2666 LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Low_INT_ClearAndDisable \n");
2667
2668 EIP202_CDR_FillLevel_Low_INT_ClearAndDisable(
2669 CDR_IOArea + InterfaceId);
2670
2671 Adapter_Interrupt_Disable(EIP202_Devices[InterfaceId].CDR_IRQ_ID,
2672 EIP202_Devices[InterfaceId].CDR_IRQ_Flags);
2673
2674 EIP202_Interrupts[InterfaceId] &= ~BIT_1;
2675}
2676
2677
2678/*----------------------------------------------------------------------------
2679 * Adapter_PECDev_SetResultHandler
2680 */
2681void Adapter_PECDev_SetResultHandler(
2682 const unsigned int InterfaceId,
2683 Adapter_InterruptHandler_t HandlerFunction)
2684{
2685 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2686 return;
2687
2688 Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].RDR_IRQ_ID,
2689 HandlerFunction);
2690}
2691
2692
2693/*----------------------------------------------------------------------------
2694 * Adapter_PECDev_SetCommandHandler
2695 */
2696void Adapter_PECDev_SetCommandHandler(
2697 const unsigned int InterfaceId,
2698 Adapter_InterruptHandler_t HandlerFunction)
2699{
2700 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2701 return;
2702
2703 Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].CDR_IRQ_ID,
2704 HandlerFunction);
2705}
2706#endif // ADAPTER_EIP202_INTERRUPTS_ENABLE
2707
2708
2709/*----------------------------------------------------------------------------
2710 * Adapter_PECDev_Scatter_Preload
2711 */
2712PEC_Status_t
2713Adapter_PECDev_Scatter_Preload(
2714 const unsigned int InterfaceId,
2715 DMABuf_Handle_t * Handles_p,
2716 const unsigned int HandlesCount)
2717{
2718 unsigned int i;
2719 EIP202_RDR_Prepared_Control_t RDR_Control;
2720 EIP202_Ring_Error_t res;
2721 unsigned int Submitted,FilledRDR;
2722 for (i = 0; i < HandlesCount; i++)
2723 {
2724 DMABuf_Handle_t ParticleHandle = Handles_p[i];
2725 DMAResource_Handle_t DMAHandle = Adapter_DMABuf_Handle2DMAResourceHandle(ParticleHandle);
2726 DMAResource_Record_t * Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
2727
2728 RDR_Control.fFirstSegment = true;
2729#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
2730 RDR_Control.fLastSegment = false;
2731#else
2732 RDR_Control.fLastSegment = true;
2733 // When No scatter gather supported, packets must fit into single buffer.
2734#endif
2735 RDR_Control.PrepSegmentByteCount = Rec_p->Props.Size;
2736 RDR_Control.ExpectedResultWordCount = 0;
2737 EIP202_RDR_Prepared[InterfaceId][i].PrepControlWord =
2738 EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
2739 Adapter_GetPhysAddr(ParticleHandle,
2740 &(EIP202_RDR_Prepared[InterfaceId][i].DstPacketAddr));
2741 }
2742 res = EIP202_RDR_Descriptor_Prepare(RDR_IOArea + InterfaceId,
2743 EIP202_RDR_Prepared[InterfaceId],
2744 HandlesCount,
2745 &Submitted,
2746 &FilledRDR);
2747 if (res != EIP202_RING_NO_ERROR || Submitted != HandlesCount)
2748 {
2749 LOG_CRIT("Adapter_PECDev_Packet_Put: writing prepared descriptors"
2750 "error code %d count=%d expected=%d\n",
2751 res, Submitted, HandlesCount);
2752 return PEC_ERROR_INTERNAL;
2753 }
2754
2755 return PEC_STATUS_OK;
2756}
2757
2758
2759/*----------------------------------------------------------------------------
2760 * Adapter_PECDev_Put_Dump
2761 */
2762void
2763Adapter_PECDev_Put_Dump(
2764 const unsigned int InterfaceId,
2765 const unsigned int FirstSlotId,
2766 const unsigned int LastSlotId,
2767 const bool fDumpCDRAdmin,
2768 const bool fDumpCDRCache)
2769{
2770 void * va;
2771 unsigned int i, CDOffset;
2772 uint32_t Word32;
2773 EIP202_RingAdmin_t RingAdmin;
2774 DMAResource_AddrPair_t Addr_Pair;
2775
2776 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2777 return;
2778
2779 if (FirstSlotId >= ADAPTER_EIP202_MAX_PACKETS ||
2780 LastSlotId >= ADAPTER_EIP202_MAX_PACKETS)
2781 return;
2782
2783 if (FirstSlotId > LastSlotId)
2784 return;
2785
2786 AdapterLib_Ring_EIP202_CDR_Status_Report(InterfaceId);
2787
2788 ZEROINIT(RingAdmin);
2789 EIP202_CDR_Dump(CDR_IOArea + InterfaceId, &RingAdmin);
2790 CDOffset = RingAdmin.DescOffsWordCount;
2791
2792 ZEROINIT(Addr_Pair);
2793 DMAResource_Translate(CDR_Handle[InterfaceId],
2794 DMARES_DOMAIN_HOST,
2795 &Addr_Pair);
2796 va = Addr_Pair.Address_p;
2797
2798 if (fDumpCDRAdmin)
2799 {
2800 void * pa;
2801
2802 ZEROINIT(Addr_Pair);
2803 DMAResource_Translate(CDR_Handle[InterfaceId],
2804 DMARES_DOMAIN_BUS,
2805 &Addr_Pair);
2806 pa = Addr_Pair.Address_p;
2807
2808 LOG_CRIT("\n\tCDR admin data, all sizes in 32-bit words:\n"
2809 "\tSeparate: %s\n"
2810 "\tRing size: %d\n"
2811 "\tDescriptor size: %d\n"
2812 "\tInput ring size: %d\n"
2813 "\tInput ring tail: %d\n"
2814 "\tOutput ring size: %d\n"
2815 "\tOutput ring head: %d\n"
2816 "\tRing phys addr: %p\n"
2817 "\tRing host addr: %p\n",
2818 RingAdmin.fSeparate ? "yes" : "no",
2819 RingAdmin.RingSizeWordCount,
2820 RingAdmin.DescOffsWordCount,
2821 RingAdmin.IN_Size,
2822 RingAdmin.IN_Tail,
2823 RingAdmin.OUT_Size,
2824 RingAdmin.OUT_Head,
2825 pa,
2826 va);
2827 }
2828
2829 LOG_CRIT("\n\tCDR dump, first slot %d, last slot %d\n",
2830 FirstSlotId,
2831 LastSlotId);
2832
2833 for (i = FirstSlotId; i <= LastSlotId; i++)
2834 {
2835 unsigned int j;
2836
2837 LOG_CRIT("\tDescriptor %d:\n", i);
2838 for (j = 0; j < CDOffset; j++)
2839 {
2840 Word32 = DMAResource_Read32(CDR_Handle[InterfaceId],
2841 i * CDOffset + j);
2842
2843 LOG_CRIT("\tCD[%02d] word[%02d] 0x%08x\n",
2844 i,
2845 j,
2846 Word32);
2847 }
2848 }
2849
2850 if (!fDumpCDRCache)
2851 return;
2852
2853 LOG_CRIT("\n\tCDR cache dump, size %d entries\n",
2854 ADAPTER_EIP202_MAX_LOGICDESCR);
2855
2856 for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
2857 {
2858 unsigned int j;
2859
2860 LOG_CRIT("\tDescriptor %d cache:\n", i);
2861
2862 Word32 = EIP202_CDR_Entries[InterfaceId][i].ControlWord;
2863 LOG_CRIT("\tCDC[%02d] word[00] 0x%08x\n", i, Word32);
2864
2865 Word32 = EIP202_CDR_Entries[InterfaceId][i].SrcPacketAddr.Addr;
2866 LOG_CRIT("\tCDC[%02d] word[02] 0x%08x\n", i, Word32);
2867
2868 Word32 = EIP202_CDR_Entries[InterfaceId][i].SrcPacketAddr.UpperAddr;
2869 LOG_CRIT("\tCDC[%02d] word[03] 0x%08x\n", i, Word32);
2870
2871 Word32 = EIP202_CDR_Entries[InterfaceId][i].TokenDataAddr.Addr;
2872 LOG_CRIT("\tCDC[%02d] word[04] 0x%08x\n", i, Word32);
2873
2874 Word32 = EIP202_CDR_Entries[InterfaceId][i].TokenDataAddr.UpperAddr;
2875 LOG_CRIT("\tCDC[%02d] word[05] 0x%08x\n", i, Word32);
2876
2877 if (EIP202_CDR_Entries[InterfaceId][i].Token_p)
2878 for (j = 0; j < IOToken_InWordCount_Get(); j++)
2879 {
2880 Word32 = EIP202_CDR_Entries[InterfaceId][i].Token_p[j];
2881 LOG_CRIT("\tCDC[%02d] word[%02d] 0x%08x\n", i, 6 + j, Word32);
2882 }
2883 }
2884
2885 return;
2886}
2887
2888
2889/*----------------------------------------------------------------------------
2890 * Adapter_PECDev_Get_Dump
2891 */
2892void
2893Adapter_PECDev_Get_Dump(
2894 const unsigned int InterfaceId,
2895 const unsigned int FirstSlotId,
2896 const unsigned int LastSlotId,
2897 const bool fDumpRDRAdmin,
2898 const bool fDumpRDRCache)
2899{
2900 void * va;
2901 unsigned int i, RDOffset;
2902 uint32_t Word32;
2903 EIP202_RingAdmin_t RingAdmin;
2904 DMAResource_AddrPair_t Addr_Pair;
2905
2906 if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
2907 return;
2908
2909 if (FirstSlotId >= ADAPTER_EIP202_MAX_PACKETS ||
2910 LastSlotId >= ADAPTER_EIP202_MAX_PACKETS)
2911 return;
2912
2913 if (FirstSlotId > LastSlotId)
2914 return;
2915
2916 AdapterLib_Ring_EIP202_RDR_Status_Report(InterfaceId);
2917
2918 ZEROINIT(RingAdmin);
2919 EIP202_RDR_Dump(RDR_IOArea + InterfaceId, &RingAdmin);
2920 RDOffset = RingAdmin.DescOffsWordCount;
2921
2922 ZEROINIT(Addr_Pair);
2923 DMAResource_Translate(RDR_Handle[InterfaceId],
2924 DMARES_DOMAIN_HOST,
2925 &Addr_Pair);
2926 va = Addr_Pair.Address_p;
2927
2928 if (fDumpRDRAdmin)
2929 {
2930 void * pa;
2931
2932 ZEROINIT(Addr_Pair);
2933 DMAResource_Translate(RDR_Handle[InterfaceId],
2934 DMARES_DOMAIN_BUS,
2935 &Addr_Pair);
2936 pa = Addr_Pair.Address_p;
2937
2938 LOG_CRIT("\n\tRDR admin data, all sizes in 32-bit words:\n"
2939 "\tSeparate: %s\n"
2940 "\tRing size: %d\n"
2941 "\tDescriptor size: %d\n"
2942 "\tInput ring size: %d\n"
2943 "\tInput ring tail: %d\n"
2944 "\tOutput ring size: %d\n"
2945 "\tOutput ring head: %d\n"
2946 "\tRing phys addr: %p\n"
2947 "\tRing host addr: %p\n",
2948 RingAdmin.fSeparate ? "yes" : "no",
2949 RingAdmin.RingSizeWordCount,
2950 RingAdmin.DescOffsWordCount,
2951 RingAdmin.IN_Size,
2952 RingAdmin.IN_Tail,
2953 RingAdmin.OUT_Size,
2954 RingAdmin.OUT_Head,
2955 pa,
2956 va);
2957 }
2958
2959 LOG_CRIT("\n\tRDR dump, first slot %d, last slot %d\n",
2960 FirstSlotId,
2961 LastSlotId);
2962
2963 for (i = FirstSlotId; i <= LastSlotId; i++)
2964 {
2965 unsigned int j;
2966
2967 LOG_CRIT("\tDescriptor %d:\n", i);
2968 for (j = 0; j < RDOffset; j++)
2969 {
2970 Word32 = DMAResource_Read32(RDR_Handle[InterfaceId],
2971 i * RDOffset + j);
2972
2973 LOG_CRIT("\tRD[%02d] word[%02d] 0x%08x\n",
2974 i,
2975 j,
2976 Word32);
2977 }
2978 }
2979
2980 if (!fDumpRDRCache)
2981 return;
2982
2983 LOG_CRIT("\n\tRDR cache dump, size %d entries\n",
2984 ADAPTER_EIP202_MAX_LOGICDESCR);
2985
2986 for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
2987 {
2988 unsigned int j;
2989
2990 LOG_CRIT("\tDescriptor %d cache:\n", i);
2991
2992 Word32 = EIP202_RDR_Entries[InterfaceId][i].ProcControlWord;
2993 LOG_CRIT("\tRDC[%02d] word[00] 0x%08x\n", i, Word32);
2994
2995 Word32 = EIP202_RDR_Entries[InterfaceId][i].DstPacketAddr.Addr;
2996 LOG_CRIT("\tRDC[%02d] word[02] 0x%08x\n", i, Word32);
2997
2998 Word32 = EIP202_RDR_Entries[InterfaceId][i].DstPacketAddr.UpperAddr;
2999 LOG_CRIT("\tRDC[%02d] word[03] 0x%08x\n", i, Word32);
3000
3001 for (j = 0; j < IOToken_OutWordCount_Get(); j++)
3002 {
3003 Word32 = EIP202_RDR_Entries[InterfaceId][i].Token_p[j];
3004 LOG_CRIT("\tRDC[%02d] word[%02d] 0x%08x\n", i, 4 + j, Word32);
3005 }
3006 }
3007
3008 return;
3009}
3010
3011
3012/* end of file adapter_ring_eip202.c */