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