1 /* 2 * SwitchChannel.c 3 * 4 * Copyright(c) 1998 - 2010 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 /** \file SwitchChannel.c 35 * \brief SwitchChannel module interface 36 * 37 * \see SwitchChannelApi.h 38 */ 39 40 /****************************************************************************************************/ 41 /* */ 42 /* MODULE: SwitchChannel.c */ 43 /* PURPOSE: SwitchChannel module interface. */ 44 /* This module perform SwitchChannel (Dynamic Frequency Selection) */ 45 /* according to AP command. The object responsibles for switching channel after*/ 46 /* the requires time and quieting the channel for the required duration */ 47 /* time. */ 48 /****************************************************************************************************/ 49 50 #define __FILE_ID__ FILE_ID_7 51 #include "tidef.h" 52 #include "report.h" 53 #include "osApi.h" 54 #include "paramOut.h" 55 #include "SwitchChannelApi.h" 56 #include "DataCtrl_Api.h" 57 #include "regulatoryDomainApi.h" 58 #include "apConn.h" 59 #include "siteMgrApi.h" 60 #include "PowerMgr_API.h" 61 #include "healthMonitor.h" 62 #include "TWDriver.h" 63 #include "DrvMainModules.h" 64 65 /* allocation vector */ 66 #define SC_INIT_BIT (1) 67 #define SC_SM_INIT_BIT (2) 68 69 #define SC_SWITCH_CHANNEL_CMD_LEN 3 70 #define SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS 0 71 #define SC_SWITCH_CHANNEL_MODE_TX_SUS 1 72 73 74 #define SC_CHANNEL_INVALID TI_FALSE 75 #define SC_CHANNEL_VALID TI_TRUE 76 77 /* Enumerations */ 78 79 /** state machine states */ 80 typedef enum 81 { 82 SC_STATE_IDLE = 0, 83 SC_STATE_WAIT_4_CMD = 1, 84 SC_STATE_WAIT_4_SCR = 2, 85 SC_STATE_SC_IN_PROG = 3, 86 SC_STATE_LAST = 4 87 } switchChannel_smStates; 88 89 /** State machine events */ 90 typedef enum 91 { 92 SC_EVENT_START = 0, 93 SC_EVENT_STOP = 1, 94 SC_EVENT_SC_CMD = 2, 95 SC_EVENT_SCR_RUN = 3, 96 SC_EVENT_SCR_FAIL = 4, 97 SC_EVENT_SC_CMPLT = 5, 98 SC_EVENT_FW_RESET = 6, 99 SC_EVENT_LAST = 7 100 } switchChannel_smEvents; 101 102 103 #define SC_NUM_STATES SC_STATE_LAST 104 #define SC_NUM_EVENTS SC_EVENT_LAST 105 106 107 /* Structures */ 108 typedef struct 109 { 110 111 /* SwitchChannel parameters that can be configured externally */ 112 TI_BOOL dot11SpectrumManagementRequired; 113 114 /* Internal SwitchChannel parameters */ 115 TI_UINT8 currentState; 116 dot11_CHANNEL_SWITCH_t curChannelSwitchCmdParams; 117 TI_UINT32 SCRRequestTimestamp; 118 TI_UINT8 currentChannel; 119 TI_BOOL switchChannelStarted; 120 121 #ifdef TI_DBG 122 /* switchChannelCmd for debug */ 123 dot11_CHANNEL_SWITCH_t debugChannelSwitchCmdParams; 124 TI_UINT8 ignoreCancelSwitchChannelCmd; 125 #endif 126 127 /* SwitchChannel SM */ 128 fsm_stateMachine_t *pSwitchChannelSm; 129 130 /* SwitchChannel handles to other objects */ 131 TI_HANDLE hTWD; 132 TI_HANDLE hSiteMgr; 133 TI_HANDLE hSCR; 134 TI_HANDLE hRegulatoryDomain; 135 TI_HANDLE hPowerMngr; 136 TI_HANDLE hApConn; 137 TI_HANDLE hReport; 138 TI_HANDLE hOs; 139 140 } switchChannel_t; 141 142 143 144 145 /* External data definitions */ 146 147 /* Local functions definitions */ 148 149 /* Global variables */ 150 151 152 /********************************************************************************/ 153 /* Internal functions prototypes. */ 154 /********************************************************************************/ 155 156 157 /* SM functions */ 158 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData); 159 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData); 160 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData); 161 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData); 162 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData); 163 static TI_STATUS switchChannel_smNop(void *pData); 164 static TI_STATUS switchChannel_smUnexpected(void *pData); 165 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData); 166 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData); 167 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData); 168 static TI_STATUS switchChannel_smStart(void *pData); 169 170 171 /* other functions */ 172 static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec); 173 static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data); 174 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel); 175 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel); 176 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus, 177 EScrResourceId eResource, EScePendReason pendReason ); 178 #ifdef TI_DBG 179 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel); 180 #endif 181 182 183 /********************************************************************************/ 184 /* Interface functions Implementation. */ 185 /********************************************************************************/ 186 187 188 /************************************************************************ 189 * switchChannel_create * 190 ************************************************************************/ 191 /** 192 * 193 * \b Description: 194 * 195 * This procedure is called by the config manager when the driver is created. 196 * It creates the SwitchChannel object. 197 * 198 * \b ARGS: 199 * 200 * I - hOs - OS context \n 201 * 202 * \b RETURNS: 203 * 204 * Handle to the SwitchChannel object. 205 * 206 * \sa 207 */ 208 TI_HANDLE switchChannel_create(TI_HANDLE hOs) 209 { 210 switchChannel_t *pSwitchChannel = NULL; 211 TI_UINT32 initVec = 0; 212 TI_STATUS status; 213 214 /* allocating the SwitchChannel object */ 215 pSwitchChannel = os_memoryAlloc(hOs,sizeof(switchChannel_t)); 216 217 if (pSwitchChannel == NULL) 218 return NULL; 219 220 initVec |= (1 << SC_INIT_BIT); 221 222 os_memoryZero(hOs, pSwitchChannel, sizeof(switchChannel_t)); 223 224 pSwitchChannel->hOs = hOs; 225 226 status = fsm_Create(hOs, &pSwitchChannel->pSwitchChannelSm, SC_NUM_STATES, SC_NUM_EVENTS); 227 if (status != TI_OK) 228 { 229 release_module(pSwitchChannel, initVec); 230 WLAN_OS_REPORT(("FATAL ERROR: switchChannel_create(): Error Creating pSwitchChannelSm - Aborting\n")); 231 return NULL; 232 } 233 initVec |= (1 << SC_SM_INIT_BIT); 234 235 return(pSwitchChannel); 236 } 237 238 /************************************************************************ 239 * switchChannel_init * 240 ************************************************************************/ 241 /** 242 * 243 * \b Description: 244 * 245 * This procedure is called by the DrvMain when the driver is initialized. 246 * It initializes the SwitchChannel object's variables and handlers and creates the SwitchChannel SM. 247 * 248 * \b ARGS: 249 * 250 * I - pStadHandles - The driver modules handles \n 251 * 252 * \b RETURNS: 253 * 254 * void 255 * 256 * \sa 257 */ 258 void switchChannel_init (TStadHandlesList *pStadHandles) 259 { 260 switchChannel_t *pSwitchChannel = (switchChannel_t *)(pStadHandles->hSwitchChannel); 261 262 /** Roaming State Machine matrix */ 263 fsm_actionCell_t switchChannel_SM[SC_NUM_STATES][SC_NUM_EVENTS] = 264 { 265 /* next state and actions for IDLE state */ 266 { {SC_STATE_WAIT_4_CMD, switchChannel_smStart}, /* START */ 267 {SC_STATE_IDLE, switchChannel_smNop}, /* STOP */ 268 {SC_STATE_IDLE, switchChannel_smNop}, /* SC_CMD */ 269 {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SCR_RUN */ 270 {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SCR_FAIL */ 271 {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SC_CMPLT */ 272 {SC_STATE_IDLE, switchChannel_smUnexpected} /* FW_RESET */ 273 }, 274 275 /* next state and actions for WAIT_4_CMD state */ 276 { {SC_STATE_WAIT_4_CMD, switchChannel_smNop}, /* START */ 277 {SC_STATE_IDLE, switchChannel_smStopWhileWait4Cmd}, /* STOP */ 278 {SC_STATE_WAIT_4_SCR, switchChannel_smReqSCR_UpdateCmd}, /* SC_CMD */ 279 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_RUN */ 280 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_FAIL */ 281 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SC_CMPLT */ 282 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected} /* FW_RESET */ 283 284 }, 285 286 /* next state and actions for WAIT_4_SCR state */ 287 { {SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected}, /* START */ 288 {SC_STATE_IDLE, switchChannel_smStopWhileWait4Scr}, /* STOP */ 289 {SC_STATE_WAIT_4_SCR, switchChannel_smNop}, /* SC_CMD */ 290 {SC_STATE_SC_IN_PROG, switchChannel_smStartSwitchChannelCmd}, /* SCR_RUN */ 291 {SC_STATE_WAIT_4_CMD, switchChannel_smScrFailWhileWait4Scr}, /* SCR_FAIL */ 292 {SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected} , /* SC_CMPLT */ 293 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected} /* FW_RESET */ 294 295 }, 296 297 /* next state and actions for switchChannel_IN_PROG state */ 298 { {SC_STATE_SC_IN_PROG, switchChannel_smUnexpected}, /* START */ 299 {SC_STATE_IDLE, switchChannel_smStopWhileSwitchChannelInProg}, /* STOP */ 300 {SC_STATE_SC_IN_PROG, switchChannel_smNop}, /* SC_CMD */ 301 {SC_STATE_SC_IN_PROG, switchChannel_smUnexpected}, /* SCR_RUN */ 302 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_FAIL */ 303 {SC_STATE_WAIT_4_CMD, switchChannel_smSwitchChannelCmplt}, /* SC_CMPLT */ 304 {SC_STATE_WAIT_4_CMD, switchChannel_smFwResetWhileSCInProg} /* FW_RESET */ 305 } 306 }; 307 308 fsm_Config(pSwitchChannel->pSwitchChannelSm, 309 &switchChannel_SM[0][0], 310 SC_NUM_STATES, 311 SC_NUM_EVENTS, 312 switchChannel_smEvent, pSwitchChannel->hOs); 313 314 /* init handlers */ 315 pSwitchChannel->hTWD = pStadHandles->hTWD; 316 pSwitchChannel->hSiteMgr = pStadHandles->hSiteMgr; 317 pSwitchChannel->hSCR = pStadHandles->hSCR; 318 pSwitchChannel->hRegulatoryDomain = pStadHandles->hRegulatoryDomain; 319 pSwitchChannel->hApConn = pStadHandles->hAPConnection; 320 pSwitchChannel->hReport = pStadHandles->hReport; 321 pSwitchChannel->hOs = pStadHandles->hOs; 322 } 323 324 325 TI_STATUS switchChannel_SetDefaults (TI_HANDLE hSwitchChannel, SwitchChannelInitParams_t *SwitchChannelInitParams) 326 { 327 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; 328 329 /* init variables */ 330 pSwitchChannel->dot11SpectrumManagementRequired = SwitchChannelInitParams->dot11SpectrumManagementRequired; 331 pSwitchChannel->currentState = SC_STATE_IDLE; 332 pSwitchChannel->currentChannel = 0; 333 pSwitchChannel->switchChannelStarted = TI_FALSE; 334 335 /* register to SCR */ 336 scr_registerClientCB(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, 337 switchChannel_scrStatusCB, pSwitchChannel); 338 339 /* register to Switch Channel Complete event in HAL */ 340 TWD_RegisterEvent (pSwitchChannel->hTWD, 341 TWD_OWN_EVENT_SWITCH_CHANNEL_CMPLT, 342 (void *)switchChannel_SwitchChannelCmdCompleteReturn, 343 pSwitchChannel); 344 345 TWD_EnableEvent (pSwitchChannel->hTWD, TWD_OWN_EVENT_SWITCH_CHANNEL_CMPLT); 346 #ifdef TI_DBG 347 /* for debug */ 348 pSwitchChannel->debugChannelSwitchCmdParams.hdr[0] = CHANNEL_SWITCH_ANNOUNCEMENT_IE_ID; 349 pSwitchChannel->debugChannelSwitchCmdParams.hdr[1] = SC_SWITCH_CHANNEL_CMD_LEN; 350 pSwitchChannel->ignoreCancelSwitchChannelCmd = 0; 351 #endif 352 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INIT, ".....SwitchChannel configured successfully\n"); 353 354 return TI_OK; 355 } 356 357 358 /************************************************************************ 359 * switchChannel_stop * 360 ************************************************************************/ 361 /** 362 * 363 * \b Description: 364 * 365 * This procedure is called by the SME when the state is changed from CONNECTED. 366 * It generates a STOP event to the SwitchChannel SM. 367 * 368 * \b ARGS: 369 * 370 * I - hSwitchChannel - SwitchChannel context \n 371 * 372 * \b RETURNS: 373 * 374 * TI_OK on success, TI_NOK otherwise 375 * 376 * \sa 377 */ 378 TI_STATUS switchChannel_stop(TI_HANDLE hSwitchChannel) 379 { 380 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; 381 382 pSwitchChannel->switchChannelStarted = TI_FALSE; 383 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel)); 384 385 } 386 387 /************************************************************************ 388 * switchChannel_start * 389 ************************************************************************/ 390 /** 391 * 392 * \b Description: 393 * 394 * This procedure is called by the SME when the state is changed to CONNECTED. 395 * It generates a START event to the SwitchChannel SM. 396 * 397 * \b ARGS: 398 * 399 * I - hSwitchChannel - SwitchChannel context \n 400 * 401 * \b RETURNS: 402 * 403 * TI_OK on success, TI_NOK otherwise 404 * 405 * \sa 406 */ 407 TI_STATUS switchChannel_start(TI_HANDLE hSwitchChannel) 408 { 409 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; 410 pSwitchChannel->switchChannelStarted = TI_TRUE; 411 412 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel)); 413 414 } 415 416 417 /************************************************************************ 418 * switchChannel_unload * 419 ************************************************************************/ 420 /** 421 * 422 * \b Description: 423 * 424 * This procedure is called by the config manager when the driver is unloaded. 425 * It frees any memory allocated and timers. 426 * 427 * \b ARGS: 428 * 429 * I - hSwitchChannel - SwitchChannel context \n 430 * 431 * \b RETURNS: 432 * 433 * TI_OK on success, TI_NOK otherwise 434 * 435 * \sa 436 */ 437 TI_STATUS switchChannel_unload(TI_HANDLE hSwitchChannel) 438 { 439 TI_UINT32 initVec; 440 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; 441 442 if (pSwitchChannel == NULL) 443 return TI_OK; 444 445 initVec = 0xff; 446 release_module(pSwitchChannel, initVec); 447 448 return TI_OK; 449 } 450 451 452 /************************************************************************ 453 * switchChannel_recvCmd * 454 ************************************************************************/ 455 /*DESCRIPTION: This function is called by MLME Parser upon receiving of 456 Beacon, Probe Response or Action with Switch Channel command, 457 or beacon/ 458 performs the following: 459 - Initializes the switching channel procedure. 460 - Setting timer to the actual switching time(if needed) 461 462 INPUT: hSwitchChannel - SwitchChannel handle. 463 switchMode - indicates whether to stop transmission 464 until the scheduled channel switch. 465 newChannelNum - indicates the number of the new channel. 466 durationTime - indicates the time (expressed in ms) until 467 the scheduled channel switch should accure. 468 469 OUTPUT: None 470 471 RETURN: TI_OK on success, TI_NOK otherwise 472 473 ************************************************************************/ 474 475 void switchChannel_recvCmd(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_UINT8 channel) 476 { 477 478 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; 479 paramInfo_t param; 480 481 if (pSwitchChannel==NULL) 482 { 483 return; 484 } 485 486 param.paramType = REGULATORY_DOMAIN_DFS_CHANNELS_RANGE; 487 regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain, ¶m); 488 489 if (!pSwitchChannel->dot11SpectrumManagementRequired || 490 (channel < param.content.DFS_ChannelRange.minDFS_channelNum) || 491 (channel > param.content.DFS_ChannelRange.maxDFS_channelNum)) 492 { /* Do not parse Switch Channel IE, when SpectrumManagement is disabled, 493 or the channel is non-DFS channel */ 494 return; 495 } 496 #ifdef TI_DBG 497 /* for debug purposes only */ 498 if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0) 499 { 500 return; 501 } 502 #endif 503 504 if (channelSwitch == NULL) 505 { /* No SC IE, update regDomain */ 506 param.paramType = REGULATORY_DOMAIN_UPDATE_CHANNEL_VALIDITY; 507 param.content.channel = channel; 508 regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); 509 } 510 else 511 { /* SC IE exists */ 512 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n", channelSwitch->channelNumber, channelSwitch->channelSwitchMode, channelSwitch->channelSwitchCount); 513 514 /* Checking channel number validity */ 515 param.content.channel = channelSwitch->channelNumber; 516 param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; 517 regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m); 518 if ( ( !param.content.bIsChannelSupprted ) || 519 (channelSwitch->channelSwitchCount == 0) || 520 (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)) 521 { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid, 522 or the TBTT count is 0 */ 523 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "report Roaming trigger\n"); 524 if (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS) 525 { 526 param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY; 527 param.content.channelValidity.channelNum = channel; 528 param.content.channelValidity.channelValidity = TI_FALSE; 529 regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); 530 } 531 532 if (TI_TRUE == pSwitchChannel->switchChannelStarted) 533 { 534 apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL); 535 } 536 537 } 538 else 539 { /* Invoke Switch Channel command */ 540 /* update the new SCC params */ 541 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; 542 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; 543 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; 544 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel); 545 } 546 547 } 548 549 } 550 551 552 /************************************************************************ 553 * switchChannel_powerSaveStatusReturn * 554 ************************************************************************/ 555 /** 556 * 557 * \b Description: 558 * 559 * This procedure is called when power save status is returned 560 * 561 * \b ARGS: 562 * 563 * I/O - hSwitchChannel - SwitchChannel context \n 564 * 565 * \b RETURNS: 566 * 567 * TI_OK on success, TI_NOK otherwise. 568 * 569 * \sa 570 */ 571 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel) 572 { 573 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 574 575 if (pSwitchChannel == NULL) 576 { 577 return; 578 } 579 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_SwitchChannelCmdCompleteReturn \n"); 580 581 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMPLT, pSwitchChannel); 582 583 } 584 585 /************************************************************************ 586 * switchChannel_enableDisableSpectrumMngmt * 587 ************************************************************************/ 588 /** 589 * 590 * \b Description: 591 * 592 * This procedure enables or disables the spectrum management 593 * 594 * \b ARGS: 595 * 596 * I - hSwitchChannel - SwitchChannel context \n 597 * I - enableDisable - TI_TRUE - Enable, TI_FALSE - Disable 598 * 599 * \b RETURNS: 600 * 601 * TI_OK on success, TI_NOK otherwise. 602 * 603 * \sa 604 */ 605 void switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel, TI_BOOL enableDisable) 606 { 607 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 608 609 610 if (hSwitchChannel == NULL) 611 { 612 return; 613 } 614 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_enableDisableSpectrumMngmt, enableDisable=%d \n", enableDisable); 615 616 pSwitchChannel->dot11SpectrumManagementRequired = enableDisable; 617 618 if (enableDisable) 619 { /* Enable SC, if it was started invoke start event. 620 otherwise, wait for a start event */ 621 if (pSwitchChannel->switchChannelStarted) 622 { 623 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel); 624 } 625 } 626 else 627 { /* Disable SC */ 628 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel); 629 } 630 631 } 632 633 634 635 /************************************************************************ 636 * SwitchChannel internal functions * 637 ************************************************************************/ 638 639 /************************************************************************ 640 * switchChannel_smEvent * 641 ************************************************************************/ 642 /** 643 * 644 * \b Description: 645 * 646 * SwitchChannel state machine transition function 647 * 648 * \b ARGS: 649 * 650 * I/O - currentState - current state in the state machine\n 651 * I - event - specific event for the state machine\n 652 * I - pData - Data for state machine action function\n 653 * 654 * \b RETURNS: 655 * 656 * TI_OK on success, TI_NOK otherwise. 657 * 658 * \sa 659 */ 660 static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data) 661 { 662 TI_STATUS status; 663 TI_UINT8 nextState; 664 switchChannel_t *pSwitchChannel = (switchChannel_t*)data; 665 666 667 status = fsm_GetNextState(pSwitchChannel->pSwitchChannelSm, *currState, event, &nextState); 668 if (status != TI_OK) 669 { 670 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent, fsm_GetNextState error\n"); 671 return(TI_NOK); 672 } 673 674 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState); 675 676 status = fsm_Event(pSwitchChannel->pSwitchChannelSm, currState, event, (void *)pSwitchChannel); 677 678 if (status != TI_OK) 679 { 680 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent fsm_Event error\n"); 681 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState); 682 } 683 return status; 684 685 } 686 687 688 /************************************************************************ 689 * switchChannel_smStart * 690 ************************************************************************/ 691 /** 692 * 693 * 694 * \b Description: 695 * 696 * This function is called when the station becomes connected. 697 * update the current channel. 698 * 699 * \b ARGS: 700 * 701 * I - pData - pointer to the SwitchChannel SM context \n 702 * 703 * \b RETURNS: 704 * 705 * TI_OK if successful, TI_NOK otherwise. 706 * 707 * 708 *************************************************************************/ 709 static TI_STATUS switchChannel_smStart(void *pData) 710 { 711 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 712 paramInfo_t param; 713 714 if (pSwitchChannel == NULL) 715 { 716 return TI_NOK; 717 } 718 719 /* get the current channel number */ 720 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 721 siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m); 722 pSwitchChannel->currentChannel = param.content.siteMgrCurrentChannel; 723 724 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStart, channelNo=%d\n", pSwitchChannel->currentChannel); 725 return TI_OK; 726 727 } 728 729 /************************************************************************ 730 * switchChannel_smReqSCR_UpdateCmd * 731 ************************************************************************/ 732 /** 733 * 734 * 735 * \b Description: 736 * 737 * Update the Switch Channel command parameters. 738 * Request SCR and wait for SCR return. 739 * if tx status suspend 740 * update regulatory Domain 741 * update tx 742 * start periodic timer 743 744 * 745 * \b ARGS: 746 * 747 * I - pData - pointer to the SwitchChannel SM context \n 748 * 749 * \b RETURNS: 750 * 751 * TI_OK if successful, TI_NOK otherwise. 752 * 753 * 754 *************************************************************************/ 755 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData) 756 { 757 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 758 EScrClientRequestStatus scrStatus; 759 EScePendReason scrPendReason; 760 761 if (pSwitchChannel == NULL) 762 { 763 return TI_NOK; 764 } 765 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smReqSCR_UpdateCmd, channelNo=%d, TBTT = %d, Mode = %d\n", pSwitchChannel->curChannelSwitchCmdParams.channelNumber, pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount, pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode); 766 767 768 /* Save the TS when requesting SCR */ 769 pSwitchChannel->SCRRequestTimestamp = os_timeStampMs(pSwitchChannel->hOs); 770 771 scrStatus = scr_clientRequest(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, 772 SCR_RESOURCE_SERVING_CHANNEL, &scrPendReason); 773 if ((scrStatus != SCR_CRS_RUN) && (scrStatus != SCR_CRS_PEND)) 774 { 775 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smReqSCR_UpdateCmd():Abort the switch channel, request Roaming, scrStatus=%d\n", scrStatus); 776 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel)); 777 778 } 779 if (scrStatus == SCR_CRS_RUN) 780 { 781 switchChannel_scrStatusCB(pSwitchChannel, scrStatus, SCR_RESOURCE_SERVING_CHANNEL, scrPendReason); 782 } 783 else if ((scrPendReason==SCR_PR_OTHER_CLIENT_RUNNING) || 784 (scrPendReason==SCR_PR_DIFFERENT_GROUP_RUNNING) ) 785 { /* No use to wait for the SCR, invoke FAIL */ 786 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel)); 787 } 788 /* wait for the SCR callback function to be called */ 789 return TI_OK; 790 791 } 792 793 794 /************************************************************************ 795 * switchChannel_scrStatusCB * 796 ************************************************************************/ 797 /** 798 * 799 * 800 * \b Description: 801 * 802 * This function is called by the SCR when: 803 * the resource is reserved for the SwitchChannel - SCR_CRS_RUN 804 * recovery occurred - SCR_CRS_ABORT 805 * other = ERROR 806 * 807 * \b ARGS: 808 * 809 * I - hSwitchChannel - pointer to the SwitchChannel SM context \n 810 * I - requestStatus - the SCR request status \n 811 * I - eResource - the resource for which the CB is issued \n 812 * I - pendReason - The SCR pend status in case of pend reply \n 813 * 814 * \b RETURNS: 815 * 816 * None. 817 * 818 * 819 *************************************************************************/ 820 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus, 821 EScrResourceId eResource, EScePendReason pendReason ) 822 { 823 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 824 switchChannel_smEvents scEvent; 825 826 if (pSwitchChannel == NULL) 827 { 828 return; 829 } 830 831 switch (requestStatus) 832 { 833 case SCR_CRS_RUN: 834 scEvent = SC_EVENT_SCR_RUN; 835 break; 836 case SCR_CRS_FW_RESET: 837 scEvent = SC_EVENT_FW_RESET; 838 break; 839 case SCR_CRS_PEND: 840 scEvent = SC_EVENT_SCR_FAIL; 841 break; 842 case SCR_CRS_ABORT: 843 default: 844 TRACE2(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_scrStatusCB scrStatus = %d, pendReason=%d\n", requestStatus, pendReason); 845 scEvent = SC_EVENT_SCR_FAIL; 846 break; 847 } 848 849 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, scEvent, pSwitchChannel); 850 851 } 852 853 854 855 /************************************************************************ 856 * switchChannel_smStartSwitchChannelCmd * 857 ************************************************************************/ 858 /** 859 * 860 * 861 * \b Description: 862 * 863 * This function is called once SwitchChannel command was received and the SCR 864 * request returned with reason RUN. 865 * In this case perform the following: 866 * Set CMD to FW 867 868 869 * 870 * \b ARGS: 871 * 872 * I - pData - pointer to the SwitchChannel SM context \n 873 * 874 * \b RETURNS: 875 * 876 * TI_OK if successful, TI_NOK otherwise. 877 * 878 * 879 *************************************************************************/ 880 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData) 881 { 882 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; 883 TSwitchChannelParams pSwitchChannelCmd; 884 TI_UINT32 switchChannelTimeDuration; 885 paramInfo_t param; 886 887 if (pSwitchChannel == NULL) 888 { 889 return TI_NOK; 890 } 891 892 param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM; 893 siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m); 894 895 switchChannelTimeDuration = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount * param.content.beaconInterval * 1024 / 1000; 896 if ( (switchChannelTimeDuration!=0) && 897 ((os_timeStampMs(pSwitchChannel->hOs) - pSwitchChannel->SCRRequestTimestamp) >= switchChannelTimeDuration )) 898 { /* There's no time to perfrom the SCC, set the Count to 1 */ 899 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 1; 900 } 901 902 apConn_indicateSwitchChannelInProgress(pSwitchChannel->hApConn); 903 904 pSwitchChannelCmd.channelNumber = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; 905 pSwitchChannelCmd.switchTime = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount; 906 pSwitchChannelCmd.txFlag = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode; 907 pSwitchChannelCmd.flush = 0; 908 TWD_CmdSwitchChannel (pSwitchChannel->hTWD, &pSwitchChannelCmd); 909 910 TRACE4(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "TWD_CmdSwitchChannel:Set the cmd in HAL. Params:\n channelNumber=%d, switchTime=%d, txFlag=%d, flush=%d \n", pSwitchChannelCmd.channelNumber, pSwitchChannelCmd.switchTime, pSwitchChannelCmd.txFlag, pSwitchChannelCmd.flush); 911 912 return TI_OK; 913 914 } 915 916 /************************************************************************ 917 * switchChannel_smFwResetWhileSCInProg * 918 ************************************************************************/ 919 /** 920 * 921 * 922 * \b Description: 923 * 924 * This function is called when Switch Channel command is cancelled. 925 * In this case update TX nad regulatory Domain adn HAL. 926 * Release the SCR and exit PS. 927 * 928 * \b ARGS: 929 * 930 * I - pData - pointer to the SwitchChannel SM context \n 931 * 932 * \b RETURNS: 933 * 934 * TI_OK if successful, TI_NOK otherwise. 935 * 936 * 937 *************************************************************************/ 938 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData) 939 { 940 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; 941 paramInfo_t param; 942 943 if (pSwitchChannel == NULL) 944 { 945 return TI_NOK; 946 } 947 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smFwResetWhileSCInProg \n"); 948 949 /* Update new current channel */ 950 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 951 param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; 952 siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m); 953 954 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); 955 956 switchChannel_zeroDatabase(pSwitchChannel); 957 958 /* release the SCR */ 959 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 960 961 return TI_OK; 962 963 } 964 965 966 /************************************************************************ 967 * switchChannel_smSwitchChannelCmplt * 968 ************************************************************************/ 969 /** 970 * 971 * 972 * \b Description: 973 * 974 * This function is called when SwitchChannel command completed in FW. 975 * In this case release SCR and update current channel. 976 * If TX was sus, it will be enabled only after first Beacon is recieved. 977 * Exit PS. 978 * 979 * \b ARGS: 980 * 981 * I - pData - pointer to the SwitchChannel SM context \n 982 * 983 * \b RETURNS: 984 * 985 * TI_OK if successful, TI_NOK otherwise. 986 * 987 * 988 *************************************************************************/ 989 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData) 990 { 991 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; 992 paramInfo_t param; 993 994 if (pSwitchChannel == NULL) 995 { 996 return TI_NOK; 997 } 998 999 /* Update new current channel */ 1000 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 1001 param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; 1002 siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m); 1003 1004 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smSwitchChannelCmplt, new channelNum = %d\n", pSwitchChannel->currentChannel); 1005 1006 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); 1007 switchChannel_zeroDatabase(pSwitchChannel); 1008 1009 /* release the SCR */ 1010 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1011 1012 return TI_OK; 1013 1014 } 1015 1016 1017 1018 /************************************************************************ 1019 * switchChannel_smScrFailWhileWait4Scr * 1020 ************************************************************************/ 1021 /** 1022 * 1023 * 1024 * \b Description: 1025 * 1026 * This function is called when recovery occurred, while waiting for SCR due 1027 * to previous switch channel command. 1028 * Exit PS 1029 * Release SCR. 1030 * 1031 * \b ARGS: 1032 * 1033 * I - pData - pointer to the SwitchChannel SM context \n 1034 * 1035 * \b RETURNS: 1036 * 1037 * TI_OK if successful, TI_NOK otherwise. 1038 * 1039 * 1040 *************************************************************************/ 1041 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData) 1042 { 1043 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1044 1045 if (pSwitchChannel == NULL) 1046 { 1047 return TI_NOK; 1048 } 1049 1050 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smScrFailWhileWait4Scr\n"); 1051 1052 switchChannel_zeroDatabase(pSwitchChannel); 1053 1054 /* release the SCR is not required !!! */ 1055 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1056 1057 return TI_OK; 1058 } 1059 1060 /************************************************************************ 1061 * switchChannel_smStopWhileWait4Cmd * 1062 ************************************************************************/ 1063 /** 1064 * 1065 * 1066 * \b Description: 1067 * 1068 * This function is called when the station becomes Disconnected and the current 1069 * state is Wait4Cmd. In this case perfrom: 1070 * Stop the timer 1071 * Enable TX if it was disabled 1072 * Zero the current command parameters 1073 * Stop the timer 1074 * 1075 * \b ARGS: 1076 * 1077 * I - pData - pointer to the SwitchChannel SM context \n 1078 * 1079 * \b RETURNS: 1080 * 1081 * TI_OK if successful, TI_NOK otherwise. 1082 * 1083 * 1084 *************************************************************************/ 1085 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData) 1086 { 1087 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1088 1089 if (pSwitchChannel == NULL) 1090 { 1091 return TI_NOK; 1092 } 1093 1094 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Cmd\n"); 1095 1096 switchChannel_zeroDatabase(pSwitchChannel); 1097 1098 return TI_OK; 1099 } 1100 1101 /************************************************************************ 1102 * switchChannel_smStopWhileWait4Scr * 1103 ************************************************************************/ 1104 /** 1105 * 1106 * 1107 * \b Description: 1108 * 1109 * This function is called when the station becomes Disconnected and the current 1110 * state is Wait4Scr. In this case perfrom: 1111 * Stop the timer 1112 * Enable TX if it was disabled 1113 * Zero the current command parameters 1114 * Complete SCR 1115 * 1116 * \b ARGS: 1117 * 1118 * I - pData - pointer to the SwitchChannel SM context \n 1119 * 1120 * \b RETURNS: 1121 * 1122 * TI_OK if successful, TI_NOK otherwise. 1123 * 1124 * 1125 *************************************************************************/ 1126 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData) 1127 { 1128 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1129 1130 if (pSwitchChannel == NULL) 1131 { 1132 return TI_NOK; 1133 } 1134 1135 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Scr\n"); 1136 1137 1138 switchChannel_zeroDatabase(pSwitchChannel); 1139 1140 /* release the SCR */ 1141 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1142 1143 return TI_OK; 1144 } 1145 1146 /************************************************************************ 1147 * switchChannel_smStopWhileSwitchChannelInProg * 1148 ************************************************************************/ 1149 /** 1150 * 1151 * 1152 * \b Description: 1153 * 1154 * This function is called when the station becomes Disconnected and the current 1155 * state is SwitchChannelInProg. In this case perfrom: 1156 * Stop the timer 1157 * Enable TX if it was disabled 1158 * Zero the current command parameters 1159 * resume self test 1160 * Complete SCR 1161 * Exit PS 1162 * 1163 * \b ARGS: 1164 * 1165 * I - pData - pointer to the SwitchChannel SM context \n 1166 * 1167 * \b RETURNS: 1168 * 1169 * TI_OK if successful, TI_NOK otherwise. 1170 * 1171 * 1172 *************************************************************************/ 1173 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData) 1174 { 1175 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1176 1177 if (pSwitchChannel == NULL) 1178 { 1179 return TI_NOK; 1180 } 1181 1182 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileSwitchChannelInProg\n"); 1183 1184 /* Exit PS */ 1185 /*PowerMgr_exitFromDriverMode(pSwitchChannel->hPowerMngr, "SwitchChannel");*/ 1186 1187 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); 1188 1189 TWD_CmdSwitchChannelCancel (pSwitchChannel->hTWD, pSwitchChannel->currentChannel); 1190 switchChannel_zeroDatabase(pSwitchChannel); 1191 1192 /* release the SCR */ 1193 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1194 1195 return TI_OK; 1196 } 1197 1198 1199 1200 1201 /************************************************************************ 1202 * switchChannel_zeroDatabase * 1203 ************************************************************************/ 1204 /** 1205 * 1206 * 1207 * \b Description: 1208 * 1209 * This function is called when the SwitchChannel internal database should be zero. 1210 * The following parameters are zerod: 1211 * SwitchChannelChannelRange - the timestamps and validity state of channels 1212 * curChannelSwitchCmdParams - the current switch channel command parameters 1213 * 1214 * \b ARGS: 1215 * 1216 * I - pSwitchChannel - pointer to the SwitchChannel SM context \n 1217 * I - channelNum - channel number \n 1218 * I - timestamp - required timestamp \n 1219 * 1220 * \b RETURNS: 1221 * 1222 * None. 1223 * 1224 * 1225 *************************************************************************/ 1226 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel) 1227 { 1228 1229 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_zeroDatabase\n"); 1230 1231 1232 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = 0; 1233 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 0; 1234 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS; 1235 pSwitchChannel->currentChannel = 0; 1236 1237 } 1238 1239 /*********************************************************************** 1240 * release_module 1241 ***********************************************************************/ 1242 /* 1243 DESCRIPTION: Called by the destroy function or by the create function (on failure) 1244 Go over the vector, for each bit that is set, release the corresponding module. 1245 1246 INPUT: pSwitchChannel - SwitchChannel pointer. 1247 initVec - Vector that contains a bit set for each module thah had been initiualized 1248 1249 OUTPUT: 1250 1251 RETURN: TI_OK on success, TI_NOK otherwise 1252 1253 ************************************************************************/ 1254 static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec) 1255 { 1256 if (pSwitchChannel == NULL) 1257 { 1258 return; 1259 } 1260 if (initVec & (1 << SC_SM_INIT_BIT)) 1261 { 1262 fsm_Unload(pSwitchChannel->hOs, pSwitchChannel->pSwitchChannelSm); 1263 } 1264 1265 if (initVec & (1 << SC_INIT_BIT)) 1266 { 1267 os_memoryFree(pSwitchChannel->hOs, pSwitchChannel, sizeof(switchChannel_t)); 1268 } 1269 1270 initVec = 0; 1271 } 1272 1273 1274 /** 1275 * 1276 * switchChannel_smNop - Do nothing 1277 * 1278 * \b Description: 1279 * 1280 * Do nothing in the SM. 1281 * 1282 * \b ARGS: 1283 * 1284 * I - pData - pointer to the SwitchChannel SM context \n 1285 * 1286 * \b RETURNS: 1287 * 1288 * TI_OK if successful, TI_NOK otherwise. 1289 * 1290 * 1291 */ 1292 static TI_STATUS switchChannel_smNop(void *pData) 1293 { 1294 switchChannel_t *pSwitchChannel; 1295 1296 pSwitchChannel = (switchChannel_t*)pData; 1297 if (pSwitchChannel == NULL) 1298 { 1299 return TI_NOK; 1300 } 1301 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, " switchChannel_smNop\n"); 1302 1303 return TI_OK; 1304 } 1305 1306 /** 1307 * 1308 * switchChannel_smUnexpected - Unexpected event 1309 * 1310 * \b Description: 1311 * 1312 * Unexpected event in the SM. 1313 * 1314 * \b ARGS: 1315 * 1316 * I - pData - pointer to the SwitchChannel SM context \n 1317 * 1318 * \b RETURNS: 1319 * 1320 * TI_OK if successful, TI_NOK otherwise. 1321 * 1322 * 1323 */ 1324 static TI_STATUS switchChannel_smUnexpected(void *pData) 1325 { 1326 switchChannel_t *pSwitchChannel; 1327 1328 pSwitchChannel = (switchChannel_t*)pData; 1329 if (pSwitchChannel == NULL) 1330 { 1331 return TI_NOK; 1332 } 1333 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, " switchChannel_smUnexpected, state = %d\n", pSwitchChannel->currentState); 1334 1335 return TI_NOK; 1336 } 1337 1338 /******************************************************************************* 1339 *********** Debug functions *********** 1340 *******************************************************************************/ 1341 #ifdef TI_DBG 1342 1343 /************************************************************************ 1344 * switchChannel_recvCmd * 1345 ************************************************************************/ 1346 /*DESCRIPTION: This function is called by MLME Parser upon receiving of 1347 Beacon, Probe Response or Action with Switch Channel command, 1348 or beacon/ 1349 performs the following: 1350 - Initializes the switching channel procedure. 1351 - Setting timer to the actual switching time(if needed) 1352 1353 INPUT: hSwitchChannel - SwitchChannel handle. 1354 switchMode - indicates whether to stop transmission 1355 until the scheduled channel switch. 1356 newChannelNum - indicates the number of the new channel. 1357 durationTime - indicates the time (expressed in ms) until 1358 the scheduled channel switch should accure. 1359 1360 OUTPUT: None 1361 1362 RETURN: TI_OK on success, TI_NOK otherwise 1363 1364 ************************************************************************/ 1365 1366 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel) 1367 { 1368 1369 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; 1370 paramInfo_t param; 1371 1372 if (pSwitchChannel==NULL) 1373 { 1374 return; 1375 } 1376 1377 1378 /* The following is for debug purposes only 1379 It will be operated when the Switch Channel cmd is opertated from debug CLI */ 1380 if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0) 1381 { 1382 if (pSwitchChannel->ignoreCancelSwitchChannelCmd == 1) 1383 { 1384 /* update the new SCC params */ 1385 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; 1386 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; 1387 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; 1388 1389 pSwitchChannel->ignoreCancelSwitchChannelCmd = 2; 1390 } 1391 else if (channelSwitch->channelSwitchCount>0) 1392 { 1393 channelSwitch->channelSwitchCount --; 1394 } 1395 else 1396 { 1397 pSwitchChannel->ignoreCancelSwitchChannelCmd = 0; 1398 } 1399 1400 1401 /* search in the buffer pointer to the beginning of the 1402 Switch Cahnnel Announcement IE according to the IE ID */ 1403 1404 /* SC IE exists on the serving channel */ 1405 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n", channelSwitch->channelNumber, channelSwitch->channelSwitchMode, channelSwitch->channelSwitchCount); 1406 1407 /* Checking channel number validity */ 1408 param.content.channel = channelSwitch->channelNumber; 1409 param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; 1410 regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m); 1411 if (( !param.content.bIsChannelSupprted ) || 1412 (channelSwitch->channelSwitchCount == 0) || 1413 (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)) 1414 { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid, 1415 or the TBTT count is 0 */ 1416 apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL); 1417 } 1418 else 1419 { /* Invoke Switch Channel command */ 1420 /* update the new SCC params */ 1421 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; 1422 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; 1423 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; 1424 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel); 1425 } 1426 } 1427 1428 } 1429 1430 void switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel, SC_switchChannelCmdParam_e switchChannelCmdParam, TI_UINT8 param) 1431 { 1432 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1433 1434 if (pSwitchChannel == NULL) 1435 { 1436 return; 1437 } 1438 1439 switch (switchChannelCmdParam) 1440 { 1441 case SC_SWITCH_CHANNEL_NUM: 1442 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelNum=%d \n ", param)); 1443 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber = param; 1444 break; 1445 case SC_SWITCH_CHANNEL_TBTT: 1446 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchCount=%d \n ", param)); 1447 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount = param; 1448 break; 1449 case SC_SWITCH_CHANNEL_MODE: 1450 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchMode=%d \n ", param)); 1451 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode = param; 1452 break; 1453 default: 1454 WLAN_OS_REPORT(("ERROR: SwitchChannelDebug_setSwitchChannelCmdParams, wrong switchChannelCmdParam=%d \n ", 1455 switchChannelCmdParam)); 1456 break; 1457 } 1458 1459 } 1460 void switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket) 1461 { 1462 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1463 1464 if (pSwitchChannel == NULL) 1465 { 1466 return; 1467 } 1468 1469 WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n cmd params: channelNumber=%d, channelSwitchCount=%d, channelSwitchMode=%d \n", 1470 BeaconPacket, 1471 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber, 1472 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount, 1473 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode)); 1474 1475 1476 pSwitchChannel->ignoreCancelSwitchChannelCmd= 1; 1477 switchChannel_recvCmd4Debug(hSwitchChannel, &pSwitchChannel->debugChannelSwitchCmdParams, BeaconPacket, pSwitchChannel->currentChannel); 1478 } 1479 1480 void switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket) 1481 { 1482 1483 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1484 1485 if (pSwitchChannel == NULL) 1486 { 1487 return; 1488 } 1489 1490 WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n",BeaconPacket)); 1491 1492 pSwitchChannel->ignoreCancelSwitchChannelCmd= 0; 1493 switchChannel_recvCmd4Debug(hSwitchChannel, NULL, BeaconPacket, pSwitchChannel->currentChannel); 1494 } 1495 1496 1497 void switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel) 1498 { 1499 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1500 1501 if (pSwitchChannel == NULL) 1502 { 1503 return; 1504 } 1505 1506 WLAN_OS_REPORT(("SwitchChannel debug params are: channelNumber=%d, channelSwitchCount=%d , channelSwitchMode=%d \n", 1507 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber, 1508 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount, 1509 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode)); 1510 1511 WLAN_OS_REPORT(("SwitchChannel state=%d, currentChannel=%d \n", pSwitchChannel->currentState, pSwitchChannel->currentChannel)); 1512 1513 1514 } 1515 1516 void switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel, TI_UINT8 channelNum, TI_BOOL validity) 1517 { 1518 paramInfo_t param; 1519 1520 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1521 1522 if (pSwitchChannel == NULL) 1523 { 1524 return; 1525 } 1526 1527 param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY; 1528 param.content.channelValidity.channelNum = channelNum; 1529 param.content.channelValidity.channelValidity = validity; 1530 regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); 1531 1532 } 1533 1534 #endif /* TI_DBG */ 1535 1536 1537 1538 1539 1540 1541