1 /**
2  * @file IxNpeMhSend.c
3  *
4  * @author Intel Corporation
5  * @date 18 Jan 2002
6  *
7  * @brief This file contains the implementation of the private API for the
8  * Send module.
9  *
10  *
11  * @par
12  * IXP400 SW Release version 2.0
13  *
14  * -- Copyright Notice --
15  *
16  * @par
17  * Copyright 2001-2005, Intel Corporation.
18  * All rights reserved.
19  *
20  * @par
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions
23  * are met:
24  * 1. Redistributions of source code must retain the above copyright
25  *    notice, this list of conditions and the following disclaimer.
26  * 2. Redistributions in binary form must reproduce the above copyright
27  *    notice, this list of conditions and the following disclaimer in the
28  *    documentation and/or other materials provided with the distribution.
29  * 3. Neither the name of the Intel Corporation nor the names of its contributors
30  *    may be used to endorse or promote products derived from this software
31  *    without specific prior written permission.
32  *
33  * @par
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
35  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  *
46  * @par
47  * -- End of Copyright Notice --
48 */
49 
50 /*
51  * Put the system defined include files required.
52  */
53 
54 
55 /*
56  * Put the user defined include files required.
57  */
58 
59 #include "IxNpeMhMacros_p.h"
60 
61 #include "IxNpeMhConfig_p.h"
62 #include "IxNpeMhSend_p.h"
63 #include "IxNpeMhSolicitedCbMgr_p.h"
64 
65 /*
66  * #defines and macros used in this file.
67  */
68 
69 /**
70  * @def IX_NPEMH_INFIFO_RETRY_DELAY_US
71  *
72  * @brief Amount of time (uSecs) to delay between retries
73  * while inFIFO is Full when attempting to send a message
74  */
75 #define IX_NPEMH_INFIFO_RETRY_DELAY_US (1)
76 
77 
78 /*
79  * Typedefs whose scope is limited to this file.
80  */
81 
82 /**
83  * @struct IxNpeMhSendStats
84  *
85  * @brief This structure is used to maintain statistics for the Send
86  * module.
87  */
88 
89 typedef struct
90 {
91     UINT32 sends;             /**< send invocations */
92     UINT32 sendWithResponses; /**< send with response invocations */
93     UINT32 queueFulls;        /**< fifo queue full occurrences */
94     UINT32 queueFullRetries;  /**< fifo queue full retry occurrences */
95     UINT32 maxQueueFullRetries; /**< max fifo queue full retries */
96     UINT32 callbackFulls;     /**< callback list full occurrences */
97 } IxNpeMhSendStats;
98 
99 /*
100  * Variable declarations global to this file only.  Externs are followed by
101  * static variables.
102  */
103 
104 PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES];
105 
106 /*
107  * Extern function prototypes.
108  */
109 
110 /*
111  * Static function prototypes.
112  */
113 PRIVATE
114 BOOL ixNpeMhSendInFifoIsFull(
115     IxNpeMhNpeId npeId,
116     UINT32 maxSendRetries);
117 
118 /*
119  * Function definition: ixNpeMhSendInFifoIsFull
120  */
121 
122 PRIVATE
ixNpeMhSendInFifoIsFull(IxNpeMhNpeId npeId,UINT32 maxSendRetries)123 BOOL ixNpeMhSendInFifoIsFull(
124     IxNpeMhNpeId npeId,
125     UINT32 maxSendRetries)
126 {
127     BOOL isFull = FALSE;
128     UINT32 numRetries = 0;
129 
130     /* check the NPE's inFIFO */
131     isFull = ixNpeMhConfigInFifoIsFull (npeId);
132 
133     /* we retry a few times, just to give the NPE a chance to read from */
134     /* the FIFO if the FIFO is currently full */
135     while (isFull && (numRetries++ < maxSendRetries))
136     {
137 	if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT)
138 	{
139 	    /* Delay here for as short a time as possible (1 us). */
140 	    /* Adding a delay here should ensure we are not hogging */
141 	    /* the AHB bus while we are retrying                    */
142 	    ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
143 	}
144 
145         /* re-check the NPE's inFIFO */
146         isFull = ixNpeMhConfigInFifoIsFull (npeId);
147 
148         /* update statistical info */
149         ixNpeMhSendStats[npeId].queueFullRetries++;
150     }
151 
152     /* record the highest number of retries that occurred */
153     if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries)
154     {
155 	ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries;
156     }
157 
158     if (isFull)
159     {
160         /* update statistical info */
161         ixNpeMhSendStats[npeId].queueFulls++;
162     }
163 
164     return isFull;
165 }
166 
167 /*
168  * Function definition: ixNpeMhSendMessageSend
169  */
170 
ixNpeMhSendMessageSend(IxNpeMhNpeId npeId,IxNpeMhMessage message,UINT32 maxSendRetries)171 IX_STATUS ixNpeMhSendMessageSend (
172     IxNpeMhNpeId npeId,
173     IxNpeMhMessage message,
174     UINT32 maxSendRetries)
175 {
176     IX_STATUS status;
177 
178     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
179                      "ixNpeMhSendMessageSend\n");
180 
181     /* update statistical info */
182     ixNpeMhSendStats[npeId].sends++;
183 
184     /* check if the NPE's inFIFO is full - if so return an error */
185     if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
186     {
187         IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
188         return IX_FAIL;
189     }
190 
191     /* write the message to the NPE's inFIFO */
192     status = ixNpeMhConfigInFifoWrite (npeId, message);
193 
194     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
195                      "ixNpeMhSendMessageSend\n");
196 
197     return status;
198 }
199 
200 /*
201  * Function definition: ixNpeMhSendMessageWithResponseSend
202  */
203 
ixNpeMhSendMessageWithResponseSend(IxNpeMhNpeId npeId,IxNpeMhMessage message,IxNpeMhMessageId solicitedMessageId,IxNpeMhCallback solicitedCallback,UINT32 maxSendRetries)204 IX_STATUS ixNpeMhSendMessageWithResponseSend (
205     IxNpeMhNpeId npeId,
206     IxNpeMhMessage message,
207     IxNpeMhMessageId solicitedMessageId,
208     IxNpeMhCallback solicitedCallback,
209     UINT32 maxSendRetries)
210 {
211     IX_STATUS status = IX_SUCCESS;
212 
213     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
214                      "ixNpeMhSendMessageWithResponseSend\n");
215 
216     /* update statistical info */
217     ixNpeMhSendStats[npeId].sendWithResponses++;
218 
219     /* sr: this sleep will call the receive routine (no interrupts used!!!) */
220     ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
221 
222     /* check if the NPE's inFIFO is full - if so return an error */
223     if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
224     {
225         IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
226         return IX_FAIL;
227     }
228 
229     /* save the solicited callback */
230     status = ixNpeMhSolicitedCbMgrCallbackSave (
231         npeId, solicitedMessageId, solicitedCallback);
232     if (status != IX_SUCCESS)
233     {
234         IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n");
235 
236         /* update statistical info */
237         ixNpeMhSendStats[npeId].callbackFulls++;
238 
239         return status;
240     }
241 
242     /* write the message to the NPE's inFIFO */
243     status = ixNpeMhConfigInFifoWrite (npeId, message);
244 
245     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
246                      "ixNpeMhSendMessageWithResponseSend\n");
247 
248     return status;
249 }
250 
251 /*
252  * Function definition: ixNpeMhSendShow
253  */
254 
ixNpeMhSendShow(IxNpeMhNpeId npeId)255 void ixNpeMhSendShow (
256     IxNpeMhNpeId npeId)
257 {
258     /* show the message send invocation counter */
259     IX_NPEMH_SHOW ("Send invocations",
260                    ixNpeMhSendStats[npeId].sends);
261 
262     /* show the message send with response invocation counter */
263     IX_NPEMH_SHOW ("Send with response invocations",
264                    ixNpeMhSendStats[npeId].sendWithResponses);
265 
266     /* show the fifo queue full occurrence counter */
267     IX_NPEMH_SHOW ("Fifo queue full occurrences",
268                    ixNpeMhSendStats[npeId].queueFulls);
269 
270     /* show the fifo queue full retry occurrence counter */
271     IX_NPEMH_SHOW ("Fifo queue full retry occurrences",
272                    ixNpeMhSendStats[npeId].queueFullRetries);
273 
274     /* show the fifo queue full maximum retries counter */
275     IX_NPEMH_SHOW ("Maximum fifo queue full retries",
276                    ixNpeMhSendStats[npeId].maxQueueFullRetries);
277 
278     /* show the callback list full occurrence counter */
279     IX_NPEMH_SHOW ("Solicited callback list full occurrences",
280                    ixNpeMhSendStats[npeId].callbackFulls);
281 }
282 
283 /*
284  * Function definition: ixNpeMhSendShowReset
285  */
286 
ixNpeMhSendShowReset(IxNpeMhNpeId npeId)287 void ixNpeMhSendShowReset (
288     IxNpeMhNpeId npeId)
289 {
290     /* reset the message send invocation counter */
291     ixNpeMhSendStats[npeId].sends = 0;
292 
293     /* reset the message send with response invocation counter */
294     ixNpeMhSendStats[npeId].sendWithResponses = 0;
295 
296     /* reset the fifo queue full occurrence counter */
297     ixNpeMhSendStats[npeId].queueFulls = 0;
298 
299     /* reset the fifo queue full retry occurrence counter */
300     ixNpeMhSendStats[npeId].queueFullRetries = 0;
301 
302     /* reset the max fifo queue full retries counter */
303     ixNpeMhSendStats[npeId].maxQueueFullRetries = 0;
304 
305     /* reset the callback list full occurrence counter */
306     ixNpeMhSendStats[npeId].callbackFulls = 0;
307 }
308