Example #1
0
static void ar6000_wow_resume(AR_SOFTC_T *ar)
{
    if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
        A_UINT16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
        A_UINT16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period;
        WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {TRUE, FALSE};
        ar->arWowState = WLAN_WOW_STATE_NONE;
#ifdef CONFIG_HAS_WAKELOCK
        wake_lock_timeout(&ar6k_wow_wake_lock, 3*HZ);
#endif
        if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!=A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n"));
        }
#if WOW_SET_SCAN_PARAMS
        wmi_scanparams_cmd(ar->arWmi, fg_start_period,
                                   ar->scParams.fg_end_period,
                                   bg_period,
                                   ar->scParams.minact_chdwell_time,
                                   ar->scParams.maxact_chdwell_time,
                                   ar->scParams.pas_chdwell_time,
                                   ar->scParams.shortScanRatio,
                                   ar->scParams.scanCtrlFlags,
                                   ar->scParams.max_dfsch_act_time,
                                   ar->scParams.maxact_scan_per_ssid);
#else
       (void)fg_start_period; 
       (void)bg_period;
#endif 


#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
        if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == A_OK) {
        }
#endif
        ar6k_send_asleep_event_to_app(ar, FALSE); 
        AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n"));
    } else {
        AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume"));
    }
    ar->arWlanPowerState = WLAN_POWER_STATE_ON;
}
Example #2
0
static void ar6000_wow_suspend(AR_SOFTC_T *ar)
{
#define WOW_LIST_ID 1
    if (ar->arNetworkType != AP_NETWORK) {
        /* Setup WoW for unicast & Arp request for our own IP
        disable background scan. Set listen interval into 1000 TUs
        Enable keepliave for 110 seconds
        */
        struct in_ifaddr **ifap = NULL;
        struct in_ifaddr *ifa = NULL;
        struct in_device *in_dev;
        A_UINT8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        A_STATUS status;
        WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } };
        WMI_DEL_WOW_PATTERN_CMD delWowCmd;
        WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {FALSE, TRUE};
        WMI_SET_WOW_MODE_CMD wowMode = {    .enable_wow = TRUE, 
                                            .hostReqDelay = 500 };/*500 ms delay*/
        
        if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n"));
            return;
        }

        ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/

#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
        if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == A_OK) {
        }
#endif

#if WOW_SET_SCAN_PARAMS
        status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0);
#endif 
        /* clear up our WoW pattern first */
        delWowCmd.filter_list_id = WOW_LIST_ID;
        delWowCmd.filter_id = 0;
        wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd);

        /* setup unicast packet pattern for WoW */
        if (ar->arNetDev->dev_addr[1]) {
            addWowCmd.filter_list_id = WOW_LIST_ID;
            addWowCmd.filter_size = 6; /* MAC address */
            addWowCmd.filter_offset = 0;
            status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size);
            if (status != A_OK) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n"));
            }
        }
        /* setup ARP request for our own IP */
        if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) {
            for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) {
                if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) {
                    break; /* found */
                }
            }
        }
        if (ifa && ifa->ifa_local) {
            WMI_SET_IP_CMD ipCmd;
            memset(&ipCmd, 0, sizeof(ipCmd));
            ipCmd.ips[0] = ifa->ifa_local;
            status = wmi_set_ip_cmd(ar->arWmi, &ipCmd);
            if (status != A_OK) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n"));
            }
        }

#ifndef ATH6K_CONFIG_OTA_MODE
        wmi_powermode_cmd(ar->arWmi, REC_POWER);
#endif

        status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n"));
        }
        ar6k_send_asleep_event_to_app(ar, TRUE);

        status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n"));
        }

        ar->arWowState = WLAN_WOW_STATE_SUSPENDING;
        if (ar->arTxPending[ar->arControlEp]) {
            A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent,
            ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
            if (!timeleft || signal_pending(current)) {
               /* what can I do? wow resume at once */
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp]));
            }
        }

        status = hifWaitForPendingRecv(ar->arHifDevice);

        ar->arWowState = WLAN_WOW_STATE_SUSPENDED;
        ar->arWlanPowerState = WLAN_POWER_STATE_WOW;
    } else {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n"));
    }
}
Example #3
0
void
CAR6KMini::WMIConnectIndication(
	IN USHORT		Channel, 
	IN PBYTE 		PeerBSSID,
	IN USHORT		listenInterval,
	IN USHORT		beaconInterval,
	NETWORK_TYPE	networkType, 
	IN BYTE			assocReqLen, 
	IN BYTE			assocRespLen,
	IN PBYTE		assocInfo,
	IN BYTE			beaconIeLen)
	
