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 */
80 typedef enum
81 {
82 SC_STATE_IDLE = 0,
83 SC_STATE_WAIT_4_CMD = 1,
84 SC_STATE_WAIT_4_SCR = 2,
85 SC_STATE_SC_IN_PROG = 3,
86 SC_STATE_LAST = 4
87 } switchChannel_smStates;
88
89 /** State machine events */
90 typedef enum
91 {
92 SC_EVENT_START = 0,
93 SC_EVENT_STOP = 1,
94 SC_EVENT_SC_CMD = 2,
95 SC_EVENT_SCR_RUN = 3,
96 SC_EVENT_SCR_FAIL = 4,
97 SC_EVENT_SC_CMPLT = 5,
98 SC_EVENT_FW_RESET = 6,
99 SC_EVENT_LAST = 7
100 } switchChannel_smEvents;
101
102
103 #define SC_NUM_STATES SC_STATE_LAST
104 #define SC_NUM_EVENTS SC_EVENT_LAST
105
106
107 /* Structures */
108 typedef struct
109 {
110
111 /* SwitchChannel parameters that can be configured externally */
112 TI_BOOL dot11SpectrumManagementRequired;
113
114 /* Internal SwitchChannel parameters */
115 TI_UINT8 currentState;
116 dot11_CHANNEL_SWITCH_t curChannelSwitchCmdParams;
117 TI_UINT32 SCRRequestTimestamp;
118 TI_UINT8 currentChannel;
119 TI_BOOL switchChannelStarted;
120
121 #ifdef TI_DBG
122 /* switchChannelCmd for debug */
123 dot11_CHANNEL_SWITCH_t debugChannelSwitchCmdParams;
124 TI_UINT8 ignoreCancelSwitchChannelCmd;
125 #endif
126
127 /* SwitchChannel SM */
128 fsm_stateMachine_t *pSwitchChannelSm;
129
130 /* SwitchChannel handles to other objects */
131 TI_HANDLE hTWD;
132 TI_HANDLE hSiteMgr;
133 TI_HANDLE hSCR;
134 TI_HANDLE hRegulatoryDomain;
135 TI_HANDLE hPowerMngr;
136 TI_HANDLE hApConn;
137 TI_HANDLE hReport;
138 TI_HANDLE hOs;
139
140 } switchChannel_t;
141
142
143
144
145 /* External data definitions */
146
147 /* Local functions definitions */
148
149 /* Global variables */
150
151
152 /********************************************************************************/
153 /* Internal functions prototypes. */
154 /********************************************************************************/
155
156
157 /* SM functions */
158 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData);
159 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData);
160 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData);
161 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData);
162 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData);
163 static TI_STATUS switchChannel_smNop(void *pData);
164 static TI_STATUS switchChannel_smUnexpected(void *pData);
165 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData);
166 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData);
167 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData);
168 static TI_STATUS switchChannel_smStart(void *pData);
169
170
171 /* other functions */
172 static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec);
173 static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data);
174 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel);
175 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel);
176 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus,
177 EScrResourceId eResource, EScePendReason pendReason );
178 #ifdef TI_DBG
179 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel);
180 #endif
181
182
183 /********************************************************************************/
184 /* Interface functions Implementation. */
185 /********************************************************************************/
186
187
188 /************************************************************************
189 * switchChannel_create *
190 ************************************************************************/
191 /**
192 *
193 * \b Description:
194 *
195 * This procedure is called by the config manager when the driver is created.
196 * It creates the SwitchChannel object.
197 *
198 * \b ARGS:
199 *
200 * I - hOs - OS context \n
201 *
202 * \b RETURNS:
203 *
204 * Handle to the SwitchChannel object.
205 *
206 * \sa
207 */
switchChannel_create(TI_HANDLE hOs)208 TI_HANDLE switchChannel_create(TI_HANDLE hOs)
209 {
210 switchChannel_t *pSwitchChannel = NULL;
211 TI_UINT32 initVec = 0;
212 TI_STATUS status;
213
214 /* allocating the SwitchChannel object */
215 pSwitchChannel = os_memoryAlloc(hOs,sizeof(switchChannel_t));
216
217 if (pSwitchChannel == NULL)
218 return NULL;
219
220 initVec |= (1 << SC_INIT_BIT);
221
222 os_memoryZero(hOs, pSwitchChannel, sizeof(switchChannel_t));
223
224 pSwitchChannel->hOs = hOs;
225
226 status = fsm_Create(hOs, &pSwitchChannel->pSwitchChannelSm, SC_NUM_STATES, SC_NUM_EVENTS);
227 if (status != TI_OK)
228 {
229 release_module(pSwitchChannel, initVec);
230 WLAN_OS_REPORT(("FATAL ERROR: switchChannel_create(): Error Creating pSwitchChannelSm - Aborting\n"));
231 return NULL;
232 }
233 initVec |= (1 << SC_SM_INIT_BIT);
234
235 return(pSwitchChannel);
236 }
237
238 /************************************************************************
239 * switchChannel_init *
240 ************************************************************************/
241 /**
242 *
243 * \b Description:
244 *
245 * This procedure is called by the DrvMain when the driver is initialized.
246 * It initializes the SwitchChannel object's variables and handlers and creates the SwitchChannel SM.
247 *
248 * \b ARGS:
249 *
250 * I - pStadHandles - The driver modules handles \n
251 *
252 * \b RETURNS:
253 *
254 * void
255 *
256 * \sa
257 */
switchChannel_init(TStadHandlesList * pStadHandles)258 void switchChannel_init (TStadHandlesList *pStadHandles)
259 {
260 switchChannel_t *pSwitchChannel = (switchChannel_t *)(pStadHandles->hSwitchChannel);
261
262 /** Roaming State Machine matrix */
263 fsm_actionCell_t switchChannel_SM[SC_NUM_STATES][SC_NUM_EVENTS] =
264 {
265 /* next state and actions for IDLE state */
266 { {SC_STATE_WAIT_4_CMD, switchChannel_smStart}, /* START */
267 {SC_STATE_IDLE, switchChannel_smNop}, /* STOP */
268 {SC_STATE_IDLE, switchChannel_smNop}, /* SC_CMD */
269 {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SCR_RUN */
270 {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SCR_FAIL */
271 {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SC_CMPLT */
272 {SC_STATE_IDLE, switchChannel_smUnexpected} /* FW_RESET */
273 },
274
275 /* next state and actions for WAIT_4_CMD state */
276 { {SC_STATE_WAIT_4_CMD, switchChannel_smNop}, /* START */
277 {SC_STATE_IDLE, switchChannel_smStopWhileWait4Cmd}, /* STOP */
278 {SC_STATE_WAIT_4_SCR, switchChannel_smReqSCR_UpdateCmd}, /* SC_CMD */
279 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_RUN */
280 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_FAIL */
281 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SC_CMPLT */
282 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected} /* FW_RESET */
283
284 },
285
286 /* next state and actions for WAIT_4_SCR state */
287 { {SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected}, /* START */
288 {SC_STATE_IDLE, switchChannel_smStopWhileWait4Scr}, /* STOP */
289 {SC_STATE_WAIT_4_SCR, switchChannel_smNop}, /* SC_CMD */
290 {SC_STATE_SC_IN_PROG, switchChannel_smStartSwitchChannelCmd}, /* SCR_RUN */
291 {SC_STATE_WAIT_4_CMD, switchChannel_smScrFailWhileWait4Scr}, /* SCR_FAIL */
292 {SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected} , /* SC_CMPLT */
293 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected} /* FW_RESET */
294
295 },
296
297 /* next state and actions for switchChannel_IN_PROG state */
298 { {SC_STATE_SC_IN_PROG, switchChannel_smUnexpected}, /* START */
299 {SC_STATE_IDLE, switchChannel_smStopWhileSwitchChannelInProg}, /* STOP */
300 {SC_STATE_SC_IN_PROG, switchChannel_smNop}, /* SC_CMD */
301 {SC_STATE_SC_IN_PROG, switchChannel_smUnexpected}, /* SCR_RUN */
302 {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_FAIL */
303 {SC_STATE_WAIT_4_CMD, switchChannel_smSwitchChannelCmplt}, /* SC_CMPLT */
304 {SC_STATE_WAIT_4_CMD, switchChannel_smFwResetWhileSCInProg} /* FW_RESET */
305 }
306 };
307
308 fsm_Config(pSwitchChannel->pSwitchChannelSm,
309 &switchChannel_SM[0][0],
310 SC_NUM_STATES,
311 SC_NUM_EVENTS,
312 switchChannel_smEvent, pSwitchChannel->hOs);
313
314 /* init handlers */
315 pSwitchChannel->hTWD = pStadHandles->hTWD;
316 pSwitchChannel->hSiteMgr = pStadHandles->hSiteMgr;
317 pSwitchChannel->hSCR = pStadHandles->hSCR;
318 pSwitchChannel->hRegulatoryDomain = pStadHandles->hRegulatoryDomain;
319 pSwitchChannel->hApConn = pStadHandles->hAPConnection;
320 pSwitchChannel->hReport = pStadHandles->hReport;
321 pSwitchChannel->hOs = pStadHandles->hOs;
322 }
323
324
switchChannel_SetDefaults(TI_HANDLE hSwitchChannel,SwitchChannelInitParams_t * SwitchChannelInitParams)325 TI_STATUS switchChannel_SetDefaults (TI_HANDLE hSwitchChannel, SwitchChannelInitParams_t *SwitchChannelInitParams)
326 {
327 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
328
329 /* init variables */
330 pSwitchChannel->dot11SpectrumManagementRequired = SwitchChannelInitParams->dot11SpectrumManagementRequired;
331 pSwitchChannel->currentState = SC_STATE_IDLE;
332 pSwitchChannel->currentChannel = 0;
333 pSwitchChannel->switchChannelStarted = TI_FALSE;
334
335 /* register to SCR */
336 scr_registerClientCB(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL,
337 switchChannel_scrStatusCB, pSwitchChannel);
338
339 /* register to Switch Channel Complete event in HAL */
340 TWD_RegisterEvent (pSwitchChannel->hTWD,
341 TWD_OWN_EVENT_SWITCH_CHANNEL_CMPLT,
342 (void *)switchChannel_SwitchChannelCmdCompleteReturn,
343 pSwitchChannel);
344
345 TWD_EnableEvent (pSwitchChannel->hTWD, TWD_OWN_EVENT_SWITCH_CHANNEL_CMPLT);
346 #ifdef TI_DBG
347 /* for debug */
348 pSwitchChannel->debugChannelSwitchCmdParams.hdr[0] = CHANNEL_SWITCH_ANNOUNCEMENT_IE_ID;
349 pSwitchChannel->debugChannelSwitchCmdParams.hdr[1] = SC_SWITCH_CHANNEL_CMD_LEN;
350 pSwitchChannel->ignoreCancelSwitchChannelCmd = 0;
351 #endif
352 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INIT, ".....SwitchChannel configured successfully\n");
353
354 return TI_OK;
355 }
356
357
358 /************************************************************************
359 * switchChannel_stop *
360 ************************************************************************/
361 /**
362 *
363 * \b Description:
364 *
365 * This procedure is called by the SME when the state is changed from CONNECTED.
366 * It generates a STOP event to the SwitchChannel SM.
367 *
368 * \b ARGS:
369 *
370 * I - hSwitchChannel - SwitchChannel context \n
371 *
372 * \b RETURNS:
373 *
374 * TI_OK on success, TI_NOK otherwise
375 *
376 * \sa
377 */
switchChannel_stop(TI_HANDLE hSwitchChannel)378 TI_STATUS switchChannel_stop(TI_HANDLE hSwitchChannel)
379 {
380 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
381
382 pSwitchChannel->switchChannelStarted = TI_FALSE;
383 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel));
384
385 }
386
387 /************************************************************************
388 * switchChannel_start *
389 ************************************************************************/
390 /**
391 *
392 * \b Description:
393 *
394 * This procedure is called by the SME when the state is changed to CONNECTED.
395 * It generates a START event to the SwitchChannel SM.
396 *
397 * \b ARGS:
398 *
399 * I - hSwitchChannel - SwitchChannel context \n
400 *
401 * \b RETURNS:
402 *
403 * TI_OK on success, TI_NOK otherwise
404 *
405 * \sa
406 */
switchChannel_start(TI_HANDLE hSwitchChannel)407 TI_STATUS switchChannel_start(TI_HANDLE hSwitchChannel)
408 {
409 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
410 pSwitchChannel->switchChannelStarted = TI_TRUE;
411
412 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel));
413
414 }
415
416
417 /************************************************************************
418 * switchChannel_unload *
419 ************************************************************************/
420 /**
421 *
422 * \b Description:
423 *
424 * This procedure is called by the config manager when the driver is unloaded.
425 * It frees any memory allocated and timers.
426 *
427 * \b ARGS:
428 *
429 * I - hSwitchChannel - SwitchChannel context \n
430 *
431 * \b RETURNS:
432 *
433 * TI_OK on success, TI_NOK otherwise
434 *
435 * \sa
436 */
switchChannel_unload(TI_HANDLE hSwitchChannel)437 TI_STATUS switchChannel_unload(TI_HANDLE hSwitchChannel)
438 {
439 TI_UINT32 initVec;
440 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
441
442 if (pSwitchChannel == NULL)
443 return TI_OK;
444
445 initVec = 0xff;
446 release_module(pSwitchChannel, initVec);
447
448 return TI_OK;
449 }
450
451
452 /************************************************************************
453 * switchChannel_recvCmd *
454 ************************************************************************/
455 /*DESCRIPTION: This function is called by MLME Parser upon receiving of
456 Beacon, Probe Response or Action with Switch Channel command,
457 or beacon/
458 performs the following:
459 - Initializes the switching channel procedure.
460 - Setting timer to the actual switching time(if needed)
461
462 INPUT: hSwitchChannel - SwitchChannel handle.
463 switchMode - indicates whether to stop transmission
464 until the scheduled channel switch.
465 newChannelNum - indicates the number of the new channel.
466 durationTime - indicates the time (expressed in ms) until
467 the scheduled channel switch should accure.
468
469 OUTPUT: None
470
471 RETURN: TI_OK on success, TI_NOK otherwise
472
473 ************************************************************************/
474
switchChannel_recvCmd(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,TI_UINT8 channel)475 void switchChannel_recvCmd(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_UINT8 channel)
476 {
477
478 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
479 paramInfo_t param;
480
481 if (pSwitchChannel==NULL)
482 {
483 return;
484 }
485
486 param.paramType = REGULATORY_DOMAIN_DFS_CHANNELS_RANGE;
487 regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain, ¶m);
488
489 if (!pSwitchChannel->dot11SpectrumManagementRequired ||
490 (channel < param.content.DFS_ChannelRange.minDFS_channelNum) ||
491 (channel > param.content.DFS_ChannelRange.maxDFS_channelNum))
492 { /* Do not parse Switch Channel IE, when SpectrumManagement is disabled,
493 or the channel is non-DFS channel */
494 return;
495 }
496 #ifdef TI_DBG
497 /* for debug purposes only */
498 if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0)
499 {
500 return;
501 }
502 #endif
503
504 if (channelSwitch == NULL)
505 { /* No SC IE, update regDomain */
506 param.paramType = REGULATORY_DOMAIN_UPDATE_CHANNEL_VALIDITY;
507 param.content.channel = channel;
508 regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m);
509 }
510 else
511 { /* SC IE exists */
512 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n", channelSwitch->channelNumber, channelSwitch->channelSwitchMode, channelSwitch->channelSwitchCount);
513
514 /* Checking channel number validity */
515 param.content.channel = channelSwitch->channelNumber;
516 param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED;
517 regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m);
518 if ( ( !param.content.bIsChannelSupprted ) ||
519 (channelSwitch->channelSwitchCount == 0) ||
520 (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS))
521 { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid,
522 or the TBTT count is 0 */
523 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "report Roaming trigger\n");
524 if (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)
525 {
526 param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY;
527 param.content.channelValidity.channelNum = channel;
528 param.content.channelValidity.channelValidity = TI_FALSE;
529 regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m);
530 }
531 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 */
switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)566 void 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 */
switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel,TI_BOOL enableDisable)600 void 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 */
switchChannel_smEvent(TI_UINT8 * currState,TI_UINT8 event,void * data)655 static 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 *************************************************************************/
switchChannel_smStart(void * pData)704 static 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 *************************************************************************/
switchChannel_smReqSCR_UpdateCmd(void * pData)750 static 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 *************************************************************************/
switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel,EScrClientRequestStatus requestStatus,EScrResourceId eResource,EScePendReason pendReason)815 void 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 *************************************************************************/
switchChannel_smStartSwitchChannelCmd(void * pData)875 static 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 *************************************************************************/
switchChannel_smFwResetWhileSCInProg(void * pData)933 static 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 *************************************************************************/
switchChannel_smSwitchChannelCmplt(void * pData)984 static 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 *************************************************************************/
switchChannel_smScrFailWhileWait4Scr(void * pData)1036 static 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 *************************************************************************/
switchChannel_smStopWhileWait4Cmd(void * pData)1080 static 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 *************************************************************************/
switchChannel_smStopWhileWait4Scr(void * pData)1121 static 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 *************************************************************************/
switchChannel_smStopWhileSwitchChannelInProg(void * pData)1168 static 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 *************************************************************************/
switchChannel_zeroDatabase(switchChannel_t * pSwitchChannel)1221 static 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 /*
1238 DESCRIPTION: 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
1241 INPUT: pSwitchChannel - SwitchChannel pointer.
1242 initVec - Vector that contains a bit set for each module thah had been initiualized
1243
1244 OUTPUT:
1245
1246 RETURN: TI_OK on success, TI_NOK otherwise
1247
1248 ************************************************************************/
release_module(switchChannel_t * pSwitchChannel,TI_UINT32 initVec)1249 static 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 */
switchChannel_smNop(void * pData)1287 static 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 */
switchChannel_smUnexpected(void * pData)1319 static 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
1348 INPUT: 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
1355 OUTPUT: None
1356
1357 RETURN: TI_OK on success, TI_NOK otherwise
1358
1359 ************************************************************************/
1360
switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,TI_BOOL BeaconPacket,TI_UINT8 channel)1361 static 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
switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel,SC_switchChannelCmdParam_e switchChannelCmdParam,TI_UINT8 param)1425 void 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 }
switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel,TI_BOOL BeaconPacket)1455 void 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
switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel,TI_BOOL BeaconPacket)1475 void 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
switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)1492 void 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
switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel,TI_UINT8 channelNum,TI_BOOL validity)1511 void 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