* 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
[parent not found: <YWcuGcFPGCtaPh+2@lore-desk--annotate>]
* 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
* [PATCH v4 00/16] Add MT7921 SDIO WiFi support @ 2021-10-12 22:51 sean.wang 2021-10-12 22:52 ` sean.wang 0 siblings, 1 reply; 10+ messages in thread From: sean.wang @ 2021-10-12 22:51 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, Sean Wang From: Sean Wang <objelf@gmail.com> The patchset adds the SDIO support to the MT7921 driver, basically are made up of 3 parts. PART 1: patch 1-5, 8-9 and 12-14 These are preliminary patches for mt7921s driver to refactor and reuse the current mt7921e driver as much as possible. PART 2: patch 6-7, 10 These are preliminary patches for mt7921s driver to refactor and reuse the current mt7663s driver as much as possible. PART 3: patch 11 and 15-16 These are specific patches for mt7921s driver and reset mechanism in the same framework where mt7921e have been supported. The patchset are built and generated against the current mt76 tree with the tag mt76-for-kvalo-2021-10-12 to help the review and merge process be easier. The change list from v1 to v2 1. rework the whole driver according to the new patches added ("mt76: introduce __mt76_mcu_send_firmware routine"), ("mt76: not accounting the MCU header size in __mt76_mcu_send_firmware for mt7915/21") and ("mt76: sdio: move common code in mt76_sdio module") 2. drop pci_init.c and sdio_init.c by moving the related logic to pci.c and sdio.c, respectively. 3. cosmetics the patches like removing unnecessary new line, adding an extra space to fixed_map table and so on ... 4. fix typo in commit message The change list from v2 to v3 1. rebase onto the latest mt76 branch 2. update per Lorenzo comments on v2 3. fix scheduling while atomic in mt7921_mac_sta_poll for mt7921s driver The change list from v3 to v4 1. change the title of coverletter 2. fix the git message in patch 14 3. rebase onto the mt76-for-kvalo-2021-10-12 Lorenzo Bianconi (1): mt76: sdio: move common code in mt76_sdio module Sean Wang (15): mt76: mt7921: refactor mac.c to be bus independent mt76: mt7921: refactor dma.c to be pcie specific mt76: mt7921: refactor mcu.c to be bus independent mt76: mt7921: refactor init.c to be bus independent mt76: mt7921: add MT7921_COMMON module mt76: connac: move mcu reg access utility routines in mt76_connac_lib module mt76: mt7663s: rely on mcu reg access utility mt76: mt7921: make all event parser reusable between mt7921s and mt7921e mt76: mt7921: use physical addr to unify register access mt76: sdio: extend sdio module to support CONNAC2 mt76: connac: extend mcu_get_nic_capability mt76: mt7921: rely on mcu_get_nic_capability mt76: mt7921: refactor mt7921_mcu_send_message mt76: mt7921: introduce mt7921s support mt76: mt7921s: add reset support drivers/net/wireless/mediatek/mt76/Makefile | 2 +- drivers/net/wireless/mediatek/mt76/mt76.h | 22 + .../wireless/mediatek/mt76/mt7615/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt7615/mcu.c | 28 -- .../wireless/mediatek/mt76/mt7615/mt7615.h | 6 - .../net/wireless/mediatek/mt76/mt7615/sdio.c | 282 +------------ .../wireless/mediatek/mt76/mt7615/sdio_mcu.c | 11 +- .../wireless/mediatek/mt76/mt76_connac_mcu.c | 93 +++++ .../wireless/mediatek/mt76/mt76_connac_mcu.h | 2 + .../net/wireless/mediatek/mt76/mt7921/Kconfig | 18 +- .../wireless/mediatek/mt76/mt7921/Makefile | 8 +- .../wireless/mediatek/mt76/mt7921/debugfs.c | 18 +- .../net/wireless/mediatek/mt76/mt7921/dma.c | 38 +- .../wireless/mediatek/mt76/mt7921/eeprom.c | 101 ----- .../net/wireless/mediatek/mt76/mt7921/init.c | 51 +-- .../net/wireless/mediatek/mt76/mt7921/mac.c | 381 ++---------------- .../net/wireless/mediatek/mt76/mt7921/mac.h | 4 + .../net/wireless/mediatek/mt76/mt7921/main.c | 8 + .../net/wireless/mediatek/mt76/mt7921/mcu.c | 135 ++----- .../wireless/mediatek/mt76/mt7921/mt7921.h | 94 ++++- .../net/wireless/mediatek/mt76/mt7921/pci.c | 48 ++- .../wireless/mediatek/mt76/mt7921/pci_mac.c | 354 ++++++++++++++++ .../wireless/mediatek/mt76/mt7921/pci_mcu.c | 115 ++++++ .../net/wireless/mediatek/mt76/mt7921/regs.h | 22 +- .../net/wireless/mediatek/mt76/mt7921/sdio.c | 285 +++++++++++++ .../wireless/mediatek/mt76/mt7921/sdio_mac.c | 220 ++++++++++ .../wireless/mediatek/mt76/mt7921/sdio_mcu.c | 135 +++++++ drivers/net/wireless/mediatek/mt76/sdio.c | 282 +++++++++++++ .../mediatek/mt76/{mt7615 => }/sdio.h | 50 ++- .../mediatek/mt76/{mt7615 => }/sdio_txrx.c | 171 +++++--- 30 files changed, 1987 insertions(+), 999 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7921/sdio.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c rename drivers/net/wireless/mediatek/mt76/{mt7615 => }/sdio.h (68%) rename drivers/net/wireless/mediatek/mt76/{mt7615 => }/sdio_txrx.c (59%) -- 2.25.1 _______________________________________________ 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
* 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
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.