| From f83c601c7b525c0adedcf1f5e8041acd350c7e2d Mon Sep 17 00:00:00 2001 |
| From: Sujuan Chen <sujuan.chen@mediatek.com> |
| Date: Mon, 18 Sep 2023 13:23:56 +0800 |
| Subject: [PATCH] mtk: wed: add dma mask limitation and GFP_DMA32 for board >= |
| 4GB dram |
| |
| --- |
| drivers/net/ethernet/mediatek/mtk_wed.c | 16 +++++++++++----- |
| drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 4 ++-- |
| drivers/net/ethernet/mediatek/mtk_wed_wo.c | 4 ++-- |
| drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 + |
| 4 files changed, 16 insertions(+), 9 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c |
| index 5eeb3ed..094bc94 100644 |
| --- a/drivers/net/ethernet/mediatek/mtk_wed.c |
| +++ b/drivers/net/ethernet/mediatek/mtk_wed.c |
| @@ -625,7 +625,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) |
| void *buf; |
| int s; |
| |
| - page = __dev_alloc_pages(GFP_KERNEL, 0); |
| + page = __dev_alloc_pages(GFP_KERNEL | GFP_DMA32, 0); |
| if (!page) |
| return -ENOMEM; |
| |
| @@ -646,10 +646,11 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) |
| |
| for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) { |
| struct mtk_wdma_desc *desc = desc_ptr; |
| + u32 ctrl; |
| |
| desc->buf0 = cpu_to_le32(buf_phys); |
| if (!mtk_wed_is_v3_or_greater(dev->hw)) { |
| - u32 txd_size, ctrl; |
| + u32 txd_size; |
| |
| txd_size = dev->wlan.init_buf(buf, buf_phys, |
| token++); |
| @@ -663,11 +664,11 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) |
| ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG0 | |
| FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, |
| MTK_WED_BUF_SIZE - txd_size); |
| - desc->ctrl = cpu_to_le32(ctrl); |
| desc->info = 0; |
| } else { |
| - desc->ctrl = cpu_to_le32(token << 16); |
| + ctrl = token << 16 | TX_DMA_SDP1(buf_phys); |
| } |
| + desc->ctrl = cpu_to_le32(ctrl); |
| |
| desc_ptr += desc_size; |
| buf += MTK_WED_BUF_SIZE; |
| @@ -749,7 +750,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev) |
| void *buf; |
| int s; |
| |
| - page = __dev_alloc_pages(GFP_KERNEL, 0); |
| + page = __dev_alloc_pages(GFP_KERNEL | GFP_DMA32, 0); |
| if (!page) |
| return -ENOMEM; |
| |
| @@ -769,6 +770,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev) |
| buf_phys = page_phys; |
| for (s = 0; s < MTK_WED_RX_PAGE_BUF_PER_PAGE; s++) { |
| desc->buf0 = cpu_to_le32(buf_phys); |
| + desc->token = cpu_to_le32(RX_DMA_SDP1(buf_phys)); |
| desc++; |
| buf += MTK_WED_PAGE_BUF_SIZE; |
| buf_phys += MTK_WED_PAGE_BUF_SIZE; |
| @@ -2457,6 +2459,10 @@ mtk_wed_attach(struct mtk_wed_device *dev) |
| dev->version = hw->version; |
| dev->hw->pci_base = mtk_wed_get_pci_base(dev); |
| |
| + ret = dma_set_mask_and_coherent(hw->dev, DMA_BIT_MASK(32)); |
| + if (ret) |
| + return ret; |
| + |
| if (hw->eth->dma_dev == hw->eth->dev && |
| of_dma_is_coherent(hw->eth->dev->of_node)) |
| mtk_eth_set_dma_device(hw->eth, hw->dev); |
| diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c |
| index 18d1fb1..a88061c 100644 |
| --- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c |
| +++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c |
| @@ -145,7 +145,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo) |
| }req; |
| |
| exp->log_size = EXCEPTION_LOG_SIZE; |
| - exp->log = kmalloc(exp->log_size, GFP_ATOMIC); |
| + exp->log = page_frag_alloc(&wo->page, exp->log_size, GFP_ATOMIC | GFP_DMA32); |
| if (!exp->log) |
| return -ENOMEM; |
| |
| @@ -165,7 +165,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo) |
| &req, sizeof(req), false); |
| |
| free: |
| - kfree(exp->log); |
| + skb_free_frag(exp->log); |
| return -ENOMEM; |
| } |
| |
| diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.c b/drivers/net/ethernet/mediatek/mtk_wed_wo.c |
| index 54b7787..e991d20 100644 |
| --- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c |
| +++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c |
| @@ -88,7 +88,7 @@ woif_q_rx_fill(struct mtk_wed_wo *wo, struct wed_wo_queue *q, bool rx) |
| page = &q->rx_page; |
| |
| while (q->queued < q->ndesc) { |
| - buf = page_frag_alloc(page, len, GFP_ATOMIC); |
| + buf = page_frag_alloc(page, len, GFP_ATOMIC | GFP_DMA32); |
| if (!buf) |
| break; |
| |
| @@ -555,7 +555,7 @@ void mtk_wed_wo_exit(struct mtk_wed_hw *hw) |
| |
| if (wo->exp.log) { |
| dma_unmap_single(wo->hw->dev, wo->exp.phys, wo->exp.log_size, DMA_FROM_DEVICE); |
| - kfree(wo->exp.log); |
| + skb_free_frag(wo->exp.log); |
| } |
| |
| wo->hw = NULL; |
| diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h |
| index b24fef3..5afa6de 100644 |
| --- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h |
| +++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h |
| @@ -193,6 +193,7 @@ struct mtk_wed_wo { |
| const struct wed_wo_drv_ops *drv_ops; |
| const struct wed_wo_mcu_ops *mcu_ops; |
| const struct wed_wo_queue_ops *queue_ops; |
| + struct page_frag_cache page; |
| |
| struct net_device napi_dev; |
| spinlock_t rx_lock; |
| -- |
| 2.18.0 |
| |