OSDN Git Service

mt76: add support for 802.3 rx frames
authorFelix Fietkau <nbd@nbd.name>
Wed, 16 Dec 2020 15:05:51 +0000 (16:05 +0100)
committerFelix Fietkau <nbd@nbd.name>
Sun, 11 Apr 2021 16:50:37 +0000 (18:50 +0200)
Do not try to access the header when receiving them

Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/agg-rx.c
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7603/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/mt7921/mac.c

index df25c00..144e8a8 100644 (file)
@@ -122,6 +122,7 @@ mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
        struct ieee80211_bar *bar = mt76_skb_get_hdr(skb);
        struct mt76_wcid *wcid = status->wcid;
        struct mt76_rx_tid *tid;
+       u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
        u16 seqno;
 
        if (!ieee80211_is_ctl(bar->frame_control))
@@ -130,9 +131,9 @@ mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
        if (!ieee80211_is_back_req(bar->frame_control))
                return;
 
-       status->tid = le16_to_cpu(bar->control) >> 12;
+       status->qos_ctl = tidno = le16_to_cpu(bar->control) >> 12;
        seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(bar->start_seq_num));
-       tid = rcu_dereference(wcid->aggr[status->tid]);
+       tid = rcu_dereference(wcid->aggr[tidno]);
        if (!tid)
                return;
 
@@ -147,12 +148,12 @@ mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
 void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
 {
        struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
-       struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
        struct mt76_wcid *wcid = status->wcid;
        struct ieee80211_sta *sta;
        struct mt76_rx_tid *tid;
        bool sn_less;
        u16 seqno, head, size, idx;
+       u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
        u8 ackp;
 
        __skb_queue_tail(frames, skb);
@@ -161,18 +162,18 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
        if (!sta)
                return;
 
-       if (!status->aggr) {
+       if (!status->aggr && !(status->flag & RX_FLAG_8023)) {
                mt76_rx_aggr_check_ctl(skb, frames);
                return;
        }
 
        /* not part of a BA session */
-       ackp = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_ACK_POLICY_MASK;
+       ackp = status->qos_ctl & IEEE80211_QOS_CTL_ACK_POLICY_MASK;
        if (ackp != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
            ackp != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)
                return;
 
-       tid = rcu_dereference(wcid->aggr[status->tid]);
+       tid = rcu_dereference(wcid->aggr[tidno]);
        if (!tid)
                return;
 
index 696d00d..f9381bd 100644 (file)
@@ -737,6 +737,7 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
        struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
        struct mt76_wcid *wcid = status->wcid;
        struct ieee80211_hdr *hdr;
+       u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
        int ret;
 
        if (!(status->flag & RX_FLAG_DECRYPTED))
@@ -757,12 +758,12 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
        }
 
        BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0]));
