1 /*
2 * SwitchChannel.c
3 *
4 * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /** \file SwitchChannel.c
35 * \brief SwitchChannel module interface
36 *
37 * \see SwitchChannelApi.h
38 */
39
40 /****************************************************************************************************/
41 /* */
42 /* MODULE: SwitchChannel.c */
43 /* PURPOSE: SwitchChannel module interface. */
44 /* This module perform SwitchChannel (Dynamic Frequency Selection) */
45 /* according to AP command. The object responsibles for switching channel after*/
46 /* the requires time and quieting the channel for the required duration */
47 /* time. */
48 /****************************************************************************************************/
49
50 #define __FILE_ID__ FILE_ID_7
51 #include "tidef.h"
52 #include "report.h"
53 #include "osApi.h"
54 #include "paramOut.h"
55 #include "SwitchChannelApi.h"
56 #include "DataCtrl_Api.h"
57 #include "regulatoryDomainApi.h"
58 #include "apConn.h"
59 #include "siteMgrApi.h"
60 #include "PowerMgr_API.h"
61 #include "healthMonitor.h"
62 #include "TWDriver.h"
63 #include "DrvMainModules.h"
64
65 /* allocation vector */
66 #define SC_INIT_BIT (1)
67 #define SC_SM_INIT_BIT (2)
68
69 #define SC_SWITCH_CHANNEL_CMD_LEN 3
70 #define SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS 0
71 #define SC_SWITCH_CHANNEL_MODE_TX_SUS 1
72
73
74 #define SC_CHANNEL_INVALID TI_FALSE
75 #define SC_CHANNEL_VALID TI_TRUE
76
77 /* Enumerations */
78
79 /** state machine states */
80 typedef enum
81 {
82 SC_STATE_IDLE = 0,
83 SC_STATE_WAIT_4_CMD = 1,
84 SC_STATE_WAIT_4_SCR = 2,
85 SC_STATE_SC_IN_PROG = 3,
86 SC_STATE_LAST = 4
87 } switchChannel_smStates;
88
89 /** State machine events */
90 typedef enum
91 {
92 SC_EVENT_START = 0,
93 SC_EVENT_STOP = 1,
94 SC_EVENT_SC_CMD = 2,
95 SC_EVENT_SCR_RUN = 3,
96 SC_EVENT_SCR_FAIL = 4,
97 SC_EVENT_SC_CMPLT = 5,
98 SC_EVENT_FW_RESET = 6,
99 SC_EVENT_LAST = 7
100 } switchChannel_smEvents;
101
102
103 #define SC_NUM_STATES SC_STATE_LAST
104 #define SC_NUM_EVENTS SC_EVENT_LAST
105
106
107 /* Structures */
108 typedef struct
109 {
110
111 /* SwitchChannel parameters that can be configured externally */
112 TI_BOOL dot11SpectrumManagementRequired;
113
114 /* Internal SwitchChannel parameters */
115 TI_UINT8 currentState;
116 dot11_CHANNEL_SWITCH_t curChannelSwitchCmdParams;
117 TI_UINT32 SCRRequestTimestamp;
118 TI_UINT8 currentChannel;
119 TI_BOOL switchChannelStarted;
120
121 #ifdef TI_DBG
122 /* switchChannelCmd for debug */
123 dot11_CHANNEL_SWITCH_t debugChannelSwitchCmdParams;
124 TI_UINT8 ignoreCancelSwitchChannelCmd;
125 #endif
126
127 /* SwitchChannel SM */
128 fsm_stateMachine_t *pSwitchChannelSm;
129
130 /* SwitchChannel handles to other objects */
131 TI_HANDLE hTWD;
132 TI_HANDLE hSiteMgr;
133 TI_HANDLE hSCR;
134 TI_HANDLE hRegulatoryDomain;
135 TI_HANDLE hPowerMngr;
136 TI_HANDLE hApConn;
137 TI_HANDLE hReport;
138 TI_HANDLE hOs;
139
140 } switchChannel_t;
141
142
143
144
145 /* External data definitions */
146
147 /* Local functions definitions */
148
149 /* Global variables */
150
151
152 /********************************************************************************/
153 /* Internal functions prototypes. */
154 /********************************************************************************/
155
156
157 /* SM functions */
158 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData);
159 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData);
160 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData);
161 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData);
162 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData);
163 static TI_STATUS switchChannel_smNop(void *pData);
164 static TI_STATUS switchChannel_smUnexpected(void *pData);
165 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData);
166 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData);
167 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData);
168 static TI_STATUS switchChannel_smStart(void *pData);
169
170
171 /* other functions */
172 static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec);
173 static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data);
174 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel);
175 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel);
176 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus,
177 EScrResourceId eResource, EScePendReason pendReason );
178 #ifdef TI_DBG
179 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel);
180 #endif
181
182
183 /********************************************************************************/
184 /* Interface functions Implementation. */
185 /********************************************************************************/
186
187
188 /************************************************************************
189 * switchChannel_create *
190 ************************************************************************/
191 /**
192 *
193 * \b Description:
194 *
195 * This procedure is called by the config manager when the driver is created.
196 * It creates the SwitchChannel object.
197 *
198 * \b ARGS:
199 *
200 * I - hOs - OS context \n
201 *
202 * \b RETURNS:
203 *
204 * Handle to the SwitchChannel object.
205 *
206 * \sa
207 */
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
532 if (TI_TRUE == pSwitchChannel->switchChannelStarted)
533 {
534 apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL);
535 }
536
537 }
538 else
539 { /* Invoke Switch Channel command */
540 /* update the new SCC params */
541 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
542 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
543 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
544 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel);
545 }
546
547 }
548
549 }
550
551
552 /************************************************************************
553 * switchChannel_powerSaveStatusReturn *
554 ************************************************************************/
555 /**
556 *
557 * \b Description:
558 *
559 * This procedure is called when power save status is returned
560 *
561 * \b ARGS:
562 *
563 * I/O - hSwitchChannel - SwitchChannel context \n
564 *
565 * \b RETURNS:
566 *
567 * TI_OK on success, TI_NOK otherwise.
568 *
569 * \sa
570 */
switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)571 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)
572 {
573 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
574
575 if (pSwitchChannel == NULL)
576 {
577 return;
578 }
579 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_SwitchChannelCmdCompleteReturn \n");
580
581 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMPLT, pSwitchChannel);
582
583 }
584
585 /************************************************************************
586 * switchChannel_enableDisableSpectrumMngmt *
587 ************************************************************************/
588 /**
589 *
590 * \b Description:
591 *
592 * This procedure enables or disables the spectrum management
593 *
594 * \b ARGS:
595 *
596 * I - hSwitchChannel - SwitchChannel context \n
597 * I - enableDisable - TI_TRUE - Enable, TI_FALSE - Disable
598 *
599 * \b RETURNS:
600 *
601 * TI_OK on success, TI_NOK otherwise.
602 *
603 * \sa
604 */
switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel,TI_BOOL enableDisable)605 void switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel, TI_BOOL enableDisable)
606 {
607 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
608
609
610 if (hSwitchChannel == NULL)
611 {
612 return;
613 }
614 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_enableDisableSpectrumMngmt, enableDisable=%d \n", enableDisable);
615
616 pSwitchChannel->dot11SpectrumManagementRequired = enableDisable;
617
618 if (enableDisable)
619 { /* Enable SC, if it was started invoke start event.
620 otherwise, wait for a start event */
621 if (pSwitchChannel->switchChannelStarted)
622 {
623 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel);
624 }
625 }
626 else
627 { /* Disable SC */
628 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel);
629 }
630
631 }
632
633
634
635 /************************************************************************
636 * SwitchChannel internal functions *
637 ************************************************************************/
638
639 /************************************************************************
640 * switchChannel_smEvent *
641 ************************************************************************/
642 /**
643 *
644 * \b Description:
645 *
646 * SwitchChannel state machine transition function
647 *
648 * \b ARGS:
649 *
650 * I/O - currentState - current state in the state machine\n
651 * I - event - specific event for the state machine\n
652 * I - pData - Data for state machine action function\n
653 *
654 * \b RETURNS:
655 *
656 * TI_OK on success, TI_NOK otherwise.
657 *
658 * \sa
659 */
switchChannel_smEvent(TI_UINT8 * currState,TI_UINT8 event,void * data)660 static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data)
661 {
662 TI_STATUS status;
663 TI_UINT8 nextState;
664 switchChannel_t *pSwitchChannel = (switchChannel_t*)data;
665
666
667 status = fsm_GetNextState(pSwitchChannel->pSwitchChannelSm, *currState, event, &nextState);
668 if (status != TI_OK)
669 {
670 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent, fsm_GetNextState error\n");
671 return(TI_NOK);
672 }
673
674 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState);
675
676 status = fsm_Event(pSwitchChannel->pSwitchChannelSm, currState, event, (void *)pSwitchChannel);
677
678 if (status != TI_OK)
679 {
680 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent fsm_Event error\n");
681 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState);
682 }
683 return status;
684
685 }
686
687
688 /************************************************************************
689 * switchChannel_smStart *
690 ************************************************************************/
691 /**
692 *
693 *
694 * \b Description:
695 *
696 * This function is called when the station becomes connected.
697 * update the current channel.
698 *
699 * \b ARGS:
700 *
701 * I - pData - pointer to the SwitchChannel SM context \n
702 *
703 * \b RETURNS:
704 *
705 * TI_OK if successful, TI_NOK otherwise.
706 *
707 *
708 *************************************************************************/
switchChannel_smStart(void * pData)709 static TI_STATUS switchChannel_smStart(void *pData)
710 {
711 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData;
712 paramInfo_t param;
713
714 if (pSwitchChannel == NULL)
715 {
716 return TI_NOK;
717 }
718
719 /* get the current channel number */
720 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
721 siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m);
722 pSwitchChannel->currentChannel = param.content.siteMgrCurrentChannel;
723
724 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStart, channelNo=%d\n", pSwitchChannel->currentChannel);
725 return TI_OK;
726
727 }
728
729 /************************************************************************
730 * switchChannel_smReqSCR_UpdateCmd *
731 ************************************************************************/
732 /**
733 *
734 *
735 * \b Description:
736 *
737 * Update the Switch Channel command parameters.
738 * Request SCR and wait for SCR return.
739 * if tx status suspend
740 * update regulatory Domain
741 * update tx
742 * start periodic timer
743
744 *
745 * \b ARGS:
746 *
747 * I - pData - pointer to the SwitchChannel SM context \n
748 *
749 * \b RETURNS:
750 *
751 * TI_OK if successful, TI_NOK otherwise.
752 *
753 *
754 *************************************************************************/
switchChannel_smReqSCR_UpdateCmd(void * pData)755 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData)
756 {
757 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData;
758 EScrClientRequestStatus scrStatus;
759 EScePendReason scrPendReason;
760
761 if (pSwitchChannel == NULL)
762 {
763 return TI_NOK;
764 }
765 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smReqSCR_UpdateCmd, channelNo=%d, TBTT = %d, Mode = %d\n", pSwitchChannel->curChannelSwitchCmdParams.channelNumber, pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount, pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode);
766
767
768 /* Save the TS when requesting SCR */
769 pSwitchChannel->SCRRequestTimestamp = os_timeStampMs(pSwitchChannel->hOs);
770
771 scrStatus = scr_clientRequest(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL,
772 SCR_RESOURCE_SERVING_CHANNEL, &scrPendReason);
773 if ((scrStatus != SCR_CRS_RUN) && (scrStatus != SCR_CRS_PEND))
774 {
775 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smReqSCR_UpdateCmd():Abort the switch channel, request Roaming, scrStatus=%d\n", scrStatus);
776 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));
777
778 }
779 if (scrStatus == SCR_CRS_RUN)
780 {
781 switchChannel_scrStatusCB(pSwitchChannel, scrStatus, SCR_RESOURCE_SERVING_CHANNEL, scrPendReason);
782 }
783 else if ((scrPendReason==SCR_PR_OTHER_CLIENT_RUNNING) ||
784 (scrPendReason==SCR_PR_DIFFERENT_GROUP_RUNNING) )
785 { /* No use to wait for the SCR, invoke FAIL */
786 return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));
787 }
788 /* wait for the SCR callback function to be called */
789 return TI_OK;
790
791 }
792
793
794 /************************************************************************
795 * switchChannel_scrStatusCB *
796 ************************************************************************/
797 /**
798 *
799 *
800 * \b Description:
801 *
802 * This function is called by the SCR when:
803 * the resource is reserved for the SwitchChannel - SCR_CRS_RUN
804 * recovery occurred - SCR_CRS_ABORT
805 * other = ERROR
806 *
807 * \b ARGS:
808 *
809 * I - hSwitchChannel - pointer to the SwitchChannel SM context \n
810 * I - requestStatus - the SCR request status \n
811 * I - eResource - the resource for which the CB is issued \n
812 * I - pendReason - The SCR pend status in case of pend reply \n
813 *
814 * \b RETURNS:
815 *
816 * None.
817 *
818 *
819 *************************************************************************/
switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel,EScrClientRequestStatus requestStatus,EScrResourceId eResource,EScePendReason pendReason)820 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus,
821 EScrResourceId eResource, EScePendReason pendReason )
822 {
823 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
824 switchChannel_smEvents scEvent;
825
826 if (pSwitchChannel == NULL)
827 {
828 return;
829 }
830
831 switch (requestStatus)
832 {
833 case SCR_CRS_RUN:
834 scEvent = SC_EVENT_SCR_RUN;
835 break;
836 case SCR_CRS_FW_RESET:
837 scEvent = SC_EVENT_FW_RESET;
838 break;
839 case SCR_CRS_PEND:
840 scEvent = SC_EVENT_SCR_FAIL;
841 break;
842 case SCR_CRS_ABORT:
843 default:
844 TRACE2(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_scrStatusCB scrStatus = %d, pendReason=%d\n", requestStatus, pendReason);
845 scEvent = SC_EVENT_SCR_FAIL;
846 break;
847 }
848
849 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, scEvent, pSwitchChannel);
850
851 }
852
853
854
855 /************************************************************************
856 * switchChannel_smStartSwitchChannelCmd *
857 ************************************************************************/
858 /**
859 *
860 *
861 * \b Description:
862 *
863 * This function is called once SwitchChannel command was received and the SCR
864 * request returned with reason RUN.
865 * In this case perform the following:
866 * Set CMD to FW
867
868
869 *
870 * \b ARGS:
871 *
872 * I - pData - pointer to the SwitchChannel SM context \n
873 *
874 * \b RETURNS:
875 *
876 * TI_OK if successful, TI_NOK otherwise.
877 *
878 *
879 *************************************************************************/
switchChannel_smStartSwitchChannelCmd(void * pData)880 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData)
881 {
882 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData;
883 TSwitchChannelParams pSwitchChannelCmd;
884 TI_UINT32 switchChannelTimeDuration;
885 paramInfo_t param;
886
887 if (pSwitchChannel == NULL)
888 {
889 return TI_NOK;
890 }
891
892 param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM;
893 siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m);
894
895 switchChannelTimeDuration = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount * param.content.beaconInterval * 1024 / 1000;
896 if ( (switchChannelTimeDuration!=0) &&
897 ((os_timeStampMs(pSwitchChannel->hOs) - pSwitchChannel->SCRRequestTimestamp) >= switchChannelTimeDuration ))
898 { /* There's no time to perfrom the SCC, set the Count to 1 */
899 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 1;
900 }
901
902 apConn_indicateSwitchChannelInProgress(pSwitchChannel->hApConn);
903
904 pSwitchChannelCmd.channelNumber = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
905 pSwitchChannelCmd.switchTime = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount;
906 pSwitchChannelCmd.txFlag = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode;
907 pSwitchChannelCmd.flush = 0;
908 TWD_CmdSwitchChannel (pSwitchChannel->hTWD, &pSwitchChannelCmd);
909
910 TRACE4(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "TWD_CmdSwitchChannel:Set the cmd in HAL. Params:\n channelNumber=%d, switchTime=%d, txFlag=%d, flush=%d \n", pSwitchChannelCmd.channelNumber, pSwitchChannelCmd.switchTime, pSwitchChannelCmd.txFlag, pSwitchChannelCmd.flush);
911
912 return TI_OK;
913
914 }
915
916 /************************************************************************
917 * switchChannel_smFwResetWhileSCInProg *
918 ************************************************************************/
919 /**
920 *
921 *
922 * \b Description:
923 *
924 * This function is called when Switch Channel command is cancelled.
925 * In this case update TX nad regulatory Domain adn HAL.
926 * Release the SCR and exit PS.
927 *
928 * \b ARGS:
929 *
930 * I - pData - pointer to the SwitchChannel SM context \n
931 *
932 * \b RETURNS:
933 *
934 * TI_OK if successful, TI_NOK otherwise.
935 *
936 *
937 *************************************************************************/
switchChannel_smFwResetWhileSCInProg(void * pData)938 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData)
939 {
940 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData;
941 paramInfo_t param;
942
943 if (pSwitchChannel == NULL)
944 {
945 return TI_NOK;
946 }
947 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smFwResetWhileSCInProg \n");
948
949 /* Update new current channel */
950 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
951 param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
952 siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m);
953
954 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
955
956 switchChannel_zeroDatabase(pSwitchChannel);
957
958 /* release the SCR */
959 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
960
961 return TI_OK;
962
963 }
964
965
966 /************************************************************************
967 * switchChannel_smSwitchChannelCmplt *
968 ************************************************************************/
969 /**
970 *
971 *
972 * \b Description:
973 *
974 * This function is called when SwitchChannel command completed in FW.
975 * In this case release SCR and update current channel.
976 * If TX was sus, it will be enabled only after first Beacon is recieved.
977 * Exit PS.
978 *
979 * \b ARGS:
980 *
981 * I - pData - pointer to the SwitchChannel SM context \n
982 *
983 * \b RETURNS:
984 *
985 * TI_OK if successful, TI_NOK otherwise.
986 *
987 *
988 *************************************************************************/
switchChannel_smSwitchChannelCmplt(void * pData)989 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData)
990 {
991 switchChannel_t *pSwitchChannel = (switchChannel_t *)pData;
992 paramInfo_t param;
993
994 if (pSwitchChannel == NULL)
995 {
996 return TI_NOK;
997 }
998
999 /* Update new current channel */
1000 param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
1001 param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
1002 siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m);
1003
1004 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smSwitchChannelCmplt, new channelNum = %d\n", pSwitchChannel->currentChannel);
1005
1006 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
1007 switchChannel_zeroDatabase(pSwitchChannel);
1008
1009 /* release the SCR */
1010 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1011
1012 return TI_OK;
1013
1014 }
1015
1016
1017
1018 /************************************************************************
1019 * switchChannel_smScrFailWhileWait4Scr *
1020 ************************************************************************/
1021 /**
1022 *
1023 *
1024 * \b Description:
1025 *
1026 * This function is called when recovery occurred, while waiting for SCR due
1027 * to previous switch channel command.
1028 * Exit PS
1029 * Release SCR.
1030 *
1031 * \b ARGS:
1032 *
1033 * I - pData - pointer to the SwitchChannel SM context \n
1034 *
1035 * \b RETURNS:
1036 *
1037 * TI_OK if successful, TI_NOK otherwise.
1038 *
1039 *
1040 *************************************************************************/
switchChannel_smScrFailWhileWait4Scr(void * pData)1041 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData)
1042 {
1043 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData;
1044
1045 if (pSwitchChannel == NULL)
1046 {
1047 return TI_NOK;
1048 }
1049
1050 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smScrFailWhileWait4Scr\n");
1051
1052 switchChannel_zeroDatabase(pSwitchChannel);
1053
1054 /* release the SCR is not required !!! */
1055 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1056
1057 return TI_OK;
1058 }
1059
1060 /************************************************************************
1061 * switchChannel_smStopWhileWait4Cmd *
1062 ************************************************************************/
1063 /**
1064 *
1065 *
1066 * \b Description:
1067 *
1068 * This function is called when the station becomes Disconnected and the current
1069 * state is Wait4Cmd. In this case perfrom:
1070 * Stop the timer
1071 * Enable TX if it was disabled
1072 * Zero the current command parameters
1073 * Stop the timer
1074 *
1075 * \b ARGS:
1076 *
1077 * I - pData - pointer to the SwitchChannel SM context \n
1078 *
1079 * \b RETURNS:
1080 *
1081 * TI_OK if successful, TI_NOK otherwise.
1082 *
1083 *
1084 *************************************************************************/
switchChannel_smStopWhileWait4Cmd(void * pData)1085 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData)
1086 {
1087 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData;
1088
1089 if (pSwitchChannel == NULL)
1090 {
1091 return TI_NOK;
1092 }
1093
1094 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Cmd\n");
1095
1096 switchChannel_zeroDatabase(pSwitchChannel);
1097
1098 return TI_OK;
1099 }
1100
1101 /************************************************************************
1102 * switchChannel_smStopWhileWait4Scr *
1103 ************************************************************************/
1104 /**
1105 *
1106 *
1107 * \b Description:
1108 *
1109 * This function is called when the station becomes Disconnected and the current
1110 * state is Wait4Scr. In this case perfrom:
1111 * Stop the timer
1112 * Enable TX if it was disabled
1113 * Zero the current command parameters
1114 * Complete SCR
1115 *
1116 * \b ARGS:
1117 *
1118 * I - pData - pointer to the SwitchChannel SM context \n
1119 *
1120 * \b RETURNS:
1121 *
1122 * TI_OK if successful, TI_NOK otherwise.
1123 *
1124 *
1125 *************************************************************************/
switchChannel_smStopWhileWait4Scr(void * pData)1126 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData)
1127 {
1128 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData;
1129
1130 if (pSwitchChannel == NULL)
1131 {
1132 return TI_NOK;
1133 }
1134
1135 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Scr\n");
1136
1137
1138 switchChannel_zeroDatabase(pSwitchChannel);
1139
1140 /* release the SCR */
1141 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1142
1143 return TI_OK;
1144 }
1145
1146 /************************************************************************
1147 * switchChannel_smStopWhileSwitchChannelInProg *
1148 ************************************************************************/
1149 /**
1150 *
1151 *
1152 * \b Description:
1153 *
1154 * This function is called when the station becomes Disconnected and the current
1155 * state is SwitchChannelInProg. In this case perfrom:
1156 * Stop the timer
1157 * Enable TX if it was disabled
1158 * Zero the current command parameters
1159 * resume self test
1160 * Complete SCR
1161 * Exit PS
1162 *
1163 * \b ARGS:
1164 *
1165 * I - pData - pointer to the SwitchChannel SM context \n
1166 *
1167 * \b RETURNS:
1168 *
1169 * TI_OK if successful, TI_NOK otherwise.
1170 *
1171 *
1172 *************************************************************************/
switchChannel_smStopWhileSwitchChannelInProg(void * pData)1173 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData)
1174 {
1175 switchChannel_t *pSwitchChannel = (switchChannel_t*)pData;
1176
1177 if (pSwitchChannel == NULL)
1178 {
1179 return TI_NOK;
1180 }
1181
1182 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileSwitchChannelInProg\n");
1183
1184 /* Exit PS */
1185 /*PowerMgr_exitFromDriverMode(pSwitchChannel->hPowerMngr, "SwitchChannel");*/
1186
1187 apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
1188
1189 TWD_CmdSwitchChannelCancel (pSwitchChannel->hTWD, pSwitchChannel->currentChannel);
1190 switchChannel_zeroDatabase(pSwitchChannel);
1191
1192 /* release the SCR */
1193 scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1194
1195 return TI_OK;
1196 }
1197
1198
1199
1200
1201 /************************************************************************
1202 * switchChannel_zeroDatabase *
1203 ************************************************************************/
1204 /**
1205 *
1206 *
1207 * \b Description:
1208 *
1209 * This function is called when the SwitchChannel internal database should be zero.
1210 * The following parameters are zerod:
1211 * SwitchChannelChannelRange - the timestamps and validity state of channels
1212 * curChannelSwitchCmdParams - the current switch channel command parameters
1213 *
1214 * \b ARGS:
1215 *
1216 * I - pSwitchChannel - pointer to the SwitchChannel SM context \n
1217 * I - channelNum - channel number \n
1218 * I - timestamp - required timestamp \n
1219 *
1220 * \b RETURNS:
1221 *
1222 * None.
1223 *
1224 *
1225 *************************************************************************/
switchChannel_zeroDatabase(switchChannel_t * pSwitchChannel)1226 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel)
1227 {
1228
1229 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_zeroDatabase\n");
1230
1231
1232 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = 0;
1233 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 0;
1234 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS;
1235 pSwitchChannel->currentChannel = 0;
1236
1237 }
1238
1239 /***********************************************************************
1240 * release_module
1241 ***********************************************************************/
1242 /*
1243 DESCRIPTION: Called by the destroy function or by the create function (on failure)
1244 Go over the vector, for each bit that is set, release the corresponding module.
1245
1246 INPUT: pSwitchChannel - SwitchChannel pointer.
1247 initVec - Vector that contains a bit set for each module thah had been initiualized
1248
1249 OUTPUT:
1250
1251 RETURN: TI_OK on success, TI_NOK otherwise
1252
1253 ************************************************************************/
release_module(switchChannel_t * pSwitchChannel,TI_UINT32 initVec)1254 static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec)
1255 {
1256 if (pSwitchChannel == NULL)
1257 {
1258 return;
1259 }
1260 if (initVec & (1 << SC_SM_INIT_BIT))
1261 {
1262 fsm_Unload(pSwitchChannel->hOs, pSwitchChannel->pSwitchChannelSm);
1263 }
1264
1265 if (initVec & (1 << SC_INIT_BIT))
1266 {
1267 os_memoryFree(pSwitchChannel->hOs, pSwitchChannel, sizeof(switchChannel_t));
1268 }
1269
1270 initVec = 0;
1271 }
1272
1273
1274 /**
1275 *
1276 * switchChannel_smNop - Do nothing
1277 *
1278 * \b Description:
1279 *
1280 * Do nothing in the SM.
1281 *
1282 * \b ARGS:
1283 *
1284 * I - pData - pointer to the SwitchChannel SM context \n
1285 *
1286 * \b RETURNS:
1287 *
1288 * TI_OK if successful, TI_NOK otherwise.
1289 *
1290 *
1291 */
switchChannel_smNop(void * pData)1292 static TI_STATUS switchChannel_smNop(void *pData)
1293 {
1294 switchChannel_t *pSwitchChannel;
1295
1296 pSwitchChannel = (switchChannel_t*)pData;
1297 if (pSwitchChannel == NULL)
1298 {
1299 return TI_NOK;
1300 }
1301 TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, " switchChannel_smNop\n");
1302
1303 return TI_OK;
1304 }
1305
1306 /**
1307 *
1308 * switchChannel_smUnexpected - Unexpected event
1309 *
1310 * \b Description:
1311 *
1312 * Unexpected event in the SM.
1313 *
1314 * \b ARGS:
1315 *
1316 * I - pData - pointer to the SwitchChannel SM context \n
1317 *
1318 * \b RETURNS:
1319 *
1320 * TI_OK if successful, TI_NOK otherwise.
1321 *
1322 *
1323 */
switchChannel_smUnexpected(void * pData)1324 static TI_STATUS switchChannel_smUnexpected(void *pData)
1325 {
1326 switchChannel_t *pSwitchChannel;
1327
1328 pSwitchChannel = (switchChannel_t*)pData;
1329 if (pSwitchChannel == NULL)
1330 {
1331 return TI_NOK;
1332 }
1333 TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, " switchChannel_smUnexpected, state = %d\n", pSwitchChannel->currentState);
1334
1335 return TI_NOK;
1336 }
1337
1338 /*******************************************************************************
1339 *********** Debug functions ***********
1340 *******************************************************************************/
1341 #ifdef TI_DBG
1342
1343 /************************************************************************
1344 * switchChannel_recvCmd *
1345 ************************************************************************/
1346 /*DESCRIPTION: This function is called by MLME Parser upon receiving of
1347 Beacon, Probe Response or Action with Switch Channel command,
1348 or beacon/
1349 performs the following:
1350 - Initializes the switching channel procedure.
1351 - Setting timer to the actual switching time(if needed)
1352
1353 INPUT: hSwitchChannel - SwitchChannel handle.
1354 switchMode - indicates whether to stop transmission
1355 until the scheduled channel switch.
1356 newChannelNum - indicates the number of the new channel.
1357 durationTime - indicates the time (expressed in ms) until
1358 the scheduled channel switch should accure.
1359
1360 OUTPUT: None
1361
1362 RETURN: TI_OK on success, TI_NOK otherwise
1363
1364 ************************************************************************/
1365
switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,TI_BOOL BeaconPacket,TI_UINT8 channel)1366 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel)
1367 {
1368
1369 switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
1370 paramInfo_t param;
1371
1372 if (pSwitchChannel==NULL)
1373 {
1374 return;
1375 }
1376
1377
1378 /* The following is for debug purposes only
1379 It will be operated when the Switch Channel cmd is opertated from debug CLI */
1380 if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0)
1381 {
1382 if (pSwitchChannel->ignoreCancelSwitchChannelCmd == 1)
1383 {
1384 /* update the new SCC params */
1385 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
1386 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
1387 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
1388
1389 pSwitchChannel->ignoreCancelSwitchChannelCmd = 2;
1390 }
1391 else if (channelSwitch->channelSwitchCount>0)
1392 {
1393 channelSwitch->channelSwitchCount --;
1394 }
1395 else
1396 {
1397 pSwitchChannel->ignoreCancelSwitchChannelCmd = 0;
1398 }
1399
1400
1401 /* search in the buffer pointer to the beginning of the
1402 Switch Cahnnel Announcement IE according to the IE ID */
1403
1404 /* SC IE exists on the serving channel */
1405 TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n", channelSwitch->channelNumber, channelSwitch->channelSwitchMode, channelSwitch->channelSwitchCount);
1406
1407 /* Checking channel number validity */
1408 param.content.channel = channelSwitch->channelNumber;
1409 param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED;
1410 regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m);
1411 if (( !param.content.bIsChannelSupprted ) ||
1412 (channelSwitch->channelSwitchCount == 0) ||
1413 (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS))
1414 { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid,
1415 or the TBTT count is 0 */
1416 apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL);
1417 }
1418 else
1419 { /* Invoke Switch Channel command */
1420 /* update the new SCC params */
1421 pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
1422 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
1423 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
1424 switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel);
1425 }
1426 }
1427
1428 }
1429
switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel,SC_switchChannelCmdParam_e switchChannelCmdParam,TI_UINT8 param)1430 void switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel, SC_switchChannelCmdParam_e switchChannelCmdParam, TI_UINT8 param)
1431 {
1432 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1433
1434 if (pSwitchChannel == NULL)
1435 {
1436 return;
1437 }
1438
1439 switch (switchChannelCmdParam)
1440 {
1441 case SC_SWITCH_CHANNEL_NUM:
1442 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelNum=%d \n ", param));
1443 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber = param;
1444 break;
1445 case SC_SWITCH_CHANNEL_TBTT:
1446 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchCount=%d \n ", param));
1447 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount = param;
1448 break;
1449 case SC_SWITCH_CHANNEL_MODE:
1450 WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchMode=%d \n ", param));
1451 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode = param;
1452 break;
1453 default:
1454 WLAN_OS_REPORT(("ERROR: SwitchChannelDebug_setSwitchChannelCmdParams, wrong switchChannelCmdParam=%d \n ",
1455 switchChannelCmdParam));
1456 break;
1457 }
1458
1459 }
switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel,TI_BOOL BeaconPacket)1460 void switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket)
1461 {
1462 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1463
1464 if (pSwitchChannel == NULL)
1465 {
1466 return;
1467 }
1468
1469 WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n cmd params: channelNumber=%d, channelSwitchCount=%d, channelSwitchMode=%d \n",
1470 BeaconPacket,
1471 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber,
1472 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount,
1473 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode));
1474
1475
1476 pSwitchChannel->ignoreCancelSwitchChannelCmd= 1;
1477 switchChannel_recvCmd4Debug(hSwitchChannel, &pSwitchChannel->debugChannelSwitchCmdParams, BeaconPacket, pSwitchChannel->currentChannel);
1478 }
1479
switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel,TI_BOOL BeaconPacket)1480 void switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket)
1481 {
1482
1483 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1484
1485 if (pSwitchChannel == NULL)
1486 {
1487 return;
1488 }
1489
1490 WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n",BeaconPacket));
1491
1492 pSwitchChannel->ignoreCancelSwitchChannelCmd= 0;
1493 switchChannel_recvCmd4Debug(hSwitchChannel, NULL, BeaconPacket, pSwitchChannel->currentChannel);
1494 }
1495
1496
switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)1497 void switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)
1498 {
1499 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1500
1501 if (pSwitchChannel == NULL)
1502 {
1503 return;
1504 }
1505
1506 WLAN_OS_REPORT(("SwitchChannel debug params are: channelNumber=%d, channelSwitchCount=%d , channelSwitchMode=%d \n",
1507 pSwitchChannel->debugChannelSwitchCmdParams.channelNumber,
1508 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount,
1509 pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode));
1510
1511 WLAN_OS_REPORT(("SwitchChannel state=%d, currentChannel=%d \n", pSwitchChannel->currentState, pSwitchChannel->currentChannel));
1512
1513
1514 }
1515
switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel,TI_UINT8 channelNum,TI_BOOL validity)1516 void switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel, TI_UINT8 channelNum, TI_BOOL validity)
1517 {
1518 paramInfo_t param;
1519
1520 switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1521
1522 if (pSwitchChannel == NULL)
1523 {
1524 return;
1525 }
1526
1527 param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY;
1528 param.content.channelValidity.channelNum = channelNum;
1529 param.content.channelValidity.channelValidity = validity;
1530 regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m);
1531
1532 }
1533
1534 #endif /* TI_DBG */
1535
1536
1537
1538
1539
1540
1541