* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
[not found] <YWcJe27HQMS7B85j@lore-desk--annotate>
@ 2021-10-13 17:56 ` sean.wang
0 siblings, 0 replies; 10+ messages in thread
From: sean.wang @ 2021-10-13 17:56 UTC (permalink / raw)
To: lorenzo.bianconi
Cc: nbd, sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Eric-SY.Chang,
Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu, Eddie.Chen, ch.yeh,
posh.sun, ted.huang, Eric.Liang, Stella.Chang, Tom.Chou,
steve.lee, jsiuda, frankgor, jemele, abhishekpandit, shawnku,
linux-wireless, linux-mediatek
From: Sean Wang <sean.wang@mediatek.com>
>> From: Sean Wang <sean.wang@mediatek.com>
>>
>> Extend sdio module to support CONNAC2 hw that mt7921s rely on.
>>
>> Tested-by: Deren Wu <deren.wu@mediatek.com>
>> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
>> Co-developed-by: Deren Wu <deren.wu@mediatek.com>
>> Signed-off-by: Deren Wu <deren.wu@mediatek.com>
>> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
>> ---
>> drivers/net/wireless/mediatek/mt76/mt76.h | 5 +-
>> .../net/wireless/mediatek/mt76/mt7615/sdio.c | 5 +-
>> drivers/net/wireless/mediatek/mt76/sdio.c | 23 ++++++-
>> drivers/net/wireless/mediatek/mt76/sdio.h | 50 ++++++++++++++-
>> .../net/wireless/mediatek/mt76/sdio_txrx.c | 62 ++++++++++++++++---
>> 5 files changed, 128 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h
>> b/drivers/net/wireless/mediatek/mt76/mt76.h
>> index e2f33956a122..06f0d1348d52 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
>> @@ -505,6 +505,8 @@ struct mt76_sdio {
>>
>> struct sdio_func *func;
>> void *intr_data;
>> + int intr_size;
>> + u8 hw_ver;
>>
>> struct {
>> int pse_data_quota;
>> @@ -1249,7 +1251,8 @@ int mt76s_alloc_queues(struct mt76_dev *dev);
>> void mt76s_deinit(struct mt76_dev *dev); void mt76s_sdio_irq(struct
>> sdio_func *func); void mt76s_txrx_worker(struct mt76_sdio *sdio);
>> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func);
>> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func,
>> + int hw_ver);
>> u32 mt76s_rr(struct mt76_dev *dev, u32 offset); void mt76s_wr(struct
>> mt76_dev *dev, u32 offset, u32 val);
>> u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> index f47e25f6dedb..a6b5d536d962 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> @@ -100,7 +100,7 @@ static int mt7663s_probe(struct sdio_func *func,
>> if (ret < 0)
>> goto error;
>>
>> - ret = mt76s_hw_init(mdev, func);
>> + ret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);
>> if (ret)
>> goto error;
>>
>> @@ -108,8 +108,9 @@ static int mt7663s_probe(struct sdio_func *func,
>> (mt76_rr(dev, MT_HW_REV) & 0xff);
>> dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
>>
>> + mdev->sdio.intr_size = sizeof(struct mt76_connac_sdio_intr);
>> mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
>> - sizeof(struct mt76s_intr),
>> + mdev->sdio.intr_size,
>> GFP_KERNEL);
>> if (!mdev->sdio.intr_data) {
>> ret = -ENOMEM;
>> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c
>> b/drivers/net/wireless/mediatek/mt76/sdio.c
>> index 82fb4c110b90..bb40cc3e9c2b 100644
>> --- a/drivers/net/wireless/mediatek/mt76/sdio.c
>> +++ b/drivers/net/wireless/mediatek/mt76/sdio.c
>> @@ -221,11 +221,13 @@ int mt76s_rd_rp(struct mt76_dev *dev, u32 base,
>> } EXPORT_SYMBOL_GPL(mt76s_rd_rp);
>>
>> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
>> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int
>> +hw_ver)
>> {
>> u32 status, ctrl;
>> int ret;
>>
>> + dev->sdio.hw_ver = hw_ver;
>> +
>> sdio_claim_host(func);
>>
>> ret = sdio_enable_func(func);
>> @@ -255,12 +257,27 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
>> goto disable_func;
>>
>> ctrl = WHIER_RX0_DONE_INT_EN | WHIER_TX_DONE_INT_EN;
>> + if (hw_ver == MT76_CONNAC2_SDIO)
>> + ctrl |= WHIER_RX1_DONE_INT_EN;
>> sdio_writel(func, ctrl, MCR_WHIER, &ret);
>> if (ret < 0)
>> goto disable_func;
>>
>> - /* set WHISR as read clear and Rx aggregation number as 16 */
>> - ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
>> + switch (hw_ver) {
>> + case MT76_CONNAC_SDIO:
>> + /* set WHISR as read clear and Rx aggregation number as 16 */
>> + ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
>> + break;
>> + default:
>> + ctrl = sdio_readl(func, MCR_WHCR, &ret);
>> + if (ret < 0)
>> + goto disable_func;
>> + ctrl &= ~MAX_HIF_RX_LEN_NUM_CONNAC2;
>> + ctrl &= ~W_INT_CLR_CTRL; /* read clear */
>> + ctrl |= FIELD_PREP(MAX_HIF_RX_LEN_NUM_CONNAC2, 0);
>> + break;
>> + }
>> +
>> sdio_writel(func, ctrl, MCR_WHCR, &ret);
>> if (ret < 0)
>> goto disable_func;
>> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.h
>> b/drivers/net/wireless/mediatek/mt76/sdio.h
>> index 03877d89e152..7d2ec044dcb1 100644
>> --- a/drivers/net/wireless/mediatek/mt76/sdio.h
>> +++ b/drivers/net/wireless/mediatek/mt76/sdio.h
>> @@ -21,7 +21,12 @@
>> #define MCR_WHCR 0x000C
>> #define W_INT_CLR_CTRL BIT(1)
>> #define RECV_MAILBOX_RD_CLR_EN BIT(2)
>> +#define WF_SYS_RSTB BIT(4) /* supported in CONNAC2 */
>> +#define WF_WHOLE_PATH_RSTB BIT(5) /* supported in CONNAC2 */
>> +#define WF_SDIO_WF_PATH_RSTB BIT(6) /* supported in CONNAC2 */
>> #define MAX_HIF_RX_LEN_NUM GENMASK(13, 8)
>> +#define MAX_HIF_RX_LEN_NUM_CONNAC2 GENMASK(14, 8) /* supported in CONNAC2 */
>> +#define WF_RST_DONE BIT(15) /* supported in CONNAC2 */
>> #define RX_ENHANCE_MODE BIT(16)
>>
>> #define MCR_WHISR 0x0010
>> @@ -29,6 +34,7 @@
>> #define WHIER_D2H_SW_INT GENMASK(31, 8)
>> #define WHIER_FW_OWN_BACK_INT_EN BIT(7)
>> #define WHIER_ABNORMAL_INT_EN BIT(6)
>> +#define WHIER_WDT_INT_EN BIT(5) /* supported in CONNAC2 */
>> #define WHIER_RX1_DONE_INT_EN BIT(2)
>> #define WHIER_RX0_DONE_INT_EN BIT(1)
>> #define WHIER_TX_DONE_INT_EN BIT(0)
>> @@ -100,7 +106,37 @@
>>
>> #define MCR_SWPCDBGR 0x0154
>>
>> -struct mt76s_intr {
>> +#define MCR_H2DSM2R 0x0160 /* supported in CONNAC2 */
>> +#define MCR_H2DSM3R 0x0164 /* supported in CONNAC2 */
>> +#define MCR_D2HRM3R 0x0174 /* supported in CONNAC2 */
>> +#define MCR_WTQCR8 0x0190 /* supported in CONNAC2 */
>> +#define MCR_WTQCR9 0x0194 /* supported in CONNAC2 */
>> +#define MCR_WTQCR10 0x0198 /* supported in CONNAC2 */
>> +#define MCR_WTQCR11 0x019C /* supported in CONNAC2 */
>> +#define MCR_WTQCR12 0x01A0 /* supported in CONNAC2 */
>> +#define MCR_WTQCR13 0x01A4 /* supported in CONNAC2 */
>> +#define MCR_WTQCR14 0x01A8 /* supported in CONNAC2 */
>> +#define MCR_WTQCR15 0x01AC /* supported in CONNAC2 */
>> +
>> +enum mt76_connac_sdio_ver {
>> + MT76_CONNAC_SDIO,
>> + MT76_CONNAC2_SDIO,
>> +};
>> +
>> +struct mt76_connac2_sdio_intr {
>> + u32 isr;
>> + struct {
>> + u32 wtqcr[16];
>> + } tx;
>> + struct {
>> + u16 num[2];
>> + u16 len0[16];
>> + u16 len1[128];
>> + } rx;
>> + u32 rec_mb[2];
>> +} __packed;
>> +
>> +struct mt76_connac_sdio_intr {
>> u32 isr;
>> struct {
>> u32 wtqcr[8];
>> @@ -112,4 +148,16 @@ struct mt76s_intr {
>> u32 rec_mb[2];
>> } __packed;
>>
>> +struct mt76s_intr {
>> + u32 isr;
>> + struct {
>> + u32 *wtqcr;
>> + } tx;
>> + struct {
>> + u16 num[2];
>> + u16 *len[2];
>> + } rx;
>> + u32 rec_mb[2];
>> +};
>> +
>> #endif
>> diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> index ceb3dc0613d6..73289a9845d7 100644
>> --- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> +++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> @@ -81,7 +81,7 @@ static int
>> mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
>> struct mt76s_intr *intr)
>> {
>> - struct mt76_queue *q = &dev->q_rx[qid];
>> + struct mt76_queue *q = &dev->q_rx[0];
>
>why qid is always 0 here?
>
In the current driver, we can see we only created one Rx queue (dev->q_rx with qid = 0)
in mt76s_alloc_queues for processing all incoming packets including MCU events and wifi packets.
And from the point of view of the device,
mt7663s use the hardware queue 0 for all MCU events and wifi packets;
mt7921s use the hardware queue 1 for all MCU events and wifi packets.
So if we don't remap from hardware queue 1 to dev->q_rx[0] for mt7921s to handle incoming packets,
we will get the kernel panic on accessing the invalid pointer on dev->q_rx[1].
Sean
>Regards,
>Lorenzo
>
<snip>
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
@ 2021-10-13 17:56 ` sean.wang
0 siblings, 0 replies; 10+ messages in thread
From: sean.wang @ 2021-10-13 17:56 UTC (permalink / raw)
To: lorenzo.bianconi
Cc: nbd, sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Eric-SY.Chang,
Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu, Eddie.Chen, ch.yeh,
posh.sun, ted.huang, Eric.Liang, Stella.Chang, Tom.Chou,
steve.lee, jsiuda, frankgor, jemele, abhishekpandit, shawnku,
linux-wireless, linux-mediatek
From: Sean Wang <sean.wang@mediatek.com>
>> From: Sean Wang <sean.wang@mediatek.com>
>>
>> Extend sdio module to support CONNAC2 hw that mt7921s rely on.
>>
>> Tested-by: Deren Wu <deren.wu@mediatek.com>
>> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
>> Co-developed-by: Deren Wu <deren.wu@mediatek.com>
>> Signed-off-by: Deren Wu <deren.wu@mediatek.com>
>> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
>> ---
>> drivers/net/wireless/mediatek/mt76/mt76.h | 5 +-
>> .../net/wireless/mediatek/mt76/mt7615/sdio.c | 5 +-
>> drivers/net/wireless/mediatek/mt76/sdio.c | 23 ++++++-
>> drivers/net/wireless/mediatek/mt76/sdio.h | 50 ++++++++++++++-
>> .../net/wireless/mediatek/mt76/sdio_txrx.c | 62 ++++++++++++++++---
>> 5 files changed, 128 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h
>> b/drivers/net/wireless/mediatek/mt76/mt76.h
>> index e2f33956a122..06f0d1348d52 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
>> @@ -505,6 +505,8 @@ struct mt76_sdio {
>>
>> struct sdio_func *func;
>> void *intr_data;
>> + int intr_size;
>> + u8 hw_ver;
>>
>> struct {
>> int pse_data_quota;
>> @@ -1249,7 +1251,8 @@ int mt76s_alloc_queues(struct mt76_dev *dev);
>> void mt76s_deinit(struct mt76_dev *dev); void mt76s_sdio_irq(struct
>> sdio_func *func); void mt76s_txrx_worker(struct mt76_sdio *sdio);
>> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func);
>> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func,
>> + int hw_ver);
>> u32 mt76s_rr(struct mt76_dev *dev, u32 offset); void mt76s_wr(struct
>> mt76_dev *dev, u32 offset, u32 val);
>> u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> index f47e25f6dedb..a6b5d536d962 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
>> @@ -100,7 +100,7 @@ static int mt7663s_probe(struct sdio_func *func,
>> if (ret < 0)
>> goto error;
>>
>> - ret = mt76s_hw_init(mdev, func);
>> + ret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);
>> if (ret)
>> goto error;
>>
>> @@ -108,8 +108,9 @@ static int mt7663s_probe(struct sdio_func *func,
>> (mt76_rr(dev, MT_HW_REV) & 0xff);
>> dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
>>
>> + mdev->sdio.intr_size = sizeof(struct mt76_connac_sdio_intr);
>> mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
>> - sizeof(struct mt76s_intr),
>> + mdev->sdio.intr_size,
>> GFP_KERNEL);
>> if (!mdev->sdio.intr_data) {
>> ret = -ENOMEM;
>> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c
>> b/drivers/net/wireless/mediatek/mt76/sdio.c
>> index 82fb4c110b90..bb40cc3e9c2b 100644
>> --- a/drivers/net/wireless/mediatek/mt76/sdio.c
>> +++ b/drivers/net/wireless/mediatek/mt76/sdio.c
>> @@ -221,11 +221,13 @@ int mt76s_rd_rp(struct mt76_dev *dev, u32 base,
>> } EXPORT_SYMBOL_GPL(mt76s_rd_rp);
>>
>> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
>> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int
>> +hw_ver)
>> {
>> u32 status, ctrl;
>> int ret;
>>
>> + dev->sdio.hw_ver = hw_ver;
>> +
>> sdio_claim_host(func);
>>
>> ret = sdio_enable_func(func);
>> @@ -255,12 +257,27 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
>> goto disable_func;
>>
>> ctrl = WHIER_RX0_DONE_INT_EN | WHIER_TX_DONE_INT_EN;
>> + if (hw_ver == MT76_CONNAC2_SDIO)
>> + ctrl |= WHIER_RX1_DONE_INT_EN;
>> sdio_writel(func, ctrl, MCR_WHIER, &ret);
>> if (ret < 0)
>> goto disable_func;
>>
>> - /* set WHISR as read clear and Rx aggregation number as 16 */
>> - ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
>> + switch (hw_ver) {
>> + case MT76_CONNAC_SDIO:
>> + /* set WHISR as read clear and Rx aggregation number as 16 */
>> + ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
>> + break;
>> + default:
>> + ctrl = sdio_readl(func, MCR_WHCR, &ret);
>> + if (ret < 0)
>> + goto disable_func;
>> + ctrl &= ~MAX_HIF_RX_LEN_NUM_CONNAC2;
>> + ctrl &= ~W_INT_CLR_CTRL; /* read clear */
>> + ctrl |= FIELD_PREP(MAX_HIF_RX_LEN_NUM_CONNAC2, 0);
>> + break;
>> + }
>> +
>> sdio_writel(func, ctrl, MCR_WHCR, &ret);
>> if (ret < 0)
>> goto disable_func;
>> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.h
>> b/drivers/net/wireless/mediatek/mt76/sdio.h
>> index 03877d89e152..7d2ec044dcb1 100644
>> --- a/drivers/net/wireless/mediatek/mt76/sdio.h
>> +++ b/drivers/net/wireless/mediatek/mt76/sdio.h
>> @@ -21,7 +21,12 @@
>> #define MCR_WHCR 0x000C
>> #define W_INT_CLR_CTRL BIT(1)
>> #define RECV_MAILBOX_RD_CLR_EN BIT(2)
>> +#define WF_SYS_RSTB BIT(4) /* supported in CONNAC2 */
>> +#define WF_WHOLE_PATH_RSTB BIT(5) /* supported in CONNAC2 */
>> +#define WF_SDIO_WF_PATH_RSTB BIT(6) /* supported in CONNAC2 */
>> #define MAX_HIF_RX_LEN_NUM GENMASK(13, 8)
>> +#define MAX_HIF_RX_LEN_NUM_CONNAC2 GENMASK(14, 8) /* supported in CONNAC2 */
>> +#define WF_RST_DONE BIT(15) /* supported in CONNAC2 */
>> #define RX_ENHANCE_MODE BIT(16)
>>
>> #define MCR_WHISR 0x0010
>> @@ -29,6 +34,7 @@
>> #define WHIER_D2H_SW_INT GENMASK(31, 8)
>> #define WHIER_FW_OWN_BACK_INT_EN BIT(7)
>> #define WHIER_ABNORMAL_INT_EN BIT(6)
>> +#define WHIER_WDT_INT_EN BIT(5) /* supported in CONNAC2 */
>> #define WHIER_RX1_DONE_INT_EN BIT(2)
>> #define WHIER_RX0_DONE_INT_EN BIT(1)
>> #define WHIER_TX_DONE_INT_EN BIT(0)
>> @@ -100,7 +106,37 @@
>>
>> #define MCR_SWPCDBGR 0x0154
>>
>> -struct mt76s_intr {
>> +#define MCR_H2DSM2R 0x0160 /* supported in CONNAC2 */
>> +#define MCR_H2DSM3R 0x0164 /* supported in CONNAC2 */
>> +#define MCR_D2HRM3R 0x0174 /* supported in CONNAC2 */
>> +#define MCR_WTQCR8 0x0190 /* supported in CONNAC2 */
>> +#define MCR_WTQCR9 0x0194 /* supported in CONNAC2 */
>> +#define MCR_WTQCR10 0x0198 /* supported in CONNAC2 */
>> +#define MCR_WTQCR11 0x019C /* supported in CONNAC2 */
>> +#define MCR_WTQCR12 0x01A0 /* supported in CONNAC2 */
>> +#define MCR_WTQCR13 0x01A4 /* supported in CONNAC2 */
>> +#define MCR_WTQCR14 0x01A8 /* supported in CONNAC2 */
>> +#define MCR_WTQCR15 0x01AC /* supported in CONNAC2 */
>> +
>> +enum mt76_connac_sdio_ver {
>> + MT76_CONNAC_SDIO,
>> + MT76_CONNAC2_SDIO,
>> +};
>> +
>> +struct mt76_connac2_sdio_intr {
>> + u32 isr;
>> + struct {
>> + u32 wtqcr[16];
>> + } tx;
>> + struct {
>> + u16 num[2];
>> + u16 len0[16];
>> + u16 len1[128];
>> + } rx;
>> + u32 rec_mb[2];
>> +} __packed;
>> +
>> +struct mt76_connac_sdio_intr {
>> u32 isr;
>> struct {
>> u32 wtqcr[8];
>> @@ -112,4 +148,16 @@ struct mt76s_intr {
>> u32 rec_mb[2];
>> } __packed;
>>
>> +struct mt76s_intr {
>> + u32 isr;
>> + struct {
>> + u32 *wtqcr;
>> + } tx;
>> + struct {
>> + u16 num[2];
>> + u16 *len[2];
>> + } rx;
>> + u32 rec_mb[2];
>> +};
>> +
>> #endif
>> diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> index ceb3dc0613d6..73289a9845d7 100644
>> --- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> +++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
>> @@ -81,7 +81,7 @@ static int
>> mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
>> struct mt76s_intr *intr)
>> {
>> - struct mt76_queue *q = &dev->q_rx[qid];
>> + struct mt76_queue *q = &dev->q_rx[0];
>
>why qid is always 0 here?
>
In the current driver, we can see we only created one Rx queue (dev->q_rx with qid = 0)
in mt76s_alloc_queues for processing all incoming packets including MCU events and wifi packets.
And from the point of view of the device,
mt7663s use the hardware queue 0 for all MCU events and wifi packets;
mt7921s use the hardware queue 1 for all MCU events and wifi packets.
So if we don't remap from hardware queue 1 to dev->q_rx[0] for mt7921s to handle incoming packets,
we will get the kernel panic on accessing the invalid pointer on dev->q_rx[1].
Sean
>Regards,
>Lorenzo
>
<snip>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
2021-10-13 17:56 ` sean.wang
@ 2021-10-13 19:06 ` Lorenzo Bianconi
-1 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2021-10-13 19:06 UTC (permalink / raw)
To: sean.wang
Cc: lorenzo.bianconi, nbd, Soul.Huang, YN.Chen, Leon.Yen,
Eric-SY.Chang, Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu,
Eddie.Chen, ch.yeh, posh.sun, ted.huang, Eric.Liang,
Stella.Chang, Tom.Chou, steve.lee, jsiuda, frankgor, jemele,
abhishekpandit, shawnku, linux-wireless, linux-mediatek
[-- Attachment #1: Type: text/plain, Size: 3533 bytes --]
[...]
>
> In the current driver, we can see we only created one Rx queue (dev->q_rx with qid = 0)
> in mt76s_alloc_queues for processing all incoming packets including MCU events and wifi packets.
>
> And from the point of view of the device,
> mt7663s use the hardware queue 0 for all MCU events and wifi packets;
> mt7921s use the hardware queue 1 for all MCU events and wifi packets.
>
> So if we don't remap from hardware queue 1 to dev->q_rx[0] for mt7921s to handle incoming packets,
> we will get the kernel panic on accessing the invalid pointer on dev->q_rx[1].
>
> Sean
>
> >Regards,
> >Lorenzo
> >
>
> <snip>
ok, what about doing something like the patch below?
If it works for you, I will post a formal patch.
Regards,
Lorenzo
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 792573dad2e1..25524a21dffa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1254,7 +1254,8 @@ void mt76u_queues_deinit(struct mt76_dev *dev);
int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
const struct mt76_bus_ops *bus_ops);
-int mt76s_alloc_queues(struct mt76_dev *dev);
+int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid);
+int mt76s_alloc_tx(struct mt76_dev *dev);
void mt76s_deinit(struct mt76_dev *dev);
void mt76s_sdio_irq(struct sdio_func *func);
void mt76s_txrx_worker(struct mt76_sdio *sdio);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index c3bd163e0278..577561aaee31 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -147,7 +147,11 @@ static int mt7663s_probe(struct sdio_func *func,
}
}
- ret = mt76s_alloc_queues(&dev->mt76);
+ ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MAIN);
+ if (ret < 0)
+ goto error;
+
+ ret = mt76s_alloc_tx(mdev);
if (ret)
goto error;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index bb40cc3e9c2b..c99acc21225e 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -299,8 +299,7 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)
}
EXPORT_SYMBOL_GPL(mt76s_hw_init);
-static int
-mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
+int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
{
struct mt76_queue *q = &dev->q_rx[qid];
@@ -317,6 +316,7 @@ mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
return 0;
}
+EXPORT_SYMBOL_GPL(mt76s_alloc_rx_queue);
static struct mt76_queue *mt76s_alloc_tx_queue(struct mt76_dev *dev)
{
@@ -338,7 +338,7 @@ static struct mt76_queue *mt76s_alloc_tx_queue(struct mt76_dev *dev)
return q;
}
-static int mt76s_alloc_tx(struct mt76_dev *dev)
+int mt76s_alloc_tx(struct mt76_dev *dev)
{
struct mt76_queue *q;
int i;
@@ -361,18 +361,7 @@ static int mt76s_alloc_tx(struct mt76_dev *dev)
return 0;
}
-
-int mt76s_alloc_queues(struct mt76_dev *dev)
-{
- int err;
-
- err = mt76s_alloc_rx_queue(dev, MT_RXQ_MAIN);
- if (err < 0)
- return err;
-
- return mt76s_alloc_tx(dev);
-}
-EXPORT_SYMBOL_GPL(mt76s_alloc_queues);
+EXPORT_SYMBOL_GPL(mt76s_alloc_tx);
static struct mt76_queue_entry *
mt76s_get_next_rx_entry(struct mt76_queue *q)
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
@ 2021-10-13 19:06 ` Lorenzo Bianconi
0 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2021-10-13 19:06 UTC (permalink / raw)
To: sean.wang
Cc: lorenzo.bianconi, nbd, Soul.Huang, YN.Chen, Leon.Yen,
Eric-SY.Chang, Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu,
Eddie.Chen, ch.yeh, posh.sun, ted.huang, Eric.Liang,
Stella.Chang, Tom.Chou, steve.lee, jsiuda, frankgor, jemele,
abhishekpandit, shawnku, linux-wireless, linux-mediatek
[-- Attachment #1.1: Type: text/plain, Size: 3533 bytes --]
[...]
>
> In the current driver, we can see we only created one Rx queue (dev->q_rx with qid = 0)
> in mt76s_alloc_queues for processing all incoming packets including MCU events and wifi packets.
>
> And from the point of view of the device,
> mt7663s use the hardware queue 0 for all MCU events and wifi packets;
> mt7921s use the hardware queue 1 for all MCU events and wifi packets.
>
> So if we don't remap from hardware queue 1 to dev->q_rx[0] for mt7921s to handle incoming packets,
> we will get the kernel panic on accessing the invalid pointer on dev->q_rx[1].
>
> Sean
>
> >Regards,
> >Lorenzo
> >
>
> <snip>
ok, what about doing something like the patch below?
If it works for you, I will post a formal patch.
Regards,
Lorenzo
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 792573dad2e1..25524a21dffa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1254,7 +1254,8 @@ void mt76u_queues_deinit(struct mt76_dev *dev);
int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
const struct mt76_bus_ops *bus_ops);
-int mt76s_alloc_queues(struct mt76_dev *dev);
+int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid);
+int mt76s_alloc_tx(struct mt76_dev *dev);
void mt76s_deinit(struct mt76_dev *dev);
void mt76s_sdio_irq(struct sdio_func *func);
void mt76s_txrx_worker(struct mt76_sdio *sdio);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index c3bd163e0278..577561aaee31 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -147,7 +147,11 @@ static int mt7663s_probe(struct sdio_func *func,
}
}
- ret = mt76s_alloc_queues(&dev->mt76);
+ ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MAIN);
+ if (ret < 0)
+ goto error;
+
+ ret = mt76s_alloc_tx(mdev);
if (ret)
goto error;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index bb40cc3e9c2b..c99acc21225e 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -299,8 +299,7 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)
}
EXPORT_SYMBOL_GPL(mt76s_hw_init);
-static int
-mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
+int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
{
struct mt76_queue *q = &dev->q_rx[qid];
@@ -317,6 +316,7 @@ mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
return 0;
}
+EXPORT_SYMBOL_GPL(mt76s_alloc_rx_queue);
static struct mt76_queue *mt76s_alloc_tx_queue(struct mt76_dev *dev)
{
@@ -338,7 +338,7 @@ static struct mt76_queue *mt76s_alloc_tx_queue(struct mt76_dev *dev)
return q;
}
-static int mt76s_alloc_tx(struct mt76_dev *dev)
+int mt76s_alloc_tx(struct mt76_dev *dev)
{
struct mt76_queue *q;
int i;
@@ -361,18 +361,7 @@ static int mt76s_alloc_tx(struct mt76_dev *dev)
return 0;
}
-
-int mt76s_alloc_queues(struct mt76_dev *dev)
-{
- int err;
-
- err = mt76s_alloc_rx_queue(dev, MT_RXQ_MAIN);
- if (err < 0)
- return err;
-
- return mt76s_alloc_tx(dev);
-}
-EXPORT_SYMBOL_GPL(mt76s_alloc_queues);
+EXPORT_SYMBOL_GPL(mt76s_alloc_tx);
static struct mt76_queue_entry *
mt76s_get_next_rx_entry(struct mt76_queue *q)
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 170 bytes --]
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
[not found] <YWcuGcFPGCtaPh+2@lore-desk--annotate>
@ 2021-10-13 21:22 ` sean.wang
0 siblings, 0 replies; 10+ messages in thread
From: sean.wang @ 2021-10-13 21:22 UTC (permalink / raw)
To: lorenzo.bianconi
Cc: nbd, sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Eric-SY.Chang,
Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu, Eddie.Chen, ch.yeh,
posh.sun, ted.huang, Eric.Liang, Stella.Chang, Tom.Chou,
steve.lee, jsiuda, frankgor, jemele, abhishekpandit, shawnku,
linux-wireless, linux-mediatek
From: Sean Wang <sean.wang@mediatek.com>
>[...]
>>
>> In the current driver, we can see we only created one Rx queue
>> (dev->q_rx with qid = 0) in mt76s_alloc_queues for processing all incoming packets including MCU events and wifi packets.
>>
>> And from the point of view of the device, mt7663s use the hardware
>> queue 0 for all MCU events and wifi packets; mt7921s use the hardware
>> queue 1 for all MCU events and wifi packets.
>>
>> So if we don't remap from hardware queue 1 to dev->q_rx[0] for mt7921s
>> to handle incoming packets, we will get the kernel panic on accessing the invalid pointer on dev->q_rx[1].
>>
>> Sean
>>
>> >Regards,
>> >Lorenzo
>> >
>>
>> <snip>
>
>ok, what about doing something like the patch below?
>If it works for you, I will post a formal patch.
go ahead. that looks fine to me.
>
>Regards,
>Lorenzo
>
<snip>
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
@ 2021-10-13 21:22 ` sean.wang
0 siblings, 0 replies; 10+ messages in thread
From: sean.wang @ 2021-10-13 21:22 UTC (permalink / raw)
To: lorenzo.bianconi
Cc: nbd, sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Eric-SY.Chang,
Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu, Eddie.Chen, ch.yeh,
posh.sun, ted.huang, Eric.Liang, Stella.Chang, Tom.Chou,
steve.lee, jsiuda, frankgor, jemele, abhishekpandit, shawnku,
linux-wireless, linux-mediatek
From: Sean Wang <sean.wang@mediatek.com>
>[...]
>>
>> In the current driver, we can see we only created one Rx queue
>> (dev->q_rx with qid = 0) in mt76s_alloc_queues for processing all incoming packets including MCU events and wifi packets.
>>
>> And from the point of view of the device, mt7663s use the hardware
>> queue 0 for all MCU events and wifi packets; mt7921s use the hardware
>> queue 1 for all MCU events and wifi packets.
>>
>> So if we don't remap from hardware queue 1 to dev->q_rx[0] for mt7921s
>> to handle incoming packets, we will get the kernel panic on accessing the invalid pointer on dev->q_rx[1].
>>
>> Sean
>>
>> >Regards,
>> >Lorenzo
>> >
>>
>> <snip>
>
>ok, what about doing something like the patch below?
>If it works for you, I will post a formal patch.
go ahead. that looks fine to me.
>
>Regards,
>Lorenzo
>
<snip>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
2021-10-12 22:52 ` sean.wang
@ 2021-10-13 16:29 ` Lorenzo Bianconi
-1 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2021-10-13 16:29 UTC (permalink / raw)
To: sean.wang
Cc: nbd, lorenzo.bianconi, Soul.Huang, YN.Chen, Leon.Yen,
Eric-SY.Chang, Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu,
Eddie.Chen, ch.yeh, posh.sun, ted.huang, Eric.Liang,
Stella.Chang, Tom.Chou, steve.lee, jsiuda, frankgor, jemele,
abhishekpandit, shawnku, linux-wireless, linux-mediatek
[-- Attachment #1: Type: text/plain, Size: 10895 bytes --]
> From: Sean Wang <sean.wang@mediatek.com>
>
> Extend sdio module to support CONNAC2 hw that mt7921s rely on.
>
> Tested-by: Deren Wu <deren.wu@mediatek.com>
> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Co-developed-by: Deren Wu <deren.wu@mediatek.com>
> Signed-off-by: Deren Wu <deren.wu@mediatek.com>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> ---
> drivers/net/wireless/mediatek/mt76/mt76.h | 5 +-
> .../net/wireless/mediatek/mt76/mt7615/sdio.c | 5 +-
> drivers/net/wireless/mediatek/mt76/sdio.c | 23 ++++++-
> drivers/net/wireless/mediatek/mt76/sdio.h | 50 ++++++++++++++-
> .../net/wireless/mediatek/mt76/sdio_txrx.c | 62 ++++++++++++++++---
> 5 files changed, 128 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index e2f33956a122..06f0d1348d52 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -505,6 +505,8 @@ struct mt76_sdio {
>
> struct sdio_func *func;
> void *intr_data;
> + int intr_size;
> + u8 hw_ver;
>
> struct {
> int pse_data_quota;
> @@ -1249,7 +1251,8 @@ int mt76s_alloc_queues(struct mt76_dev *dev);
> void mt76s_deinit(struct mt76_dev *dev);
> void mt76s_sdio_irq(struct sdio_func *func);
> void mt76s_txrx_worker(struct mt76_sdio *sdio);
> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func);
> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func,
> + int hw_ver);
> u32 mt76s_rr(struct mt76_dev *dev, u32 offset);
> void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val);
> u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
> index f47e25f6dedb..a6b5d536d962 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
> @@ -100,7 +100,7 @@ static int mt7663s_probe(struct sdio_func *func,
> if (ret < 0)
> goto error;
>
> - ret = mt76s_hw_init(mdev, func);
> + ret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);
> if (ret)
> goto error;
>
> @@ -108,8 +108,9 @@ static int mt7663s_probe(struct sdio_func *func,
> (mt76_rr(dev, MT_HW_REV) & 0xff);
> dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
>
> + mdev->sdio.intr_size = sizeof(struct mt76_connac_sdio_intr);
> mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
> - sizeof(struct mt76s_intr),
> + mdev->sdio.intr_size,
> GFP_KERNEL);
> if (!mdev->sdio.intr_data) {
> ret = -ENOMEM;
> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
> index 82fb4c110b90..bb40cc3e9c2b 100644
> --- a/drivers/net/wireless/mediatek/mt76/sdio.c
> +++ b/drivers/net/wireless/mediatek/mt76/sdio.c
> @@ -221,11 +221,13 @@ int mt76s_rd_rp(struct mt76_dev *dev, u32 base,
> }
> EXPORT_SYMBOL_GPL(mt76s_rd_rp);
>
> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)
> {
> u32 status, ctrl;
> int ret;
>
> + dev->sdio.hw_ver = hw_ver;
> +
> sdio_claim_host(func);
>
> ret = sdio_enable_func(func);
> @@ -255,12 +257,27 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
> goto disable_func;
>
> ctrl = WHIER_RX0_DONE_INT_EN | WHIER_TX_DONE_INT_EN;
> + if (hw_ver == MT76_CONNAC2_SDIO)
> + ctrl |= WHIER_RX1_DONE_INT_EN;
> sdio_writel(func, ctrl, MCR_WHIER, &ret);
> if (ret < 0)
> goto disable_func;
>
> - /* set WHISR as read clear and Rx aggregation number as 16 */
> - ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
> + switch (hw_ver) {
> + case MT76_CONNAC_SDIO:
> + /* set WHISR as read clear and Rx aggregation number as 16 */
> + ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
> + break;
> + default:
> + ctrl = sdio_readl(func, MCR_WHCR, &ret);
> + if (ret < 0)
> + goto disable_func;
> + ctrl &= ~MAX_HIF_RX_LEN_NUM_CONNAC2;
> + ctrl &= ~W_INT_CLR_CTRL; /* read clear */
> + ctrl |= FIELD_PREP(MAX_HIF_RX_LEN_NUM_CONNAC2, 0);
> + break;
> + }
> +
> sdio_writel(func, ctrl, MCR_WHCR, &ret);
> if (ret < 0)
> goto disable_func;
> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.h b/drivers/net/wireless/mediatek/mt76/sdio.h
> index 03877d89e152..7d2ec044dcb1 100644
> --- a/drivers/net/wireless/mediatek/mt76/sdio.h
> +++ b/drivers/net/wireless/mediatek/mt76/sdio.h
> @@ -21,7 +21,12 @@
> #define MCR_WHCR 0x000C
> #define W_INT_CLR_CTRL BIT(1)
> #define RECV_MAILBOX_RD_CLR_EN BIT(2)
> +#define WF_SYS_RSTB BIT(4) /* supported in CONNAC2 */
> +#define WF_WHOLE_PATH_RSTB BIT(5) /* supported in CONNAC2 */
> +#define WF_SDIO_WF_PATH_RSTB BIT(6) /* supported in CONNAC2 */
> #define MAX_HIF_RX_LEN_NUM GENMASK(13, 8)
> +#define MAX_HIF_RX_LEN_NUM_CONNAC2 GENMASK(14, 8) /* supported in CONNAC2 */
> +#define WF_RST_DONE BIT(15) /* supported in CONNAC2 */
> #define RX_ENHANCE_MODE BIT(16)
>
> #define MCR_WHISR 0x0010
> @@ -29,6 +34,7 @@
> #define WHIER_D2H_SW_INT GENMASK(31, 8)
> #define WHIER_FW_OWN_BACK_INT_EN BIT(7)
> #define WHIER_ABNORMAL_INT_EN BIT(6)
> +#define WHIER_WDT_INT_EN BIT(5) /* supported in CONNAC2 */
> #define WHIER_RX1_DONE_INT_EN BIT(2)
> #define WHIER_RX0_DONE_INT_EN BIT(1)
> #define WHIER_TX_DONE_INT_EN BIT(0)
> @@ -100,7 +106,37 @@
>
> #define MCR_SWPCDBGR 0x0154
>
> -struct mt76s_intr {
> +#define MCR_H2DSM2R 0x0160 /* supported in CONNAC2 */
> +#define MCR_H2DSM3R 0x0164 /* supported in CONNAC2 */
> +#define MCR_D2HRM3R 0x0174 /* supported in CONNAC2 */
> +#define MCR_WTQCR8 0x0190 /* supported in CONNAC2 */
> +#define MCR_WTQCR9 0x0194 /* supported in CONNAC2 */
> +#define MCR_WTQCR10 0x0198 /* supported in CONNAC2 */
> +#define MCR_WTQCR11 0x019C /* supported in CONNAC2 */
> +#define MCR_WTQCR12 0x01A0 /* supported in CONNAC2 */
> +#define MCR_WTQCR13 0x01A4 /* supported in CONNAC2 */
> +#define MCR_WTQCR14 0x01A8 /* supported in CONNAC2 */
> +#define MCR_WTQCR15 0x01AC /* supported in CONNAC2 */
> +
> +enum mt76_connac_sdio_ver {
> + MT76_CONNAC_SDIO,
> + MT76_CONNAC2_SDIO,
> +};
> +
> +struct mt76_connac2_sdio_intr {
> + u32 isr;
> + struct {
> + u32 wtqcr[16];
> + } tx;
> + struct {
> + u16 num[2];
> + u16 len0[16];
> + u16 len1[128];
> + } rx;
> + u32 rec_mb[2];
> +} __packed;
> +
> +struct mt76_connac_sdio_intr {
> u32 isr;
> struct {
> u32 wtqcr[8];
> @@ -112,4 +148,16 @@ struct mt76s_intr {
> u32 rec_mb[2];
> } __packed;
>
> +struct mt76s_intr {
> + u32 isr;
> + struct {
> + u32 *wtqcr;
> + } tx;
> + struct {
> + u16 num[2];
> + u16 *len[2];
> + } rx;
> + u32 rec_mb[2];
> +};
> +
> #endif
> diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
> index ceb3dc0613d6..73289a9845d7 100644
> --- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
> +++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
> @@ -81,7 +81,7 @@ static int
> mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
> struct mt76s_intr *intr)
> {
> - struct mt76_queue *q = &dev->q_rx[qid];
> + struct mt76_queue *q = &dev->q_rx[0];
why qid is always 0 here?
Regards,
Lorenzo
> struct mt76_sdio *sdio = &dev->sdio;
> int len = 0, err, i;
> struct page *page;
> @@ -112,8 +112,10 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
> for (i = 0; i < intr->rx.num[qid]; i++) {
> int index = (q->head + i) % q->ndesc;
> struct mt76_queue_entry *e = &q->entry[index];
> + __le32 *rxd = (__le32 *)buf;
>
> - len = intr->rx.len[qid][i];
> + /* parse rxd to get the actual packet length */
> + len = FIELD_GET(GENMASK(15, 0), le32_to_cpu(rxd[0]));
> e->skb = mt76s_build_rx_skb(buf, len, round_up(len + 4, 4));
> if (!e->skb)
> break;
> @@ -132,35 +134,72 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
> return i;
> }
>
> +static void mt76s_intr_parse(struct mt76_dev *dev, void *data,
> + struct mt76s_intr *intr)
> +{
> + struct mt76_connac_sdio_intr *intr_v1;
> + struct mt76_connac2_sdio_intr *intr_v2;
> + int i;
> +
> + switch (dev->sdio.hw_ver) {
> + case MT76_CONNAC_SDIO:
> + intr_v1 = data;
> + intr->isr = intr_v1->isr;
> + intr->tx.wtqcr = intr_v1->tx.wtqcr;
> + for (i = 0; i < 2 ; i++) {
> + intr->rx.num[i] = intr_v1->rx.num[i];
> + intr->rx.len[i] = intr_v1->rx.len[i];
> + intr->rec_mb[i] = intr_v1->rec_mb[i];
> + }
> + break;
> + default:
> + intr_v2 = data;
> + intr->isr = intr_v2->isr;
> + intr->tx.wtqcr = intr_v2->tx.wtqcr;
> + for (i = 0; i < 2 ; i++) {
> + intr->rx.num[i] = intr_v2->rx.num[i];
> + if (!i)
> + intr->rx.len[0] = intr_v2->rx.len0;
> + else
> + intr->rx.len[1] = intr_v2->rx.len1;
> + intr->rec_mb[i] = intr_v2->rec_mb[i];
> + }
> + break;
> + }
> +}
> +
> static int mt76s_rx_handler(struct mt76_dev *dev)
> {
> struct mt76_sdio *sdio = &dev->sdio;
> - struct mt76s_intr *intr = sdio->intr_data;
> + void *data = sdio->intr_data;
> + struct mt76s_intr intr;
> int nframes = 0, ret;
>
> - ret = sdio_readsb(sdio->func, intr, MCR_WHISR, sizeof(*intr));
> + ret = sdio_readsb(sdio->func, data, MCR_WHISR, sdio->intr_size);
> if (ret < 0)
> return ret;
>
> - trace_dev_irq(dev, intr->isr, 0);
> + mt76s_intr_parse(dev, data, &intr);
>
> - if (intr->isr & WHIER_RX0_DONE_INT_EN) {
> - ret = mt76s_rx_run_queue(dev, 0, intr);
> + trace_dev_irq(dev, intr.isr, 0);
> +
> + if (intr.isr & WHIER_RX0_DONE_INT_EN) {
> + ret = mt76s_rx_run_queue(dev, 0, &intr);
> if (ret > 0) {
> mt76_worker_schedule(&sdio->net_worker);
> nframes += ret;
> }
> }
>
> - if (intr->isr & WHIER_RX1_DONE_INT_EN) {
> - ret = mt76s_rx_run_queue(dev, 1, intr);
> + if (intr.isr & WHIER_RX1_DONE_INT_EN) {
> + ret = mt76s_rx_run_queue(dev, 1, &intr);
> if (ret > 0) {
> mt76_worker_schedule(&sdio->net_worker);
> nframes += ret;
> }
> }
>
> - nframes += !!mt76s_refill_sched_quota(dev, intr->tx.wtqcr);
> + nframes += !!mt76s_refill_sched_quota(dev, intr.tx.wtqcr);
>
> return nframes;
> }
> @@ -173,6 +212,9 @@ mt76s_tx_pick_quota(struct mt76_sdio *sdio, bool mcu, int buf_sz,
>
> pse_sz = DIV_ROUND_UP(buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ);
>
> + if (mcu && sdio->hw_ver == MT76_CONNAC2_SDIO)
> + pse_sz = 1;
> +
> if (mcu) {
> if (sdio->sched.pse_mcu_quota < *pse_size + pse_sz)
> return -EBUSY;
> --
> 2.25.1
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
@ 2021-10-13 16:29 ` Lorenzo Bianconi
0 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2021-10-13 16:29 UTC (permalink / raw)
To: sean.wang
Cc: nbd, lorenzo.bianconi, Soul.Huang, YN.Chen, Leon.Yen,
Eric-SY.Chang, Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu,
Eddie.Chen, ch.yeh, posh.sun, ted.huang, Eric.Liang,
Stella.Chang, Tom.Chou, steve.lee, jsiuda, frankgor, jemele,
abhishekpandit, shawnku, linux-wireless, linux-mediatek
[-- Attachment #1.1: Type: text/plain, Size: 10895 bytes --]
> From: Sean Wang <sean.wang@mediatek.com>
>
> Extend sdio module to support CONNAC2 hw that mt7921s rely on.
>
> Tested-by: Deren Wu <deren.wu@mediatek.com>
> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Co-developed-by: Deren Wu <deren.wu@mediatek.com>
> Signed-off-by: Deren Wu <deren.wu@mediatek.com>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> ---
> drivers/net/wireless/mediatek/mt76/mt76.h | 5 +-
> .../net/wireless/mediatek/mt76/mt7615/sdio.c | 5 +-
> drivers/net/wireless/mediatek/mt76/sdio.c | 23 ++++++-
> drivers/net/wireless/mediatek/mt76/sdio.h | 50 ++++++++++++++-
> .../net/wireless/mediatek/mt76/sdio_txrx.c | 62 ++++++++++++++++---
> 5 files changed, 128 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index e2f33956a122..06f0d1348d52 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -505,6 +505,8 @@ struct mt76_sdio {
>
> struct sdio_func *func;
> void *intr_data;
> + int intr_size;
> + u8 hw_ver;
>
> struct {
> int pse_data_quota;
> @@ -1249,7 +1251,8 @@ int mt76s_alloc_queues(struct mt76_dev *dev);
> void mt76s_deinit(struct mt76_dev *dev);
> void mt76s_sdio_irq(struct sdio_func *func);
> void mt76s_txrx_worker(struct mt76_sdio *sdio);
> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func);
> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func,
> + int hw_ver);
> u32 mt76s_rr(struct mt76_dev *dev, u32 offset);
> void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val);
> u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
> index f47e25f6dedb..a6b5d536d962 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
> @@ -100,7 +100,7 @@ static int mt7663s_probe(struct sdio_func *func,
> if (ret < 0)
> goto error;
>
> - ret = mt76s_hw_init(mdev, func);
> + ret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);
> if (ret)
> goto error;
>
> @@ -108,8 +108,9 @@ static int mt7663s_probe(struct sdio_func *func,
> (mt76_rr(dev, MT_HW_REV) & 0xff);
> dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
>
> + mdev->sdio.intr_size = sizeof(struct mt76_connac_sdio_intr);
> mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
> - sizeof(struct mt76s_intr),
> + mdev->sdio.intr_size,
> GFP_KERNEL);
> if (!mdev->sdio.intr_data) {
> ret = -ENOMEM;
> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
> index 82fb4c110b90..bb40cc3e9c2b 100644
> --- a/drivers/net/wireless/mediatek/mt76/sdio.c
> +++ b/drivers/net/wireless/mediatek/mt76/sdio.c
> @@ -221,11 +221,13 @@ int mt76s_rd_rp(struct mt76_dev *dev, u32 base,
> }
> EXPORT_SYMBOL_GPL(mt76s_rd_rp);
>
> -int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
> +int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)
> {
> u32 status, ctrl;
> int ret;
>
> + dev->sdio.hw_ver = hw_ver;
> +
> sdio_claim_host(func);
>
> ret = sdio_enable_func(func);
> @@ -255,12 +257,27 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
> goto disable_func;
>
> ctrl = WHIER_RX0_DONE_INT_EN | WHIER_TX_DONE_INT_EN;
> + if (hw_ver == MT76_CONNAC2_SDIO)
> + ctrl |= WHIER_RX1_DONE_INT_EN;
> sdio_writel(func, ctrl, MCR_WHIER, &ret);
> if (ret < 0)
> goto disable_func;
>
> - /* set WHISR as read clear and Rx aggregation number as 16 */
> - ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
> + switch (hw_ver) {
> + case MT76_CONNAC_SDIO:
> + /* set WHISR as read clear and Rx aggregation number as 16 */
> + ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
> + break;
> + default:
> + ctrl = sdio_readl(func, MCR_WHCR, &ret);
> + if (ret < 0)
> + goto disable_func;
> + ctrl &= ~MAX_HIF_RX_LEN_NUM_CONNAC2;
> + ctrl &= ~W_INT_CLR_CTRL; /* read clear */
> + ctrl |= FIELD_PREP(MAX_HIF_RX_LEN_NUM_CONNAC2, 0);
> + break;
> + }
> +
> sdio_writel(func, ctrl, MCR_WHCR, &ret);
> if (ret < 0)
> goto disable_func;
> diff --git a/drivers/net/wireless/mediatek/mt76/sdio.h b/drivers/net/wireless/mediatek/mt76/sdio.h
> index 03877d89e152..7d2ec044dcb1 100644
> --- a/drivers/net/wireless/mediatek/mt76/sdio.h
> +++ b/drivers/net/wireless/mediatek/mt76/sdio.h
> @@ -21,7 +21,12 @@
> #define MCR_WHCR 0x000C
> #define W_INT_CLR_CTRL BIT(1)
> #define RECV_MAILBOX_RD_CLR_EN BIT(2)
> +#define WF_SYS_RSTB BIT(4) /* supported in CONNAC2 */
> +#define WF_WHOLE_PATH_RSTB BIT(5) /* supported in CONNAC2 */
> +#define WF_SDIO_WF_PATH_RSTB BIT(6) /* supported in CONNAC2 */
> #define MAX_HIF_RX_LEN_NUM GENMASK(13, 8)
> +#define MAX_HIF_RX_LEN_NUM_CONNAC2 GENMASK(14, 8) /* supported in CONNAC2 */
> +#define WF_RST_DONE BIT(15) /* supported in CONNAC2 */
> #define RX_ENHANCE_MODE BIT(16)
>
> #define MCR_WHISR 0x0010
> @@ -29,6 +34,7 @@
> #define WHIER_D2H_SW_INT GENMASK(31, 8)
> #define WHIER_FW_OWN_BACK_INT_EN BIT(7)
> #define WHIER_ABNORMAL_INT_EN BIT(6)
> +#define WHIER_WDT_INT_EN BIT(5) /* supported in CONNAC2 */
> #define WHIER_RX1_DONE_INT_EN BIT(2)
> #define WHIER_RX0_DONE_INT_EN BIT(1)
> #define WHIER_TX_DONE_INT_EN BIT(0)
> @@ -100,7 +106,37 @@
>
> #define MCR_SWPCDBGR 0x0154
>
> -struct mt76s_intr {
> +#define MCR_H2DSM2R 0x0160 /* supported in CONNAC2 */
> +#define MCR_H2DSM3R 0x0164 /* supported in CONNAC2 */
> +#define MCR_D2HRM3R 0x0174 /* supported in CONNAC2 */
> +#define MCR_WTQCR8 0x0190 /* supported in CONNAC2 */
> +#define MCR_WTQCR9 0x0194 /* supported in CONNAC2 */
> +#define MCR_WTQCR10 0x0198 /* supported in CONNAC2 */
> +#define MCR_WTQCR11 0x019C /* supported in CONNAC2 */
> +#define MCR_WTQCR12 0x01A0 /* supported in CONNAC2 */
> +#define MCR_WTQCR13 0x01A4 /* supported in CONNAC2 */
> +#define MCR_WTQCR14 0x01A8 /* supported in CONNAC2 */
> +#define MCR_WTQCR15 0x01AC /* supported in CONNAC2 */
> +
> +enum mt76_connac_sdio_ver {
> + MT76_CONNAC_SDIO,
> + MT76_CONNAC2_SDIO,
> +};
> +
> +struct mt76_connac2_sdio_intr {
> + u32 isr;
> + struct {
> + u32 wtqcr[16];
> + } tx;
> + struct {
> + u16 num[2];
> + u16 len0[16];
> + u16 len1[128];
> + } rx;
> + u32 rec_mb[2];
> +} __packed;
> +
> +struct mt76_connac_sdio_intr {
> u32 isr;
> struct {
> u32 wtqcr[8];
> @@ -112,4 +148,16 @@ struct mt76s_intr {
> u32 rec_mb[2];
> } __packed;
>
> +struct mt76s_intr {
> + u32 isr;
> + struct {
> + u32 *wtqcr;
> + } tx;
> + struct {
> + u16 num[2];
> + u16 *len[2];
> + } rx;
> + u32 rec_mb[2];
> +};
> +
> #endif
> diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
> index ceb3dc0613d6..73289a9845d7 100644
> --- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
> +++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
> @@ -81,7 +81,7 @@ static int
> mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
> struct mt76s_intr *intr)
> {
> - struct mt76_queue *q = &dev->q_rx[qid];
> + struct mt76_queue *q = &dev->q_rx[0];
why qid is always 0 here?
Regards,
Lorenzo
> struct mt76_sdio *sdio = &dev->sdio;
> int len = 0, err, i;
> struct page *page;
> @@ -112,8 +112,10 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
> for (i = 0; i < intr->rx.num[qid]; i++) {
> int index = (q->head + i) % q->ndesc;
> struct mt76_queue_entry *e = &q->entry[index];
> + __le32 *rxd = (__le32 *)buf;
>
> - len = intr->rx.len[qid][i];
> + /* parse rxd to get the actual packet length */
> + len = FIELD_GET(GENMASK(15, 0), le32_to_cpu(rxd[0]));
> e->skb = mt76s_build_rx_skb(buf, len, round_up(len + 4, 4));
> if (!e->skb)
> break;
> @@ -132,35 +134,72 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
> return i;
> }
>
> +static void mt76s_intr_parse(struct mt76_dev *dev, void *data,
> + struct mt76s_intr *intr)
> +{
> + struct mt76_connac_sdio_intr *intr_v1;
> + struct mt76_connac2_sdio_intr *intr_v2;
> + int i;
> +
> + switch (dev->sdio.hw_ver) {
> + case MT76_CONNAC_SDIO:
> + intr_v1 = data;
> + intr->isr = intr_v1->isr;
> + intr->tx.wtqcr = intr_v1->tx.wtqcr;
> + for (i = 0; i < 2 ; i++) {
> + intr->rx.num[i] = intr_v1->rx.num[i];
> + intr->rx.len[i] = intr_v1->rx.len[i];
> + intr->rec_mb[i] = intr_v1->rec_mb[i];
> + }
> + break;
> + default:
> + intr_v2 = data;
> + intr->isr = intr_v2->isr;
> + intr->tx.wtqcr = intr_v2->tx.wtqcr;
> + for (i = 0; i < 2 ; i++) {
> + intr->rx.num[i] = intr_v2->rx.num[i];
> + if (!i)
> + intr->rx.len[0] = intr_v2->rx.len0;
> + else
> + intr->rx.len[1] = intr_v2->rx.len1;
> + intr->rec_mb[i] = intr_v2->rec_mb[i];
> + }
> + break;
> + }
> +}
> +
> static int mt76s_rx_handler(struct mt76_dev *dev)
> {
> struct mt76_sdio *sdio = &dev->sdio;
> - struct mt76s_intr *intr = sdio->intr_data;
> + void *data = sdio->intr_data;
> + struct mt76s_intr intr;
> int nframes = 0, ret;
>
> - ret = sdio_readsb(sdio->func, intr, MCR_WHISR, sizeof(*intr));
> + ret = sdio_readsb(sdio->func, data, MCR_WHISR, sdio->intr_size);
> if (ret < 0)
> return ret;
>
> - trace_dev_irq(dev, intr->isr, 0);
> + mt76s_intr_parse(dev, data, &intr);
>
> - if (intr->isr & WHIER_RX0_DONE_INT_EN) {
> - ret = mt76s_rx_run_queue(dev, 0, intr);
> + trace_dev_irq(dev, intr.isr, 0);
> +
> + if (intr.isr & WHIER_RX0_DONE_INT_EN) {
> + ret = mt76s_rx_run_queue(dev, 0, &intr);
> if (ret > 0) {
> mt76_worker_schedule(&sdio->net_worker);
> nframes += ret;
> }
> }
>
> - if (intr->isr & WHIER_RX1_DONE_INT_EN) {
> - ret = mt76s_rx_run_queue(dev, 1, intr);
> + if (intr.isr & WHIER_RX1_DONE_INT_EN) {
> + ret = mt76s_rx_run_queue(dev, 1, &intr);
> if (ret > 0) {
> mt76_worker_schedule(&sdio->net_worker);
> nframes += ret;
> }
> }
>
> - nframes += !!mt76s_refill_sched_quota(dev, intr->tx.wtqcr);
> + nframes += !!mt76s_refill_sched_quota(dev, intr.tx.wtqcr);
>
> return nframes;
> }
> @@ -173,6 +212,9 @@ mt76s_tx_pick_quota(struct mt76_sdio *sdio, bool mcu, int buf_sz,
>
> pse_sz = DIV_ROUND_UP(buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ);
>
> + if (mcu && sdio->hw_ver == MT76_CONNAC2_SDIO)
> + pse_sz = 1;
> +
> if (mcu) {
> if (sdio->sched.pse_mcu_quota < *pse_size + pse_sz)
> return -EBUSY;
> --
> 2.25.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 170 bytes --]
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
2021-10-12 22:51 [PATCH v4 00/16] Add MT7921 SDIO WiFi support sean.wang
@ 2021-10-12 22:52 ` sean.wang
0 siblings, 0 replies; 10+ messages in thread
From: sean.wang @ 2021-10-12 22:52 UTC (permalink / raw)
To: nbd, lorenzo.bianconi
Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Eric-SY.Chang,
Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu, Eddie.Chen, ch.yeh,
posh.sun, ted.huang, Eric.Liang, Stella.Chang, Tom.Chou,
steve.lee, jsiuda, frankgor, jemele, abhishekpandit, shawnku,
linux-wireless, linux-mediatek, Deren Wu
From: Sean Wang <sean.wang@mediatek.com>
Extend sdio module to support CONNAC2 hw that mt7921s rely on.
Tested-by: Deren Wu <deren.wu@mediatek.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Co-developed-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 5 +-
.../net/wireless/mediatek/mt76/mt7615/sdio.c | 5 +-
drivers/net/wireless/mediatek/mt76/sdio.c | 23 ++++++-
drivers/net/wireless/mediatek/mt76/sdio.h | 50 ++++++++++++++-
.../net/wireless/mediatek/mt76/sdio_txrx.c | 62 ++++++++++++++++---
5 files changed, 128 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index e2f33956a122..06f0d1348d52 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -505,6 +505,8 @@ struct mt76_sdio {
struct sdio_func *func;
void *intr_data;
+ int intr_size;
+ u8 hw_ver;
struct {
int pse_data_quota;
@@ -1249,7 +1251,8 @@ int mt76s_alloc_queues(struct mt76_dev *dev);
void mt76s_deinit(struct mt76_dev *dev);
void mt76s_sdio_irq(struct sdio_func *func);
void mt76s_txrx_worker(struct mt76_sdio *sdio);
-int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func);
+int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func,
+ int hw_ver);
u32 mt76s_rr(struct mt76_dev *dev, u32 offset);
void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val);
u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index f47e25f6dedb..a6b5d536d962 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -100,7 +100,7 @@ static int mt7663s_probe(struct sdio_func *func,
if (ret < 0)
goto error;
- ret = mt76s_hw_init(mdev, func);
+ ret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);
if (ret)
goto error;
@@ -108,8 +108,9 @@ static int mt7663s_probe(struct sdio_func *func,
(mt76_rr(dev, MT_HW_REV) & 0xff);
dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
+ mdev->sdio.intr_size = sizeof(struct mt76_connac_sdio_intr);
mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
- sizeof(struct mt76s_intr),
+ mdev->sdio.intr_size,
GFP_KERNEL);
if (!mdev->sdio.intr_data) {
ret = -ENOMEM;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index 82fb4c110b90..bb40cc3e9c2b 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -221,11 +221,13 @@ int mt76s_rd_rp(struct mt76_dev *dev, u32 base,
}
EXPORT_SYMBOL_GPL(mt76s_rd_rp);
-int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
+int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)
{
u32 status, ctrl;
int ret;
+ dev->sdio.hw_ver = hw_ver;
+
sdio_claim_host(func);
ret = sdio_enable_func(func);
@@ -255,12 +257,27 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
goto disable_func;
ctrl = WHIER_RX0_DONE_INT_EN | WHIER_TX_DONE_INT_EN;
+ if (hw_ver == MT76_CONNAC2_SDIO)
+ ctrl |= WHIER_RX1_DONE_INT_EN;
sdio_writel(func, ctrl, MCR_WHIER, &ret);
if (ret < 0)
goto disable_func;
- /* set WHISR as read clear and Rx aggregation number as 16 */
- ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
+ switch (hw_ver) {
+ case MT76_CONNAC_SDIO:
+ /* set WHISR as read clear and Rx aggregation number as 16 */
+ ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
+ break;
+ default:
+ ctrl = sdio_readl(func, MCR_WHCR, &ret);
+ if (ret < 0)
+ goto disable_func;
+ ctrl &= ~MAX_HIF_RX_LEN_NUM_CONNAC2;
+ ctrl &= ~W_INT_CLR_CTRL; /* read clear */
+ ctrl |= FIELD_PREP(MAX_HIF_RX_LEN_NUM_CONNAC2, 0);
+ break;
+ }
+
sdio_writel(func, ctrl, MCR_WHCR, &ret);
if (ret < 0)
goto disable_func;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.h b/drivers/net/wireless/mediatek/mt76/sdio.h
index 03877d89e152..7d2ec044dcb1 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.h
+++ b/drivers/net/wireless/mediatek/mt76/sdio.h
@@ -21,7 +21,12 @@
#define MCR_WHCR 0x000C
#define W_INT_CLR_CTRL BIT(1)
#define RECV_MAILBOX_RD_CLR_EN BIT(2)
+#define WF_SYS_RSTB BIT(4) /* supported in CONNAC2 */
+#define WF_WHOLE_PATH_RSTB BIT(5) /* supported in CONNAC2 */
+#define WF_SDIO_WF_PATH_RSTB BIT(6) /* supported in CONNAC2 */
#define MAX_HIF_RX_LEN_NUM GENMASK(13, 8)
+#define MAX_HIF_RX_LEN_NUM_CONNAC2 GENMASK(14, 8) /* supported in CONNAC2 */
+#define WF_RST_DONE BIT(15) /* supported in CONNAC2 */
#define RX_ENHANCE_MODE BIT(16)
#define MCR_WHISR 0x0010
@@ -29,6 +34,7 @@
#define WHIER_D2H_SW_INT GENMASK(31, 8)
#define WHIER_FW_OWN_BACK_INT_EN BIT(7)
#define WHIER_ABNORMAL_INT_EN BIT(6)
+#define WHIER_WDT_INT_EN BIT(5) /* supported in CONNAC2 */
#define WHIER_RX1_DONE_INT_EN BIT(2)
#define WHIER_RX0_DONE_INT_EN BIT(1)
#define WHIER_TX_DONE_INT_EN BIT(0)
@@ -100,7 +106,37 @@
#define MCR_SWPCDBGR 0x0154
-struct mt76s_intr {
+#define MCR_H2DSM2R 0x0160 /* supported in CONNAC2 */
+#define MCR_H2DSM3R 0x0164 /* supported in CONNAC2 */
+#define MCR_D2HRM3R 0x0174 /* supported in CONNAC2 */
+#define MCR_WTQCR8 0x0190 /* supported in CONNAC2 */
+#define MCR_WTQCR9 0x0194 /* supported in CONNAC2 */
+#define MCR_WTQCR10 0x0198 /* supported in CONNAC2 */
+#define MCR_WTQCR11 0x019C /* supported in CONNAC2 */
+#define MCR_WTQCR12 0x01A0 /* supported in CONNAC2 */
+#define MCR_WTQCR13 0x01A4 /* supported in CONNAC2 */
+#define MCR_WTQCR14 0x01A8 /* supported in CONNAC2 */
+#define MCR_WTQCR15 0x01AC /* supported in CONNAC2 */
+
+enum mt76_connac_sdio_ver {
+ MT76_CONNAC_SDIO,
+ MT76_CONNAC2_SDIO,
+};
+
+struct mt76_connac2_sdio_intr {
+ u32 isr;
+ struct {
+ u32 wtqcr[16];
+ } tx;
+ struct {
+ u16 num[2];
+ u16 len0[16];
+ u16 len1[128];
+ } rx;
+ u32 rec_mb[2];
+} __packed;
+
+struct mt76_connac_sdio_intr {
u32 isr;
struct {
u32 wtqcr[8];
@@ -112,4 +148,16 @@ struct mt76s_intr {
u32 rec_mb[2];
} __packed;
+struct mt76s_intr {
+ u32 isr;
+ struct {
+ u32 *wtqcr;
+ } tx;
+ struct {
+ u16 num[2];
+ u16 *len[2];
+ } rx;
+ u32 rec_mb[2];
+};
+
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
index ceb3dc0613d6..73289a9845d7 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
@@ -81,7 +81,7 @@ static int
mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
struct mt76s_intr *intr)
{
- struct mt76_queue *q = &dev->q_rx[qid];
+ struct mt76_queue *q = &dev->q_rx[0];
struct mt76_sdio *sdio = &dev->sdio;
int len = 0, err, i;
struct page *page;
@@ -112,8 +112,10 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
for (i = 0; i < intr->rx.num[qid]; i++) {
int index = (q->head + i) % q->ndesc;
struct mt76_queue_entry *e = &q->entry[index];
+ __le32 *rxd = (__le32 *)buf;
- len = intr->rx.len[qid][i];
+ /* parse rxd to get the actual packet length */
+ len = FIELD_GET(GENMASK(15, 0), le32_to_cpu(rxd[0]));
e->skb = mt76s_build_rx_skb(buf, len, round_up(len + 4, 4));
if (!e->skb)
break;
@@ -132,35 +134,72 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
return i;
}
+static void mt76s_intr_parse(struct mt76_dev *dev, void *data,
+ struct mt76s_intr *intr)
+{
+ struct mt76_connac_sdio_intr *intr_v1;
+ struct mt76_connac2_sdio_intr *intr_v2;
+ int i;
+
+ switch (dev->sdio.hw_ver) {
+ case MT76_CONNAC_SDIO:
+ intr_v1 = data;
+ intr->isr = intr_v1->isr;
+ intr->tx.wtqcr = intr_v1->tx.wtqcr;
+ for (i = 0; i < 2 ; i++) {
+ intr->rx.num[i] = intr_v1->rx.num[i];
+ intr->rx.len[i] = intr_v1->rx.len[i];
+ intr->rec_mb[i] = intr_v1->rec_mb[i];
+ }
+ break;
+ default:
+ intr_v2 = data;
+ intr->isr = intr_v2->isr;
+ intr->tx.wtqcr = intr_v2->tx.wtqcr;
+ for (i = 0; i < 2 ; i++) {
+ intr->rx.num[i] = intr_v2->rx.num[i];
+ if (!i)
+ intr->rx.len[0] = intr_v2->rx.len0;
+ else
+ intr->rx.len[1] = intr_v2->rx.len1;
+ intr->rec_mb[i] = intr_v2->rec_mb[i];
+ }
+ break;
+ }
+}
+
static int mt76s_rx_handler(struct mt76_dev *dev)
{
struct mt76_sdio *sdio = &dev->sdio;
- struct mt76s_intr *intr = sdio->intr_data;
+ void *data = sdio->intr_data;
+ struct mt76s_intr intr;
int nframes = 0, ret;
- ret = sdio_readsb(sdio->func, intr, MCR_WHISR, sizeof(*intr));
+ ret = sdio_readsb(sdio->func, data, MCR_WHISR, sdio->intr_size);
if (ret < 0)
return ret;
- trace_dev_irq(dev, intr->isr, 0);
+ mt76s_intr_parse(dev, data, &intr);
- if (intr->isr & WHIER_RX0_DONE_INT_EN) {
- ret = mt76s_rx_run_queue(dev, 0, intr);
+ trace_dev_irq(dev, intr.isr, 0);
+
+ if (intr.isr & WHIER_RX0_DONE_INT_EN) {
+ ret = mt76s_rx_run_queue(dev, 0, &intr);
if (ret > 0) {
mt76_worker_schedule(&sdio->net_worker);
nframes += ret;
}
}
- if (intr->isr & WHIER_RX1_DONE_INT_EN) {
- ret = mt76s_rx_run_queue(dev, 1, intr);
+ if (intr.isr & WHIER_RX1_DONE_INT_EN) {
+ ret = mt76s_rx_run_queue(dev, 1, &intr);
if (ret > 0) {
mt76_worker_schedule(&sdio->net_worker);
nframes += ret;
}
}
- nframes += !!mt76s_refill_sched_quota(dev, intr->tx.wtqcr);
+ nframes += !!mt76s_refill_sched_quota(dev, intr.tx.wtqcr);
return nframes;
}
@@ -173,6 +212,9 @@ mt76s_tx_pick_quota(struct mt76_sdio *sdio, bool mcu, int buf_sz,
pse_sz = DIV_ROUND_UP(buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ);
+ if (mcu && sdio->hw_ver == MT76_CONNAC2_SDIO)
+ pse_sz = 1;
+
if (mcu) {
if (sdio->sched.pse_mcu_quota < *pse_size + pse_sz)
return -EBUSY;
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2
@ 2021-10-12 22:52 ` sean.wang
0 siblings, 0 replies; 10+ messages in thread
From: sean.wang @ 2021-10-12 22:52 UTC (permalink / raw)
To: nbd, lorenzo.bianconi
Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Eric-SY.Chang,
Mark-YW.Chen, Deren.Wu, km.lin, robin.chiu, Eddie.Chen, ch.yeh,
posh.sun, ted.huang, Eric.Liang, Stella.Chang, Tom.Chou,
steve.lee, jsiuda, frankgor, jemele, abhishekpandit, shawnku,
linux-wireless, linux-mediatek, Deren Wu
From: Sean Wang <sean.wang@mediatek.com>
Extend sdio module to support CONNAC2 hw that mt7921s rely on.
Tested-by: Deren Wu <deren.wu@mediatek.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Co-developed-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 5 +-
.../net/wireless/mediatek/mt76/mt7615/sdio.c | 5 +-
drivers/net/wireless/mediatek/mt76/sdio.c | 23 ++++++-
drivers/net/wireless/mediatek/mt76/sdio.h | 50 ++++++++++++++-
.../net/wireless/mediatek/mt76/sdio_txrx.c | 62 ++++++++++++++++---
5 files changed, 128 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index e2f33956a122..06f0d1348d52 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -505,6 +505,8 @@ struct mt76_sdio {
struct sdio_func *func;
void *intr_data;
+ int intr_size;
+ u8 hw_ver;
struct {
int pse_data_quota;
@@ -1249,7 +1251,8 @@ int mt76s_alloc_queues(struct mt76_dev *dev);
void mt76s_deinit(struct mt76_dev *dev);
void mt76s_sdio_irq(struct sdio_func *func);
void mt76s_txrx_worker(struct mt76_sdio *sdio);
-int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func);
+int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func,
+ int hw_ver);
u32 mt76s_rr(struct mt76_dev *dev, u32 offset);
void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val);
u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index f47e25f6dedb..a6b5d536d962 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -100,7 +100,7 @@ static int mt7663s_probe(struct sdio_func *func,
if (ret < 0)
goto error;
- ret = mt76s_hw_init(mdev, func);
+ ret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);
if (ret)
goto error;
@@ -108,8 +108,9 @@ static int mt7663s_probe(struct sdio_func *func,
(mt76_rr(dev, MT_HW_REV) & 0xff);
dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
+ mdev->sdio.intr_size = sizeof(struct mt76_connac_sdio_intr);
mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
- sizeof(struct mt76s_intr),
+ mdev->sdio.intr_size,
GFP_KERNEL);
if (!mdev->sdio.intr_data) {
ret = -ENOMEM;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index 82fb4c110b90..bb40cc3e9c2b 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -221,11 +221,13 @@ int mt76s_rd_rp(struct mt76_dev *dev, u32 base,
}
EXPORT_SYMBOL_GPL(mt76s_rd_rp);
-int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
+int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)
{
u32 status, ctrl;
int ret;
+ dev->sdio.hw_ver = hw_ver;
+
sdio_claim_host(func);
ret = sdio_enable_func(func);
@@ -255,12 +257,27 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func)
goto disable_func;
ctrl = WHIER_RX0_DONE_INT_EN | WHIER_TX_DONE_INT_EN;
+ if (hw_ver == MT76_CONNAC2_SDIO)
+ ctrl |= WHIER_RX1_DONE_INT_EN;
sdio_writel(func, ctrl, MCR_WHIER, &ret);
if (ret < 0)
goto disable_func;
- /* set WHISR as read clear and Rx aggregation number as 16 */
- ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
+ switch (hw_ver) {
+ case MT76_CONNAC_SDIO:
+ /* set WHISR as read clear and Rx aggregation number as 16 */
+ ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
+ break;
+ default:
+ ctrl = sdio_readl(func, MCR_WHCR, &ret);
+ if (ret < 0)
+ goto disable_func;
+ ctrl &= ~MAX_HIF_RX_LEN_NUM_CONNAC2;
+ ctrl &= ~W_INT_CLR_CTRL; /* read clear */
+ ctrl |= FIELD_PREP(MAX_HIF_RX_LEN_NUM_CONNAC2, 0);
+ break;
+ }
+
sdio_writel(func, ctrl, MCR_WHCR, &ret);
if (ret < 0)
goto disable_func;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.h b/drivers/net/wireless/mediatek/mt76/sdio.h
index 03877d89e152..7d2ec044dcb1 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.h
+++ b/drivers/net/wireless/mediatek/mt76/sdio.h
@@ -21,7 +21,12 @@
#define MCR_WHCR 0x000C
#define W_INT_CLR_CTRL BIT(1)
#define RECV_MAILBOX_RD_CLR_EN BIT(2)
+#define WF_SYS_RSTB BIT(4) /* supported in CONNAC2 */
+#define WF_WHOLE_PATH_RSTB BIT(5) /* supported in CONNAC2 */
+#define WF_SDIO_WF_PATH_RSTB BIT(6) /* supported in CONNAC2 */
#define MAX_HIF_RX_LEN_NUM GENMASK(13, 8)
+#define MAX_HIF_RX_LEN_NUM_CONNAC2 GENMASK(14, 8) /* supported in CONNAC2 */
+#define WF_RST_DONE BIT(15) /* supported in CONNAC2 */
#define RX_ENHANCE_MODE BIT(16)
#define MCR_WHISR 0x0010
@@ -29,6 +34,7 @@
#define WHIER_D2H_SW_INT GENMASK(31, 8)
#define WHIER_FW_OWN_BACK_INT_EN BIT(7)
#define WHIER_ABNORMAL_INT_EN BIT(6)
+#define WHIER_WDT_INT_EN BIT(5) /* supported in CONNAC2 */
#define WHIER_RX1_DONE_INT_EN BIT(2)
#define WHIER_RX0_DONE_INT_EN BIT(1)
#define WHIER_TX_DONE_INT_EN BIT(0)
@@ -100,7 +106,37 @@
#define MCR_SWPCDBGR 0x0154
-struct mt76s_intr {
+#define MCR_H2DSM2R 0x0160 /* supported in CONNAC2 */
+#define MCR_H2DSM3R 0x0164 /* supported in CONNAC2 */
+#define MCR_D2HRM3R 0x0174 /* supported in CONNAC2 */
+#define MCR_WTQCR8 0x0190 /* supported in CONNAC2 */
+#define MCR_WTQCR9 0x0194 /* supported in CONNAC2 */
+#define MCR_WTQCR10 0x0198 /* supported in CONNAC2 */
+#define MCR_WTQCR11 0x019C /* supported in CONNAC2 */
+#define MCR_WTQCR12 0x01A0 /* supported in CONNAC2 */
+#define MCR_WTQCR13 0x01A4 /* supported in CONNAC2 */
+#define MCR_WTQCR14 0x01A8 /* supported in CONNAC2 */
+#define MCR_WTQCR15 0x01AC /* supported in CONNAC2 */
+
+enum mt76_connac_sdio_ver {
+ MT76_CONNAC_SDIO,
+ MT76_CONNAC2_SDIO,
+};
+
+struct mt76_connac2_sdio_intr {
+ u32 isr;
+ struct {
+ u32 wtqcr[16];
+ } tx;
+ struct {
+ u16 num[2];
+ u16 len0[16];
+ u16 len1[128];
+ } rx;
+ u32 rec_mb[2];
+} __packed;
+
+struct mt76_connac_sdio_intr {
u32 isr;
struct {
u32 wtqcr[8];
@@ -112,4 +148,16 @@ struct mt76s_intr {
u32 rec_mb[2];
} __packed;
+struct mt76s_intr {
+ u32 isr;
+ struct {
+ u32 *wtqcr;
+ } tx;
+ struct {
+ u16 num[2];
+ u16 *len[2];
+ } rx;
+ u32 rec_mb[2];
+};
+
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
index ceb3dc0613d6..73289a9845d7 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
@@ -81,7 +81,7 @@ static int
mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
struct mt76s_intr *intr)
{
- struct mt76_queue *q = &dev->q_rx[qid];
+ struct mt76_queue *q = &dev->q_rx[0];
struct mt76_sdio *sdio = &dev->sdio;
int len = 0, err, i;
struct page *page;
@@ -112,8 +112,10 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
for (i = 0; i < intr->rx.num[qid]; i++) {
int index = (q->head + i) % q->ndesc;
struct mt76_queue_entry *e = &q->entry[index];
+ __le32 *rxd = (__le32 *)buf;
- len = intr->rx.len[qid][i];
+ /* parse rxd to get the actual packet length */
+ len = FIELD_GET(GENMASK(15, 0), le32_to_cpu(rxd[0]));
e->skb = mt76s_build_rx_skb(buf, len, round_up(len + 4, 4));
if (!e->skb)
break;
@@ -132,35 +134,72 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
return i;
}
+static void mt76s_intr_parse(struct mt76_dev *dev, void *data,
+ struct mt76s_intr *intr)
+{
+ struct mt76_connac_sdio_intr *intr_v1;
+ struct mt76_connac2_sdio_intr *intr_v2;
+ int i;
+
+ switch (dev->sdio.hw_ver) {
+ case MT76_CONNAC_SDIO:
+ intr_v1 = data;
+ intr->isr = intr_v1->isr;
+ intr->tx.wtqcr = intr_v1->tx.wtqcr;
+ for (i = 0; i < 2 ; i++) {
+ intr->rx.num[i] = intr_v1->rx.num[i];
+ intr->rx.len[i] = intr_v1->rx.len[i];
+ intr->rec_mb[i] = intr_v1->rec_mb[i];
+ }
+ break;
+ default:
+ intr_v2 = data;
+ intr->isr = intr_v2->isr;
+ intr->tx.wtqcr = intr_v2->tx.wtqcr;
+ for (i = 0; i < 2 ; i++) {
+ intr->rx.num[i] = intr_v2->rx.num[i];
+ if (!i)
+ intr->rx.len[0] = intr_v2->rx.len0;
+ else
+ intr->rx.len[1] = intr_v2->rx.len1;
+ intr->rec_mb[i] = intr_v2->rec_mb[i];
+ }
+ break;
+ }
+}
+
static int mt76s_rx_handler(struct mt76_dev *dev)
{
struct mt76_sdio *sdio = &dev->sdio;
- struct mt76s_intr *intr = sdio->intr_data;
+ void *data = sdio->intr_data;
+ struct mt76s_intr intr;
int nframes = 0, ret;
- ret = sdio_readsb(sdio->func, intr, MCR_WHISR, sizeof(*intr));
+ ret = sdio_readsb(sdio->func, data, MCR_WHISR, sdio->intr_size);
if (ret < 0)
return ret;
- trace_dev_irq(dev, intr->isr, 0);
+ mt76s_intr_parse(dev, data, &intr);
- if (intr->isr & WHIER_RX0_DONE_INT_EN) {
- ret = mt76s_rx_run_queue(dev, 0, intr);
+ trace_dev_irq(dev, intr.isr, 0);
+
+ if (intr.isr & WHIER_RX0_DONE_INT_EN) {
+ ret = mt76s_rx_run_queue(dev, 0, &intr);
if (ret > 0) {
mt76_worker_schedule(&sdio->net_worker);
nframes += ret;
}
}
- if (intr->isr & WHIER_RX1_DONE_INT_EN) {
- ret = mt76s_rx_run_queue(dev, 1, intr);
+ if (intr.isr & WHIER_RX1_DONE_INT_EN) {
+ ret = mt76s_rx_run_queue(dev, 1, &intr);
if (ret > 0) {
mt76_worker_schedule(&sdio->net_worker);
nframes += ret;
}
}
- nframes += !!mt76s_refill_sched_quota(dev, intr->tx.wtqcr);
+ nframes += !!mt76s_refill_sched_quota(dev, intr.tx.wtqcr);
return nframes;
}
@@ -173,6 +212,9 @@ mt76s_tx_pick_quota(struct mt76_sdio *sdio, bool mcu, int buf_sz,
pse_sz = DIV_ROUND_UP(buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ);
+ if (mcu && sdio->hw_ver == MT76_CONNAC2_SDIO)
+ pse_sz = 1;
+
if (mcu) {
if (sdio->sched.pse_mcu_quota < *pse_size + pse_sz)
return -EBUSY;
--
2.25.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-10-13 21:24 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <YWcJe27HQMS7B85j@lore-desk--annotate>
2021-10-13 17:56 ` [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2 sean.wang
2021-10-13 17:56 ` sean.wang
2021-10-13 19:06 ` Lorenzo Bianconi
2021-10-13 19:06 ` Lorenzo Bianconi
[not found] <YWcuGcFPGCtaPh+2@lore-desk--annotate>
2021-10-13 21:22 ` sean.wang
2021-10-13 21:22 ` sean.wang
2021-10-12 22:51 [PATCH v4 00/16] Add MT7921 SDIO WiFi support sean.wang
2021-10-12 22:52 ` [PATCH v4 11/16] mt76: sdio: extend sdio module to support CONNAC2 sean.wang
2021-10-12 22:52 ` sean.wang
2021-10-13 16:29 ` Lorenzo Bianconi
2021-10-13 16:29 ` Lorenzo Bianconi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.