static void zfScanMgrEventScanCompleteCb(zdev_t* dev)
{
    if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
    {
        zfSendNullData(dev, 0);
    }
    return;
}
static void zfScanSendProbeRequest(zdev_t* dev)
{
    u8_t k;
    u16_t  dst[3] = { 0xffff, 0xffff, 0xffff };

    zmw_get_wlan_dev(dev);

    /* Increase rxBeaconCount to prevent beacon lost */
    if (zfStaIsConnected(dev))
    {
        wd->sta.rxBeaconCount++;
    }

    if ( wd->sta.bPassiveScan )
    {
        return;
    }
    /* enable 802.l11h and in DFS Band , disable sending probe request */
    if (wd->sta.DFSEnable)
    {
        if (zfHpIsDfsChannel(dev, wd->sta.scanFrequency))
        {
            return;
        }
    }

    zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, 0, 0, 0);

    if ( wd->sta.disableProbingWithSsid )
    {
        return;
    }

    for (k=1; k<=ZM_MAX_PROBE_HIDDEN_SSID_SIZE; k++)
    {
        if ( wd->ws.probingSsidList[k-1].ssidLen != 0 )
        {
            zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, k, 0, 0);
        }
    }
}
Exemple #3
0
/*     convert MIMO2 to OUTS             */
void zfAdjustCtrlSetting(zdev_t* dev, u16_t* header, zbuf_t* buf)
{
    /* MIMO2 => OUTS FB-50 */
    /* length not change, only modify format */

    u32_t oldMT;
	u32_t oldMCS;

    u32_t phyCtrl;
    u32_t oldPhyCtrl;
    
    u16_t tpc = 0;

    zmw_get_wlan_dev(dev);
    struct zsHpPriv* hpPriv = (struct zsHpPriv*)wd->hpPrivate;

   /* mm */
    if (header == NULL)
    {
        oldPhyCtrl = zmw_buf_readh(dev, buf, 4) | ((u32_t)zmw_buf_readh(dev, buf, 6) << 16);
    }
    else
    {
        oldPhyCtrl = header[2] | ((u32_t)header[3] <<16);
    }

	phyCtrl = 0;
    

	/* MT : Bit[1~0] */
	oldMT = oldPhyCtrl&0x3;
	phyCtrl |= oldMT;
    if ( oldMT == 0x3 )   /* DL-OFDM (Duplicate Legacy OFDM) */
		phyCtrl |= 0x1;		


	/* PT : Bit[2]    HT PT: 0 Mixed mode    1 Green field */
	phyCtrl |= (oldPhyCtrl&0x4);

	/* Bandwidth control : Bit[4~3] */
	if ( oldPhyCtrl&0x800000 )    /* Bit23 : 40M */
	{
		#if 0
		if (oldMT == 0x3)             /* DL-OFDM */
            phyCtrl |= (0x3<<3);   /* 40M duplicate */   
		else
			phyCtrl |= (0x2<<3);   /* 40M shared */
		#else
		if (oldMT == 0x2 && ((struct zsHpPriv*)wd->hpPrivate)->hwBw40)
		{
			phyCtrl |= (0x2<<3);   /* 40M shared */
		}
		#endif
	}
	else {
        oldPhyCtrl &= ~0x80000000;
    }

	/* MCS : Bit[24~18] */
	oldMCS = (oldPhyCtrl&0x7f0000)>>16;  /* Bit[22~16] */
	phyCtrl |= (oldMCS<<18);

	/* Short GI : Bit[31]*/
    phyCtrl |= (oldPhyCtrl&0x80000000);

	/* AM : Antenna mask */
	//if ((oldMT == 2) && (oldMCS > 7))
	if (hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM)
	{
	    phyCtrl |= (0x1<<15);
	}
	else
	{
	    /* HT                     Tx 2 chain */
	    /* OFDM 6M/9M/12M/18M/24M Tx 2 chain */
	    /* OFDM 36M/48M/54M/      Tx 1 chain */
	    /* CCK                    Tx 2 chain */
	    if ((oldMT == 2) || (oldMT == 3))
	    {
	        phyCtrl |= (0x5<<15);
	    }
	    else if (oldMT == 1)
	    {
	        if ((oldMCS == 0xb) || (oldMCS == 0xf) ||
	            (oldMCS == 0xa) || (oldMCS == 0xe) || 
	            (oldMCS == 0x9))                       //6M/9M/12M/18M/24M
	        {
	            phyCtrl |= (0x5<<15);
	        }
	        else
	        {
	            phyCtrl |= (0x1<<15);
	        }
	    }
	    else //(oldMT==0)
	    {
	        phyCtrl |= (0x5<<15);
	    }
	}
	//else
	//    phyCtrl |= (0x1<<15);

	/* TPC */
	/* TODO : accelerating these code */
	if (hpPriv->hwFrequency < 3000)
	{
        if (oldMT == 0)
        {
            /* CCK */
            tpc = (hpPriv->tPow2xCck[oldMCS]&0x3f);
        }
        else if (oldMT == 1)
        {
            /* OFDM */
            if (oldMCS == 0xc)
            {
                tpc = (hpPriv->tPow2x2g[3]&0x3f);
            }
            else if (oldMCS == 0x8)
            {
                tpc = (hpPriv->tPow2x2g[2]&0x3f);
            }
            else if (oldMCS == 0xd)
            {
                tpc = (hpPriv->tPow2x2g[1]&0x3f);
            }
            else if (oldMCS == 0x9)
            {
                tpc = ((hpPriv->tPow2x2g[0]-hpPriv->tPow2x2g24HeavyClipOffset)&0x3f);
            }
            else
            {
                tpc = (hpPriv->tPow2x2g[0]&0x3f);
            }
        }
        else if (oldMT == 2)
        {
            if ( oldPhyCtrl&0x800000 )    /* Bit23 : 40M */
            {
                /* HT 40 */
                tpc = (hpPriv->tPow2x2gHt40[oldMCS&0x7]&0x3f);
            }
            else
            {
                /* HT 20 */
                tpc = (hpPriv->tPow2x2gHt20[oldMCS&0x7]&0x3f);
            }   
        }
    }
    else  //5GHz
    {
        if (oldMT == 1)
        {
            /* OFDM */
            if (oldMCS == 0xc)
            {
                tpc = (hpPriv->tPow2x5g[3]&0x3f);
            }
            else if (oldMCS == 0x8)
            {
                tpc = (hpPriv->tPow2x5g[2]&0x3f);
            }
            else if (oldMCS == 0xd)
            {
                tpc = (hpPriv->tPow2x5g[1]&0x3f);
            }
            else
            {
                tpc = (hpPriv->tPow2x5g[0]&0x3f);
            }
        }
        else if (oldMT == 2)
        {
            if ( oldPhyCtrl&0x800000 )    /* Bit23 : 40M */
            {
                /* HT 40 */
                tpc = (hpPriv->tPow2x5gHt40[oldMCS&0x7]&0x3f);
            }
            else
            {
                /* HT 20 */
                tpc = (hpPriv->tPow2x5gHt20[oldMCS&0x7]&0x3f);
            }
        }
    }  
    
    /* Tx power adjust for HT40 */
	/* HT40   +1dBm */
	if ((oldMT==2) && (oldPhyCtrl&0x800000) )  
	{
	    tpc += 2;
	}  
	tpc &= 0x3f;
    
    /* Evl force tx TPC */
    if(wd->forceTxTPC)  
    {
        tpc = (u16_t)(wd->forceTxTPC & 0x3f);
    }
    
    if (hpPriv->hwFrequency < 3000) {
        wd->maxTxPower2 &= 0x3f;
        tpc = (tpc > wd->maxTxPower2)? wd->maxTxPower2 : tpc;
    } else {
        wd->maxTxPower5 &= 0x3f;
        tpc = (tpc > wd->maxTxPower5)? wd->maxTxPower5 : tpc;
    }


#define ZM_MIN_TPC     5
#define ZM_TPC_OFFSET  5
#define ZM_SIGNAL_THRESHOLD  56
    if ((wd->sta.bScheduleScan == FALSE) && (wd->sta.bChannelScan == FALSE))
    {
        if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
                && (zfStaIsConnected(dev))
                && (wd->SignalStrength > ZM_SIGNAL_THRESHOLD))
        {
            if (tpc > ((ZM_MIN_TPC+ZM_TPC_OFFSET)*2))
            {
                tpc -= (ZM_TPC_OFFSET*2);
            }
            else if (tpc > (ZM_MIN_TPC*2))
            {
                tpc = (ZM_MIN_TPC*2);
            }
        }
    }
