static bool ath6kl_parse_data_pkt_for_wake_lock(struct ath6kl *ar, struct sk_buff *skb) { struct net_device *ndev; struct ath6kl_vif *vif; struct ethhdr *hdr; bool need_wake = false; u16 dst_port; vif = ath6kl_vif_first(ar); if (!vif) return need_wake; if (skb->len < sizeof(struct ethhdr)) return need_wake; hdr = (struct ethhdr *) skb->data; if (!is_multicast_ether_addr(hdr->h_dest)) { switch (ntohs(hdr->h_proto)) { case 0x0800: /* IP */ need_wake = ath6kl_parse_ip_pkt_for_wake_lock(skb); break; case 0x888e: /* EAPOL */ case 0x88c7: /* RSN_PREAUTH */ case 0x88b4: /* WAPI */ need_wake = true; break; default: break; } } else if (!is_broadcast_ether_addr(hdr->h_dest)) { if (skb->len >= 14 + 20) { /* mDNS packets */ u8 *dst_ipaddr = (u8 *)(skb->data + 14 + 20 - 4); ndev = vif->ndev; if (((dst_ipaddr[3] & 0xf8) == 0xf8) && (vif->nw_type == AP_NETWORK || (ndev->flags & IFF_ALLMULTI || ndev->flags & IFF_MULTICAST))) need_wake = true; } } else if (vif->nw_type == AP_NETWORK) { switch (ntohs(hdr->h_proto)) { case 0x0800: /* IP */ if (skb->len >= 14 + 20 + 2) { dst_port = *(u16 *)(skb->data + 14 + 20); /* dhcp req */ need_wake = (ntohs(dst_port) == 0x43); } break; case 0x0806: need_wake = true; default: break; } } return need_wake; }
static bool ath6kl_parse_data_pkt_for_wake_lock(struct ath6kl *ar, struct sk_buff *skb) { struct net_device *ndev; struct ath6kl_vif *vif; struct ethhdr *hdr; bool need_wake = false; u16 dst_port; vif = ath6kl_vif_first(ar); if (!vif) return need_wake; if (skb->len < sizeof(struct ethhdr)) return need_wake; hdr = (struct ethhdr *) skb->data; #if 0 // by bbelief if (test_and_clear_bit(WOW_RESUME_PRINT, &ar->flag)) { ath6kl_dbg(ATH6KL_DBG_SUSPEND, "(wow) dest mac:%pM, src mac:%pM, type/len :%04x\n", hdr->h_dest, hdr->h_source, be16_to_cpu(hdr->h_proto)); } #endif if (!is_multicast_ether_addr(hdr->h_dest)) { switch (ntohs(hdr->h_proto)) { case 0x0800: /* IP */ need_wake = ath6kl_parse_ip_pkt_for_wake_lock(skb); break; case 0x888e: /* EAPOL */ case 0x88c7: /* RSN_PREAUTH */ case 0x88b4: /* WAPI */ need_wake = true; break; default: break; } } else if (!is_broadcast_ether_addr(hdr->h_dest)) { if (skb->len >= 14 + 20) { /* mDNS packets */ u8 *dst_ipaddr = (u8 *)(skb->data + 14 + 20 - 4); ndev = vif->ndev; if (((dst_ipaddr[3] & 0xf8) == 0xf8) && (vif->nw_type == AP_NETWORK || (ndev->flags & IFF_ALLMULTI || ndev->flags & IFF_MULTICAST))) need_wake = true; } } else if (vif->nw_type == AP_NETWORK) { switch (ntohs(hdr->h_proto)) { case 0x0800: /* IP */ if (skb->len >= 14 + 20 + 2) { dst_port = *(u16 *)(skb->data + 14 + 20); /* dhcp req */ need_wake = (ntohs(dst_port) == 0x43); } break; case 0x0806: need_wake = true; default: break; } } return need_wake; }