diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 9d104a05044d..ff1ffb46198a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -51,6 +51,7 @@ #include <linux/reset.h> #include <linux/of_mdio.h> #include "dwmac1000.h" +#include "dwxgmac2.h" #include "hwif.h" #define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES) @@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) else 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) @@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, if (!priv->hwts_rx_en) return; /* 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; /* Check if timestamp is available */ @@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) u32 ts_event_en = 0; u32 value = 0; u32 sec_inc; + bool xmac; + + xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { 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) /* PTP v1, UDP, any kind of event packet */ config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; /* take time stamp for all event messages */ - if (priv->plat->has_gmac4) + if (xmac) snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; else snap_type_sel = PTP_TCR_SNAPTYPSEL_1; @@ -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; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - if (priv->plat->has_gmac4) + if (xmac) snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; else snap_type_sel = PTP_TCR_SNAPTYPSEL_1; @@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - if (priv->plat->has_gmac4) + if (xmac) snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; else snap_type_sel = PTP_TCR_SNAPTYPSEL_1; @@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) /* program Sub Second Increment reg */ stmmac_config_sub_second_increment(priv, priv->ptpaddr, priv->plat->clk_ptp_rate, - priv->plat->has_gmac4, &sec_inc); + xmac, &sec_inc); temp = div_u64(1000000000ULL, sec_inc); /* 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) */ 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)) return -EOPNOTSUPP; priv->adv_ts = 0; - /* Check if adv_ts can be enabled for dwmac 4.x core */ - if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp) + /* Check if adv_ts can be enabled for dwmac 4.x / xgmac core */ + if (xmac && priv->dma_cap.atime_stamp) priv->adv_ts = 1; /* Dwmac 3.x core with extend_desc can support adv_ts */ else if (priv->extend_desc && priv->dma_cap.atime_stamp) @@ -2173,6 +2194,12 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) 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 */ for (chan = 0; chan < rx_channels_count; chan++) { rx_q = &priv->rx_queue[chan]; @@ -2203,12 +2230,6 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) for (chan = 0; chan < dma_csr_ch; 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; } @@ -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", __func__); #endif - /* Start the ball rolling... */ - stmmac_start_all_dma(priv); - priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; if (priv->use_riwt) { @@ -2549,6 +2567,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) stmmac_enable_tso(priv, priv->ioaddr, 1, chan); } + /* Start the ball rolling... */ + stmmac_start_all_dma(priv); + return 0; } @@ -3305,6 +3326,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) int coe = priv->hw->rx_csum; unsigned int next_entry; unsigned int count = 0; + bool xmac; + + xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; if (netif_msg_rx_status(priv)) { void *rx_head; @@ -3406,7 +3430,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) * in case of GMAC4 because it needs * to refill the used descriptors, always. */ - if (unlikely(!priv->plat->has_gmac4 && + if (unlikely(!xmac && ((frame_len < priv->rx_copybreak) || stmmac_rx_threshold_count(rx_q)))) { skb = netdev_alloc_skb_ip_align(priv->dev, @@ -3642,7 +3666,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) u32 tx_cnt = priv->plat->tx_queues_to_use; u32 queues_count; u32 queue; + bool xmac; + xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt; if (priv->irq_wake) @@ -3661,7 +3687,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) return IRQ_HANDLED; /* 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 mtl_status; @@ -4269,6 +4295,8 @@ int stmmac_dvr_probe(struct device *device, ndev->min_mtu = ETH_ZLEN - ETH_HLEN; if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00)) ndev->max_mtu = JUMBO_LEN; + else if (priv->plat->has_xgmac) + ndev->max_mtu = XGMAC_JUMBO_LEN; else ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); /* Will not overwrite ndev->max_mtu if plat->maxmtu > ndev->max_mtu @@ -4290,7 +4318,8 @@ int stmmac_dvr_probe(struct device *device, * has to be disable and this can be done by passing the * 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; dev_info(priv->device, "Enable RX Mitigation via HW Watchdog Timer\n"); |