blob: 57c8be30e51ded9e273443c72a82eccad0670116 [file] [log] [blame]
Wolfgang Denkba94a1b2006-05-30 15:56:48 +02001/**
2 * @file IxNpeMhReceive.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 * Receive 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#include "IxOsal.h"
59#include "IxNpeMhMacros_p.h"
60#include "IxNpeMhConfig_p.h"
61#include "IxNpeMhReceive_p.h"
62#include "IxNpeMhSolicitedCbMgr_p.h"
63#include "IxNpeMhUnsolicitedCbMgr_p.h"
64
65/*
66 * #defines and macros used in this file.
67 */
68
69/*
70 * Typedefs whose scope is limited to this file.
71 */
72
73/**
74 * @struct IxNpeMhReceiveStats
75 *
76 * @brief This structure is used to maintain statistics for the Receive
77 * module.
78 */
79
80typedef struct
81{
82 UINT32 isrs; /**< receive ISR invocations */
83 UINT32 receives; /**< receive messages invocations */
84 UINT32 messages; /**< messages received */
85 UINT32 solicited; /**< solicited messages received */
86 UINT32 unsolicited; /**< unsolicited messages received */
87 UINT32 callbacks; /**< callbacks invoked */
88} IxNpeMhReceiveStats;
89
90/*
91 * Variable declarations global to this file only. Externs are followed by
92 * static variables.
93 */
94
95PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES];
96
97/*
98 * Extern function prototypes.
99 */
100
101/*
102 * Static function prototypes.
103 */
104PRIVATE
105void ixNpeMhReceiveIsr (int npeId);
106
107PRIVATE
108void ixNpeMhReceiveIsr (int npeId)
109{
110 int lockKey;
111
112 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
113 "ixNpeMhReceiveIsr\n");
114
115 lockKey = ixOsalIrqLock ();
116
117 /* invoke the message receive routine to get messages from the NPE */
118 ixNpeMhReceiveMessagesReceive (npeId);
119
120 /* update statistical info */
121 ixNpeMhReceiveStats[npeId].isrs++;
122
123 ixOsalIrqUnlock (lockKey);
124
125 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
126 "ixNpeMhReceiveIsr\n");
127}
128
129/*
130 * Function definition: ixNpeMhReceiveInitialize
131 */
132
133void ixNpeMhReceiveInitialize (void)
134{
135 IxNpeMhNpeId npeId = 0;
136
137 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
138 "ixNpeMhReceiveInitialize\n");
139
140 /* for each NPE ... */
141 for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
142 {
143 /* register our internal ISR for the NPE to handle "outFIFO not */
144 /* empty" interrupts */
145 ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr);
146 }
147
148 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
149 "ixNpeMhReceiveInitialize\n");
150}
151
152/*
153 * Function definition: ixNpeMhReceiveMessagesReceive
154 */
155
156IX_STATUS ixNpeMhReceiveMessagesReceive (
157 IxNpeMhNpeId npeId)
158{
159 IxNpeMhMessage message = { { 0, 0 } };
160 IxNpeMhMessageId messageId = 0;
161 IxNpeMhCallback callback = NULL;
162 IX_STATUS status;
163
164 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
165 "ixNpeMhReceiveMessagesReceive\n");
166
167 /* update statistical info */
168 ixNpeMhReceiveStats[npeId].receives++;
169
170 /* while the NPE has messages in its outFIFO */
171 while (!ixNpeMhConfigOutFifoIsEmpty (npeId))
172 {
173 /* read a message from the NPE's outFIFO */
174 status = ixNpeMhConfigOutFifoRead (npeId, &message);
175
176 if (IX_SUCCESS != status)
177 {
178 return status;
179 }
180
181 /* get the ID of the message */
182 messageId = ixNpeMhConfigMessageIdGet (message);
183
184 IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG,
185 "Received message from NPE %d with ID 0x%02X\n",
186 npeId, messageId);
187
188 /* update statistical info */
189 ixNpeMhReceiveStats[npeId].messages++;
190
191 /* try to find a matching unsolicited callback for this message. */
192
193 /* we assume the message is unsolicited. only if there is no */
194 /* unsolicited callback for this message type do we assume the */
195 /* message is solicited. it is much faster to check for an */
196 /* unsolicited callback, so doing this check first should result */
197 /* in better performance. */
198
199 ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
200 npeId, messageId, &callback);
201
202 if (callback != NULL)
203 {
204 IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
205 "Found matching unsolicited callback\n");
206
207 /* update statistical info */
208 ixNpeMhReceiveStats[npeId].unsolicited++;
209 }
210
211 /* if no unsolicited callback was found try to find a matching */
212 /* solicited callback for this message */
213 if (callback == NULL)
214 {
215 ixNpeMhSolicitedCbMgrCallbackRetrieve (
216 npeId, messageId, &callback);
217
218 if (callback != NULL)
219 {
220 IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
221 "Found matching solicited callback\n");
222
223 /* update statistical info */
224 ixNpeMhReceiveStats[npeId].solicited++;
225 }
226 }
227
228 /* if a callback (either unsolicited or solicited) was found */
229 if (callback != NULL)
230 {
231 /* invoke the callback to pass the message back to the client */
232 callback (npeId, message);
233
234 /* update statistical info */
235 ixNpeMhReceiveStats[npeId].callbacks++;
236 }
237 else /* no callback (neither unsolicited nor solicited) was found */
238 {
239 IX_NPEMH_TRACE2 (IX_NPEMH_WARNING,
240 "No matching callback for NPE %d"
241 " and ID 0x%02X, discarding message\n",
242 npeId, messageId);
243
244 /* the message will be discarded. this is normal behaviour */
245 /* if the client passes a NULL solicited callback when */
246 /* sending a message. this indicates that the client is not */
247 /* interested in receiving the response. alternatively a */
248 /* NULL callback here may signify an unsolicited message */
249 /* with no appropriate registered callback. */
250 }
251 }
252
253 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
254 "ixNpeMhReceiveMessagesReceive\n");
255
256 return IX_SUCCESS;
257}
258
259/*
260 * Function definition: ixNpeMhReceiveShow
261 */
262
263void ixNpeMhReceiveShow (
264 IxNpeMhNpeId npeId)
265{
266 /* show the ISR invocation counter */
267 IX_NPEMH_SHOW ("Receive ISR invocations",
268 ixNpeMhReceiveStats[npeId].isrs);
269
270 /* show the receive message invocation counter */
271 IX_NPEMH_SHOW ("Receive messages invocations",
272 ixNpeMhReceiveStats[npeId].receives);
273
274 /* show the message received counter */
275 IX_NPEMH_SHOW ("Messages received",
276 ixNpeMhReceiveStats[npeId].messages);
277
278 /* show the solicited message counter */
279 IX_NPEMH_SHOW ("Solicited messages received",
280 ixNpeMhReceiveStats[npeId].solicited);
281
282 /* show the unsolicited message counter */
283 IX_NPEMH_SHOW ("Unsolicited messages received",
284 ixNpeMhReceiveStats[npeId].unsolicited);
285
286 /* show the callback invoked counter */
287 IX_NPEMH_SHOW ("Callbacks invoked",
288 ixNpeMhReceiveStats[npeId].callbacks);
289
290 /* show the message discarded counter */
291 IX_NPEMH_SHOW ("Received messages discarded",
292 (ixNpeMhReceiveStats[npeId].messages -
293 ixNpeMhReceiveStats[npeId].callbacks));
294}
295
296/*
297 * Function definition: ixNpeMhReceiveShowReset
298 */
299
300void ixNpeMhReceiveShowReset (
301 IxNpeMhNpeId npeId)
302{
303 /* reset the ISR invocation counter */
304 ixNpeMhReceiveStats[npeId].isrs = 0;
305
306 /* reset the receive message invocation counter */
307 ixNpeMhReceiveStats[npeId].receives = 0;
308
309 /* reset the message received counter */
310 ixNpeMhReceiveStats[npeId].messages = 0;
311
312 /* reset the solicited message counter */
313 ixNpeMhReceiveStats[npeId].solicited = 0;
314
315 /* reset the unsolicited message counter */
316 ixNpeMhReceiveStats[npeId].unsolicited = 0;
317
318 /* reset the callback invoked counter */
319 ixNpeMhReceiveStats[npeId].callbacks = 0;
320}