1/****************************************************************************
2**+-----------------------------------------------------------------------+**
3**|                                                                       |**
4**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
5**| All rights reserved.                                                  |**
6**|                                                                       |**
7**| Redistribution and use in source and binary forms, with or without    |**
8**| modification, are permitted provided that the following conditions    |**
9**| are met:                                                              |**
10**|                                                                       |**
11**|  * Redistributions of source code must retain the above copyright     |**
12**|    notice, this list of conditions and the following disclaimer.      |**
13**|  * Redistributions in binary form must reproduce the above copyright  |**
14**|    notice, this list of conditions and the following disclaimer in    |**
15**|    the documentation and/or other materials provided with the         |**
16**|    distribution.                                                      |**
17**|  * Neither the name Texas Instruments nor the names of its            |**
18**|    contributors may be used to endorse or promote products derived    |**
19**|    from this software without specific prior written permission.      |**
20**|                                                                       |**
21**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
22**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
23**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
24**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
25**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
26**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
27**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
28**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
29**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
30**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
31**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
32**|                                                                       |**
33**+-----------------------------------------------------------------------+**
34****************************************************************************/
35
36/****************************************************************************
37 *
38 *   MODULE:  whalBus_Api.c
39 *   PURPOSE: shared memory bus access component API
40 *
41 ****************************************************************************/
42#include "whalCommon.h"
43#include "whalCtrl.h"
44#include "whalBus_Api.h"
45#include "shmBus.h"
46#include "TNETWIF.h"
47#include "TNETWArb.h"
48#include "TNETW_Driver.h"
49#include "whalHwAccess.h"
50#include "CmdMBox_api.h"
51#include "eventMbox_api.h"
52#include "FwEvent_api.h"
53
54
55/* Handle return status inside a state machine */
56#define EXCEPT(pwhalbus,status)                                 \
57    switch (status) {                                           \
58        case OK:                                                \
59        case TNETWIF_COMPLETE:                                  \
60             break;                                             \
61        case TNETWIF_PENDING:                                   \
62             return;                                            \
63        default:                                                \
64             whal_hwCtrl_FinalizeOnFailure (pwhalbus->hHwCtrl); \
65             return;                                            \
66    }
67
68
69 /****************************************************************************
70 *                      static function declaration
71 *****************************************************************************/
72static void whalBus_ConfigSm (TI_HANDLE hWhalBus, UINT8 module_id, TI_STATUS status);
73
74 /****************************************************************************
75 *                      whalBus_Create()
76 ****************************************************************************
77 * DESCRIPTION: Create the Bus access component
78 *
79 * INPUTS:
80 *
81 * OUTPUT:  None
82 *
83 * RETURNS: The Created object
84 ****************************************************************************/
85TI_HANDLE whalBus_Create (TI_HANDLE hOs)
86{
87    whalBus_T *pWhalBus;
88
89    pWhalBus = os_memoryAlloc (hOs, sizeof(whalBus_T));
90    if (pWhalBus == NULL)
91        return NULL;
92
93    os_memoryZero (hOs, pWhalBus, sizeof(whalBus_T));
94
95    pWhalBus->hOs = hOs;
96
97    pWhalBus->hTNETWIF  = TNETWIF_Create (hOs);
98    pWhalBus->pHwEeprom = whal_hwEeprom_Create (hOs);
99
100  #ifdef TI_DBG
101    pWhalBus->pTrc      = whal_traceCreate(hOs);
102  #else
103    pWhalBus->pTrc      = NULL;
104  #endif
105
106    if (!pWhalBus->hTNETWIF || !pWhalBus->pHwEeprom)
107    {
108        whalBus_Destroy ((TI_HANDLE)pWhalBus);
109        return NULL;
110    }
111
112    return (TI_HANDLE)pWhalBus;
113}
114
115/****************************************************************************
116 *                      whalBus_Destroy()
117 ****************************************************************************
118 * DESCRIPTION: Destroy the object
119 *
120 * INPUTS:
121 *      hWhalBus        The object to free
122 *
123 * OUTPUT:  None
124 *
125 * RETURNS: OK or NOK
126 ****************************************************************************/
127int whalBus_Destroy(TI_HANDLE hWhalBus)
128{
129    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
130
131    if (pWhalBus == NULL)
132        return OK;
133
134    whal_hwEeprom_Destroy(pWhalBus->pHwEeprom);
135
136#ifdef TI_DBG
137    whal_traceDestroy(pWhalBus->pTrc);
138#endif
139    TNETWIF_Destroy(pWhalBus->hTNETWIF);
140
141    os_memoryFree(pWhalBus->hOs, pWhalBus, sizeof(whalBus_T));
142    return OK;
143}
144
145
146/****************************************************************************
147 *                      whalBus_ConfigSm()
148 ****************************************************************************
149 * DESCRIPTION: Config the object
150 *
151 * INPUTS:
152 *      hWhalBus        The object to free
153 *
154 * OUTPUT:  None
155 *
156 * RETURNS: OK or NOK
157 ****************************************************************************/
158static void whalBus_ConfigSm (TI_HANDLE hWhalBus, UINT8 module_id, TI_STATUS status)
159{
160    whalBus_T  *pWhalBus  = (whalBus_T *)hWhalBus;
161    WHAL_CTRL  *pWhalCtrl = (WHAL_CTRL *)pWhalBus->hWhalCtrl;
162    TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)pWhalCtrl->hTNETW_Driver;
163
164    /* Pass the TNETWIF handle in each SHM Bus Module : HwIntr,HwRx,HwTx,Hw_Mbox,Hw_EventMbox */
165    /* From now on these modules will  be using only the TNETWIF handle and this one will send the request to the HwAccess module */
166    switch (pWhalBus->uInitStage)
167    {
168    case 0:
169        pWhalBus->uInitStage ++;
170        whal_hwEeprom_Config (pWhalBus->pHwEeprom, pWhalBus->hTNETWIF, pWhalBus->hReport);
171
172        /* disable interrupts */
173        status = TNETWIF_WriteRegOpt (pTnetwDrv->hTNETWIF,
174                                      ACX_REG_INTERRUPT_MASK,
175                                      ACX_INTR_ALL,
176                                      HAL_INIT_MODULE_ID,
177                                      whalBus_ConfigSm,
178                                      hWhalBus);
179        EXCEPT (pWhalBus, status)
180
181    case 1:
182        pWhalBus->uInitStage = 0;
183
184        CmdMBox_Config (pTnetwDrv->hCmdMBox,
185                        pWhalBus->hTNETWIF,
186                        pTnetwDrv->hFwEvent,
187                        pTnetwDrv->hCmdQueue,
188                        pWhalBus->hReport);
189
190        eventMbox_Config (pTnetwDrv->hEventMbox,
191                          pTnetwDrv->hTNETWIF,
192                          pTnetwDrv->hHwIntr,
193                          pTnetwDrv->hReport,
194                          pTnetwDrv->hFwEvent,
195                          pTnetwDrv->hHalCtrl);
196
197      #ifdef TI_DBG
198        /* Initiate the trace object */
199        whal_traceConfig (pWhalBus->pTrc, pWhalBus->hTNETWIF, pWhalBus->hReport);
200      #endif
201
202        /* Call upper module callback */
203        pWhalBus->fCb (pWhalBus->hCb, status);
204
205        WLAN_REPORT_INIT (pWhalBus->hReport, HAL_HW_CTRL_MODULE_LOG,
206                          ("whalBus_Config: EXITING SUCCESS !!!\n"));
207    }
208}
209
210
211/****************************************************************************
212 *                      whalBus_Config()
213 ****************************************************************************
214 * DESCRIPTION: Config the object
215 *
216 * INPUTS:
217 *      hWhalBus        The object to free
218 *
219 * OUTPUT:  None
220 *
221 * RETURNS: OK or NOK
222 ****************************************************************************/
223TI_STATUS whalBus_Config
224(
225    TI_HANDLE hWhalBus,
226    TI_HANDLE hWhalCtrl,
227    UINT8     AccessMode,
228    UINT32    RegBaseAddr,
229    UINT32    MemBaseAddr,
230    TI_HANDLE hReport,
231    TI_HANDLE hMemMgr,
232    fnotify_t fCb,
233    TI_HANDLE hCb
234)
235{
236    whalBus_T  *pWhalBus  = (whalBus_T *)hWhalBus;
237    WHAL_CTRL  *pWhalCtrl = (WHAL_CTRL *)hWhalCtrl;
238    TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)pWhalCtrl->hTNETW_Driver;
239
240    if (pWhalBus == NULL)
241        return OK;
242
243    pWhalBus->hReport = hReport;
244    pWhalBus->hTnetwDrv = (TI_HANDLE)pTnetwDrv;
245    pWhalBus->hWhalCtrl = hWhalCtrl;
246    pWhalBus->fCb = fCb;
247    pWhalBus->hCb = hCb;
248    pWhalBus->uInitStage = 0;
249
250    /* Call the TNETWIF Configuration */
251    return TNETWIF_Config (pWhalBus->hTNETWIF,
252                           hReport,
253                           RegBaseAddr,
254                           MemBaseAddr,
255                           whalBus_ConfigSm,
256                           hWhalBus);
257}
258
259
260/****************************************************************************
261 *                      whalBus_GetTnentwifHandle()
262 ****************************************************************************
263 * DESCRIPTION: Return TNETWIF handle
264 *
265 * INPUTS:
266 *      hWhalBus        The object handle
267 *
268 * OUTPUT:  None
269 *
270 * RETURNS: TNETWIF handle
271 ****************************************************************************/
272TI_HANDLE whalBus_GetTnentwifHandle (TI_HANDLE hWhalBus)
273{
274    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
275
276    return pWhalBus->hTNETWIF;
277}
278
279/****************************************************************************
280 *                      whalBus_ExitFromInitMode()
281 ****************************************************************************
282 * DESCRIPTION: Change the state of the Bus Access After init
283 *
284 * INPUTS:
285 *      hWhalBus        The object handle
286 *
287 * OUTPUT:  None
288 *
289 * RETURNS: OK or NOK
290 ****************************************************************************/
291int whalBus_ExitFromInitMode(TI_HANDLE hWhalBus)
292{
293    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
294    TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)pWhalBus->hTnetwDrv;
295  #if defined(USE_SYNC_API)
296    UINT32      uIntVect;
297  #endif
298
299    /* Set The Bus Access Mbox to Work in Async Mode */
300    CmdMBox_SetModeNormal (pTnetwDrv->hCmdMBox);
301
302  #if defined(USE_SYNC_API)
303
304    uIntVect = FwEvent_GetEnabled (pTnetwDrv->hFwEvent);
305
306    /* Clearing all the interrupt status register sources */
307    TNETWIF_WriteRegSync (pWhalBus->hTNETWIF, ACX_REG_INTERRUPT_MASK, ~uIntVect);
308
309  #endif
310
311    return OK;
312}
313/*
314 * --------------------------------------------------------------
315 *                  Registers/Memory access API
316 * --------------------------------------------------------------
317 */
318
319UINT32 whalBus_MacRegRead(TI_HANDLE hWhalBus, UINT32 RegAddr)
320{
321    UINT32 data = 0;
322  #ifdef USE_SYNC_API
323    TNETWIF_ReadRegSync(((whalBus_T *)hWhalBus)->hTNETWIF,RegAddr,(UINT32 *)&data);
324  #endif
325    return data;
326}
327
328void whalBus_MacRegWrite(TI_HANDLE hWhalBus, UINT32 RegAddr, UINT32 Val)
329{
330  #ifdef USE_SYNC_API
331    TNETWIF_WriteRegSync(((whalBus_T *)hWhalBus)->hTNETWIF, RegAddr, Val);
332  #endif
333}
334
335void whalBus_MemCopyTo (TI_HANDLE hWhalBus, char *DestOffset, char *Src, int Len)
336{
337  #ifdef USE_SYNC_API
338    TNETWIF_WriteMemSync(((whalBus_T *)hWhalBus)->hTNETWIF,(UINT32)DestOffset,(UINT8*)Src,Len);
339  #endif
340}
341
342void whalBus_MemCopyFrom (TI_HANDLE hWhalBus, UINT8 *Dest, char *SrcOffset, int Len)
343{
344  #ifdef USE_SYNC_API
345    TNETWIF_ReadMemSync(((whalBus_T *)hWhalBus)->hTNETWIF,(UINT32)SrcOffset,Dest,Len);
346  #endif
347}
348
349#define WRITE_PHY_NUM_RETRIES     4
350
351void    whalBus_PhyRegWrite      (TI_HANDLE hWhalBus, UINT32 PhyRegAddr, UINT32 DataVal)
352{
353  #ifdef USE_SYNC_API
354    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
355    int NumRetries=1;
356    UINT32 data;
357    TNETWIF_WriteRegSync(pWhalBus->hTNETWIF, ACX_PHY_ADDR_REG, PhyRegAddr);
358    TNETWIF_WriteRegSync(pWhalBus->hTNETWIF, ACX_PHY_DATA_REG, DataVal);
359    TNETWIF_WriteRegSync(pWhalBus->hTNETWIF, ACX_PHY_CTRL_REG, ACX_PHY_REG_WR_MASK);
360
361    os_StalluSec(pWhalBus->hOs, 10000);
362
363    /* wait for write complete */
364        TNETWIF_ReadRegSync(pWhalBus->hTNETWIF,ACX_PHY_CTRL_REG,&data);
365    while (data  && (NumRetries < WRITE_PHY_NUM_RETRIES))
366    {
367        NumRetries++;
368        WLAN_REPORT_REPLY(pWhalBus->hReport, HAL_HW_CTRL_MODULE_LOG,
369                          ("ACX_PHY_CTRL_REG Write, Addr - %#x  Data - %#x, retry\n", PhyRegAddr, DataVal));
370        os_StalluSec(pWhalBus->hOs, 10000);
371                TNETWIF_ReadRegSync(pWhalBus->hTNETWIF,ACX_PHY_CTRL_REG,&data);
372    }
373  #endif
374}
375
376UINT32  whalBus_PhyRegRead (TI_HANDLE hWhalBus, UINT32 PhyRegAddr)
377{
378    UINT32  DataVal = 0;
379  #ifdef USE_SYNC_API
380    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
381    int NumRetries=1;
382    UINT32 data;
383    TNETWIF_WriteRegSync(pWhalBus->hTNETWIF, ACX_PHY_ADDR_REG, PhyRegAddr);
384    TNETWIF_WriteRegSync(pWhalBus->hTNETWIF, ACX_PHY_CTRL_REG, ACX_PHY_REG_RD_MASK);
385    os_StalluSec(pWhalBus->hOs, 10000);
386
387    /* wait for write complete */
388    TNETWIF_ReadRegSync(pWhalBus->hTNETWIF,ACX_PHY_CTRL_REG,&data);
389    while ( data  && (NumRetries < WRITE_PHY_NUM_RETRIES))
390    {
391        NumRetries++;
392        WLAN_REPORT_REPLY(pWhalBus->hReport, HAL_HW_CTRL_MODULE_LOG,
393                          ("ACX_PHY_CTRL_REG Read, Addr - %#x  retry\n", PhyRegAddr));
394        os_StalluSec(pWhalBus->hOs, 10000);
395        TNETWIF_ReadRegSync(pWhalBus->hTNETWIF,ACX_PHY_CTRL_REG,&data);
396    }
397
398    TNETWIF_ReadRegSync(pWhalBus->hTNETWIF,ACX_PHY_DATA_REG,&DataVal);
399  #endif
400    return DataVal;
401}
402
403
404/*
405 * --------------------------------------------------------------
406 *                  Interrupt handler API
407 * --------------------------------------------------------------
408 */
409void whalBus_TNETWIF_HandleBusTxn_Complete  (TI_HANDLE hWhalBus)
410{
411    TNETWIF_BusTxn_Complete (((whalBus_T *)hWhalBus)->hTNETWIF);
412}
413
414void    whalBus_performHealthMonitorTest(TI_HANDLE hWhalBus, UINT32 test)
415{
416#ifdef TI_DBG
417    switch (test) {
418
419    case 1:
420        WLAN_OS_REPORT(("HAL Perform Health Monitor MBOX Test\n"));
421        break;
422#if 0
423    case 2:
424        WLAN_OS_REPORT(("HAL Perform Health Monitor TX STUCK Test\n"));
425        whal_hwTx_performHealthMonitorTest(((whalBus_T *)hWhalBus)->pHwTx);
426        break;
427#endif
428    }
429#endif
430}
431
432/* Dummy function */
433/*
434 * --------------------------------------------------------------
435 *                  Debug API
436 * --------------------------------------------------------------
437 */
438#ifdef TI_DBG
439void whalBus_PrintInfo(TI_HANDLE hWhalBus, UINT32 funcType, void *pParam)
440{
441    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
442
443    switch (funcType)
444    {
445    case BUS_PRINT_ARBITER:
446        TNETWArb_PrintStat (((TNETWIF_t*)pWhalBus->hTNETWIF)->hTNETWArb);
447        break;
448
449    default:
450        WLAN_OS_REPORT(("%s: Invalid function type: %d\n\n", __FUNCTION__, funcType));
451        break;
452    }
453}
454#endif
455
456
457
458/****************************************************************************
459 *                      whalBus_ReConfig()
460 ****************************************************************************
461 * DESCRIPTION: ReConfig the object (In case of recovery)
462 *
463 * INPUTS:
464 *      hWhalBus        The object to free
465 *
466 * OUTPUT:  None
467 *
468 * RETURNS: OK or NOK
469 ****************************************************************************/
470int whalBus_ReConfig(TI_HANDLE hWhalBus )
471{
472    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
473    /*Add a function in HwAccess that Reconfig (SDIO_Stop/SDIO_Start) and also in SPI */
474    TNETWIF_ReConfig(pWhalBus->hTNETWIF);
475    return OK;
476}
477
478/****************************************************************************
479 *                      whalBus_TNETWIF_ElpCtrl_SetMode()
480 ****************************************************************************
481 * DESCRIPTION: wrapper function for the lower TNETWIF_ElpCtrl_Mode
482 *
483 * INPUTS:
484 *      hWhalBus        The current context handle
485 *      mode            The ElpCtrl mode
486 *
487 * OUTPUT:  None
488 *
489 * RETURNS: OK or NOK
490 ****************************************************************************/
491int whalBus_TNETWIF_ElpCtrl_SetMode(TI_HANDLE hWhalBus, elpCtrl_Mode_e mode)
492{
493    whalBus_T *pWhalBus = (whalBus_T *)hWhalBus;
494
495    return TNETWIF_ElpCtrl_Mode(pWhalBus->hTNETWIF,mode);
496}
497
498
499