/** * eth_type_trans - determine the packet's protocol ID. * @skb: received socket data * @dev: receiving network device * * The rule here is that we * assume 802.3 if the type field is short enough to be a length. * This is normal practice and works for any 'now in use' protocol. */ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) { unsigned short _service_access_point; const unsigned short *sap; const struct ethhdr *eth; skb->dev = dev; skb_reset_mac_header(skb); skb_pull_inline(skb, ETH_HLEN); eth = eth_hdr(skb); if (unlikely(is_multicast_ether_addr(eth->h_dest))) { if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; } else if (unlikely(!ether_addr_equal_64bits(eth->h_dest, dev->dev_addr))) skb->pkt_type = PACKET_OTHERHOST; /* * Some variants of DSA tagging don't have an ethertype field * at all, so we check here whether one of those tagging * variants has been configured on the receiving interface, * and if so, set skb->protocol without looking at the packet. */ if (unlikely(netdev_uses_dsa_tags(dev))) return htons(ETH_P_DSA); if (unlikely(netdev_uses_trailer_tags(dev))) return htons(ETH_P_TRAILER); if (likely(ntohs(eth->h_proto) >= ETH_P_802_3_MIN)) return eth->h_proto; /* * This is a magic hack to spot IPX packets. Older Novell breaks * the protocol design and runs IPX over 802.3 without an 802.2 LLC * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This * won't work for fault tolerant netware but does for the rest. */ sap = skb_header_pointer(skb, 0, sizeof(*sap), &_service_access_point); if (sap && *sap == 0xFFFF) return htons(ETH_P_802_3); /* * Real 802.2 LLC */ return htons(ETH_P_802_2); }
/* This is necessary only for a number of stats, see the caller. */ static int il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header) { /* Filter incoming packets to determine if they are targeted toward * this network, discarding packets coming from ourselves */ switch (il->iw_mode) { case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ /* packets to our IBSS update information */ return ether_addr_equal_64bits(header->addr3, il->bssid); case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ /* packets to our IBSS update information */ return ether_addr_equal_64bits(header->addr2, il->bssid); default: return 1; } }
/* For sw LPS*/ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct ieee80211_hdr *hdr = data; struct ieee80211_tim_ie *tim_ie; u8 *tim; u8 tim_len; bool u_buffed; bool m_buffed; if (mac->opmode != NL80211_IFTYPE_STATION) return; if (!rtlpriv->psc.swctrl_lps) return; if (rtlpriv->mac80211.link_state != MAC80211_LINKED) return; if (!rtlpriv->psc.sw_ps_enabled) return; if (rtlpriv->psc.fwctrl_lps) return; if (likely(!(hw->conf.flags & IEEE80211_CONF_PS))) return; /* check if this really is a beacon */ if (!ieee80211_is_beacon(hdr->frame_control)) return; /* min. beacon length + FCS_LEN */ if (len <= 40 + FCS_LEN) return; /* and only beacons from the associated BSSID, please */ if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) return; rtlpriv->psc.last_beacon = jiffies; tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); if (!tim) return; if (tim[1] < sizeof(*tim_ie)) return; tim_len = tim[1]; tim_ie = (struct ieee80211_tim_ie *) &tim[2]; if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period)) rtlpriv->psc.dtim_counter = tim_ie->dtim_count; /* Check whenever the PHY can be turned off again. */ /* 1. What about buffered unicast traffic for our AID? */ u_buffed = ieee80211_check_tim(tim_ie, tim_len, rtlpriv->mac80211.assoc_id); /* 2. Maybe the AP wants to send multicast/broadcast data? */ m_buffed = tim_ie->bitmap_ctrl & 0x01; rtlpriv->psc.multi_buffered = m_buffed; /* unicast will process by mac80211 through * set ~IEEE80211_CONF_PS, So we just check * multicast frames here */ if (!m_buffed) { /* back to low-power land. and delay is * prevent null power save frame tx fail */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); } }
bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr) { return ieee80211_is_beacon(hdr->frame_control) && !is_zero_ether_addr(common->curbssid) && ether_addr_equal_64bits(hdr->addr3, common->curbssid); }