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