{
	BYTE       len = 0;
	int        i = 0;
	A_STATUS wmiStatus;
	bss_t * bss;

	NDIS_DEBUG_PRINTF(1,"WMIConnectIndication Enter , %02x:%02x:%02x:%02x:%02x:%02x \r\n",
							PeerBSSID[0],PeerBSSID[1],PeerBSSID[2],PeerBSSID[3],PeerBSSID[4],PeerBSSID[5]);

	/* Set the Listen interval to appropriate value (100/1000 TUs) depending
	 * on the power mode setting. For REC Mode we always indicate 1000TUs to the
	 * AP in the conn. req. but reset it appropriately here upon conn Ind.
	 */
	if( m_80211_PowerMode == Ndis802_11PowerModeFast_PSP ) 
	{
	

		wmiStatus = wmi_listeninterval_cmd((struct wmi_t *)m_pWMI, 
			m_ListenInterval, 0);
	
		if (wmiStatus != A_OK) 
		{
			NDIS_DEBUG_PRINTF(DBG_ERR_LOG,"AR6K: ERROR - wmi_listeninterval_cmd failed = %u \r\n", wmiStatus);
		}
	}


	memcpy(m_PeerBSSID, PeerBSSID, ETHERNET_MAC_ADDRESS_LENGTH);
	m_ConnectedChannel = Channel;
	m_Connected = true;
	m_ConnectInProgress = false;
	m_AssocReqLen = assocReqLen;
	m_AssocRespLen = assocRespLen;
	m_BeaconIeLen = beaconIeLen;
	
	if (m_pAssocInfo != NULL) {
		A_FREE(m_pAssocInfo);
	}


	m_pAssocInfo = (PBYTE)malloc(m_AssocReqLen + m_AssocRespLen + m_BeaconIeLen);
	if(m_pAssocInfo == NULL ) 
	{
		NDIS_DEBUG_PRINTF(DBG_ERR, " %s() -> malloc faile!! size = %d \r\n",__FUNCTION__, m_AssocReqLen + m_AssocRespLen + m_BeaconIeLen);
		return;
	}
	else 
	{
		memcpy(m_pAssocInfo, assocInfo, m_AssocReqLen + m_AssocRespLen + m_BeaconIeLen);
	}


    // Send Command to Enable or disable Background Scan
	if (m_Config.bkScanEnable) 
	{
	    m_WMIBssFilter = ALL_BUT_BSS_FILTER;
	} 
	else 
	{
	    m_WMIBssFilter = NONE_BSS_FILTER;
    }
	
	wmi_bssfilter_cmd((struct wmi_t *)m_pWMI, m_WMIBssFilter,0);

	//Add the key here for WEP encryption with open Auth or Autoswitch.
	// For Shared Auth, the keys are plumbed before the connect cmd is issued and
	// for WPA/WPA2, the keys are plumbed when the AddKey OID comes.

	if (m_AuthenticationMode == Ndis802_11AuthModeOpen ||
		m_AuthenticationMode == Ndis802_11AuthModeAutoSwitch ) 

	{

		if (m_EncryptionStatus == Ndis802_11WEPEnabled) 
		{
			
			NDIS_DEBUG_PRINTF(DBG_TRACE, "WEP encryption  \r\n");
			
			for (i=0;i<4;i++) 
			{
				if (m_cbKey[i] != 0) 
				{
					NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6K: adding WEP keys @ index %d \r\n", i);

					wmiStatus = wmi_addKey_cmd((wmi_t *)m_pWMI, (A_UINT8)m_KeyIndex[i], 	
						WEP_CRYPT, m_KeyUsage[i], (A_UINT8)m_cbKey[i], NULL, m_Key[i],
						KEY_OP_INIT_VAL,NULL,NO_SYNC_WMIFLAG);

                    if (wmiStatus != A_OK) 
					{
					    NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6K: ERROR - wmi_addKey_cmd failed = %u \r\n", wmiStatus);
                    }
				}
			}
		}
	}

	// Indicate MEDIA_CONNECT to Ndis
	NdisMIndicateStatus(m_MiniportAdapterHandle, NDIS_STATUS_MEDIA_CONNECT, 0, 0);
	NdisMIndicateStatusComplete(m_MiniportAdapterHandle);
	bss=wmi_find_node((wmi_t *)m_pWMI,m_PeerBSSID);
    if (bss != NULL) {
	    m_beaconInterval = bss->ni_cie.ie_beaconInt;
    }

	NDIS_DEBUG_PRINTF(DBG_TRACE,"%s() - Exit !! \r\n",__FUNCTION__);
	return;
}