1 // SPDX-License-Identifier: GPL-2.0-only 2 /******************************************************************************* 3 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs. 4 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for 5 developing this code. 6 7 This only implements the mac core functions for this chip. 8 9 Copyright (C) 2007-2009 STMicroelectronics Ltd 10 11 12 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 13 *******************************************************************************/ 14 15 #include <linux/crc32.h> 16 #include <linux/slab.h> 17 #include <linux/ethtool.h> 18 #include <linux/io.h> 19 #include <linux/string_choices.h> 20 #include "stmmac.h" 21 #include "stmmac_pcs.h" 22 #include "stmmac_ptp.h" 23 #include "dwmac1000.h" 24 25 static int dwmac1000_pcs_init(struct stmmac_priv *priv) 26 { 27 if (!priv->dma_cap.pcs) 28 return 0; 29 30 return stmmac_integrated_pcs_init(priv, GMAC_PCS_BASE, 31 GMAC_INT_DISABLE_PCSLINK | 32 GMAC_INT_DISABLE_PCSAN); 33 } 34 35 static void dwmac1000_core_init(struct mac_device_info *hw, 36 struct net_device *dev) 37 { 38 void __iomem *ioaddr = hw->pcsr; 39 int mtu = dev->mtu; 40 u32 value; 41 42 /* Configure GMAC core */ 43 value = readl(ioaddr + GMAC_CONTROL); 44 45 if (mtu > 1500) 46 value |= GMAC_CONTROL_2K; 47 if (mtu > 2000) 48 value |= GMAC_CONTROL_JE; 49 50 writel(value | GMAC_CORE_INIT, ioaddr + GMAC_CONTROL); 51 52 /* Mask GMAC interrupts */ 53 writel(GMAC_INT_DEFAULT_MASK, ioaddr + GMAC_INT_MASK); 54 55 #ifdef STMMAC_VLAN_TAG_USED 56 /* Tag detection without filtering */ 57 writel(0x0, ioaddr + GMAC_VLAN_TAG); 58 #endif 59 } 60 61 static void dwmac1000_irq_modify(struct mac_device_info *hw, u32 disable, 62 u32 enable) 63 { 64 void __iomem *int_mask = hw->pcsr + GMAC_INT_MASK; 65 unsigned long flags; 66 u32 value; 67 68 spin_lock_irqsave(&hw->irq_ctrl_lock, flags); 69 value = readl(int_mask) | disable; 70 value &= ~enable; 71 writel(value, int_mask); 72 spin_unlock_irqrestore(&hw->irq_ctrl_lock, flags); 73 } 74 75 static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw) 76 { 77 void __iomem *ioaddr = hw->pcsr; 78 u32 value = readl(ioaddr + GMAC_CONTROL); 79 80 if (hw->rx_csum) 81 value |= GMAC_CONTROL_IPC; 82 else 83 value &= ~GMAC_CONTROL_IPC; 84 85 writel(value, ioaddr + GMAC_CONTROL); 86 87 value = readl(ioaddr + GMAC_CONTROL); 88 89 return !!(value & GMAC_CONTROL_IPC); 90 } 91 92 static void dwmac1000_dump_regs(struct mac_device_info *hw, u32 *reg_space) 93 { 94 void __iomem *ioaddr = hw->pcsr; 95 int i; 96 97 for (i = 0; i < 55; i++) 98 reg_space[i] = readl(ioaddr + i * 4); 99 } 100 101 static void dwmac1000_set_umac_addr(struct mac_device_info *hw, 102 const unsigned char *addr, 103 unsigned int reg_n) 104 { 105 void __iomem *ioaddr = hw->pcsr; 106 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), 107 GMAC_ADDR_LOW(reg_n)); 108 } 109 110 static void dwmac1000_get_umac_addr(struct mac_device_info *hw, 111 unsigned char *addr, 112 unsigned int reg_n) 113 { 114 void __iomem *ioaddr = hw->pcsr; 115 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), 116 GMAC_ADDR_LOW(reg_n)); 117 } 118 119 static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits, 120 int mcbitslog2) 121 { 122 int numhashregs, regs; 123 124 switch (mcbitslog2) { 125 case 6: 126 writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW); 127 writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH); 128 return; 129 case 7: 130 numhashregs = 4; 131 break; 132 case 8: 133 numhashregs = 8; 134 break; 135 default: 136 pr_debug("STMMAC: err in setting multicast filter\n"); 137 return; 138 } 139 for (regs = 0; regs < numhashregs; regs++) 140 writel(mcfilterbits[regs], 141 ioaddr + GMAC_EXTHASH_BASE + regs * 4); 142 } 143 144 static void dwmac1000_set_filter(struct mac_device_info *hw, 145 struct net_device *dev) 146 { 147 void __iomem *ioaddr = (void __iomem *)dev->base_addr; 148 unsigned int value = 0; 149 unsigned int perfect_addr_number = hw->unicast_filter_entries; 150 u32 mc_filter[8]; 151 int mcbitslog2 = hw->mcast_bits_log2; 152 153 pr_debug("%s: # mcasts %d, # unicast %d\n", __func__, 154 netdev_mc_count(dev), netdev_uc_count(dev)); 155 156 memset(mc_filter, 0, sizeof(mc_filter)); 157 158 if (dev->flags & IFF_PROMISC) { 159 value = GMAC_FRAME_FILTER_PR | GMAC_FRAME_FILTER_PCF; 160 } else if (dev->flags & IFF_ALLMULTI) { 161 value = GMAC_FRAME_FILTER_PM; /* pass all multi */ 162 } else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) { 163 /* Fall back to all multicast if we've no filter */ 164 value = GMAC_FRAME_FILTER_PM; 165 } else if (!netdev_mc_empty(dev)) { 166 struct netdev_hw_addr *ha; 167 168 /* Hash filter for multicast */ 169 value = GMAC_FRAME_FILTER_HMC; 170 171 netdev_for_each_mc_addr(ha, dev) { 172 /* The upper n bits of the calculated CRC are used to 173 * index the contents of the hash table. The number of 174 * bits used depends on the hardware configuration 175 * selected at core configuration time. 176 */ 177 int bit_nr = bitrev32(~crc32_le(~0, ha->addr, 178 ETH_ALEN)) >> 179 (32 - mcbitslog2); 180 /* The most significant bit determines the register to 181 * use (H/L) while the other 5 bits determine the bit 182 * within the register. 183 */ 184 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 185 } 186 } 187 188 value |= GMAC_FRAME_FILTER_HPF; 189 dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2); 190 191 /* Handle multiple unicast addresses (perfect filtering) */ 192 if (netdev_uc_count(dev) > perfect_addr_number) 193 /* Switch to promiscuous mode if more than unicast 194 * addresses are requested than supported by hardware. 195 */ 196 value |= GMAC_FRAME_FILTER_PR; 197 else { 198 int reg = 1; 199 struct netdev_hw_addr *ha; 200 201 netdev_for_each_uc_addr(ha, dev) { 202 stmmac_set_mac_addr(ioaddr, ha->addr, 203 GMAC_ADDR_HIGH(reg), 204 GMAC_ADDR_LOW(reg)); 205 reg++; 206 } 207 208 while (reg < perfect_addr_number) { 209 writel(0, ioaddr + GMAC_ADDR_HIGH(reg)); 210 writel(0, ioaddr + GMAC_ADDR_LOW(reg)); 211 reg++; 212 } 213 } 214 215 #ifdef FRAME_FILTER_DEBUG 216 /* Enable Receive all mode (to debug filtering_fail errors) */ 217 value |= GMAC_FRAME_FILTER_RA; 218 #endif 219 writel(value, ioaddr + GMAC_FRAME_FILTER); 220 } 221 222 223 static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, 224 unsigned int fc, unsigned int pause_time, 225 u32 tx_cnt) 226 { 227 void __iomem *ioaddr = hw->pcsr; 228 /* Set flow such that DZPQ in Mac Register 6 is 0, 229 * and unicast pause detect is enabled. 230 */ 231 unsigned int flow = GMAC_FLOW_CTRL_UP; 232 233 pr_debug("GMAC Flow-Control:\n"); 234 if (fc & FLOW_RX) { 235 pr_debug("\tReceive Flow-Control ON\n"); 236 flow |= GMAC_FLOW_CTRL_RFE; 237 } 238 if (fc & FLOW_TX) { 239 pr_debug("\tTransmit Flow-Control ON\n"); 240 flow |= GMAC_FLOW_CTRL_TFE; 241 } 242 243 if (duplex) { 244 pr_debug("\tduplex mode: PAUSE %d\n", pause_time); 245 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT); 246 } 247 248 writel(flow, ioaddr + GMAC_FLOW_CTRL); 249 } 250 251 static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode) 252 { 253 void __iomem *ioaddr = hw->pcsr; 254 unsigned int pmt = 0; 255 256 if (mode & WAKE_MAGIC) { 257 pr_debug("GMAC: WOL Magic frame\n"); 258 pmt |= power_down | magic_pkt_en; 259 } 260 if (mode & WAKE_UCAST) { 261 pr_debug("GMAC: WOL on global unicast\n"); 262 pmt |= power_down | global_unicast | wake_up_frame_en; 263 } 264 265 writel(pmt, ioaddr + GMAC_PMT); 266 } 267 268 static int dwmac1000_irq_status(struct mac_device_info *hw, 269 struct stmmac_extra_stats *x) 270 { 271 void __iomem *ioaddr = hw->pcsr; 272 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); 273 u32 intr_mask = readl(ioaddr + GMAC_INT_MASK); 274 int ret = 0; 275 276 /* Discard masked bits */ 277 intr_status &= ~intr_mask; 278 279 /* Not used events (e.g. MMC interrupts) are not handled. */ 280 if ((intr_status & GMAC_INT_STATUS_MMCTIS)) 281 x->mmc_tx_irq_n++; 282 if (unlikely(intr_status & GMAC_INT_STATUS_MMCRIS)) 283 x->mmc_rx_irq_n++; 284 if (unlikely(intr_status & GMAC_INT_STATUS_MMCCSUM)) 285 x->mmc_rx_csum_offload_irq_n++; 286 if (unlikely(intr_status & GMAC_INT_DISABLE_PMT)) { 287 /* clear the PMT bits 5 and 6 by reading the PMT status reg */ 288 readl(ioaddr + GMAC_PMT); 289 x->irq_receive_pmt_irq_n++; 290 } 291 292 /* MAC tx/rx EEE LPI entry/exit interrupts */ 293 if (intr_status & GMAC_INT_STATUS_LPIIS) { 294 /* Clean LPI interrupt by reading the Reg 12 */ 295 ret = readl(ioaddr + LPI_CTRL_STATUS); 296 297 if (ret & LPI_CTRL_STATUS_TLPIEN) 298 x->irq_tx_path_in_lpi_mode_n++; 299 if (ret & LPI_CTRL_STATUS_TLPIEX) 300 x->irq_tx_path_exit_lpi_mode_n++; 301 if (ret & LPI_CTRL_STATUS_RLPIEN) 302 x->irq_rx_path_in_lpi_mode_n++; 303 if (ret & LPI_CTRL_STATUS_RLPIEX) 304 x->irq_rx_path_exit_lpi_mode_n++; 305 } 306 307 dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); 308 309 return ret; 310 } 311 312 static int dwmac1000_set_lpi_mode(struct mac_device_info *hw, 313 enum stmmac_lpi_mode mode, 314 bool en_tx_lpi_clockgating, u32 et) 315 { 316 void __iomem *ioaddr = hw->pcsr; 317 u32 value; 318 319 if (mode == STMMAC_LPI_TIMER) 320 return -EOPNOTSUPP; 321 322 value = readl(ioaddr + LPI_CTRL_STATUS); 323 if (mode == STMMAC_LPI_FORCED) 324 value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA; 325 else 326 value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA); 327 writel(value, ioaddr + LPI_CTRL_STATUS); 328 329 return 0; 330 } 331 332 static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link) 333 { 334 void __iomem *ioaddr = hw->pcsr; 335 u32 value; 336 337 value = readl(ioaddr + LPI_CTRL_STATUS); 338 339 if (link) 340 value |= LPI_CTRL_STATUS_PLS; 341 else 342 value &= ~LPI_CTRL_STATUS_PLS; 343 344 writel(value, ioaddr + LPI_CTRL_STATUS); 345 } 346 347 static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw) 348 { 349 void __iomem *ioaddr = hw->pcsr; 350 int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16); 351 352 /* Program the timers in the LPI timer control register: 353 * LS: minimum time (ms) for which the link 354 * status from PHY should be ok before transmitting 355 * the LPI pattern. 356 * TW: minimum time (us) for which the core waits 357 * after it has stopped transmitting the LPI pattern. 358 */ 359 writel(value, ioaddr + LPI_TIMER_CTRL); 360 } 361 362 static void dwmac1000_ctrl_ane(struct stmmac_priv *priv, bool ane, 363 bool srgmi_ral) 364 { 365 dwmac_ctrl_ane(priv->ioaddr, GMAC_PCS_BASE, ane, srgmi_ral); 366 } 367 368 static void dwmac1000_debug(struct stmmac_priv *priv, void __iomem *ioaddr, 369 struct stmmac_extra_stats *x, 370 u32 rx_queues, u32 tx_queues) 371 { 372 u32 value = readl(ioaddr + GMAC_DEBUG); 373 374 if (value & GMAC_DEBUG_TXSTSFSTS) 375 x->mtl_tx_status_fifo_full++; 376 if (value & GMAC_DEBUG_TXFSTS) 377 x->mtl_tx_fifo_not_empty++; 378 if (value & GMAC_DEBUG_TWCSTS) 379 x->mmtl_fifo_ctrl++; 380 if (value & GMAC_DEBUG_TRCSTS_MASK) { 381 u32 trcsts = (value & GMAC_DEBUG_TRCSTS_MASK) 382 >> GMAC_DEBUG_TRCSTS_SHIFT; 383 if (trcsts == GMAC_DEBUG_TRCSTS_WRITE) 384 x->mtl_tx_fifo_read_ctrl_write++; 385 else if (trcsts == GMAC_DEBUG_TRCSTS_TXW) 386 x->mtl_tx_fifo_read_ctrl_wait++; 387 else if (trcsts == GMAC_DEBUG_TRCSTS_READ) 388 x->mtl_tx_fifo_read_ctrl_read++; 389 else 390 x->mtl_tx_fifo_read_ctrl_idle++; 391 } 392 if (value & GMAC_DEBUG_TXPAUSED) 393 x->mac_tx_in_pause++; 394 if (value & GMAC_DEBUG_TFCSTS_MASK) { 395 u32 tfcsts = (value & GMAC_DEBUG_TFCSTS_MASK) 396 >> GMAC_DEBUG_TFCSTS_SHIFT; 397 398 if (tfcsts == GMAC_DEBUG_TFCSTS_XFER) 399 x->mac_tx_frame_ctrl_xfer++; 400 else if (tfcsts == GMAC_DEBUG_TFCSTS_GEN_PAUSE) 401 x->mac_tx_frame_ctrl_pause++; 402 else if (tfcsts == GMAC_DEBUG_TFCSTS_WAIT) 403 x->mac_tx_frame_ctrl_wait++; 404 else 405 x->mac_tx_frame_ctrl_idle++; 406 } 407 if (value & GMAC_DEBUG_TPESTS) 408 x->mac_gmii_tx_proto_engine++; 409 if (value & GMAC_DEBUG_RXFSTS_MASK) { 410 u32 rxfsts = (value & GMAC_DEBUG_RXFSTS_MASK) 411 >> GMAC_DEBUG_RRCSTS_SHIFT; 412 413 if (rxfsts == GMAC_DEBUG_RXFSTS_FULL) 414 x->mtl_rx_fifo_fill_level_full++; 415 else if (rxfsts == GMAC_DEBUG_RXFSTS_AT) 416 x->mtl_rx_fifo_fill_above_thresh++; 417 else if (rxfsts == GMAC_DEBUG_RXFSTS_BT) 418 x->mtl_rx_fifo_fill_below_thresh++; 419 else 420 x->mtl_rx_fifo_fill_level_empty++; 421 } 422 if (value & GMAC_DEBUG_RRCSTS_MASK) { 423 u32 rrcsts = (value & GMAC_DEBUG_RRCSTS_MASK) >> 424 GMAC_DEBUG_RRCSTS_SHIFT; 425 426 if (rrcsts == GMAC_DEBUG_RRCSTS_FLUSH) 427 x->mtl_rx_fifo_read_ctrl_flush++; 428 else if (rrcsts == GMAC_DEBUG_RRCSTS_RSTAT) 429 x->mtl_rx_fifo_read_ctrl_read_data++; 430 else if (rrcsts == GMAC_DEBUG_RRCSTS_RDATA) 431 x->mtl_rx_fifo_read_ctrl_status++; 432 else 433 x->mtl_rx_fifo_read_ctrl_idle++; 434 } 435 if (value & GMAC_DEBUG_RWCSTS) 436 x->mtl_rx_fifo_ctrl_active++; 437 if (value & GMAC_DEBUG_RFCFCSTS_MASK) 438 x->mac_rx_frame_ctrl_fifo = (value & GMAC_DEBUG_RFCFCSTS_MASK) 439 >> GMAC_DEBUG_RFCFCSTS_SHIFT; 440 if (value & GMAC_DEBUG_RPESTS) 441 x->mac_gmii_rx_proto_engine++; 442 } 443 444 static void dwmac1000_set_mac_loopback(void __iomem *ioaddr, bool enable) 445 { 446 u32 value = readl(ioaddr + GMAC_CONTROL); 447 448 if (enable) 449 value |= GMAC_CONTROL_LM; 450 else 451 value &= ~GMAC_CONTROL_LM; 452 453 writel(value, ioaddr + GMAC_CONTROL); 454 } 455 456 const struct stmmac_ops dwmac1000_ops = { 457 .pcs_init = dwmac1000_pcs_init, 458 .core_init = dwmac1000_core_init, 459 .irq_modify = dwmac1000_irq_modify, 460 .set_mac = stmmac_set_mac, 461 .rx_ipc = dwmac1000_rx_ipc_enable, 462 .dump_regs = dwmac1000_dump_regs, 463 .host_irq_status = dwmac1000_irq_status, 464 .set_filter = dwmac1000_set_filter, 465 .flow_ctrl = dwmac1000_flow_ctrl, 466 .pmt = dwmac1000_pmt, 467 .set_umac_addr = dwmac1000_set_umac_addr, 468 .get_umac_addr = dwmac1000_get_umac_addr, 469 .set_lpi_mode = dwmac1000_set_lpi_mode, 470 .set_eee_timer = dwmac1000_set_eee_timer, 471 .set_eee_pls = dwmac1000_set_eee_pls, 472 .debug = dwmac1000_debug, 473 .pcs_ctrl_ane = dwmac1000_ctrl_ane, 474 .set_mac_loopback = dwmac1000_set_mac_loopback, 475 }; 476 477 int dwmac1000_setup(struct stmmac_priv *priv) 478 { 479 struct mac_device_info *mac = priv->hw; 480 481 dev_info(priv->device, "\tDWMAC1000\n"); 482 483 priv->dev->priv_flags |= IFF_UNICAST_FLT; 484 mac->pcsr = priv->ioaddr; 485 mac->multicast_filter_bins = priv->plat->multicast_filter_bins; 486 mac->unicast_filter_entries = priv->plat->unicast_filter_entries; 487 mac->mcast_bits_log2 = 0; 488 489 if (mac->multicast_filter_bins) 490 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins); 491 492 mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | 493 MAC_10 | MAC_100 | MAC_1000; 494 mac->link.duplex = GMAC_CONTROL_DM; 495 mac->link.speed10 = GMAC_CONTROL_PS; 496 mac->link.speed100 = GMAC_CONTROL_PS | GMAC_CONTROL_FES; 497 mac->link.speed1000 = 0; 498 mac->link.speed_mask = GMAC_CONTROL_PS | GMAC_CONTROL_FES; 499 mac->mii.addr = GMAC_MII_ADDR; 500 mac->mii.data = GMAC_MII_DATA; 501 mac->mii.addr_shift = 11; 502 mac->mii.addr_mask = 0x0000F800; 503 mac->mii.reg_shift = 6; 504 mac->mii.reg_mask = 0x000007C0; 505 mac->mii.clk_csr_shift = 2; 506 mac->mii.clk_csr_mask = GENMASK(5, 2); 507 508 return 0; 509 } 510 511 /* DWMAC 1000 HW Timestaming ops */ 512 513 void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time) 514 { 515 u64 ns; 516 517 ns = readl(ptpaddr + GMAC_PTP_ATNR); 518 ns += (u64)readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC; 519 520 *ptp_time = ns; 521 } 522 523 void dwmac1000_timestamp_interrupt(struct stmmac_priv *priv) 524 { 525 struct ptp_clock_event event; 526 u32 ts_status, num_snapshot; 527 unsigned long flags; 528 u64 ptp_time; 529 int i; 530 531 /* Clears the timestamp interrupt */ 532 ts_status = readl(priv->ptpaddr + GMAC3_X_TIMESTAMP_STATUS); 533 534 if (!(priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN)) 535 return; 536 537 num_snapshot = (ts_status & GMAC3_X_ATSNS) >> GMAC3_X_ATSNS_SHIFT; 538 539 for (i = 0; i < num_snapshot; i++) { 540 read_lock_irqsave(&priv->ptp_lock, flags); 541 stmmac_get_ptptime(priv, priv->ptpaddr, &ptp_time); 542 read_unlock_irqrestore(&priv->ptp_lock, flags); 543 544 event.type = PTP_CLOCK_EXTTS; 545 event.index = 0; 546 event.timestamp = ptp_time; 547 ptp_clock_event(priv->ptp_clock, &event); 548 } 549 } 550 551 /* DWMAC 1000 ptp_clock_info ops */ 552 553 static void dwmac1000_timestamp_interrupt_cfg(struct stmmac_priv *priv, bool en) 554 { 555 void __iomem *ioaddr = priv->ioaddr; 556 557 u32 intr_mask = readl(ioaddr + GMAC_INT_MASK); 558 559 if (en) 560 intr_mask &= ~GMAC_INT_DISABLE_TIMESTAMP; 561 else 562 intr_mask |= GMAC_INT_DISABLE_TIMESTAMP; 563 564 writel(intr_mask, ioaddr + GMAC_INT_MASK); 565 } 566 567 int dwmac1000_ptp_enable(struct ptp_clock_info *ptp, 568 struct ptp_clock_request *rq, int on) 569 { 570 struct stmmac_priv *priv = 571 container_of(ptp, struct stmmac_priv, ptp_clock_ops); 572 void __iomem *ptpaddr = priv->ptpaddr; 573 int ret = -EOPNOTSUPP; 574 u32 tcr_val; 575 576 switch (rq->type) { 577 case PTP_CLK_REQ_EXTTS: 578 mutex_lock(&priv->aux_ts_lock); 579 tcr_val = readl(ptpaddr + PTP_TCR); 580 581 if (on) { 582 tcr_val |= GMAC_PTP_TCR_ATSEN0; 583 tcr_val |= GMAC_PTP_TCR_ATSFC; 584 priv->plat->flags |= STMMAC_FLAG_EXT_SNAPSHOT_EN; 585 } else { 586 tcr_val &= ~GMAC_PTP_TCR_ATSEN0; 587 priv->plat->flags &= ~STMMAC_FLAG_EXT_SNAPSHOT_EN; 588 } 589 590 netdev_dbg(priv->dev, "Auxiliary Snapshot %s.\n", 591 str_enabled_disabled(on)); 592 writel(tcr_val, ptpaddr + PTP_TCR); 593 594 /* wait for auxts fifo clear to finish */ 595 ret = readl_poll_timeout(ptpaddr + PTP_TCR, tcr_val, 596 !(tcr_val & GMAC_PTP_TCR_ATSFC), 597 10, 10000); 598 599 mutex_unlock(&priv->aux_ts_lock); 600 601 dwmac1000_timestamp_interrupt_cfg(priv, on); 602 break; 603 604 default: 605 break; 606 } 607 608 return ret; 609 } 610