mac_rx.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428
  1. /**************************************************************************************************
  2. Filename: mac_rx.c
  3. Revised: $Date: 2007-10-08 14:05:36 -0700 (Mon, 08 Oct 2007) $
  4. Revision: $Revision: 15624 $
  5. Description: Describe the purpose and contents of the file.
  6. Copyright 2006-2012 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /* ------------------------------------------------------------------------------------------------
  34. * Includes
  35. * ------------------------------------------------------------------------------------------------
  36. */
  37. /* hal */
  38. #include "hal_defs.h"
  39. #include "hal_types.h"
  40. /* OSAL */
  41. #include "OSAL.h"
  42. /* high-level */
  43. #include "mac_high_level.h"
  44. #include "mac_spec.h"
  45. /* MAC security */
  46. #include "mac_security.h"
  47. /* exported low-level */
  48. #include "mac_low_level.h"
  49. /* low-level specific */
  50. #include "mac_rx.h"
  51. #include "mac_tx.h"
  52. #include "mac_rx_onoff.h"
  53. #include "mac_radio.h"
  54. /* target specific */
  55. #include "mac_radio_defs.h"
  56. #include "mac_autopend.h"
  57. /* debug */
  58. #include "mac_assert.h"
  59. /* ------------------------------------------------------------------------------------------------
  60. * Defines
  61. * ------------------------------------------------------------------------------------------------
  62. */
  63. #define MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT 16 /* adjustable to tune performance */
  64. /* receive FIFO bytes needed to start a valid receive (see function rxStartIsr for details) */
  65. #define RX_THRESHOLD_START_LEN (MAC_PHY_PHR_LEN + \
  66. MAC_FCF_FIELD_LEN + \
  67. MAC_SEQ_NUM_FIELD_LEN + \
  68. MAC_FCS_FIELD_LEN)
  69. /* maximum size of addressing fields (note: command frame identifier processed as part of address) */
  70. #define MAX_ADDR_FIELDS_LEN ((MAC_EXT_ADDR_FIELD_LEN + MAC_PAN_ID_FIELD_LEN) * 2)
  71. /* addressing mode reserved value */
  72. #define ADDR_MODE_RESERVERED 1
  73. /* length of command frame identifier */
  74. #define CMD_FRAME_ID_LEN 1
  75. /* packet size mask is equal to the maximum value */
  76. #define PHY_PACKET_SIZE_MASK 0x7F
  77. /* value for promiscuous off, must not conflict with other mode variants from separate include files */
  78. #define PROMISCUOUS_MODE_OFF 0x00
  79. /* bit of proprietary FCS format that indicates if the CRC is OK */
  80. #define PROPRIETARY_FCS_CRC_OK_BIT 0x80
  81. /* dummy length value for unused entry in lookup table */
  82. #define DUMMY_LEN 0xBE
  83. /* value for rxThresholdIntState */
  84. #define RX_THRESHOLD_INT_STATE_INACTIVE 0
  85. #define RX_THRESHOLD_INT_STATE_ACTIVE 1
  86. #define RX_THRESHOLD_INT_STATE_RESET 2
  87. /* ------------------------------------------------------------------------------------------------
  88. * Macros
  89. * ------------------------------------------------------------------------------------------------
  90. */
  91. #define MEM_ALLOC(x) macDataRxMemAlloc(x)
  92. #define MEM_FREE(x) macDataRxMemFree((uint8 **)x)
  93. /*
  94. * Macro for encoding frame control information into internal flags format.
  95. * Parameter is pointer to the frame. NOTE! If either the internal frame
  96. * format *or* the specification changes, this macro will need to be modified.
  97. */
  98. #define INTERNAL_FCF_FLAGS(p) ((((p)[1] >> 4) & 0x03) | ((p)[0] & 0x78))
  99. /*
  100. * The radio replaces the actual FCS with different information. This proprietary FCS is
  101. * the same length as the original and includes:
  102. * 1) the RSSI value
  103. * 2) the average correlation value (used for LQI)
  104. * 3) a CRC passed bit
  105. *
  106. * These macros decode the proprietary FCS. The macro parameter is a pointer to the two byte FCS.
  107. */
  108. #define PROPRIETARY_FCS_RSSI(p) ((int8)((p)[0]))
  109. #define PROPRIETARY_FCS_CRC_OK(p) ((p)[1] & PROPRIETARY_FCS_CRC_OK_BIT)
  110. #define PROPRIETARY_FCS_CORRELATION_VALUE(p) ((p)[1] & ~PROPRIETARY_FCS_CRC_OK_BIT)
  111. /*
  112. * Macros for security control field.
  113. */
  114. #define SECURITY_LEVEL(s) (s & 0x07)
  115. #define KEY_IDENTIFIER_MODE(s) ((s & 0x18) >> 3)
  116. #define SECURITY_CONTROL_RESERVED(s) ((s & 0xE0) >> 5)
  117. /* ------------------------------------------------------------------------------------------------
  118. * Global Variables
  119. * ------------------------------------------------------------------------------------------------
  120. */
  121. uint8 macRxActive;
  122. uint8 macRxFilter;
  123. uint8 macRxOutgoingAckFlag;
  124. /* ------------------------------------------------------------------------------------------------
  125. * Local Constants
  126. * ------------------------------------------------------------------------------------------------
  127. */
  128. static const uint8 CODE macRxAddrLen[] =
  129. {
  130. 0, /* no address */
  131. DUMMY_LEN, /* reserved */
  132. MAC_PAN_ID_FIELD_LEN + MAC_SHORT_ADDR_FIELD_LEN, /* short address + pan id */
  133. MAC_PAN_ID_FIELD_LEN + MAC_EXT_ADDR_FIELD_LEN /* extended address + pan id */
  134. };
  135. /* ------------------------------------------------------------------------------------------------
  136. * Local Prototypes
  137. * ------------------------------------------------------------------------------------------------
  138. */
  139. static void rxHaltCleanupFinalStep(void);
  140. static void rxStartIsr(void);
  141. static void rxAddrIsr(void);
  142. #ifdef MAC_SECURITY
  143. static void rxSecurityHdrIsr(void);
  144. #endif
  145. static void rxPayloadIsr(void);
  146. static void rxDiscardIsr(void);
  147. static void rxFcsIsr(void);
  148. static void rxPrepPayload(void);
  149. static void rxDiscardFrame(void);
  150. static void rxDone(void);
  151. static void rxPostRxUpdates(void);
  152. /* ------------------------------------------------------------------------------------------------
  153. * Local Variables
  154. * ------------------------------------------------------------------------------------------------
  155. */
  156. static void (* pFuncRxState)(void);
  157. static macRx_t * pRxBuf;
  158. static uint8 rxBuf[MAC_PHY_PHR_LEN + MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN];
  159. static uint8 rxUnreadLen;
  160. static uint8 rxNextLen;
  161. static uint8 rxPayloadLen;
  162. static uint8 rxFilter;
  163. static uint8 rxPromiscuousMode;
  164. static uint8 rxIsrActiveFlag;
  165. static uint8 rxResetFlag;
  166. static uint8 rxFifoOverflowCount;
  167. #ifdef PACKET_FILTER_STATS
  168. uint32 rxCrcFailure = 0;
  169. uint32 rxCrcSuccess = 0;
  170. #endif /* PACKET_FILTER_STATS */
  171. #ifdef CC2591_COMPRESSION_WORKAROUND
  172. void macRxResetRssi(void);
  173. #endif
  174. /**************************************************************************************************
  175. * @fn macRxInit
  176. *
  177. * @brief Initialize receive variable states.
  178. *
  179. * @param none
  180. *
  181. * @return none
  182. **************************************************************************************************
  183. */
  184. MAC_INTERNAL_API void macRxInit(void)
  185. {
  186. macRxFilter = RX_FILTER_OFF;
  187. rxPromiscuousMode = PROMISCUOUS_MODE_OFF;
  188. pRxBuf = NULL; /* required for macRxReset() to function correctly */
  189. macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
  190. pFuncRxState = &rxStartIsr;
  191. macRxOutgoingAckFlag = 0;
  192. rxIsrActiveFlag = 0;
  193. rxResetFlag = 0;
  194. rxFifoOverflowCount = 0;
  195. }
  196. /**************************************************************************************************
  197. * @fn macRxRadioPowerUpInit
  198. *
  199. * @brief Initialization for after radio first powers up.
  200. *
  201. * @param none
  202. *
  203. * @return none
  204. **************************************************************************************************
  205. */
  206. MAC_INTERNAL_API void macRxRadioPowerUpInit(void)
  207. {
  208. /* set threshold at initial value */
  209. MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
  210. /* clear any accidental threshold interrupt that happened as part of power up sequence */
  211. MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG();
  212. /* enable threshold interrupts */
  213. MAC_RADIO_ENABLE_RX_THRESHOLD_INTERRUPT();
  214. }
  215. /**************************************************************************************************
  216. * @fn macRxTxReset
  217. *
  218. * @brief Reset the receive state.
  219. *
  220. * @param none
  221. *
  222. * @return none
  223. **************************************************************************************************
  224. */
  225. MAC_INTERNAL_API void macRxTxReset(void)
  226. {
  227. /* forces receiver off, cleans up by calling macRxHaltCleanup() and macTxHaltCleanup() */
  228. macRxHardDisable();
  229. /*
  230. * Note : transmit does not require any reset logic
  231. * beyond what macRxHardDisable() provides.
  232. */
  233. /* restore deault filter mode to off */
  234. macRxFilter = RX_FILTER_OFF;
  235. /* return promiscuous mode to default off state */
  236. macRxPromiscuousMode(MAC_PROMISCUOUS_MODE_OFF);
  237. }
  238. /**************************************************************************************************
  239. * @fn macRxHaltCleanup
  240. *
  241. * @brief Cleanup up the receive logic after receiver is forced off.
  242. *
  243. * @param none
  244. *
  245. * @return none
  246. **************************************************************************************************
  247. */
  248. MAC_INTERNAL_API void macRxHaltCleanup(void)
  249. {
  250. rxResetFlag = 1;
  251. if (!rxIsrActiveFlag)
  252. {
  253. rxHaltCleanupFinalStep();
  254. rxResetFlag = 0;
  255. }
  256. }
  257. /*=================================================================================================
  258. * @fn rxHaltCleanupFinalStep
  259. *
  260. * @brief Required cleanup if receiver is halted in the middle of a receive.
  261. *
  262. * @param none
  263. *
  264. * @return none
  265. *=================================================================================================
  266. */
  267. static void rxHaltCleanupFinalStep(void)
  268. {
  269. /* cancel any upcoming ACK transmit complete callback */
  270. MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
  271. /* set start of frame threshold */
  272. MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
  273. /* flush the receive FIFO */
  274. MAC_RADIO_FLUSH_RX_FIFO();
  275. /* clear any receive interrupt that happened to squeak through */
  276. MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG();
  277. /* if data buffer has been allocated, free it */
  278. if (pRxBuf != NULL)
  279. {
  280. MEM_FREE((uint8 **)&pRxBuf);
  281. }
  282. /* MEM_FREE() sets parameter to NULL. */
  283. pFuncRxState = &rxStartIsr;
  284. /* if receive was active, perform the post receive updates */
  285. if (macRxActive || macRxOutgoingAckFlag)
  286. {
  287. macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
  288. macRxOutgoingAckFlag = 0;
  289. rxPostRxUpdates();
  290. }
  291. }
  292. /**************************************************************************************************
  293. * @fn macRxThresholdIsr
  294. *
  295. * @brief Interrupt service routine called when bytes in FIFO reach threshold value.
  296. * It implements a state machine for receiving a packet.
  297. *
  298. * @param none
  299. *
  300. * @return none
  301. **************************************************************************************************
  302. */
  303. MAC_INTERNAL_API void macRxThresholdIsr(void)
  304. {
  305. /* if currently reseting, do not execute receive ISR logic */
  306. if (rxResetFlag)
  307. {
  308. return;
  309. }
  310. /*
  311. * Call the function that handles the current receive state.
  312. * A flag is set for the duration of the call to indicate
  313. * the ISR is executing. This is necessary for the reset
  314. * logic so it does not perform a reset in the middle of
  315. * executing the ISR.
  316. */
  317. rxIsrActiveFlag = 1;
  318. (*pFuncRxState)();
  319. rxIsrActiveFlag = 0;
  320. /* if a reset occurred during the ISR, peform cleanup here */
  321. if (rxResetFlag)
  322. {
  323. rxHaltCleanupFinalStep();
  324. rxResetFlag = 0;
  325. }
  326. }
  327. /*=================================================================================================
  328. * @fn rxStartIsr
  329. *
  330. * @brief First ISR state for receiving a packet - compute packet length, allocate
  331. * buffer, initialize buffer. Acknowledgements are handled immediately without
  332. * allocating a buffer.
  333. *
  334. * @param none
  335. *
  336. * @return none
  337. *=================================================================================================
  338. */
  339. static void rxStartIsr(void)
  340. {
  341. uint8 addrLen;
  342. uint8 ackWithPending;
  343. uint8 dstAddrMode;
  344. uint8 srcAddrMode;
  345. uint8 mhrLen = 0;
  346. MAC_ASSERT(!macRxActive); /* receive on top of receive */
  347. /* indicate rx is active */
  348. macRxActive = MAC_RX_ACTIVE_STARTED;
  349. /*
  350. * For bullet proof functionality, need to see if the receiver was just turned off.
  351. * The logic to request turning off the receiver, disables interrupts and then checks
  352. * the value of macRxActive. If it is TRUE, the receiver will not be turned off.
  353. *
  354. * There is a small hole though. It's possible to attempt turning off the receiver
  355. * in the window from when the receive interrupt fires and the point where macRxActive
  356. * is set to TRUE. To plug this hole, the on/off status must be tested *after*
  357. * macRxActive has been set. If the receiver is off at this point, there is nothing
  358. * in the RX fifo and the receive is simply aborted.
  359. *
  360. * Also, there are some considerations in case a hard disable just happened. Usually,
  361. * the receiver will just be off at this point after a hard disable. The check described
  362. * above will account for this case too. However, if a hard disable were immediately
  363. * followed by an enable, the receiver would be on. To catch this case, the receive
  364. * FIFO is also tested to see if it is empty. Recovery is identical to the other cases.
  365. */
  366. if (!macRxOnFlag || MAC_RADIO_RX_FIFO_IS_EMPTY())
  367. {
  368. /* reset active flag */
  369. macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
  370. /*
  371. * To be absolutely bulletproof, must make sure no transmit queue'ed up during
  372. * the tiny, tiny window when macRxActive was not zero.
  373. */
  374. rxPostRxUpdates();
  375. /* return immediately from here */
  376. return;
  377. }
  378. /*
  379. * If interrupts are held off for too long it's possible the previous "transmit done"
  380. * callback is pending. If this is the case, it needs to be completed before
  381. * continuing with the receive logic.
  382. */
  383. MAC_RADIO_FORCE_TX_DONE_IF_PENDING();
  384. /*
  385. * It's possible receive logic is still waiting for confirmation of an ACK that went out
  386. * for the previous receive. This is OK but the callback needs to be canceled at this point.
  387. * That callback execute receive cleanup logic that will run at the completion
  388. * of *this* receive. Also, it is important the flag for the outgoing ACK to be cleared.
  389. */
  390. MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
  391. macRxOutgoingAckFlag = 0;
  392. /*
  393. * Make a module-local copy of macRxFilter. This prevents the selected
  394. * filter from changing in the middle of a receive.
  395. */
  396. rxFilter = macRxFilter;
  397. /*-------------------------------------------------------------------------------
  398. * Read initial frame information from FIFO.
  399. *
  400. * This code is not triggered until the following are in the RX FIFO:
  401. * frame length - one byte containing length of MAC frame (excludes this field)
  402. * frame control field - two bytes defining frame type, addressing fields, control flags
  403. * sequence number - one byte unique sequence identifier
  404. * additional two bytes - these bytes are available in case the received frame is an ACK,
  405. * if so, the frame can be verified and responded to immediately,
  406. * if not an ACK, these bytes will be processed normally
  407. */
  408. /* read frame length, frame control field, and sequence number from FIFO */
  409. MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_PHY_PHR_LEN + MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN);
  410. /* bytes to read from FIFO equals frame length minus length of MHR fields just read from FIFO */
  411. rxUnreadLen = (rxBuf[0] & PHY_PACKET_SIZE_MASK) - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN;
  412. /*
  413. * Workaround for chip bug #1547. The receive buffer can sometimes be corrupted by hardware.
  414. * This usually occurs under heavy traffic. If a corrupted receive buffer is detected
  415. * the entire receive buffer is flushed.
  416. *
  417. * In the case that this workaround is not needed, an assert is used to make sure the
  418. * receive length field is not corrupted. This is important because a corrupted receive
  419. * length field is utterly fatal and, if not caught here, extremely hard to track down.
  420. */
  421. if (macChipVersion == REV_A)
  422. {
  423. if ((rxUnreadLen > (MAC_A_MAX_PHY_PACKET_SIZE - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN)) ||
  424. (MAC_FRAME_TYPE(&rxBuf[1]) > MAC_FRAME_TYPE_MAX_VALID))
  425. {
  426. MAC_RADIO_FLUSH_RX_FIFO();
  427. rxDone();
  428. return;
  429. }
  430. }
  431. else
  432. {
  433. /* radio supplied a corrupted receive buffer length */
  434. MAC_ASSERT(rxUnreadLen <= (MAC_A_MAX_PHY_PACKET_SIZE - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN));
  435. }
  436. /*-------------------------------------------------------------------------------
  437. * Process ACKs.
  438. *
  439. * If this frame is an ACK, process it immediately and exit from here.
  440. * If this frame is not an ACK and transmit is listening for an ACK, let
  441. * the transmit logic know an non-ACK was received so transmit can complete.
  442. *
  443. * In promiscuous mode ACKs are treated like any other frame.
  444. */
  445. if ((MAC_FRAME_TYPE(&rxBuf[1]) == MAC_FRAME_TYPE_ACK) && (rxPromiscuousMode == PROMISCUOUS_MODE_OFF))
  446. {
  447. halIntState_t s;
  448. uint8 fcsBuf[MAC_FCF_FIELD_LEN];
  449. /*
  450. * There are guaranteed to be two unread bytes in the FIFO. By defintion, for ACK frames
  451. * these two bytes will be the FCS.
  452. */
  453. /* read FCS from FIFO (threshold set so bytes are guaranteed to be there) */
  454. MAC_RADIO_READ_RX_FIFO(fcsBuf, MAC_FCS_FIELD_LEN);
  455. /*
  456. * This critical section ensures that the ACK timeout won't be triggered in the
  457. * middle of receiving the ACK frame.
  458. */
  459. HAL_ENTER_CRITICAL_SECTION(s);
  460. /* see if transmit is listening for an ACK */
  461. if (macTxActive == MAC_TX_ACTIVE_LISTEN_FOR_ACK)
  462. {
  463. MAC_ASSERT(pMacDataTx != NULL); /* transmit buffer must be present */
  464. /* record link quality metrics for the receive ACK */
  465. {
  466. int8 rssiDbm;
  467. uint8 corr;
  468. rssiDbm = PROPRIETARY_FCS_RSSI(fcsBuf) + MAC_RADIO_RSSI_OFFSET;
  469. MAC_RADIO_RSSI_LNA_OFFSET(rssiDbm);
  470. corr = PROPRIETARY_FCS_CORRELATION_VALUE(fcsBuf);
  471. pMacDataTx->internal.mpduLinkQuality = macRadioComputeLQI(rssiDbm, corr);
  472. pMacDataTx->internal.correlation = corr;
  473. pMacDataTx->internal.rssi= rssiDbm;
  474. }
  475. /*
  476. * It's okay if the ACK timeout is triggered here. The callbacks for ACK received
  477. * or ACK not received will check "macTxActive" flag before taking any actions.
  478. */
  479. HAL_EXIT_CRITICAL_SECTION(s);
  480. /*
  481. * An ACK was received so transmit logic needs to know. If the FCS failed,
  482. * the transmit logic still needs to know. In that case, treat the frame
  483. * as a non-ACK to complete the active transmit.
  484. */
  485. if (PROPRIETARY_FCS_CRC_OK(fcsBuf))
  486. {
  487. /* call transmit logic to indicate ACK was received */
  488. macTxAckReceivedCallback(MAC_SEQ_NUMBER(&rxBuf[1]), MAC_FRAME_PENDING(&rxBuf[1]));
  489. }
  490. else
  491. {
  492. macTxAckNotReceivedCallback();
  493. }
  494. }
  495. else
  496. {
  497. HAL_EXIT_CRITICAL_SECTION(s);
  498. }
  499. /* receive is done, exit from here */
  500. rxDone();
  501. return;
  502. }
  503. else if (macTxActive == MAC_TX_ACTIVE_LISTEN_FOR_ACK)
  504. {
  505. macTxAckNotReceivedCallback();
  506. }
  507. /*-------------------------------------------------------------------------------
  508. * Apply filtering.
  509. *
  510. * For efficiency, see if filtering is even 'on' before processing. Also test
  511. * to make sure promiscuous mode is disabled. If promiscuous mode is enabled,
  512. * do not apply filtering.
  513. */
  514. if ((rxFilter != RX_FILTER_OFF) && !rxPromiscuousMode)
  515. {
  516. if (/* filter all frames */
  517. (rxFilter == RX_FILTER_ALL) ||
  518. /* filter non-beacon frames */
  519. ((rxFilter == RX_FILTER_NON_BEACON_FRAMES) &&
  520. (MAC_FRAME_TYPE(&rxBuf[1]) != MAC_FRAME_TYPE_BEACON)) ||
  521. /* filter non-command frames */
  522. ((rxFilter == RX_FILTER_NON_COMMAND_FRAMES) &&
  523. ((MAC_FRAME_TYPE(&rxBuf[1]) != MAC_FRAME_TYPE_COMMAND))))
  524. {
  525. /* discard rest of frame */
  526. rxDiscardFrame();
  527. return;
  528. }
  529. }
  530. /*-------------------------------------------------------------------------------
  531. * Compute length of addressing fields. Compute payload length.
  532. */
  533. /* decode addressing modes */
  534. dstAddrMode = MAC_DEST_ADDR_MODE(&rxBuf[1]);
  535. srcAddrMode = MAC_SRC_ADDR_MODE(&rxBuf[1]);
  536. /*
  537. * Workaround for chip bug #1547. The receive buffer can sometimes be corrupted by hardware.
  538. * This usually occurs under heavy traffic. If a corrupted receive buffer is detected
  539. * the entire receive buffer is flushed.
  540. */
  541. if (macChipVersion == REV_A)
  542. {
  543. if ((srcAddrMode == ADDR_MODE_RESERVERED) || (dstAddrMode == ADDR_MODE_RESERVERED))
  544. {
  545. MAC_RADIO_FLUSH_RX_FIFO();
  546. rxDone();
  547. return;
  548. }
  549. }
  550. /*
  551. * Compute the addressing field length. A lookup table based on addressing
  552. * mode is used for efficiency. If the source address is present and the
  553. * frame is intra-PAN, the PAN Id is not repeated. In this case, the address
  554. * length is adjusted to match the smaller length.
  555. */
  556. addrLen = macRxAddrLen[dstAddrMode] + macRxAddrLen[srcAddrMode];
  557. if ((srcAddrMode != SADDR_MODE_NONE) && MAC_INTRA_PAN(&rxBuf[1]))
  558. {
  559. addrLen -= MAC_PAN_ID_FIELD_LEN;
  560. }
  561. /*
  562. * If there are not enough unread bytes to include the computed address
  563. * plus FCS field, the frame is corrupted and must be discarded.
  564. */
  565. if ((addrLen + MAC_FCS_FIELD_LEN) > rxUnreadLen)
  566. {
  567. /* discard frame and exit */
  568. rxDiscardFrame();
  569. return;
  570. }
  571. /* aux security header plus payload length is equal to unread bytes minus
  572. * address length, minus the FCS
  573. */
  574. rxPayloadLen = rxUnreadLen - addrLen - MAC_FCS_FIELD_LEN;
  575. /*-------------------------------------------------------------------------------
  576. * Allocate memory for the incoming frame.
  577. */
  578. if (MAC_SEC_ENABLED(&rxBuf[1]))
  579. {
  580. /* increase the allocation size of MAC header for security */
  581. mhrLen = MAC_MHR_LEN;
  582. }
  583. pRxBuf = (macRx_t *) MEM_ALLOC(sizeof(macRx_t) + mhrLen + rxPayloadLen);
  584. if (pRxBuf == NULL)
  585. {
  586. /* Cancel the outgoing TX ACK */
  587. MAC_RADIO_CANCEL_TX_ACK();
  588. /* buffer allocation failed, discard the frame and exit*/
  589. rxDiscardFrame();
  590. return;
  591. }
  592. /*-------------------------------------------------------------------------------
  593. * Set up to process ACK request. Do not ACK if in promiscuous mode.
  594. */
  595. ackWithPending = 0;
  596. if (!rxPromiscuousMode)
  597. {
  598. macRxOutgoingAckFlag = MAC_ACK_REQUEST(&rxBuf[1]);
  599. }
  600. /*-------------------------------------------------------------------------------
  601. * Process any ACK request.
  602. */
  603. if (macRxOutgoingAckFlag)
  604. {
  605. halIntState_t s;
  606. /*
  607. * This critical section ensures that the callback ISR is initiated within time
  608. * to guarantee correlation with the strobe.
  609. */
  610. HAL_ENTER_CRITICAL_SECTION(s);
  611. /* Do not ack data packet with pending more data */
  612. if( MAC_FRAME_TYPE(&rxBuf[1]) == MAC_FRAME_TYPE_COMMAND )
  613. {
  614. if( macRxCheckMACPendingCallback())
  615. {
  616. /* Check is any mac data pending for end devices */
  617. ackWithPending = MAC_RX_FLAG_ACK_PENDING;
  618. }
  619. else
  620. {
  621. if( macSrcMatchIsEnabled )
  622. {
  623. /* When autopend is enabled, check if allpending is set to true */
  624. if( MAC_SrcMatchCheckAllPending() == MAC_AUTOACK_PENDING_ALL_ON )
  625. {
  626. ackWithPending = MAC_RX_FLAG_ACK_PENDING;
  627. }
  628. }
  629. else
  630. {
  631. /* When autopend is disabled, check the application pending callback */
  632. if( macRxCheckPendingCallback() )
  633. {
  634. ackWithPending = MAC_RX_FLAG_ACK_PENDING;
  635. }
  636. }
  637. }
  638. }
  639. if( ackWithPending == MAC_RX_FLAG_ACK_PENDING )
  640. {
  641. MAC_RADIO_TX_ACK_PEND();
  642. }
  643. else
  644. {
  645. MAC_RADIO_TX_ACK();
  646. }
  647. /* request a callback to macRxAckTxDoneCallback() when the ACK transmit has finished */
  648. MAC_RADIO_REQUEST_ACK_TX_DONE_CALLBACK();
  649. HAL_EXIT_CRITICAL_SECTION(s);
  650. }
  651. /*-------------------------------------------------------------------------------
  652. * Populate the receive buffer going up to high-level.
  653. */
  654. /* configure the payload buffer
  655. * save MAC header pointer regardless of security status.
  656. */
  657. pRxBuf->mhr.p = pRxBuf->msdu.p = (uint8 *) (pRxBuf + 1);
  658. pRxBuf->mhr.len = pRxBuf->msdu.len = rxPayloadLen;
  659. if (MAC_SEC_ENABLED(&rxBuf[1]))
  660. {
  661. /* Copy FCF and sequence number to RX buffer */
  662. pRxBuf->mhr.len = MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN;
  663. osal_memcpy(pRxBuf->mhr.p, &rxBuf[1], pRxBuf->mhr.len);
  664. pRxBuf->mhr.p += pRxBuf->mhr.len;
  665. }
  666. /* set internal values */
  667. pRxBuf->mac.srcAddr.addrMode = srcAddrMode;
  668. pRxBuf->mac.dstAddr.addrMode = dstAddrMode;
  669. pRxBuf->mac.timestamp = MAC_RADIO_BACKOFF_CAPTURE();
  670. pRxBuf->mac.timestamp2 = MAC_RADIO_TIMER_CAPTURE();
  671. pRxBuf->internal.frameType = MAC_FRAME_TYPE(&rxBuf[1]);
  672. pRxBuf->mac.dsn = MAC_SEQ_NUMBER(&rxBuf[1]);
  673. pRxBuf->internal.flags = INTERNAL_FCF_FLAGS(&rxBuf[1]) | ackWithPending;
  674. /*-------------------------------------------------------------------------------
  675. * If the processing the addressing fields does not require more bytes from
  676. * the FIFO go directly address processing function. Otherwise, configure
  677. * interrupt to jump there once bytes are received.
  678. */
  679. if (addrLen == 0)
  680. {
  681. /* no addressing fields to read, prepare for payload interrupts */
  682. pFuncRxState = &rxPayloadIsr;
  683. rxPrepPayload();
  684. }
  685. else
  686. {
  687. /* need to read and process addressing fields, prepare for address interrupt */
  688. rxNextLen = addrLen;
  689. if (MAC_SEC_ENABLED(&rxBuf[1]))
  690. {
  691. /* When security is enabled, read off security control field as well */
  692. MAC_RADIO_SET_RX_THRESHOLD(rxNextLen + MAC_SEC_CONTROL_FIELD_LEN);
  693. }
  694. else
  695. {
  696. MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
  697. }
  698. pFuncRxState = &rxAddrIsr;
  699. }
  700. }
  701. /*=================================================================================================
  702. * @fn rxAddrIsr
  703. *
  704. * @brief Receive ISR state for decoding address. Reads and stores the address information
  705. * from the incoming packet.
  706. *
  707. * @param none
  708. *
  709. * @return none
  710. *=================================================================================================
  711. */
  712. static void rxAddrIsr(void)
  713. {
  714. uint8 buf[MAX_ADDR_FIELDS_LEN];
  715. uint8 dstAddrMode;
  716. uint8 srcAddrMode;
  717. #ifdef MAC_SECURITY
  718. uint8 securityControl;
  719. #endif /* MAC_SECURITY */
  720. uint8 * p;
  721. MAC_ASSERT(rxNextLen != 0); /* logic assumes at least one address byte in buffer */
  722. /* read out address fields into local buffer in one shot */
  723. MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);
  724. /* set pointer to buffer with addressing fields */
  725. p = buf;
  726. /* destination address */
  727. dstAddrMode = MAC_DEST_ADDR_MODE(&rxBuf[1]);
  728. if (dstAddrMode != SADDR_MODE_NONE)
  729. {
  730. pRxBuf->mac.srcPanId = pRxBuf->mac.dstPanId = BUILD_UINT16(p[0], p[1]);
  731. p += MAC_PAN_ID_FIELD_LEN;
  732. if (dstAddrMode == SADDR_MODE_EXT)
  733. {
  734. sAddrExtCpy(pRxBuf->mac.dstAddr.addr.extAddr, p);
  735. p += MAC_EXT_ADDR_FIELD_LEN;
  736. }
  737. else
  738. {
  739. pRxBuf->mac.dstAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]);
  740. p += MAC_SHORT_ADDR_FIELD_LEN;
  741. }
  742. }
  743. /* sources address */
  744. srcAddrMode = MAC_SRC_ADDR_MODE(&rxBuf[1]);
  745. if (srcAddrMode != SADDR_MODE_NONE)
  746. {
  747. if (!(pRxBuf->internal.flags & MAC_RX_FLAG_INTRA_PAN))
  748. {
  749. pRxBuf->mac.srcPanId = BUILD_UINT16(p[0], p[1]);
  750. p += MAC_PAN_ID_FIELD_LEN;
  751. }
  752. if (srcAddrMode == SADDR_MODE_EXT)
  753. {
  754. sAddrExtCpy(pRxBuf->mac.srcAddr.addr.extAddr, p);
  755. }
  756. else
  757. {
  758. pRxBuf->mac.srcAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]);
  759. }
  760. }
  761. #ifdef MAC_SECURITY
  762. if (MAC_SEC_ENABLED(&rxBuf[1]))
  763. {
  764. uint8 keyIdMode;
  765. if (MAC_FRAME_VERSION(&rxBuf[1]) == 0)
  766. {
  767. /* MAC_UNSUPPORTED_LEGACY - Cancel the outgoing TX ACK.
  768. * It may be too late but we have to try.
  769. */
  770. MAC_RADIO_CANCEL_TX_ACK();
  771. /* clean up after unsupported security legacy */
  772. macRxHaltCleanup();
  773. return;
  774. }
  775. /* Copy addressing fields to RX buffer */
  776. osal_memcpy(pRxBuf->mhr.p, buf, rxNextLen);
  777. pRxBuf->mhr.p += rxNextLen;
  778. pRxBuf->mhr.len += rxNextLen;
  779. /*-------------------------------------------------------------------------------
  780. * Prepare for auxiliary security header interrupts.
  781. */
  782. /* read out security control field from FIFO (threshold set so bytes are guaranteed to be there) */
  783. MAC_RADIO_READ_RX_FIFO(&securityControl, MAC_SEC_CONTROL_FIELD_LEN);
  784. /* Copy security fields to MHR buffer */
  785. *pRxBuf->mhr.p = securityControl;
  786. pRxBuf->mhr.p += MAC_SEC_CONTROL_FIELD_LEN;
  787. pRxBuf->mhr.len += MAC_SEC_CONTROL_FIELD_LEN;
  788. /* store security level and key ID mode */
  789. pRxBuf->sec.securityLevel = SECURITY_LEVEL(securityControl);
  790. pRxBuf->sec.keyIdMode = keyIdMode = KEY_IDENTIFIER_MODE(securityControl);
  791. /* Corrupted RX frame, should never occur. */
  792. if ((keyIdMode > MAC_KEY_ID_MODE_8)
  793. /* Get the next RX length according to AuxLen table minus security control field.
  794. * The security control length is counted already.
  795. */
  796. || ((macKeySourceLen[keyIdMode] + MAC_FRAME_COUNTER_LEN) >= rxPayloadLen)
  797. /* Security Enabled subfield is one, but the Security Level in the header is zero:
  798. * MAC_UNSUPPORTED_SECURITY - Cancel the outgoing TX ACK.
  799. */
  800. || (pRxBuf->sec.securityLevel == MAC_SEC_LEVEL_NONE))
  801. {
  802. /* It may be too late but we have to try. */
  803. MAC_RADIO_CANCEL_TX_ACK();
  804. /* clean up after unsupported security or corrupted RX frame. */
  805. macRxHaltCleanup();
  806. return;
  807. }
  808. /* get the next RX length according to AuxLen table minus security control field.
  809. * The sceurity control length is counted already.
  810. */
  811. rxNextLen = macKeySourceLen[keyIdMode] + MAC_FRAME_COUNTER_LEN;
  812. MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
  813. pFuncRxState = &rxSecurityHdrIsr;
  814. }
  815. else
  816. #endif /* MAC_SECURITY */
  817. {
  818. /* clear security level */
  819. pRxBuf->sec.securityLevel = MAC_SEC_LEVEL_NONE;
  820. /*-------------------------------------------------------------------------------
  821. * Prepare for payload interrupts.
  822. */
  823. pFuncRxState = &rxPayloadIsr;
  824. rxPrepPayload();
  825. }
  826. }
  827. #ifdef MAC_SECURITY
  828. /*=================================================================================================
  829. * @fn rxSecurityHdrIsr
  830. *
  831. * @brief Receive ISR state for reading out and storing the auxiliary security header.
  832. *
  833. * @param none
  834. *
  835. * @return none
  836. *=================================================================================================
  837. */
  838. static void rxSecurityHdrIsr(void)
  839. {
  840. uint8 buf[MAC_FRAME_COUNTER_LEN + MAC_KEY_ID_8_LEN];
  841. /* read out frame counter and key ID */
  842. MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);
  843. /* Incoming frame counter */
  844. macFrameCounter = BUILD_UINT32(buf[0], buf[1], buf[2], buf[3]);
  845. if (rxNextLen - MAC_FRAME_COUNTER_LEN > 0)
  846. {
  847. /* Explicit mode */
  848. osal_memcpy(pRxBuf->sec.keySource, &buf[MAC_FRAME_COUNTER_LEN], rxNextLen - MAC_FRAME_COUNTER_LEN - 1);
  849. pRxBuf->sec.keyIndex = buf[rxNextLen - MAC_KEY_INDEX_LEN];
  850. }
  851. /* Copy security fields to RX buffer */
  852. osal_memcpy(pRxBuf->mhr.p, buf, rxNextLen);
  853. pRxBuf->mhr.p += rxNextLen;
  854. pRxBuf->mhr.len += rxNextLen;
  855. /* Update payload pointer and payload length. The rxPayloadLen includes security header length
  856. * and SCF byte. The security header and SCF length must be deducted from the rxPayloadLen.
  857. */
  858. rxPayloadLen -= (rxNextLen + MAC_SEC_CONTROL_FIELD_LEN);
  859. pRxBuf->msdu.len = rxPayloadLen;
  860. pRxBuf->mhr.len += rxPayloadLen;
  861. /*-------------------------------------------------------------------------------
  862. * Prepare for payload interrupts.
  863. */
  864. pFuncRxState = &rxPayloadIsr;
  865. rxPrepPayload();
  866. }
  867. #endif /* MAC_SECURITY */
  868. /*=================================================================================================
  869. * @fn rxPrepPayload
  870. *
  871. * @brief Common code to prepare for the payload ISR.
  872. *
  873. * @param none
  874. *
  875. * @return none
  876. *=================================================================================================
  877. */
  878. static void rxPrepPayload(void)
  879. {
  880. if (rxPayloadLen == 0)
  881. {
  882. MAC_RADIO_SET_RX_THRESHOLD(MAC_FCS_FIELD_LEN);
  883. pFuncRxState = &rxFcsIsr;
  884. }
  885. else
  886. {
  887. rxNextLen = MIN(rxPayloadLen, MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT);
  888. MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
  889. }
  890. }
  891. /*=================================================================================================
  892. * @fn rxPayloadIsr
  893. *
  894. * @brief Receive ISR state for reading out and storing the packet payload.
  895. *
  896. * @param none
  897. *
  898. * @return none
  899. *=================================================================================================
  900. */
  901. static void rxPayloadIsr(void)
  902. {
  903. MAC_RADIO_READ_RX_FIFO(pRxBuf->mhr.p, rxNextLen);
  904. pRxBuf->mhr.p += rxNextLen;
  905. rxPayloadLen -= rxNextLen;
  906. rxPrepPayload();
  907. }
  908. /*=================================================================================================
  909. * @fn rxFcsIsr
  910. *
  911. * @brief Receive ISR state for handling the FCS.
  912. *
  913. * @param none
  914. *
  915. * @return none
  916. *=================================================================================================
  917. */
  918. static void rxFcsIsr(void)
  919. {
  920. uint8 crcOK;
  921. uint8 ackWithPending = 0;
  922. /* read FCS, rxBuf is now available storage */
  923. MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_FCS_FIELD_LEN);
  924. /*
  925. * The FCS has actually been replaced within the radio by a proprietary version of the FCS.
  926. * This proprietary FCS is two bytes (same length as the real FCS) and contains:
  927. * 1) the RSSI value
  928. * 2) the average correlation value (used for LQI)
  929. * 3) a CRC passed bit
  930. */
  931. /* save the "CRC-is-OK" status */
  932. crcOK = PROPRIETARY_FCS_CRC_OK(rxBuf);
  933. /*
  934. * See if the frame should be passed up to high-level MAC. If the CRC is OK, the
  935. * the frame is always passed up. Frames with a bad CRC are also passed up *if*
  936. * a special variant of promiscuous mode is active.
  937. */
  938. if (crcOK || (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC))
  939. {
  940. int8 rssiDbm;
  941. uint8 corr;
  942. #ifdef PACKET_FILTER_STATS
  943. rxCrcSuccess++;
  944. #endif /* PACKET_FILTER_STATS */
  945. /*
  946. * As power saving optimization, set state variable to indicate physical receive
  947. * has completed and then request turning of the receiver. This means the receiver
  948. * can be off (if other conditions permit) during execution of the callback function.
  949. *
  950. * The receiver will be requested to turn off once again at the end of the receive
  951. * logic. There is no harm in doing this.
  952. */
  953. macRxActive = MAC_RX_ACTIVE_DONE;
  954. macRxOffRequest();
  955. /* decode RSSI and correlation values */
  956. rssiDbm = PROPRIETARY_FCS_RSSI(rxBuf) + MAC_RADIO_RSSI_OFFSET;
  957. MAC_RADIO_RSSI_LNA_OFFSET(rssiDbm);
  958. corr = PROPRIETARY_FCS_CORRELATION_VALUE(rxBuf);
  959. /* Read the source matching result back */
  960. if( macSrcMatchIsEnabled && MAC_RADIO_SRC_MATCH_RESULT() )
  961. {
  962. /* This result will not overwrite the previously determined pRxBuf->internal.flags */
  963. ackWithPending = MAC_RX_FLAG_ACK_PENDING;
  964. }
  965. /* record parameters that get passed up to high-level */
  966. pRxBuf->internal.flags |= ( crcOK | ackWithPending );
  967. pRxBuf->mac.mpduLinkQuality = macRadioComputeLQI(rssiDbm, corr);
  968. pRxBuf->mac.rssi = rssiDbm;
  969. pRxBuf->mac.correlation = corr;
  970. /* set the MSDU pointer to point at start of data */
  971. pRxBuf->mhr.p = (uint8 *) (pRxBuf + 1);
  972. pRxBuf->msdu.p += (pRxBuf->mhr.len - pRxBuf->msdu.len);
  973. /* finally... execute callback function */
  974. macRxCompleteCallback(pRxBuf);
  975. pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */
  976. }
  977. else
  978. {
  979. #ifdef PACKET_FILTER_STATS
  980. rxCrcFailure++;
  981. #endif /* PACKET_FILTER_STATS */
  982. /*
  983. * The CRC is bad so no ACK was sent. Cancel any callback and clear the flag.
  984. * (It's OK to cancel the outgoing ACK even if an ACK was not requested. It's
  985. * slightly more efficient to do so.)
  986. */
  987. MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
  988. macRxOutgoingAckFlag = 0;
  989. /* the CRC failed so the packet must be discarded */
  990. MEM_FREE((uint8 **)&pRxBuf);
  991. pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */
  992. }
  993. /* reset threshold level, reset receive state, and complete receive logic */
  994. MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
  995. pFuncRxState = &rxStartIsr;
  996. rxDone();
  997. }
  998. /*=================================================================================================
  999. * @fn rxDone
  1000. *
  1001. * @brief Common exit point for receive.
  1002. *
  1003. * @param none
  1004. *
  1005. * @return none
  1006. *=================================================================================================
  1007. */
  1008. static void rxDone(void)
  1009. {
  1010. /* Make sure the peak RSSI is reset */
  1011. COMPRESSION_WORKAROUND_RESET_RSSI();
  1012. /* if the receive FIFO has overflowed, flush it here */
  1013. if (MAC_RADIO_RX_FIFO_HAS_OVERFLOWED())
  1014. {
  1015. MAC_RADIO_FLUSH_RX_FIFO();
  1016. }
  1017. /* mark receive as inactive */
  1018. macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
  1019. /* if there is no outgoing ACK, run the post receive updates */
  1020. if (!macRxOutgoingAckFlag)
  1021. {
  1022. rxPostRxUpdates();
  1023. }
  1024. }
  1025. /**************************************************************************************************
  1026. * @fn macRxAckTxDoneCallback
  1027. *
  1028. * @brief Function called when the outoing ACK has completed transmitting.
  1029. *
  1030. * @param none
  1031. *
  1032. * @return none
  1033. **************************************************************************************************
  1034. */
  1035. void macRxAckTxDoneCallback(void)
  1036. {
  1037. macRxOutgoingAckFlag = 0;
  1038. /*
  1039. * With certain interrupt priorities and timing conditions, it is possible this callback
  1040. * could be executed before the primary receive logic completes. To prevent this, the
  1041. * post updates are only executed if receive logic is no longer active. In the case the
  1042. * post updates are not executed here, they will execute when the main receive logic
  1043. * completes.
  1044. */
  1045. if (!macRxActive)
  1046. {
  1047. rxPostRxUpdates();
  1048. }
  1049. }
  1050. /*=================================================================================================
  1051. * @fn rxPostRxUpdates
  1052. *
  1053. * @brief Updates that need to be performed once receive is complete.
  1054. *
  1055. * It is not fatal to execute this function if somehow receive is active. Under
  1056. * certain timing/interrupt conditions a new receive may have started before this
  1057. * function executes. This should happen very rarely (if it happens at all) and
  1058. * would cause no problems.
  1059. *
  1060. * @param none
  1061. *
  1062. * @return none
  1063. *=================================================================================================
  1064. */
  1065. static void rxPostRxUpdates(void)
  1066. {
  1067. /* turn off receiver if permitted */
  1068. macRxOffRequest();
  1069. /* update the transmit power, update may have been blocked by transmit of outgoing ACK */
  1070. macRadioUpdateTxPower();
  1071. /* initiate and transmit that was queued during receive */
  1072. macTxStartQueuedFrame();
  1073. }
  1074. /*=================================================================================================
  1075. * @fn rxDiscardFrame
  1076. *
  1077. * @brief Initializes for discarding a packet. Must be called before ACK is strobed.
  1078. *
  1079. * @param none
  1080. *
  1081. * @return none
  1082. *=================================================================================================
  1083. */
  1084. static void rxDiscardFrame(void)
  1085. {
  1086. MAC_ASSERT(pFuncRxState == &rxStartIsr); /* illegal state for calling discard frame function */
  1087. if (rxUnreadLen == 0)
  1088. {
  1089. rxDone();
  1090. }
  1091. else
  1092. {
  1093. rxNextLen = MIN(rxUnreadLen, MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT);
  1094. MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
  1095. pFuncRxState = &rxDiscardIsr;
  1096. }
  1097. }
  1098. /*=================================================================================================
  1099. * @fn rxDiscardIsr
  1100. *
  1101. * @brief Receive ISR state for discarding a packet.
  1102. *
  1103. * @param none
  1104. *
  1105. * @return none
  1106. *=================================================================================================
  1107. */
  1108. static void rxDiscardIsr(void)
  1109. {
  1110. uint8 buf[MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT];
  1111. MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);
  1112. rxUnreadLen -= rxNextLen;
  1113. /* read out and discard bytes until all bytes of packet are disposed of */
  1114. if (rxUnreadLen != 0)
  1115. {
  1116. if (rxUnreadLen < MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT)
  1117. {
  1118. rxNextLen = rxUnreadLen;
  1119. MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
  1120. }
  1121. }
  1122. else
  1123. {
  1124. /* reset threshold level, reset receive state, and complete receive logic */
  1125. MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
  1126. pFuncRxState = &rxStartIsr;
  1127. rxDone();
  1128. }
  1129. }
  1130. /**************************************************************************************************
  1131. * @fn macRxFifoOverflowIsr
  1132. *
  1133. * @brief This interrupt service routine is called when RX FIFO overflow. Note that this
  1134. * exception does not retrieve the good frames that are trapped in the RX FIFO.
  1135. * It simply halts and cleanup the RX.
  1136. *
  1137. * @param none
  1138. *
  1139. * @return none
  1140. **************************************************************************************************
  1141. */
  1142. MAC_INTERNAL_API void macRxFifoOverflowIsr(void)
  1143. {
  1144. rxFifoOverflowCount++; /* This flag is used for debug purpose only */
  1145. macRxHaltCleanup();
  1146. }
  1147. /**************************************************************************************************
  1148. * @fn macRxPromiscuousMode
  1149. *
  1150. * @brief Sets promiscuous mode - enabling or disabling it.
  1151. *
  1152. * @param none
  1153. *
  1154. * @return none
  1155. **************************************************************************************************
  1156. */
  1157. MAC_INTERNAL_API void macRxPromiscuousMode(uint8 mode)
  1158. {
  1159. rxPromiscuousMode = mode;
  1160. if (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_OFF)
  1161. {
  1162. MAC_RADIO_TURN_ON_RX_FRAME_FILTERING();
  1163. }
  1164. else
  1165. {
  1166. MAC_ASSERT((mode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC) ||
  1167. (mode == MAC_PROMISCUOUS_MODE_COMPLIANT)); /* invalid mode */
  1168. MAC_RADIO_TURN_OFF_RX_FRAME_FILTERING();
  1169. }
  1170. }
  1171. #ifdef CC2591_COMPRESSION_WORKAROUND
  1172. /**************************************************************************************************
  1173. * @fn macRxResetRssi
  1174. *
  1175. * @brief This function reset RSSI peak if the device is not actively in TX or RX.
  1176. *
  1177. * @param none
  1178. *
  1179. * @return none
  1180. **************************************************************************************************
  1181. */
  1182. void macRxResetRssi(void)
  1183. {
  1184. if ( !(macRxActive || macRxOutgoingAckFlag || macTxActive) )
  1185. {
  1186. COMPRESSION_WORKAROUND_RESET_RSSI();
  1187. }
  1188. }
  1189. #endif /* CC2591_COMPRESSION_WORKAROUND */
  1190. /**************************************************************************************************
  1191. * Compile Time Integrity Checks
  1192. **************************************************************************************************
  1193. */
  1194. /* check for changes to the spec that would affect the source code */
  1195. #if ((MAC_A_MAX_PHY_PACKET_SIZE != 0x7F ) || \
  1196. (MAC_FCF_FIELD_LEN != 2 ) || \
  1197. (MAC_FCF_FRAME_TYPE_POS != 0 ) || \
  1198. (MAC_FCF_FRAME_PENDING_POS != 4 ) || \
  1199. (MAC_FCF_ACK_REQUEST_POS != 5 ) || \
  1200. (MAC_FCF_INTRA_PAN_POS != 6 ) || \
  1201. (MAC_FCF_DST_ADDR_MODE_POS != 10 ) || \
  1202. (MAC_FCF_FRAME_VERSION_POS != 12 ) || \
  1203. (MAC_FCF_SRC_ADDR_MODE_POS != 14 ))
  1204. #error "ERROR! Change to the spec that requires modification of source code."
  1205. #endif
  1206. /* check for changes to the internal flags format */
  1207. #if ((MAC_RX_FLAG_VERSION != 0x03) || \
  1208. (MAC_RX_FLAG_ACK_PENDING != 0x04) || \
  1209. (MAC_RX_FLAG_SECURITY != 0x08) || \
  1210. (MAC_RX_FLAG_PENDING != 0x10) || \
  1211. (MAC_RX_FLAG_ACK_REQUEST != 0x20) || \
  1212. (MAC_RX_FLAG_INTRA_PAN != 0x40))
  1213. #error "ERROR! Change to the internal RX flags format. Requires modification of source code."
  1214. #endif
  1215. /* validate CRC OK bit optimization */
  1216. #if (MAC_RX_FLAG_CRC_OK != PROPRIETARY_FCS_CRC_OK_BIT)
  1217. #error "ERROR! Optimization relies on these bits having the same position."
  1218. #endif
  1219. #if (MAC_RX_ACTIVE_NO_ACTIVITY != 0x00)
  1220. #error "ERROR! Zero is reserved value of macRxActive. Allows boolean operations, e.g !macRxActive."
  1221. #endif
  1222. #if (MAC_PROMISCUOUS_MODE_OFF != 0x00)
  1223. #error "ERROR! Zero is reserved value of rxPromiscuousMode. Allows boolean operations, e.g !rxPromiscuousMode."
  1224. #endif
  1225. /**************************************************************************************************
  1226. */