コード例 #1
0
void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent)
{
#ifdef CONFIG_PM
    if (ar->arWowState!=WOW_STATE_NONE) {
        if (ar->arWowState==WOW_STATE_SUSPENDING) {
            AR_DEBUG_PRINTF(ATH_DEBUG_SUSPEND,("%s: Received IRQ while we are wow suspending!!!\n", __func__));
            return;
        }
        /* Wow resume from irq interrupt */
        AR_DEBUG_PRINTF(ATH_DEBUG_SUSPEND, ("%s: WoW resume from irq thread status %d\n", 
                        __func__, ar->arOsPowerCtrl));
        ar6000_wow_resume(ar);
        ar->arOsPowerCtrl = WLAN_PWR_CTRL_UP;
    } else if (screen_is_off && skb && ar->arConnected) {
        A_BOOL needWake = FALSE;
        if (isEvent) {
            if (A_NETBUF_LEN(skb) >= sizeof(A_UINT16)) {
                A_UINT16 cmd = *(const A_UINT16 *)A_NETBUF_DATA(skb);
                switch (cmd) {
                case WMI_CONNECT_EVENTID:
                case WMI_DISCONNECT_EVENTID:
                    needWake = TRUE;
                    break;
                default:
                    /* dont wake lock the system for other event */
                    break;
                }
            }
        } else if (A_NETBUF_LEN(skb) >= sizeof(ATH_MAC_HDR)) {
            ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
            if (!IEEE80211_IS_MULTICAST(datap->dstMac)) {
                switch (A_BE2CPU16(datap->typeOrLen)) {
                case 0x0800: /* IP */
                case 0x888e: /* EAPOL */
                case 0x88c7: /* RSN_PREAUTH */
                case 0x88b4: /* WAPI */
                     needWake = TRUE;
                     break;
                case 0x0806: /* ARP is not important to hold wake lock */
                default:
                    break;
                }
            }
        }
        if (needWake) {
            /* keep host wake up if there is any event and packate comming in*/
            wake_lock_timeout(&ar6k_wow_wake_lock, 3*HZ);
            if (wowledon) {
                char buf[32];
                int len = sprintf(buf, "on");         
                android_readwrite_file("/sys/power/state", NULL, buf, len);

                len = sprintf(buf, "%d", 127);
                android_readwrite_file("/sys/class/leds/lcd-backlight/brightness", 
                                       NULL, buf,len);                    
            }
        }
    }
#endif /* CONFIG_PM */
}
コード例 #2
0
ファイル: ar6000_android.c プロジェクト: burstlam/AR6kSDK.3.1
void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent)
{
#ifdef CONFIG_HAS_WAKELOCK
    unsigned long wake_timeout = HZ; /* 1 second for normal window's ping test */
#endif
    AR_SOFTC_DEV_T *arPriv;
    A_UINT8  i; 
    A_BOOL needWake = FALSE;
    for(i = 0; i < num_device; i++) 
    {
        arPriv = ar->arDev[i];
        if (
#ifdef CONFIG_HAS_EARLYSUSPEND
            screen_is_off && 
#endif
                skb && arPriv->arConnected) {
            if (isEvent) {
                if (A_NETBUF_LEN(skb) >= sizeof(A_UINT16)) {
                    A_UINT16 cmd = *(const A_UINT16 *)A_NETBUF_DATA(skb);
                    switch (cmd) {
                    case WMI_CONNECT_EVENTID:
#ifdef CONFIG_HAS_WAKELOCK
                         wake_timeout = 3*HZ;
#endif
                         needWake = TRUE;
                         break;
                    default:
                        /* dont wake lock the system for other event */
                         break;
                    }
                }
            } else if (A_NETBUF_LEN(skb) >= sizeof(ATH_MAC_HDR)) {
                ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
                if (!IEEE80211_IS_MULTICAST(datap->dstMac)) {
                    switch (A_BE2CPU16(datap->typeOrLen)) {
                    case 0x0800: /* IP */
                        if (A_NETBUF_LEN(skb)>=24 &&
                            *((A_UCHAR*)A_NETBUF_DATA(skb)+23)==0x11) {
                            A_UCHAR *udpPkt = (A_UCHAR*)A_NETBUF_DATA(skb)+14;
                            A_UINT8 ihl = (*udpPkt & 0x0f) * sizeof(A_UINT32);
                            const A_UCHAR ipsec_keepalive[] = { 
                                0x11, 0x94, 0x11, 0x94, 0x00, 0x09, 0x00, 0x00, 0xff
                            };
                            udpPkt += ihl;
                            if (A_NETBUF_LEN(skb)>=14+ihl+sizeof(ipsec_keepalive) &&
                                    !memcmp(udpPkt, ipsec_keepalive, sizeof(ipsec_keepalive)-3) &&
                                    udpPkt[8]==0xff) {
                                /* 
                                 * RFC 3948 UDP Encapsulation of IPsec ESP Packets
                                 * Source and Destination port must be 4500
                                 * Receivers MUST NOT depend upon the UDP checksum being zero 
                                 * Sender must use 1 byte payload with 0xff
                                 * Receiver SHOULD ignore a received NAT-keepalive packet
                                 *
                                 * IPSec over UDP NAT keepalive packet. Just ignore
                                 */
                                break;
                            }
                        }
                    case 0x888e: /* EAPOL */
                    case 0x88c7: /* RSN_PREAUTH */
                    case 0x88b4: /* WAPI */
                         needWake = TRUE;
                         break;
                    case 0x0806: /* ARP is not important to hold wake lock */
                        needWake = (arPriv->arNetworkType==AP_NETWORK);
                        break;
                    default:
                         break;
                    }
                } else if ( !IEEE80211_IS_BROADCAST(datap->dstMac) ) {
                    if (A_NETBUF_LEN(skb)>=14+20 ) {
					    /* check if it is mDNS packets */
                        A_UINT8 *dstIpAddr = (A_UINT8*)(A_NETBUF_DATA(skb)+14+20-4);                    
                        struct net_device *ndev = arPriv->arNetDev;
                        needWake = ((dstIpAddr[3] & 0xf8) == 0xf8) &&
                                (arPriv->arNetworkType==AP_NETWORK || 
                                (ndev->flags & IFF_ALLMULTI || ndev->flags & IFF_MULTICAST));
                    }
                }else if (arPriv->arNetworkType==AP_NETWORK) {
                    switch (A_BE2CPU16(datap->typeOrLen)) {
                    case 0x0800: /* IP */
                        if (A_NETBUF_LEN(skb)>=14+20+2) {
                            A_UINT16 dstPort = *(A_UINT16*)(A_NETBUF_DATA(skb)+14+20);
                            dstPort = A_BE2CPU16(dstPort);
                            needWake = (dstPort == 0x43); /* dhcp request */
                        }
                        break;
                    case 0x0806: 
                        needWake = TRUE;
                    default:
                        break;
                    }
                }
             }
         }
    }
    if (needWake) {
#ifdef CONFIG_HAS_WAKELOCK
        /* keep host wake up if there is any event and packate comming in*/
        wake_lock_timeout(&ar6k_wow_wake_lock, wake_timeout);
#endif
        if (wowledon) {
            char buf[32];
            int len = sprintf(buf, "on");
            android_readwrite_file("/sys/power/state", NULL, buf, len);

            len = sprintf(buf, "%d", 127);
            android_readwrite_file("/sys/class/leds/lcd-backlight/brightness",
                                   NULL, buf,len);
        }
    }
}
コード例 #3
0
ファイル: car6krx.cpp プロジェクト: NemProjects/WLAN
void
CAR6KMini::ReceiveWMIDataPacket(
	HTC_EVENT_INFO  *evInfo)