#undef ZM_MIN_TPC     
#undef ZM_TPC_OFFSET  
#undef ZM_SIGNAL_THRESHOLD 

    #ifndef ZM_OTUS_LINUX_PHASE_2
    phyCtrl |= (tpc & 0x3f) << 9;
    #endif
    
    /* Set bits[8:6]BF-MCS for heavy clip */
    if ((phyCtrl&0x3) == 2)
	{
	    phyCtrl |= ((phyCtrl >> 12) & 0x1c0);
    }
void zfScanMgrScanEventStart(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    if ( wd->sta.bChannelScan )
    {
        return;
    }

    zfPowerSavingMgrWakeup(dev);

    zmw_enter_critical_section(dev);

    if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
    {
        goto no_scan;
    }

    //zfBssInfoRefresh(dev);
    zfBssInfoRefresh(dev, 0);
    wd->sta.bChannelScan = TRUE;
    wd->sta.bScheduleScan = FALSE;
    zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
    zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);

    //zm_debug_msg1("start scan = ", KeQueryInterruptTime());
    wd->sta.scanFrequency = zfChGetFirstChannel(dev, &wd->sta.bPassiveScan);
    zmw_leave_critical_section(dev);

    /* avoid lose receive packet when site survey */
    //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
    //{
    //    zfSendNullData(dev, 1);
    //}
