1/* 2 * SwitchChannel.c 3 * 4 * Copyright(c) 1998 - 2009 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 */ 80typedef 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 */ 90typedef 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 */ 108typedef 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 */ 158static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData); 159static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData); 160static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData); 161static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData); 162static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData); 163static TI_STATUS switchChannel_smNop(void *pData); 164static TI_STATUS switchChannel_smUnexpected(void *pData); 165static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData); 166static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData); 167static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData); 168static TI_STATUS switchChannel_smStart(void *pData); 169 170 171/* other functions */ 172static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec); 173static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data); 174static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel); 175void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel); 176void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus, 177 EScrResourceId eResource, EScePendReason pendReason ); 178#ifdef TI_DBG 179static 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*/ 208TI_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*/ 258void 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 325TI_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*/ 378TI_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*/ 407TI_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*/ 437TI_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 462INPUT: 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 469OUTPUT: None 470 471RETURN: TI_OK on success, TI_NOK otherwise 472 473************************************************************************/ 474 475void 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 apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL); 532 } 533 else 534 { /* Invoke Switch Channel command */ 535 /* update the new SCC params */ 536 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; 537 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; 538 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; 539 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel); 540 } 541 542 } 543 544} 545 546 547/************************************************************************ 548 * switchChannel_powerSaveStatusReturn * 549 ************************************************************************/ 550/** 551* 552* \b Description: 553* 554* This procedure is called when power save status is returned 555* 556* \b ARGS: 557* 558* I/O - hSwitchChannel - SwitchChannel context \n 559* 560* \b RETURNS: 561* 562* TI_OK on success, TI_NOK otherwise. 563* 564* \sa 565*/ 566void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel) 567{ 568 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 569 570 if (pSwitchChannel == NULL) 571 { 572 return; 573 } 574 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_SwitchChannelCmdCompleteReturn \n"); 575 576 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMPLT, pSwitchChannel); 577 578} 579 580/************************************************************************ 581 * switchChannel_enableDisableSpectrumMngmt * 582 ************************************************************************/ 583/** 584* 585* \b Description: 586* 587* This procedure enables or disables the spectrum management 588* 589* \b ARGS: 590* 591* I - hSwitchChannel - SwitchChannel context \n 592* I - enableDisable - TI_TRUE - Enable, TI_FALSE - Disable 593* 594* \b RETURNS: 595* 596* TI_OK on success, TI_NOK otherwise. 597* 598* \sa 599*/ 600void switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel, TI_BOOL enableDisable) 601{ 602 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 603 604 605 if (hSwitchChannel == NULL) 606 { 607 return; 608 } 609 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_enableDisableSpectrumMngmt, enableDisable=%d \n", enableDisable); 610 611 pSwitchChannel->dot11SpectrumManagementRequired = enableDisable; 612 613 if (enableDisable) 614 { /* Enable SC, if it was started invoke start event. 615 otherwise, wait for a start event */ 616 if (pSwitchChannel->switchChannelStarted) 617 { 618 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel); 619 } 620 } 621 else 622 { /* Disable SC */ 623 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel); 624 } 625 626} 627 628 629 630/************************************************************************ 631 * SwitchChannel internal functions * 632 ************************************************************************/ 633 634/************************************************************************ 635 * switchChannel_smEvent * 636 ************************************************************************/ 637/** 638* 639* \b Description: 640* 641* SwitchChannel state machine transition function 642* 643* \b ARGS: 644* 645* I/O - currentState - current state in the state machine\n 646* I - event - specific event for the state machine\n 647* I - pData - Data for state machine action function\n 648* 649* \b RETURNS: 650* 651* TI_OK on success, TI_NOK otherwise. 652* 653* \sa 654*/ 655static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data) 656{ 657 TI_STATUS status; 658 TI_UINT8 nextState; 659 switchChannel_t *pSwitchChannel = (switchChannel_t*)data; 660 661 662 status = fsm_GetNextState(pSwitchChannel->pSwitchChannelSm, *currState, event, &nextState); 663 if (status != TI_OK) 664 { 665 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent, fsm_GetNextState error\n"); 666 return(TI_NOK); 667 } 668 669 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState); 670 671 status = fsm_Event(pSwitchChannel->pSwitchChannelSm, currState, event, (void *)pSwitchChannel); 672 673 if (status != TI_OK) 674 { 675 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent fsm_Event error\n"); 676 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState); 677 } 678 return status; 679 680} 681 682 683/************************************************************************ 684 * switchChannel_smStart * 685 ************************************************************************/ 686/** 687* 688* 689* \b Description: 690* 691* This function is called when the station becomes connected. 692 * update the current channel. 693* 694* \b ARGS: 695* 696* I - pData - pointer to the SwitchChannel SM context \n 697* 698* \b RETURNS: 699* 700* TI_OK if successful, TI_NOK otherwise. 701* 702* 703*************************************************************************/ 704static TI_STATUS switchChannel_smStart(void *pData) 705{ 706 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 707 paramInfo_t param; 708 709 if (pSwitchChannel == NULL) 710 { 711 return TI_NOK; 712 } 713 714 /* get the current channel number */ 715 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 716 siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m); 717 pSwitchChannel->currentChannel = param.content.siteMgrCurrentChannel; 718 719 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStart, channelNo=%d\n", pSwitchChannel->currentChannel); 720 return TI_OK; 721 722} 723 724/************************************************************************ 725 * switchChannel_smReqSCR_UpdateCmd * 726 ************************************************************************/ 727/** 728* 729* 730* \b Description: 731* 732* Update the Switch Channel command parameters. 733 * Request SCR and wait for SCR return. 734 * if tx status suspend 735 * update regulatory Domain 736 * update tx 737 * start periodic timer 738 739* 740* \b ARGS: 741* 742* I - pData - pointer to the SwitchChannel SM context \n 743* 744* \b RETURNS: 745* 746* TI_OK if successful, TI_NOK otherwise. 747* 748* 749*************************************************************************/ 750static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData) 751{ 752 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 753 EScrClientRequestStatus scrStatus; 754 EScePendReason scrPendReason; 755 756 if (pSwitchChannel == NULL) 757 { 758 return TI_NOK; 759 } 760 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); 761 762 763 /* Save the TS when requesting SCR */ 764 pSwitchChannel->SCRRequestTimestamp = os_timeStampMs(pSwitchChannel->hOs); 765 766 scrStatus = scr_clientRequest(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, 767 SCR_RESOURCE_SERVING_CHANNEL, &scrPendReason); 768 if ((scrStatus != SCR_CRS_RUN) && (scrStatus != SCR_CRS_PEND)) 769 { 770 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smReqSCR_UpdateCmd():Abort the switch channel, request Roaming, scrStatus=%d\n", scrStatus); 771 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel)); 772 773 } 774 if (scrStatus == SCR_CRS_RUN) 775 { 776 switchChannel_scrStatusCB(pSwitchChannel, scrStatus, SCR_RESOURCE_SERVING_CHANNEL, scrPendReason); 777 } 778 else if ((scrPendReason==SCR_PR_OTHER_CLIENT_RUNNING) || 779 (scrPendReason==SCR_PR_DIFFERENT_GROUP_RUNNING) ) 780 { /* No use to wait for the SCR, invoke FAIL */ 781 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel)); 782 } 783 /* wait for the SCR callback function to be called */ 784 return TI_OK; 785 786} 787 788 789/************************************************************************ 790 * switchChannel_scrStatusCB * 791 ************************************************************************/ 792/** 793* 794* 795* \b Description: 796* 797* This function is called by the SCR when: 798 * the resource is reserved for the SwitchChannel - SCR_CRS_RUN 799 * recovery occurred - SCR_CRS_ABORT 800 * other = ERROR 801* 802* \b ARGS: 803* 804* I - hSwitchChannel - pointer to the SwitchChannel SM context \n 805* I - requestStatus - the SCR request status \n 806* I - eResource - the resource for which the CB is issued \n 807* I - pendReason - The SCR pend status in case of pend reply \n 808* 809* \b RETURNS: 810* 811* None. 812* 813* 814*************************************************************************/ 815void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus, 816 EScrResourceId eResource, EScePendReason pendReason ) 817{ 818 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 819 switchChannel_smEvents scEvent; 820 821 if (pSwitchChannel == NULL) 822 { 823 return; 824 } 825 826 switch (requestStatus) 827 { 828 case SCR_CRS_RUN: 829 scEvent = SC_EVENT_SCR_RUN; 830 break; 831 case SCR_CRS_FW_RESET: 832 scEvent = SC_EVENT_FW_RESET; 833 break; 834 case SCR_CRS_PEND: 835 scEvent = SC_EVENT_SCR_FAIL; 836 break; 837 case SCR_CRS_ABORT: 838 default: 839 TRACE2(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_scrStatusCB scrStatus = %d, pendReason=%d\n", requestStatus, pendReason); 840 scEvent = SC_EVENT_SCR_FAIL; 841 break; 842 } 843 844 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, scEvent, pSwitchChannel); 845 846} 847 848 849 850/************************************************************************ 851 * switchChannel_smStartSwitchChannelCmd * 852 ************************************************************************/ 853/** 854* 855* 856* \b Description: 857* 858* This function is called once SwitchChannel command was received and the SCR 859 * request returned with reason RUN. 860 * In this case perform the following: 861 * Set CMD to FW 862 863 864* 865* \b ARGS: 866* 867* I - pData - pointer to the SwitchChannel SM context \n 868* 869* \b RETURNS: 870* 871* TI_OK if successful, TI_NOK otherwise. 872* 873* 874*************************************************************************/ 875static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData) 876{ 877 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; 878 TSwitchChannelParams pSwitchChannelCmd; 879 TI_UINT32 switchChannelTimeDuration; 880 paramInfo_t param; 881 882 if (pSwitchChannel == NULL) 883 { 884 return TI_NOK; 885 } 886 887 param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM; 888 siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m); 889 890 switchChannelTimeDuration = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount * param.content.beaconInterval * 1024 / 1000; 891 if ( (switchChannelTimeDuration!=0) && 892 ((os_timeStampMs(pSwitchChannel->hOs) - pSwitchChannel->SCRRequestTimestamp) >= switchChannelTimeDuration )) 893 { /* There's no time to perfrom the SCC, set the Count to 1 */ 894 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 1; 895 } 896 897 apConn_indicateSwitchChannelInProgress(pSwitchChannel->hApConn); 898 899 pSwitchChannelCmd.channelNumber = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; 900 pSwitchChannelCmd.switchTime = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount; 901 pSwitchChannelCmd.txFlag = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode; 902 pSwitchChannelCmd.flush = 0; 903 TWD_CmdSwitchChannel (pSwitchChannel->hTWD, &pSwitchChannelCmd); 904 905 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); 906 907 return TI_OK; 908 909} 910 911/************************************************************************ 912 * switchChannel_smFwResetWhileSCInProg * 913 ************************************************************************/ 914/** 915* 916* 917* \b Description: 918* 919* This function is called when Switch Channel command is cancelled. 920 * In this case update TX nad regulatory Domain adn HAL. 921 * Release the SCR and exit PS. 922* 923* \b ARGS: 924* 925* I - pData - pointer to the SwitchChannel SM context \n 926* 927* \b RETURNS: 928* 929* TI_OK if successful, TI_NOK otherwise. 930* 931* 932*************************************************************************/ 933static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData) 934{ 935 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; 936 paramInfo_t param; 937 938 if (pSwitchChannel == NULL) 939 { 940 return TI_NOK; 941 } 942 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smFwResetWhileSCInProg \n"); 943 944 /* Update new current channel */ 945 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 946 param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; 947 siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m); 948 949 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); 950 951 switchChannel_zeroDatabase(pSwitchChannel); 952 953 /* release the SCR */ 954 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 955 956 return TI_OK; 957 958} 959 960 961/************************************************************************ 962 * switchChannel_smSwitchChannelCmplt * 963 ************************************************************************/ 964/** 965* 966* 967* \b Description: 968* 969* This function is called when SwitchChannel command completed in FW. 970 * In this case release SCR and update current channel. 971 * If TX was sus, it will be enabled only after first Beacon is recieved. 972 * Exit PS. 973* 974* \b ARGS: 975* 976* I - pData - pointer to the SwitchChannel SM context \n 977* 978* \b RETURNS: 979* 980* TI_OK if successful, TI_NOK otherwise. 981* 982* 983*************************************************************************/ 984static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData) 985{ 986 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; 987 paramInfo_t param; 988 989 if (pSwitchChannel == NULL) 990 { 991 return TI_NOK; 992 } 993 994 /* Update new current channel */ 995 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 996 param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; 997 siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m); 998 999 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smSwitchChannelCmplt, new channelNum = %d\n", pSwitchChannel->currentChannel); 1000 1001 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); 1002 switchChannel_zeroDatabase(pSwitchChannel); 1003 1004 /* release the SCR */ 1005 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1006 1007 return TI_OK; 1008 1009} 1010 1011 1012 1013/************************************************************************ 1014 * switchChannel_smScrFailWhileWait4Scr * 1015 ************************************************************************/ 1016/** 1017* 1018* 1019* \b Description: 1020* 1021* This function is called when recovery occurred, while waiting for SCR due 1022 * to previous switch channel command. 1023 * Exit PS 1024 * Release SCR. 1025* 1026* \b ARGS: 1027* 1028* I - pData - pointer to the SwitchChannel SM context \n 1029* 1030* \b RETURNS: 1031* 1032* TI_OK if successful, TI_NOK otherwise. 1033* 1034* 1035*************************************************************************/ 1036static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData) 1037{ 1038 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1039 1040 if (pSwitchChannel == NULL) 1041 { 1042 return TI_NOK; 1043 } 1044 1045 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smScrFailWhileWait4Scr\n"); 1046 1047 switchChannel_zeroDatabase(pSwitchChannel); 1048 1049 /* release the SCR is not required !!! */ 1050 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1051 1052 return TI_OK; 1053} 1054 1055/************************************************************************ 1056 * switchChannel_smStopWhileWait4Cmd * 1057 ************************************************************************/ 1058/** 1059* 1060* 1061* \b Description: 1062* 1063* This function is called when the station becomes Disconnected and the current 1064* state is Wait4Cmd. In this case perfrom: 1065 * Stop the timer 1066 * Enable TX if it was disabled 1067 * Zero the current command parameters 1068 * Stop the timer 1069* 1070* \b ARGS: 1071* 1072* I - pData - pointer to the SwitchChannel SM context \n 1073* 1074* \b RETURNS: 1075* 1076* TI_OK if successful, TI_NOK otherwise. 1077* 1078* 1079*************************************************************************/ 1080static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData) 1081{ 1082 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1083 1084 if (pSwitchChannel == NULL) 1085 { 1086 return TI_NOK; 1087 } 1088 1089 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Cmd\n"); 1090 1091 switchChannel_zeroDatabase(pSwitchChannel); 1092 1093 return TI_OK; 1094} 1095 1096/************************************************************************ 1097 * switchChannel_smStopWhileWait4Scr * 1098 ************************************************************************/ 1099/** 1100* 1101* 1102* \b Description: 1103* 1104* This function is called when the station becomes Disconnected and the current 1105* state is Wait4Scr. In this case perfrom: 1106 * Stop the timer 1107 * Enable TX if it was disabled 1108 * Zero the current command parameters 1109 * Complete SCR 1110* 1111* \b ARGS: 1112* 1113* I - pData - pointer to the SwitchChannel SM context \n 1114* 1115* \b RETURNS: 1116* 1117* TI_OK if successful, TI_NOK otherwise. 1118* 1119* 1120*************************************************************************/ 1121static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData) 1122{ 1123 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1124 1125 if (pSwitchChannel == NULL) 1126 { 1127 return TI_NOK; 1128 } 1129 1130 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Scr\n"); 1131 1132 1133 switchChannel_zeroDatabase(pSwitchChannel); 1134 1135 /* release the SCR */ 1136 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1137 1138 return TI_OK; 1139} 1140 1141/************************************************************************ 1142 * switchChannel_smStopWhileSwitchChannelInProg * 1143 ************************************************************************/ 1144/** 1145* 1146* 1147* \b Description: 1148* 1149* This function is called when the station becomes Disconnected and the current 1150* state is SwitchChannelInProg. In this case perfrom: 1151 * Stop the timer 1152 * Enable TX if it was disabled 1153 * Zero the current command parameters 1154 * resume self test 1155 * Complete SCR 1156 * Exit PS 1157* 1158* \b ARGS: 1159* 1160* I - pData - pointer to the SwitchChannel SM context \n 1161* 1162* \b RETURNS: 1163* 1164* TI_OK if successful, TI_NOK otherwise. 1165* 1166* 1167*************************************************************************/ 1168static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData) 1169{ 1170 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; 1171 1172 if (pSwitchChannel == NULL) 1173 { 1174 return TI_NOK; 1175 } 1176 1177 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileSwitchChannelInProg\n"); 1178 1179 /* Exit PS */ 1180 /*PowerMgr_exitFromDriverMode(pSwitchChannel->hPowerMngr, "SwitchChannel");*/ 1181 1182 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); 1183 1184 TWD_CmdSwitchChannelCancel (pSwitchChannel->hTWD, pSwitchChannel->currentChannel); 1185 switchChannel_zeroDatabase(pSwitchChannel); 1186 1187 /* release the SCR */ 1188 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); 1189 1190 return TI_OK; 1191} 1192 1193 1194 1195 1196/************************************************************************ 1197 * switchChannel_zeroDatabase * 1198 ************************************************************************/ 1199/** 1200* 1201* 1202* \b Description: 1203* 1204* This function is called when the SwitchChannel internal database should be zero. 1205 * The following parameters are zerod: 1206 * SwitchChannelChannelRange - the timestamps and validity state of channels 1207 * curChannelSwitchCmdParams - the current switch channel command parameters 1208* 1209* \b ARGS: 1210* 1211* I - pSwitchChannel - pointer to the SwitchChannel SM context \n 1212* I - channelNum - channel number \n 1213* I - timestamp - required timestamp \n 1214* 1215* \b RETURNS: 1216* 1217* None. 1218* 1219* 1220*************************************************************************/ 1221static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel) 1222{ 1223 1224 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_zeroDatabase\n"); 1225 1226 1227 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = 0; 1228 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 0; 1229 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS; 1230 pSwitchChannel->currentChannel = 0; 1231 1232} 1233 1234/*********************************************************************** 1235 * release_module 1236 ***********************************************************************/ 1237/* 1238DESCRIPTION: Called by the destroy function or by the create function (on failure) 1239 Go over the vector, for each bit that is set, release the corresponding module. 1240 1241INPUT: pSwitchChannel - SwitchChannel pointer. 1242 initVec - Vector that contains a bit set for each module thah had been initiualized 1243 1244OUTPUT: 1245 1246RETURN: TI_OK on success, TI_NOK otherwise 1247 1248************************************************************************/ 1249static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec) 1250{ 1251 if (pSwitchChannel == NULL) 1252 { 1253 return; 1254 } 1255 if (initVec & (1 << SC_SM_INIT_BIT)) 1256 { 1257 fsm_Unload(pSwitchChannel->hOs, pSwitchChannel->pSwitchChannelSm); 1258 } 1259 1260 if (initVec & (1 << SC_INIT_BIT)) 1261 { 1262 os_memoryFree(pSwitchChannel->hOs, pSwitchChannel, sizeof(switchChannel_t)); 1263 } 1264 1265 initVec = 0; 1266} 1267 1268 1269/** 1270* 1271* switchChannel_smNop - Do nothing 1272* 1273* \b Description: 1274* 1275* Do nothing in the SM. 1276* 1277* \b ARGS: 1278* 1279* I - pData - pointer to the SwitchChannel SM context \n 1280* 1281* \b RETURNS: 1282* 1283* TI_OK if successful, TI_NOK otherwise. 1284* 1285* 1286*/ 1287static TI_STATUS switchChannel_smNop(void *pData) 1288{ 1289 switchChannel_t *pSwitchChannel; 1290 1291 pSwitchChannel = (switchChannel_t*)pData; 1292 if (pSwitchChannel == NULL) 1293 { 1294 return TI_NOK; 1295 } 1296 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, " switchChannel_smNop\n"); 1297 1298 return TI_OK; 1299} 1300 1301/** 1302* 1303* switchChannel_smUnexpected - Unexpected event 1304* 1305* \b Description: 1306* 1307* Unexpected event in the SM. 1308* 1309* \b ARGS: 1310* 1311* I - pData - pointer to the SwitchChannel SM context \n 1312* 1313* \b RETURNS: 1314* 1315* TI_OK if successful, TI_NOK otherwise. 1316* 1317* 1318*/ 1319static TI_STATUS switchChannel_smUnexpected(void *pData) 1320{ 1321 switchChannel_t *pSwitchChannel; 1322 1323 pSwitchChannel = (switchChannel_t*)pData; 1324 if (pSwitchChannel == NULL) 1325 { 1326 return TI_NOK; 1327 } 1328 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, " switchChannel_smUnexpected, state = %d\n", pSwitchChannel->currentState); 1329 1330 return TI_NOK; 1331} 1332 1333/******************************************************************************* 1334*********** Debug functions *********** 1335*******************************************************************************/ 1336#ifdef TI_DBG 1337 1338/************************************************************************ 1339 * switchChannel_recvCmd * 1340 ************************************************************************/ 1341/*DESCRIPTION: This function is called by MLME Parser upon receiving of 1342 Beacon, Probe Response or Action with Switch Channel command, 1343 or beacon/ 1344 performs the following: 1345 - Initializes the switching channel procedure. 1346 - Setting timer to the actual switching time(if needed) 1347 1348INPUT: hSwitchChannel - SwitchChannel handle. 1349 switchMode - indicates whether to stop transmission 1350 until the scheduled channel switch. 1351 newChannelNum - indicates the number of the new channel. 1352 durationTime - indicates the time (expressed in ms) until 1353 the scheduled channel switch should accure. 1354 1355OUTPUT: None 1356 1357RETURN: TI_OK on success, TI_NOK otherwise 1358 1359************************************************************************/ 1360 1361static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel) 1362{ 1363 1364 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; 1365 paramInfo_t param; 1366 1367 if (pSwitchChannel==NULL) 1368 { 1369 return; 1370 } 1371 1372 1373 /* The following is for debug purposes only 1374 It will be operated when the Switch Channel cmd is opertated from debug CLI */ 1375 if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0) 1376 { 1377 if (pSwitchChannel->ignoreCancelSwitchChannelCmd == 1) 1378 { 1379 /* update the new SCC params */ 1380 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; 1381 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; 1382 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; 1383 1384 pSwitchChannel->ignoreCancelSwitchChannelCmd = 2; 1385 } 1386 else if (channelSwitch->channelSwitchCount>0) 1387 { 1388 channelSwitch->channelSwitchCount --; 1389 } 1390 else 1391 { 1392 pSwitchChannel->ignoreCancelSwitchChannelCmd = 0; 1393 } 1394 1395 1396 /* search in the buffer pointer to the beginning of the 1397 Switch Cahnnel Announcement IE according to the IE ID */ 1398 1399 /* SC IE exists on the serving channel */ 1400 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); 1401 1402 /* Checking channel number validity */ 1403 param.content.channel = channelSwitch->channelNumber; 1404 param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; 1405 regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m); 1406 if (( !param.content.bIsChannelSupprted ) || 1407 (channelSwitch->channelSwitchCount == 0) || 1408 (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)) 1409 { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid, 1410 or the TBTT count is 0 */ 1411 apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL); 1412 } 1413 else 1414 { /* Invoke Switch Channel command */ 1415 /* update the new SCC params */ 1416 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; 1417 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; 1418 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; 1419 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel); 1420 } 1421 } 1422 1423} 1424 1425void switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel, SC_switchChannelCmdParam_e switchChannelCmdParam, TI_UINT8 param) 1426{ 1427 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1428 1429 if (pSwitchChannel == NULL) 1430 { 1431 return; 1432 } 1433 1434 switch (switchChannelCmdParam) 1435 { 1436 case SC_SWITCH_CHANNEL_NUM: 1437 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelNum=%d \n ", param)); 1438 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber = param; 1439 break; 1440 case SC_SWITCH_CHANNEL_TBTT: 1441 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchCount=%d \n ", param)); 1442 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount = param; 1443 break; 1444 case SC_SWITCH_CHANNEL_MODE: 1445 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchMode=%d \n ", param)); 1446 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode = param; 1447 break; 1448 default: 1449 WLAN_OS_REPORT(("ERROR: SwitchChannelDebug_setSwitchChannelCmdParams, wrong switchChannelCmdParam=%d \n ", 1450 switchChannelCmdParam)); 1451 break; 1452 } 1453 1454} 1455void switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket) 1456{ 1457 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1458 1459 if (pSwitchChannel == NULL) 1460 { 1461 return; 1462 } 1463 1464 WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n cmd params: channelNumber=%d, channelSwitchCount=%d, channelSwitchMode=%d \n", 1465 BeaconPacket, 1466 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber, 1467 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount, 1468 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode)); 1469 1470 1471 pSwitchChannel->ignoreCancelSwitchChannelCmd= 1; 1472 switchChannel_recvCmd4Debug(hSwitchChannel, &pSwitchChannel->debugChannelSwitchCmdParams, BeaconPacket, pSwitchChannel->currentChannel); 1473} 1474 1475void switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket) 1476{ 1477 1478 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1479 1480 if (pSwitchChannel == NULL) 1481 { 1482 return; 1483 } 1484 1485 WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n",BeaconPacket)); 1486 1487 pSwitchChannel->ignoreCancelSwitchChannelCmd= 0; 1488 switchChannel_recvCmd4Debug(hSwitchChannel, NULL, BeaconPacket, pSwitchChannel->currentChannel); 1489} 1490 1491 1492void switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel) 1493{ 1494 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1495 1496 if (pSwitchChannel == NULL) 1497 { 1498 return; 1499 } 1500 1501 WLAN_OS_REPORT(("SwitchChannel debug params are: channelNumber=%d, channelSwitchCount=%d , channelSwitchMode=%d \n", 1502 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber, 1503 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount, 1504 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode)); 1505 1506 WLAN_OS_REPORT(("SwitchChannel state=%d, currentChannel=%d \n", pSwitchChannel->currentState, pSwitchChannel->currentChannel)); 1507 1508 1509} 1510 1511void switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel, TI_UINT8 channelNum, TI_BOOL validity) 1512{ 1513 paramInfo_t param; 1514 1515 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; 1516 1517 if (pSwitchChannel == NULL) 1518 { 1519 return; 1520 } 1521 1522 param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY; 1523 param.content.channelValidity.channelNum = channelNum; 1524 param.content.channelValidity.channelValidity = validity; 1525 regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); 1526 1527} 1528 1529#endif /* TI_DBG */ 1530 1531 1532 1533 1534 1535 1536