//
//  This function processes data from an HTC_BUFFER_RECEIVED indication
//  not on the WMI_CONTROL_MBOX endpoint.
//
{
	ndis_mini_buf_t *pb = (ndis_mini_buf_t *)evInfo->cookie;
	NDIS_STATUS      Status;
	NDIS_PACKET     *pPacket;
	NDIS_BUFFER     *pBuffer;
	PBYTE            pData;
	ULONG            cbData;
	BOOL			 doDix = FALSE;
	USHORT			 etherType;
	SNAP_HEADER		 *pSnapHdr;
	MAC_ADDRESS		 *pDestAddr,*tempAddr;
	BOOL			 mcForUs = FALSE;
		
	
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "AR6K: +ReceiveWMIDataPacket");

	    
    if (evInfo->status != A_OK) {
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket Error in receiving : status = %x\n", evInfo->status);
		if (A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
    }
    
	// evInfo->actualLength is the length of the pb->data including
	//      2 bytes: WMI_DATA_HEADER [optional - only if HTC header is 46 00]
	//     14 bytes: 802.3 MAC header
	//      8 bytes: SNAP header (with EthType as last 2 bytes)
	//      N bytes: payload (e.g. IP packet)
	pData = evInfo->buffer; 
	cbData = evInfo->actualLength;

	// Remove the WMI_DATA_HDR.
	if (cbData < sizeof(WMI_DATA_HDR))
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket missing WMI header (%u bytes)\n", evInfo->actualLength);
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
    }
	pData += sizeof(WMI_DATA_HDR);
	cbData -= sizeof(WMI_DATA_HDR);

	if (cbData < sizeof(ETHERNET_MAC_HEADER) + sizeof(SNAP_HEADER))
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket missing MAC + SNAP (%u bytes)\n", cbData);
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
	}

