@@ -239,5 +239,8 @@ void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw,
struct sk_buff *skb);
void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
struct mt76_connac_pm *pm);
+int mt76_connac_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_offset,
+ struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif);
#endif /* __MT76_CONNAC_H */
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: ISC
/* Copyright (C) 2020 MediaTek Inc. */
+#include "mt76_connac_mac.h"
#include "mt76_connac.h"
int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)
@@ -115,3 +116,70 @@ void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
mt76_worker_schedule(&phy->dev->tx_worker);
}
EXPORT_SYMBOL_GPL(mt76_connac_pm_dequeue_skbs);
+
+/* The HW does not translate the mac header to 802.3 for mesh point */
+int mt76_connac_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_offset,
+ struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif)
+{
+ struct ethhdr *eth_hdr = (struct ethhdr *)(skb->data + hdr_offset);
+ __le32 *rxd = (__le32 *)skb->data;
+ struct ieee80211_hdr hdr;
+ __le32 qos_ctrl, ht_ctrl;
+
+ if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) !=
+ MT_RXD3_NORMAL_U2M)
+ return -EINVAL;
+
+ if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4))
+ return -EINVAL;
+
+ /* store the info from RXD and ethhdr to avoid being overridden */
+ hdr.frame_control = FIELD_GET(MT_RXD6_FRAME_CONTROL, rxd[6]);
+ hdr.seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, rxd[8]);
+ qos_ctrl = FIELD_GET(MT_RXD8_QOS_CTL, rxd[8]);
+ ht_ctrl = FIELD_GET(MT_RXD9_HT_CONTROL, rxd[9]);
+
+ hdr.duration_id = 0;
+ ether_addr_copy(hdr.addr1, vif->addr);
+ ether_addr_copy(hdr.addr2, sta->addr);
+ switch (le16_to_cpu(hdr.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_offset + 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 (eth_hdr->h_proto >= cpu_to_be16(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, 2), &ht_ctrl, 2);
+ if (ieee80211_is_data_qos(hdr.frame_control))
+ memcpy(skb_push(skb, 2), &qos_ctrl, 2);
+ 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;
+}
+EXPORT_SYMBOL_GPL(mt76_connac_reverse_frag0_hdr_trans);
@@ -387,80 +387,6 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u32 mode)
}
}
-/* The HW does not translate the mac header to 802.3 for mesh point */
-static int mt7915_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 mt7915_sta *msta = (struct mt7915_sta *)status->wcid;
- __le32 *rxd = (__le32 *)skb->data;
- struct ieee80211_sta *sta;
- struct ieee80211_vif *vif;
- struct ieee80211_hdr hdr;
- __le32 qos_ctrl, ht_ctrl;
-
- if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) !=
- 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 */
- hdr.frame_control = FIELD_GET(MT_RXD6_FRAME_CONTROL, rxd[6]);
- hdr.seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, rxd[8]);
- qos_ctrl = FIELD_GET(MT_RXD8_QOS_CTL, rxd[8]);
- ht_ctrl = FIELD_GET(MT_RXD9_HT_CONTROL, rxd[9]);
-
- hdr.duration_id = 0;
- ether_addr_copy(hdr.addr1, vif->addr);
- ether_addr_copy(hdr.addr2, sta->addr);
- switch (le16_to_cpu(hdr.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 (eth_hdr->h_proto >= cpu_to_be16(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, 2), &ht_ctrl, 2);
- if (ieee80211_is_data_qos(hdr.frame_control))
- memcpy(skb_push(skb, 2), &qos_ctrl, 2);
- 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
mt7915_mac_fill_rx_rate(struct mt7915_dev *dev,
struct mt76_rx_status *status,
@@ -781,8 +707,20 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad;
if (hdr_trans && ieee80211_has_morefrags(fc)) {
- if (mt7915_reverse_frag0_hdr_trans(skb, hdr_gap))
+ struct mt7915_sta *msta = (struct mt7915_sta *)status->wcid;
+ struct ieee80211_sta *sta;
+ struct ieee80211_vif *vif;
+
+ 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);
+ if (mt76_connac_reverse_frag0_hdr_trans(skb, hdr_gap, sta, vif))
return -EINVAL;
+
hdr_trans = false;
} else {
int pad_start = 0;
@@ -398,80 +398,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;
- __le32 qos_ctrl, ht_ctrl;
-
- if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) !=
- 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 */
- hdr.frame_control = FIELD_GET(MT_RXD6_FRAME_CONTROL, rxd[6]);
- hdr.seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, rxd[8]);
- qos_ctrl = FIELD_GET(MT_RXD8_QOS_CTL, rxd[8]);
- ht_ctrl = FIELD_GET(MT_RXD9_HT_CONTROL, rxd[9]);
-
- hdr.duration_id = 0;
- ether_addr_copy(hdr.addr1, vif->addr);
- ether_addr_copy(hdr.addr2, sta->addr);
- switch (le16_to_cpu(hdr.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 (eth_hdr->h_proto >= cpu_to_be16(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, 2), &ht_ctrl, 2);
- if (ieee80211_is_data_qos(hdr.frame_control))
- memcpy(skb_push(skb, 2), &qos_ctrl, 2);
- 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)
{
@@ -758,8 +684,20 @@ 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 mt7921_sta *msta = (struct mt7921_sta *)status->wcid;
+ struct ieee80211_sta *sta;
+ struct ieee80211_vif *vif;
+
+ 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);
+ if (mt76_connac_reverse_frag0_hdr_trans(skb, hdr_gap, sta, vif))
return -EINVAL;
+
hdr_trans = false;
} else {
skb_pull(skb, hdr_gap);
Move mt76_connac_reverse_frag0_hdr_trans in mt76-connac since it is shared between mt7921 and mt7915 drivers. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> --- .../net/wireless/mediatek/mt76/mt76_connac.h | 3 + .../wireless/mediatek/mt76/mt76_connac_mac.c | 68 ++++++++++++++ .../net/wireless/mediatek/mt76/mt7915/mac.c | 88 +++---------------- .../net/wireless/mediatek/mt76/mt7921/mac.c | 88 +++---------------- 4 files changed, 97 insertions(+), 150 deletions(-)