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 */
switchChannel_create(TI_HANDLE hOs)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 */
switchChannel_config(TI_HANDLE hSwitchChannel,TI_HANDLE hHalCtrl,TI_HANDLE hSiteMgr,TI_HANDLE hSCR,TI_HANDLE hRegulatoryDomain,TI_HANDLE hApConn,TI_HANDLE hReport,TI_HANDLE hOs,TI_HANDLE hHealthMonitor,SwitchChannelInitParams_t * SwitchChannelInitParams)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 */
switchChannel_stop(TI_HANDLE hSwitchChannel)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 */
switchChannel_start(TI_HANDLE hSwitchChannel)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 */
switchChannel_unload(TI_HANDLE hSwitchChannel)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
switchChannel_recvCmd(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,UINT8 channel)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 */
switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)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 */
switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel,BOOL enableDisable)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 */
switchChannel_smEvent(UINT8 * currState,UINT8 event,void * data)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 *************************************************************************/
switchChannel_smStart(void * pData)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 *************************************************************************/
switchChannel_smReqSCR_UpdateCmd(void * pData)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 *************************************************************************/
switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel,scr_clientRequestStatus_e requestStatus,scr_pendReason_e pendReason)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 *************************************************************************/
switchChannel_smStartSwitchChannelCmd(void * pData)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 *************************************************************************/
switchChannel_smFwResetWhileSCInProg(void * pData)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 *************************************************************************/
switchChannel_smSwitchChannelCmplt(void * pData)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 *************************************************************************/
switchChannel_smScrFailWhileWait4Scr(void * pData)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 *************************************************************************/
switchChannel_smStopWhileWait4Cmd(void * pData)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 *************************************************************************/
switchChannel_smStopWhileWait4Scr(void * pData)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 *************************************************************************/
switchChannel_smStopWhileSwitchChannelInProg(void * pData)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 *************************************************************************/
switchChannel_zeroDatabase(switchChannel_t * pSwitchChannel)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 ************************************************************************/
release_module(switchChannel_t * pSwitchChannel,UINT32 initVec)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 */
switchChannel_smNop(void * pData)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 */
switchChannel_smUnexpected(void * pData)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
switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,BOOL BeaconPacket,UINT8 channel)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
switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel,SC_switchChannelCmdParam_e switchChannelCmdParam,UINT8 param)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 }
switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel,BOOL BeaconPacket)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
switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel,BOOL BeaconPacket)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
switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)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
switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel,UINT8 channelNum,BOOL validity)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