Commit 8c6fc097 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller

net: stmmac: gmac4+: Add Split Header support

GMAC4+ cores also support the Split Header feature.

Add the support for Split Header feature in the RX path following the
same implementation logic that XGMAC followed.
Signed-off-by: default avatarJose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a24cae70
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
/* MAC registers */ /* MAC registers */
#define GMAC_CONFIG 0x00000000 #define GMAC_CONFIG 0x00000000
#define GMAC_EXT_CONFIG 0x00000004
#define GMAC_PACKET_FILTER 0x00000008 #define GMAC_PACKET_FILTER 0x00000008
#define GMAC_HASH_TAB(x) (0x10 + (x) * 4) #define GMAC_HASH_TAB(x) (0x10 + (x) * 4)
#define GMAC_VLAN_TAG 0x00000050 #define GMAC_VLAN_TAG 0x00000050
...@@ -188,6 +189,11 @@ enum power_event { ...@@ -188,6 +189,11 @@ enum power_event {
#define GMAC_CONFIG_TE BIT(1) #define GMAC_CONFIG_TE BIT(1)
#define GMAC_CONFIG_RE BIT(0) #define GMAC_CONFIG_RE BIT(0)
/* MAC extended config */
#define GMAC_CONFIG_HDSMS GENMASK(22, 20)
#define GMAC_CONFIG_HDSMS_SHIFT 20
#define GMAC_CONFIG_HDSMS_256 (0x2 << GMAC_CONFIG_HDSMS_SHIFT)
/* MAC HW features0 bitmap */ /* MAC HW features0 bitmap */
#define GMAC_HW_FEAT_SAVLANINS BIT(27) #define GMAC_HW_FEAT_SAVLANINS BIT(27)
#define GMAC_HW_FEAT_ADDMAC BIT(18) #define GMAC_HW_FEAT_ADDMAC BIT(18)
...@@ -211,6 +217,7 @@ enum power_event { ...@@ -211,6 +217,7 @@ enum power_event {
#define GMAC_HW_HASH_TB_SZ GENMASK(25, 24) #define GMAC_HW_HASH_TB_SZ GENMASK(25, 24)
#define GMAC_HW_FEAT_AVSEL BIT(20) #define GMAC_HW_FEAT_AVSEL BIT(20)
#define GMAC_HW_TSOEN BIT(18) #define GMAC_HW_TSOEN BIT(18)
#define GMAC_HW_FEAT_SPHEN BIT(17)
#define GMAC_HW_ADDR64 GENMASK(15, 14) #define GMAC_HW_ADDR64 GENMASK(15, 14)
#define GMAC_HW_TXFIFOSIZE GENMASK(10, 6) #define GMAC_HW_TXFIFOSIZE GENMASK(10, 6)
#define GMAC_HW_RXFIFOSIZE GENMASK(4, 0) #define GMAC_HW_RXFIFOSIZE GENMASK(4, 0)
......
...@@ -83,9 +83,10 @@ static int dwmac4_wrback_get_rx_status(void *data, struct stmmac_extra_stats *x, ...@@ -83,9 +83,10 @@ static int dwmac4_wrback_get_rx_status(void *data, struct stmmac_extra_stats *x,
if (unlikely(rdes3 & RDES3_OWN)) if (unlikely(rdes3 & RDES3_OWN))
return dma_own; return dma_own;
/* Verify rx error by looking at the last segment. */ if (unlikely(rdes3 & RDES3_CONTEXT_DESCRIPTOR))
if (likely(!(rdes3 & RDES3_LAST_DESCRIPTOR)))
return discard_frame; return discard_frame;
if (likely(!(rdes3 & RDES3_LAST_DESCRIPTOR)))
return rx_not_ls;
if (unlikely(rdes3 & RDES3_ERROR_SUMMARY)) { if (unlikely(rdes3 & RDES3_ERROR_SUMMARY)) {
if (unlikely(rdes3 & RDES3_GIANT_PACKET)) if (unlikely(rdes3 & RDES3_GIANT_PACKET))
...@@ -188,7 +189,7 @@ static void dwmac4_set_tx_owner(struct dma_desc *p) ...@@ -188,7 +189,7 @@ static void dwmac4_set_tx_owner(struct dma_desc *p)
static void dwmac4_set_rx_owner(struct dma_desc *p, int disable_rx_ic) static void dwmac4_set_rx_owner(struct dma_desc *p, int disable_rx_ic)
{ {
p->des3 = cpu_to_le32(RDES3_OWN | RDES3_BUFFER1_VALID_ADDR); p->des3 |= cpu_to_le32(RDES3_OWN | RDES3_BUFFER1_VALID_ADDR);
if (!disable_rx_ic) if (!disable_rx_ic)
p->des3 |= cpu_to_le32(RDES3_INT_ON_COMPLETION_EN); p->des3 |= cpu_to_le32(RDES3_INT_ON_COMPLETION_EN);
...@@ -492,6 +493,18 @@ static void dwmac4_set_vlan(struct dma_desc *p, u32 type) ...@@ -492,6 +493,18 @@ static void dwmac4_set_vlan(struct dma_desc *p, u32 type)
p->des2 |= cpu_to_le32(type & TDES2_VLAN_TAG_MASK); p->des2 |= cpu_to_le32(type & TDES2_VLAN_TAG_MASK);
} }
static int dwmac4_get_rx_header_len(struct dma_desc *p, unsigned int *len)
{
*len = le32_to_cpu(p->des2) & RDES2_HL;
return 0;
}
static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr)
{
p->des2 = cpu_to_le32(lower_32_bits(addr));
p->des3 = cpu_to_le32(upper_32_bits(addr) | RDES3_BUFFER2_VALID_ADDR);
}
const struct stmmac_desc_ops dwmac4_desc_ops = { const struct stmmac_desc_ops dwmac4_desc_ops = {
.tx_status = dwmac4_wrback_get_tx_status, .tx_status = dwmac4_wrback_get_tx_status,
.rx_status = dwmac4_wrback_get_rx_status, .rx_status = dwmac4_wrback_get_rx_status,
...@@ -519,6 +532,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = { ...@@ -519,6 +532,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = {
.set_sarc = dwmac4_set_sarc, .set_sarc = dwmac4_set_sarc,
.set_vlan_tag = dwmac4_set_vlan_tag, .set_vlan_tag = dwmac4_set_vlan_tag,
.set_vlan = dwmac4_set_vlan, .set_vlan = dwmac4_set_vlan,
.get_rx_header_len = dwmac4_get_rx_header_len,
.set_sec_addr = dwmac4_set_sec_addr,
}; };
const struct stmmac_mode_ops dwmac4_ring_mode_ops = { const struct stmmac_mode_ops dwmac4_ring_mode_ops = {
......
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
#define RDES2_L4_FILTER_MATCH BIT(28) #define RDES2_L4_FILTER_MATCH BIT(28)
#define RDES2_L3_L4_FILT_NB_MATCH_MASK GENMASK(27, 26) #define RDES2_L3_L4_FILT_NB_MATCH_MASK GENMASK(27, 26)
#define RDES2_L3_L4_FILT_NB_MATCH_SHIFT 26 #define RDES2_L3_L4_FILT_NB_MATCH_SHIFT 26
#define RDES2_HL GENMASK(9, 0)
/* RDES3 (write back format) */ /* RDES3 (write back format) */
#define RDES3_PACKET_SIZE_MASK GENMASK(14, 0) #define RDES3_PACKET_SIZE_MASK GENMASK(14, 0)
......
...@@ -368,6 +368,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr, ...@@ -368,6 +368,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
dma_cap->hash_tb_sz = (hw_cap & GMAC_HW_HASH_TB_SZ) >> 24; dma_cap->hash_tb_sz = (hw_cap & GMAC_HW_HASH_TB_SZ) >> 24;
dma_cap->av = (hw_cap & GMAC_HW_FEAT_AVSEL) >> 20; dma_cap->av = (hw_cap & GMAC_HW_FEAT_AVSEL) >> 20;
dma_cap->tsoen = (hw_cap & GMAC_HW_TSOEN) >> 18; dma_cap->tsoen = (hw_cap & GMAC_HW_TSOEN) >> 18;
dma_cap->sphen = (hw_cap & GMAC_HW_FEAT_SPHEN) >> 17;
dma_cap->addr64 = (hw_cap & GMAC_HW_ADDR64) >> 14; dma_cap->addr64 = (hw_cap & GMAC_HW_ADDR64) >> 14;
switch (dma_cap->addr64) { switch (dma_cap->addr64) {
...@@ -460,6 +461,22 @@ static void dwmac4_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan) ...@@ -460,6 +461,22 @@ static void dwmac4_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan)
writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan)); writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
} }
static void dwmac4_enable_sph(void __iomem *ioaddr, bool en, u32 chan)
{
u32 value = readl(ioaddr + GMAC_EXT_CONFIG);
value &= ~GMAC_CONFIG_HDSMS;
value |= GMAC_CONFIG_HDSMS_256; /* Segment max 256 bytes */
writel(value, ioaddr + GMAC_EXT_CONFIG);
value = readl(ioaddr + DMA_CHAN_CONTROL(chan));
if (en)
value |= DMA_CONTROL_SPH;
else
value &= ~DMA_CONTROL_SPH;
writel(value, ioaddr + DMA_CHAN_CONTROL(chan));
}
const struct stmmac_dma_ops dwmac4_dma_ops = { const struct stmmac_dma_ops dwmac4_dma_ops = {
.reset = dwmac4_dma_reset, .reset = dwmac4_dma_reset,
.init = dwmac4_dma_init, .init = dwmac4_dma_init,
...@@ -486,6 +503,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = { ...@@ -486,6 +503,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
.enable_tso = dwmac4_enable_tso, .enable_tso = dwmac4_enable_tso,
.qmode = dwmac4_qmode, .qmode = dwmac4_qmode,
.set_bfsize = dwmac4_set_bfsize, .set_bfsize = dwmac4_set_bfsize,
.enable_sph = dwmac4_enable_sph,
}; };
const struct stmmac_dma_ops dwmac410_dma_ops = { const struct stmmac_dma_ops dwmac410_dma_ops = {
...@@ -514,4 +532,5 @@ const struct stmmac_dma_ops dwmac410_dma_ops = { ...@@ -514,4 +532,5 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
.enable_tso = dwmac4_enable_tso, .enable_tso = dwmac4_enable_tso,
.qmode = dwmac4_qmode, .qmode = dwmac4_qmode,
.set_bfsize = dwmac4_set_bfsize, .set_bfsize = dwmac4_set_bfsize,
.enable_sph = dwmac4_enable_sph,
}; };
...@@ -110,6 +110,7 @@ ...@@ -110,6 +110,7 @@
#define DMA_CHAN_STATUS(x) (DMA_CHANX_BASE_ADDR(x) + 0x60) #define DMA_CHAN_STATUS(x) (DMA_CHANX_BASE_ADDR(x) + 0x60)
/* DMA Control X */ /* DMA Control X */
#define DMA_CONTROL_SPH BIT(24)
#define DMA_CONTROL_MSS_MASK GENMASK(13, 0) #define DMA_CONTROL_MSS_MASK GENMASK(13, 0)
/* DMA Tx Channel X Control register defines */ /* DMA Tx Channel X Control register defines */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment