wifi: mt76: mt7921s: fix a potential firmware freeze during startup
authorLeon Yen <leon.yen@mediatek.com>
Mon, 16 Sep 2024 06:01:57 +0000 (14:01 +0800)
committerFelix Fietkau <nbd@nbd.name>
Mon, 13 Jan 2025 10:21:54 +0000 (11:21 +0100)
The maximum command quota of the firmware may be exceeded because the
command to retrieve the quota setting has not been taken into account.

This patch considers not only the quota usage of the command retrieving
quota settings but also limits the total quota usage.

Signed-off-by: Leon Yen <leon.yen@mediatek.com>
Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Link: https://patch.msgid.link/20240916060157.10157-1-mingyen.hsieh@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
drivers/net/wireless/mediatek/mt76/sdio_txrx.c

index ca2dba3ac65d57bdb5ed510041a6589e1902e57a..599123967af6111be0d865df6ffbafc794eadb76 100644 (file)
@@ -636,6 +636,7 @@ struct mt76_sdio {
        u8 hw_ver;
        wait_queue_head_t wait;
 
+       int pse_mcu_quota_max;
        struct {
                int pse_data_quota;
                int ple_data_quota;
index 02c1de8620a7f2a596c2353c60286b01f75a170d..ddc5986086d9a9c3fcbdcc9fb667b8cfb3c52bc7 100644 (file)
@@ -507,7 +507,10 @@ static void mt7921_mcu_parse_tx_resource(struct mt76_dev *dev,
 
        tx_res = (struct mt7921_tx_resource *)skb->data;
        sdio->sched.pse_data_quota = le32_to_cpu(tx_res->pse_data_quota);
-       sdio->sched.pse_mcu_quota = le32_to_cpu(tx_res->pse_mcu_quota);
+       sdio->pse_mcu_quota_max = le32_to_cpu(tx_res->pse_mcu_quota);
+       /* The mcu quota usage of this function itself must be taken into consideration */
+       sdio->sched.pse_mcu_quota =
+               sdio->sched.pse_mcu_quota ? sdio->pse_mcu_quota_max : sdio->pse_mcu_quota_max - 1;
        sdio->sched.ple_data_quota = le32_to_cpu(tx_res->ple_data_quota);
        sdio->sched.pse_page_size = le16_to_cpu(tx_res->pse_page_size);
        sdio->sched.deficit = tx_res->pp_padding;
index ddd8c0cc744df9b0bcd568c7aabf964b3aa5a027..0a927a7313a6ef738ff1527f1c52cbdd63145a52 100644 (file)
@@ -46,6 +46,10 @@ static int mt76s_refill_sched_quota(struct mt76_dev *dev, u32 *data)
                return 0;
 
        sdio->sched.pse_mcu_quota += pse_mcu_quota;
+       if (sdio->pse_mcu_quota_max &&
+           sdio->sched.pse_mcu_quota > sdio->pse_mcu_quota_max) {
+               sdio->sched.pse_mcu_quota = sdio->pse_mcu_quota_max;
+       }
        sdio->sched.pse_data_quota += pse_data_quota;
        sdio->sched.ple_data_quota += ple_data_quota;