Commit 7d9e6c5a authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller

net: stmmac: Integrate XGMAC into main driver flow

Now that we have all the XGMAC related callbacks, lets start integrating
this IP block into main driver.

Also, we corrected the initialization flow to only start DMA after
setting descriptors length.
Signed-off-by: default avatarJose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4bb7aff9
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/of_mdio.h> #include <linux/of_mdio.h>
#include "dwmac1000.h" #include "dwmac1000.h"
#include "dwxgmac2.h"
#include "hwif.h" #include "hwif.h"
#define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES) #define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES)
...@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) ...@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
else else
priv->clk_csr = 0; priv->clk_csr = 0;
} }
if (priv->plat->has_xgmac) {
if (clk_rate > 400000000)
priv->clk_csr = 0x5;
else if (clk_rate > 350000000)
priv->clk_csr = 0x4;
else if (clk_rate > 300000000)
priv->clk_csr = 0x3;
else if (clk_rate > 250000000)
priv->clk_csr = 0x2;
else if (clk_rate > 150000000)
priv->clk_csr = 0x1;
else
priv->clk_csr = 0x0;
}
} }
static void print_pkt(unsigned char *buf, int len) static void print_pkt(unsigned char *buf, int len)
...@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, ...@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
if (!priv->hwts_rx_en) if (!priv->hwts_rx_en)
return; return;
/* For GMAC4, the valid timestamp is from CTX next desc. */ /* For GMAC4, the valid timestamp is from CTX next desc. */
if (priv->plat->has_gmac4) if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
desc = np; desc = np;
/* Check if timestamp is available */ /* Check if timestamp is available */
...@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
u32 ts_event_en = 0; u32 ts_event_en = 0;
u32 value = 0; u32 value = 0;
u32 sec_inc; u32 sec_inc;
bool xmac;
xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
netdev_alert(priv->dev, "No support for HW time stamping\n"); netdev_alert(priv->dev, "No support for HW time stamping\n");
...@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
/* PTP v1, UDP, any kind of event packet */ /* PTP v1, UDP, any kind of event packet */
config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
/* take time stamp for all event messages */ /* take time stamp for all event messages */
if (priv->plat->has_gmac4) if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1; snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
...@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA; ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */ /* take time stamp for all event messages */
if (priv->plat->has_gmac4) if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1; snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
...@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA; ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */ /* take time stamp for all event messages */
if (priv->plat->has_gmac4) if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1; snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
...@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
/* program Sub Second Increment reg */ /* program Sub Second Increment reg */
stmmac_config_sub_second_increment(priv, stmmac_config_sub_second_increment(priv,
priv->ptpaddr, priv->plat->clk_ptp_rate, priv->ptpaddr, priv->plat->clk_ptp_rate,
priv->plat->has_gmac4, &sec_inc); xmac, &sec_inc);
temp = div_u64(1000000000ULL, sec_inc); temp = div_u64(1000000000ULL, sec_inc);
/* Store sub second increment and flags for later use */ /* Store sub second increment and flags for later use */
...@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
*/ */
static int stmmac_init_ptp(struct stmmac_priv *priv) static int stmmac_init_ptp(struct stmmac_priv *priv)
{ {
bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
return -EOPNOTSUPP; return -EOPNOTSUPP;
priv->adv_ts = 0; priv->adv_ts = 0;
/* Check if adv_ts can be enabled for dwmac 4.x core */ /* Check if adv_ts can be enabled for dwmac 4.x / xgmac core */
if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp) if (xmac && priv->dma_cap.atime_stamp)
priv->adv_ts = 1; priv->adv_ts = 1;
/* Dwmac 3.x core with extend_desc can support adv_ts */ /* Dwmac 3.x core with extend_desc can support adv_ts */
else if (priv->extend_desc && priv->dma_cap.atime_stamp) else if (priv->extend_desc && priv->dma_cap.atime_stamp)
...@@ -2173,6 +2194,12 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) ...@@ -2173,6 +2194,12 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
return ret; return ret;
} }
/* DMA Configuration */
stmmac_dma_init(priv, priv->ioaddr, priv->plat->dma_cfg, atds);
if (priv->plat->axi)
stmmac_axi(priv, priv->ioaddr, priv->plat->axi);
/* DMA RX Channel Configuration */ /* DMA RX Channel Configuration */
for (chan = 0; chan < rx_channels_count; chan++) { for (chan = 0; chan < rx_channels_count; chan++) {
rx_q = &priv->rx_queue[chan]; rx_q = &priv->rx_queue[chan];
...@@ -2203,12 +2230,6 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) ...@@ -2203,12 +2230,6 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
for (chan = 0; chan < dma_csr_ch; chan++) for (chan = 0; chan < dma_csr_ch; chan++)
stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan); stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
/* DMA Configuration */
stmmac_dma_init(priv, priv->ioaddr, priv->plat->dma_cfg, atds);
if (priv->plat->axi)
stmmac_axi(priv, priv->ioaddr, priv->plat->axi);
return ret; return ret;
} }
...@@ -2526,9 +2547,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) ...@@ -2526,9 +2547,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
netdev_warn(priv->dev, "%s: failed debugFS registration\n", netdev_warn(priv->dev, "%s: failed debugFS registration\n",
__func__); __func__);
#endif #endif
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
if (priv->use_riwt) { if (priv->use_riwt) {
...@@ -2549,6 +2567,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) ...@@ -2549,6 +2567,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
stmmac_enable_tso(priv, priv->ioaddr, 1, chan); stmmac_enable_tso(priv, priv->ioaddr, 1, chan);
} }
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
return 0; return 0;
} }
...@@ -3305,6 +3326,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) ...@@ -3305,6 +3326,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
int coe = priv->hw->rx_csum; int coe = priv->hw->rx_csum;
unsigned int next_entry; unsigned int next_entry;
unsigned int count = 0; unsigned int count = 0;
bool xmac;
xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
if (netif_msg_rx_status(priv)) { if (netif_msg_rx_status(priv)) {
void *rx_head; void *rx_head;
...@@ -3406,7 +3430,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) ...@@ -3406,7 +3430,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
* in case of GMAC4 because it needs * in case of GMAC4 because it needs
* to refill the used descriptors, always. * to refill the used descriptors, always.
*/ */
if (unlikely(!priv->plat->has_gmac4 && if (unlikely(!xmac &&
((frame_len < priv->rx_copybreak) || ((frame_len < priv->rx_copybreak) ||
stmmac_rx_threshold_count(rx_q)))) { stmmac_rx_threshold_count(rx_q)))) {
skb = netdev_alloc_skb_ip_align(priv->dev, skb = netdev_alloc_skb_ip_align(priv->dev,
...@@ -3642,7 +3666,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) ...@@ -3642,7 +3666,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
u32 tx_cnt = priv->plat->tx_queues_to_use; u32 tx_cnt = priv->plat->tx_queues_to_use;
u32 queues_count; u32 queues_count;
u32 queue; u32 queue;
bool xmac;
xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt; queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt;
if (priv->irq_wake) if (priv->irq_wake)
...@@ -3661,7 +3687,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) ...@@ -3661,7 +3687,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
/* To handle GMAC own interrupts */ /* To handle GMAC own interrupts */
if ((priv->plat->has_gmac) || (priv->plat->has_gmac4)) { if ((priv->plat->has_gmac) || xmac) {
int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats); int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats);
int mtl_status; int mtl_status;
...@@ -4269,6 +4295,8 @@ int stmmac_dvr_probe(struct device *device, ...@@ -4269,6 +4295,8 @@ int stmmac_dvr_probe(struct device *device,
ndev->min_mtu = ETH_ZLEN - ETH_HLEN; ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00)) if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00))
ndev->max_mtu = JUMBO_LEN; ndev->max_mtu = JUMBO_LEN;
else if (priv->plat->has_xgmac)
ndev->max_mtu = XGMAC_JUMBO_LEN;
else else
ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
/* Will not overwrite ndev->max_mtu if plat->maxmtu > ndev->max_mtu /* Will not overwrite ndev->max_mtu if plat->maxmtu > ndev->max_mtu
...@@ -4290,7 +4318,8 @@ int stmmac_dvr_probe(struct device *device, ...@@ -4290,7 +4318,8 @@ int stmmac_dvr_probe(struct device *device,
* has to be disable and this can be done by passing the * has to be disable and this can be done by passing the
* riwt_off field from the platform. * riwt_off field from the platform.
*/ */
if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) { if (((priv->synopsys_id >= DWMAC_CORE_3_50) ||
(priv->plat->has_xgmac)) && (!priv->plat->riwt_off)) {
priv->use_riwt = 1; priv->use_riwt = 1;
dev_info(priv->device, dev_info(priv->device,
"Enable RX Mitigation via HW Watchdog Timer\n"); "Enable RX Mitigation via HW Watchdog Timer\n");
......
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