2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Purpose: Handles the management command interface functions
28 * s_vProbeChannel - Active scan channel
29 * s_MgrMakeProbeRequest - Make ProbeRequest packet
30 * CommandTimer - Timer function to handle command
31 * s_bCommandComplete - Command Complete function
32 * bScheduleCommand - Push Command and wait Command Scheduler to do
33 * vCommandTimer- Command call back functions
34 * vCommandTimerWait- Call back timer
35 * bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue
57 /*--------------------- Static Definitions -------------------------*/
59 /*--------------------- Static Classes ----------------------------*/
61 /*--------------------- Static Variables --------------------------*/
62 static int msglevel
= MSG_LEVEL_INFO
;
63 /*--------------------- Static Functions --------------------------*/
73 s_MgrMakeProbeRequest(
76 unsigned char *pScanBSSID
,
78 PWLAN_IE_SUPP_RATES pCurrRates
,
79 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
88 /*--------------------- Export Variables --------------------------*/
90 /*--------------------- Export Functions --------------------------*/
94 * Stop AdHoc beacon during scan process
98 * pDevice - Pointer to the adapter
107 vAdHocBeaconStop(PSDevice pDevice
)
109 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
113 * temporarily stop Beacon packet for AdHoc Server
114 * if all of the following conditions are met:
115 * (1) STA is in AdHoc mode
116 * (2) VT3253 is programmed as automatic Beacon Transmitting
117 * (3) One of the following conditions is met
118 * (3.1) AdHoc channel is in B/G band and the
119 * current scan channel is in A band
121 * (3.2) AdHoc channel is in A mode
124 if ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) &&
125 (pMgmt
->eCurrState
>= WMAC_STATE_STARTED
)) {
126 if ((pMgmt
->uIBSSChannel
<= CB_MAX_CHANNEL_24G
) &&
127 (pMgmt
->uScanChannel
> CB_MAX_CHANNEL_24G
)) {
130 if (pMgmt
->uIBSSChannel
> CB_MAX_CHANNEL_24G
)
136 MACvRegBitsOff(pDevice
->PortOffset
, MAC_REG_TCR
, TCR_AUTOBCNTX
);
137 } /* vAdHocBeaconStop */
141 * Restart AdHoc beacon after scan process complete
145 * pDevice - Pointer to the adapter
154 vAdHocBeaconRestart(PSDevice pDevice
)
156 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
159 * Restart Beacon packet for AdHoc Server
160 * if all of the following coditions are met:
161 * (1) STA is in AdHoc mode
162 * (2) VT3253 is programmed as automatic Beacon Transmitting
164 if ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) &&
165 (pMgmt
->eCurrState
>= WMAC_STATE_STARTED
)) {
166 MACvRegBitsOn(pDevice
->PortOffset
, MAC_REG_TCR
, TCR_AUTOBCNTX
);
172 * Routine Description:
173 * Prepare and send probe request management frames.
187 //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M
188 unsigned char abyCurrSuppRatesG
[] = {WLAN_EID_SUPP_RATES
, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
189 unsigned char abyCurrExtSuppRatesG
[] = {WLAN_EID_EXTSUPP_RATES
, 4, 0x0C, 0x12, 0x18, 0x60};
191 unsigned char abyCurrSuppRatesA
[] = {WLAN_EID_SUPP_RATES
, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
192 unsigned char abyCurrSuppRatesB
[] = {WLAN_EID_SUPP_RATES
, 4, 0x02, 0x04, 0x0B, 0x16};
193 unsigned char *pbyRate
;
194 PSTxMgmtPacket pTxPacket
;
195 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
198 if (pDevice
->eCurrentPHYType
== PHY_TYPE_11A
)
199 pbyRate
= &abyCurrSuppRatesA
[0];
200 else if (pDevice
->eCurrentPHYType
== PHY_TYPE_11B
)
201 pbyRate
= &abyCurrSuppRatesB
[0];
203 pbyRate
= &abyCurrSuppRatesG
[0];
205 // build an assocreq frame and send it
206 pTxPacket
= s_MgrMakeProbeRequest
211 (PWLAN_IE_SSID
)pMgmt
->abyScanSSID
,
212 (PWLAN_IE_SUPP_RATES
)pbyRate
,
213 (PWLAN_IE_SUPP_RATES
)abyCurrExtSuppRatesG
216 if (pTxPacket
!= NULL
) {
217 for (ii
= 0; ii
< 2; ii
++) {
218 if (csMgmt_xmit(pDevice
, pTxPacket
) != CMD_STATUS_PENDING
)
219 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Probe request sending fail.. \n");
221 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Probe request is sending.. \n");
228 * Routine Description:
229 * Constructs an probe request frame
233 * A ptr to Tx frame or NULL on allocation failure
238 s_MgrMakeProbeRequest(
241 unsigned char *pScanBSSID
,
243 PWLAN_IE_SUPP_RATES pCurrRates
,
244 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
248 PSTxMgmtPacket pTxPacket
= NULL
;
249 WLAN_FR_PROBEREQ sFrame
;
251 pTxPacket
= (PSTxMgmtPacket
)pMgmt
->pbyMgmtPacketPool
;
252 memset(pTxPacket
, 0, sizeof(STxMgmtPacket
) + WLAN_PROBEREQ_FR_MAXLEN
);
253 pTxPacket
->p80211Header
= (PUWLAN_80211HDR
)((unsigned char *)pTxPacket
+ sizeof(STxMgmtPacket
));
254 sFrame
.pBuf
= (unsigned char *)pTxPacket
->p80211Header
;
255 sFrame
.len
= WLAN_PROBEREQ_FR_MAXLEN
;
256 vMgrEncodeProbeRequest(&sFrame
);
257 sFrame
.pHdr
->sA3
.wFrameCtl
= cpu_to_le16(
259 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR
) |
260 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ
)
262 memcpy(sFrame
.pHdr
->sA3
.abyAddr1
, pScanBSSID
, WLAN_ADDR_LEN
);
263 memcpy(sFrame
.pHdr
->sA3
.abyAddr2
, pMgmt
->abyMACAddr
, WLAN_ADDR_LEN
);
264 memcpy(sFrame
.pHdr
->sA3
.abyAddr3
, pScanBSSID
, WLAN_BSSID_LEN
);
265 // Copy the SSID, pSSID->len=0 indicate broadcast SSID
266 sFrame
.pSSID
= (PWLAN_IE_SSID
)(sFrame
.pBuf
+ sFrame
.len
);
267 sFrame
.len
+= pSSID
->len
+ WLAN_IEHDR_LEN
;
268 memcpy(sFrame
.pSSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
269 sFrame
.pSuppRates
= (PWLAN_IE_SUPP_RATES
)(sFrame
.pBuf
+ sFrame
.len
);
270 sFrame
.len
+= pCurrRates
->len
+ WLAN_IEHDR_LEN
;
271 memcpy(sFrame
.pSuppRates
, pCurrRates
, pCurrRates
->len
+ WLAN_IEHDR_LEN
);
272 // Copy the extension rate set
273 if (pDevice
->eCurrentPHYType
== PHY_TYPE_11G
) {
274 sFrame
.pExtSuppRates
= (PWLAN_IE_SUPP_RATES
)(sFrame
.pBuf
+ sFrame
.len
);
275 sFrame
.len
+= pCurrExtSuppRates
->len
+ WLAN_IEHDR_LEN
;
276 memcpy(sFrame
.pExtSuppRates
, pCurrExtSuppRates
, pCurrExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
278 pTxPacket
->cbMPDULen
= sFrame
.len
;
279 pTxPacket
->cbPayloadLen
= sFrame
.len
- WLAN_HDR_ADDR3_LEN
;
286 void *hDeviceContext
,
290 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
292 init_timer(&pDevice
->sTimerCommand
);
293 pDevice
->sTimerCommand
.data
= (unsigned long) pDevice
;
294 pDevice
->sTimerCommand
.function
= (TimerFunction
)vCommandTimer
;
295 // RUN_AT :1 msec ~= (HZ/1024)
296 pDevice
->sTimerCommand
.expires
= (unsigned int)RUN_AT((MSecond
* HZ
) >> 10);
297 add_timer(&pDevice
->sTimerCommand
);
306 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
307 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
308 PWLAN_IE_SSID pItemSSID
;
309 PWLAN_IE_SSID pItemSSIDCurr
;
312 unsigned char byMask
[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
315 if (pDevice
->dwDiagRefCount
!= 0)
317 if (!pDevice
->bCmdRunning
)
320 spin_lock_irq(&pDevice
->lock
);
322 switch (pDevice
->eCommandState
) {
323 case WLAN_CMD_SCAN_START
:
325 pDevice
->byReAssocCount
= 0;
326 if (pDevice
->bRadioOff
) {
327 s_bCommandComplete(pDevice
);
328 spin_unlock_irq(&pDevice
->lock
);
332 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) {
333 s_bCommandComplete(pDevice
);
334 CARDbSetBSSID(pMgmt
->pAdapter
, pMgmt
->abyCurrBSSID
, OP_MODE_AP
);
335 spin_unlock_irq(&pDevice
->lock
);
339 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCommandState= WLAN_CMD_SCAN_START\n");
340 pItemSSID
= (PWLAN_IE_SSID
)pMgmt
->abyScanSSID
;
341 // wait all Data TD complete
342 if (pDevice
->iTDUsed
[TYPE_AC0DMA
] != 0) {
343 spin_unlock_irq(&pDevice
->lock
);
344 vCommandTimerWait((void *)pDevice
, 10);
348 if (pMgmt
->uScanChannel
== 0) {
349 pMgmt
->uScanChannel
= pDevice
->byMinChannel
;
350 // Set Baseband to be more sensitive.
353 if (pMgmt
->uScanChannel
> pDevice
->byMaxChannel
) {
354 pMgmt
->eScanState
= WMAC_NO_SCANNING
;
356 // Set Baseband's sensitivity back.
358 set_channel(pMgmt
->pAdapter
, pMgmt
->uCurrChannel
);
359 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Scanning, set back to channel: [%d]\n", pMgmt
->uCurrChannel
);
360 if (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
)
361 CARDbSetBSSID(pMgmt
->pAdapter
, pMgmt
->abyCurrBSSID
, OP_MODE_ADHOC
);
363 CARDbSetBSSID(pMgmt
->pAdapter
, pMgmt
->abyCurrBSSID
, OP_MODE_INFRASTRUCTURE
);
365 vAdHocBeaconRestart(pDevice
);
366 s_bCommandComplete(pDevice
);
369 //2008-8-4 <add> by chester
370 if (!is_channel_valid(pMgmt
->uScanChannel
)) {
371 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Invalid channel pMgmt->uScanChannel = %d \n", pMgmt
->uScanChannel
);
372 s_bCommandComplete(pDevice
);
373 spin_unlock_irq(&pDevice
->lock
);
376 if (pMgmt
->uScanChannel
== pDevice
->byMinChannel
) {
377 pMgmt
->abyScanBSSID
[0] = 0xFF;
378 pMgmt
->abyScanBSSID
[1] = 0xFF;
379 pMgmt
->abyScanBSSID
[2] = 0xFF;
380 pMgmt
->abyScanBSSID
[3] = 0xFF;
381 pMgmt
->abyScanBSSID
[4] = 0xFF;
382 pMgmt
->abyScanBSSID
[5] = 0xFF;
383 pItemSSID
->byElementID
= WLAN_EID_SSID
;
384 pMgmt
->eScanState
= WMAC_IS_SCANNING
;
388 vAdHocBeaconStop(pDevice
);
390 if (set_channel(pMgmt
->pAdapter
, pMgmt
->uScanChannel
))
391 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"SCAN Channel: %d\n", pMgmt
->uScanChannel
);
393 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"SET SCAN Channel Fail: %d\n", pMgmt
->uScanChannel
);
395 CARDbSetBSSID(pMgmt
->pAdapter
, pMgmt
->abyCurrBSSID
, OP_MODE_UNKNOWN
);
396 pMgmt
->uScanChannel
++;
397 //2008-8-4 <modify> by chester
398 if (!is_channel_valid(pMgmt
->uScanChannel
) &&
399 pMgmt
->uScanChannel
<= pDevice
->byMaxChannel
) {
400 pMgmt
->uScanChannel
= pDevice
->byMaxChannel
+ 1;
401 pMgmt
->eCommandState
= WLAN_CMD_SCAN_END
;
405 if (!pMgmt
->b11hEnable
||
406 (pMgmt
->uScanChannel
< CB_MAX_CHANNEL_24G
)) {
407 s_vProbeChannel(pDevice
);
408 spin_unlock_irq(&pDevice
->lock
);
409 vCommandTimerWait((void *)pDevice
, WCMD_ACTIVE_SCAN_TIME
);
412 spin_unlock_irq(&pDevice
->lock
);
413 vCommandTimerWait((void *)pDevice
, WCMD_PASSIVE_SCAN_TIME
);
421 case WLAN_CMD_SCAN_END
:
423 // Set Baseband's sensitivity back.
425 set_channel(pMgmt
->pAdapter
, pMgmt
->uCurrChannel
);
426 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Scanning, set back to channel: [%d]\n", pMgmt
->uCurrChannel
);
427 if (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
)
428 CARDbSetBSSID(pMgmt
->pAdapter
, pMgmt
->abyCurrBSSID
, OP_MODE_ADHOC
);
430 CARDbSetBSSID(pMgmt
->pAdapter
, pMgmt
->abyCurrBSSID
, OP_MODE_INFRASTRUCTURE
);
432 pMgmt
->eScanState
= WMAC_NO_SCANNING
;
433 vAdHocBeaconRestart(pDevice
);
434 //2008-0409-07, <Add> by Einsn Liu
435 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
436 if (pMgmt
->eScanType
== WMAC_SCAN_PASSIVE
)
437 {//send scan event to wpa_Supplicant
438 union iwreq_data wrqu
;
439 memset(&wrqu
, 0, sizeof(wrqu
));
440 wireless_send_event(pDevice
->dev
, SIOCGIWSCAN
, &wrqu
, NULL
);
443 s_bCommandComplete(pDevice
);
446 case WLAN_CMD_DISASSOCIATE_START
:
447 pDevice
->byReAssocCount
= 0;
448 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) &&
449 (pMgmt
->eCurrState
!= WMAC_STATE_ASSOC
)) {
450 s_bCommandComplete(pDevice
);
451 spin_unlock_irq(&pDevice
->lock
);
454 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Send Disassociation Packet..\n");
455 // reason = 8 : disassoc because sta has left
456 vMgrDisassocBeginSta((void *)pDevice
, pMgmt
, pMgmt
->abyCurrBSSID
, (8), &Status
);
457 pDevice
->bLinkPass
= false;
458 // unlock command busy
459 pItemSSID
= (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
;
461 memset(pItemSSID
->abySSID
, 0, WLAN_SSID_MAXLEN
);
462 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
463 pMgmt
->sNodeDBTable
[0].bActive
= false;
465 netif_stop_queue(pDevice
->dev
);
466 pDevice
->eCommandState
= WLAN_DISASSOCIATE_WAIT
;
467 // wait all Control TD complete
468 if (pDevice
->iTDUsed
[TYPE_TXDMA0
] != 0) {
469 vCommandTimerWait((void *)pDevice
, 10);
470 spin_unlock_irq(&pDevice
->lock
);
473 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" CARDbRadioPowerOff\n");
474 //2008-09-02 <mark> by chester
475 s_bCommandComplete(pDevice
);
478 case WLAN_DISASSOCIATE_WAIT
:
479 // wait all Control TD complete
480 if (pDevice
->iTDUsed
[TYPE_TXDMA0
] != 0) {
481 vCommandTimerWait((void *)pDevice
, 10);
482 spin_unlock_irq(&pDevice
->lock
);
485 //2008-09-02 <mark> by chester
486 s_bCommandComplete(pDevice
);
489 case WLAN_CMD_SSID_START
:
490 pDevice
->byReAssocCount
= 0;
491 if (pDevice
->bRadioOff
) {
492 s_bCommandComplete(pDevice
);
493 spin_unlock_irq(&pDevice
->lock
);
496 printk("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
)->abySSID
);
497 pItemSSID
= (PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
;
498 pItemSSIDCurr
= (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
;
499 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" cmd: desire ssid = %s\n", pItemSSID
->abySSID
);
500 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" cmd: curr ssid = %s\n", pItemSSIDCurr
->abySSID
);
502 if (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) {
503 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
504 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" pItemSSID->len =%d\n", pItemSSID
->len
);
505 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" pItemSSIDCurr->len = %d\n", pItemSSIDCurr
->len
);
506 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" desire ssid = %s\n", pItemSSID
->abySSID
);
507 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" curr ssid = %s\n", pItemSSIDCurr
->abySSID
);
510 if ((pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) ||
511 ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
))) {
512 if (pItemSSID
->len
== pItemSSIDCurr
->len
) {
513 if (memcmp(pItemSSID
->abySSID
, pItemSSIDCurr
->abySSID
, pItemSSID
->len
) == 0) {
514 s_bCommandComplete(pDevice
);
515 spin_unlock_irq(&pDevice
->lock
);
520 netif_stop_queue(pDevice
->dev
);
521 pDevice
->bLinkPass
= false;
524 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
525 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
526 PSvDisablePowerSaving((void *)pDevice
);
527 BSSvClearNodeDBTable(pDevice
, 0);
529 vMgrJoinBSSBegin((void *)pDevice
, &Status
);
531 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
)) {
532 // Call mgr to begin the deauthentication
533 // reason = (3) because sta has left ESS
534 if (pMgmt
->eCurrState
>= WMAC_STATE_AUTH
)
535 vMgrDeAuthenBeginSta((void *)pDevice
, pMgmt
, pMgmt
->abyCurrBSSID
, (3), &Status
);
537 // Call mgr to begin the authentication
538 vMgrAuthenBeginSta((void *)pDevice
, pMgmt
, &Status
);
539 if (Status
== CMD_STATUS_SUCCESS
) {
540 pDevice
->byLinkWaitCount
= 0;
541 pDevice
->eCommandState
= WLAN_AUTHENTICATE_WAIT
;
542 vCommandTimerWait((void *)pDevice
, AUTHENTICATE_TIMEOUT
);
543 spin_unlock_irq(&pDevice
->lock
);
544 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
549 else if (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) {
550 if (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
) {
551 if (netif_queue_stopped(pDevice
->dev
))
552 netif_wake_queue(pDevice
->dev
);
554 pDevice
->bLinkPass
= true;
556 pMgmt
->sNodeDBTable
[0].bActive
= true;
557 pMgmt
->sNodeDBTable
[0].uInActiveCount
= 0;
558 bClearBSSID_SCAN(pDevice
);
561 vMgrCreateOwnIBSS((void *)pDevice
, &Status
);
562 if (Status
!= CMD_STATUS_SUCCESS
)
563 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" WLAN_CMD_IBSS_CREATE fail ! \n");
565 BSSvAddMulticastNode(pDevice
);
569 else if (pMgmt
->eCurrMode
== WMAC_MODE_STANDBY
) {
570 if (pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
||
571 pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
) {
573 vMgrCreateOwnIBSS((void *)pDevice
, &Status
);
574 if (Status
!= CMD_STATUS_SUCCESS
)
575 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" WLAN_CMD_IBSS_CREATE fail ! \n");
577 BSSvAddMulticastNode(pDevice
);
578 if (netif_queue_stopped(pDevice
->dev
))
579 netif_wake_queue(pDevice
->dev
);
581 pDevice
->bLinkPass
= true;
583 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Disconnect SSID none\n");
584 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
586 union iwreq_data wrqu
;
587 memset(&wrqu
, 0, sizeof(wrqu
));
588 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
589 printk("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
590 wireless_send_event(pDevice
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
596 s_bCommandComplete(pDevice
);
599 case WLAN_AUTHENTICATE_WAIT
:
600 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
601 if (pMgmt
->eCurrState
== WMAC_STATE_AUTH
) {
602 // Call mgr to begin the association
603 pDevice
->byLinkWaitCount
= 0;
604 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCurrState == WMAC_STATE_AUTH\n");
605 vMgrAssocBeginSta((void *)pDevice
, pMgmt
, &Status
);
606 if (Status
== CMD_STATUS_SUCCESS
) {
607 pDevice
->byLinkWaitCount
= 0;
608 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCommandState = WLAN_ASSOCIATE_WAIT\n");
609 pDevice
->eCommandState
= WLAN_ASSOCIATE_WAIT
;
610 vCommandTimerWait((void *)pDevice
, ASSOCIATE_TIMEOUT
);
611 spin_unlock_irq(&pDevice
->lock
);
616 else if (pMgmt
->eCurrState
< WMAC_STATE_AUTHPENDING
) {
617 printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
618 } else if (pDevice
->byLinkWaitCount
<= 4) { //mike add:wait another 2 sec if authenticated_frame delay!
619 pDevice
->byLinkWaitCount
++;
620 printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice
->byLinkWaitCount
);
621 spin_unlock_irq(&pDevice
->lock
);
622 vCommandTimerWait((void *)pDevice
, AUTHENTICATE_TIMEOUT
/2);
625 pDevice
->byLinkWaitCount
= 0;
626 s_bCommandComplete(pDevice
);
629 case WLAN_ASSOCIATE_WAIT
:
630 if (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) {
631 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCurrState == WMAC_STATE_ASSOC\n");
632 if (pDevice
->ePSMode
!= WMAC_POWER_CAM
)
633 PSvEnablePowerSaving((void *)pDevice
, pMgmt
->wListenInterval
);
635 if (pMgmt
->eAuthenMode
>= WMAC_AUTH_WPA
)
636 KeybRemoveAllKey(&(pDevice
->sKey
), pDevice
->abyBSSID
, pDevice
->PortOffset
);
638 pDevice
->bLinkPass
= true;
639 pDevice
->byLinkWaitCount
= 0;
640 pDevice
->byReAssocCount
= 0;
641 bClearBSSID_SCAN(pDevice
);
642 if (pDevice
->byFOETuning
) {
643 BBvSetFOE(pDevice
->PortOffset
);
644 PSbSendNullPacket(pDevice
);
646 if (netif_queue_stopped(pDevice
->dev
))
647 netif_wake_queue(pDevice
->dev
);
650 if (pDevice
->IsTxDataTrigger
) { //TxDataTimer is not triggered at the first time
651 del_timer(&pDevice
->sTimerTxData
);
652 init_timer(&pDevice
->sTimerTxData
);
653 pDevice
->sTimerTxData
.data
= (unsigned long) pDevice
;
654 pDevice
->sTimerTxData
.function
= (TimerFunction
)BSSvSecondTxData
;
655 pDevice
->sTimerTxData
.expires
= RUN_AT(10*HZ
); //10s callback
656 pDevice
->fTxDataInSleep
= false;
657 pDevice
->nTxDataTimeCout
= 0;
660 pDevice
->IsTxDataTrigger
= true;
661 add_timer(&pDevice
->sTimerTxData
);
663 } else if (pMgmt
->eCurrState
< WMAC_STATE_ASSOCPENDING
) {
664 printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
665 } else if (pDevice
->byLinkWaitCount
<= 4) { //mike add:wait another 2 sec if associated_frame delay!
666 pDevice
->byLinkWaitCount
++;
667 printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice
->byLinkWaitCount
);
668 spin_unlock_irq(&pDevice
->lock
);
669 vCommandTimerWait((void *)pDevice
, ASSOCIATE_TIMEOUT
/2);
672 pDevice
->byLinkWaitCount
= 0;
674 s_bCommandComplete(pDevice
);
677 case WLAN_CMD_AP_MODE_START
:
678 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCommandState == WLAN_CMD_AP_MODE_START\n");
680 if (pMgmt
->eConfigMode
== WMAC_CONFIG_AP
) {
681 del_timer(&pMgmt
->sTimerSecondCallback
);
682 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
683 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
684 pDevice
->bLinkPass
= false;
685 if (pDevice
->bEnableHostWEP
)
686 BSSvClearNodeDBTable(pDevice
, 1);
688 BSSvClearNodeDBTable(pDevice
, 0);
689 pDevice
->uAssocCount
= 0;
690 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
691 pDevice
->bFixRate
= false;
693 vMgrCreateOwnIBSS((void *)pDevice
, &Status
);
694 if (Status
!= CMD_STATUS_SUCCESS
)
695 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
" vMgrCreateOwnIBSS fail ! \n");
697 // alway turn off unicast bit
698 MACvRegBitsOff(pDevice
->PortOffset
, MAC_REG_RCR
, RCR_UNICAST
);
699 pDevice
->byRxMode
&= ~RCR_UNICAST
;
700 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"wcmd: rx_mode = %x\n", pDevice
->byRxMode
);
701 BSSvAddMulticastNode(pDevice
);
702 if (netif_queue_stopped(pDevice
->dev
))
703 netif_wake_queue(pDevice
->dev
);
705 pDevice
->bLinkPass
= true;
706 add_timer(&pMgmt
->sTimerSecondCallback
);
708 s_bCommandComplete(pDevice
);
711 case WLAN_CMD_TX_PSPACKET_START
:
713 if (pMgmt
->sNodeDBTable
[0].bRxPSPoll
) {
714 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[0].sTxPSQueue
)) != NULL
) {
715 if (skb_queue_empty(&pMgmt
->sNodeDBTable
[0].sTxPSQueue
)) {
716 pMgmt
->abyPSTxMap
[0] &= ~byMask
[0];
717 pDevice
->bMoreData
= false;
719 pDevice
->bMoreData
= true;
721 if (!device_dma0_xmit(pDevice
, skb
, 0))
722 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Multicast ps tx fail \n");
724 pMgmt
->sNodeDBTable
[0].wEnQueueCnt
--;
729 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
730 if (pMgmt
->sNodeDBTable
[ii
].bActive
&&
731 pMgmt
->sNodeDBTable
[ii
].bRxPSPoll
) {
732 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Index=%d Enqueu Cnt= %d\n",
733 ii
, pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
);
734 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
)) != NULL
) {
735 if (skb_queue_empty(&pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
)) {
737 pMgmt
->abyPSTxMap
[pMgmt
->sNodeDBTable
[ii
].wAID
>> 3] &=
738 ~byMask
[pMgmt
->sNodeDBTable
[ii
].wAID
& 7];
739 pDevice
->bMoreData
= false;
741 pDevice
->bMoreData
= true;
743 if (!device_dma0_xmit(pDevice
, skb
, ii
))
744 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"sta ps tx fail \n");
746 pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
--;
747 // check if sta ps enabled, and wait next pspoll.
748 // if sta ps disable, then send all pending buffers.
749 if (pMgmt
->sNodeDBTable
[ii
].bPSEnable
)
752 if (skb_queue_empty(&pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
)) {
754 pMgmt
->abyPSTxMap
[pMgmt
->sNodeDBTable
[ii
].wAID
>> 3] &=
755 ~byMask
[pMgmt
->sNodeDBTable
[ii
].wAID
& 7];
756 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Index=%d PS queue clear \n", ii
);
758 pMgmt
->sNodeDBTable
[ii
].bRxPSPoll
= false;
762 s_bCommandComplete(pDevice
);
765 case WLAN_CMD_RADIO_START
:
766 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCommandState == WLAN_CMD_RADIO_START\n");
767 if (pDevice
->bRadioCmd
)
768 CARDbRadioPowerOn(pDevice
);
770 CARDbRadioPowerOff(pDevice
);
772 s_bCommandComplete(pDevice
);
775 case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE
:
776 // wait all TD complete
777 if (pDevice
->iTDUsed
[TYPE_AC0DMA
] != 0) {
778 vCommandTimerWait((void *)pDevice
, 10);
779 spin_unlock_irq(&pDevice
->lock
);
782 if (pDevice
->iTDUsed
[TYPE_TXDMA0
] != 0) {
783 vCommandTimerWait((void *)pDevice
, 10);
784 spin_unlock_irq(&pDevice
->lock
);
787 pDevice
->byBBVGACurrent
= pDevice
->byBBVGANew
;
788 BBvSetVGAGainOffset(pDevice
, pDevice
->byBBVGACurrent
);
789 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"SetVGAGainOffset %02X\n", pDevice
->byBBVGACurrent
);
790 s_bCommandComplete(pDevice
);
794 s_bCommandComplete(pDevice
);
798 spin_unlock_irq(&pDevice
->lock
);
809 bool bRadioCmd
= false;
810 bool bForceSCAN
= true;
811 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
813 pDevice
->eCommandState
= WLAN_CMD_IDLE
;
814 if (pDevice
->cbFreeCmdQueue
== CMD_Q_SIZE
) {
815 //Command Queue Empty
816 pDevice
->bCmdRunning
= false;
819 pDevice
->eCommand
= pDevice
->eCmdQueue
[pDevice
->uCmdDequeueIdx
].eCmd
;
820 pSSID
= (PWLAN_IE_SSID
)pDevice
->eCmdQueue
[pDevice
->uCmdDequeueIdx
].abyCmdDesireSSID
;
821 bRadioCmd
= pDevice
->eCmdQueue
[pDevice
->uCmdDequeueIdx
].bRadioCmd
;
822 bForceSCAN
= pDevice
->eCmdQueue
[pDevice
->uCmdDequeueIdx
].bForceSCAN
;
823 ADD_ONE_WITH_WRAP_AROUND(pDevice
->uCmdDequeueIdx
, CMD_Q_SIZE
);
824 pDevice
->cbFreeCmdQueue
++;
825 pDevice
->bCmdRunning
= true;
826 switch (pDevice
->eCommand
) {
827 case WLAN_CMD_BSSID_SCAN
:
828 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCommandState= WLAN_CMD_BSSID_SCAN\n");
829 pDevice
->eCommandState
= WLAN_CMD_SCAN_START
;
830 pMgmt
->uScanChannel
= 0;
832 memcpy(pMgmt
->abyScanSSID
, pSSID
, WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
834 memset(pMgmt
->abyScanSSID
, 0, WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
838 pDevice
->eCommandState
= WLAN_CMD_SSID_START
;
839 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
840 pSSID
->len
= WLAN_SSID_MAXLEN
;
842 memcpy(pDevice
->pMgmt
->abyDesireSSID
, pSSID
, WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
843 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"eCommandState= WLAN_CMD_SSID_START\n");
845 case WLAN_CMD_DISASSOCIATE
:
846 pDevice
->eCommandState
= WLAN_CMD_DISASSOCIATE_START
;
848 case WLAN_CMD_RX_PSPOLL
:
849 pDevice
->eCommandState
= WLAN_CMD_TX_PSPACKET_START
;
851 case WLAN_CMD_RUN_AP
:
852 pDevice
->eCommandState
= WLAN_CMD_AP_MODE_START
;
855 pDevice
->eCommandState
= WLAN_CMD_RADIO_START
;
856 pDevice
->bRadioCmd
= bRadioCmd
;
858 case WLAN_CMD_CHANGE_BBSENSITIVITY
:
859 pDevice
->eCommandState
= WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE
;
867 vCommandTimerWait((void *)pDevice
, 0);
873 bool bScheduleCommand(
874 void *hDeviceContext
,
876 unsigned char *pbyItem0
879 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
881 if (pDevice
->cbFreeCmdQueue
== 0)
884 pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].eCmd
= eCommand
;
885 pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].bForceSCAN
= true;
886 memset(pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].abyCmdDesireSSID
, 0 , WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
888 if (pbyItem0
!= NULL
) {
890 case WLAN_CMD_BSSID_SCAN
:
891 memcpy(pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].abyCmdDesireSSID
,
892 pbyItem0
, WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
893 pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].bForceSCAN
= false;
897 memcpy(pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].abyCmdDesireSSID
,
898 pbyItem0
, WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
901 case WLAN_CMD_DISASSOCIATE
:
902 pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].bNeedRadioOFF
= *((int *)pbyItem0
);
905 case WLAN_CMD_RX_PSPOLL
:
909 pDevice
->eCmdQueue
[pDevice
->uCmdEnqueueIdx
].bRadioCmd
= *((int *)pbyItem0
);
912 case WLAN_CMD_CHANGE_BBSENSITIVITY
:
913 pDevice
->eCommandState
= WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE
;
921 ADD_ONE_WITH_WRAP_AROUND(pDevice
->uCmdEnqueueIdx
, CMD_Q_SIZE
);
922 pDevice
->cbFreeCmdQueue
--;
924 if (!pDevice
->bCmdRunning
)
925 s_bCommandComplete(pDevice
);
932 * Clear BSSID_SCAN cmd in CMD Queue
936 * hDeviceContext - Pointer to the adapter
941 * Return Value: true if success; otherwise false
944 bool bClearBSSID_SCAN(
948 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
949 unsigned int uCmdDequeueIdx
= pDevice
->uCmdDequeueIdx
;
952 if ((pDevice
->cbFreeCmdQueue
< CMD_Q_SIZE
) && (uCmdDequeueIdx
!= pDevice
->uCmdEnqueueIdx
)) {
953 for (ii
= 0; ii
< (CMD_Q_SIZE
- pDevice
->cbFreeCmdQueue
); ii
++) {
954 if (pDevice
->eCmdQueue
[uCmdDequeueIdx
].eCmd
== WLAN_CMD_BSSID_SCAN
)
955 pDevice
->eCmdQueue
[uCmdDequeueIdx
].eCmd
= WLAN_CMD_IDLE
;
956 ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx
, CMD_Q_SIZE
);
957 if (uCmdDequeueIdx
== pDevice
->uCmdEnqueueIdx
)
964 //mike add:reset command timer
970 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
973 del_timer(&pDevice
->sTimerCommand
);
975 init_timer(&pDevice
->sTimerCommand
);
976 pDevice
->sTimerCommand
.data
= (unsigned long) pDevice
;
977 pDevice
->sTimerCommand
.function
= (TimerFunction
)vCommandTimer
;
978 pDevice
->sTimerCommand
.expires
= RUN_AT(HZ
);
979 pDevice
->cbFreeCmdQueue
= CMD_Q_SIZE
;
980 pDevice
->uCmdDequeueIdx
= 0;
981 pDevice
->uCmdEnqueueIdx
= 0;
982 pDevice
->eCommandState
= WLAN_CMD_IDLE
;
983 pDevice
->bCmdRunning
= false;
984 pDevice
->bCmdClear
= false;
993 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
994 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
995 pDevice
->nTxDataTimeCout
++;
997 if (pDevice
->nTxDataTimeCout
< 4) //don't tx data if timer less than 40s
999 pDevice
->sTimerTxData
.expires
= RUN_AT(10*HZ
); //10s callback
1000 add_timer(&pDevice
->sTimerTxData
);
1004 spin_lock_irq(&pDevice
->lock
);
1006 if ((pDevice
->bLinkPass
&& (pMgmt
->eAuthenMode
< WMAC_AUTH_WPA
)) || //open && sharekey linking
1007 pDevice
->fWPA_Authened
) { //wpa linking
1009 if (pDevice
->bLinkPass
== true) {
1011 pDevice
->fTxDataInSleep
= true;
1012 PSbSendNullPacket(pDevice
); //send null packet
1013 pDevice
->fTxDataInSleep
= false;
1015 spin_unlock_irq(&pDevice
->lock
);
1017 pDevice
->sTimerTxData
.expires
= RUN_AT(10*HZ
); //10s callback
1018 add_timer(&pDevice
->sTimerTxData
);