diff mbox series

mt76: mt7921: fix network buffer leak by txs missing

Message ID 7f6efbd8e749b21bec2257c54b8258ebe89738fe.1638795555.git.deren.wu@mediatek.com (mailing list archive)
State New, archived
Headers show
Series mt76: mt7921: fix network buffer leak by txs missing | expand

Commit Message

Deren Wu Dec. 7, 2021, 5:04 p.m. UTC
From: Deren Wu <deren.wu@mediatek.com>

TXS in mt7921 may be forwared to tx_done event. Should try to catch
TXS information in tx_done event as well.

Signed-off-by: Deren Wu <deren.wu@mediatek.com>
---
 .../net/wireless/mediatek/mt76/mt7921/mac.c   |  2 +-
 .../net/wireless/mediatek/mt76/mt7921/mcu.c   | 17 ++++++++++++
 .../net/wireless/mediatek/mt76/mt7921/mcu.h   | 27 +++++++++++++++++++
 .../wireless/mediatek/mt76/mt7921/mt7921.h    |  1 +
 4 files changed, 46 insertions(+), 1 deletion(-)

Comments

Lorenzo Bianconi Dec. 7, 2021, 8:11 p.m. UTC | #1
> From: Deren Wu <deren.wu@mediatek.com>
> 
> TXS in mt7921 may be forwared to tx_done event. Should try to catch
> TXS information in tx_done event as well.
> 
> Signed-off-by: Deren Wu <deren.wu@mediatek.com>
> ---
>  .../net/wireless/mediatek/mt76/mt7921/mac.c   |  2 +-
>  .../net/wireless/mediatek/mt76/mt7921/mcu.c   | 17 ++++++++++++
>  .../net/wireless/mediatek/mt76/mt7921/mcu.h   | 27 +++++++++++++++++++
>  .../wireless/mediatek/mt76/mt7921/mt7921.h    |  1 +
>  4 files changed, 46 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> index edf54b192f37..2514708e9ac8 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> @@ -1150,7 +1150,7 @@ mt7921_mac_add_txs_skb(struct mt7921_dev *dev, struct mt76_wcid *wcid, int pid,
>  	return !!skb;
>  }
>  
> -static void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
> +void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
>  {
>  	struct mt7921_sta *msta = NULL;
>  	struct mt76_wcid *wcid;
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
> index 1227d626e9d3..8f58af4e29c6 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
> @@ -418,6 +418,20 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
>  	trace_lp_event(dev, event->state);
>  }
>  
> +static void
> +mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
> +{
> +	struct mt7921_mcu_tx_done_event *event;
> +
> +	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
> +	event = (struct mt7921_mcu_tx_done_event *)skb->data;
> +
> +	if (event->pid < MT_PACKET_ID_FIRST)
> +		return;

I guess we do not need it since it is already checked in mt7921_mac_add_txs

> +
> +	mt7921_mac_add_txs(dev, event->txs);
> +}
> +
>  static void
>  mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
>  {
> @@ -445,6 +459,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
>  	case MCU_EVENT_LP_INFO:
>  		mt7921_mcu_low_power_event(dev, skb);
>  		break;
> +	case MCU_EVENT_TX_DONE:
> +		mt7921_mcu_tx_done_event(dev, skb);
> +		break;
>  	default:
>  		break;
>  	}
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
> index edc0c73f8c01..821af6e8d99a 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
> @@ -91,6 +91,33 @@ enum {
>  	MCU_EVENT_COREDUMP = 0xf0,
>  };
>  
> +struct mt7921_mcu_tx_done_event {
> +	u8 pid;
> +	u8 status;
> +	u16 seq;
> +
> +	u8 wlan_idx;
> +	u8 tx_cnt;
> +	u16 tx_rate;

can you please fix endianness of mt7921_mcu_tx_done_event?

Regards,
Lorenzo

> +
> +	u8 flag;
> +	u8 tid;
> +	u8 rsp_rate;
> +	u8 mcs;
> +
> +	u8 bw;
> +	u8 tx_pwr;
> +	u8 reason;
> +	u8 rsv0[1];
> +
> +	u32 delay;
> +	u32 timestamp;
> +	u32 applied_flag;
> +	u8 txs[28];
> +
> +	u8 rsv1[32];
> +} __packed;
> +
>  /* ext event table */
>  enum {
>  	MCU_EXT_EVENT_RATE_REPORT = 0x87,
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> index d6b823713ba3..96647801850a 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> @@ -464,4 +464,5 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
>  			   struct mt76_tx_info *tx_info);
>  void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
>  bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
> +void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data);
>  #endif
> -- 
> 2.18.0
>
diff mbox series

Patch

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index edf54b192f37..2514708e9ac8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -1150,7 +1150,7 @@  mt7921_mac_add_txs_skb(struct mt7921_dev *dev, struct mt76_wcid *wcid, int pid,
 	return !!skb;
 }
 
-static void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
+void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
 {
 	struct mt7921_sta *msta = NULL;
 	struct mt76_wcid *wcid;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 1227d626e9d3..8f58af4e29c6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -418,6 +418,20 @@  mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
 	trace_lp_event(dev, event->state);
 }
 
+static void
+mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
+{
+	struct mt7921_mcu_tx_done_event *event;
+
+	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
+	event = (struct mt7921_mcu_tx_done_event *)skb->data;
+
+	if (event->pid < MT_PACKET_ID_FIRST)
+		return;
+
+	mt7921_mac_add_txs(dev, event->txs);
+}
+
 static void
 mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
 {
@@ -445,6 +459,9 @@  mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
 	case MCU_EVENT_LP_INFO:
 		mt7921_mcu_low_power_event(dev, skb);
 		break;
+	case MCU_EVENT_TX_DONE:
+		mt7921_mcu_tx_done_event(dev, skb);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
index edc0c73f8c01..821af6e8d99a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
@@ -91,6 +91,33 @@  enum {
 	MCU_EVENT_COREDUMP = 0xf0,
 };
 
+struct mt7921_mcu_tx_done_event {
+	u8 pid;
+	u8 status;
+	u16 seq;
+
+	u8 wlan_idx;
+	u8 tx_cnt;
+	u16 tx_rate;
+
+	u8 flag;
+	u8 tid;
+	u8 rsp_rate;
+	u8 mcs;
+
+	u8 bw;
+	u8 tx_pwr;
+	u8 reason;
+	u8 rsv0[1];
+
+	u32 delay;
+	u32 timestamp;
+	u32 applied_flag;
+	u8 txs[28];
+
+	u8 rsv1[32];
+} __packed;
+
 /* ext event table */
 enum {
 	MCU_EXT_EVENT_RATE_REPORT = 0x87,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index d6b823713ba3..96647801850a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -464,4 +464,5 @@  int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 			   struct mt76_tx_info *tx_info);
 void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
 bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
+void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data);
 #endif