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 *****************************************************************************/ 72 static 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 ****************************************************************************/ 85 TI_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 ****************************************************************************/ 127 int 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 ****************************************************************************/ 158 static 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 ****************************************************************************/ 223 TI_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 ****************************************************************************/ 272 TI_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 ****************************************************************************/ 291 int 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 319 UINT32 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 328 void 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 335 void 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 342 void 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 351 void 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 376 UINT32 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 */ 409 void whalBus_TNETWIF_HandleBusTxn_Complete (TI_HANDLE hWhalBus) 410 { 411 TNETWIF_BusTxn_Complete (((whalBus_T *)hWhalBus)->hTNETWIF); 412 } 413 414 void 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 439 void 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 ****************************************************************************/ 470 int 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 ****************************************************************************/ 491 int 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