//    zm_debug_msg0("scan 0");
//    zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);

    #if 1
    if (zfStaIsConnected(dev))
    {// If doing site survey !
        zfHpBeginSiteSurvey(dev, 1);
        zmw_enter_critical_section(dev);
        wd->sta.ibssSiteSurveyStatus = 1;
        zmw_leave_critical_section(dev);
    }
    else
    {
        zfHpBeginSiteSurvey(dev, 0);
        zmw_enter_critical_section(dev);
        wd->sta.ibssSiteSurveyStatus = 0;
        zmw_leave_critical_section(dev);
    }
    #endif

    zm_debug_msg0("scan 0");
    zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);

    return;

no_scan:
    zmw_leave_critical_section(dev);
    return;
}
u8_t zfScanMgrScanEventTimeout(zdev_t* dev)
{
    u16_t   nextScanFrequency = 0;
    u8_t    temp;

    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);
    if ( wd->sta.scanFrequency == 0 )
    {
        zmw_leave_critical_section(dev);
        return -1;
    }

    nextScanFrequency = zfChGetNextChannel(dev, wd->sta.scanFrequency,
                                           &wd->sta.bPassiveScan);

    if ( (nextScanFrequency == 0xffff)
         || (wd->sta.scanFrequency == zfChGetLastChannel(dev, &temp)) )
    {
        u8_t currScanType;
        u8_t isExternalScan = 0;
        u8_t isInternalScan = 0;

        //zm_debug_msg1("end scan = ", KeQueryInterruptTime());
        wd->sta.scanFrequency = 0;

        zm_debug_msg1("scan 1 type: ", wd->sta.scanMgr.currScanType);
        zm_debug_msg1("scan channel count = ", wd->regulationTable.allowChannelCnt);

        //zfBssInfoRefresh(dev);
        zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);

        if ( wd->sta.bChannelScan == FALSE )
        {
            zm_debug_msg0("WOW!! scan is cancelled\n");
            zmw_leave_critical_section(dev);
            goto report_scan_result;
        }


        currScanType = wd->sta.scanMgr.currScanType;
        switch(currScanType)
        {
            case ZM_SCAN_MGR_SCAN_EXTERNAL:
                isExternalScan = 1;

                if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] )
                {
                    wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] = 0;
                    isInternalScan = 1;
                }

                break;

            case ZM_SCAN_MGR_SCAN_INTERNAL:
                isInternalScan = 1;

                if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_EXTERNAL - 1] )
                {
                    // Because the external scan should pre-empts internal scan.
                    // So this shall not be happened!!
                    zm_assert(0);
                }

                break;

            default:
                zm_assert(0);
                break;
        }

        wd->sta.scanMgr.scanReqs[currScanType - 1] = 0;
        wd->sta.scanMgr.scanStartDelay = 100;
        wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE;
        zmw_leave_critical_section(dev);

        //Set channel according to AP's configuration
        zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
                wd->ExtOffset, zfScanMgrEventScanCompleteCb);

        wd->sta.bChannelScan = FALSE;

        #if 1
        if (zfStaIsConnected(dev))
        { // Finish site survey, reset the variable to detect using wrong frequency !
            zfHpFinishSiteSurvey(dev, 1);
            zmw_enter_critical_section(dev);
            wd->sta.ibssSiteSurveyStatus = 2;
            wd->tickIbssReceiveBeacon = 0;
            wd->sta.ibssReceiveBeaconCount = 0;
            zmw_leave_critical_section(dev);

            /* #5 Re-enable RIFS function after the site survey ! */
            /* This is because switch band will reset the BB register to initial value */
            if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED )
            {
                zfHpEnableRifs(dev, ((wd->sta.currentFrequency<3000)?1:0), wd->sta.EnableHT, wd->sta.HT2040);
            }
        }
        else
        {
            zfHpFinishSiteSurvey(dev, 0);
            zmw_enter_critical_section(dev);
            wd->sta.ibssSiteSurveyStatus = 0;
            zmw_leave_critical_section(dev);
        }
        #endif

