mt76: add support for 802.3 rx frames
Subsystems (2)
Felix Fietkau
maintainerPATCH 1/7 mt76: add support for 802.3 rx frames
Do not try to access the header when receiving them
--- drivers/net/wireless/mediatek/mt76/agg-rx.c | 13 ++++++----- drivers/net/wireless/mediatek/mt76/mac80211.c | 23 ++++++++++++++----- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- .../net/wireless/mediatek/mt76/mt7603/mac.c | 2 +- .../net/wireless/mediatek/mt76/mt7615/mac.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 4 +++- .../net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- .../net/wireless/mediatek/mt76/mt7921/mac.c | 2 +- 8 files changed, 32 insertions(+), 18 deletions(-)
drivers/net/wireless/mediatek/mt76/agg-rx.c +7 -6
@@ -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 ;
drivers/net/wireless/mediatek/mt76/mac80211.c +17 -6
@@ -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 ;
drivers/net/wireless/mediatek/mt76/mt76.h +1 -1
@@ -499,7 +499,7 @@ struct mt76_rx_status { u8 ext_phy:1; u8 aggr:1; -u8 tid; +u8 qos_ctl;u16 seqno;u16 freq;
drivers/net/wireless/mediatek/mt76/mt7603/mac.c +1 -1
@@ -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 ;
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +1 -1
@@ -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 ;
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +3 -1
@@ -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);
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +1 -1
@@ -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 ;
drivers/net/wireless/mediatek/mt76/mt7921/mac.c +1 -1
@@ -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 ;
Signature · 1 line
2.28.0
Felix Fietkau
maintainerPATCH 2/7 mt76: mt7915: enable hw rx-amsdu de-aggregation
From: Lorenzo Bianconi <[email protected]>
Enable hw rx-amsdu de-aggregation support available in 7915 devices. This is a preliminary patch to enable rx checksum offload
--- drivers/net/wireless/mediatek/mt76/mac80211.c | 55 ++++++++++++++++++- drivers/net/wireless/mediatek/mt76/mt76.h | 6 ++ .../net/wireless/mediatek/mt76/mt7915/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/mac.c | 16 +++++- .../net/wireless/mediatek/mt76/mt7915/mac.h | 4 ++ 5 files changed, 81 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mac80211.c +54 -1
@@ -508,6 +508,45 @@ void mt76_free_device(struct mt76_dev *dev) }EXPORT_SYMBOL_GPL (mt76_free_device); +static void mt76_rx_release_burst (struct mt76_dev *dev,enum mt76_rxq_id q, +struct sk_buff *skb) +{ +struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; +struct sk_buff *nskb = dev->rx_amsdu[q].head; + +/* first amsdu subframe */ +if (status->first_amsdu) { + dev->rx_amsdu[q].tail = &skb_shinfo (skb)->frag_list; + dev->rx_amsdu[q].seqno = status->seqno; + dev->rx_amsdu[q].head = skb; + goto enqueue; + } + +/* ampdu or out-of-order amsdu subframes */ +if (!status->amsdu || status->seqno != dev->rx_amsdu[q].seqno) { +/* release pending frames */ +if (dev->rx_amsdu[q].head) +__skb_queue_tail (&dev->rx_skb[q], + dev->rx_amsdu[q].head); + nskb = skb; + goto reset_burst; + } + +/* trailing amsdu subframes */ + *dev->rx_amsdu[q].tail = skb; +if (!status->last_amsdu) { + dev->rx_amsdu[q].tail = &skb->next; +return ; + } + +reset_burst: + dev->rx_amsdu[q].head =NULL ; + dev->rx_amsdu[q].tail =NULL ; +enqueue: +if (nskb) +__skb_queue_tail (&dev->rx_skb[q], nskb); +} +void mt76_rx (struct mt76_dev *dev,enum mt76_rxq_id q,struct sk_buff *skb) {struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
@@ -525,7 +564,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) phy->test.rx_stats.fcs_error[q]++; }#endif -__skb_queue_tail (&dev->rx_skb[q], skb); + +mt76_rx_release_burst (dev, q, skb); }EXPORT_SYMBOL_GPL (mt76_rx);
@@ -937,13 +977,26 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,spin_lock (&dev->rx_lock);while ((skb =__skb_dequeue (frames)) !=NULL ) { +struct sk_buff *nskb =skb_shinfo (skb)->frag_list; +if (mt76_check_ccmp_pn (skb)) {dev_kfree_skb (skb);continue ; } +skb_shinfo (skb)->frag_list =NULL ;mt76_rx_convert (dev, skb, &hw, &sta);ieee80211_rx_list (hw, sta, skb, &list); + +/* subsequent amsdu frames */ +while (nskb) { + skb = nskb; + nskb = nskb->next; + skb->next =NULL ; + +mt76_rx_convert (dev, skb, &hw, &sta); +ieee80211_rx_list (hw, sta, skb, &list); + } }spin_unlock (&dev->rx_lock);
drivers/net/wireless/mediatek/mt76/mt76.h +6 -0
@@ -507,6 +507,7 @@ struct mt76_rx_status {u8 enc_flags; u8 encoding:2, bw:3, he_ru:3; u8 he_gi:2, he_dcm:1; + u8 amsdu:1, first_amsdu:1, last_amsdu:1;u8 rate_idx;u8 nss;u8 band;
@@ -631,6 +632,11 @@ struct mt76_dev {spinlock_t rx_lock;struct napi_struct napi[__MT_RXQ_MAX];struct sk_buff_head rx_skb[__MT_RXQ_MAX]; +struct { +struct sk_buff *head; +struct sk_buff **tail; +u16 seqno; + } rx_amsdu[__MT_RXQ_MAX];struct list_head txwi_cache;struct mt76_queue *q_mcu[__MT_MCUQ_MAX];
drivers/net/wireless/mediatek/mt76/mt7915/init.c +2 -2
@@ -153,8 +153,8 @@ static void mt7915_mac_init(struct mt7915_dev *dev)int i;mt76_rmw_field (dev,MT_MDP_DCR1 ,MT_MDP_DCR1_MAX_RX_LEN ,1536 ); -/* disable hardware de-agg */ -mt76_clear (dev,MT_MDP_DCR0 ,MT_MDP_DCR0_DAMSDU_EN ); +/* enable hardware de-agg */ +mt76_set (dev,MT_MDP_DCR0 ,MT_MDP_DCR0_DAMSDU_EN );for (i =0 ; i <MT7915_WTBL_SIZE ; i++) mt7915_mac_wtbl_update(dev, i,
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +15 -1
@@ -320,8 +320,9 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)u32 rxd1 =le32_to_cpu (rxd[1 ]);u32 rxd2 =le32_to_cpu (rxd[2 ]);u32 rxd3 =le32_to_cpu (rxd[3 ]); +u32 rxd4 =le32_to_cpu (rxd[4 ]);bool unicast, insert_ccmp_hdr = false; -u8 remove_pad; +u8 remove_pad, amsdu_info;int i, idx;memset (status,0 ,sizeof (*status));
@@ -338,6 +339,9 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)if (!test_bit (MT76_STATE_RUNNING , &mphy->state))return -EINVAL ; +if (rxd2 &MT_RXD2_NORMAL_AMSDU_ERR ) +return -EINVAL ; + unicast =FIELD_GET (MT_RXD3_NORMAL_ADDR_TYPE , rxd3) ==MT_RXD3_NORMAL_U2M ; idx =FIELD_GET (MT_RXD1_NORMAL_WLAN_IDX , rxd1); status->wcid =mt7915_rx_get_wcid (dev, idx, unicast);
@@ -541,6 +545,16 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)skb_pull (skb, (u8 *)rxd - skb->data +2 * remove_pad); + amsdu_info =FIELD_GET (MT_RXD4_NORMAL_PAYLOAD_FORMAT , rxd4); + status->amsdu = !!amsdu_info; +if (status->amsdu) { + status->first_amsdu = amsdu_info ==MT_RXD4_FIRST_AMSDU_FRAME ; + status->last_amsdu = amsdu_info ==MT_RXD4_LAST_AMSDU_FRAME ; +memmove (skb->data +2 , skb->data, +ieee80211_get_hdrlen_from_skb (skb)); +skb_pull (skb,2 ); + } +if (insert_ccmp_hdr) {u8 key_id =FIELD_GET (MT_RXD1_NORMAL_KEY_ID , rxd1);
drivers/net/wireless/mediatek/mt76/mt7915/mac.h +4 -0
@@ -86,6 +86,10 @@ enum rx_pkt_type {/* RXD DW4 */ #define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0) +#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0) +#define MT_RXD4_MID_AMSDU_FRAME BIT(1) +#define MT_RXD4_LAST_AMSDU_FRAME BIT(0) +#define MT_RXD4_NORMAL_PATTERN_DROP BIT(9)#define MT_RXD4_NORMAL_CLS BIT(10)#define MT_RXD4_NORMAL_OFLD GENMASK(12, 11)
Signature · 1 line
2.28.0
Felix Fietkau
maintainerPATCH 3/7 mt76: mt7915: add rx checksum offload support
In reply to Felix FietkauSet skb->ip_summed to CHECKSUM_UNNECESSARY if the hardware has validated the IP and TCP/UDP checksum
--- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 1 + drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 5 +++++ 2 files changed, 6 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7915/init.c +1 -0
@@ -93,6 +93,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw) hw->queues =4 ; hw->max_rx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF ; hw->max_tx_aggregation_subframes =IEEE80211_MAX_AMPDU_BUF ; + hw->netdev_features =NETIF_F_RXCSUM ; phy->slottime =9 ;
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +5 -0
@@ -317,10 +317,12 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)__le32 *rxd = (__le32 *)skb->data;__le32 *rxv =NULL ;u32 mode =0 ; +u32 rxd0 =le32_to_cpu (rxd[0 ]);u32 rxd1 =le32_to_cpu (rxd[1 ]);u32 rxd2 =le32_to_cpu (rxd[2 ]);u32 rxd3 =le32_to_cpu (rxd[3 ]);u32 rxd4 =le32_to_cpu (rxd[4 ]); +u32 csum_mask =MT_RXD0_NORMAL_IP_SUM |MT_RXD0_NORMAL_UDP_TCP_SUM ;bool unicast, insert_ccmp_hdr = false;u8 remove_pad, amsdu_info;int i, idx;
@@ -366,6 +368,9 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)if (!sband->channels)return -EINVAL ; +if ((rxd0 & csum_mask) == csum_mask) + skb->ip_summed =CHECKSUM_UNNECESSARY ; +if (rxd1 &MT_RXD1_NORMAL_FCS_ERR ) status->flag |=RX_FLAG_FAILED_FCS_CRC ;
Signature · 1 line
2.28.0
Felix Fietkau
maintainerPATCH 4/7 mt76: mt7915: add support for rx decapsulation offload
In reply to Felix FietkauFor AP and Client mode, the hardware can pass received packets as 802.3 frames that can be passed to the network stack as-is.
--- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt7915/init.c | 1 + .../net/wireless/mediatek/mt76/mt7915/mac.c | 44 +++++++++++++++---- .../net/wireless/mediatek/mt76/mt7915/mac.h | 11 +++++ .../net/wireless/mediatek/mt76/mt7915/main.c | 21 ++++++++- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 25 +++++++++++ 6 files changed, 92 insertions(+), 11 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -0
@@ -197,6 +197,7 @@ enum mt76_wcid_flags {MT_WCID_FLAG_CHECK_PS ,MT_WCID_FLAG_PS ,MT_WCID_FLAG_4ADDR , + MT_WCID_FLAG_HDR_TRANS, };#define MT76_N_WCIDS 288
drivers/net/wireless/mediatek/mt76/mt7915/init.c +1 -0
@@ -109,6 +109,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)ieee80211_hw_set (hw,HAS_RATE_CONTROL );ieee80211_hw_set (hw,SUPPORTS_TX_ENCAP_OFFLOAD ); +ieee80211_hw_set (hw,SUPPORTS_RX_DECAP_OFFLOAD );ieee80211_hw_set (hw,WANT_MONITOR_VIF ); hw->max_tx_fragments =4 ;
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +35 -9
81 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7915/mac.h +11 -0
@@ -101,6 +101,17 @@ enum rx_pkt_type {#define MT_RXV_HDR_BAND_IDX BIT(24) +/* RXD GROUP4 */ +#define MT_RXD6_FRAME_CONTROL GENMASK(15, 0) +#define MT_RXD6_TA_LO GENMASK(31, 16) + +#define MT_RXD7_TA_HI GENMASK(31, 0) + +#define MT_RXD8_SEQ_CTRL GENMASK(15, 0) +#define MT_RXD8_QOS_CTL GENMASK(31, 16) + +#define MT_RXD9_HT_CONTROL GENMASK(31, 0) +/* P-RXV */ #define MT_PRXV_TX_RATE GENMASK(6, 0)#define MT_PRXV_TX_DCM BIT(4)
drivers/net/wireless/mediatek/mt76/mt7915/main.c +19 -2
@@ -34,14 +34,14 @@ static int mt7915_start(struct ieee80211_hw *hw)if (!running) {mt7915_mcu_set_pm (dev,0 ,0 ); -mt7915_mcu_set_mac (dev,0 , true, false); +mt7915_mcu_set_mac (dev,0 , true, true);mt7915_mcu_set_scs (dev,0 , true);mt7915_mac_enable_nf (dev,0 ); }if (phy != &dev->phy) {mt7915_mcu_set_pm (dev,1 ,0 ); -mt7915_mcu_set_mac (dev,1 , true, false); +mt7915_mcu_set_mac (dev,1 , true, true);mt7915_mcu_set_scs (dev,1 , true);mt7915_mac_enable_nf (dev,1 ); }
@@ -888,6 +888,22 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,mt7915_mcu_sta_update_hdr_trans (dev, vif, sta); } +static void mt7915_sta_set_decap_offload (struct ieee80211_hw *hw, +struct ieee80211_vif *vif, +struct ieee80211_sta *sta, +bool enabled) +{ +struct mt7915_dev *dev =mt7915_hw_dev (hw); +struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + +if (enabled) +set_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags); +else +clear_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags); + +mt7915_mcu_sta_update_hdr_trans (dev, vif, sta); +} +const struct ieee80211_ops mt7915_ops = { .tx = mt7915_tx, .start = mt7915_start,
@@ -920,6 +936,7 @@ const struct ieee80211_ops mt7915_ops = { .set_coverage_class = mt7915_set_coverage_class, .sta_statistics = mt7915_sta_statistics, .sta_set_4addr = mt7915_sta_set_4addr, + .sta_set_decap_offload = mt7915_sta_set_decap_offload, CFG80211_TESTMODE_CMD(mt76_testmode_cmd) CFG80211_TESTMODE_DUMP(mt76_testmode_dump)#ifdef CONFIG_MAC80211_DEBUGFS
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +25 -0
@@ -1685,6 +1685,7 @@ mt7915_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,return ; msta = (struct mt7915_sta *)sta->drv_priv; + htr->no_rx_trans = !test_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags);if (test_bit (MT_WCID_FLAG_4ADDR , &msta->wcid.flags)) { htr->to_ds = true; htr->from_ds = true;
@@ -2869,6 +2870,27 @@ void mt7915_mcu_exit(struct mt7915_dev *dev)skb_queue_purge (&dev->mt76.mcu.res_q); } +static int +mt7915_mcu_set_rx_hdr_trans_blacklist (struct mt7915_dev *dev,int band) +{ +struct { +u8 operation; +u8 count; +u8 _rsv[2 ]; +u8 index; +u8 enable; +__le16 etype; + } req = { + .operation =1 , + .count =1 , + .enable =1 , + .etype =cpu_to_le16 (ETH_P_PAE ), + }; + +return mt76_mcu_send_msg (&dev->mt76,MCU_EXT_CMD (RX_HDR_TRANS ), + &req,sizeof (req), false); +} +int mt7915_mcu_set_mac (struct mt7915_dev *dev,int band,bool enable,bool hdr_trans) {
@@ -2899,6 +2921,9 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band,if (ret)return ret; +if (hdr_trans) +mt7915_mcu_set_rx_hdr_trans_blacklist (dev, band); +return mt76_mcu_send_msg (&dev->mt76,MCU_EXT_CMD (MAC_INIT_CTRL ), &req_mac,sizeof (req_mac), true); }
Signature · 1 line
2.28.0
Felix Fietkau
maintainerPATCH 5/7 mt76: mt7615: fix key set/delete issues
In reply to Felix FietkauThere were multiple issues in the current key set/remove code:
- deleting a key with the previous key index deletes the current key
- BIP key would only be uploaded correctly initially and corrupted on rekey
Rework the code to better keep track of multiple keys and check for the key index before deleting the current key
--- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt7615/mac.c | 97 ++++++++++--------- .../net/wireless/mediatek/mt76/mt7615/main.c | 18 ++-- 3 files changed, 65 insertions(+), 51 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -0
@@ -223,6 +223,7 @@ struct mt76_wcid {u16 idx;u8 hw_key_idx; +u8 hw_key_idx2; u8 sta:1; u8 ext_phy:1;
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +53 -44
158 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7615/main.c +11 -7
@@ -337,7 +337,8 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,struct mt7615_sta *msta = sta ? (struct mt7615_sta *)sta->drv_priv : &mvif->sta;struct mt76_wcid *wcid = &msta->wcid; -int idx = key->keyidx, err; +int idx = key->keyidx, err =0 ; +u8 *wcid_keyidx = &wcid->hw_key_idx;/* The hardware does not support per-STA RX GTK, fallback * to software mode for these.
@@ -352,6 +353,7 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,/* fall back to sw encryption for unsupported ciphers */ switch (key->cipher) {case WLAN_CIPHER_SUITE_AES_CMAC : + wcid_keyidx = &wcid->hw_key_idx2; key->flags |=IEEE80211_KEY_FLAG_GENERATE_MMIE ;break ;case WLAN_CIPHER_SUITE_TKIP :
@@ -369,12 +371,13 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,mt7615_mutex_acquire (dev); -if (cmd ==SET_KEY ) { - key->hw_key_idx = wcid->idx; - wcid->hw_key_idx = idx; - }else if (idx == wcid->hw_key_idx) { - wcid->hw_key_idx =-1 ; - } +if (cmd ==SET_KEY ) + *wcid_keyidx = idx; +else if (idx == *wcid_keyidx) + *wcid_keyidx =-1 ; +else + goto out; +mt76_wcid_key_setup (&dev->mt76, wcid, cmd ==SET_KEY ? key :NULL );
@@ -383,6 +386,7 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,else err =__mt7615_mac_wtbl_set_key (dev, wcid, key, cmd); +out:mt7615_mutex_release (dev);return err;
Signature · 1 line
2.28.0
Felix Fietkau
maintainerPATCH 6/7 mt76: mt7615: fix tx skb dma unmap
In reply to Felix FietkauThe first pointer in the txp needs to be unmapped as well, otherwise it will leak DMA mapping entries
--- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +1 -1
@@ -690,7 +690,7 @@ mt7615_txp_skb_unmap_fw(struct mt76_dev *dev, struct mt7615_fw_txp *txp) {int i; -for (i =1 ; i < txp->nbuf; i++) +for (i =0 ; i < txp->nbuf; i++)dma_unmap_single (dev->dev,le32_to_cpu (txp->buf[i]),le16_to_cpu (txp->len[i]),DMA_TO_DEVICE ); }
Signature · 1 line
2.28.0
Felix Fietkau
maintainerPATCH 7/7 mt76: mt7915: fix tx skb dma unmap
In reply to Felix FietkauThe first pointer in the txp needs to be unmapped as well, otherwise it will leak DMA mapping entries
--- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +1 -1
@@ -1136,7 +1136,7 @@ void mt7915_txp_skb_unmap(struct mt76_dev *dev,int i; txp =mt7915_txwi_to_txp (dev, t); -for (i =1 ; i < txp->nbuf; i++) +for (i =0 ; i < txp->nbuf; i++)dma_unmap_single (dev->dev,le32_to_cpu (txp->buf[i]),le16_to_cpu (txp->len[i]),DMA_TO_DEVICE ); }
Signature · 1 line
2.28.0