introduce mt7986 ethernet support
Subsystems (5)
Lorenzo Bianconi
maintainerv2 cover introduce mt7986 ethernet support
Add support for mt7986-eth driver available on mt7986 soc.
Changes since v1:
- drop SRAM option
- convert ring->dma to void
- convert scratch_ring to void
- enable port4
- fix irq dts bindings
- drop gmac1 support from mt7986a-rfb dts for the moment
Lorenzo Bianconi (15):
arm64: dts: mediatek: mt7986: introduce ethernet nodes
dt-bindings: net: mediatek,net: add mt7986-eth binding
net: ethernet: mtk_eth_soc: move tx dma desc configuration in
mtk_tx_set_dma_desc
net: ethernet: mtk_eth_soc: add txd_size to mtk_soc_data
net: ethernet: mtk_eth_soc: rely on txd_size in
mtk_tx_alloc/mtk_tx_clean
net: ethernet: mtk_eth_soc: rely on txd_size in mtk_desc_to_tx_buf
net: ethernet: mtk_eth_soc: rely on txd_size in txd_to_idx
net: ethernet: mtk_eth_soc: add rxd_size to mtk_soc_data
net: ethernet: mtk_eth_soc: rely on txd_size field in
mtk_poll_tx/mtk_poll_rx
net: ethernet: mtk_eth_soc: rely on rxd_size field in
mtk_rx_alloc/mtk_rx_clean
net: ethernet: mtk_eth_soc: introduce device register map
net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
net: ethernet: mtk_eth_soc: convert ring dma pointer to void
net: ethernet: mtk_eth_soc: convert scratch_ring pointer to void
net: ethernet: mtk_eth_soc: introduce support for mt7986 chipset
.../devicetree/bindings/net/mediatek,net.yaml | 141 +++- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 74 ++ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 39 ++ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 70 ++ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 630 +++++++++++++----- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 328 +++++++-- 6 files changed, 1037 insertions(+), 245 deletions(-)
Signature · 7 lines
2.35.3 _______________________________________________ Linux-mediatek mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-mediatek
Lorenzo Bianconi
maintainerPATCH v2 1/15 arm64: dts: mediatek: mt7986: introduce ethernet nodes
Introduce ethernet nodes in mt7986 bindings in order to enable mt7986a/mt7986b ethernet support.
--- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 74 ++++++++++++++++++++ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 39 +++++++++++ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 70 ++++++++++++++++++ 3 files changed, 183 insertions(+)
arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts +74 -0
@@ -25,6 +25,80 @@ memory@40000000 { }; }; +ð { + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&mdio { + switch: switch@0 { + compatible = "mediatek,mt7531"; + reg = <31>; + reset-gpios = <&pio 5 0>; + }; +}; + +&switch { + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan0"; + }; + + port@1 { + reg = <1>; + label = "lan1"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan3"; + }; + + port@4 { + reg = <4>; + label = "lan4"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; +}; + &uart0 { status = "okay"; };
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +39 -0
@@ -222,6 +222,45 @@ ethsys: syscon@15000000 { #reset-cells = <1>; }; + eth: ethernet@15100000 { + compatible = "mediatek,mt7986-eth"; + reg = <0 0x15100000 0 0x80000>; + interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>; + clocks = <ðsys CLK_ETH_FE_EN>, + <ðsys CLK_ETH_GP2_EN>, + <ðsys CLK_ETH_GP1_EN>, + <ðsys CLK_ETH_WOCPU1_EN>, + <ðsys CLK_ETH_WOCPU0_EN>, + <&sgmiisys0 CLK_SGMII0_TX250M_EN>, + <&sgmiisys0 CLK_SGMII0_RX250M_EN>, + <&sgmiisys0 CLK_SGMII0_CDR_REF>, + <&sgmiisys0 CLK_SGMII0_CDR_FB>, + <&sgmiisys1 CLK_SGMII1_TX250M_EN>, + <&sgmiisys1 CLK_SGMII1_RX250M_EN>, + <&sgmiisys1 CLK_SGMII1_CDR_REF>, + <&sgmiisys1 CLK_SGMII1_CDR_FB>, + <&topckgen CLK_TOP_NETSYS_SEL>, + <&topckgen CLK_TOP_NETSYS_500M_SEL>; + clock-names = "fe", "gp2", "gp1", "wocpu1", "wocpu0", + "sgmii_tx250m", "sgmii_rx250m", + "sgmii_cdr_ref", "sgmii_cdr_fb", + "sgmii2_tx250m", "sgmii2_rx250m", + "sgmii2_cdr_ref", "sgmii2_cdr_fb", + "netsys0", "netsys1"; + assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>, + <&topckgen CLK_TOP_SGM_325M_SEL>; + assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>, + <&apmixedsys CLK_APMIXED_SGMPLL>; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>; + #reset-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; };
arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts +70 -0
73 lines not on this page · raw message
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 2/15 dt-bindings: net: mediatek,net: add mt7986-eth binding
In reply to Lorenzo BianconiIntroduce dts bindings for mt7986 soc in mediatek,net.yaml.
--- .../devicetree/bindings/net/mediatek,net.yaml | 141 +++++++++++++++++- 1 file changed, 139 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/net/mediatek,net.yaml +139 -2
@@ -21,6 +21,7 @@ properties: - mediatek,mt7623-eth - mediatek,mt7622-eth - mediatek,mt7629-eth + - mediatek,mt7986-eth - ralink,rt5350-eth reg:
@@ -28,7 +29,7 @@ properties: interrupts: minItems: 3 - maxItems: 3 + maxItems: 4 power-domains: maxItems: 1
@@ -88,6 +89,9 @@ allOf: - mediatek,mt7623-eth then: properties: + interrupts: + maxItems: 3 + clocks: minItems: 4 maxItems: 4
@@ -112,6 +116,9 @@ allOf: const: mediatek,mt7622-eth then: properties: + interrupts: + maxItems: 3 + clocks: minItems: 11 maxItems: 11
@@ -155,6 +162,9 @@ allOf: const: mediatek,mt7629-eth then: properties: + interrupts: + maxItems: 3 + clocks: minItems: 17 maxItems: 17
@@ -189,6 +199,42 @@ allOf: minItems: 2 maxItems: 2 + - if: + properties: + compatible: + contains: + const: mediatek,mt7986-eth + then: + properties: + interrupts: + minItems: 4 + + clocks: + minItems: 15 + maxItems: 15 + + clock-names: + items: + - const: fe + - const: gp2 + - const: gp1 + - const: wocpu1 + - const: wocpu0 + - const: sgmii_tx250m + - const: sgmii_rx250m + - const: sgmii_cdr_ref + - const: sgmii_cdr_fb + - const: sgmii2_tx250m + - const: sgmii2_rx250m + - const: sgmii2_cdr_ref + - const: sgmii2_cdr_fb + - const: netsys0 + - const: netsys1 + + mediatek,sgmiisys: + minItems: 2 + maxItems: 2 + patternProperties: "^mac@[0-1]$": type: object
@@ -219,7 +265,6 @@ required: - interrupts - clocks - clock-names - - power-domains - mediatek,ethsys unevaluatedProperties: false
@@ -295,3 +340,95 @@ examples: }; }; }; + + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/clock/mt7622-clk.h> + + soc { + #address-cells = <2>; + #size-cells = <2>; + + eth: ethernet@15100000 { + #define CLK_ETH_FE_EN 0 + #define CLK_ETH_WOCPU1_EN 3 + #define CLK_ETH_WOCPU0_EN 4 + #define CLK_TOP_NETSYS_SEL 43 + #define CLK_TOP_NETSYS_500M_SEL 44 + #define CLK_TOP_NETSYS_2X_SEL 46 + #define CLK_TOP_SGM_325M_SEL 47 + #define CLK_APMIXED_NET2PLL 1 + #define CLK_APMIXED_SGMPLL 3 + + compatible = "mediatek,mt7986-eth"; + reg = <0 0x15100000 0 0x80000>; + interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>; + clocks = <ðsys CLK_ETH_FE_EN>, + <ðsys CLK_ETH_GP2_EN>, + <ðsys CLK_ETH_GP1_EN>, + <ðsys CLK_ETH_WOCPU1_EN>, + <ðsys CLK_ETH_WOCPU0_EN>, + <&sgmiisys0 CLK_SGMII_TX250M_EN>, + <&sgmiisys0 CLK_SGMII_RX250M_EN>, + <&sgmiisys0 CLK_SGMII_CDR_REF>, + <&sgmiisys0 CLK_SGMII_CDR_FB>, + <&sgmiisys1 CLK_SGMII_TX250M_EN>, + <&sgmiisys1 CLK_SGMII_RX250M_EN>, + <&sgmiisys1 CLK_SGMII_CDR_REF>, + <&sgmiisys1 CLK_SGMII_CDR_FB>, + <&topckgen CLK_TOP_NETSYS_SEL>, + <&topckgen CLK_TOP_NETSYS_SEL>; + clock-names = "fe", "gp2", "gp1", "wocpu1", "wocpu0", + "sgmii_tx250m", "sgmii_rx250m", + "sgmii_cdr_ref", "sgmii_cdr_fb", + "sgmii2_tx250m", "sgmii2_rx250m", + "sgmii2_cdr_ref", "sgmii2_cdr_fb", + "netsys0", "netsys1"; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>; + assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>, + <&topckgen CLK_TOP_SGM_325M_SEL>; + assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>, + <&apmixedsys CLK_APMIXED_SGMPLL>; + + #address-cells = <1>; + #size-cells = <0>; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + phy5: ethernet-phy@0 { + compatible = "ethernet-phy-id67c9.de0a"; + phy-mode = "2500base-x"; + reset-gpios = <&pio 6 1>; + reset-deassert-us = <20000>; + reg = <5>; + }; + + phy6: ethernet-phy@1 { + compatible = "ethernet-phy-id67c9.de0a"; + phy-mode = "2500base-x"; + reg = <6>; + }; + }; + + mac0: mac@0 { + compatible = "mediatek,eth-mac"; + phy-mode = "2500base-x"; + phy-handle = <&phy5>; + reg = <0>; + }; + + mac1: mac@1 { + compatible = "mediatek,eth-mac"; + phy-mode = "2500base-x"; + phy-handle = <&phy6>; + reg = <1>; + }; + }; + };
Signature · 1 line
2.35.3
Re: [PATCH v2 net-next 02/15] dt-bindings: net: mediatek,net: add mt7986-eth binding
Quoted 7 lines · Lorenzo Bianconi
Introduce dts bindings for mt7986 soc in mediatek,net.yaml.
Signed-off-by Lorenzo Bianconi <[email protected]>--- .../devicetree/bindings/net/mediatek,net.yaml | 141 +++++++++++++++++- 1 file changed, 139 insertions(+), 2 deletions(-)
Doesn't apply for me, so not tested, but:
Lorenzo Bianconi
maintainerPATCH v2 3/15 net: ethernet: mtk_eth_soc: move tx dma desc configuration in mtk_tx_set_dma_desc
In reply to Lorenzo BianconiMove tx dma descriptor configuration in mtk_tx_set_dma_desc routine. This is a preliminary patch to introduce mt7986 ethernet support since it relies on a different tx dma descriptor layout.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 +++++++++++--------- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 ++ 2 files changed, 67 insertions(+), 49 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +56 -49
@@ -918,18 +918,51 @@ static void setup_tx_buf(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, } } +static void mtk_tx_set_dma_desc (struct net_device *dev,struct mtk_tx_dma *desc, +struct mtk_tx_dma_desc_info *info) +{ +struct mtk_mac *mac =netdev_priv (dev); +u32 data; + +WRITE_ONCE (desc->txd1, info->addr); + + data =TX_DMA_SWC |TX_DMA_PLEN0 (info->size); +if (info->last) + data |=TX_DMA_LS0 ; +WRITE_ONCE (desc->txd3, data); + + data = (mac->id +1 ) <<TX_DMA_FPORT_SHIFT ;/* forward port */ +if (info->first) { +if (info->gso) + data |=TX_DMA_TSO ; +/* tx checksum offload */ +if (info->csum) + data |=TX_DMA_CHKSUM ; +/* vlan header offload */ +if (info->vlan) + data |=TX_DMA_INS_VLAN | info->vlan_tci; + } +WRITE_ONCE (desc->txd4, data); +} +static int mtk_tx_map (struct sk_buff *skb,struct net_device *dev,int tx_num,struct mtk_tx_ring *ring,bool gso) { +struct mtk_tx_dma_desc_info txd_info = { + .size =skb_headlen (skb), + .gso = gso, + .csum = skb->ip_summed ==CHECKSUM_PARTIAL , + .vlan =skb_vlan_tag_present (skb), + .vlan_tci =skb_vlan_tag_get (skb), + .first = true, + .last = !skb_is_nonlinear (skb), + };struct mtk_mac *mac =netdev_priv (dev);struct mtk_eth *eth = mac->hw;struct mtk_tx_dma *itxd, *txd;struct mtk_tx_dma *itxd_pdma, *txd_pdma;struct mtk_tx_buf *itx_buf, *tx_buf; -dma_addr_t mapped_addr; -unsigned int nr_frags;int i, n_desc =1 ; -u32 txd4 =0 , fport;int k =0 ; itxd = ring->next_free;
@@ -937,49 +970,32 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,if (itxd == ring->last_free)return -ENOMEM ; -/* set the forward port */ - fport = (mac->id +1 ) <<TX_DMA_FPORT_SHIFT ; - txd4 |= fport; - itx_buf =mtk_desc_to_tx_buf (ring, itxd);memset (itx_buf,0 ,sizeof (*itx_buf)); -if (gso) - txd4 |=TX_DMA_TSO ; - -/* TX Checksum offload */ -if (skb->ip_summed ==CHECKSUM_PARTIAL ) - txd4 |=TX_DMA_CHKSUM ; - -/* VLAN header offload */ -if (skb_vlan_tag_present (skb)) - txd4 |=TX_DMA_INS_VLAN |skb_vlan_tag_get (skb); - - mapped_addr =dma_map_single (eth->dma_dev, skb->data, -skb_headlen (skb),DMA_TO_DEVICE ); -if (unlikely (dma_mapping_error (eth->dma_dev, mapped_addr))) + txd_info.addr =dma_map_single (eth->dma_dev, skb->data, txd_info.size, +DMA_TO_DEVICE ); +if (unlikely (dma_mapping_error (eth->dma_dev, txd_info.addr)))return -ENOMEM ; -WRITE_ONCE (itxd->txd1, mapped_addr); +mtk_tx_set_dma_desc (dev, itxd, &txd_info); + itx_buf->flags |=MTK_TX_FLAGS_SINGLE0 ; itx_buf->flags |= (!mac->id) ?MTK_TX_FLAGS_FPORT0 :MTK_TX_FLAGS_FPORT1 ; -setup_tx_buf (eth, itx_buf, itxd_pdma, mapped_addr,skb_headlen (skb), +setup_tx_buf (eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, k++);/* TX SG offload */ txd = itxd; txd_pdma =qdma_to_pdma (ring, txd); - nr_frags =skb_shinfo (skb)->nr_frags; -for (i =0 ; i < nr_frags; i++) { +for (i =0 ; i <skb_shinfo (skb)->nr_frags; i++) {skb_frag_t *frag = &skb_shinfo (skb)->frags[i];unsigned int offset =0 ;int frag_size =skb_frag_size (frag);while (frag_size) { -bool last_frag = false; -unsigned int frag_map_size;bool new_desc = true; if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) ||
@@ -994,23 +1010,17 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, new_desc = false; } - - frag_map_size =min (frag_size,MTK_TX_DMA_BUF_LEN ); - mapped_addr =skb_frag_dma_map (eth->dma_dev, frag, offset, - frag_map_size, -DMA_TO_DEVICE ); -if (unlikely (dma_mapping_error (eth->dma_dev, mapped_addr))) +memset (&txd_info,0 ,sizeof (struct mtk_tx_dma_desc_info )); + txd_info.size =min (frag_size,MTK_TX_DMA_BUF_LEN ); + txd_info.last = i ==skb_shinfo (skb)->nr_frags -1 && + !(frag_size - txd_info.size); + txd_info.addr =skb_frag_dma_map (eth->dma_dev, frag, + offset, txd_info.size, +DMA_TO_DEVICE ); +if (unlikely (dma_mapping_error (eth->dma_dev, txd_info.addr))) goto err_dma; -if (i == nr_frags -1 && - (frag_size - frag_map_size) ==0 ) - last_frag = true; - -WRITE_ONCE (txd->txd1, mapped_addr); -WRITE_ONCE (txd->txd3, (TX_DMA_SWC | -TX_DMA_PLEN0 (frag_map_size) | - last_frag *TX_DMA_LS0 )); -WRITE_ONCE (txd->txd4, fport); +mtk_tx_set_dma_desc (dev, txd, &txd_info); tx_buf =mtk_desc_to_tx_buf (ring, txd);if (new_desc)
@@ -1020,20 +1030,17 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, tx_buf->flags |= (!mac->id) ?MTK_TX_FLAGS_FPORT0 :MTK_TX_FLAGS_FPORT1 ; -setup_tx_buf (eth, tx_buf, txd_pdma, mapped_addr, - frag_map_size, k++); +setup_tx_buf (eth, tx_buf, txd_pdma, txd_info.addr, + txd_info.size, k++); - frag_size -= frag_map_size; - offset += frag_map_size; + frag_size -= txd_info.size; + offset += txd_info.size; } }/* store skb to cleanup */ itx_buf->skb = skb; -WRITE_ONCE (itxd->txd4, txd4); -WRITE_ONCE (itxd->txd3, (TX_DMA_SWC |TX_DMA_PLEN0 (skb_headlen (skb)) | - (!nr_frags *TX_DMA_LS0 )));if (!MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA )) {if (k &0x1 ) txd_pdma->txd2 |=TX_DMA_LS0 ;
drivers/net/ethernet/mediatek/mtk_eth_soc.h +11 -0
@@ -844,6 +844,17 @@ enum mkt_eth_capabilities { MTK_MUX_U3_GMAC2_TO_QPHY | \ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) +struct mtk_tx_dma_desc_info { +dma_addr_t addr; +u32 size; +u16 vlan_tci; +u8 gso:1 ; +u8 csum:1 ; +u8 vlan:1 ; +u8 first:1 ; +u8 last:1 ; +}; +/* struct mtk_eth_data - This is the structure holding all differences * among various plaforms * @ana_rgc3: The offset for register ANA_RGC3 related to
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 4/15 net: ethernet: mtk_eth_soc: add txd_size to mtk_soc_data
In reply to Lorenzo BianconiIn order to remove mtk_tx_dma size dependency, introduce txd_size in mtk_soc_data data structure. Rely on txd_size in mtk_init_fq_dma() and mtk_dma_free() routines.
This is a preliminary patch to add mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 47 +++++++++++++++------ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++ 2 files changed, 38 insertions(+), 13 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +34 -13
@@ -784,20 +784,20 @@ static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd,/* the qdma core needs scratch memory to be setup */ static int mtk_init_fq_dma (struct mtk_eth *eth) { +const struct mtk_soc_data *soc = eth->soc;dma_addr_t phy_ring_tail;int cnt =MTK_DMA_SIZE ;dma_addr_t dma_addr;int i; eth->scratch_ring =dma_alloc_coherent (eth->dma_dev, - cnt *sizeof (struct mtk_tx_dma ), + cnt * soc->txrx.txd_size, ð->phy_scratch_ring,GFP_ATOMIC );if (unlikely (!eth->scratch_ring))return -ENOMEM ; - eth->scratch_head =kcalloc (cnt,MTK_QDMA_PAGE_SIZE , -GFP_KERNEL ); + eth->scratch_head =kcalloc (cnt,MTK_QDMA_PAGE_SIZE ,GFP_KERNEL );if (unlikely (!eth->scratch_head))return -ENOMEM ;
@@ -807,16 +807,19 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)if (unlikely (dma_mapping_error (eth->dma_dev, dma_addr)))return -ENOMEM ; - phy_ring_tail = eth->phy_scratch_ring + - (sizeof (struct mtk_tx_dma ) * (cnt -1 )); + phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt -1 );for (i =0 ; i < cnt; i++) { - eth->scratch_ring[i].txd1 = - (dma_addr + (i *MTK_QDMA_PAGE_SIZE )); +struct mtk_tx_dma *txd; + + txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size; + txd->txd1 = dma_addr + i *MTK_QDMA_PAGE_SIZE ;if (i < cnt -1 ) - eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring + - ((i +1 ) *sizeof (struct mtk_tx_dma ))); - eth->scratch_ring[i].txd3 =TX_DMA_SDL (MTK_QDMA_PAGE_SIZE ); + txd->txd2 = eth->phy_scratch_ring + + (i +1 ) * soc->txrx.txd_size; + + txd->txd3 =TX_DMA_PLEN0 (MTK_QDMA_PAGE_SIZE ); + txd->txd4 =0 ; }mtk_w32 (eth, eth->phy_scratch_ring,MTK_QDMA_FQ_HEAD );
@@ -2108,6 +2111,7 @@ static int mtk_dma_init(struct mtk_eth *eth)static void mtk_dma_free (struct mtk_eth *eth) { +const struct mtk_soc_data *soc = eth->soc;int i;for (i =0 ; i <MTK_MAC_COUNT ; i++)
@@ -2115,9 +2119,8 @@ static void mtk_dma_free(struct mtk_eth *eth)netdev_reset_queue (eth->netdev[i]);if (eth->scratch_ring) {dma_free_coherent (eth->dma_dev, -MTK_DMA_SIZE *sizeof (struct mtk_tx_dma ), - eth->scratch_ring, - eth->phy_scratch_ring); +MTK_DMA_SIZE * soc->txrx.txd_size, + eth->scratch_ring, eth->phy_scratch_ring); eth->scratch_ring =NULL ; eth->phy_scratch_ring =0 ; }
@@ -3353,6 +3356,9 @@ static const struct mtk_soc_data mt2701_data = { .hw_features = MTK_HW_FEATURES, .required_clks = MT7623_CLKS_BITMAP, .required_pctl = true, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + }, };static const struct mtk_soc_data mt7621_data = {
@@ -3361,6 +3367,9 @@ static const struct mtk_soc_data mt7621_data = { .required_clks = MT7621_CLKS_BITMAP, .required_pctl = false, .offload_version = 2, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + }, };static const struct mtk_soc_data mt7622_data = {
@@ -3370,6 +3379,9 @@ static const struct mtk_soc_data mt7622_data = { .required_clks = MT7622_CLKS_BITMAP, .required_pctl = false, .offload_version = 2, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + }, };static const struct mtk_soc_data mt7623_data = {
@@ -3378,6 +3390,9 @@ static const struct mtk_soc_data mt7623_data = { .required_clks = MT7623_CLKS_BITMAP, .required_pctl = true, .offload_version = 2, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + }, };static const struct mtk_soc_data mt7629_data = {
@@ -3386,6 +3401,9 @@ static const struct mtk_soc_data mt7629_data = { .hw_features = MTK_HW_FEATURES, .required_clks = MT7629_CLKS_BITMAP, .required_pctl = false, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + }, };static const struct mtk_soc_data rt5350_data = {
@@ -3393,6 +3411,9 @@ static const struct mtk_soc_data rt5350_data = { .hw_features = MTK_HW_FEATURES_MT7628, .required_clks = MT7628_CLKS_BITMAP, .required_pctl = false, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + }, };const struct of_device_id of_mtk_match[] = {
drivers/net/ethernet/mediatek/mtk_eth_soc.h +4 -0
@@ -865,6 +865,7 @@ struct mtk_tx_dma_desc_info {* the target SoC * @required_pctl A bool value to show whether the SoC requires * the extra setup for those pins used by GMAC. +* @txd_size TX DMA descriptor size. */ struct mtk_soc_data {u32 ana_rgc3;
@@ -873,6 +874,9 @@ struct mtk_soc_data {bool required_pctl;u8 offload_version;netdev_features_t hw_features; +struct { +u32 txd_size; + } txrx; };/* currently no SoC has more than 2 macs */
Signature · 1 line
2.35.3
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 04/15] net: ethernet: mtk_eth_soc: add txd_size to mtk_soc_data
drivers/net/ethernet/mediatek/mtk_eth_soc.c static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd, · line 800
Quoted 11 lines · On Mon, 16 May 2022 18:06:31 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.c +2
-3eth->scratch_ring =dma_alloc_coherent (eth->dma_dev, - cnt *sizeof (struct mtk_tx_dma ), + cnt * soc->txrx.txd_size, ð->phy_scratch_ring,GFP_ATOMIC );if (unlikely (!eth->scratch_ring))return -ENOMEM ; - eth->scratch_head =kcalloc (cnt,MTK_QDMA_PAGE_SIZE , -GFP_KERNEL ); + eth->scratch_head =kcalloc (cnt,MTK_QDMA_PAGE_SIZE ,GFP_KERNEL );
Unrelated, but GFP_ATOMIC right next to GFP_KERNEL caught my attention.
Lorenzo Bianconi
maintainerRe: [PATCH v2 net-next 04/15] net: ethernet: mtk_eth_soc: add txd_size to mtk_soc_data
Quoted 9 lines · On Mon, 16 May 2022 18:06:31 +0200 Lorenzo Bianconi wrote:
Quoted 8 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +1
-1eth->scratch_ring =dma_alloc_coherent (eth->dma_dev, - cnt *sizeof (struct mtk_tx_dma ), + cnt * soc->txrx.txd_size, ð->phy_scratch_ring,GFP_ATOMIC );if (unlikely (!eth->scratch_ring))return -ENOMEM ;
Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd, · line 800
Quoted 3 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +1
-2- eth->scratch_head =kcalloc (cnt,MTK_QDMA_PAGE_SIZE , -GFP_KERNEL ); + eth->scratch_head =kcalloc (cnt,MTK_QDMA_PAGE_SIZE ,GFP_KERNEL );Unrelated, but
GFP_ATOMICright next toGFP_KERNELcaught my attention.
ack, mtk_init_fq_dma() is run by mtk_open() so it is ok to use GFP_KERNEL. I will fix it in v3.
Regards,
Lorenzo
Lorenzo Bianconi
maintainerPATCH v2 5/15 net: ethernet: mtk_eth_soc: rely on txd_size in mtk_tx_alloc/mtk_tx_clean
In reply to Lorenzo BianconiThis is a preliminary patch to add mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 39 ++++++++++++--------- 1 file changed, 22 insertions(+), 17 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +22 -17
@@ -1568,25 +1568,30 @@ static int mtk_napi_rx(struct napi_struct *napi, int budget)static int mtk_tx_alloc (struct mtk_eth *eth) { +const struct mtk_soc_data *soc = eth->soc;struct mtk_tx_ring *ring = ð->tx_ring; -int i, sz =sizeof (*ring->dma); +struct mtk_tx_dma *txd; +int i; ring->buf =kcalloc (MTK_DMA_SIZE ,sizeof (*ring->buf),GFP_KERNEL );if (!ring->buf) goto no_tx_mem; - ring->dma =dma_alloc_coherent (eth->dma_dev,MTK_DMA_SIZE * sz, + ring->dma =dma_alloc_coherent (eth->dma_dev, +MTK_DMA_SIZE * soc->txrx.txd_size, &ring->phys,GFP_ATOMIC );if (!ring->dma) goto no_tx_mem;for (i =0 ; i <MTK_DMA_SIZE ; i++) {int next = (i +1 ) %MTK_DMA_SIZE ; -u32 next_ptr = ring->phys + next * sz; +u32 next_ptr = ring->phys + next * soc->txrx.txd_size; - ring->dma[i].txd2 = next_ptr; - ring->dma[i].txd3 =TX_DMA_LS0 |TX_DMA_OWNER_CPU ; + txd = (void *)ring->dma + i * soc->txrx.txd_size; + txd->txd2 = next_ptr; + txd->txd3 =TX_DMA_LS0 |TX_DMA_OWNER_CPU ; + txd->txd4 =0 ; }/* On MT7688 (PDMA only) this driver uses the ring->dma structs
@@ -1594,9 +1599,9 @@ static int mtk_tx_alloc(struct mtk_eth *eth)* descriptors in ring->dma_pdma. */ if (!MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA )) { - ring->dma_pdma =dma_alloc_coherent (eth->dma_dev,MTK_DMA_SIZE * sz, - &ring->phys_pdma, -GFP_ATOMIC ); + ring->dma_pdma =dma_alloc_coherent (eth->dma_dev, +MTK_DMA_SIZE * soc->txrx.txd_size, + &ring->phys_pdma,GFP_ATOMIC );if (!ring->dma_pdma) goto no_tx_mem;
@@ -1609,8 +1614,9 @@ static int mtk_tx_alloc(struct mtk_eth *eth) ring->dma_size =MTK_DMA_SIZE ;atomic_set (&ring->free_count,MTK_DMA_SIZE -2 ); ring->next_free = &ring->dma[0 ]; - ring->last_free = &ring->dma[MTK_DMA_SIZE -1 ]; - ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE -1 ) * sz)); + ring->last_free = (void *)txd; + ring->last_free_ptr = (u32)(ring->phys + + (MTK_DMA_SIZE -1 ) * soc->txrx.txd_size); ring->thresh =MAX_SKB_FRAGS ;/* make sure that all changes to the dma ring are flushed before we
@@ -1622,7 +1628,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)mtk_w32 (eth, ring->phys,MTK_QTX_CTX_PTR );mtk_w32 (eth, ring->phys,MTK_QTX_DTX_PTR );mtk_w32 (eth, - ring->phys + ((MTK_DMA_SIZE -1 ) * sz), + ring->phys + (MTK_DMA_SIZE -1 ) * soc->txrx.txd_size,MTK_QTX_CRX_PTR );mtk_w32 (eth, ring->last_free_ptr,MTK_QTX_DRX_PTR ); mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
@@ -1642,6 +1648,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)static void mtk_tx_clean (struct mtk_eth *eth) { +const struct mtk_soc_data *soc = eth->soc;struct mtk_tx_ring *ring = ð->tx_ring;int i;
@@ -1654,17 +1661,15 @@ static void mtk_tx_clean(struct mtk_eth *eth)if (ring->dma) {dma_free_coherent (eth->dma_dev, -MTK_DMA_SIZE *sizeof (*ring->dma), - ring->dma, - ring->phys); +MTK_DMA_SIZE * soc->txrx.txd_size, + ring->dma, ring->phys); ring->dma =NULL ; }if (ring->dma_pdma) {dma_free_coherent (eth->dma_dev, -MTK_DMA_SIZE *sizeof (*ring->dma_pdma), - ring->dma_pdma, - ring->phys_pdma); +MTK_DMA_SIZE * soc->txrx.txd_size, + ring->dma_pdma, ring->phys_pdma); ring->dma_pdma =NULL ; } }
Signature · 1 line
2.35.3
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 05/15] net: ethernet: mtk_eth_soc: rely on txd_size in mtk_tx_alloc/mtk_tx_clean
drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_napi_rx(struct napi_struct *napi, int budget) · line 1572
Quoted 5 lines · On Mon, 16 May 2022 18:06:32 +0200 Lorenzo Bianconi wrote:
static int
mtk_tx_alloc(struct mtk_eth *eth)
{drivers/net/ethernet/mediatek/mtk_eth_soc.c +1
-1+const struct mtk_soc_data *soc = eth->soc;struct mtk_tx_ring *ring = ð->tx_ring; -int i, sz =sizeof (*ring->dma);
The change would be smaller if you left sz in place. I guess you have a reason not to?
drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_napi_rx(struct napi_struct *napi, int budget) · line 1583
Quoted 12 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +4
-1+struct mtk_tx_dma *txd; +int i; ring->buf =kcalloc (MTK_DMA_SIZE ,sizeof (*ring->buf),GFP_KERNEL );if (!ring->buf) goto no_tx_mem; - ring->dma =dma_alloc_coherent (eth->dma_dev,MTK_DMA_SIZE * sz, + ring->dma =dma_alloc_coherent (eth->dma_dev, +MTK_DMA_SIZE * soc->txrx.txd_size, &ring->phys,GFP_ATOMIC );
Another GFP nugget.
Lorenzo Bianconi
maintainerRe: [PATCH v2 net-next 05/15] net: ethernet: mtk_eth_soc: rely on txd_size in mtk_tx_alloc/mtk_tx_clean
Quoted 9 lines · On Mon, 16 May 2022 18:06:32 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_napi_rx(struct napi_struct *napi, int budget) · line 1572
Quoted 5 lines
static int
mtk_tx_alloc(struct mtk_eth *eth)
{drivers/net/ethernet/mediatek/mtk_eth_soc.c +1
-1+const struct mtk_soc_data *soc = eth->soc;struct mtk_tx_ring *ring = ð->tx_ring; -int i, sz =sizeof (*ring->dma);The change would be smaller if you left sz in place. I guess you have a reason not to?
ack, I will do in v3.
Quoted 9 lines
Quoted 9 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +2
-0+struct mtk_tx_dma *txd; +int i; ring->buf =kcalloc (MTK_DMA_SIZE ,sizeof (*ring->buf),GFP_KERNEL );if (!ring->buf) goto no_tx_mem;
Quoted 6 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_napi_rx(struct napi_struct *napi, int budget) · line 1583
Quoted 4 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +2
-1- ring->dma =dma_alloc_coherent (eth->dma_dev,MTK_DMA_SIZE * sz, + ring->dma =dma_alloc_coherent (eth->dma_dev, +MTK_DMA_SIZE * soc->txrx.txd_size, &ring->phys,GFP_ATOMIC );Another GFP nugget.
ack I will fix it in v3.
Regards,
Lorenzo
Lorenzo Bianconi
maintainerPATCH v2 6/15 net: ethernet: mtk_eth_soc: rely on txd_size in mtk_desc_to_tx_buf
In reply to Lorenzo BianconiThis is a preliminary patch to add mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 26 ++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +15 -11
@@ -837,10 +837,11 @@ static inline void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc)return ret + (desc - ring->phys); } -static inline struct mtk_tx_buf *mtk_desc_to_tx_buf (struct mtk_tx_ring *ring, -struct mtk_tx_dma *txd) +static struct mtk_tx_buf *mtk_desc_to_tx_buf (struct mtk_tx_ring *ring, +struct mtk_tx_dma *txd, +u32 txd_size) { -int idx = txd - ring->dma; +int idx = ((void *)txd - (void *)ring->dma) / txd_size;return &ring->buf[idx]; }
@@ -962,6 +963,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, };struct mtk_mac *mac =netdev_priv (dev);struct mtk_eth *eth = mac->hw; +const struct mtk_soc_data *soc = eth->soc;struct mtk_tx_dma *itxd, *txd;struct mtk_tx_dma *itxd_pdma, *txd_pdma;struct mtk_tx_buf *itx_buf, *tx_buf;
@@ -973,7 +975,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,if (itxd == ring->last_free)return -ENOMEM ; - itx_buf =mtk_desc_to_tx_buf (ring, itxd); + itx_buf =mtk_desc_to_tx_buf (ring, itxd, soc->txrx.txd_size);memset (itx_buf,0 ,sizeof (*itx_buf)); txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
@@ -1001,7 +1003,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,while (frag_size) {bool new_desc = true; -if (MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA ) || +if (MTK_HAS_CAPS (soc->caps,MTK_QDMA ) || (i &0x1 )) { txd =mtk_qdma_phys_to_virt (ring, txd->txd2); txd_pdma =qdma_to_pdma (ring, txd);
@@ -1025,7 +1027,8 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,mtk_tx_set_dma_desc (dev, txd, &txd_info); - tx_buf =mtk_desc_to_tx_buf (ring, txd); + tx_buf =mtk_desc_to_tx_buf (ring, txd, + soc->txrx.txd_size);if (new_desc)memset (tx_buf,0 ,sizeof (*tx_buf)); tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC ;
@@ -1044,7 +1047,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,/* store skb to cleanup */ itx_buf->skb = skb; -if (!MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA )) { +if (!MTK_HAS_CAPS (soc->caps,MTK_QDMA )) {if (k &0x1 ) txd_pdma->txd2 |=TX_DMA_LS0 ;else
@@ -1062,7 +1065,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,*/ wmb (); -if (MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA )) { +if (MTK_HAS_CAPS (soc->caps,MTK_QDMA )) {if (netif_xmit_stopped (netdev_get_tx_queue (dev,0 )) || !netdev_xmit_more ())mtk_w32 (eth, txd->txd2,MTK_QTX_CTX_PTR );
@@ -1076,13 +1079,13 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, err_dma: do { - tx_buf = mtk_desc_to_tx_buf(ring, itxd); + tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size); /* unmap dma */ mtk_tx_unmap(eth, tx_buf, false); itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) + if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) itxd_pdma->txd2 = TX_DMA_DESP2_DEF; itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
@@ -1393,7 +1396,8 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,if ((desc->txd3 &TX_DMA_OWNER_CPU ) ==0 )break ; - tx_buf =mtk_desc_to_tx_buf (ring, desc); + tx_buf =mtk_desc_to_tx_buf (ring, desc, + eth->soc->txrx.txd_size);if (tx_buf->flags &MTK_TX_FLAGS_FPORT1 ) mac =1 ;
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 7/15 net: ethernet: mtk_eth_soc: rely on txd_size in txd_to_idx
In reply to Lorenzo BianconiThis is a preliminary patch to add mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +7 -4
@@ -852,9 +852,10 @@ static struct mtk_tx_dma *qdma_to_pdma(struct mtk_tx_ring *ring,return ring->dma_pdma - ring->dma + dma; } -static int txd_to_idx (struct mtk_tx_ring *ring,struct mtk_tx_dma *dma) +static int txd_to_idx (struct mtk_tx_ring *ring,struct mtk_tx_dma *dma, +u32 txd_size) { -return ((void *)dma - (void *)ring->dma) /sizeof (*dma); +return ((void *)dma - (void *)ring->dma) / txd_size; } static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
@@ -1070,8 +1071,10 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, !netdev_xmit_more())mtk_w32 (eth, txd->txd2,MTK_QTX_CTX_PTR ); }else { -int next_idx =NEXT_DESP_IDX (txd_to_idx (ring, txd), - ring->dma_size); +int next_idx; + + next_idx =NEXT_DESP_IDX (txd_to_idx (ring, txd, soc->txrx.txd_size), + ring->dma_size);mtk_w32 (eth, next_idx,MT7628_TX_CTX_IDX0 ); }
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 8/15 net: ethernet: mtk_eth_soc: add rxd_size to mtk_soc_data
In reply to Lorenzo BianconiSimilar to tx counterpart, introduce rxd_size in mtk_soc_data data structure.
This is a preliminary patch to add mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 13 +++++++++---- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +9 -4
@@ -1719,7 +1719,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) } ring->dma =dma_alloc_coherent (eth->dma_dev, - rx_dma_size *sizeof (*ring->dma), + rx_dma_size * eth->soc->txrx.rxd_size, &ring->phys,GFP_ATOMIC );if (!ring->dma)return -ENOMEM ;
@@ -1777,9 +1777,8 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)if (ring->dma) {dma_free_coherent (eth->dma_dev, - ring->dma_size *sizeof (*ring->dma), - ring->dma, - ring->phys); + ring->dma_size * eth->soc->txrx.rxd_size, + ring->dma, ring->phys); ring->dma =NULL ; } }
@@ -3370,6 +3369,7 @@ static const struct mtk_soc_data mt2701_data = { .required_pctl = true, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }, };
@@ -3381,6 +3381,7 @@ static const struct mtk_soc_data mt7621_data = { .offload_version = 2, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }, };
@@ -3393,6 +3394,7 @@ static const struct mtk_soc_data mt7622_data = { .offload_version = 2, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }, };
@@ -3404,6 +3406,7 @@ static const struct mtk_soc_data mt7623_data = { .offload_version = 2, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }, };
@@ -3415,6 +3418,7 @@ static const struct mtk_soc_data mt7629_data = { .required_pctl = false, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }, };
@@ -3425,6 +3429,7 @@ static const struct mtk_soc_data rt5350_data = { .required_pctl = false, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }, };
drivers/net/ethernet/mediatek/mtk_eth_soc.h +2 -0
@@ -866,6 +866,7 @@ struct mtk_tx_dma_desc_info {* @required_pctl A bool value to show whether the SoC requires * the extra setup for those pins used by GMAC. * @txd_size TX DMA descriptor size. +* @rxd_size RX DMA descriptor size. */ struct mtk_soc_data {u32 ana_rgc3;
@@ -876,6 +877,7 @@ struct mtk_soc_data {netdev_features_t hw_features;struct {u32 txd_size; +u32 rxd_size; } txrx; };
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 9/15 net: ethernet: mtk_eth_soc: rely on txd_size field in mtk_poll_tx/mtk_poll_rx
In reply to Lorenzo BianconiThis is a preliminary to ad mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +6 -3
@@ -1211,9 +1211,12 @@ static struct mtk_rx_ring *mtk_get_rx_ring(struct mtk_eth *eth)return ð->rx_ring[0 ];for (i =0 ; i <MTK_MAX_RX_RING_NUM ; i++) { +struct mtk_rx_dma *rxd; + ring = ð->rx_ring[i]; idx =NEXT_DESP_IDX (ring->calc_idx, ring->dma_size); -if (ring->dma[idx].rxd2 &RX_DMA_DONE ) { + rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; +if (rxd->rxd2 &RX_DMA_DONE ) { ring->calc_idx_update = true;return ring; }
@@ -1264,7 +1267,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, goto rx_done; idx =NEXT_DESP_IDX (ring->calc_idx, ring->dma_size); - rxd = &ring->dma[idx]; + rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; data = ring->data[idx];if (!mtk_rx_get_desc (&trxd, rxd))
@@ -1453,7 +1456,7 @@ static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget,mtk_tx_unmap (eth, tx_buf, true); - desc = &ring->dma[cpu]; + desc = (void *)ring->dma + cpu * eth->soc->txrx.txd_size; ring->last_free = desc;atomic_inc (&ring->free_count);
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 10/15 net: ethernet: mtk_eth_soc: rely on rxd_size field in mtk_rx_alloc/mtk_rx_clean
In reply to Lorenzo BianconiThis is a preliminary patch to add mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 26 ++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +18 -8
@@ -1728,18 +1728,25 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)return -ENOMEM ;for (i =0 ; i < rx_dma_size; i++) { +struct mtk_rx_dma *rxd; +dma_addr_t dma_addr =dma_map_single (eth->dma_dev, ring->data[i] +NET_SKB_PAD + eth->ip_align, ring->buf_size,DMA_FROM_DEVICE );if (unlikely (dma_mapping_error (eth->dma_dev, dma_addr)))return -ENOMEM ; - ring->dma[i].rxd1 = (unsigned int )dma_addr; + + rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; + rxd->rxd1 = (unsigned int )dma_addr;if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) - ring->dma[i].rxd2 =RX_DMA_LSO ; + rxd->rxd2 =RX_DMA_LSO ;else - ring->dma[i].rxd2 =RX_DMA_PLEN0 (ring->buf_size); + rxd->rxd2 =RX_DMA_PLEN0 (ring->buf_size); + + rxd->rxd3 =0 ; + rxd->rxd4 =0 ; } ring->dma_size = rx_dma_size; ring->calc_idx_update = false;
@@ -1764,14 +1771,17 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)if (ring->data && ring->dma) {for (i =0 ; i < ring->dma_size; i++) { +struct mtk_rx_dma *rxd; +if (!ring->data[i])continue ; -if (!ring->dma[i].rxd1) + + rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; +if (!rxd->rxd1)continue ; -dma_unmap_single (eth->dma_dev, - ring->dma[i].rxd1, - ring->buf_size, -DMA_FROM_DEVICE ); + +dma_unmap_single (eth->dma_dev, rxd->rxd1, + ring->buf_size,DMA_FROM_DEVICE );skb_free_frag (ring->data[i]); }kfree (ring->data);
Signature · 1 line
2.35.3
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 10/15] net: ethernet: mtk_eth_soc: rely on rxd_size field in mtk_rx_alloc/mtk_rx_clean
drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) · line 1749
Quoted 13 lines · On Mon, 16 May 2022 18:06:37 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.c +8
-2+ + rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; + rxd->rxd1 = (unsigned int )dma_addr;if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) - ring->dma[i].rxd2 =RX_DMA_LSO ; + rxd->rxd2 =RX_DMA_LSO ;else - ring->dma[i].rxd2 =RX_DMA_PLEN0 (ring->buf_size); + rxd->rxd2 =RX_DMA_PLEN0 (ring->buf_size); + + rxd->rxd3 =0 ; + rxd->rxd4 =0 ;
The clearing of rxd3/rxd4 should probably have been mentioned in the commit message. It does not seem related to descriptor size.
Lorenzo Bianconi
maintainerRe: [PATCH v2 net-next 10/15] net: ethernet: mtk_eth_soc: rely on rxd_size field in mtk_rx_alloc/mtk_rx_clean
Quoted 5 lines · On Mon, 16 May 2022 18:06:37 +0200 Lorenzo Bianconi wrote:
Quoted 4 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +3
-0+ + rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; + rxd->rxd1 = (unsigned int )dma_addr;
Quoted 12 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) · line 1749
Quoted 9 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +5
-2if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) - ring->dma[i].rxd2 =RX_DMA_LSO ; + rxd->rxd2 =RX_DMA_LSO ;else - ring->dma[i].rxd2 =RX_DMA_PLEN0 (ring->buf_size); + rxd->rxd2 =RX_DMA_PLEN0 (ring->buf_size); + + rxd->rxd3 =0 ; + rxd->rxd4 =0 ;The clearing of rxd3/rxd4 should probably have been mentioned in the commit message. It does not seem related to descriptor size.
ack, I will do it in v3.
Regards,
Lorenzo
_______________________________________________
Linux-mediatek mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-mediatek
Lorenzo Bianconi
maintainerPATCH v2 11/15 net: ethernet: mtk_eth_soc: introduce device register map
In reply to Lorenzo BianconiIntroduce reg_map structure to add the capability to support different register definitions.
This is a preliminary patch to introduce mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 17 +++ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 160 +++++++++++++------- 2 files changed, 121 insertions(+), 56 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +17 -0
@@ -34,6 +34,17 @@ MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");#define MTK_ETHTOOL_STAT (x) { #x, \ offsetof(struct mtk_hw_stats, x) / sizeof(u64) } +static const u32 mtk_reg_map[] = { + [MTK_PDMA_BASE ] =0x0800 , + [MTK_PDMA_LRO_CTRL ] =0x0980 , + [MTK_PDMA_ALT_SCORE_DELTA_BASE ] =0x0a4c , + [MTK_PDMA_LRO_RX_RING_DIP_BASE ] =0x0b04 , + [MTK_PDMA_LRO_RX_RING_CTRL_BASE ] =0x0b28 , + [MTK_QDMA_BASE ] =0x1800 , + [MTK_GDM1_TX_STAT_BASE ] =0x2400 , + [MTK_PDMA_RSS_GLO_BASE ] =0x3000 , +}; +/* strings used by ethtool */ static const struct mtk_ethtool_stats { char str[ETH_GSTRING_LEN];
@@ -3376,6 +3387,7 @@ static int mtk_remove(struct platform_device *pdev) }static const struct mtk_soc_data mt2701_data = { + .reg_map = mtk_reg_map, .caps =MT7623_CAPS |MTK_HWLRO , .hw_features =MTK_HW_FEATURES , .required_clks =MT7623_CLKS_BITMAP ,
@@ -3387,6 +3399,7 @@ static const struct mtk_soc_data mt2701_data = { };static const struct mtk_soc_data mt7621_data = { + .reg_map = mtk_reg_map, .caps =MT7621_CAPS , .hw_features =MTK_HW_FEATURES , .required_clks =MT7621_CLKS_BITMAP ,
@@ -3399,6 +3412,7 @@ static const struct mtk_soc_data mt7621_data = { };static const struct mtk_soc_data mt7622_data = { + .reg_map = mtk_reg_map, .ana_rgc3 =0x2028 , .caps =MT7622_CAPS |MTK_HWLRO , .hw_features =MTK_HW_FEATURES ,
@@ -3412,6 +3426,7 @@ static const struct mtk_soc_data mt7622_data = { };static const struct mtk_soc_data mt7623_data = { + .reg_map = mtk_reg_map, .caps =MT7623_CAPS |MTK_HWLRO , .hw_features =MTK_HW_FEATURES , .required_clks =MT7623_CLKS_BITMAP ,
@@ -3424,6 +3439,7 @@ static const struct mtk_soc_data mt7623_data = { };static const struct mtk_soc_data mt7629_data = { + .reg_map = mtk_reg_map, .ana_rgc3 =0x128 , .caps =MT7629_CAPS |MTK_HWLRO , .hw_features =MTK_HW_FEATURES ,
@@ -3436,6 +3452,7 @@ static const struct mtk_soc_data mt7629_data = { };static const struct mtk_soc_data rt5350_data = { + .reg_map = mtk_reg_map, .caps =MT7628_CAPS , .hw_features =MTK_HW_FEATURES_MT7628 , .required_clks =MT7628_CLKS_BITMAP ,
drivers/net/ethernet/mediatek/mtk_eth_soc.h +104 -56
292 lines not on this page · raw message
Signature · 1 line
2.35.3
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 11/15] net: ethernet: mtk_eth_soc: introduce device register map
drivers/net/ethernet/mediatek/mtk_eth_soc.h line 116
Quoted 4 lines · On Mon, 16 May 2022 18:06:38 +0200 Lorenzo Bianconi wrote:
/* PDMA RX Base Pointer Register */
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1
-1-#define MTK_PRX_BASE_PTR0 0x900 +#define MTK_PRX_BASE_PTR0 (eth->soc->reg_map[MTK_PDMA_BASE] + 0x100)#define MTK_PRX_BASE_PTR_CFG (x) (MTK_PRX_BASE_PTR0 + (x * 0x10))
Implicit macro arguments are really unpleasant for people doing tree-wide changes or otherwise unfamiliar with the driver.
Nothing we can do to avoid this?
Lorenzo Bianconi
maintainerRe: [PATCH v2 net-next 11/15] net: ethernet: mtk_eth_soc: introduce device register map
Quoted 10 lines · On Mon, 16 May 2022 18:06:38 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.h line 116
Quoted 4 lines
/* PDMA RX Base Pointer Register */
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1
-1-#define MTK_PRX_BASE_PTR0 0x900 +#define MTK_PRX_BASE_PTR0 (eth->soc->reg_map[MTK_PDMA_BASE] + 0x100)#define MTK_PRX_BASE_PTR_CFG (x) (MTK_PRX_BASE_PTR0 + (x * 0x10))Implicit macro arguments are really unpleasant for people doing tree-wide changes or otherwise unfamiliar with the driver.
Nothing we can do to avoid this?
I used this approach in order to have just few changes in the codebase. I guess the best option would be to explicitly add eth parameter to the register macros, what do you think?
Regards,
Lorenzo
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 11/15] net: ethernet: mtk_eth_soc: introduce device register map
Quoted 9 lines · On Wed, 18 May 2022 11:48:43 +0200 Lorenzo Bianconi wrote:
Quoted 9 lines · On Mon, 16 May 2022 18:06:38 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.h line 116
Quoted 4 lines
/* PDMA RX Base Pointer Register */
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1
-1-#define MTK_PRX_BASE_PTR0 0x900 +#define MTK_PRX_BASE_PTR0 (eth->soc->reg_map[MTK_PDMA_BASE] + 0x100)#define MTK_PRX_BASE_PTR_CFG (x) (MTK_PRX_BASE_PTR0 + (x * 0x10))Implicit macro arguments are really unpleasant for people doing tree-wide changes or otherwise unfamiliar with the driver.
Quoted 4 lines
Quoted 1 line
Nothing we can do to avoid this?
I used this approach in order to have just few changes in the codebase. I guess the best option would be to explicitly add eth parameter to the register macros, what do you think?
I don't think there's a best known practice, you'll have to exercise your judgment. Taking a look at a random example of MTK_PDMA_INT_STATUS. Looks like that one is already assigned to eth->tx_int_status_reg. Maybe that can be generalized? Personally I'd forgo the macros completely and just use eth->soc->register_name in the code.
_______________________________________________
Linux-mediatek mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-mediatek
Lorenzo Bianconi
maintainerRe: [PATCH v2 net-next 11/15] net: ethernet: mtk_eth_soc: introduce device register map
Quoted 12 lines · On Wed, 18 May 2022 11:48:43 +0200 Lorenzo Bianconi wrote:
Quoted 11 lines
Quoted 10 lines · On Mon, 16 May 2022 18:06:38 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.h line 116
Quoted 4 lines
/* PDMA RX Base Pointer Register */
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1
-1-#define MTK_PRX_BASE_PTR0 0x900 +#define MTK_PRX_BASE_PTR0 (eth->soc->reg_map[MTK_PDMA_BASE] + 0x100)#define MTK_PRX_BASE_PTR_CFG (x) (MTK_PRX_BASE_PTR0 + (x * 0x10))Implicit macro arguments are really unpleasant for people doing tree-wide changes or otherwise unfamiliar with the driver.
Nothing we can do to avoid this?
Quoted 8 lines
Quoted 2 lines
I used this approach in order to have just few changes in the codebase. I guess the best option would be to explicitly add eth parameter to the register macros, what do you think?
I don't think there's a best known practice, you'll have to exercise your judgment. Taking a look at a random example of
MTK_PDMA_INT_STATUS. Looks like that one is already assigned toeth->tx_int_status_reg. Maybe that can be generalized? Personally I'd forgo the macros completely and just useeth->soc->register_namein the code.
I personally think the code is easier to read if we use macros in this case. Let's consider MTK_LRO_CTRL_DW1_CFG(), it depends on the particular soc based on the register map and even on the ring index. I guess the best trade-off we can get is to explicitly pass eth to the macros as parameter when needed.
Regards,
Lorenzo
_______________________________________________
Linux-mediatek mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-mediatek
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 11/15] net: ethernet: mtk_eth_soc: introduce device register map
Quoted 10 lines · On Thu, 19 May 2022 09:51:28 +0200 Lorenzo Bianconi wrote:
Quoted 5 lines
I don't think there's a best known practice, you'll have to exercise your judgment. Taking a look at a random example of
MTK_PDMA_INT_STATUS. Looks like that one is already assigned toeth->tx_int_status_reg. Maybe that can be generalized? Personally I'd forgo the macros completely and just useeth->soc->register_namein the code.I personally think the code is easier to read if we use macros in this case. Let's consider
MTK_LRO_CTRL_DW1_CFG(), it depends on the particular soc based on the register map and even on the ring index. I guess the best trade-off we can get is to explicitly pass eth to the macros as parameter when needed.
Yeah, do you, I was just sharing what my knee jerk direction would be. You know the code better.
Lorenzo Bianconi
maintainerRe: [PATCH v2 net-next 11/15] net: ethernet: mtk_eth_soc: introduce device register map
Quoted 7 lines · On Thu, 19 May 2022 09:51:28 +0200 Lorenzo Bianconi wrote:
Quoted 6 lines
Quoted 5 lines
I don't think there's a best known practice, you'll have to exercise your judgment. Taking a look at a random example of
MTK_PDMA_INT_STATUS. Looks like that one is already assigned toeth->tx_int_status_reg. Maybe that can be generalized? Personally I'd forgo the macros completely and just useeth->soc->register_namein the code.
Quoted 7 lines
Quoted 4 lines
I personally think the code is easier to read if we use macros in this case. Let's consider
MTK_LRO_CTRL_DW1_CFG(), it depends on the particular soc based on the register map and even on the ring index. I guess the best trade-off we can get is to explicitly pass eth to the macros as parameter when needed.Yeah, do you, I was just sharing what my knee jerk direction would be. You know the code better.
reworking the code I introduced a register map removing the macro dependency. I will post v3 soon.
Regards,
Lorenzo
Lorenzo Bianconi
maintainerPATCH v2 12/15 net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
In reply to Lorenzo BianconiIntroduce MTK_NETSYS_V2 support. MTK_NETSYS_V2 defines 32B TX/RX DMA descriptors.
This is a preliminary patch to add mt7986 ethernet support.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 312 ++++++++++++++++---- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 129 +++++++- 2 files changed, 366 insertions(+), 75 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +247 -65
@@ -778,8 +778,8 @@ static inline int mtk_max_buf_size(int frag_size)return buf_size; } -static inline bool mtk_rx_get_desc (struct mtk_rx_dma *rxd, -struct mtk_rx_dma *dma_rxd) +static bool mtk_rx_get_desc (struct mtk_eth *eth,struct mtk_rx_dma_v2 *rxd, +struct mtk_rx_dma_v2 *dma_rxd) { rxd->rxd2 =READ_ONCE (dma_rxd->rxd2);if (!(rxd->rxd2 &RX_DMA_DONE ))
@@ -788,6 +788,10 @@ static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd, rxd->rxd1 =READ_ONCE (dma_rxd->rxd1); rxd->rxd3 =READ_ONCE (dma_rxd->rxd3); rxd->rxd4 =READ_ONCE (dma_rxd->rxd4); +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) { + rxd->rxd5 =READ_ONCE (dma_rxd->rxd5); + rxd->rxd6 =READ_ONCE (dma_rxd->rxd6); + }return true; }
@@ -821,7 +825,7 @@ static int mtk_init_fq_dma(struct mtk_eth *eth) phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt -1 );for (i =0 ; i < cnt; i++) { -struct mtk_tx_dma *txd; +struct mtk_tx_dma_v2 *txd; txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size; txd->txd1 = dma_addr + i *MTK_QDMA_PAGE_SIZE ;
@@ -831,6 +835,12 @@ static int mtk_init_fq_dma(struct mtk_eth *eth) txd->txd3 =TX_DMA_PLEN0 (MTK_QDMA_PAGE_SIZE ); txd->txd4 =0 ; +if (MTK_HAS_CAPS (soc->caps,MTK_NETSYS_V2 )) { + txd->txd5 =0 ; + txd->txd6 =0 ; + txd->txd7 =0 ; + txd->txd8 =0 ; + } }mtk_w32 (eth, eth->phy_scratch_ring,MTK_QDMA_FQ_HEAD );
@@ -934,10 +944,12 @@ static void setup_tx_buf(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, } } -static void mtk_tx_set_dma_desc (struct net_device *dev,struct mtk_tx_dma *desc, -struct mtk_tx_dma_desc_info *info) +static void mtk_tx_set_dma_desc_v1 (struct net_device *dev,void *txd, +struct mtk_tx_dma_desc_info *info) {struct mtk_mac *mac =netdev_priv (dev); +struct mtk_eth *eth = mac->hw; +struct mtk_tx_dma *desc = txd;u32 data;WRITE_ONCE (desc->txd1, info->addr);
@@ -961,6 +973,59 @@ static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc,WRITE_ONCE (desc->txd4, data); } +static void mtk_tx_set_dma_desc_v2 (struct net_device *dev,void *txd, +struct mtk_tx_dma_desc_info *info) +{ +struct mtk_mac *mac =netdev_priv (dev); +struct mtk_tx_dma_v2 *desc = txd; +struct mtk_eth *eth = mac->hw; +u32 data; + +WRITE_ONCE (desc->txd1, info->addr); + + data =TX_DMA_PLEN0 (info->size); +if (info->last) + data |=TX_DMA_LS0 ; +WRITE_ONCE (desc->txd3, data); + +if (!info->qid && mac->id) + info->qid =MTK_QDMA_GMAC2_QID ; + + data = (mac->id +1 ) <<TX_DMA_FPORT_SHIFT_V2 ;/* forward port */ + data |=TX_DMA_SWC_V2 |QID_BITS_V2 (info->qid); +WRITE_ONCE (desc->txd4, data); + + data =0 ; +if (info->first) { +if (info->gso) + data |=TX_DMA_TSO_V2 ; +/* tx checksum offload */ +if (info->csum) + data |=TX_DMA_CHKSUM_V2 ; + } +WRITE_ONCE (desc->txd5, data); + + data =0 ; +if (info->first && info->vlan) + data |=TX_DMA_INS_VLAN_V2 | info->vlan_tci; +WRITE_ONCE (desc->txd6, data); + +WRITE_ONCE (desc->txd7,0 ); +WRITE_ONCE (desc->txd8,0 ); +} + +static void mtk_tx_set_dma_desc (struct net_device *dev,void *txd, +struct mtk_tx_dma_desc_info *info) +{ +struct mtk_mac *mac =netdev_priv (dev); +struct mtk_eth *eth = mac->hw; + +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) +mtk_tx_set_dma_desc_v2 (dev, txd, info); +else +mtk_tx_set_dma_desc_v1 (dev, txd, info); +} +static int mtk_tx_map (struct sk_buff *skb,struct net_device *dev,int tx_num,struct mtk_tx_ring *ring,bool gso) {
@@ -969,6 +1034,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, .gso = gso, .csum = skb->ip_summed == CHECKSUM_PARTIAL, .vlan = skb_vlan_tag_present(skb), + .qid = skb->mark & MTK_QDMA_TX_MASK, .vlan_tci = skb_vlan_tag_get(skb), .first = true, .last = !skb_is_nonlinear(skb),
@@ -1028,7 +1094,9 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, }memset (&txd_info,0 ,sizeof (struct mtk_tx_dma_desc_info )); - txd_info.size =min (frag_size,MTK_TX_DMA_BUF_LEN ); + txd_info.size = min_t(unsigned int, frag_size, + soc->txrx.dma_max_len); + txd_info.qid = skb->mark &MTK_QDMA_TX_MASK ; txd_info.last = i ==skb_shinfo (skb)->nr_frags -1 && !(frag_size - txd_info.size); txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
@@ -1109,17 +1177,16 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,return -ENOMEM ; } -static inline int mtk_cal_txd_req (struct sk_buff *skb) +static int mtk_cal_txd_req (struct mtk_eth *eth,struct sk_buff *skb) { -int i, nfrags; +int i, nfrags =1 ;skb_frag_t *frag; - nfrags =1 ;if (skb_is_gso (skb)) {for (i =0 ; i <skb_shinfo (skb)->nr_frags; i++) { frag = &skb_shinfo (skb)->frags[i]; nfrags +=DIV_ROUND_UP (skb_frag_size (frag), -MTK_TX_DMA_BUF_LEN ); + eth->soc->txrx.dma_max_len); } }else { nfrags +=skb_shinfo (skb)->nr_frags;
@@ -1171,7 +1238,7 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)if (unlikely (test_bit (MTK_RESETTING , ð->state))) goto drop; - tx_num =mtk_cal_txd_req (skb); + tx_num =mtk_cal_txd_req (eth, skb);if (unlikely (atomic_read (&ring->free_count) <= tx_num)) {netif_stop_queue (dev); netif_err(eth, tx_queued, dev,
@@ -1263,7 +1330,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,int idx;struct sk_buff *skb;u8 *data, *new_data; -struct mtk_rx_dma *rxd, trxd; +struct mtk_rx_dma_v2 *rxd, trxd;int done =0 , bytes =0 ;while (done < budget) {
@@ -1271,7 +1338,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,unsigned int pktlen;dma_addr_t dma_addr;u32 hash, reason; -int mac; +int mac =0 ; ring =mtk_get_rx_ring (eth);if (unlikely (!ring))
@@ -1281,16 +1348,15 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; data = ring->data[idx]; -if (!mtk_rx_get_desc (&trxd, rxd)) +if (!mtk_rx_get_desc (eth, &trxd, rxd))break ;/* find out which mac the packet come from. values start at 1 */ -if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 ) || - (trxd.rxd4 &RX_DMA_SPECIAL_TAG )) - mac =0 ; -else - mac = ((trxd.rxd4 >>RX_DMA_FPORT_SHIFT ) & -RX_DMA_FPORT_MASK ) -1 ; +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) + mac =RX_DMA_GET_SPORT_V2 (trxd.rxd5) -1 ; +else if (!MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 ) && + !(trxd.rxd4 &RX_DMA_SPECIAL_TAG )) + mac =RX_DMA_GET_SPORT (trxd.rxd4) -1 ;if (unlikely (mac <0 || mac >=MTK_MAC_COUNT || !eth->netdev[mac]))
@@ -1333,7 +1399,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, pktlen =RX_DMA_GET_PLEN0 (trxd.rxd2); skb->dev = netdev;skb_put (skb, pktlen); -if (trxd.rxd4 & eth->rx_dma_l4_valid) +if (trxd.rxd4 & eth->soc->txrx.rx_dma_l4_valid) skb->ip_summed =CHECKSUM_UNNECESSARY ;else skb_checksum_none_assert (skb);
@@ -1351,10 +1417,25 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,mtk_ppe_check_skb (eth->ppe, skb, trxd.rxd4 &MTK_RXD4_FOE_ENTRY ); -if (netdev->features &NETIF_F_HW_VLAN_CTAG_RX && - (trxd.rxd2 &RX_DMA_VTAG )) -__vlan_hwaccel_put_tag (skb,htons (ETH_P_8021Q ), -RX_DMA_VID (trxd.rxd3)); +if (netdev->features &NETIF_F_HW_VLAN_CTAG_RX ) { +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) { +if (trxd.rxd3 &RX_DMA_VTAG_V2 ) +__vlan_hwaccel_put_tag (skb, +htons (RX_DMA_VPID (trxd.rxd4)), +RX_DMA_VID (trxd.rxd4)); + }else if (trxd.rxd2 &RX_DMA_VTAG ) { +__vlan_hwaccel_put_tag (skb,htons (ETH_P_8021Q ), +RX_DMA_VID (trxd.rxd3)); + } + +/* If the device is attached to a dsa switch, the special +* tag inserted in VLAN field by hw switch can * be offloaded +* by RX HW VLAN offload. Clear vlan info. +*/ +if (netdev_uses_dsa (netdev)) +__vlan_hwaccel_clear_tag (skb); + } +skb_record_rx_queue (skb,0 );napi_gro_receive (napi, skb);
@@ -1366,7 +1447,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) rxd->rxd2 =RX_DMA_LSO ;else - rxd->rxd2 =RX_DMA_PLEN0 (ring->buf_size); + rxd->rxd2 =RX_DMA_PREP_PLEN0 (ring->buf_size); ring->calc_idx = idx;
@@ -1565,7 +1646,8 @@ static int mtk_napi_rx(struct napi_struct *napi, int budget) do { int rx_done; - mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_STATUS); + mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, + MTK_PDMA_INT_STATUS); rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth); rx_done_total += rx_done;
@@ -1579,10 +1661,11 @@ static int mtk_napi_rx(struct napi_struct *napi, int budget)if (rx_done_total == budget)return budget; - }while (mtk_r32 (eth,MTK_PDMA_INT_STATUS ) &MTK_RX_DONE_INT ); + }while (mtk_r32 (eth,MTK_PDMA_INT_STATUS ) & + eth->soc->txrx.rx_irq_done_mask);if (napi_complete_done (napi, rx_done_total)) -mtk_rx_irq_enable (eth,MTK_RX_DONE_INT ); +mtk_rx_irq_enable (eth, eth->soc->txrx.rx_irq_done_mask);return rx_done_total; }
@@ -1591,7 +1674,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) {const struct mtk_soc_data *soc = eth->soc;struct mtk_tx_ring *ring = ð->tx_ring; -struct mtk_tx_dma *txd; +struct mtk_tx_dma_v2 *txd;int i; ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf),
@@ -1613,13 +1696,19 @@ static int mtk_tx_alloc(struct mtk_eth *eth) txd->txd2 = next_ptr; txd->txd3 =TX_DMA_LS0 |TX_DMA_OWNER_CPU ; txd->txd4 =0 ; +if (MTK_HAS_CAPS (soc->caps,MTK_NETSYS_V2 )) { + txd->txd5 =0 ; + txd->txd6 =0 ; + txd->txd7 =0 ; + txd->txd8 =0 ; + } }/* On MT7688 (PDMA only) this driver uses the ring->dma structs * only as the framework. The real HW descriptors are the PDMA * descriptors in ring->dma_pdma. */ -if (!MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA )) { +if (!MTK_HAS_CAPS (soc->caps,MTK_QDMA )) { ring->dma_pdma =dma_alloc_coherent (eth->dma_dev,MTK_DMA_SIZE * soc->txrx.txd_size, &ring->phys_pdma,GFP_ATOMIC );
@@ -1700,13 +1789,11 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)struct mtk_rx_ring *ring;int rx_data_len, rx_dma_size;int i; -u32 offset =0 ;if (rx_flag ==MTK_RX_FLAGS_QDMA ) {if (ring_no)return -EINVAL ; ring = ð->rx_ring_qdma; - offset =0x1000 ; }else { ring = ð->rx_ring[ring_no]; }
@@ -1739,7 +1826,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)return -ENOMEM ;for (i =0 ; i < rx_dma_size; i++) { -struct mtk_rx_dma *rxd; +struct mtk_rx_dma_v2 *rxd; dma_addr_t dma_addr = dma_map_single(eth->dma_dev, ring->data[i] + NET_SKB_PAD + eth->ip_align,
@@ -1754,24 +1841,39 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) rxd->rxd2 =RX_DMA_LSO ;else - rxd->rxd2 =RX_DMA_PLEN0 (ring->buf_size); + rxd->rxd2 =RX_DMA_PREP_PLEN0 (ring->buf_size); rxd->rxd3 =0 ; rxd->rxd4 =0 ; +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) { + rxd->rxd5 =0 ; + rxd->rxd6 =0 ; + rxd->rxd7 =0 ; + rxd->rxd8 =0 ; + } } ring->dma_size = rx_dma_size; ring->calc_idx_update = false; ring->calc_idx = rx_dma_size -1 ; - ring->crx_idx_reg =MTK_PRX_CRX_IDX_CFG (ring_no); +if (rx_flag ==MTK_RX_FLAGS_QDMA ) + ring->crx_idx_reg =MTK_QRX_CRX_IDX_CFG (ring_no); +else + ring->crx_idx_reg =MTK_PRX_CRX_IDX_CFG (ring_no);/* make sure that all changes to the dma ring are flushed before we * continue */ wmb (); -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); +if (rx_flag ==MTK_RX_FLAGS_QDMA ) { +mtk_w32 (eth, ring->phys,MTK_QRX_BASE_PTR_CFG (ring_no)); +mtk_w32 (eth, rx_dma_size,MTK_QRX_MAX_CNT_CFG (ring_no)); +mtk_w32 (eth,MTK_PST_DRX_IDX_CFG (ring_no),MTK_QDMA_RST_IDX ); + }else { +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,MTK_PST_DRX_IDX_CFG (ring_no),MTK_PDMA_RST_IDX ); + } +mtk_w32 (eth, ring->calc_idx, ring->crx_idx_reg);return 0 ; }
@@ -2190,7 +2292,7 @@ static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth) eth->rx_events++;if (likely (napi_schedule_prep (ð->rx_napi))) {__napi_schedule (ð->rx_napi); -mtk_rx_irq_disable (eth,MTK_RX_DONE_INT ); +mtk_rx_irq_disable (eth, eth->soc->txrx.rx_irq_done_mask); }return IRQ_HANDLED ;
@@ -2213,8 +2315,10 @@ static irqreturn_t mtk_handle_irq(int irq, void *_eth) {struct mtk_eth *eth = _eth; -if (mtk_r32 (eth,MTK_PDMA_INT_MASK ) &MTK_RX_DONE_INT ) { -if (mtk_r32 (eth,MTK_PDMA_INT_STATUS ) &MTK_RX_DONE_INT ) +if (mtk_r32 (eth,MTK_PDMA_INT_MASK ) & + eth->soc->txrx.rx_irq_done_mask) { +if (mtk_r32 (eth,MTK_PDMA_INT_STATUS ) & + eth->soc->txrx.rx_irq_done_mask)mtk_handle_irq_rx (irq, _eth); }if (mtk_r32 (eth, eth->tx_int_mask_reg) &MTK_TX_DONE_INT ) {
@@ -2232,16 +2336,16 @@ static void mtk_poll_controller(struct net_device *dev)struct mtk_eth *eth = mac->hw;mtk_tx_irq_disable (eth,MTK_TX_DONE_INT ); -mtk_rx_irq_disable (eth,MTK_RX_DONE_INT ); +mtk_rx_irq_disable (eth, eth->soc->txrx.rx_irq_done_mask);mtk_handle_irq_rx (eth->irq[2 ], dev);mtk_tx_irq_enable (eth,MTK_TX_DONE_INT ); - mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); + mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); }#endif static int mtk_start_dma (struct mtk_eth *eth) { -u32 rx_2b_offset = (NET_IP_ALIGN ==2 ) ?MTK_RX_2B_OFFSET :0 ; +u32 val, rx_2b_offset = (NET_IP_ALIGN ==2 ) ?MTK_RX_2B_OFFSET :0 ;int err; err =mtk_dma_init (eth);
@@ -2251,12 +2355,18 @@ static int mtk_start_dma(struct mtk_eth *eth) }if (MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA )) { -mtk_w32 (eth, -MTK_TX_WB_DDONE |MTK_TX_DMA_EN | -MTK_TX_BT_32DWORDS |MTK_NDP_CO_PRO | -MTK_RX_DMA_EN |MTK_RX_2B_OFFSET | -MTK_RX_BT_32DWORDS , -MTK_QDMA_GLO_CFG ); + val =mtk_r32 (eth,MTK_QDMA_GLO_CFG ); + val |=MTK_TX_DMA_EN |MTK_RX_DMA_EN | +MTK_TX_BT_32DWORDS |MTK_NDP_CO_PRO | +MTK_RX_2B_OFFSET |MTK_TX_WB_DDONE ; + +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) + val |=MTK_MUTLI_CNT |MTK_RESV_BUF | +MTK_WCOMP_EN |MTK_DMAD_WR_WDONE | +MTK_CHK_DDONE_EN ; +else + val |=MTK_RX_BT_32DWORDS ; +mtk_w32 (eth, val,MTK_QDMA_GLO_CFG ); mtk_w32(eth, MTK_RX_DMA_EN | rx_2b_offset |
@@ -2328,7 +2438,7 @@ static int mtk_open(struct net_device *dev)napi_enable (ð->tx_napi);napi_enable (ð->rx_napi);mtk_tx_irq_enable (eth,MTK_TX_DONE_INT ); -mtk_rx_irq_enable (eth,MTK_RX_DONE_INT ); +mtk_rx_irq_enable (eth, eth->soc->txrx.rx_irq_done_mask);refcount_set (ð->dma_refcnt,1 ); }else
@@ -2380,7 +2490,7 @@ static int mtk_stop(struct net_device *dev)mtk_gdm_config (eth,MTK_GDMA_DROP_ALL );mtk_tx_irq_disable (eth,MTK_TX_DONE_INT ); -mtk_rx_irq_disable (eth,MTK_RX_DONE_INT ); +mtk_rx_irq_disable (eth, eth->soc->txrx.rx_irq_done_mask);napi_disable (ð->tx_napi);napi_disable (ð->rx_napi);
@@ -2517,7 +2627,7 @@ static int mtk_hw_init(struct mtk_eth *eth)if (eth->ethsys)regmap_update_bits (eth->ethsys,ETHSYS_DMA_AG_MAP , dma_mask, -of_dma_is_coherent (eth->dma_dev->of_node) * dma_mask); +of_dma_is_coherent (eth->dma_dev->of_node) * dma_mask);if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) { ret =device_reset (eth->dev);
@@ -2537,9 +2647,25 @@ static int mtk_hw_init(struct mtk_eth *eth)return 0 ; } -/* Non-MT7628 handling... */ -ethsys_reset (eth,RSTCTRL_FE ); -ethsys_reset (eth,RSTCTRL_PPE ); + val =RSTCTRL_FE |RSTCTRL_PPE ; +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) { +regmap_write (eth->ethsys,ETHSYS_FE_RST_CHK_IDLE_EN ,0 ); + + val |=RSTCTRL_ETH ; +if (MTK_HAS_CAPS (eth->soc->caps,MTK_RSTCTRL_PPE1 )) + val |=RSTCTRL_PPE1 ; + } + +ethsys_reset (eth, val); + +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) { +regmap_write (eth->ethsys,ETHSYS_FE_RST_CHK_IDLE_EN , +0x3ffffff ); + +/* Set FE to PDMAv2 if necessary */ + val =mtk_r32 (eth,MTK_FE_GLO_MISC ); +mtk_w32 (eth, val |BIT (4 ),MTK_FE_GLO_MISC ); + }if (eth->pctl) {/* Set GE2 driving and slew rate */
@@ -2578,11 +2704,47 @@ static int mtk_hw_init(struct mtk_eth *eth)/* FE int grouping */ mtk_w32 (eth,MTK_TX_DONE_INT ,MTK_PDMA_INT_GRP1 ); -mtk_w32 (eth,MTK_RX_DONE_INT ,MTK_PDMA_INT_GRP2 ); +mtk_w32 (eth, eth->soc->txrx.rx_irq_done_mask,MTK_PDMA_INT_GRP2 );mtk_w32 (eth,MTK_TX_DONE_INT ,MTK_QDMA_INT_GRP1 ); -mtk_w32 (eth,MTK_RX_DONE_INT ,MTK_QDMA_INT_GRP2 ); +mtk_w32 (eth, eth->soc->txrx.rx_irq_done_mask,MTK_QDMA_INT_GRP2 );mtk_w32 (eth,0x21021000 ,MTK_FE_INT_GRP ); +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) { +/* PSE should not drop port8 and port9 packets */ +mtk_w32 (eth,0x00000300 ,PSE_DROP_CFG ); + +/* PSE Free Queue Flow Control */ +mtk_w32 (eth,0x01fa01f4 ,PSE_FQFC_CFG2 ); + +/* PSE config input queue threshold */ +mtk_w32 (eth,0x001a000e ,PSE_IQ_REV (1 )); +mtk_w32 (eth,0x01ff001a ,PSE_IQ_REV (2 )); +mtk_w32 (eth,0x000e01ff ,PSE_IQ_REV (3 )); +mtk_w32 (eth,0x000e000e ,PSE_IQ_REV (4 )); +mtk_w32 (eth,0x000e000e ,PSE_IQ_REV (5 )); +mtk_w32 (eth,0x000e000e ,PSE_IQ_REV (6 )); +mtk_w32 (eth,0x000e000e ,PSE_IQ_REV (7 )); +mtk_w32 (eth,0x000e000e ,PSE_IQ_REV (8 )); + +/* PSE config output queue threshold */ +mtk_w32 (eth,0x000f000a ,PSE_OQ_TH (1 )); +mtk_w32 (eth,0x001a000f ,PSE_OQ_TH (2 )); +mtk_w32 (eth,0x000f001a ,PSE_OQ_TH (3 )); +mtk_w32 (eth,0x01ff000f ,PSE_OQ_TH (4 )); +mtk_w32 (eth,0x000f000f ,PSE_OQ_TH (5 )); +mtk_w32 (eth,0x0006000f ,PSE_OQ_TH (6 )); +mtk_w32 (eth,0x00060006 ,PSE_OQ_TH (7 )); +mtk_w32 (eth,0x00060006 ,PSE_OQ_TH (8 )); + +/* GDM and CDM Threshold */ +mtk_w32 (eth,0x00000004 ,MTK_GDM2_THRES ); +mtk_w32 (eth,0x00000004 ,MTK_CDMW0_THRES ); +mtk_w32 (eth,0x00000004 ,MTK_CDMW1_THRES ); +mtk_w32 (eth,0x00000004 ,MTK_CDME0_THRES ); +mtk_w32 (eth,0x00000004 ,MTK_CDME1_THRES ); +mtk_w32 (eth,0x00000004 ,MTK_CDMM_THRES ); + } +return 0 ; err_disable_pm:
@@ -3154,12 +3316,8 @@ static int mtk_probe(struct platform_device *pdev) eth->tx_int_status_reg =MTK_PDMA_INT_STATUS ; } -if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) { - eth->rx_dma_l4_valid =RX_DMA_L4_VALID_PDMA ; +if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 )) eth->ip_align =NET_IP_ALIGN ; - }else { - eth->rx_dma_l4_valid =RX_DMA_L4_VALID ; - }spin_lock_init (ð->page_lock);spin_lock_init (ð->tx_irq_lock);
@@ -3395,6 +3553,10 @@ static const struct mtk_soc_data mt2701_data = { .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), + .rx_irq_done_mask = MTK_RX_DONE_INT, + .rx_dma_l4_valid = RX_DMA_L4_VALID, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, }, };
@@ -3408,6 +3570,10 @@ static const struct mtk_soc_data mt7621_data = { .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), + .rx_irq_done_mask = MTK_RX_DONE_INT, + .rx_dma_l4_valid = RX_DMA_L4_VALID, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, }, };
@@ -3422,6 +3588,10 @@ static const struct mtk_soc_data mt7622_data = { .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), + .rx_irq_done_mask = MTK_RX_DONE_INT, + .rx_dma_l4_valid = RX_DMA_L4_VALID, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, }, };
@@ -3435,6 +3605,10 @@ static const struct mtk_soc_data mt7623_data = { .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), + .rx_irq_done_mask = MTK_RX_DONE_INT, + .rx_dma_l4_valid = RX_DMA_L4_VALID, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, }, };
@@ -3448,6 +3622,10 @@ static const struct mtk_soc_data mt7629_data = { .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), + .rx_irq_done_mask = MTK_RX_DONE_INT, + .rx_dma_l4_valid = RX_DMA_L4_VALID, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, }, };
@@ -3460,6 +3638,10 @@ static const struct mtk_soc_data rt5350_data = { .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), + .rx_irq_done_mask = MTK_RX_DONE_INT, + .rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA, + .dma_max_len = MTK_TX_DMA_BUF_LEN, + .dma_len_offset = 16, }, };
drivers/net/ethernet/mediatek/mtk_eth_soc.h +119 -10
260 lines not on this page · raw message
Signature · 1 line
2.35.3
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 12/15] net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
Quoted 26 lines · On Mon, 16 May 2022 18:06:39 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.c +26
-0+struct mtk_mac *mac =netdev_priv (dev); +struct mtk_tx_dma_v2 *desc = txd; +struct mtk_eth *eth = mac->hw; +u32 data; + +WRITE_ONCE (desc->txd1, info->addr); + + data =TX_DMA_PLEN0 (info->size); +if (info->last) + data |=TX_DMA_LS0 ; +WRITE_ONCE (desc->txd3, data); + +if (!info->qid && mac->id) + info->qid =MTK_QDMA_GMAC2_QID ; + + data = (mac->id +1 ) <<TX_DMA_FPORT_SHIFT_V2 ;/* forward port */ + data |=TX_DMA_SWC_V2 |QID_BITS_V2 (info->qid); +WRITE_ONCE (desc->txd4, data); + + data =0 ; +if (info->first) { +if (info->gso) + data |=TX_DMA_TSO_V2 ; +/* tx checksum offload */ +if (info->csum) + data |=TX_DMA_CHKSUM_V2 ;
drivers/net/ethernet/mediatek/mtk_eth_soc.c static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc, · line 1014
Quoted 10 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +10
-0+ } +WRITE_ONCE (desc->txd5, data); + + data =0 ; +if (info->first && info->vlan) + data |=TX_DMA_INS_VLAN_V2 | info->vlan_tci; +WRITE_ONCE (desc->txd6, data); + +WRITE_ONCE (desc->txd7,0 ); +WRITE_ONCE (desc->txd8,0 );
Why all the WRITE_ONCE()? Don't you just need a barrier between writing the descriptor and kicking the HW?
Lorenzo Bianconi
maintainerRe: [PATCH v2 net-next 12/15] net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
Quoted 32 lines · Jakub Kicinski
Quoted 31 lines · On Mon, 16 May 2022 18:06:39 +0200 Lorenzo Bianconi wrote:
drivers/net/ethernet/mediatek/mtk_eth_soc.c +31
-0+struct mtk_mac *mac =netdev_priv (dev); +struct mtk_tx_dma_v2 *desc = txd; +struct mtk_eth *eth = mac->hw; +u32 data; + +WRITE_ONCE (desc->txd1, info->addr); + + data =TX_DMA_PLEN0 (info->size); +if (info->last) + data |=TX_DMA_LS0 ; +WRITE_ONCE (desc->txd3, data); + +if (!info->qid && mac->id) + info->qid =MTK_QDMA_GMAC2_QID ; + + data = (mac->id +1 ) <<TX_DMA_FPORT_SHIFT_V2 ;/* forward port */ + data |=TX_DMA_SWC_V2 |QID_BITS_V2 (info->qid); +WRITE_ONCE (desc->txd4, data); + + data =0 ; +if (info->first) { +if (info->gso) + data |=TX_DMA_TSO_V2 ; +/* tx checksum offload */ +if (info->csum) + data |=TX_DMA_CHKSUM_V2 ; + } +WRITE_ONCE (desc->txd5, data); + + data =0 ; +if (info->first && info->vlan)
Quoted 8 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc, · line 1014
Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +5
-0+ data |=TX_DMA_INS_VLAN_V2 | info->vlan_tci; +WRITE_ONCE (desc->txd6, data); + +WRITE_ONCE (desc->txd7,0 ); +WRITE_ONCE (desc->txd8,0 );Why all the
WRITE_ONCE()? Don't you just need a barrier between writing the descriptor and kicking the HW?
I used this approach just to be aligned with current codebase:
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1006
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1031
but I guess we can even convert the code to use barrier instead. Agree?
Regards,
Lorenzo
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 12/15] net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
Quoted 11 lines · On Wed, 18 May 2022 11:53:12 +0200 Lorenzo Bianconi wrote:
Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc, · line 1014
Quoted 2 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +2
-0+WRITE_ONCE (desc->txd7,0 ); +WRITE_ONCE (desc->txd8,0 );Why all the
WRITE_ONCE()? Don't you just need a barrier between writing the descriptor and kicking the HW?I used this approach just to be aligned with current codebase:
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1006
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1031but I guess we can even convert the code to use barrier instead. Agree?
Oh, I didn't realize. No preference on converting the old code but it looks like a cargo cult to me so in the new code let's not WRITE_ONCE() all descriptor writes unless there's a reason.
Felix Fietkau
maintainerRe: [PATCH v2 net-next 12/15] net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
Quoted 11 lines · Jakub Kicinski
Quoted 10 lines · On Wed, 18 May 2022 11:53:12 +0200 Lorenzo Bianconi wrote:
Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc, · line 1014
Quoted 2 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +2
-0+WRITE_ONCE (desc->txd7,0 ); +WRITE_ONCE (desc->txd8,0 );Why all the
WRITE_ONCE()? Don't you just need a barrier between writing the descriptor and kicking the HW?I used this approach just to be aligned with current codebase:
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1006
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1031
Quoted 5 lines
Quoted 1 line
but I guess we can even convert the code to use barrier instead. Agree?
Oh, I didn't realize. No preference on converting the old code but it looks like a cargo cult to me so in the new code let's not
WRITE_ONCE()all descriptor writes unless there's a reason.
If I remember correctly, the existing places use WRITE_ONCE to prevent write tearing to uncached memory.
- Felix
_______________________________________________
Linux-mediatek mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-mediatek
Jakub Kicinski
maintainerRe: [PATCH v2 net-next 12/15] net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support
Quoted 5 lines · On Wed, 18 May 2022 17:50:12 +0200 Felix Fietkau wrote:
Quoted 4 lines · Jakub Kicinski
Quoted 4 lines
I used this approach just to be aligned with current codebase:
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1006
https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L1031
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
but I guess we can even convert the code to use barrier instead. Agree?
Oh, I didn't realize. No preference on converting the old code but it looks like a cargo cult to me so in the new code let's not
WRITE_ONCE()all descriptor writes unless there's a reason.If I remember correctly, the existing places use
WRITE_ONCEto prevent write tearing to uncached memory.
Okay, makes sense then.
Lorenzo Bianconi
maintainerPATCH v2 13/15 net: ethernet: mtk_eth_soc: convert ring dma pointer to void
In reply to Lorenzo BianconiSimplify the code converting {tx,rx} ring dma pointer to void
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 32 +++++++++------------ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 +-- 2 files changed, 16 insertions(+), 20 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +14 -18
@@ -851,18 +851,15 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)return 0 ; } -static inline void *mtk_qdma_phys_to_virt (struct mtk_tx_ring *ring,u32 desc) +static void *mtk_qdma_phys_to_virt (struct mtk_tx_ring *ring,u32 desc) { -void *ret = ring->dma; - -return ret + (desc - ring->phys); +return ring->dma + (desc - ring->phys); }static struct mtk_tx_buf *mtk_desc_to_tx_buf (struct mtk_tx_ring *ring, -struct mtk_tx_dma *txd, -u32 txd_size) +void *txd,u32 txd_size) { -int idx = ((void *)txd - (void *)ring->dma) / txd_size; +int idx = (txd - ring->dma) / txd_size;return &ring->buf[idx]; }
@@ -870,13 +867,12 @@ static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,static struct mtk_tx_dma *qdma_to_pdma (struct mtk_tx_ring *ring,struct mtk_tx_dma *dma) { -return ring->dma_pdma - ring->dma + dma; +return ring->dma_pdma - (struct mtk_tx_dma *)ring->dma + dma; } -static int txd_to_idx (struct mtk_tx_ring *ring,struct mtk_tx_dma *dma, -u32 txd_size) +static int txd_to_idx (struct mtk_tx_ring *ring,void *dma,u32 txd_size) { -return ((void *)dma - (void *)ring->dma) / txd_size; +return (dma - ring->dma) / txd_size; } static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
@@ -1293,7 +1289,7 @@ static struct mtk_rx_ring *mtk_get_rx_ring(struct mtk_eth *eth) ring = ð->rx_ring[i]; idx =NEXT_DESP_IDX (ring->calc_idx, ring->dma_size); - rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; + rxd = ring->dma + idx * eth->soc->txrx.rxd_size;if (rxd->rxd2 &RX_DMA_DONE ) { ring->calc_idx_update = true;return ring;
@@ -1345,7 +1341,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, goto rx_done; idx =NEXT_DESP_IDX (ring->calc_idx, ring->dma_size); - rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; + rxd = ring->dma + idx * eth->soc->txrx.rxd_size; data = ring->data[idx];if (!mtk_rx_get_desc (eth, &trxd, rxd))
@@ -1548,7 +1544,7 @@ static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget,mtk_tx_unmap (eth, tx_buf, true); - desc = (void *)ring->dma + cpu * eth->soc->txrx.txd_size; + desc = ring->dma + cpu * eth->soc->txrx.txd_size; ring->last_free = desc;atomic_inc (&ring->free_count);
@@ -1692,7 +1688,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)int next = (i +1 ) %MTK_DMA_SIZE ;u32 next_ptr = ring->phys + next * soc->txrx.txd_size; - txd = (void *)ring->dma + i * soc->txrx.txd_size; + txd = ring->dma + i * soc->txrx.txd_size; txd->txd2 = next_ptr; txd->txd3 =TX_DMA_LS0 |TX_DMA_OWNER_CPU ; txd->txd4 =0 ;
@@ -1723,7 +1719,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) ring->dma_size =MTK_DMA_SIZE ;atomic_set (&ring->free_count,MTK_DMA_SIZE -2 ); - ring->next_free = &ring->dma[0 ]; + ring->next_free = ring->dma; ring->last_free = (void *)txd; ring->last_free_ptr = (u32)(ring->phys + (MTK_DMA_SIZE -1 ) * soc->txrx.txd_size);
@@ -1835,7 +1831,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)if (unlikely (dma_mapping_error (eth->dma_dev, dma_addr)))return -ENOMEM ; - rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; + rxd = ring->dma + i * eth->soc->txrx.rxd_size; rxd->rxd1 = (unsigned int )dma_addr;if (MTK_HAS_CAPS (eth->soc->caps,MTK_SOC_MT7628 ))
@@ -1889,7 +1885,7 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)if (!ring->data[i])continue ; - rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; + rxd = ring->dma + i * eth->soc->txrx.rxd_size;if (!rxd->rxd1)continue ;
drivers/net/ethernet/mediatek/mtk_eth_soc.h +2 -2
@@ -828,7 +828,7 @@ struct mtk_tx_buf {* are present */ struct mtk_tx_ring { -struct mtk_tx_dma *dma; +void *dma;struct mtk_tx_buf *buf;dma_addr_t phys;struct mtk_tx_dma *next_free;
@@ -858,7 +858,7 @@ enum mtk_rx_flags {* @calc_idx: The current head of ring */ struct mtk_rx_ring { -struct mtk_rx_dma *dma; +void *dma;u8 **data;dma_addr_t phys;u16 frag_size;
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 14/15 net: ethernet: mtk_eth_soc: convert scratch_ring pointer to void
In reply to Lorenzo BianconiSimplify the code converting scratch_ring pointer to void
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +1 -1
@@ -827,7 +827,7 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)for (i =0 ; i < cnt; i++) {struct mtk_tx_dma_v2 *txd; - txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size; + txd = eth->scratch_ring + i * soc->txrx.txd_size; txd->txd1 = dma_addr + i *MTK_QDMA_PAGE_SIZE ;if (i < cnt -1 ) txd->txd2 = eth->phy_scratch_ring +
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1 -1
@@ -1131,7 +1131,7 @@ struct mtk_eth {struct mtk_rx_ring rx_ring_qdma;struct napi_struct tx_napi;struct napi_struct rx_napi; -struct mtk_tx_dma *scratch_ring; +void *scratch_ring;dma_addr_t phy_scratch_ring;void *scratch_head;struct clk *clks[MTK_CLK_MAX ];
Signature · 1 line
2.35.3
Lorenzo Bianconi
maintainerPATCH v2 15/15 net: ethernet: mtk_eth_soc: introduce support for mt7986 chipset
In reply to Lorenzo BianconiAdd support for mt7986-eth driver available on mt7986 soc.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 29 ++++++++++++++++++++- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 18 +++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +28 -1
@@ -45,6 +45,17 @@ static const u32 mtk_reg_map[] = { [MTK_PDMA_RSS_GLO_BASE] = 0x3000, }; +static const u32 mt7986_reg_map[] = { + [MTK_PDMA_BASE ] =0x6000 , + [MTK_PDMA_LRO_CTRL ] =0x6408 , + [MTK_PDMA_ALT_SCORE_DELTA_BASE ] =0x641c , + [MTK_PDMA_LRO_RX_RING_DIP_BASE ] =0x6414 , + [MTK_PDMA_LRO_RX_RING_CTRL_BASE ] =0x6438 , + [MTK_QDMA_BASE ] =0x4400 , + [MTK_GDM1_TX_STAT_BASE ] =0x1c00 , + [MTK_PDMA_RSS_GLO_BASE ] =0x6800 , +}; +/* strings used by ethtool */ static const struct mtk_ethtool_stats { char str[ETH_GSTRING_LEN];
@@ -68,7 +79,7 @@ static const char * const mtk_clks_source_name[] = {"ethif" ,"sgmiitop" ,"esw" ,"gp0" ,"gp1" ,"gp2" ,"fe" ,"trgpll" ,"sgmii_tx250m" ,"sgmii_rx250m" ,"sgmii_cdr_ref" ,"sgmii_cdr_fb" ,"sgmii2_tx250m" ,"sgmii2_rx250m" ,"sgmii2_cdr_ref" ,"sgmii2_cdr_fb" , - "sgmii_ck", "eth2pll", +"sgmii_ck" ,"eth2pll" ,"wocpu0" ,"wocpu1" ,"netsys0" ,"netsys1" };void mtk_w32 (struct mtk_eth *eth,u32 val,unsigned reg)
@@ -3625,6 +3636,21 @@ static const struct mtk_soc_data mt7629_data = { }, }; +static const struct mtk_soc_data mt7986_data = { + .reg_map = mt7986_reg_map, + .ana_rgc3 =0x128 , + .caps =MT7986_CAPS , + .required_clks =MT7986_CLKS_BITMAP , + .required_pctl = false, + .txrx = { + .txd_size =sizeof (struct mtk_tx_dma_v2 ), + .rxd_size =sizeof (struct mtk_rx_dma_v2 ), + .rx_irq_done_mask =MTK_RX_DONE_INT_V2 , + .dma_max_len =MTK_TX_DMA_BUF_LEN_V2 , + .dma_len_offset =8 , + }, +}; +static const struct mtk_soc_data rt5350_data = { .reg_map = mtk_reg_map, .caps =MT7628_CAPS ,
@@ -3647,6 +3673,7 @@ const struct of_device_id of_mtk_match[] = { { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, + { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, {}, };
drivers/net/ethernet/mediatek/mtk_eth_soc.h +18 -0
@@ -763,6 +763,10 @@ enum mtk_clks_map {MTK_CLK_SGMII2_CDR_FB ,MTK_CLK_SGMII_CK ,MTK_CLK_ETH2PLL , +MTK_CLK_WOCPU0 , +MTK_CLK_WOCPU1 , +MTK_CLK_NETSYS0 , +MTK_CLK_NETSYS1 , MTK_CLK_MAX };
@@ -793,6 +797,16 @@ enum mtk_clks_map { BIT(MTK_CLK_SGMII2_CDR_FB) | \ BIT(MTK_CLK_SGMII_CK) | \ BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) +#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ + BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ + BIT(MTK_CLK_SGMII_TX_250M) | \ + BIT(MTK_CLK_SGMII_RX_250M) | \ + BIT(MTK_CLK_SGMII_CDR_REF) | \ + BIT(MTK_CLK_SGMII_CDR_FB) | \ + BIT(MTK_CLK_SGMII2_TX_250M) | \ + BIT(MTK_CLK_SGMII2_RX_250M) | \ + BIT(MTK_CLK_SGMII2_CDR_REF) | \ + BIT(MTK_CLK_SGMII2_CDR_FB))enum mtk_dev_state {MTK_HW_INIT ,
@@ -991,6 +1005,10 @@ enum mkt_eth_capabilities { MTK_MUX_U3_GMAC2_TO_QPHY | \ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) +#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) +struct mtk_tx_dma_desc_info {dma_addr_t addr;u32 size;
Signature · 1 line
2.35.3