1/** 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} 321