You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.1 KiB
128 lines
4.1 KiB
From 047a4e7b17322c1b32d8db32a0df9899cb4963a3 Mon Sep 17 00:00:00 2001
|
|
From: John Crispin <john@phrozen.org>
|
|
Date: Fri, 21 Jul 2017 08:48:38 +0200
|
|
Subject: [PATCH 37/57] net-next: mediatek: bring up QDMA RX ring 0
|
|
|
|
This patch is in peparation for adding HW flow and QoS offloading. For
|
|
those features to work, the driver needs to bring up the first QDMA RX
|
|
ring. This ring is used by the PPE offloading HW.
|
|
|
|
Signed-off-by: John Crispin <john@phrozen.org>
|
|
---
|
|
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 38 ++++++++++++++++++++---------
|
|
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +++
|
|
2 files changed, 30 insertions(+), 11 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
|
@@ -1224,11 +1224,21 @@ static void mtk_tx_clean(struct mtk_eth
|
|
|
|
static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
|
|
{
|
|
- struct mtk_rx_ring *ring = ð->rx_ring[ring_no];
|
|
+ struct mtk_rx_ring *ring;
|
|
int rx_data_len, rx_dma_size;
|
|
int i;
|
|
+ u32 offset = 0;
|
|
|
|
- if (rx_flag == MTK_RX_FLAGS_HWLRO) {
|
|
+ if (rx_flag & MTK_RX_FLAGS_QDMA) {
|
|
+ if (ring_no)
|
|
+ return -EINVAL;
|
|
+ ring = ð->rx_ring_qdma;
|
|
+ offset = 0x1000;
|
|
+ } else {
|
|
+ ring = ð->rx_ring[ring_no];
|
|
+ }
|
|
+
|
|
+ if (rx_flag & MTK_RX_FLAGS_HWLRO) {
|
|
rx_data_len = MTK_MAX_LRO_RX_LENGTH;
|
|
rx_dma_size = MTK_HW_LRO_DMA_SIZE;
|
|
} else {
|
|
@@ -1276,17 +1286,16 @@ static int mtk_rx_alloc(struct mtk_eth *
|
|
*/
|
|
wmb();
|
|
|
|
- mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no));
|
|
- mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no));
|
|
- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
|
|
- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX);
|
|
+ mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset);
|
|
+ mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset);
|
|
+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset);
|
|
+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset);
|
|
|
|
return 0;
|
|
}
|
|
|
|
-static void mtk_rx_clean(struct mtk_eth *eth, int ring_no)
|
|
+static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
|
|
{
|
|
- struct mtk_rx_ring *ring = ð->rx_ring[ring_no];
|
|
int i;
|
|
|
|
if (ring->data && ring->dma) {
|
|
@@ -1612,6 +1621,10 @@ static int mtk_dma_init(struct mtk_eth *
|
|
if (err)
|
|
return err;
|
|
|
|
+ err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_QDMA);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_NORMAL);
|
|
if (err)
|
|
return err;
|
|
@@ -1651,12 +1664,13 @@ static void mtk_dma_free(struct mtk_eth
|
|
eth->phy_scratch_ring = 0;
|
|
}
|
|
mtk_tx_clean(eth);
|
|
- mtk_rx_clean(eth, 0);
|
|
+ mtk_rx_clean(eth, ð->rx_ring[0]);
|
|
+ mtk_rx_clean(eth, ð->rx_ring_qdma);
|
|
|
|
if (eth->hwlro) {
|
|
mtk_hwlro_rx_uninit(eth);
|
|
for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
|
|
- mtk_rx_clean(eth, i);
|
|
+ mtk_rx_clean(eth, ð->rx_ring[i]);
|
|
}
|
|
|
|
kfree(eth->scratch_head);
|
|
@@ -1723,7 +1737,9 @@ static int mtk_start_dma(struct mtk_eth
|
|
|
|
mtk_w32(eth,
|
|
MTK_TX_WB_DDONE | MTK_TX_DMA_EN |
|
|
- MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO,
|
|
+ MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO |
|
|
+ MTK_RX_DMA_EN | MTK_RX_2B_OFFSET |
|
|
+ MTK_RX_BT_32DWORDS,
|
|
MTK_QDMA_GLO_CFG);
|
|
|
|
mtk_w32(eth,
|
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
|
@@ -484,6 +484,7 @@ struct mtk_tx_ring {
|
|
enum mtk_rx_flags {
|
|
MTK_RX_FLAGS_NORMAL = 0,
|
|
MTK_RX_FLAGS_HWLRO,
|
|
+ MTK_RX_FLAGS_QDMA,
|
|
};
|
|
|
|
/* struct mtk_rx_ring - This struct holds info describing a RX ring
|
|
@@ -527,6 +528,7 @@ struct mtk_rx_ring {
|
|
* @dma_refcnt: track how many netdevs are using the DMA engine
|
|
* @tx_ring: Pointer to the memory holding info about the TX ring
|
|
* @rx_ring: Pointer to the memory holding info about the RX ring
|
|
+ * @rx_ring_qdma: Pointer to the memory holding info about the QDMA RX ring
|
|
* @tx_napi: The TX NAPI struct
|
|
* @rx_napi: The RX NAPI struct
|
|
* @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
|
|
@@ -556,6 +558,7 @@ struct mtk_eth {
|
|
atomic_t dma_refcnt;
|
|
struct mtk_tx_ring tx_ring;
|
|
struct mtk_rx_ring rx_ring[MTK_MAX_RX_RING_NUM];
|
|
+ struct mtk_rx_ring rx_ring_qdma;
|
|
struct napi_struct tx_napi;
|
|
struct napi_struct rx_napi;
|
|
struct mtk_tx_dma *scratch_ring;
|
|
|