report_scan_result:
        /* avoid lose receive packet when site survey */
        //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
        //{
        //    zfSendNullData(dev, 0);
        //}

        if ( isExternalScan )//Quickly reboot
        {
            if (wd->zfcbScanNotify != NULL)
            {
                wd->zfcbScanNotify(dev, NULL);
            }
        }

        if ( isInternalScan )
        {
            //wd->sta.InternalScanReq = 0;
            zfStaReconnect(dev);
        }

        return 0;
    }
    else
    {
        wd->sta.scanFrequency = nextScanFrequency;

        //zmw_enter_critical_section(dev);
        zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
        zmw_leave_critical_section(dev);

        zm_debug_msg0("scan 2");
        zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);

        return 1;
    }
}
u8_t zfScanMgrScanStart(zdev_t* dev, u8_t scanType)
{
    u8_t i;

    zmw_get_wlan_dev(dev);

    zm_debug_msg1("scanType = ", scanType);

    zmw_declare_for_critical_section();

    if ( scanType != ZM_SCAN_MGR_SCAN_INTERNAL &&
         scanType != ZM_SCAN_MGR_SCAN_EXTERNAL )
    {
        zm_debug_msg0("unknown scanType");
        return 1;
    }
    else if (zfStaIsConnecting(dev))
    {
        zm_debug_msg0("reject scan request due to connecting");
        return 1;
    }

    i = scanType - 1;

    zmw_enter_critical_section(dev);

    if ( wd->sta.scanMgr.scanReqs[i] == 1 )
    {
        zm_debug_msg1("scan rescheduled", scanType);
        goto scan_done;
    }

    wd->sta.scanMgr.scanReqs[i] = 1;
    zm_debug_msg1("scan scheduled: ", scanType);

    // If there's no scan pending, we do the scan right away.
    // If there's an internal scan and the new scan request is external one,
    // we will restart the scan.
    if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
    {
        goto schedule_scan;
    }
    else if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_INTERNAL &&
              scanType == ZM_SCAN_MGR_SCAN_EXTERNAL )
    {
        // Stop the internal scan & schedule external scan first
        zfTimerCancel(dev, ZM_EVENT_SCAN);

        /* Fix for WHQL sendrecv => we do not apply delay time in which the device
           stop transmitting packet when we already connect to some AP  */
        wd->sta.bScheduleScan = FALSE;

        zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
        zfTimerCancel(dev, ZM_EVENT_IN_SCAN);

        wd->sta.bChannelScan = FALSE;
        goto schedule_scan;
    }
    else
    {
        zm_debug_msg0("Scan is busy...waiting later to start\n");
    }

    zmw_leave_critical_section(dev);
    return 0;