#ifdef WMM
	Lock();
    wmi_implicit_create_pstream((wmi_t *)m_pWMI, pb, DNLINK_TRAFFIC,1);
	Unlock();
#endif //WMM

	
	pDestAddr=(MAC_ADDRESS *)pData;
 	
 	/* Apply NDIS receive filter */
     if (isGrp(pDestAddr)) {
         if (isBcast(pDestAddr)) {
			 if (!(m_CurrentPacketFilter & NDIS_PACKET_TYPE_BROADCAST)) {
                 if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
					a_netbuf_free(pb);
				 }			
				 goto done;
             }
         } else {
			 isMcForUs(pDestAddr,&mcForUs);
			 if (!(m_CurrentPacketFilter & (NDIS_PACKET_TYPE_MULTICAST |
				 NDIS_PACKET_TYPE_ALL_MULTICAST)) || !(mcForUs))
             {
				 if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
					a_netbuf_free(pb);
				 }
				 goto done;
             }
		}
 		
     } else {
		tempAddr=(MAC_ADDRESS *) m_PermanentAddress;
		if ((A_MACADDR_COMP(pDestAddr,tempAddr) != 0) &&
             !(m_CurrentPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS))
        {
			if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
				a_netbuf_free(pb);
			}
			goto done;
        }
	}

	 // Allocate an NDIS_PACKET from our packet pool.
	NdisAllocatePacket(&Status, &pPacket, m_RxPacketPool);
	if (NDIS_STATUS_SUCCESS != Status)
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - NdisAllocatePacket failed\n");
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
	}

	// Check for ethernetType in SNAP header for NOVELL_IPX, APPLE_TALK_ARP etc
	// remove 802.3 length and SNAP header if it is not of these types 
	
	pSnapHdr=(SNAP_HEADER *)(pData+sizeof(ETHERNET_MAC_HEADER));
	etherType=A_BE2CPU16(pSnapHdr->Type);
	
	doDix=((A_MEMCMP(pSnapHdr,&bridgeTunnel, sizeof(CAP_CONST))) == 0);
	if((!doDix) && ((A_MEMCMP(pSnapHdr,&vrfc1042, sizeof(CAP_CONST))) == 0))
	{
		doDix = ((etherType != APPLE_TALK_ARP) && (etherType != NOVELL_IPX));
	}
	// Get rid of the 802.3 length and SNAP header by copying
	// the 802.3 DestMACAddr and SrcMACAddr forward so they
	// immediately precede the EthType at the end of the SNAP header.
	// That gives us a DIX packet.

	if (doDix) {
	memmove(pData + sizeof(SNAP_HEADER), pData, ETHERNET_MAC_ADDRESS_LENGTH * 2);
	pData += sizeof(SNAP_HEADER);
	cbData -= sizeof(SNAP_HEADER);
	}


	

	// Setup the fields of NDIS_BUFFER to point to our data.
	pBuffer = &pb->NdisBuffer;
	NdisInitializeBuffer(pBuffer, pData, cbData);

	// Chain the NDIS_BUFFER to the start of the NDIS_PACKET
	NdisChainBufferAtBack(pPacket, pBuffer);
	NDIS_SET_PACKET_HEADER_SIZE(pPacket, sizeof(ETHERNET_MAC_HEADER));
	NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_SUCCESS);

