1 /**
2  *
3  * \file
4  *
5  * \brief This module contains M2M host interface APIs implementation.
6  *
7  * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
8  *
9  * \asf_license_start
10  *
11  * \page License
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  *    this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright notice,
20  *    this list of conditions and the following disclaimer in the documentation
21  *    and/or other materials provided with the distribution.
22  *
23  * 3. The name of Atmel may not be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
27  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
29  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
30  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * \asf_license_stop
39  *
40  */
41 
42 #include "common/include/nm_common.h"
43 #include "driver/source/nmbus.h"
44 #include "bsp/include/nm_bsp.h"
45 #include "m2m_hif.h"
46 #include "driver/include/m2m_types.h"
47 #include "driver/source/nmasic.h"
48 #include "driver/include/m2m_periph.h"
49 
50 #if (defined NM_EDGE_INTERRUPT)&&(defined NM_LEVEL_INTERRUPT)
51 #error "only one type of interrupt NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
52 #endif
53 
54 #if !((defined NM_EDGE_INTERRUPT)||(defined NM_LEVEL_INTERRUPT))
55 #error "define interrupt type NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
56 #endif
57 
58 #ifndef CORTUS_APP
59 #define NMI_AHB_DATA_MEM_BASE  0x30000
60 #define NMI_AHB_SHARE_MEM_BASE 0xd0000
61 
62 #define WIFI_HOST_RCV_CTRL_0	(0x1070)
63 #define WIFI_HOST_RCV_CTRL_1	(0x1084)
64 #define WIFI_HOST_RCV_CTRL_2    (0x1078)
65 #define WIFI_HOST_RCV_CTRL_3    (0x106c)
66 #define WIFI_HOST_RCV_CTRL_4	(0x150400)
67 #define WIFI_HOST_RCV_CTRL_5	(0x1088)
68 
69 typedef struct {
70  	uint8 u8ChipMode;
71  	uint8 u8ChipSleep;
72  	uint8 u8HifRXDone;
73  	uint8 u8Interrupt;
74  	uint32 u32RxAddr;
75  	uint32 u32RxSize;
76 	tpfHifCallBack pfWifiCb;
77 	tpfHifCallBack pfIpCb;
78 	tpfHifCallBack pfOtaCb;
79 	tpfHifCallBack pfSigmaCb;
80 	tpfHifCallBack pfHifCb;
81 	tpfHifCallBack pfCryptoCb;
82 	tpfHifCallBack pfSslCb;
83 }tstrHifContext;
84 
85 volatile tstrHifContext gstrHifCxt;
86 
isr(void)87 static void isr(void)
88 {
89 	gstrHifCxt.u8Interrupt++;
90 #ifdef NM_LEVEL_INTERRUPT
91 	nm_bsp_interrupt_ctrl(0);
92 #endif
93 }
hif_set_rx_done(void)94 static sint8 hif_set_rx_done(void)
95 {
96 	uint32 reg;
97 	sint8 ret = M2M_SUCCESS;
98 
99 	gstrHifCxt.u8HifRXDone = 0;
100 #ifdef NM_EDGE_INTERRUPT
101 	nm_bsp_interrupt_ctrl(1);
102 #endif
103 	ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0,&reg);
104 	if(ret != M2M_SUCCESS)goto ERR1;
105 	/* Set RX Done */
106 	reg |= NBIT1;
107 	ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
108 	if(ret != M2M_SUCCESS)goto ERR1;
109 #ifdef NM_LEVEL_INTERRUPT
110 	nm_bsp_interrupt_ctrl(1);
111 #endif
112 ERR1:
113 	return ret;
114 
115 }
116 /**
117 *	@fn			static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
118 *	@brief		WiFi call back function
119 *	@param [in]	u8OpCode
120 *					HIF Opcode type.
121 *	@param [in]	u16DataSize
122 *					HIF data length.
123 *	@param [in]	u32Addr
124 *					HIF address.
125 *	@param [in]	grp
126 *					HIF group type.
127 *	@author
128 *	@date
129 *	@version	1.0
130 */
m2m_hif_cb(uint8 u8OpCode,uint16 u16DataSize,uint32 u32Addr)131 static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
132 {
133 
134 
135 }
136 /**
137 *	@fn		NMI_API sint8 hif_chip_wake(void);
138 *	@brief	To Wakeup the chip.
139 *    @return		The function shall return ZERO for successful operation and a negative value otherwise.
140 */
141 
hif_chip_wake(void)142 sint8 hif_chip_wake(void)
143 {
144 	sint8 ret = M2M_SUCCESS;
145 	if(gstrHifCxt.u8HifRXDone)
146 	{
147 		/*chip already wake for the rx not done no need to send wake request*/
148 		return ret;
149 	}
150 	if(gstrHifCxt.u8ChipSleep == 0)
151 	{
152 		if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
153 		{
154 			ret = chip_wake();
155 			if(ret != M2M_SUCCESS)goto ERR1;
156 		}
157 		else
158 		{
159 		}
160 	}
161 	gstrHifCxt.u8ChipSleep++;
162 ERR1:
163 	return ret;
164 }
165 /*!
166 @fn	\
167 	NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
168 
169 @brief
170 	Set the sleep mode of the HIF layer.
171 
172 @param [in]	u8Pstype
173 				Sleep mode.
174 
175 @return
176 	The function SHALL return 0 for success and a negative value otherwise.
177 */
178 
hif_set_sleep_mode(uint8 u8Pstype)179 void hif_set_sleep_mode(uint8 u8Pstype)
180 {
181 	gstrHifCxt.u8ChipMode = u8Pstype;
182 }
183 /*!
184 @fn	\
185 	NMI_API uint8 hif_get_sleep_mode(void);
186 
187 @brief
188 	Get the sleep mode of the HIF layer.
189 
190 @return
191 	The function SHALL return the sleep mode of the HIF layer.
192 */
193 
hif_get_sleep_mode(void)194 uint8 hif_get_sleep_mode(void)
195 {
196 	return gstrHifCxt.u8ChipMode;
197 }
198 
199 /**
200 *	@fn		NMI_API sint8 hif_chip_sleep_sc(void);
201 *	@brief	To clear the chip sleep but keep the chip sleep
202 *    @return		The function shall return ZERO for successful operation and a negative value otherwise.
203 */
204 
hif_chip_sleep_sc(void)205 sint8 hif_chip_sleep_sc(void)
206 {
207 	if(gstrHifCxt.u8ChipSleep >= 1)
208 	{
209 		gstrHifCxt.u8ChipSleep--;
210 	}
211 	return M2M_SUCCESS;
212 }
213 /**
214 *	@fn		NMI_API sint8 hif_chip_sleep(void);
215 *	@brief	To make the chip sleep.
216 *    @return		The function shall return ZERO for successful operation and a negative value otherwise.
217 */
218 
hif_chip_sleep(void)219 sint8 hif_chip_sleep(void)
220 {
221 	sint8 ret = M2M_SUCCESS;
222 
223 	if(gstrHifCxt.u8ChipSleep >= 1)
224 	{
225 		gstrHifCxt.u8ChipSleep--;
226 	}
227 
228 	if(gstrHifCxt.u8ChipSleep == 0)
229 	{
230 		if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
231 		{
232 			ret = chip_sleep();
233 			if(ret != M2M_SUCCESS)goto ERR1;
234 
235 		}
236 		else
237 		{
238 		}
239 	}
240 ERR1:
241 	return ret;
242 }
243 /**
244 *   @fn		NMI_API sint8 hif_init(void * arg);
245 *   @brief	To initialize HIF layer.
246 *   @param [in]	arg
247 *				Pointer to the arguments.
248 *   @return		The function shall return ZERO for successful operation and a negative value otherwise.
249 */
250 
hif_init(void * arg)251 sint8 hif_init(void * arg)
252 {
253 	m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
254 	nm_bsp_register_isr(isr);
255 	hif_register_cb(M2M_REQ_GROUP_HIF,m2m_hif_cb);
256 	return M2M_SUCCESS;
257 }
258 /**
259 *	@fn		NMI_API sint8 hif_deinit(void * arg);
260 *	@brief	To De-initialize HIF layer.
261 *    @param [in]	arg
262 *				Pointer to the arguments.
263 *    @return		The function shall return ZERO for successful operation and a negative value otherwise.
264 */
hif_deinit(void * arg)265 sint8 hif_deinit(void * arg)
266 {
267 	sint8 ret = M2M_SUCCESS;
268 	ret = hif_chip_wake();
269 	m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
270 	return ret;
271 }
272 /**
273 *	@fn		NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
274 					   uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
275 *	@brief	Send packet using host interface.
276 
277 *	@param [in]	u8Gid
278 *				Group ID.
279 *	@param [in]	u8Opcode
280 *				Operation ID.
281 *	@param [in]	pu8CtrlBuf
282 *				Pointer to the Control buffer.
283 *	@param [in]	u16CtrlBufSize
284 				Control buffer size.
285 *	@param [in]	u16DataOffset
286 				Packet Data offset.
287 *	@param [in]	pu8DataBuf
288 *				Packet buffer Allocated by the caller.
289 *	@param [in]	u16DataSize
290 				Packet buffer size (including the HIF header).
291 *    @return		The function shall return ZERO for successful operation and a negative value otherwise.
292 */
293 
hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 * pu8CtrlBuf,uint16 u16CtrlBufSize,uint8 * pu8DataBuf,uint16 u16DataSize,uint16 u16DataOffset)294 sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
295 			   uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
296 {
297 	sint8		ret = M2M_ERR_SEND;
298 	volatile tstrHifHdr	strHif;
299 
300 	strHif.u8Opcode		= u8Opcode&(~NBIT7);
301 	strHif.u8Gid		= u8Gid;
302 	strHif.u16Length	= M2M_HIF_HDR_OFFSET;
303 	if(pu8DataBuf != NULL)
304 	{
305 		strHif.u16Length += u16DataOffset + u16DataSize;
306 	}
307 	else
308 	{
309 		strHif.u16Length += u16CtrlBufSize;
310 	}
311 	ret = hif_chip_wake();
312 	if(ret == M2M_SUCCESS)
313 	{
314 		volatile uint32 reg, dma_addr = 0;
315 		volatile uint16 cnt = 0;
316 //#define OPTIMIZE_BUS
317 /*please define in firmware also*/
318 #ifndef OPTIMIZE_BUS
319 		reg = 0UL;
320 		reg |= (uint32)u8Gid;
321 		reg |= ((uint32)u8Opcode<<8);
322 		reg |= ((uint32)strHif.u16Length<<16);
323 		ret = nm_write_reg(NMI_STATE_REG,reg);
324 		if(M2M_SUCCESS != ret) goto ERR1;
325 
326 		reg = 0UL;
327 		reg |= NBIT1;
328 		ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
329 		if(M2M_SUCCESS != ret) goto ERR1;
330 #else
331 		reg = 0UL;
332 		reg |= NBIT1;
333 		reg |= ((u8Opcode & NBIT7) ? (NBIT2):(0)); /*Data = 1 or config*/
334 		reg |= (u8Gid == M2M_REQ_GROUP_IP) ? (NBIT3):(0); /*IP = 1 or non IP*/
335 		reg |= ((uint32)strHif.u16Length << 4); /*length of pkt max = 4096*/
336 		ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
337 		if(M2M_SUCCESS != ret) goto ERR1;
338 #endif
339 		dma_addr = 0;
340 
341 		for(cnt = 0; cnt < 1000; cnt ++)
342 		{
343 			ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)&reg);
344 			if(ret != M2M_SUCCESS) break;
345 			/*
346 			 * If it takes too long to get a response, the slow down to
347 			 * avoid back-to-back register read operations.
348 			 */
349 			if(cnt >= 500) {
350 				if(cnt < 501) {
351 					M2M_INFO("Slowing down...\n");
352 				}
353 				nm_bsp_sleep(1);
354 			}
355 			if (!(reg & NBIT1))
356 			{
357 				ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4,(uint32 *)&dma_addr);
358 				if(ret != M2M_SUCCESS) {
359 					/*in case of read error clear the DMA address and return error*/
360 					dma_addr = 0;
361 					goto ERR1;
362 				}
363 				/*in case of success break */
364 				break;
365 			}
366 		}
367 
368 		if (dma_addr != 0)
369 		{
370 			volatile uint32	u32CurrAddr;
371 			u32CurrAddr = dma_addr;
372 			strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length);
373 			ret = nm_write_block(u32CurrAddr, (uint8*)&strHif, M2M_HIF_HDR_OFFSET);
374 			if(M2M_SUCCESS != ret) goto ERR1;
375 			u32CurrAddr += M2M_HIF_HDR_OFFSET;
376 			if(pu8CtrlBuf != NULL)
377 			{
378 				ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize);
379 				if(M2M_SUCCESS != ret) goto ERR1;
380 				u32CurrAddr += u16CtrlBufSize;
381 			}
382 			if(pu8DataBuf != NULL)
383 			{
384 				u32CurrAddr += (u16DataOffset - u16CtrlBufSize);
385 				ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize);
386 				if(M2M_SUCCESS != ret) goto ERR1;
387 				u32CurrAddr += u16DataSize;
388 			}
389 
390 			reg = dma_addr << 2;
391 			reg |= NBIT1;
392 			ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg);
393 			if(M2M_SUCCESS != ret) goto ERR1;
394 		}
395 		else
396 		{
397 			ret = hif_chip_sleep();
398 			M2M_DBG("Failed to alloc rx size %d\r",ret);
399 			ret = M2M_ERR_MEM_ALLOC;
400 			goto ERR2;
401 		}
402 
403 	}
404 	else
405 	{
406 		M2M_ERR("(HIF)Fail to wakup the chip\n");
407 		goto ERR2;
408 	}
409 	/*actual sleep ret = M2M_SUCCESS*/
410  	ret = hif_chip_sleep();
411 	return ret;
412 ERR1:
413 	/*reset the count but no actual sleep as it already bus error*/
414 	hif_chip_sleep_sc();
415 ERR2:
416 	/*logical error*/
417 	return ret;
418 }
419 /**
420 *	@fn		hif_isr
421 *	@brief	Host interface interrupt service routine
422 *	@author	M. Abdelmawla
423 *	@date	15 July 2012
424 *	@return	1 in case of interrupt received else 0 will be returned
425 *	@version	1.0
426 */
hif_isr(void)427 static sint8 hif_isr(void)
428 {
429 	sint8 ret = M2M_SUCCESS;
430 	uint32 reg;
431 	volatile tstrHifHdr strHif;
432 
433 	ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
434 	if(M2M_SUCCESS == ret)
435 	{
436 		if(reg & 0x1)	/* New interrupt has been received */
437 		{
438 			uint16 size;
439 
440 			nm_bsp_interrupt_ctrl(0);
441 			/*Clearing RX interrupt*/
442 			reg &= ~NBIT0;
443 			ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
444 			if(ret != M2M_SUCCESS)goto ERR1;
445 			gstrHifCxt.u8HifRXDone = 1;
446 			size = (uint16)((reg >> 2) & 0xfff);
447 			if (size > 0) {
448 				uint32 address = 0;
449 				/**
450 				start bus transfer
451 				**/
452 				ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
453 				if(M2M_SUCCESS != ret)
454 				{
455 					M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\n");
456 					nm_bsp_interrupt_ctrl(1);
457 					goto ERR1;
458 				}
459 				gstrHifCxt.u32RxAddr = address;
460 				gstrHifCxt.u32RxSize = size;
461 				ret = nm_read_block(address, (uint8*)&strHif, sizeof(tstrHifHdr));
462 				strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
463 				if(M2M_SUCCESS != ret)
464 				{
465 					M2M_ERR("(hif) address bus fail\n");
466 					nm_bsp_interrupt_ctrl(1);
467 					goto ERR1;
468 				}
469 				if(strHif.u16Length != size)
470 				{
471 					if((size - strHif.u16Length) > 4)
472 					{
473 						M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\n",
474 							size, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode);
475 						nm_bsp_interrupt_ctrl(1);
476 						ret = M2M_ERR_BUS_FAIL;
477 						goto ERR1;
478 					}
479 				}
480 
481 				if(M2M_REQ_GROUP_WIFI == strHif.u8Gid)
482 				{
483 					if(gstrHifCxt.pfWifiCb)
484 						gstrHifCxt.pfWifiCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
485 					else
486 						M2M_ERR("WIFI callback is not registered\n");
487 
488 				}
489 				else if(M2M_REQ_GROUP_IP == strHif.u8Gid)
490 				{
491 					if(gstrHifCxt.pfIpCb)
492 						gstrHifCxt.pfIpCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
493 					else
494 						M2M_ERR("Scoket callback is not registered\n");
495 
496 				}
497 				else if(M2M_REQ_GROUP_OTA == strHif.u8Gid)
498 				{
499 					if(gstrHifCxt.pfOtaCb)
500 						gstrHifCxt.pfOtaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
501 					else
502 						M2M_ERR("Ota callback is not registered\n");
503 
504 				}
505 				else if(M2M_REQ_GROUP_CRYPTO == strHif.u8Gid)
506 				{
507 					if(gstrHifCxt.pfCryptoCb)
508 						gstrHifCxt.pfCryptoCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
509 
510 					else
511 						M2M_ERR("Crypto callback is not registered\n");
512 				}
513 				else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid)
514 				{
515 					if(gstrHifCxt.pfSigmaCb)
516 						gstrHifCxt.pfSigmaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
517 					else
518 						M2M_ERR("Sigma callback is not registered\n");
519 				}
520 				else if(M2M_REQ_GROUP_SSL == strHif.u8Gid)
521 				{
522 				    if(gstrHifCxt.pfSslCb)
523 						gstrHifCxt.pfSslCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
524 				}
525 				else
526 				{
527 					M2M_ERR("(hif) invalid group ID\n");
528 					ret = M2M_ERR_BUS_FAIL;
529 					goto ERR1;
530 				}
531 				if(gstrHifCxt.u8HifRXDone)
532 				{
533 					M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode);
534 					ret = hif_set_rx_done();
535 					if(ret != M2M_SUCCESS) goto ERR1;
536 				}
537 			}
538 			else
539 			{
540 				M2M_ERR("(hif) Wrong Size\n");
541 				ret = M2M_ERR_RCV;
542 				goto ERR1;
543 			}
544 		}
545 		else
546 		{
547 #ifndef WIN32
548 			M2M_ERR("(hif) False interrupt %lx",reg);
549 			ret = M2M_ERR_FAIL;
550 			goto ERR1;
551 #else
552 #endif
553 		}
554 	}
555 	else
556 	{
557 		M2M_ERR("(hif) Fail to Read interrupt reg\n");
558 		goto ERR1;
559 	}
560 
561 ERR1:
562 	return ret;
563 }
564 
565 /**
566 *	@fn		hif_handle_isr(void)
567 *	@brief	Handle interrupt received from NMC1500 firmware.
568 *   @return     The function SHALL return 0 for success and a negative value otherwise.
569 */
570 
hif_handle_isr(void)571 sint8 hif_handle_isr(void)
572 {
573 	sint8 ret = M2M_SUCCESS;
574 	while (gstrHifCxt.u8Interrupt) {
575 		/*must be at that place because of the race of interrupt increment and that decrement*/
576 		/*when the interrupt enabled*/
577 		gstrHifCxt.u8Interrupt--;
578 		while(1)
579 		{
580 			ret = hif_isr();
581 			if(ret == M2M_SUCCESS) {
582 				/*we will try forever untill we get that interrupt*/
583 				/*Fail return errors here due to bus errors (reading expected values)*/
584 				break;
585 			} else {
586 				M2M_ERR("(HIF) Fail to handle interrupt %d try Again..\n",ret);
587 			}
588 		}
589 	}
590 
591 	return ret;
592 }
593 /*
594 *	@fn		hif_receive
595 *	@brief	Host interface interrupt serviece routine
596 *	@param [in]	u32Addr
597 *				Receive start address
598 *	@param [out]	pu8Buf
599 *				Pointer to receive buffer. Allocated by the caller
600 *	@param [in]	u16Sz
601 *				Receive buffer size
602 *	@param [in]	isDone
603 *				If you don't need any more packets send True otherwise send false
604 *    @return		The function shall return ZERO for successful operation and a negative value otherwise.
605 */
hif_receive(uint32 u32Addr,uint8 * pu8Buf,uint16 u16Sz,uint8 isDone)606 sint8 hif_receive(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz, uint8 isDone)
607 {
608 	sint8 ret = M2M_SUCCESS;
609 	if((u32Addr == 0)||(pu8Buf == NULL) || (u16Sz == 0))
610 	{
611 		if(isDone)
612 		{
613 			/* set RX done */
614 			ret = hif_set_rx_done();
615 		}
616 		else
617 		{
618 			ret = M2M_ERR_FAIL;
619 			M2M_ERR(" hif_receive: Invalid argument\n");
620 		}
621 		goto ERR1;
622 	}
623 
624 	if(u16Sz > gstrHifCxt.u32RxSize)
625 	{
626 		ret = M2M_ERR_FAIL;
627 		M2M_ERR("APP Requested Size is larger than the recived buffer size <%u><%lu>\n",u16Sz, gstrHifCxt.u32RxSize);
628 		goto ERR1;
629 	}
630 	if((u32Addr < gstrHifCxt.u32RxAddr)||((u32Addr + u16Sz)>(gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize)))
631 	{
632 		ret = M2M_ERR_FAIL;
633 		M2M_ERR("APP Requested Address beyond the recived buffer address and length\n");
634 		goto ERR1;
635 	}
636 
637 	/* Receive the payload */
638 	ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
639 	if(ret != M2M_SUCCESS)goto ERR1;
640 
641 	/* check if this is the last packet */
642 	if((((gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize) - (u32Addr + u16Sz)) <= 0) || isDone)
643 	{
644 		/* set RX done */
645 		ret = hif_set_rx_done();
646 	}
647 
648 ERR1:
649 	return ret;
650 }
651 
652 /**
653 *	@fn		hif_register_cb
654 *	@brief	To set Callback function for every compantent Component
655 *	@param [in]	u8Grp
656 *				Group to which the Callback function should be set.
657 *	@param [in]	fn
658 *				function to be set
659 *    @return		The function shall return ZERO for successful operation and a negative value otherwise.
660 */
661 
hif_register_cb(uint8 u8Grp,tpfHifCallBack fn)662 sint8 hif_register_cb(uint8 u8Grp,tpfHifCallBack fn)
663 {
664 	sint8 ret = M2M_SUCCESS;
665 	switch(u8Grp)
666 	{
667 		case M2M_REQ_GROUP_IP:
668 			gstrHifCxt.pfIpCb = fn;
669 			break;
670 		case M2M_REQ_GROUP_WIFI:
671 			gstrHifCxt.pfWifiCb = fn;
672 			break;
673 		case M2M_REQ_GROUP_OTA:
674 			gstrHifCxt.pfOtaCb = fn;
675 			break;
676 		case M2M_REQ_GROUP_HIF:
677 			gstrHifCxt.pfHifCb = fn;
678 			break;
679 		case M2M_REQ_GROUP_CRYPTO:
680 			gstrHifCxt.pfCryptoCb = fn;
681 			break;
682 		case M2M_REQ_GROUP_SIGMA:
683 			gstrHifCxt.pfSigmaCb = fn;
684 			break;
685 		case M2M_REQ_GROUP_SSL:
686 			gstrHifCxt.pfSslCb = fn;
687 			break;
688 		default:
689 			M2M_ERR("GRp ? %d\n",u8Grp);
690 			ret = M2M_ERR_FAIL;
691 			break;
692 	}
693 	return ret;
694 }
695 
696 #endif
697