wcmd.c revision 5e0cc8a231be82b0ec44cdf2a406b1a97dd3c971
1/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
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.
9 *
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.
14 *
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.
18 *
19 * File: wcmd.c
20 *
21 * Purpose: Handles the management command interface functions
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: May 8, 2003
26 *
27 * 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
36 *
37 * Revision History:
38 *
39 */
40
41#include "ttype.h"
42#include "tmacro.h"
43#include "device.h"
44#include "mac.h"
45#include "card.h"
46#include "80211hdr.h"
47#include "wcmd.h"
48#include "wmgr.h"
49#include "power.h"
50#include "wctl.h"
51#include "baseband.h"
52#include "rxtx.h"
53#include "rf.h"
54#include "iowpa.h"
55#include "channel.h"
56
57/*---------------------  Static Definitions -------------------------*/
58
59
60
61
62/*---------------------  Static Classes  ----------------------------*/
63
64/*---------------------  Static Variables  --------------------------*/
65static int msglevel = MSG_LEVEL_INFO;
66//static int          msglevel                =MSG_LEVEL_DEBUG;
67/*---------------------  Static Functions  --------------------------*/
68
69static
70void
71s_vProbeChannel(
72	PSDevice pDevice
73);
74
75
76static
77PSTxMgmtPacket
78s_MgrMakeProbeRequest(
79	PSDevice pDevice,
80	PSMgmtObject pMgmt,
81	unsigned char *pScanBSSID,
82	PWLAN_IE_SSID pSSID,
83	PWLAN_IE_SUPP_RATES pCurrRates,
84	PWLAN_IE_SUPP_RATES pCurrExtSuppRates
85);
86
87
88static
89bool
90s_bCommandComplete(
91	PSDevice pDevice
92);
93
94/*---------------------  Export Variables  --------------------------*/
95
96
97/*---------------------  Export Functions  --------------------------*/
98
99
100
101/*
102 * Description:
103 *      Stop AdHoc beacon during scan process
104 *
105 * Parameters:
106 *  In:
107 *      pDevice     - Pointer to the adapter
108 *  Out:
109 *      none
110 *
111 * Return Value: none
112 *
113 */
114static
115void
116vAdHocBeaconStop(PSDevice  pDevice)
117{
118
119	PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
120	bool bStop;
121
122	/*
123	 * temporarily stop Beacon packet for AdHoc Server
124	 * if all of the following conditions are met:
125	 *  (1) STA is in AdHoc mode
126	 *  (2) VT3253 is programmed as automatic Beacon Transmitting
127	 *  (3) One of the following conditions is met
128	 *      (3.1) AdHoc channel is in B/G band and the
129	 *      current scan channel is in A band
130	 *      or
131	 *      (3.2) AdHoc channel is in A mode
132	 */
133	bStop = false;
134	if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
135	    (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
136		if ((pMgmt->uIBSSChannel <=  CB_MAX_CHANNEL_24G) &&
137		    (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
138			bStop = true;
139		}
140		if (pMgmt->uIBSSChannel >  CB_MAX_CHANNEL_24G) {
141			bStop = true;
142		}
143	}
144
145	if (bStop) {
146		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
147	}
148
149} /* vAdHocBeaconStop */
150
151
152/*
153 * Description:
154 *      Restart AdHoc beacon after scan process complete
155 *
156 * Parameters:
157 *  In:
158 *      pDevice     - Pointer to the adapter
159 *  Out:
160 *      none
161 *
162 * Return Value: none
163 *
164 */
165static
166void
167vAdHocBeaconRestart(PSDevice pDevice)
168{
169	PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
170
171	/*
172	 * Restart Beacon packet for AdHoc Server
173	 * if all of the following coditions are met:
174	 *  (1) STA is in AdHoc mode
175	 *  (2) VT3253 is programmed as automatic Beacon Transmitting
176	 */
177	if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
178	    (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
179		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
180	}
181
182}
183
184
185
186
187
188
189/*+
190 *
191 * Routine Description:
192 *   Prepare and send probe request management frames.
193 *
194 *
195 * Return Value:
196 *    none.
197 *
198 -*/
199
200static
201void
202s_vProbeChannel(
203	PSDevice pDevice
204)
205{
206	//1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
207	unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
208	unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
209	//6M,   9M,   12M,  48M
210	unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
211	unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
212	unsigned char *pbyRate;
213	PSTxMgmtPacket  pTxPacket;
214	PSMgmtObject    pMgmt = pDevice->pMgmt;
215	unsigned int ii;
216
217
218	if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
219		pbyRate = &abyCurrSuppRatesA[0];
220	} else if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
221		pbyRate = &abyCurrSuppRatesB[0];
222	} else {
223		pbyRate = &abyCurrSuppRatesG[0];
224	}
225	// build an assocreq frame and send it
226	pTxPacket = s_MgrMakeProbeRequest
227		(
228			pDevice,
229			pMgmt,
230			pMgmt->abyScanBSSID,
231			(PWLAN_IE_SSID)pMgmt->abyScanSSID,
232			(PWLAN_IE_SUPP_RATES)pbyRate,
233			(PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG
234			);
235
236	if (pTxPacket != NULL) {
237		for (ii = 0; ii < 2; ii++) {
238			if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
239				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
240			} else {
241				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n");
242			}
243		}
244	}
245
246}
247
248
249
250
251/*+
252 *
253 * Routine Description:
254 *  Constructs an probe request frame
255 *
256 *
257 * Return Value:
258 *    A ptr to Tx frame or NULL on allocation failue
259 *
260 -*/
261
262
263PSTxMgmtPacket
264s_MgrMakeProbeRequest(
265	PSDevice pDevice,
266	PSMgmtObject pMgmt,
267	unsigned char *pScanBSSID,
268	PWLAN_IE_SSID pSSID,
269	PWLAN_IE_SUPP_RATES pCurrRates,
270	PWLAN_IE_SUPP_RATES pCurrExtSuppRates
271
272)
273{
274	PSTxMgmtPacket      pTxPacket = NULL;
275	WLAN_FR_PROBEREQ    sFrame;
276
277
278	pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
279	memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN);
280	pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
281	sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
282	sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
283	vMgrEncodeProbeRequest(&sFrame);
284	sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
285		(
286			WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
287			WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ)
288));
289	memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN);
290	memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
291	memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN);
292	// Copy the SSID, pSSID->len=0 indicate broadcast SSID
293	sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
294	sFrame.len += pSSID->len + WLAN_IEHDR_LEN;
295	memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
296	sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
297	sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
298	memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
299	// Copy the extension rate set
300	if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
301		sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
302		sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
303		memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
304	}
305	pTxPacket->cbMPDULen = sFrame.len;
306	pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
307
308	return pTxPacket;
309}
310
311
312
313
314
315void
316vCommandTimerWait(
317	void *hDeviceContext,
318	unsigned int MSecond
319)
320{
321	PSDevice        pDevice = (PSDevice)hDeviceContext;
322
323	init_timer(&pDevice->sTimerCommand);
324	pDevice->sTimerCommand.data = (unsigned long) pDevice;
325	pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
326	// RUN_AT :1 msec ~= (HZ/1024)
327	pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10);
328	add_timer(&pDevice->sTimerCommand);
329	return;
330}
331
332
333
334
335void
336vCommandTimer(
337	void *hDeviceContext
338)
339{
340	PSDevice        pDevice = (PSDevice)hDeviceContext;
341	PSMgmtObject    pMgmt = pDevice->pMgmt;
342	PWLAN_IE_SSID   pItemSSID;
343	PWLAN_IE_SSID   pItemSSIDCurr;
344	CMD_STATUS      Status;
345	unsigned int ii;
346	unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
347	struct sk_buff  *skb;
348
349
350	if (pDevice->dwDiagRefCount != 0)
351		return;
352	if (pDevice->bCmdRunning != true)
353		return;
354
355	spin_lock_irq(&pDevice->lock);
356
357	switch (pDevice->eCommandState) {
358
359	case WLAN_CMD_SCAN_START:
360
361		pDevice->byReAssocCount = 0;
362		if (pDevice->bRadioOff == true) {
363			s_bCommandComplete(pDevice);
364			spin_unlock_irq(&pDevice->lock);
365			return;
366		}
367
368		if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
369			s_bCommandComplete(pDevice);
370			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP);
371			spin_unlock_irq(&pDevice->lock);
372			return;
373		}
374
375		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SCAN_START\n");
376		pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
377		// wait all Data TD complete
378		if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) {
379			spin_unlock_irq(&pDevice->lock);
380			vCommandTimerWait((void *)pDevice, 10);
381			return;
382		}
383
384		if (pMgmt->uScanChannel == 0) {
385			pMgmt->uScanChannel = pDevice->byMinChannel;
386			// Set Baseband to be more sensitive.
387
388		}
389		if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
390			pMgmt->eScanState = WMAC_NO_SCANNING;
391
392			// Set Baseband's sensitivity back.
393			// Set channel back
394			set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel);
395			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
396			if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
397				CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
398			} else {
399				CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE);
400			}
401			vAdHocBeaconRestart(pDevice);
402			s_bCommandComplete(pDevice);
403
404		} else {
405//2008-8-4 <add> by chester
406			if (!is_channel_valid(pMgmt->uScanChannel)) {
407				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n", pMgmt->uScanChannel);
408				s_bCommandComplete(pDevice);
409				spin_unlock_irq(&pDevice->lock);
410				return;
411			}
412			if (pMgmt->uScanChannel == pDevice->byMinChannel) {
413				//pMgmt->eScanType = WMAC_SCAN_ACTIVE;
414				pMgmt->abyScanBSSID[0] = 0xFF;
415				pMgmt->abyScanBSSID[1] = 0xFF;
416				pMgmt->abyScanBSSID[2] = 0xFF;
417				pMgmt->abyScanBSSID[3] = 0xFF;
418				pMgmt->abyScanBSSID[4] = 0xFF;
419				pMgmt->abyScanBSSID[5] = 0xFF;
420				pItemSSID->byElementID = WLAN_EID_SSID;
421				// clear bssid list
422				// BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
423				pMgmt->eScanState = WMAC_IS_SCANNING;
424
425			}
426
427			vAdHocBeaconStop(pDevice);
428
429			if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel) == true) {
430				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SCAN Channel: %d\n", pMgmt->uScanChannel);
431			} else {
432				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel);
433			}
434			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_UNKNOWN);
435			pMgmt->uScanChannel++;
436//2008-8-4 <modify> by chester
437			if (!is_channel_valid(pMgmt->uScanChannel) &&
438			    pMgmt->uScanChannel <= pDevice->byMaxChannel) {
439				pMgmt->uScanChannel = pDevice->byMaxChannel + 1;
440				pMgmt->eCommandState = WLAN_CMD_SCAN_END;
441
442			}
443
444
445			if ((pMgmt->b11hEnable == false) ||
446			    (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
447				s_vProbeChannel(pDevice);
448				spin_unlock_irq(&pDevice->lock);
449				vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME);
450				return;
451			} else {
452				spin_unlock_irq(&pDevice->lock);
453				vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME);
454				return;
455			}
456
457		}
458
459		break;
460
461	case WLAN_CMD_SCAN_END:
462
463		// Set Baseband's sensitivity back.
464		// Set channel back
465		set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel);
466		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
467		if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
468			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
469		} else {
470			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE);
471		}
472
473		pMgmt->eScanState = WMAC_NO_SCANNING;
474		vAdHocBeaconRestart(pDevice);
475//2008-0409-07, <Add> by Einsn Liu
476#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
477		if (pMgmt->eScanType == WMAC_SCAN_PASSIVE)
478		{//send scan event to wpa_Supplicant
479			union iwreq_data wrqu;
480			memset(&wrqu, 0, sizeof(wrqu));
481			wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
482		}
483#endif
484		s_bCommandComplete(pDevice);
485		break;
486
487	case WLAN_CMD_DISASSOCIATE_START:
488		pDevice->byReAssocCount = 0;
489		if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
490		    (pMgmt->eCurrState != WMAC_STATE_ASSOC)) {
491			s_bCommandComplete(pDevice);
492			spin_unlock_irq(&pDevice->lock);
493			return;
494		} else {
495			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Disassociation Packet..\n");
496			// reason = 8 : disassoc because sta has left
497			vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status);
498			pDevice->bLinkPass = false;
499			// unlock command busy
500			pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
501			pItemSSID->len = 0;
502			memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
503			pMgmt->eCurrState = WMAC_STATE_IDLE;
504			pMgmt->sNodeDBTable[0].bActive = false;
505//                pDevice->bBeaconBufReady = false;
506		}
507		netif_stop_queue(pDevice->dev);
508		pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT;
509		// wait all Control TD complete
510		if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) {
511			vCommandTimerWait((void *)pDevice, 10);
512			spin_unlock_irq(&pDevice->lock);
513			return;
514		}
515		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " CARDbRadioPowerOff\n");
516		//2008-09-02  <mark>	by chester
517		// CARDbRadioPowerOff(pDevice);
518		s_bCommandComplete(pDevice);
519		break;
520
521	case WLAN_DISASSOCIATE_WAIT:
522		// wait all Control TD complete
523		if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) {
524			vCommandTimerWait((void *)pDevice, 10);
525			spin_unlock_irq(&pDevice->lock);
526			return;
527		}
528//2008-09-02  <mark> by chester
529		// CARDbRadioPowerOff(pDevice);
530		s_bCommandComplete(pDevice);
531		break;
532
533	case WLAN_CMD_SSID_START:
534		pDevice->byReAssocCount = 0;
535		if (pDevice->bRadioOff == true) {
536			s_bCommandComplete(pDevice);
537			spin_unlock_irq(&pDevice->lock);
538			return;
539		}
540		printk("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID);
541		//memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID,
542		//((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
543		pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
544		pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
545		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: desire ssid = %s\n", pItemSSID->abySSID);
546		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
547
548		if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
549			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
550			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSID->len =%d\n", pItemSSID->len);
551			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSIDCurr->len = %d\n", pItemSSIDCurr->len);
552			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " desire ssid = %s\n", pItemSSID->abySSID);
553			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " curr ssid = %s\n", pItemSSIDCurr->abySSID);
554		}
555
556		if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
557		    ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
558
559			if (pItemSSID->len == pItemSSIDCurr->len) {
560				if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) {
561					s_bCommandComplete(pDevice);
562					spin_unlock_irq(&pDevice->lock);
563					return;
564				}
565			}
566
567			netif_stop_queue(pDevice->dev);
568			pDevice->bLinkPass = false;
569		}
570		// set initial state
571		pMgmt->eCurrState = WMAC_STATE_IDLE;
572		pMgmt->eCurrMode = WMAC_MODE_STANDBY;
573		PSvDisablePowerSaving((void *)pDevice);
574		BSSvClearNodeDBTable(pDevice, 0);
575
576		vMgrJoinBSSBegin((void *)pDevice, &Status);
577		// if Infra mode
578		if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
579
580			// Call mgr to begin the deauthentication
581			// reason = (3) because sta has left ESS
582			if (pMgmt->eCurrState >= WMAC_STATE_AUTH) {
583				vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status);
584			}
585			// Call mgr to begin the authentication
586			vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status);
587			if (Status == CMD_STATUS_SUCCESS) {
588				pDevice->byLinkWaitCount = 0;
589				pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
590				vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT);
591				spin_unlock_irq(&pDevice->lock);
592				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
593				return;
594			}
595		}
596		// if Adhoc mode
597		else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
598			if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
599				if (netif_queue_stopped(pDevice->dev)) {
600					netif_wake_queue(pDevice->dev);
601				}
602				pDevice->bLinkPass = true;
603
604				pMgmt->sNodeDBTable[0].bActive = true;
605				pMgmt->sNodeDBTable[0].uInActiveCount = 0;
606				bClearBSSID_SCAN(pDevice);
607			} else {
608				// start own IBSS
609				vMgrCreateOwnIBSS((void *)pDevice, &Status);
610				if (Status != CMD_STATUS_SUCCESS) {
611					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
612				}
613				BSSvAddMulticastNode(pDevice);
614			}
615		}
616		// if SSID not found
617		else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) {
618			if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA ||
619			    pMgmt->eConfigMode == WMAC_CONFIG_AUTO) {
620				// start own IBSS
621				vMgrCreateOwnIBSS((void *)pDevice, &Status);
622				if (Status != CMD_STATUS_SUCCESS) {
623					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
624				}
625				BSSvAddMulticastNode(pDevice);
626				if (netif_queue_stopped(pDevice->dev)) {
627					netif_wake_queue(pDevice->dev);
628				}
629				pDevice->bLinkPass = true;
630			} else {
631				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
632#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
633				// if (pDevice->bWPASuppWextEnabled == true)
634				{
635					union iwreq_data  wrqu;
636					memset(&wrqu, 0, sizeof(wrqu));
637					wrqu.ap_addr.sa_family = ARPHRD_ETHER;
638					printk("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
639					wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
640				}
641#endif
642
643			}
644		}
645		s_bCommandComplete(pDevice);
646		break;
647
648	case WLAN_AUTHENTICATE_WAIT:
649		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_AUTHENTICATE_WAIT\n");
650		if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
651			// Call mgr to begin the association
652			pDevice->byLinkWaitCount = 0;
653			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_AUTH\n");
654			vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status);
655			if (Status == CMD_STATUS_SUCCESS) {
656				pDevice->byLinkWaitCount = 0;
657				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState = WLAN_ASSOCIATE_WAIT\n");
658				pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
659				vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT);
660				spin_unlock_irq(&pDevice->lock);
661				return;
662			}
663		}
664
665		else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
666			printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
667		} else if (pDevice->byLinkWaitCount <= 4) {    //mike add:wait another 2 sec if authenticated_frame delay!
668			pDevice->byLinkWaitCount++;
669			printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
670			spin_unlock_irq(&pDevice->lock);
671			vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2);
672			return;
673		}
674		pDevice->byLinkWaitCount = 0;
675		s_bCommandComplete(pDevice);
676		break;
677
678	case WLAN_ASSOCIATE_WAIT:
679		if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
680			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_ASSOC\n");
681			if (pDevice->ePSMode != WMAC_POWER_CAM) {
682				PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
683			}
684			if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
685				KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset);
686			}
687			pDevice->bLinkPass = true;
688			pDevice->byLinkWaitCount = 0;
689			pDevice->byReAssocCount = 0;
690			bClearBSSID_SCAN(pDevice);
691			if (pDevice->byFOETuning) {
692				BBvSetFOE(pDevice->PortOffset);
693				PSbSendNullPacket(pDevice);
694			}
695			if (netif_queue_stopped(pDevice->dev)) {
696				netif_wake_queue(pDevice->dev);
697			}
698#ifdef TxInSleep
699			if (pDevice->IsTxDataTrigger != false)   {    //TxDataTimer is not triggered at the first time
700				del_timer(&pDevice->sTimerTxData);
701				init_timer(&pDevice->sTimerTxData);
702				pDevice->sTimerTxData.data = (unsigned long) pDevice;
703				pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
704				pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
705				pDevice->fTxDataInSleep = false;
706				pDevice->nTxDataTimeCout = 0;
707			} else {
708			}
709			pDevice->IsTxDataTrigger = true;
710			add_timer(&pDevice->sTimerTxData);
711#endif
712		} else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
713			printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
714		} else if (pDevice->byLinkWaitCount <= 4) {    //mike add:wait another 2 sec if associated_frame delay!
715			pDevice->byLinkWaitCount++;
716			printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
717			spin_unlock_irq(&pDevice->lock);
718			vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2);
719			return;
720		}
721		pDevice->byLinkWaitCount = 0;
722
723		s_bCommandComplete(pDevice);
724		break;
725
726	case WLAN_CMD_AP_MODE_START:
727		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_AP_MODE_START\n");
728
729		if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
730			del_timer(&pMgmt->sTimerSecondCallback);
731			pMgmt->eCurrState = WMAC_STATE_IDLE;
732			pMgmt->eCurrMode = WMAC_MODE_STANDBY;
733			pDevice->bLinkPass = false;
734			if (pDevice->bEnableHostWEP == true)
735				BSSvClearNodeDBTable(pDevice, 1);
736			else
737				BSSvClearNodeDBTable(pDevice, 0);
738			pDevice->uAssocCount = 0;
739			pMgmt->eCurrState = WMAC_STATE_IDLE;
740			pDevice->bFixRate = false;
741
742			vMgrCreateOwnIBSS((void *)pDevice, &Status);
743			if (Status != CMD_STATUS_SUCCESS) {
744				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n");
745			}
746			// alway turn off unicast bit
747			MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST);
748			pDevice->byRxMode &= ~RCR_UNICAST;
749			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode);
750			BSSvAddMulticastNode(pDevice);
751			if (netif_queue_stopped(pDevice->dev)) {
752				netif_wake_queue(pDevice->dev);
753			}
754			pDevice->bLinkPass = true;
755			add_timer(&pMgmt->sTimerSecondCallback);
756		}
757		s_bCommandComplete(pDevice);
758		break;
759
760	case WLAN_CMD_TX_PSPACKET_START:
761		// DTIM Multicast tx
762		if (pMgmt->sNodeDBTable[0].bRxPSPoll) {
763			while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
764				if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
765					pMgmt->abyPSTxMap[0] &= ~byMask[0];
766					pDevice->bMoreData = false;
767				} else {
768					pDevice->bMoreData = true;
769				}
770				if (!device_dma0_xmit(pDevice, skb, 0)) {
771					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
772				}
773				pMgmt->sNodeDBTable[0].wEnQueueCnt--;
774			}
775		}
776
777		// PS nodes tx
778		for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
779			if (pMgmt->sNodeDBTable[ii].bActive &&
780			    pMgmt->sNodeDBTable[ii].bRxPSPoll) {
781				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
782					ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
783				while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
784					if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
785						// clear tx map
786						pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
787							~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
788						pDevice->bMoreData = false;
789					} else {
790						pDevice->bMoreData = true;
791					}
792					if (!device_dma0_xmit(pDevice, skb, ii)) {
793						DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
794					}
795					pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
796					// check if sta ps enabled, and wait next pspoll.
797					// if sta ps disable, then send all pending buffers.
798					if (pMgmt->sNodeDBTable[ii].bPSEnable)
799						break;
800				}
801				if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
802					// clear tx map
803					pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
804						~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
805					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
806				}
807				pMgmt->sNodeDBTable[ii].bRxPSPoll = false;
808			}
809		}
810
811		s_bCommandComplete(pDevice);
812		break;
813
814
815	case WLAN_CMD_RADIO_START:
816		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_RADIO_START\n");
817		if (pDevice->bRadioCmd == true)
818			CARDbRadioPowerOn(pDevice);
819		else
820			CARDbRadioPowerOff(pDevice);
821
822		s_bCommandComplete(pDevice);
823		break;
824
825
826	case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE:
827		//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_CHECK_BBSENSITIVITY_START\n");
828		// wait all TD complete
829		if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) {
830			vCommandTimerWait((void *)pDevice, 10);
831			spin_unlock_irq(&pDevice->lock);
832			return;
833		}
834		if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) {
835			vCommandTimerWait((void *)pDevice, 10);
836			spin_unlock_irq(&pDevice->lock);
837			return;
838		}
839		pDevice->byBBVGACurrent = pDevice->byBBVGANew;
840		BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
841		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent);
842		s_bCommandComplete(pDevice);
843		break;
844
845	default:
846		s_bCommandComplete(pDevice);
847		break;
848
849	} //switch
850	spin_unlock_irq(&pDevice->lock);
851	return;
852
853}
854
855
856static
857bool
858s_bCommandComplete(
859	PSDevice pDevice
860)
861{
862	PWLAN_IE_SSID pSSID;
863	bool bRadioCmd = false;
864	//unsigned short wDeAuthenReason = 0;
865	bool bForceSCAN = true;
866	PSMgmtObject  pMgmt = pDevice->pMgmt;
867
868
869	pDevice->eCommandState = WLAN_CMD_IDLE;
870	if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
871		//Command Queue Empty
872		pDevice->bCmdRunning = false;
873		return true;
874	} else {
875		pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
876		pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID;
877		bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd;
878		bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
879		ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
880		pDevice->cbFreeCmdQueue++;
881		pDevice->bCmdRunning = true;
882		switch (pDevice->eCommand) {
883		case WLAN_CMD_BSSID_SCAN:
884			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_BSSID_SCAN\n");
885			pDevice->eCommandState = WLAN_CMD_SCAN_START;
886			pMgmt->uScanChannel = 0;
887			if (pSSID->len != 0) {
888				memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
889			} else {
890				memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
891			}
892/*
893  if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) {
894  if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
895  (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
896  pDevice->eCommandState = WLAN_CMD_IDLE;
897  }
898  }
899*/
900			break;
901		case WLAN_CMD_SSID:
902			pDevice->eCommandState = WLAN_CMD_SSID_START;
903			if (pSSID->len > WLAN_SSID_MAXLEN)
904				pSSID->len = WLAN_SSID_MAXLEN;
905			if (pSSID->len != 0)
906				memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
907			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SSID_START\n");
908			break;
909		case WLAN_CMD_DISASSOCIATE:
910			pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
911			break;
912		case WLAN_CMD_RX_PSPOLL:
913			pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START;
914			break;
915		case WLAN_CMD_RUN_AP:
916			pDevice->eCommandState = WLAN_CMD_AP_MODE_START;
917			break;
918		case WLAN_CMD_RADIO:
919			pDevice->eCommandState = WLAN_CMD_RADIO_START;
920			pDevice->bRadioCmd = bRadioCmd;
921			break;
922		case WLAN_CMD_CHANGE_BBSENSITIVITY:
923			pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE;
924			break;
925
926		default:
927			break;
928
929		}
930
931		vCommandTimerWait((void *)pDevice, 0);
932	}
933
934	return true;
935}
936
937
938
939bool bScheduleCommand(
940	void *hDeviceContext,
941	CMD_CODE    eCommand,
942	unsigned char *pbyItem0
943)
944{
945	PSDevice        pDevice = (PSDevice)hDeviceContext;
946
947
948	if (pDevice->cbFreeCmdQueue == 0) {
949		return (false);
950	}
951	pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
952	pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true;
953	memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
954
955	if (pbyItem0 != NULL) {
956		switch (eCommand) {
957
958		case WLAN_CMD_BSSID_SCAN:
959			memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
960			       pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
961			pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false;
962			break;
963
964		case WLAN_CMD_SSID:
965			memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
966			       pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
967			break;
968
969		case WLAN_CMD_DISASSOCIATE:
970			pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
971			break;
972/*
973  case WLAN_CMD_DEAUTH:
974  pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((unsigned short *)pbyItem0);
975  break;
976*/
977
978		case WLAN_CMD_RX_PSPOLL:
979			break;
980
981		case WLAN_CMD_RADIO:
982			pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
983			break;
984
985		case WLAN_CMD_CHANGE_BBSENSITIVITY:
986			pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE;
987			break;
988
989		default:
990			break;
991		}
992	}
993
994	ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
995	pDevice->cbFreeCmdQueue--;
996
997	if (pDevice->bCmdRunning == false) {
998		s_bCommandComplete(pDevice);
999	} else {
1000	}
1001	return (true);
1002
1003}
1004
1005/*
1006 * Description:
1007 *      Clear BSSID_SCAN cmd in CMD Queue
1008 *
1009 * Parameters:
1010 *  In:
1011 *      hDeviceContext  - Pointer to the adapter
1012 *      eCommand        - Command
1013 *  Out:
1014 *      none
1015 *
1016 * Return Value: true if success; otherwise false
1017 *
1018 */
1019bool bClearBSSID_SCAN(
1020	void *hDeviceContext
1021)
1022{
1023	PSDevice        pDevice = (PSDevice)hDeviceContext;
1024	unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
1025	unsigned int ii;
1026
1027	if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
1028		for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) {
1029			if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN)
1030				pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE;
1031			ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE);
1032			if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx)
1033				break;
1034		}
1035	}
1036	return true;
1037}
1038
1039//mike add:reset command timer
1040void
1041vResetCommandTimer(
1042	void *hDeviceContext
1043)
1044{
1045	PSDevice        pDevice = (PSDevice)hDeviceContext;
1046
1047	//delete timer
1048	del_timer(&pDevice->sTimerCommand);
1049	//init timer
1050	init_timer(&pDevice->sTimerCommand);
1051	pDevice->sTimerCommand.data = (unsigned long) pDevice;
1052	pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
1053	pDevice->sTimerCommand.expires = RUN_AT(HZ);
1054	pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
1055	pDevice->uCmdDequeueIdx = 0;
1056	pDevice->uCmdEnqueueIdx = 0;
1057	pDevice->eCommandState = WLAN_CMD_IDLE;
1058	pDevice->bCmdRunning = false;
1059	pDevice->bCmdClear = false;
1060}
1061
1062
1063#ifdef TxInSleep
1064void
1065BSSvSecondTxData(
1066	void *hDeviceContext
1067)
1068{
1069	PSDevice        pDevice = (PSDevice)hDeviceContext;
1070	PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
1071	pDevice->nTxDataTimeCout++;
1072
1073	if (pDevice->nTxDataTimeCout < 4)     //don't tx data if timer less than 40s
1074	{
1075		pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
1076		add_timer(&pDevice->sTimerTxData);
1077		return;
1078	}
1079
1080	spin_lock_irq(&pDevice->lock);
1081#if 1
1082	if (((pDevice->bLinkPass == true) && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
1083	   (pDevice->fWPA_Authened == true)) {   //wpa linking
1084#else
1085		if (pDevice->bLinkPass == true) {
1086#endif
1087			pDevice->fTxDataInSleep = true;
1088			PSbSendNullPacket(pDevice);      //send null packet
1089			pDevice->fTxDataInSleep = false;
1090		}
1091		spin_unlock_irq(&pDevice->lock);
1092
1093		pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
1094		add_timer(&pDevice->sTimerTxData);
1095		return;
1096	}
1097#endif
1098
1099