diff options
Diffstat (limited to 'rx.c')
-rw-r--r-- | rx.c | 123 |
1 files changed, 8 insertions, 115 deletions
@@ -280,24 +280,6 @@ static inline void mwl_rx_prepare_status(struct mwl_rx_desc *pdesc, } } -static inline void mwl_rx_enable_sta_amsdu(struct mwl_priv *priv, - u8 *sta_addr) -{ - struct mwl_sta *sta_info; - struct ieee80211_sta *sta; - - spin_lock_bh(&priv->sta_lock); - list_for_each_entry(sta_info, &priv->sta_list, list) { - sta = container_of((char *)sta_info, struct ieee80211_sta, - drv_priv[0]); - if (ether_addr_equal(sta->addr, sta_addr)) { - sta_info->is_amsdu_allowed = true; - break; - } - } - spin_unlock_bh(&priv->sta_lock); -} - static inline struct mwl_vif *mwl_rx_find_vif_bss(struct mwl_priv *priv, u8 *bssid) { @@ -336,78 +318,6 @@ static inline void mwl_rx_remove_dma_header(struct sk_buff *skb, __le16 qos) skb_pull(skb, sizeof(*tr) - hdrlen); } -#ifdef CONFIG_MAC80211_MESH -static inline bool mwl_rx_process_mesh_amsdu(struct mwl_priv *priv, - struct sk_buff *skb, - struct ieee80211_rx_status *status) -{ - struct ieee80211_hdr *wh; - struct mwl_sta *sta_info; - struct ieee80211_sta *sta; - u8 *qc; - int wh_len; - int len; - u8 pad; - u8 *data; - u16 frame_len; - struct sk_buff *newskb; - - wh = (struct ieee80211_hdr *)skb->data; - - spin_lock_bh(&priv->sta_lock); - list_for_each_entry(sta_info, &priv->sta_list, list) { - sta = container_of((char *)sta_info, struct ieee80211_sta, - drv_priv[0]); - if (ether_addr_equal(sta->addr, wh->addr2)) { - if (!sta_info->is_mesh_node) { - spin_unlock_bh(&priv->sta_lock); - return false; - } - } - } - spin_unlock_bh(&priv->sta_lock); - - qc = ieee80211_get_qos_ctl(wh); - *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; - - wh_len = ieee80211_hdrlen(wh->frame_control); - len = wh_len; - data = skb->data; - - while (len < skb->len) { - frame_len = *(u8 *)(data + len + ETH_HLEN - 1) | - (*(u8 *)(data + len + ETH_HLEN - 2) << 8); - - if ((len + ETH_HLEN + frame_len) > skb->len) - break; - - newskb = dev_alloc_skb(wh_len + frame_len); - if (!newskb) - break; - - ether_addr_copy(wh->addr3, data + len); - ether_addr_copy(wh->addr4, data + len + ETH_ALEN); - memcpy(newskb->data, wh, wh_len); - memcpy(newskb->data + wh_len, data + len + ETH_HLEN, frame_len); - skb_put(newskb, wh_len + frame_len); - - pad = ((ETH_HLEN + frame_len) % 4) ? - (4 - (ETH_HLEN + frame_len) % 4) : 0; - len += (ETH_HLEN + frame_len + pad); - if (len < skb->len) - status->flag |= RX_FLAG_AMSDU_MORE; - else - status->flag &= ~RX_FLAG_AMSDU_MORE; - memcpy(IEEE80211_SKB_RXCB(newskb), status, sizeof(*status)); - ieee80211_rx(priv->hw, newskb); - } - - dev_kfree_skb_any(skb); - - return true; -} -#endif - static int mwl_rx_refill(struct mwl_priv *priv, struct mwl_rx_hndl *rx_hndl) { struct mwl_desc_data *desc; @@ -584,34 +494,17 @@ void mwl_rx_recv(unsigned long data) wh = (struct ieee80211_hdr *)prx_skb->data; - if (ieee80211_is_mgmt(wh->frame_control)) { - struct ieee80211_mgmt *mgmt; - __le16 capab; - - mgmt = (struct ieee80211_mgmt *)prx_skb->data; - - if (unlikely(ieee80211_is_action(wh->frame_control) && - mgmt->u.action.category == - WLAN_CATEGORY_BACK && - mgmt->u.action.u.addba_resp.action_code == - WLAN_ACTION_ADDBA_RESP)) { - capab = mgmt->u.action.u.addba_resp.capab; - if (le16_to_cpu(capab) & 1) - mwl_rx_enable_sta_amsdu(priv, mgmt->sa); - } - } - -#ifdef CONFIG_MAC80211_MESH - if (ieee80211_is_data_qos(wh->frame_control) && - ieee80211_has_a4(wh->frame_control)) { + if (ieee80211_is_data_qos(wh->frame_control)) { + const u8 eapol[] = {0x88, 0x8e}; u8 *qc = ieee80211_get_qos_ctl(wh); + u8 *data; + + data = prx_skb->data + + ieee80211_hdrlen(wh->frame_control) + 6; - if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) - if (mwl_rx_process_mesh_amsdu(priv, prx_skb, - &status)) - goto out; + if (!memcmp(data, eapol, sizeof(eapol))) + *qc |= 7; } -#endif memcpy(IEEE80211_SKB_RXCB(prx_skb), &status, sizeof(status)); ieee80211_rx(hw, prx_skb); |