Commit 8000ddc0 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller

net: stmmac: Add support for SA Insertion/Replacement in XGMAC cores

Add the support for Source Address Insertion and Replacement in XGMAC
cores. Two methods are supported: Descriptor based and register based.
Signed-off-by: default avatarJose Abreu <joabreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bfc56530
...@@ -337,6 +337,8 @@ ...@@ -337,6 +337,8 @@
#define XGMAC_TDES3_CPC GENMASK(27, 26) #define XGMAC_TDES3_CPC GENMASK(27, 26)
#define XGMAC_TDES3_CPC_SHIFT 26 #define XGMAC_TDES3_CPC_SHIFT 26
#define XGMAC_TDES3_TCMSSV BIT(26) #define XGMAC_TDES3_TCMSSV BIT(26)
#define XGMAC_TDES3_SAIC GENMASK(25, 23)
#define XGMAC_TDES3_SAIC_SHIFT 23
#define XGMAC_TDES3_THL GENMASK(22, 19) #define XGMAC_TDES3_THL GENMASK(22, 19)
#define XGMAC_TDES3_THL_SHIFT 19 #define XGMAC_TDES3_THL_SHIFT 19
#define XGMAC_TDES3_TSE BIT(18) #define XGMAC_TDES3_TSE BIT(18)
......
...@@ -1075,6 +1075,16 @@ static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index, ...@@ -1075,6 +1075,16 @@ static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index,
return 0; return 0;
} }
static void dwxgmac2_sarc_configure(void __iomem *ioaddr, int val)
{
u32 value = readl(ioaddr + XGMAC_TX_CONFIG);
value &= ~XGMAC_CONFIG_SARC;
value |= val << XGMAC_CONFIG_SARC_SHIFT;
writel(value, ioaddr + XGMAC_TX_CONFIG);
}
const struct stmmac_ops dwxgmac210_ops = { const struct stmmac_ops dwxgmac210_ops = {
.core_init = dwxgmac2_core_init, .core_init = dwxgmac2_core_init,
.set_mac = dwxgmac2_set_mac, .set_mac = dwxgmac2_set_mac,
...@@ -1113,6 +1123,7 @@ const struct stmmac_ops dwxgmac210_ops = { ...@@ -1113,6 +1123,7 @@ const struct stmmac_ops dwxgmac210_ops = {
.rxp_config = dwxgmac3_rxp_config, .rxp_config = dwxgmac3_rxp_config,
.get_mac_tx_timestamp = dwxgmac2_get_mac_tx_timestamp, .get_mac_tx_timestamp = dwxgmac2_get_mac_tx_timestamp,
.flex_pps_config = dwxgmac2_flex_pps_config, .flex_pps_config = dwxgmac2_flex_pps_config,
.sarc_configure = dwxgmac2_sarc_configure,
}; };
int dwxgmac2_setup(struct stmmac_priv *priv) int dwxgmac2_setup(struct stmmac_priv *priv)
......
...@@ -148,7 +148,7 @@ static void dwxgmac2_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, ...@@ -148,7 +148,7 @@ static void dwxgmac2_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
p->des2 |= cpu_to_le32(len & XGMAC_TDES2_B1L); p->des2 |= cpu_to_le32(len & XGMAC_TDES2_B1L);
tdes3 = tot_pkt_len & XGMAC_TDES3_FL; tdes3 |= tot_pkt_len & XGMAC_TDES3_FL;
if (is_fs) if (is_fs)
tdes3 |= XGMAC_TDES3_FD; tdes3 |= XGMAC_TDES3_FD;
else else
...@@ -298,6 +298,13 @@ static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr) ...@@ -298,6 +298,13 @@ static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr)
p->des3 = cpu_to_le32(upper_32_bits(addr)); p->des3 = cpu_to_le32(upper_32_bits(addr));
} }
static void dwxgmac2_set_sarc(struct dma_desc *p, u32 sarc_type)
{
sarc_type <<= XGMAC_TDES3_SAIC_SHIFT;
p->des3 |= cpu_to_le32(sarc_type & XGMAC_TDES3_SAIC);
}
const struct stmmac_desc_ops dwxgmac210_desc_ops = { const struct stmmac_desc_ops dwxgmac210_desc_ops = {
.tx_status = dwxgmac2_get_tx_status, .tx_status = dwxgmac2_get_tx_status,
.rx_status = dwxgmac2_get_rx_status, .rx_status = dwxgmac2_get_rx_status,
...@@ -324,4 +331,5 @@ const struct stmmac_desc_ops dwxgmac210_desc_ops = { ...@@ -324,4 +331,5 @@ const struct stmmac_desc_ops dwxgmac210_desc_ops = {
.get_rx_hash = dwxgmac2_get_rx_hash, .get_rx_hash = dwxgmac2_get_rx_hash,
.get_rx_header_len = dwxgmac2_get_rx_header_len, .get_rx_header_len = dwxgmac2_get_rx_header_len,
.set_sec_addr = dwxgmac2_set_sec_addr, .set_sec_addr = dwxgmac2_set_sec_addr,
.set_sarc = dwxgmac2_set_sarc,
}; };
...@@ -91,6 +91,7 @@ struct stmmac_desc_ops { ...@@ -91,6 +91,7 @@ struct stmmac_desc_ops {
enum pkt_hash_types *type); enum pkt_hash_types *type);
int (*get_rx_header_len)(struct dma_desc *p, unsigned int *len); int (*get_rx_header_len)(struct dma_desc *p, unsigned int *len);
void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr); void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr);
void (*set_sarc)(struct dma_desc *p, u32 sarc_type);
}; };
#define stmmac_init_rx_desc(__priv, __args...) \ #define stmmac_init_rx_desc(__priv, __args...) \
...@@ -147,6 +148,8 @@ struct stmmac_desc_ops { ...@@ -147,6 +148,8 @@ struct stmmac_desc_ops {
stmmac_do_callback(__priv, desc, get_rx_header_len, __args) stmmac_do_callback(__priv, desc, get_rx_header_len, __args)
#define stmmac_set_desc_sec_addr(__priv, __args...) \ #define stmmac_set_desc_sec_addr(__priv, __args...) \
stmmac_do_void_callback(__priv, desc, set_sec_addr, __args) stmmac_do_void_callback(__priv, desc, set_sec_addr, __args)
#define stmmac_set_desc_sarc(__priv, __args...) \
stmmac_do_void_callback(__priv, desc, set_sarc, __args)
struct stmmac_dma_cfg; struct stmmac_dma_cfg;
struct dma_features; struct dma_features;
...@@ -350,6 +353,8 @@ struct stmmac_ops { ...@@ -350,6 +353,8 @@ struct stmmac_ops {
bool is_double); bool is_double);
/* TX Timestamp */ /* TX Timestamp */
int (*get_mac_tx_timestamp)(struct mac_device_info *hw, u64 *ts); int (*get_mac_tx_timestamp)(struct mac_device_info *hw, u64 *ts);
/* Source Address Insertion / Replacement */
void (*sarc_configure)(void __iomem *ioaddr, int val);
}; };
#define stmmac_core_init(__priv, __args...) \ #define stmmac_core_init(__priv, __args...) \
...@@ -426,6 +431,8 @@ struct stmmac_ops { ...@@ -426,6 +431,8 @@ struct stmmac_ops {
stmmac_do_void_callback(__priv, mac, update_vlan_hash, __args) stmmac_do_void_callback(__priv, mac, update_vlan_hash, __args)
#define stmmac_get_mac_tx_timestamp(__priv, __args...) \ #define stmmac_get_mac_tx_timestamp(__priv, __args...) \
stmmac_do_callback(__priv, mac, get_mac_tx_timestamp, __args) stmmac_do_callback(__priv, mac, get_mac_tx_timestamp, __args)
#define stmmac_sarc_configure(__priv, __args...) \
stmmac_do_void_callback(__priv, mac, sarc_configure, __args)
/* PTP and HW Timer helpers */ /* PTP and HW Timer helpers */
struct stmmac_hwtimestamp { struct stmmac_hwtimestamp {
......
...@@ -139,6 +139,7 @@ struct stmmac_priv { ...@@ -139,6 +139,7 @@ struct stmmac_priv {
bool tx_path_in_lpi_mode; bool tx_path_in_lpi_mode;
bool tso; bool tso;
int sph; int sph;
u32 sarc_type;
unsigned int dma_buf_sz; unsigned int dma_buf_sz;
unsigned int rx_copybreak; unsigned int rx_copybreak;
......
...@@ -3004,6 +3004,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3004,6 +3004,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
priv->xstats.tx_set_ic_bit++; priv->xstats.tx_set_ic_bit++;
} }
if (priv->sarc_type)
stmmac_set_desc_sarc(priv, first, priv->sarc_type);
skb_tx_timestamp(skb); skb_tx_timestamp(skb);
if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
...@@ -3217,6 +3220,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3217,6 +3220,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
priv->xstats.tx_set_ic_bit++; priv->xstats.tx_set_ic_bit++;
} }
if (priv->sarc_type)
stmmac_set_desc_sarc(priv, first, priv->sarc_type);
skb_tx_timestamp(skb); skb_tx_timestamp(skb);
/* Ready to fill the first descriptor and set the OWN bit w/o any /* Ready to fill the first descriptor and set the OWN bit w/o any
......
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