scan_done:
    zmw_leave_critical_section(dev);
    return 1;

schedule_scan:

    wd->sta.bScheduleScan = TRUE;

    zfTimerSchedule(dev, ZM_EVENT_SCAN, wd->sta.scanMgr.scanStartDelay);
    wd->sta.scanMgr.scanStartDelay = 3;
    //wd->sta.scanMgr.scanStartDelay = 0;
    wd->sta.scanMgr.currScanType = scanType;
    zmw_leave_critical_section(dev);

    if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
    {
        zfSendNullData(dev, 1);
    }
    return 0;
}
void zfScanMgrScanStop(zdev_t* dev, u8_t scanType)
{
    u8_t scanNotifyRequired = 0;
    u8_t theOtherScan = ZM_SCAN_MGR_SCAN_NONE;

    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);

    if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
    {
        zm_assert(wd->sta.scanMgr.scanReqs[0] == 0);
        zm_assert(wd->sta.scanMgr.scanReqs[1] == 0);
        goto done;
    }

    switch(scanType)
    {
        case ZM_SCAN_MGR_SCAN_EXTERNAL:
            scanNotifyRequired = 1;
            theOtherScan = ZM_SCAN_MGR_SCAN_INTERNAL;
            break;

        case ZM_SCAN_MGR_SCAN_INTERNAL:
            theOtherScan = ZM_SCAN_MGR_SCAN_EXTERNAL;
            break;

        default:
            goto done;
    }

    if ( wd->sta.scanMgr.currScanType != scanType )
    {
        goto stop_done;
    }

    zfTimerCancel(dev, ZM_EVENT_SCAN);

    /* Fix for WHQL sendrecv => we do not apply delay time in which the device
       stop transmitting packet when we already connect to some AP  */
    wd->sta.bScheduleScan = FALSE;

    zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
    zfTimerCancel(dev, ZM_EVENT_IN_SCAN);

    wd->sta.bChannelScan = FALSE;
    wd->sta.scanFrequency = 0;

    if ( wd->sta.scanMgr.scanReqs[theOtherScan - 1] )
    {
        wd->sta.scanMgr.currScanType = theOtherScan;

        // Schedule the other scan after 1 second later
        zfTimerSchedule(dev, ZM_EVENT_SCAN, 100);
    }
    else
    {
        wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE;
    }

stop_done:
    wd->sta.scanMgr.scanReqs[scanType - 1] = 0;

    zmw_leave_critical_section(dev);

    /* avoid lose receive packet when site survey */
    if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
    {
        zfSendNullData(dev, 0);
    }

    if ( scanNotifyRequired )
    {
        zm_debug_msg0("Scan notify after reset");
        if (wd->zfcbScanNotify != NULL)
        {
            wd->zfcbScanNotify(dev, NULL);
        }
    }

    return;

done:
    zmw_leave_critical_section(dev);
    return;
}