Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
0002 /*
0003  * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
0004  * stmmac XGMAC support.
0005  */
0006 
0007 #include <linux/bitrev.h>
0008 #include <linux/crc32.h>
0009 #include <linux/iopoll.h>
0010 #include "stmmac.h"
0011 #include "stmmac_ptp.h"
0012 #include "dwxlgmac2.h"
0013 #include "dwxgmac2.h"
0014 
0015 static void dwxgmac2_core_init(struct mac_device_info *hw,
0016                    struct net_device *dev)
0017 {
0018     void __iomem *ioaddr = hw->pcsr;
0019     u32 tx, rx;
0020 
0021     tx = readl(ioaddr + XGMAC_TX_CONFIG);
0022     rx = readl(ioaddr + XGMAC_RX_CONFIG);
0023 
0024     tx |= XGMAC_CORE_INIT_TX;
0025     rx |= XGMAC_CORE_INIT_RX;
0026 
0027     if (hw->ps) {
0028         tx |= XGMAC_CONFIG_TE;
0029         tx &= ~hw->link.speed_mask;
0030 
0031         switch (hw->ps) {
0032         case SPEED_10000:
0033             tx |= hw->link.xgmii.speed10000;
0034             break;
0035         case SPEED_2500:
0036             tx |= hw->link.speed2500;
0037             break;
0038         case SPEED_1000:
0039         default:
0040             tx |= hw->link.speed1000;
0041             break;
0042         }
0043     }
0044 
0045     writel(tx, ioaddr + XGMAC_TX_CONFIG);
0046     writel(rx, ioaddr + XGMAC_RX_CONFIG);
0047     writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
0048 }
0049 
0050 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
0051 {
0052     u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
0053     u32 rx = readl(ioaddr + XGMAC_RX_CONFIG);
0054 
0055     if (enable) {
0056         tx |= XGMAC_CONFIG_TE;
0057         rx |= XGMAC_CONFIG_RE;
0058     } else {
0059         tx &= ~XGMAC_CONFIG_TE;
0060         rx &= ~XGMAC_CONFIG_RE;
0061     }
0062 
0063     writel(tx, ioaddr + XGMAC_TX_CONFIG);
0064     writel(rx, ioaddr + XGMAC_RX_CONFIG);
0065 }
0066 
0067 static int dwxgmac2_rx_ipc(struct mac_device_info *hw)
0068 {
0069     void __iomem *ioaddr = hw->pcsr;
0070     u32 value;
0071 
0072     value = readl(ioaddr + XGMAC_RX_CONFIG);
0073     if (hw->rx_csum)
0074         value |= XGMAC_CONFIG_IPC;
0075     else
0076         value &= ~XGMAC_CONFIG_IPC;
0077     writel(value, ioaddr + XGMAC_RX_CONFIG);
0078 
0079     return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC);
0080 }
0081 
0082 static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
0083                      u32 queue)
0084 {
0085     void __iomem *ioaddr = hw->pcsr;
0086     u32 value;
0087 
0088     value = readl(ioaddr + XGMAC_RXQ_CTRL0) & ~XGMAC_RXQEN(queue);
0089     if (mode == MTL_QUEUE_AVB)
0090         value |= 0x1 << XGMAC_RXQEN_SHIFT(queue);
0091     else if (mode == MTL_QUEUE_DCB)
0092         value |= 0x2 << XGMAC_RXQEN_SHIFT(queue);
0093     writel(value, ioaddr + XGMAC_RXQ_CTRL0);
0094 }
0095 
0096 static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
0097                    u32 queue)
0098 {
0099     void __iomem *ioaddr = hw->pcsr;
0100     u32 value, reg;
0101 
0102     reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
0103     if (queue >= 4)
0104         queue -= 4;
0105 
0106     value = readl(ioaddr + reg);
0107     value &= ~XGMAC_PSRQ(queue);
0108     value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
0109 
0110     writel(value, ioaddr + reg);
0111 }
0112 
0113 static void dwxgmac2_tx_queue_prio(struct mac_device_info *hw, u32 prio,
0114                    u32 queue)
0115 {
0116     void __iomem *ioaddr = hw->pcsr;
0117     u32 value, reg;
0118 
0119     reg = (queue < 4) ? XGMAC_TC_PRTY_MAP0 : XGMAC_TC_PRTY_MAP1;
0120     if (queue >= 4)
0121         queue -= 4;
0122 
0123     value = readl(ioaddr + reg);
0124     value &= ~XGMAC_PSTC(queue);
0125     value |= (prio << XGMAC_PSTC_SHIFT(queue)) & XGMAC_PSTC(queue);
0126 
0127     writel(value, ioaddr + reg);
0128 }
0129 
0130 static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw,
0131                         u32 rx_alg)
0132 {
0133     void __iomem *ioaddr = hw->pcsr;
0134     u32 value;
0135 
0136     value = readl(ioaddr + XGMAC_MTL_OPMODE);
0137     value &= ~XGMAC_RAA;
0138 
0139     switch (rx_alg) {
0140     case MTL_RX_ALGORITHM_SP:
0141         break;
0142     case MTL_RX_ALGORITHM_WSP:
0143         value |= XGMAC_RAA;
0144         break;
0145     default:
0146         break;
0147     }
0148 
0149     writel(value, ioaddr + XGMAC_MTL_OPMODE);
0150 }
0151 
0152 static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
0153                         u32 tx_alg)
0154 {
0155     void __iomem *ioaddr = hw->pcsr;
0156     bool ets = true;
0157     u32 value;
0158     int i;
0159 
0160     value = readl(ioaddr + XGMAC_MTL_OPMODE);
0161     value &= ~XGMAC_ETSALG;
0162 
0163     switch (tx_alg) {
0164     case MTL_TX_ALGORITHM_WRR:
0165         value |= XGMAC_WRR;
0166         break;
0167     case MTL_TX_ALGORITHM_WFQ:
0168         value |= XGMAC_WFQ;
0169         break;
0170     case MTL_TX_ALGORITHM_DWRR:
0171         value |= XGMAC_DWRR;
0172         break;
0173     default:
0174         ets = false;
0175         break;
0176     }
0177 
0178     writel(value, ioaddr + XGMAC_MTL_OPMODE);
0179 
0180     /* Set ETS if desired */
0181     for (i = 0; i < MTL_MAX_TX_QUEUES; i++) {
0182         value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(i));
0183         value &= ~XGMAC_TSA;
0184         if (ets)
0185             value |= XGMAC_ETS;
0186         writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(i));
0187     }
0188 }
0189 
0190 static void dwxgmac2_set_mtl_tx_queue_weight(struct mac_device_info *hw,
0191                          u32 weight, u32 queue)
0192 {
0193     void __iomem *ioaddr = hw->pcsr;
0194 
0195     writel(weight, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
0196 }
0197 
0198 static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
0199                     u32 chan)
0200 {
0201     void __iomem *ioaddr = hw->pcsr;
0202     u32 value, reg;
0203 
0204     reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1;
0205     if (queue >= 4)
0206         queue -= 4;
0207 
0208     value = readl(ioaddr + reg);
0209     value &= ~XGMAC_QxMDMACH(queue);
0210     value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue);
0211 
0212     writel(value, ioaddr + reg);
0213 }
0214 
0215 static void dwxgmac2_config_cbs(struct mac_device_info *hw,
0216                 u32 send_slope, u32 idle_slope,
0217                 u32 high_credit, u32 low_credit, u32 queue)
0218 {
0219     void __iomem *ioaddr = hw->pcsr;
0220     u32 value;
0221 
0222     writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue));
0223     writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
0224     writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue));
0225     writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue));
0226 
0227     value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
0228     value &= ~XGMAC_TSA;
0229     value |= XGMAC_CC | XGMAC_CBS;
0230     writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
0231 }
0232 
0233 static void dwxgmac2_dump_regs(struct mac_device_info *hw, u32 *reg_space)
0234 {
0235     void __iomem *ioaddr = hw->pcsr;
0236     int i;
0237 
0238     for (i = 0; i < XGMAC_MAC_REGSIZE; i++)
0239         reg_space[i] = readl(ioaddr + i * 4);
0240 }
0241 
0242 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
0243                     struct stmmac_extra_stats *x)
0244 {
0245     void __iomem *ioaddr = hw->pcsr;
0246     u32 stat, en;
0247     int ret = 0;
0248 
0249     en = readl(ioaddr + XGMAC_INT_EN);
0250     stat = readl(ioaddr + XGMAC_INT_STATUS);
0251 
0252     stat &= en;
0253 
0254     if (stat & XGMAC_PMTIS) {
0255         x->irq_receive_pmt_irq_n++;
0256         readl(ioaddr + XGMAC_PMT);
0257     }
0258 
0259     if (stat & XGMAC_LPIIS) {
0260         u32 lpi = readl(ioaddr + XGMAC_LPI_CTRL);
0261 
0262         if (lpi & XGMAC_TLPIEN) {
0263             ret |= CORE_IRQ_TX_PATH_IN_LPI_MODE;
0264             x->irq_tx_path_in_lpi_mode_n++;
0265         }
0266         if (lpi & XGMAC_TLPIEX) {
0267             ret |= CORE_IRQ_TX_PATH_EXIT_LPI_MODE;
0268             x->irq_tx_path_exit_lpi_mode_n++;
0269         }
0270         if (lpi & XGMAC_RLPIEN)
0271             x->irq_rx_path_in_lpi_mode_n++;
0272         if (lpi & XGMAC_RLPIEX)
0273             x->irq_rx_path_exit_lpi_mode_n++;
0274     }
0275 
0276     return ret;
0277 }
0278 
0279 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
0280 {
0281     void __iomem *ioaddr = hw->pcsr;
0282     int ret = 0;
0283     u32 status;
0284 
0285     status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
0286     if (status & BIT(chan)) {
0287         u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
0288 
0289         if (chan_status & XGMAC_RXOVFIS)
0290             ret |= CORE_IRQ_MTL_RX_OVERFLOW;
0291 
0292         writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
0293     }
0294 
0295     return ret;
0296 }
0297 
0298 static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
0299                    unsigned int fc, unsigned int pause_time,
0300                    u32 tx_cnt)
0301 {
0302     void __iomem *ioaddr = hw->pcsr;
0303     u32 i;
0304 
0305     if (fc & FLOW_RX)
0306         writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
0307     if (fc & FLOW_TX) {
0308         for (i = 0; i < tx_cnt; i++) {
0309             u32 value = XGMAC_TFE;
0310 
0311             if (duplex)
0312                 value |= pause_time << XGMAC_PT_SHIFT;
0313 
0314             writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
0315         }
0316     }
0317 }
0318 
0319 static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
0320 {
0321     void __iomem *ioaddr = hw->pcsr;
0322     u32 val = 0x0;
0323 
0324     if (mode & WAKE_MAGIC)
0325         val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
0326     if (mode & WAKE_UCAST)
0327         val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
0328     if (val) {
0329         u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
0330         cfg |= XGMAC_CONFIG_RE;
0331         writel(cfg, ioaddr + XGMAC_RX_CONFIG);
0332     }
0333 
0334     writel(val, ioaddr + XGMAC_PMT);
0335 }
0336 
0337 static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
0338                    const unsigned char *addr,
0339                    unsigned int reg_n)
0340 {
0341     void __iomem *ioaddr = hw->pcsr;
0342     u32 value;
0343 
0344     value = (addr[5] << 8) | addr[4];
0345     writel(value | XGMAC_AE, ioaddr + XGMAC_ADDRx_HIGH(reg_n));
0346 
0347     value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
0348     writel(value, ioaddr + XGMAC_ADDRx_LOW(reg_n));
0349 }
0350 
0351 static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
0352                    unsigned char *addr, unsigned int reg_n)
0353 {
0354     void __iomem *ioaddr = hw->pcsr;
0355     u32 hi_addr, lo_addr;
0356 
0357     /* Read the MAC address from the hardware */
0358     hi_addr = readl(ioaddr + XGMAC_ADDRx_HIGH(reg_n));
0359     lo_addr = readl(ioaddr + XGMAC_ADDRx_LOW(reg_n));
0360 
0361     /* Extract the MAC address from the high and low words */
0362     addr[0] = lo_addr & 0xff;
0363     addr[1] = (lo_addr >> 8) & 0xff;
0364     addr[2] = (lo_addr >> 16) & 0xff;
0365     addr[3] = (lo_addr >> 24) & 0xff;
0366     addr[4] = hi_addr & 0xff;
0367     addr[5] = (hi_addr >> 8) & 0xff;
0368 }
0369 
0370 static void dwxgmac2_set_eee_mode(struct mac_device_info *hw,
0371                   bool en_tx_lpi_clockgating)
0372 {
0373     void __iomem *ioaddr = hw->pcsr;
0374     u32 value;
0375 
0376     value = readl(ioaddr + XGMAC_LPI_CTRL);
0377 
0378     value |= XGMAC_LPITXEN | XGMAC_LPITXA;
0379     if (en_tx_lpi_clockgating)
0380         value |= XGMAC_TXCGE;
0381 
0382     writel(value, ioaddr + XGMAC_LPI_CTRL);
0383 }
0384 
0385 static void dwxgmac2_reset_eee_mode(struct mac_device_info *hw)
0386 {
0387     void __iomem *ioaddr = hw->pcsr;
0388     u32 value;
0389 
0390     value = readl(ioaddr + XGMAC_LPI_CTRL);
0391     value &= ~(XGMAC_LPITXEN | XGMAC_LPITXA | XGMAC_TXCGE);
0392     writel(value, ioaddr + XGMAC_LPI_CTRL);
0393 }
0394 
0395 static void dwxgmac2_set_eee_pls(struct mac_device_info *hw, int link)
0396 {
0397     void __iomem *ioaddr = hw->pcsr;
0398     u32 value;
0399 
0400     value = readl(ioaddr + XGMAC_LPI_CTRL);
0401     if (link)
0402         value |= XGMAC_PLS;
0403     else
0404         value &= ~XGMAC_PLS;
0405     writel(value, ioaddr + XGMAC_LPI_CTRL);
0406 }
0407 
0408 static void dwxgmac2_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
0409 {
0410     void __iomem *ioaddr = hw->pcsr;
0411     u32 value;
0412 
0413     value = (tw & 0xffff) | ((ls & 0x3ff) << 16);
0414     writel(value, ioaddr + XGMAC_LPI_TIMER_CTRL);
0415 }
0416 
0417 static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
0418                 int mcbitslog2)
0419 {
0420     int numhashregs, regs;
0421 
0422     switch (mcbitslog2) {
0423     case 6:
0424         numhashregs = 2;
0425         break;
0426     case 7:
0427         numhashregs = 4;
0428         break;
0429     case 8:
0430         numhashregs = 8;
0431         break;
0432     default:
0433         return;
0434     }
0435 
0436     for (regs = 0; regs < numhashregs; regs++)
0437         writel(mcfilterbits[regs], ioaddr + XGMAC_HASH_TABLE(regs));
0438 }
0439 
0440 static void dwxgmac2_set_filter(struct mac_device_info *hw,
0441                 struct net_device *dev)
0442 {
0443     void __iomem *ioaddr = (void __iomem *)dev->base_addr;
0444     u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
0445     int mcbitslog2 = hw->mcast_bits_log2;
0446     u32 mc_filter[8];
0447     int i;
0448 
0449     value &= ~(XGMAC_FILTER_PR | XGMAC_FILTER_HMC | XGMAC_FILTER_PM);
0450     value |= XGMAC_FILTER_HPF;
0451 
0452     memset(mc_filter, 0, sizeof(mc_filter));
0453 
0454     if (dev->flags & IFF_PROMISC) {
0455         value |= XGMAC_FILTER_PR;
0456         value |= XGMAC_FILTER_PCF;
0457     } else if ((dev->flags & IFF_ALLMULTI) ||
0458            (netdev_mc_count(dev) > hw->multicast_filter_bins)) {
0459         value |= XGMAC_FILTER_PM;
0460 
0461         for (i = 0; i < XGMAC_MAX_HASH_TABLE; i++)
0462             writel(~0x0, ioaddr + XGMAC_HASH_TABLE(i));
0463     } else if (!netdev_mc_empty(dev) && (dev->flags & IFF_MULTICAST)) {
0464         struct netdev_hw_addr *ha;
0465 
0466         value |= XGMAC_FILTER_HMC;
0467 
0468         netdev_for_each_mc_addr(ha, dev) {
0469             u32 nr = (bitrev32(~crc32_le(~0, ha->addr, 6)) >>
0470                     (32 - mcbitslog2));
0471             mc_filter[nr >> 5] |= (1 << (nr & 0x1F));
0472         }
0473     }
0474 
0475     dwxgmac2_set_mchash(ioaddr, mc_filter, mcbitslog2);
0476 
0477     /* Handle multiple unicast addresses */
0478     if (netdev_uc_count(dev) > hw->unicast_filter_entries) {
0479         value |= XGMAC_FILTER_PR;
0480     } else {
0481         struct netdev_hw_addr *ha;
0482         int reg = 1;
0483 
0484         netdev_for_each_uc_addr(ha, dev) {
0485             dwxgmac2_set_umac_addr(hw, ha->addr, reg);
0486             reg++;
0487         }
0488 
0489         for ( ; reg < XGMAC_ADDR_MAX; reg++) {
0490             writel(0, ioaddr + XGMAC_ADDRx_HIGH(reg));
0491             writel(0, ioaddr + XGMAC_ADDRx_LOW(reg));
0492         }
0493     }
0494 
0495     writel(value, ioaddr + XGMAC_PACKET_FILTER);
0496 }
0497 
0498 static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
0499 {
0500     u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
0501 
0502     if (enable)
0503         value |= XGMAC_CONFIG_LM;
0504     else
0505         value &= ~XGMAC_CONFIG_LM;
0506 
0507     writel(value, ioaddr + XGMAC_RX_CONFIG);
0508 }
0509 
0510 static int dwxgmac2_rss_write_reg(void __iomem *ioaddr, bool is_key, int idx,
0511                   u32 val)
0512 {
0513     u32 ctrl = 0;
0514 
0515     writel(val, ioaddr + XGMAC_RSS_DATA);
0516     ctrl |= idx << XGMAC_RSSIA_SHIFT;
0517     ctrl |= is_key ? XGMAC_ADDRT : 0x0;
0518     ctrl |= XGMAC_OB;
0519     writel(ctrl, ioaddr + XGMAC_RSS_ADDR);
0520 
0521     return readl_poll_timeout(ioaddr + XGMAC_RSS_ADDR, ctrl,
0522                   !(ctrl & XGMAC_OB), 100, 10000);
0523 }
0524 
0525 static int dwxgmac2_rss_configure(struct mac_device_info *hw,
0526                   struct stmmac_rss *cfg, u32 num_rxq)
0527 {
0528     void __iomem *ioaddr = hw->pcsr;
0529     u32 value, *key;
0530     int i, ret;
0531 
0532     value = readl(ioaddr + XGMAC_RSS_CTRL);
0533     if (!cfg || !cfg->enable) {
0534         value &= ~XGMAC_RSSE;
0535         writel(value, ioaddr + XGMAC_RSS_CTRL);
0536         return 0;
0537     }
0538 
0539     key = (u32 *)cfg->key;
0540     for (i = 0; i < (ARRAY_SIZE(cfg->key) / sizeof(u32)); i++) {
0541         ret = dwxgmac2_rss_write_reg(ioaddr, true, i, key[i]);
0542         if (ret)
0543             return ret;
0544     }
0545 
0546     for (i = 0; i < ARRAY_SIZE(cfg->table); i++) {
0547         ret = dwxgmac2_rss_write_reg(ioaddr, false, i, cfg->table[i]);
0548         if (ret)
0549             return ret;
0550     }
0551 
0552     for (i = 0; i < num_rxq; i++)
0553         dwxgmac2_map_mtl_to_dma(hw, i, XGMAC_QDDMACH);
0554 
0555     value |= XGMAC_UDP4TE | XGMAC_TCP4TE | XGMAC_IP2TE | XGMAC_RSSE;
0556     writel(value, ioaddr + XGMAC_RSS_CTRL);
0557     return 0;
0558 }
0559 
0560 static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash,
0561                       __le16 perfect_match, bool is_double)
0562 {
0563     void __iomem *ioaddr = hw->pcsr;
0564 
0565     writel(hash, ioaddr + XGMAC_VLAN_HASH_TABLE);
0566 
0567     if (hash) {
0568         u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
0569 
0570         value |= XGMAC_FILTER_VTFE;
0571 
0572         writel(value, ioaddr + XGMAC_PACKET_FILTER);
0573 
0574         value = readl(ioaddr + XGMAC_VLAN_TAG);
0575 
0576         value |= XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV;
0577         if (is_double) {
0578             value |= XGMAC_VLAN_EDVLP;
0579             value |= XGMAC_VLAN_ESVL;
0580             value |= XGMAC_VLAN_DOVLTC;
0581         } else {
0582             value &= ~XGMAC_VLAN_EDVLP;
0583             value &= ~XGMAC_VLAN_ESVL;
0584             value &= ~XGMAC_VLAN_DOVLTC;
0585         }
0586 
0587         value &= ~XGMAC_VLAN_VID;
0588         writel(value, ioaddr + XGMAC_VLAN_TAG);
0589     } else if (perfect_match) {
0590         u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
0591 
0592         value |= XGMAC_FILTER_VTFE;
0593 
0594         writel(value, ioaddr + XGMAC_PACKET_FILTER);
0595 
0596         value = readl(ioaddr + XGMAC_VLAN_TAG);
0597 
0598         value &= ~XGMAC_VLAN_VTHM;
0599         value |= XGMAC_VLAN_ETV;
0600         if (is_double) {
0601             value |= XGMAC_VLAN_EDVLP;
0602             value |= XGMAC_VLAN_ESVL;
0603             value |= XGMAC_VLAN_DOVLTC;
0604         } else {
0605             value &= ~XGMAC_VLAN_EDVLP;
0606             value &= ~XGMAC_VLAN_ESVL;
0607             value &= ~XGMAC_VLAN_DOVLTC;
0608         }
0609 
0610         value &= ~XGMAC_VLAN_VID;
0611         writel(value | perfect_match, ioaddr + XGMAC_VLAN_TAG);
0612     } else {
0613         u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
0614 
0615         value &= ~XGMAC_FILTER_VTFE;
0616 
0617         writel(value, ioaddr + XGMAC_PACKET_FILTER);
0618 
0619         value = readl(ioaddr + XGMAC_VLAN_TAG);
0620 
0621         value &= ~(XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV);
0622         value &= ~(XGMAC_VLAN_EDVLP | XGMAC_VLAN_ESVL);
0623         value &= ~XGMAC_VLAN_DOVLTC;
0624         value &= ~XGMAC_VLAN_VID;
0625 
0626         writel(value, ioaddr + XGMAC_VLAN_TAG);
0627     }
0628 }
0629 
0630 struct dwxgmac3_error_desc {
0631     bool valid;
0632     const char *desc;
0633     const char *detailed_desc;
0634 };
0635 
0636 #define STAT_OFF(field)     offsetof(struct stmmac_safety_stats, field)
0637 
0638 static void dwxgmac3_log_error(struct net_device *ndev, u32 value, bool corr,
0639                    const char *module_name,
0640                    const struct dwxgmac3_error_desc *desc,
0641                    unsigned long field_offset,
0642                    struct stmmac_safety_stats *stats)
0643 {
0644     unsigned long loc, mask;
0645     u8 *bptr = (u8 *)stats;
0646     unsigned long *ptr;
0647 
0648     ptr = (unsigned long *)(bptr + field_offset);
0649 
0650     mask = value;
0651     for_each_set_bit(loc, &mask, 32) {
0652         netdev_err(ndev, "Found %s error in %s: '%s: %s'\n", corr ?
0653                 "correctable" : "uncorrectable", module_name,
0654                 desc[loc].desc, desc[loc].detailed_desc);
0655 
0656         /* Update counters */
0657         ptr[loc]++;
0658     }
0659 }
0660 
0661 static const struct dwxgmac3_error_desc dwxgmac3_mac_errors[32]= {
0662     { true, "ATPES", "Application Transmit Interface Parity Check Error" },
0663     { true, "DPES", "Descriptor Cache Data Path Parity Check Error" },
0664     { true, "TPES", "TSO Data Path Parity Check Error" },
0665     { true, "TSOPES", "TSO Header Data Path Parity Check Error" },
0666     { true, "MTPES", "MTL Data Path Parity Check Error" },
0667     { true, "MTSPES", "MTL TX Status Data Path Parity Check Error" },
0668     { true, "MTBUPES", "MAC TBU Data Path Parity Check Error" },
0669     { true, "MTFCPES", "MAC TFC Data Path Parity Check Error" },
0670     { true, "ARPES", "Application Receive Interface Data Path Parity Check Error" },
0671     { true, "MRWCPES", "MTL RWC Data Path Parity Check Error" },
0672     { true, "MRRCPES", "MTL RCC Data Path Parity Check Error" },
0673     { true, "CWPES", "CSR Write Data Path Parity Check Error" },
0674     { true, "ASRPES", "AXI Slave Read Data Path Parity Check Error" },
0675     { true, "TTES", "TX FSM Timeout Error" },
0676     { true, "RTES", "RX FSM Timeout Error" },
0677     { true, "CTES", "CSR FSM Timeout Error" },
0678     { true, "ATES", "APP FSM Timeout Error" },
0679     { true, "PTES", "PTP FSM Timeout Error" },
0680     { false, "UNKNOWN", "Unknown Error" }, /* 18 */
0681     { false, "UNKNOWN", "Unknown Error" }, /* 19 */
0682     { false, "UNKNOWN", "Unknown Error" }, /* 20 */
0683     { true, "MSTTES", "Master Read/Write Timeout Error" },
0684     { true, "SLVTES", "Slave Read/Write Timeout Error" },
0685     { true, "ATITES", "Application Timeout on ATI Interface Error" },
0686     { true, "ARITES", "Application Timeout on ARI Interface Error" },
0687     { true, "FSMPES", "FSM State Parity Error" },
0688     { false, "UNKNOWN", "Unknown Error" }, /* 26 */
0689     { false, "UNKNOWN", "Unknown Error" }, /* 27 */
0690     { false, "UNKNOWN", "Unknown Error" }, /* 28 */
0691     { false, "UNKNOWN", "Unknown Error" }, /* 29 */
0692     { false, "UNKNOWN", "Unknown Error" }, /* 30 */
0693     { true, "CPI", "Control Register Parity Check Error" },
0694 };
0695 
0696 static void dwxgmac3_handle_mac_err(struct net_device *ndev,
0697                     void __iomem *ioaddr, bool correctable,
0698                     struct stmmac_safety_stats *stats)
0699 {
0700     u32 value;
0701 
0702     value = readl(ioaddr + XGMAC_MAC_DPP_FSM_INT_STATUS);
0703     writel(value, ioaddr + XGMAC_MAC_DPP_FSM_INT_STATUS);
0704 
0705     dwxgmac3_log_error(ndev, value, correctable, "MAC",
0706                dwxgmac3_mac_errors, STAT_OFF(mac_errors), stats);
0707 }
0708 
0709 static const struct dwxgmac3_error_desc dwxgmac3_mtl_errors[32]= {
0710     { true, "TXCES", "MTL TX Memory Error" },
0711     { true, "TXAMS", "MTL TX Memory Address Mismatch Error" },
0712     { true, "TXUES", "MTL TX Memory Error" },
0713     { false, "UNKNOWN", "Unknown Error" }, /* 3 */
0714     { true, "RXCES", "MTL RX Memory Error" },
0715     { true, "RXAMS", "MTL RX Memory Address Mismatch Error" },
0716     { true, "RXUES", "MTL RX Memory Error" },
0717     { false, "UNKNOWN", "Unknown Error" }, /* 7 */
0718     { true, "ECES", "MTL EST Memory Error" },
0719     { true, "EAMS", "MTL EST Memory Address Mismatch Error" },
0720     { true, "EUES", "MTL EST Memory Error" },
0721     { false, "UNKNOWN", "Unknown Error" }, /* 11 */
0722     { true, "RPCES", "MTL RX Parser Memory Error" },
0723     { true, "RPAMS", "MTL RX Parser Memory Address Mismatch Error" },
0724     { true, "RPUES", "MTL RX Parser Memory Error" },
0725     { false, "UNKNOWN", "Unknown Error" }, /* 15 */
0726     { false, "UNKNOWN", "Unknown Error" }, /* 16 */
0727     { false, "UNKNOWN", "Unknown Error" }, /* 17 */
0728     { false, "UNKNOWN", "Unknown Error" }, /* 18 */
0729     { false, "UNKNOWN", "Unknown Error" }, /* 19 */
0730     { false, "UNKNOWN", "Unknown Error" }, /* 20 */
0731     { false, "UNKNOWN", "Unknown Error" }, /* 21 */
0732     { false, "UNKNOWN", "Unknown Error" }, /* 22 */
0733     { false, "UNKNOWN", "Unknown Error" }, /* 23 */
0734     { false, "UNKNOWN", "Unknown Error" }, /* 24 */
0735     { false, "UNKNOWN", "Unknown Error" }, /* 25 */
0736     { false, "UNKNOWN", "Unknown Error" }, /* 26 */
0737     { false, "UNKNOWN", "Unknown Error" }, /* 27 */
0738     { false, "UNKNOWN", "Unknown Error" }, /* 28 */
0739     { false, "UNKNOWN", "Unknown Error" }, /* 29 */
0740     { false, "UNKNOWN", "Unknown Error" }, /* 30 */
0741     { false, "UNKNOWN", "Unknown Error" }, /* 31 */
0742 };
0743 
0744 static void dwxgmac3_handle_mtl_err(struct net_device *ndev,
0745                     void __iomem *ioaddr, bool correctable,
0746                     struct stmmac_safety_stats *stats)
0747 {
0748     u32 value;
0749 
0750     value = readl(ioaddr + XGMAC_MTL_ECC_INT_STATUS);
0751     writel(value, ioaddr + XGMAC_MTL_ECC_INT_STATUS);
0752 
0753     dwxgmac3_log_error(ndev, value, correctable, "MTL",
0754                dwxgmac3_mtl_errors, STAT_OFF(mtl_errors), stats);
0755 }
0756 
0757 static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
0758     { true, "TCES", "DMA TSO Memory Error" },
0759     { true, "TAMS", "DMA TSO Memory Address Mismatch Error" },
0760     { true, "TUES", "DMA TSO Memory Error" },
0761     { false, "UNKNOWN", "Unknown Error" }, /* 3 */
0762     { true, "DCES", "DMA DCACHE Memory Error" },
0763     { true, "DAMS", "DMA DCACHE Address Mismatch Error" },
0764     { true, "DUES", "DMA DCACHE Memory Error" },
0765     { false, "UNKNOWN", "Unknown Error" }, /* 7 */
0766     { false, "UNKNOWN", "Unknown Error" }, /* 8 */
0767     { false, "UNKNOWN", "Unknown Error" }, /* 9 */
0768     { false, "UNKNOWN", "Unknown Error" }, /* 10 */
0769     { false, "UNKNOWN", "Unknown Error" }, /* 11 */
0770     { false, "UNKNOWN", "Unknown Error" }, /* 12 */
0771     { false, "UNKNOWN", "Unknown Error" }, /* 13 */
0772     { false, "UNKNOWN", "Unknown Error" }, /* 14 */
0773     { false, "UNKNOWN", "Unknown Error" }, /* 15 */
0774     { false, "UNKNOWN", "Unknown Error" }, /* 16 */
0775     { false, "UNKNOWN", "Unknown Error" }, /* 17 */
0776     { false, "UNKNOWN", "Unknown Error" }, /* 18 */
0777     { false, "UNKNOWN", "Unknown Error" }, /* 19 */
0778     { false, "UNKNOWN", "Unknown Error" }, /* 20 */
0779     { false, "UNKNOWN", "Unknown Error" }, /* 21 */
0780     { false, "UNKNOWN", "Unknown Error" }, /* 22 */
0781     { false, "UNKNOWN", "Unknown Error" }, /* 23 */
0782     { false, "UNKNOWN", "Unknown Error" }, /* 24 */
0783     { false, "UNKNOWN", "Unknown Error" }, /* 25 */
0784     { false, "UNKNOWN", "Unknown Error" }, /* 26 */
0785     { false, "UNKNOWN", "Unknown Error" }, /* 27 */
0786     { false, "UNKNOWN", "Unknown Error" }, /* 28 */
0787     { false, "UNKNOWN", "Unknown Error" }, /* 29 */
0788     { false, "UNKNOWN", "Unknown Error" }, /* 30 */
0789     { false, "UNKNOWN", "Unknown Error" }, /* 31 */
0790 };
0791 
0792 static void dwxgmac3_handle_dma_err(struct net_device *ndev,
0793                     void __iomem *ioaddr, bool correctable,
0794                     struct stmmac_safety_stats *stats)
0795 {
0796     u32 value;
0797 
0798     value = readl(ioaddr + XGMAC_DMA_ECC_INT_STATUS);
0799     writel(value, ioaddr + XGMAC_DMA_ECC_INT_STATUS);
0800 
0801     dwxgmac3_log_error(ndev, value, correctable, "DMA",
0802                dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
0803 }
0804 
0805 static int
0806 dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
0807                 struct stmmac_safety_feature_cfg *safety_cfg)
0808 {
0809     u32 value;
0810 
0811     if (!asp)
0812         return -EINVAL;
0813 
0814     /* 1. Enable Safety Features */
0815     writel(0x0, ioaddr + XGMAC_MTL_ECC_CONTROL);
0816 
0817     /* 2. Enable MTL Safety Interrupts */
0818     value = readl(ioaddr + XGMAC_MTL_ECC_INT_ENABLE);
0819     value |= XGMAC_RPCEIE; /* RX Parser Memory Correctable Error */
0820     value |= XGMAC_ECEIE; /* EST Memory Correctable Error */
0821     value |= XGMAC_RXCEIE; /* RX Memory Correctable Error */
0822     value |= XGMAC_TXCEIE; /* TX Memory Correctable Error */
0823     writel(value, ioaddr + XGMAC_MTL_ECC_INT_ENABLE);
0824 
0825     /* 3. Enable DMA Safety Interrupts */
0826     value = readl(ioaddr + XGMAC_DMA_ECC_INT_ENABLE);
0827     value |= XGMAC_DCEIE; /* Descriptor Cache Memory Correctable Error */
0828     value |= XGMAC_TCEIE; /* TSO Memory Correctable Error */
0829     writel(value, ioaddr + XGMAC_DMA_ECC_INT_ENABLE);
0830 
0831     /* Only ECC Protection for External Memory feature is selected */
0832     if (asp <= 0x1)
0833         return 0;
0834 
0835     /* 4. Enable Parity and Timeout for FSM */
0836     value = readl(ioaddr + XGMAC_MAC_FSM_CONTROL);
0837     value |= XGMAC_PRTYEN; /* FSM Parity Feature */
0838     value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
0839     writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
0840 
0841     return 0;
0842 }
0843 
0844 static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
0845                        void __iomem *ioaddr,
0846                        unsigned int asp,
0847                        struct stmmac_safety_stats *stats)
0848 {
0849     bool err, corr;
0850     u32 mtl, dma;
0851     int ret = 0;
0852 
0853     if (!asp)
0854         return -EINVAL;
0855 
0856     mtl = readl(ioaddr + XGMAC_MTL_SAFETY_INT_STATUS);
0857     dma = readl(ioaddr + XGMAC_DMA_SAFETY_INT_STATUS);
0858 
0859     err = (mtl & XGMAC_MCSIS) || (dma & XGMAC_MCSIS);
0860     corr = false;
0861     if (err) {
0862         dwxgmac3_handle_mac_err(ndev, ioaddr, corr, stats);
0863         ret |= !corr;
0864     }
0865 
0866     err = (mtl & (XGMAC_MEUIS | XGMAC_MECIS)) ||
0867           (dma & (XGMAC_MSUIS | XGMAC_MSCIS));
0868     corr = (mtl & XGMAC_MECIS) || (dma & XGMAC_MSCIS);
0869     if (err) {
0870         dwxgmac3_handle_mtl_err(ndev, ioaddr, corr, stats);
0871         ret |= !corr;
0872     }
0873 
0874     err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
0875     corr = dma & XGMAC_DECIS;
0876     if (err) {
0877         dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
0878         ret |= !corr;
0879     }
0880 
0881     return ret;
0882 }
0883 
0884 static const struct dwxgmac3_error {
0885     const struct dwxgmac3_error_desc *desc;
0886 } dwxgmac3_all_errors[] = {
0887     { dwxgmac3_mac_errors },
0888     { dwxgmac3_mtl_errors },
0889     { dwxgmac3_dma_errors },
0890 };
0891 
0892 static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
0893                      int index, unsigned long *count,
0894                      const char **desc)
0895 {
0896     int module = index / 32, offset = index % 32;
0897     unsigned long *ptr = (unsigned long *)stats;
0898 
0899     if (module >= ARRAY_SIZE(dwxgmac3_all_errors))
0900         return -EINVAL;
0901     if (!dwxgmac3_all_errors[module].desc[offset].valid)
0902         return -EINVAL;
0903     if (count)
0904         *count = *(ptr + index);
0905     if (desc)
0906         *desc = dwxgmac3_all_errors[module].desc[offset].desc;
0907     return 0;
0908 }
0909 
0910 static int dwxgmac3_rxp_disable(void __iomem *ioaddr)
0911 {
0912     u32 val = readl(ioaddr + XGMAC_MTL_OPMODE);
0913 
0914     val &= ~XGMAC_FRPE;
0915     writel(val, ioaddr + XGMAC_MTL_OPMODE);
0916 
0917     return 0;
0918 }
0919 
0920 static void dwxgmac3_rxp_enable(void __iomem *ioaddr)
0921 {
0922     u32 val;
0923 
0924     val = readl(ioaddr + XGMAC_MTL_OPMODE);
0925     val |= XGMAC_FRPE;
0926     writel(val, ioaddr + XGMAC_MTL_OPMODE);
0927 }
0928 
0929 static int dwxgmac3_rxp_update_single_entry(void __iomem *ioaddr,
0930                         struct stmmac_tc_entry *entry,
0931                         int pos)
0932 {
0933     int ret, i;
0934 
0935     for (i = 0; i < (sizeof(entry->val) / sizeof(u32)); i++) {
0936         int real_pos = pos * (sizeof(entry->val) / sizeof(u32)) + i;
0937         u32 val;
0938 
0939         /* Wait for ready */
0940         ret = readl_poll_timeout(ioaddr + XGMAC_MTL_RXP_IACC_CTRL_ST,
0941                      val, !(val & XGMAC_STARTBUSY), 1, 10000);
0942         if (ret)
0943             return ret;
0944 
0945         /* Write data */
0946         val = *((u32 *)&entry->val + i);
0947         writel(val, ioaddr + XGMAC_MTL_RXP_IACC_DATA);
0948 
0949         /* Write pos */
0950         val = real_pos & XGMAC_ADDR;
0951         writel(val, ioaddr + XGMAC_MTL_RXP_IACC_CTRL_ST);
0952 
0953         /* Write OP */
0954         val |= XGMAC_WRRDN;
0955         writel(val, ioaddr + XGMAC_MTL_RXP_IACC_CTRL_ST);
0956 
0957         /* Start Write */
0958         val |= XGMAC_STARTBUSY;
0959         writel(val, ioaddr + XGMAC_MTL_RXP_IACC_CTRL_ST);
0960 
0961         /* Wait for done */
0962         ret = readl_poll_timeout(ioaddr + XGMAC_MTL_RXP_IACC_CTRL_ST,
0963                      val, !(val & XGMAC_STARTBUSY), 1, 10000);
0964         if (ret)
0965             return ret;
0966     }
0967 
0968     return 0;
0969 }
0970 
0971 static struct stmmac_tc_entry *
0972 dwxgmac3_rxp_get_next_entry(struct stmmac_tc_entry *entries,
0973                 unsigned int count, u32 curr_prio)
0974 {
0975     struct stmmac_tc_entry *entry;
0976     u32 min_prio = ~0x0;
0977     int i, min_prio_idx;
0978     bool found = false;
0979 
0980     for (i = count - 1; i >= 0; i--) {
0981         entry = &entries[i];
0982 
0983         /* Do not update unused entries */
0984         if (!entry->in_use)
0985             continue;
0986         /* Do not update already updated entries (i.e. fragments) */
0987         if (entry->in_hw)
0988             continue;
0989         /* Let last entry be updated last */
0990         if (entry->is_last)
0991             continue;
0992         /* Do not return fragments */
0993         if (entry->is_frag)
0994             continue;
0995         /* Check if we already checked this prio */
0996         if (entry->prio < curr_prio)
0997             continue;
0998         /* Check if this is the minimum prio */
0999         if (entry->prio < min_prio) {
1000             min_prio = entry->prio;
1001             min_prio_idx = i;
1002             found = true;
1003         }
1004     }
1005 
1006     if (found)
1007         return &entries[min_prio_idx];
1008     return NULL;
1009 }
1010 
1011 static int dwxgmac3_rxp_config(void __iomem *ioaddr,
1012                    struct stmmac_tc_entry *entries,
1013                    unsigned int count)
1014 {
1015     struct stmmac_tc_entry *entry, *frag;
1016     int i, ret, nve = 0;
1017     u32 curr_prio = 0;
1018     u32 old_val, val;
1019 
1020     /* Force disable RX */
1021     old_val = readl(ioaddr + XGMAC_RX_CONFIG);
1022     val = old_val & ~XGMAC_CONFIG_RE;
1023     writel(val, ioaddr + XGMAC_RX_CONFIG);
1024 
1025     /* Disable RX Parser */
1026     ret = dwxgmac3_rxp_disable(ioaddr);
1027     if (ret)
1028         goto re_enable;
1029 
1030     /* Set all entries as NOT in HW */
1031     for (i = 0; i < count; i++) {
1032         entry = &entries[i];
1033         entry->in_hw = false;
1034     }
1035 
1036     /* Update entries by reverse order */
1037     while (1) {
1038         entry = dwxgmac3_rxp_get_next_entry(entries, count, curr_prio);
1039         if (!entry)
1040             break;
1041 
1042         curr_prio = entry->prio;
1043         frag = entry->frag_ptr;
1044 
1045         /* Set special fragment requirements */
1046         if (frag) {
1047             entry->val.af = 0;
1048             entry->val.rf = 0;
1049             entry->val.nc = 1;
1050             entry->val.ok_index = nve + 2;
1051         }
1052 
1053         ret = dwxgmac3_rxp_update_single_entry(ioaddr, entry, nve);
1054         if (ret)
1055             goto re_enable;
1056 
1057         entry->table_pos = nve++;
1058         entry->in_hw = true;
1059 
1060         if (frag && !frag->in_hw) {
1061             ret = dwxgmac3_rxp_update_single_entry(ioaddr, frag, nve);
1062             if (ret)
1063                 goto re_enable;
1064             frag->table_pos = nve++;
1065             frag->in_hw = true;
1066         }
1067     }
1068 
1069     if (!nve)
1070         goto re_enable;
1071 
1072     /* Update all pass entry */
1073     for (i = 0; i < count; i++) {
1074         entry = &entries[i];
1075         if (!entry->is_last)
1076             continue;
1077 
1078         ret = dwxgmac3_rxp_update_single_entry(ioaddr, entry, nve);
1079         if (ret)
1080             goto re_enable;
1081 
1082         entry->table_pos = nve++;
1083     }
1084 
1085     /* Assume n. of parsable entries == n. of valid entries */
1086     val = (nve << 16) & XGMAC_NPE;
1087     val |= nve & XGMAC_NVE;
1088     writel(val, ioaddr + XGMAC_MTL_RXP_CONTROL_STATUS);
1089 
1090     /* Enable RX Parser */
1091     dwxgmac3_rxp_enable(ioaddr);
1092 
1093 re_enable:
1094     /* Re-enable RX */
1095     writel(old_val, ioaddr + XGMAC_RX_CONFIG);
1096     return ret;
1097 }
1098 
1099 static int dwxgmac2_get_mac_tx_timestamp(struct mac_device_info *hw, u64 *ts)
1100 {
1101     void __iomem *ioaddr = hw->pcsr;
1102     u32 value;
1103 
1104     if (readl_poll_timeout_atomic(ioaddr + XGMAC_TIMESTAMP_STATUS,
1105                       value, value & XGMAC_TXTSC, 100, 10000))
1106         return -EBUSY;
1107 
1108     *ts = readl(ioaddr + XGMAC_TXTIMESTAMP_NSEC) & XGMAC_TXTSSTSLO;
1109     *ts += readl(ioaddr + XGMAC_TXTIMESTAMP_SEC) * 1000000000ULL;
1110     return 0;
1111 }
1112 
1113 static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index,
1114                     struct stmmac_pps_cfg *cfg, bool enable,
1115                     u32 sub_second_inc, u32 systime_flags)
1116 {
1117     u32 tnsec = readl(ioaddr + XGMAC_PPSx_TARGET_TIME_NSEC(index));
1118     u32 val = readl(ioaddr + XGMAC_PPS_CONTROL);
1119     u64 period;
1120 
1121     if (!cfg->available)
1122         return -EINVAL;
1123     if (tnsec & XGMAC_TRGTBUSY0)
1124         return -EBUSY;
1125     if (!sub_second_inc || !systime_flags)
1126         return -EINVAL;
1127 
1128     val &= ~XGMAC_PPSx_MASK(index);
1129 
1130     if (!enable) {
1131         val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_STOP);
1132         writel(val, ioaddr + XGMAC_PPS_CONTROL);
1133         return 0;
1134     }
1135 
1136     val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_START);
1137     val |= XGMAC_TRGTMODSELx(index, XGMAC_PPSCMD_START);
1138     val |= XGMAC_PPSEN0;
1139 
1140     writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(index));
1141 
1142     if (!(systime_flags & PTP_TCR_TSCTRLSSR))
1143         cfg->start.tv_nsec = (cfg->start.tv_nsec * 1000) / 465;
1144     writel(cfg->start.tv_nsec, ioaddr + XGMAC_PPSx_TARGET_TIME_NSEC(index));
1145 
1146     period = cfg->period.tv_sec * 1000000000;
1147     period += cfg->period.tv_nsec;
1148 
1149     do_div(period, sub_second_inc);
1150 
1151     if (period <= 1)
1152         return -EINVAL;
1153 
1154     writel(period - 1, ioaddr + XGMAC_PPSx_INTERVAL(index));
1155 
1156     period >>= 1;
1157     if (period <= 1)
1158         return -EINVAL;
1159 
1160     writel(period - 1, ioaddr + XGMAC_PPSx_WIDTH(index));
1161 
1162     /* Finally, activate it */
1163     writel(val, ioaddr + XGMAC_PPS_CONTROL);
1164     return 0;
1165 }
1166 
1167 static void dwxgmac2_sarc_configure(void __iomem *ioaddr, int val)
1168 {
1169     u32 value = readl(ioaddr + XGMAC_TX_CONFIG);
1170 
1171     value &= ~XGMAC_CONFIG_SARC;
1172     value |= val << XGMAC_CONFIG_SARC_SHIFT;
1173 
1174     writel(value, ioaddr + XGMAC_TX_CONFIG);
1175 }
1176 
1177 static void dwxgmac2_enable_vlan(struct mac_device_info *hw, u32 type)
1178 {
1179     void __iomem *ioaddr = hw->pcsr;
1180     u32 value;
1181 
1182     value = readl(ioaddr + XGMAC_VLAN_INCL);
1183     value |= XGMAC_VLAN_VLTI;
1184     value |= XGMAC_VLAN_CSVL; /* Only use SVLAN */
1185     value &= ~XGMAC_VLAN_VLC;
1186     value |= (type << XGMAC_VLAN_VLC_SHIFT) & XGMAC_VLAN_VLC;
1187     writel(value, ioaddr + XGMAC_VLAN_INCL);
1188 }
1189 
1190 static int dwxgmac2_filter_wait(struct mac_device_info *hw)
1191 {
1192     void __iomem *ioaddr = hw->pcsr;
1193     u32 value;
1194 
1195     if (readl_poll_timeout(ioaddr + XGMAC_L3L4_ADDR_CTRL, value,
1196                    !(value & XGMAC_XB), 100, 10000))
1197         return -EBUSY;
1198     return 0;
1199 }
1200 
1201 static int dwxgmac2_filter_read(struct mac_device_info *hw, u32 filter_no,
1202                 u8 reg, u32 *data)
1203 {
1204     void __iomem *ioaddr = hw->pcsr;
1205     u32 value;
1206     int ret;
1207 
1208     ret = dwxgmac2_filter_wait(hw);
1209     if (ret)
1210         return ret;
1211 
1212     value = ((filter_no << XGMAC_IDDR_FNUM) | reg) << XGMAC_IDDR_SHIFT;
1213     value |= XGMAC_TT | XGMAC_XB;
1214     writel(value, ioaddr + XGMAC_L3L4_ADDR_CTRL);
1215 
1216     ret = dwxgmac2_filter_wait(hw);
1217     if (ret)
1218         return ret;
1219 
1220     *data = readl(ioaddr + XGMAC_L3L4_DATA);
1221     return 0;
1222 }
1223 
1224 static int dwxgmac2_filter_write(struct mac_device_info *hw, u32 filter_no,
1225                  u8 reg, u32 data)
1226 {
1227     void __iomem *ioaddr = hw->pcsr;
1228     u32 value;
1229     int ret;
1230 
1231     ret = dwxgmac2_filter_wait(hw);
1232     if (ret)
1233         return ret;
1234 
1235     writel(data, ioaddr + XGMAC_L3L4_DATA);
1236 
1237     value = ((filter_no << XGMAC_IDDR_FNUM) | reg) << XGMAC_IDDR_SHIFT;
1238     value |= XGMAC_XB;
1239     writel(value, ioaddr + XGMAC_L3L4_ADDR_CTRL);
1240 
1241     return dwxgmac2_filter_wait(hw);
1242 }
1243 
1244 static int dwxgmac2_config_l3_filter(struct mac_device_info *hw, u32 filter_no,
1245                      bool en, bool ipv6, bool sa, bool inv,
1246                      u32 match)
1247 {
1248     void __iomem *ioaddr = hw->pcsr;
1249     u32 value;
1250     int ret;
1251 
1252     value = readl(ioaddr + XGMAC_PACKET_FILTER);
1253     value |= XGMAC_FILTER_IPFE;
1254     writel(value, ioaddr + XGMAC_PACKET_FILTER);
1255 
1256     ret = dwxgmac2_filter_read(hw, filter_no, XGMAC_L3L4_CTRL, &value);
1257     if (ret)
1258         return ret;
1259 
1260     /* For IPv6 not both SA/DA filters can be active */
1261     if (ipv6) {
1262         value |= XGMAC_L3PEN0;
1263         value &= ~(XGMAC_L3SAM0 | XGMAC_L3SAIM0);
1264         value &= ~(XGMAC_L3DAM0 | XGMAC_L3DAIM0);
1265         if (sa) {
1266             value |= XGMAC_L3SAM0;
1267             if (inv)
1268                 value |= XGMAC_L3SAIM0;
1269         } else {
1270             value |= XGMAC_L3DAM0;
1271             if (inv)
1272                 value |= XGMAC_L3DAIM0;
1273         }
1274     } else {
1275         value &= ~XGMAC_L3PEN0;
1276         if (sa) {
1277             value |= XGMAC_L3SAM0;
1278             if (inv)
1279                 value |= XGMAC_L3SAIM0;
1280         } else {
1281             value |= XGMAC_L3DAM0;
1282             if (inv)
1283                 value |= XGMAC_L3DAIM0;
1284         }
1285     }
1286 
1287     ret = dwxgmac2_filter_write(hw, filter_no, XGMAC_L3L4_CTRL, value);
1288     if (ret)
1289         return ret;
1290 
1291     if (sa) {
1292         ret = dwxgmac2_filter_write(hw, filter_no, XGMAC_L3_ADDR0, match);
1293         if (ret)
1294             return ret;
1295     } else {
1296         ret = dwxgmac2_filter_write(hw, filter_no, XGMAC_L3_ADDR1, match);
1297         if (ret)
1298             return ret;
1299     }
1300 
1301     if (!en)
1302         return dwxgmac2_filter_write(hw, filter_no, XGMAC_L3L4_CTRL, 0);
1303 
1304     return 0;
1305 }
1306 
1307 static int dwxgmac2_config_l4_filter(struct mac_device_info *hw, u32 filter_no,
1308                      bool en, bool udp, bool sa, bool inv,
1309                      u32 match)
1310 {
1311     void __iomem *ioaddr = hw->pcsr;
1312     u32 value;
1313     int ret;
1314 
1315     value = readl(ioaddr + XGMAC_PACKET_FILTER);
1316     value |= XGMAC_FILTER_IPFE;
1317     writel(value, ioaddr + XGMAC_PACKET_FILTER);
1318 
1319     ret = dwxgmac2_filter_read(hw, filter_no, XGMAC_L3L4_CTRL, &value);
1320     if (ret)
1321         return ret;
1322 
1323     if (udp) {
1324         value |= XGMAC_L4PEN0;
1325     } else {
1326         value &= ~XGMAC_L4PEN0;
1327     }
1328 
1329     value &= ~(XGMAC_L4SPM0 | XGMAC_L4SPIM0);
1330     value &= ~(XGMAC_L4DPM0 | XGMAC_L4DPIM0);
1331     if (sa) {
1332         value |= XGMAC_L4SPM0;
1333         if (inv)
1334             value |= XGMAC_L4SPIM0;
1335     } else {
1336         value |= XGMAC_L4DPM0;
1337         if (inv)
1338             value |= XGMAC_L4DPIM0;
1339     }
1340 
1341     ret = dwxgmac2_filter_write(hw, filter_no, XGMAC_L3L4_CTRL, value);
1342     if (ret)
1343         return ret;
1344 
1345     if (sa) {
1346         value = match & XGMAC_L4SP0;
1347 
1348         ret = dwxgmac2_filter_write(hw, filter_no, XGMAC_L4_ADDR, value);
1349         if (ret)
1350             return ret;
1351     } else {
1352         value = (match << XGMAC_L4DP0_SHIFT) & XGMAC_L4DP0;
1353 
1354         ret = dwxgmac2_filter_write(hw, filter_no, XGMAC_L4_ADDR, value);
1355         if (ret)
1356             return ret;
1357     }
1358 
1359     if (!en)
1360         return dwxgmac2_filter_write(hw, filter_no, XGMAC_L3L4_CTRL, 0);
1361 
1362     return 0;
1363 }
1364 
1365 static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,
1366                      u32 addr)
1367 {
1368     void __iomem *ioaddr = hw->pcsr;
1369     u32 value;
1370 
1371     writel(addr, ioaddr + XGMAC_ARP_ADDR);
1372 
1373     value = readl(ioaddr + XGMAC_RX_CONFIG);
1374     if (en)
1375         value |= XGMAC_CONFIG_ARPEN;
1376     else
1377         value &= ~XGMAC_CONFIG_ARPEN;
1378     writel(value, ioaddr + XGMAC_RX_CONFIG);
1379 }
1380 
1381 static int dwxgmac3_est_write(void __iomem *ioaddr, u32 reg, u32 val, bool gcl)
1382 {
1383     u32 ctrl;
1384 
1385     writel(val, ioaddr + XGMAC_MTL_EST_GCL_DATA);
1386 
1387     ctrl = (reg << XGMAC_ADDR_SHIFT);
1388     ctrl |= gcl ? 0 : XGMAC_GCRR;
1389 
1390     writel(ctrl, ioaddr + XGMAC_MTL_EST_GCL_CONTROL);
1391 
1392     ctrl |= XGMAC_SRWO;
1393     writel(ctrl, ioaddr + XGMAC_MTL_EST_GCL_CONTROL);
1394 
1395     return readl_poll_timeout_atomic(ioaddr + XGMAC_MTL_EST_GCL_CONTROL,
1396                      ctrl, !(ctrl & XGMAC_SRWO), 100, 5000);
1397 }
1398 
1399 static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
1400                   unsigned int ptp_rate)
1401 {
1402     int i, ret = 0x0;
1403     u32 ctrl;
1404 
1405     ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_LOW, cfg->btr[0], false);
1406     ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_HIGH, cfg->btr[1], false);
1407     ret |= dwxgmac3_est_write(ioaddr, XGMAC_TER, cfg->ter, false);
1408     ret |= dwxgmac3_est_write(ioaddr, XGMAC_LLR, cfg->gcl_size, false);
1409     ret |= dwxgmac3_est_write(ioaddr, XGMAC_CTR_LOW, cfg->ctr[0], false);
1410     ret |= dwxgmac3_est_write(ioaddr, XGMAC_CTR_HIGH, cfg->ctr[1], false);
1411     if (ret)
1412         return ret;
1413 
1414     for (i = 0; i < cfg->gcl_size; i++) {
1415         ret = dwxgmac3_est_write(ioaddr, i, cfg->gcl[i], true);
1416         if (ret)
1417             return ret;
1418     }
1419 
1420     ctrl = readl(ioaddr + XGMAC_MTL_EST_CONTROL);
1421     ctrl &= ~XGMAC_PTOV;
1422     ctrl |= ((1000000000 / ptp_rate) * 9) << XGMAC_PTOV_SHIFT;
1423     if (cfg->enable)
1424         ctrl |= XGMAC_EEST | XGMAC_SSWL;
1425     else
1426         ctrl &= ~XGMAC_EEST;
1427 
1428     writel(ctrl, ioaddr + XGMAC_MTL_EST_CONTROL);
1429     return 0;
1430 }
1431 
1432 static void dwxgmac3_fpe_configure(void __iomem *ioaddr, u32 num_txq,
1433                    u32 num_rxq, bool enable)
1434 {
1435     u32 value;
1436 
1437     if (!enable) {
1438         value = readl(ioaddr + XGMAC_FPE_CTRL_STS);
1439 
1440         value &= ~XGMAC_EFPE;
1441 
1442         writel(value, ioaddr + XGMAC_FPE_CTRL_STS);
1443         return;
1444     }
1445 
1446     value = readl(ioaddr + XGMAC_RXQ_CTRL1);
1447     value &= ~XGMAC_RQ;
1448     value |= (num_rxq - 1) << XGMAC_RQ_SHIFT;
1449     writel(value, ioaddr + XGMAC_RXQ_CTRL1);
1450 
1451     value = readl(ioaddr + XGMAC_FPE_CTRL_STS);
1452     value |= XGMAC_EFPE;
1453     writel(value, ioaddr + XGMAC_FPE_CTRL_STS);
1454 }
1455 
1456 const struct stmmac_ops dwxgmac210_ops = {
1457     .core_init = dwxgmac2_core_init,
1458     .set_mac = dwxgmac2_set_mac,
1459     .rx_ipc = dwxgmac2_rx_ipc,
1460     .rx_queue_enable = dwxgmac2_rx_queue_enable,
1461     .rx_queue_prio = dwxgmac2_rx_queue_prio,
1462     .tx_queue_prio = dwxgmac2_tx_queue_prio,
1463     .rx_queue_routing = NULL,
1464     .prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
1465     .prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
1466     .set_mtl_tx_queue_weight = dwxgmac2_set_mtl_tx_queue_weight,
1467     .map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
1468     .config_cbs = dwxgmac2_config_cbs,
1469     .dump_regs = dwxgmac2_dump_regs,
1470     .host_irq_status = dwxgmac2_host_irq_status,
1471     .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
1472     .flow_ctrl = dwxgmac2_flow_ctrl,
1473     .pmt = dwxgmac2_pmt,
1474     .set_umac_addr = dwxgmac2_set_umac_addr,
1475     .get_umac_addr = dwxgmac2_get_umac_addr,
1476     .set_eee_mode = dwxgmac2_set_eee_mode,
1477     .reset_eee_mode = dwxgmac2_reset_eee_mode,
1478     .set_eee_timer = dwxgmac2_set_eee_timer,
1479     .set_eee_pls = dwxgmac2_set_eee_pls,
1480     .pcs_ctrl_ane = NULL,
1481     .pcs_rane = NULL,
1482     .pcs_get_adv_lp = NULL,
1483     .debug = NULL,
1484     .set_filter = dwxgmac2_set_filter,
1485     .safety_feat_config = dwxgmac3_safety_feat_config,
1486     .safety_feat_irq_status = dwxgmac3_safety_feat_irq_status,
1487     .safety_feat_dump = dwxgmac3_safety_feat_dump,
1488     .set_mac_loopback = dwxgmac2_set_mac_loopback,
1489     .rss_configure = dwxgmac2_rss_configure,
1490     .update_vlan_hash = dwxgmac2_update_vlan_hash,
1491     .rxp_config = dwxgmac3_rxp_config,
1492     .get_mac_tx_timestamp = dwxgmac2_get_mac_tx_timestamp,
1493     .flex_pps_config = dwxgmac2_flex_pps_config,
1494     .sarc_configure = dwxgmac2_sarc_configure,
1495     .enable_vlan = dwxgmac2_enable_vlan,
1496     .config_l3_filter = dwxgmac2_config_l3_filter,
1497     .config_l4_filter = dwxgmac2_config_l4_filter,
1498     .set_arp_offload = dwxgmac2_set_arp_offload,
1499     .est_configure = dwxgmac3_est_configure,
1500     .fpe_configure = dwxgmac3_fpe_configure,
1501 };
1502 
1503 static void dwxlgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
1504                       u32 queue)
1505 {
1506     void __iomem *ioaddr = hw->pcsr;
1507     u32 value;
1508 
1509     value = readl(ioaddr + XLGMAC_RXQ_ENABLE_CTRL0) & ~XGMAC_RXQEN(queue);
1510     if (mode == MTL_QUEUE_AVB)
1511         value |= 0x1 << XGMAC_RXQEN_SHIFT(queue);
1512     else if (mode == MTL_QUEUE_DCB)
1513         value |= 0x2 << XGMAC_RXQEN_SHIFT(queue);
1514     writel(value, ioaddr + XLGMAC_RXQ_ENABLE_CTRL0);
1515 }
1516 
1517 const struct stmmac_ops dwxlgmac2_ops = {
1518     .core_init = dwxgmac2_core_init,
1519     .set_mac = dwxgmac2_set_mac,
1520     .rx_ipc = dwxgmac2_rx_ipc,
1521     .rx_queue_enable = dwxlgmac2_rx_queue_enable,
1522     .rx_queue_prio = dwxgmac2_rx_queue_prio,
1523     .tx_queue_prio = dwxgmac2_tx_queue_prio,
1524     .rx_queue_routing = NULL,
1525     .prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
1526     .prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
1527     .set_mtl_tx_queue_weight = dwxgmac2_set_mtl_tx_queue_weight,
1528     .map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
1529     .config_cbs = dwxgmac2_config_cbs,
1530     .dump_regs = dwxgmac2_dump_regs,
1531     .host_irq_status = dwxgmac2_host_irq_status,
1532     .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
1533     .flow_ctrl = dwxgmac2_flow_ctrl,
1534     .pmt = dwxgmac2_pmt,
1535     .set_umac_addr = dwxgmac2_set_umac_addr,
1536     .get_umac_addr = dwxgmac2_get_umac_addr,
1537     .set_eee_mode = dwxgmac2_set_eee_mode,
1538     .reset_eee_mode = dwxgmac2_reset_eee_mode,
1539     .set_eee_timer = dwxgmac2_set_eee_timer,
1540     .set_eee_pls = dwxgmac2_set_eee_pls,
1541     .pcs_ctrl_ane = NULL,
1542     .pcs_rane = NULL,
1543     .pcs_get_adv_lp = NULL,
1544     .debug = NULL,
1545     .set_filter = dwxgmac2_set_filter,
1546     .safety_feat_config = dwxgmac3_safety_feat_config,
1547     .safety_feat_irq_status = dwxgmac3_safety_feat_irq_status,
1548     .safety_feat_dump = dwxgmac3_safety_feat_dump,
1549     .set_mac_loopback = dwxgmac2_set_mac_loopback,
1550     .rss_configure = dwxgmac2_rss_configure,
1551     .update_vlan_hash = dwxgmac2_update_vlan_hash,
1552     .rxp_config = dwxgmac3_rxp_config,
1553     .get_mac_tx_timestamp = dwxgmac2_get_mac_tx_timestamp,
1554     .flex_pps_config = dwxgmac2_flex_pps_config,
1555     .sarc_configure = dwxgmac2_sarc_configure,
1556     .enable_vlan = dwxgmac2_enable_vlan,
1557     .config_l3_filter = dwxgmac2_config_l3_filter,
1558     .config_l4_filter = dwxgmac2_config_l4_filter,
1559     .set_arp_offload = dwxgmac2_set_arp_offload,
1560     .est_configure = dwxgmac3_est_configure,
1561     .fpe_configure = dwxgmac3_fpe_configure,
1562 };
1563 
1564 int dwxgmac2_setup(struct stmmac_priv *priv)
1565 {
1566     struct mac_device_info *mac = priv->hw;
1567 
1568     dev_info(priv->device, "\tXGMAC2\n");
1569 
1570     priv->dev->priv_flags |= IFF_UNICAST_FLT;
1571     mac->pcsr = priv->ioaddr;
1572     mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
1573     mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
1574     mac->mcast_bits_log2 = 0;
1575 
1576     if (mac->multicast_filter_bins)
1577         mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
1578 
1579     mac->link.duplex = 0;
1580     mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
1581     mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
1582     mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII;
1583     mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII;
1584     mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500;
1585     mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
1586     mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
1587     mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
1588 
1589     mac->mii.addr = XGMAC_MDIO_ADDR;
1590     mac->mii.data = XGMAC_MDIO_DATA;
1591     mac->mii.addr_shift = 16;
1592     mac->mii.addr_mask = GENMASK(20, 16);
1593     mac->mii.reg_shift = 0;
1594     mac->mii.reg_mask = GENMASK(15, 0);
1595     mac->mii.clk_csr_shift = 19;
1596     mac->mii.clk_csr_mask = GENMASK(21, 19);
1597 
1598     return 0;
1599 }
1600 
1601 int dwxlgmac2_setup(struct stmmac_priv *priv)
1602 {
1603     struct mac_device_info *mac = priv->hw;
1604 
1605     dev_info(priv->device, "\tXLGMAC\n");
1606 
1607     priv->dev->priv_flags |= IFF_UNICAST_FLT;
1608     mac->pcsr = priv->ioaddr;
1609     mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
1610     mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
1611     mac->mcast_bits_log2 = 0;
1612 
1613     if (mac->multicast_filter_bins)
1614         mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
1615 
1616     mac->link.duplex = 0;
1617     mac->link.speed1000 = XLGMAC_CONFIG_SS_1000;
1618     mac->link.speed2500 = XLGMAC_CONFIG_SS_2500;
1619     mac->link.xgmii.speed10000 = XLGMAC_CONFIG_SS_10G;
1620     mac->link.xlgmii.speed25000 = XLGMAC_CONFIG_SS_25G;
1621     mac->link.xlgmii.speed40000 = XLGMAC_CONFIG_SS_40G;
1622     mac->link.xlgmii.speed50000 = XLGMAC_CONFIG_SS_50G;
1623     mac->link.xlgmii.speed100000 = XLGMAC_CONFIG_SS_100G;
1624     mac->link.speed_mask = XLGMAC_CONFIG_SS;
1625 
1626     mac->mii.addr = XGMAC_MDIO_ADDR;
1627     mac->mii.data = XGMAC_MDIO_DATA;
1628     mac->mii.addr_shift = 16;
1629     mac->mii.addr_mask = GENMASK(20, 16);
1630     mac->mii.reg_shift = 0;
1631     mac->mii.reg_mask = GENMASK(15, 0);
1632     mac->mii.clk_csr_shift = 19;
1633     mac->mii.clk_csr_mask = GENMASK(21, 19);
1634 
1635     return 0;
1636 }