diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7921/mac.c')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 95 |
1 files changed, 12 insertions, 83 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 4c2f62696b56..5b48a725e637 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -218,86 +218,6 @@ mt7921_mac_assoc_rssi(struct mt7921_dev *dev, struct sk_buff *skb) mt7921_mac_rssi_iter, skb); } -/* The HW does not translate the mac header to 802.3 for mesh point */ -static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) -{ - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - struct ethhdr *eth_hdr = (struct ethhdr *)(skb->data + hdr_gap); - struct mt7921_sta *msta = (struct mt7921_sta *)status->wcid; - __le32 *rxd = (__le32 *)skb->data; - struct ieee80211_sta *sta; - struct ieee80211_vif *vif; - struct ieee80211_hdr hdr; - u16 frame_control; - - if (le32_get_bits(rxd[3], MT_RXD3_NORMAL_ADDR_TYPE) != - MT_RXD3_NORMAL_U2M) - return -EINVAL; - - if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4)) - return -EINVAL; - - if (!msta || !msta->vif) - return -EINVAL; - - sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); - vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); - - /* store the info from RXD and ethhdr to avoid being overridden */ - frame_control = le32_get_bits(rxd[6], MT_RXD6_FRAME_CONTROL); - hdr.frame_control = cpu_to_le16(frame_control); - hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_SEQ_CTRL)); - hdr.duration_id = 0; - - ether_addr_copy(hdr.addr1, vif->addr); - ether_addr_copy(hdr.addr2, sta->addr); - switch (frame_control & (IEEE80211_FCTL_TODS | - IEEE80211_FCTL_FROMDS)) { - case 0: - ether_addr_copy(hdr.addr3, vif->bss_conf.bssid); - break; - case IEEE80211_FCTL_FROMDS: - ether_addr_copy(hdr.addr3, eth_hdr->h_source); - break; - case IEEE80211_FCTL_TODS: - ether_addr_copy(hdr.addr3, eth_hdr->h_dest); - break; - case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS: - ether_addr_copy(hdr.addr3, eth_hdr->h_dest); - ether_addr_copy(hdr.addr4, eth_hdr->h_source); - break; - default: - break; - } - - skb_pull(skb, hdr_gap + sizeof(struct ethhdr) - 2); - if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) || - eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX)) - ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header); - else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN) - ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header); - else - skb_pull(skb, 2); - - if (ieee80211_has_order(hdr.frame_control)) - memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[9], - IEEE80211_HT_CTL_LEN); - if (ieee80211_is_data_qos(hdr.frame_control)) { - __le16 qos_ctrl; - - qos_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_QOS_CTL)); - memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl, - IEEE80211_QOS_CTL_LEN); - } - - if (ieee80211_has_a4(hdr.frame_control)) - memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr)); - else - memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6); - - return 0; -} - static int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) { @@ -315,6 +235,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) u32 rxd2 = le32_to_cpu(rxd[2]); u32 rxd3 = le32_to_cpu(rxd[3]); u32 rxd4 = le32_to_cpu(rxd[4]); + struct mt7921_sta *msta; u16 seq_ctrl = 0; __le16 fc = 0; u32 mode = 0; @@ -345,8 +266,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) status->wcid = mt7921_rx_get_wcid(dev, idx, unicast); if (status->wcid) { - struct mt7921_sta *msta; - msta = container_of(status->wcid, struct mt7921_sta, wcid); spin_lock_bh(&dev->sta_poll_lock); if (list_empty(&msta->poll_list)) @@ -581,8 +500,18 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad; if (hdr_trans && ieee80211_has_morefrags(fc)) { - if (mt7921_reverse_frag0_hdr_trans(skb, hdr_gap)) + struct ieee80211_vif *vif; + int err; + + if (!msta || !msta->vif) return -EINVAL; + + vif = container_of((void *)msta->vif, struct ieee80211_vif, + drv_priv); + err = mt76_connac2_reverse_frag0_hdr_trans(vif, skb, hdr_gap); + if (err) + return err; + hdr_trans = false; } else { skb_pull(skb, hdr_gap); |