-       ret = memcmp(status->iv, wcid->rx_key_pn[status->tid],
+       ret = memcmp(status->iv, wcid->rx_key_pn[tidno],
                     sizeof(status->iv));
        if (ret <= 0)
                return -EINVAL; /* replay */
 
-       memcpy(wcid->rx_key_pn[status->tid], status->iv, sizeof(status->iv));
+       memcpy(wcid->rx_key_pn[tidno], status->iv, sizeof(status->iv));
 
        if (status->flag & RX_FLAG_IV_STRIPPED)
                status->flag |= RX_FLAG_PN_VALIDATED;
@@ -785,6 +786,7 @@ mt76_airtime_report(struct mt76_dev *dev, struct mt76_rx_status *status,
        };
        struct ieee80211_sta *sta;
        u32 airtime;
+       u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
 
        airtime = ieee80211_calc_rx_airtime(dev->hw, &info, len);
        spin_lock(&dev->cc_lock);
@@ -795,7 +797,7 @@ mt76_airtime_report(struct mt76_dev *dev, struct mt76_rx_status *status,
                return;
 
        sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
-       ieee80211_sta_register_airtime(sta, status->tid, 0, airtime);
+       ieee80211_sta_register_airtime(sta, tidno, 0, airtime);
 }
 
 static void
@@ -823,7 +825,6 @@ mt76_airtime_flush_ampdu(struct mt76_dev *dev)
 static void
 mt76_airtime_check(struct mt76_dev *dev, struct sk_buff *skb)
 {
-       struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
        struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
        struct mt76_wcid *wcid = status->wcid;
 
@@ -831,6 +832,11 @@ mt76_airtime_check(struct mt76_dev *dev, struct sk_buff *skb)
                return;
 
        if (!wcid || !wcid->sta) {
+               struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
+
+               if (status->flag & RX_FLAG_8023)
+                       return;
+
                if (!ether_addr_equal(hdr->addr1, dev->phy.macaddr))
                        return;
 
@@ -864,10 +870,12 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
        struct ieee80211_sta *sta;
        struct ieee80211_hw *hw;
        struct mt76_wcid *wcid = status->wcid;
+       u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
        bool ps;
 
        hw = mt76_phy_hw(dev, status->ext_phy);
-       if (ieee80211_is_pspoll(hdr->frame_control) && !wcid) {
+       if (ieee80211_is_pspoll(hdr->frame_control) && !wcid &&
+           !(status->flag & RX_FLAG_8023)) {
                sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
                if (sta)
                        wcid = status->wcid = (struct mt76_wcid *)sta->drv_priv;
@@ -885,6 +893,9 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
 
        wcid->inactive_count = 0;
 
+       if (status->flag & RX_FLAG_8023)
+               return;
+
        if (!test_bit(MT_WCID_FLAG_CHECK_PS, &wcid->flags))
                return;
 
@@ -902,7 +913,7 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
 
        if (ps && (ieee80211_is_data_qos(hdr->frame_control) ||
                   ieee80211_is_qos_nullfunc(hdr->frame_control)))
-               ieee80211_sta_uapsd_trigger(sta, status->tid);
+               ieee80211_sta_uapsd_trigger(sta, tidno);
 
        if (!!test_bit(MT_WCID_FLAG_PS, &wcid->flags) == ps)
                return;
index 8bf4549..a3455e2 100644 (file)
@@ -499,7 +499,7 @@ struct mt76_rx_status {
 
        u8 ext_phy:1;
        u8 aggr:1;
-       u8 tid;
+       u8 qos_ctl;
        u16 seqno;
 
        u16 freq;
index cc4e7bc..c29b60a 100644 (file)
@@ -651,7 +651,7 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
 
        status->aggr = unicast &&
                       !ieee80211_is_qos_nullfunc(hdr->frame_control);
-       status->tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
+       status->qos_ctl = *ieee80211_get_qos_ctl(hdr);
        status->seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
 
        return 0;
index 59fdd0f..6a83556 100644 (file)
@@ -458,7 +458,7 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
 
        status->aggr = unicast &&
                       !ieee80211_is_qos_nullfunc(hdr->frame_control);
-       status->tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
+       status->qos_ctl = *ieee80211_get_qos_ctl(hdr);
        status->seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
 
        return 0;
index 771bad6..0da3786 100644 (file)
@@ -770,6 +770,7 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
                           void *rxi)
 {
        struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+       struct ieee80211_hdr *hdr;
        struct mt76x02_rxwi *rxwi = rxi;
        struct mt76x02_sta *sta;
        u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
@@ -864,7 +865,8 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
        status->freq = dev->mphy.chandef.chan->center_freq;
        status->band = dev->mphy.chandef.chan->band;
 
-       status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
+       hdr = (struct ieee80211_hdr *)skb->data;
+       status->qos_ctl = *ieee80211_get_qos_ctl(hdr);
        status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
 
        return mt76x02_mac_process_rate(dev, status, rate);
index e5a2589..63524b4 100644 (file)
@@ -556,7 +556,7 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
 
        status->aggr = unicast &&
                       !ieee80211_is_qos_nullfunc(hdr->frame_control);
-       status->tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
+       status->qos_ctl = *ieee80211_get_qos_ctl(hdr);
        status->seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
 
        return 0;
index 3f90974..9468c9c 100644 (file)
@@ -530,7 +530,7 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
 
        status->aggr = unicast &&
                       !ieee80211_is_qos_nullfunc(hdr->frame_control);
-       status->tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
+       status->qos_ctl = *ieee80211_get_qos_ctl(hdr);
        status->seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
 
        return 0;