#ifdef NDIS_BUS_DRIVER
	NDIS_PACKET *PacketArray[1];
	PacketArray[0]=pPacket;
	NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, 1);
#else
	// Perform the indicate on the timer thread because tying up the
	// SDIO receive indication thread can result in a deadlock.
	PLIST_ENTRY pEntry = (PLIST_ENTRY)(pPacket->MiniportReserved);
	Lock();
	InsertTailList(&m_RxPendingPacketList, pEntry);
	NdisSetEvent(&m_RxPendingEvent);
	Unlock();
#endif	

done:
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "AR6K: -ReceiveWMIDataPacket");
}
コード例 #4
0
void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent)
{
    AR_SOFTC_DEV_T *arPriv;
    A_UINT8  i; 
    A_BOOL needWake = FALSE;
    for(i = 0; i < num_device; i++) 
    {
        arPriv = ar->arDev[i];
        if (
#ifdef CONFIG_HAS_EARLYSUSPEND
            screen_is_off && 
#endif
                skb && arPriv->arConnected) {
            if (isEvent) {
                if (A_NETBUF_LEN(skb) >= sizeof(A_UINT16)) {
                    A_UINT16 cmd = *(const A_UINT16 *)A_NETBUF_DATA(skb);
                    switch (cmd) {
                    case WMI_CONNECT_EVENTID:
                    case WMI_DISCONNECT_EVENTID:
                         needWake = TRUE;
                         break;
                    default:
                        /* dont wake lock the system for other event */
                         break;
                    }
                }
            } else if (A_NETBUF_LEN(skb) >= sizeof(ATH_MAC_HDR)) {
                ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
                if (!IEEE80211_IS_MULTICAST(datap->dstMac)) {
                    switch (A_BE2CPU16(datap->typeOrLen)) {
                    case 0x0800: /* IP */
                    case 0x888e: /* EAPOL */
                    case 0x88c7: /* RSN_PREAUTH */
                    case 0x88b4: /* WAPI */
                         needWake = TRUE;
                         break;
                    case 0x0806: /* ARP is not important to hold wake lock */
                        needWake = (arPriv->arNetworkType==AP_NETWORK);
                        break;
                    default:
                         break;
                    }
                } else if ( !IEEE80211_IS_BROADCAST(datap->dstMac) ) {
                    if (A_NETBUF_LEN(skb)>=14+20 ) {
					    /* check if it is mDNS packets */
                        A_UINT8 *dstIpAddr = (A_UINT8*)(A_NETBUF_DATA(skb)+14+20-4);                    
                        struct net_device *ndev = arPriv->arNetDev;
                        needWake = ((dstIpAddr[3] & 0xf8) == 0xf8) &&
                                (arPriv->arNetworkType==AP_NETWORK || 
                                (ndev->flags & IFF_ALLMULTI || ndev->flags & IFF_MULTICAST));
                    }
                }else if (arPriv->arNetworkType==AP_NETWORK) {
                    switch (A_BE2CPU16(datap->typeOrLen)) {
                    case 0x0800: /* IP */
                        if (A_NETBUF_LEN(skb)>=14+20+2) {
                            A_UINT16 dstPort = *(A_UINT16*)(A_NETBUF_DATA(skb)+14+20);
                            dstPort = A_BE2CPU16(dstPort);
                            needWake = (dstPort == 0x43); /* dhcp request */
                        }
                        break;
                    case 0x0806: 
                        needWake = TRUE;
                    default:
                        break;
                    }
                }
             }
         }
    }
    if (needWake) {
#ifdef CONFIG_HAS_WAKELOCK
        /* keep host wake up if there is any event and packate comming in*/
        wake_lock_timeout(&ar6k_wow_wake_lock, 3*HZ);
#endif
        if (wowledon) {
            char buf[32];
            int len = sprintf(buf, "on");
            android_readwrite_file("/sys/power/state", NULL, buf, len);

            len = sprintf(buf, "%d", 127);
            android_readwrite_file("/sys/class/leds/lcd-backlight/brightness",
                                   NULL, buf,len);
        }
    }
}