FILE
dwmac4_core.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
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 version 4.00 has been used for developing this code. 5 * 6 * This only implements the mac core functions for this chip. 7 * 8 * Copyright (C) 2015 STMicroelectronics Ltd 9 * 10 * Author: Alexandre Torgue <alexandre.torgue@st.com> 11 */ 12 13#include <linux/crc32.h> 14#include <linux/slab.h> 15#include <linux/ethtool.h> 16#include <linux/io.h> 17#include <linux/iopoll.h> 18#include "stmmac.h" 19#include "stmmac_fpe.h" 20#include "stmmac_pcs.h" 21#include "stmmac_vlan.h" 22#include "dwmac4.h" 23#include "dwmac5.h" 24 25static int dwmac4_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_PCS_LINK | GMAC_INT_PCS_ANE); 32} 33 34static void dwmac4_core_init(struct mac_device_info *hw, 35 struct net_device *dev) 36{ 37 struct stmmac_priv *priv = netdev_priv(dev); 38 void __iomem *ioaddr = hw->pcsr; 39 unsigned long clk_rate; 40 u32 value; 41 42 value = readl(ioaddr + GMAC_CONFIG); 43 writel(value | GMAC_CORE_INIT, ioaddr + GMAC_CONFIG); 44 45 /* Configure LPI 1us counter to number of CSR clock ticks in 1us - 1 */ 46 clk_rate = clk_get_rate(priv->plat->stmmac_clk); 47 writel((clk_rate / 1000000) - 1, ioaddr + GMAC4_MAC_ONEUS_TIC_COUNTER); 48 49 /* Enable GMAC interrupts */ 50 writel(GMAC_INT_DEFAULT_ENABLE, ioaddr + GMAC_INT_EN); 51 52 if (GMAC_INT_DEFAULT_ENABLE & GMAC_INT_TSIE) 53 init_waitqueue_head(&priv->tstamp_busy_wait); 54} 55 56static void dwmac4_irq_modify(struct mac_device_info *hw, u32 disable, 57 u32 enable) 58{ 59 void __iomem *int_mask = hw->pcsr + GMAC_INT_EN; 60 unsigned long flags; 61 u32 value; 62 63 spin_lock_irqsave(&hw->irq_ctrl_lock, flags); 64 value = readl(int_mask) & ~disable; 65 value |= enable; 66 writel(value, int_mask); 67 spin_unlock_irqrestore(&hw->irq_ctrl_lock, flags); 68} 69 70static void dwmac4_update_caps(struct stmmac_priv *priv) 71{ 72 if (priv->plat->tx_queues_to_use > 1) 73 priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD | MAC_1000HD); 74 else 75 priv->hw->link.caps |= (MAC_10HD | MAC_100HD | MAC_1000HD); 76} 77 78static void dwmac4_rx_queue_enable(struct mac_device_info *hw, 79 u8 mode, u32 queue) 80{ 81 void __iomem *ioaddr = hw->pcsr; 82 u32 value = readl(ioaddr + GMAC_RXQ_CTRL0); 83 84 value &= GMAC_RX_QUEUE_CLEAR(queue); 85 if (mode == MTL_QUEUE_AVB) 86 value |= GMAC_RX_AV_QUEUE_ENABLE(queue); 87 else if (mode == MTL_QUEUE_DCB) 88 value |= GMAC_RX_DCB_QUEUE_ENABLE(queue); 89 90 writel(value, ioaddr + GMAC_RXQ_CTRL0); 91} 92 93static void dwmac4_rx_queue_priority(struct mac_device_info *hw, 94 u32 prio, u32 queue) 95{ 96 void __iomem *ioaddr = hw->pcsr; 97 u32 clear_mask = 0; 98 u32 ctrl2, ctrl3; 99 int i; 100 101 ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2); 102 ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3); 103 104 /* The software must ensure that the same priority 105 * is not mapped to multiple Rx queues 106 */ 107 for (i = 0; i < 4; i++) 108 clear_mask |= ((prio << GMAC_RXQCTRL_PSRQX_SHIFT(i)) & 109 GMAC_RXQCTRL_PSRQX_MASK(i)); 110 111 ctrl2 &= ~clear_mask; 112 ctrl3 &= ~clear_mask; 113 114 /* First assign new priorities to a queue, then 115 * clear them from others queues 116 */ 117 if (queue < 4) { 118 ctrl2 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) & 119 GMAC_RXQCTRL_PSRQX_MASK(queue); 120 121 writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2); 122 writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3); 123 } else { 124 queue -= 4; 125 126 ctrl3 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) & 127 GMAC_RXQCTRL_PSRQX_MASK(queue); 128 129 writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3); 130 writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2); 131 } 132} 133 134static void dwmac4_tx_queue_priority(struct mac_device_info *hw, 135 u32 prio, u32 queue) 136{ 137 void __iomem *ioaddr = hw->pcsr; 138 u32 base_register; 139 u32 value; 140 141 base_register = (queue < 4) ? GMAC_TXQ_PRTY_MAP0 : GMAC_TXQ_PRTY_MAP1; 142 if (queue >= 4) 143 queue -= 4; 144 145 value = readl(ioaddr + base_register); 146 147 value &= ~GMAC_TXQCTRL_PSTQX_MASK(queue); 148 value |= (prio << GMAC_TXQCTRL_PSTQX_SHIFT(queue)) & 149 GMAC_TXQCTRL_PSTQX_MASK(queue); 150 151 writel(value, ioaddr + base_register); 152} 153 154static void dwmac4_rx_queue_routing(struct mac_device_info *hw, 155 u8 packet, u32 queue) 156{ 157 void __iomem *ioaddr = hw->pcsr; 158 u32 value; 159 160 static const struct stmmac_rx_routing route_possibilities[] = { 161 { GMAC_RXQCTRL_AVCPQ_MASK, GMAC_RXQCTRL_AVCPQ_SHIFT }, 162 { GMAC_RXQCTRL_PTPQ_MASK, GMAC_RXQCTRL_PTPQ_SHIFT }, 163 { GMAC_RXQCTRL_DCBCPQ_MASK, GMAC_RXQCTRL_DCBCPQ_SHIFT }, 164 { GMAC_RXQCTRL_UPQ_MASK, GMAC_RXQCTRL_UPQ_SHIFT }, 165 { GMAC_RXQCTRL_MCBCQ_MASK, GMAC_RXQCTRL_MCBCQ_SHIFT }, 166 }; 167 168 value = readl(ioaddr + GMAC_RXQ_CTRL1); 169 170 /* routing configuration */ 171 value &= ~route_possibilities[packet - 1].reg_mask; 172 value |= (queue << route_possibilities[packet-1].reg_shift) & 173 route_possibilities[packet - 1].reg_mask; 174 175 /* some packets require extra ops */ 176 if (packet == PACKET_AVCPQ) { 177 value &= ~GMAC_RXQCTRL_TACPQE; 178 value |= 0x1 << GMAC_RXQCTRL_TACPQE_SHIFT; 179 } else if (packet == PACKET_MCBCQ) { 180 value &= ~GMAC_RXQCTRL_MCBCQEN; 181 value |= 0x1 << GMAC_RXQCTRL_MCBCQEN_SHIFT; 182 } 183 184 writel(value, ioaddr + GMAC_RXQ_CTRL1); 185} 186 187static void dwmac4_prog_mtl_rx_algorithms(struct mac_device_info *hw, 188 u32 rx_alg) 189{ 190 void __iomem *ioaddr = hw->pcsr; 191 u32 value = readl(ioaddr + MTL_OPERATION_MODE); 192 193 value &= ~MTL_OPERATION_RAA; 194 switch (rx_alg) { 195 case MTL_RX_ALGORITHM_SP: 196 value |= MTL_OPERATION_RAA_SP; 197 break; 198 case MTL_RX_ALGORITHM_WSP: 199 value |= MTL_OPERATION_RAA_WSP; 200 break; 201 default: 202 break; 203 } 204 205 writel(value, ioaddr + MTL_OPERATION_MODE); 206} 207 208static void dwmac4_prog_mtl_tx_algorithms(struct mac_device_info *hw, 209 u32 tx_alg) 210{ 211 void __iomem *ioaddr = hw->pcsr; 212 u32 value = readl(ioaddr + MTL_OPERATION_MODE); 213 214 value &= ~MTL_OPERATION_SCHALG_MASK; 215 switch (tx_alg) { 216 case MTL_TX_ALGORITHM_WRR: 217 value |= MTL_OPERATION_SCHALG_WRR; 218 break; 219 case MTL_TX_ALGORITHM_WFQ: 220 value |= MTL_OPERATION_SCHALG_WFQ; 221 break; 222 case MTL_TX_ALGORITHM_DWRR: 223 value |= MTL_OPERATION_SCHALG_DWRR; 224 break; 225 case MTL_TX_ALGORITHM_SP: 226 value |= MTL_OPERATION_SCHALG_SP; 227 break; 228 default: 229 break; 230 } 231 232 writel(value, ioaddr + MTL_OPERATION_MODE); 233} 234 235static void dwmac4_set_mtl_tx_queue_weight(struct stmmac_priv *priv, 236 struct mac_device_info *hw, 237 u32 weight, u32 queue) 238{ 239 const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; 240 void __iomem *ioaddr = hw->pcsr; 241 u32 value = readl(ioaddr + mtl_txqx_weight_base_addr(dwmac4_addrs, 242 queue)); 243 244 value &= ~MTL_TXQ_WEIGHT_ISCQW_MASK; 245 value |= weight & MTL_TXQ_WEIGHT_ISCQW_MASK; 246 writel(value, ioaddr + mtl_txqx_weight_base_addr(dwmac4_addrs, queue)); 247} 248 249static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan) 250{ 251 void __iomem *ioaddr = hw->pcsr; 252 u32 value; 253 254 if (queue < 4) { 255 value = readl(ioaddr + MTL_RXQ_DMA_MAP0); 256 value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue); 257 value |= MTL_RXQ_DMA_QXMDMACH(chan, queue); 258 writel(value, ioaddr + MTL_RXQ_DMA_MAP0); 259 } else { 260 value = readl(ioaddr + MTL_RXQ_DMA_MAP1); 261 value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue - 4); 262 value |= MTL_RXQ_DMA_QXMDMACH(chan, queue - 4); 263 writel(value, ioaddr + MTL_RXQ_DMA_MAP1); 264 } 265} 266 267static void dwmac4_config_cbs(struct stmmac_priv *priv, 268 struct mac_device_info *hw, 269 u32 send_slope, u32 idle_slope, 270 u32 high_credit, u32 low_credit, u32 queue) 271{ 272 const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; 273 void __iomem *ioaddr = hw->pcsr; 274 u32 value; 275 276 pr_debug("Queue %d configured as AVB. Parameters:\n", queue); 277 pr_debug("\tsend_slope: 0x%08x\n", send_slope); 278 pr_debug("\tidle_slope: 0x%08x\n", idle_slope); 279 pr_debug("\thigh_credit: 0x%08x\n", high_credit); 280 pr_debug("\tlow_credit: 0x%08x\n", low_credit); 281 282 /* enable AV algorithm */ 283 value = readl(ioaddr + mtl_etsx_ctrl_base_addr(dwmac4_addrs, queue)); 284 value |= MTL_ETS_CTRL_AVALG; 285 value |= MTL_ETS_CTRL_CC; 286 writel(value, ioaddr + mtl_etsx_ctrl_base_addr(dwmac4_addrs, queue)); 287 288 /* configure send slope */ 289 value = readl(ioaddr + mtl_send_slp_credx_base_addr(dwmac4_addrs, 290 queue)); 291 value &= ~MTL_SEND_SLP_CRED_SSC_MASK; 292 value |= send_slope & MTL_SEND_SLP_CRED_SSC_MASK; 293 writel(value, ioaddr + mtl_send_slp_credx_base_addr(dwmac4_addrs, 294 queue)); 295 296 /* configure idle slope (same register as tx weight) */ 297 dwmac4_set_mtl_tx_queue_weight(priv, hw, idle_slope, queue); 298 299 /* configure high credit */ 300 value = readl(ioaddr + mtl_high_credx_base_addr(dwmac4_addrs, queue)); 301 value &= ~MTL_HIGH_CRED_HC_MASK; 302 value |= high_credit & MTL_HIGH_CRED_HC_MASK; 303 writel(value, ioaddr + mtl_high_credx_base_addr(dwmac4_addrs, queue)); 304 305 /* configure high credit */ 306 value = readl(ioaddr + mtl_low_credx_base_addr(dwmac4_addrs, queue)); 307 value &= ~MTL_HIGH_CRED_LC_MASK; 308 value |= low_credit & MTL_HIGH_CRED_LC_MASK; 309 writel(value, ioaddr + mtl_low_credx_base_addr(dwmac4_addrs, queue)); 310} 311 312static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space) 313{ 314 void __iomem *ioaddr = hw->pcsr; 315 int i; 316 317 for (i = 0; i < GMAC_REG_NUM; i++) 318 reg_space[i] = readl(ioaddr + i * 4); 319} 320 321static int dwmac4_rx_ipc_enable(struct mac_device_info *hw) 322{ 323 void __iomem *ioaddr = hw->pcsr; 324 u32 value = readl(ioaddr + GMAC_CONFIG); 325 326 if (hw->rx_csum) 327 value |= GMAC_CONFIG_IPC; 328 else 329 value &= ~GMAC_CONFIG_IPC; 330 331 writel(value, ioaddr + GMAC_CONFIG); 332 333 value = readl(ioaddr + GMAC_CONFIG); 334 335 return !!(value & GMAC_CONFIG_IPC); 336} 337 338static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode) 339{ 340 void __iomem *ioaddr = hw->pcsr; 341 unsigned int pmt = 0; 342 u32 config; 343 344 if (mode & WAKE_MAGIC) { 345 pr_debug("GMAC: WOL Magic frame\n"); 346 pmt |= power_down | magic_pkt_en; 347 } 348 if (mode & WAKE_UCAST) { 349 pr_debug("GMAC: WOL on global unicast\n"); 350 pmt |= power_down | global_unicast | wake_up_frame_en; 351 } 352 353 if (pmt) { 354 /* The receiver must be enabled for WOL before powering down */ 355 config = readl(ioaddr + GMAC_CONFIG); 356 config |= GMAC_CONFIG_RE; 357 writel(config, ioaddr + GMAC_CONFIG); 358 } 359 writel(pmt, ioaddr + GMAC_PMT); 360} 361 362static void dwmac4_set_umac_addr(struct mac_device_info *hw, 363 const unsigned char *addr, unsigned int reg_n) 364{ 365 void __iomem *ioaddr = hw->pcsr; 366 367 stmmac_dwmac4_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), 368 GMAC_ADDR_LOW(reg_n)); 369} 370 371static void dwmac4_get_umac_addr(struct mac_device_info *hw, 372 unsigned char *addr, unsigned int reg_n) 373{ 374 void __iomem *ioaddr = hw->pcsr; 375 376 stmmac_dwmac4_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), 377 GMAC_ADDR_LOW(reg_n)); 378} 379 380static int dwmac4_set_lpi_mode(struct mac_device_info *hw, 381 enum stmmac_lpi_mode mode, 382 bool en_tx_lpi_clockgating, u32 et) 383{ 384 void __iomem *ioaddr = hw->pcsr; 385 u32 value, mask; 386 387 if (mode == STMMAC_LPI_DISABLE) { 388 value = 0; 389 } else { 390 value = LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA; 391 392 if (mode == STMMAC_LPI_TIMER) { 393 /* Return ERANGE if the timer is larger than the 394 * register field. 395 */ 396 if (et > STMMAC_ET_MAX) 397 return -ERANGE; 398 399 /* Set the hardware LPI entry timer */ 400 writel(et, ioaddr + GMAC4_LPI_ENTRY_TIMER); 401 402 /* Interpret a zero LPI entry timer to mean 403 * immediate entry into LPI mode. 404 */ 405 if (et) 406 value |= LPI_CTRL_STATUS_LPIATE; 407 } 408 409 if (en_tx_lpi_clockgating) 410 value |= LPI_CTRL_STATUS_LPITCSE; 411 } 412 413 mask = LPI_CTRL_STATUS_LPIATE | LPI_CTRL_STATUS_LPIEN | 414 LPI_CTRL_STATUS_LPITXA | LPI_CTRL_STATUS_LPITCSE; 415 416 value |= readl(ioaddr + GMAC4_LPI_CTRL_STATUS) & ~mask; 417 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); 418 419 return 0; 420} 421 422static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link) 423{ 424 void __iomem *ioaddr = hw->pcsr; 425 u32 value; 426 427 value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); 428 429 if (link) 430 value |= LPI_CTRL_STATUS_PLS; 431 else 432 value &= ~LPI_CTRL_STATUS_PLS; 433 434 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); 435} 436 437static void dwmac4_set_eee_timer(struct mac_device_info *hw, int ls, int tw) 438{ 439 void __iomem *ioaddr = hw->pcsr; 440 int value = ((tw & 0xffff)) | ((ls & 0x3ff) << 16); 441 442 /* Program the timers in the LPI timer control register: 443 * LS: minimum time (ms) for which the link 444 * status from PHY should be ok before transmitting 445 * the LPI pattern. 446 * TW: minimum time (us) for which the core waits 447 * after it has stopped transmitting the LPI pattern. 448 */ 449 writel(value, ioaddr + GMAC4_LPI_TIMER_CTRL); 450} 451 452static void dwmac4_set_filter(struct mac_device_info *hw, 453 struct net_device *dev) 454{ 455 void __iomem *ioaddr = (void __iomem *)dev->base_addr; 456 int numhashregs = (hw->multicast_filter_bins >> 5); 457 int mcbitslog2 = hw->mcast_bits_log2; 458 unsigned int value; 459 u32 mc_filter[8]; 460 int i; 461 462 memset(mc_filter, 0, sizeof(mc_filter)); 463 464 value = readl(ioaddr + GMAC_PACKET_FILTER); 465 value &= ~GMAC_PACKET_FILTER_HMC; 466 value &= ~GMAC_PACKET_FILTER_HPF; 467 value &= ~GMAC_PACKET_FILTER_PCF; 468 value &= ~GMAC_PACKET_FILTER_PM; 469 value &= ~GMAC_PACKET_FILTER_PR; 470 value &= ~GMAC_PACKET_FILTER_RA; 471 if (dev->flags & IFF_PROMISC) { 472 /* VLAN Tag Filter Fail Packets Queuing */ 473 if (hw->vlan_fail_q_en) { 474 value = readl(ioaddr + GMAC_RXQ_CTRL4); 475 value &= ~GMAC_RXQCTRL_VFFQ_MASK; 476 value |= GMAC_RXQCTRL_VFFQE | 477 (hw->vlan_fail_q << GMAC_RXQCTRL_VFFQ_SHIFT); 478 writel(value, ioaddr + GMAC_RXQ_CTRL4); 479 value = GMAC_PACKET_FILTER_PR | GMAC_PACKET_FILTER_RA; 480 } else { 481 value = GMAC_PACKET_FILTER_PR | GMAC_PACKET_FILTER_PCF; 482 } 483 484 } else if ((dev->flags & IFF_ALLMULTI) || 485 (netdev_mc_count(dev) > hw->multicast_filter_bins)) { 486 /* Pass all multi */ 487 value |= GMAC_PACKET_FILTER_PM; 488 /* Set all the bits of the HASH tab */ 489 memset(mc_filter, 0xff, sizeof(mc_filter)); 490 } else if (!netdev_mc_empty(dev) && (dev->flags & IFF_MULTICAST)) { 491 struct netdev_hw_addr *ha; 492 493 /* Hash filter for multicast */ 494 value |= GMAC_PACKET_FILTER_HMC; 495 496 netdev_for_each_mc_addr(ha, dev) { 497 /* The upper n bits of the calculated CRC are used to 498 * index the contents of the hash table. The number of 499 * bits used depends on the hardware configuration 500 * selected at core configuration time. 501 */ 502 u32 bit_nr = bitrev32(~crc32_le(~0, ha->addr, 503 ETH_ALEN)) >> (32 - mcbitslog2); 504 /* The most significant bit determines the register to 505 * use (H/L) while the other 5 bits determine the bit 506 * within the register. 507 */ 508 mc_filter[bit_nr >> 5] |= (1 << (bit_nr & 0x1f)); 509 } 510 } 511 512 for (i = 0; i < numhashregs; i++) 513 writel(mc_filter[i], ioaddr + GMAC_HASH_TAB(i)); 514 515 value |= GMAC_PACKET_FILTER_HPF; 516 517 /* Handle multiple unicast addresses */ 518 if (netdev_uc_count(dev) > hw->unicast_filter_entries) { 519 /* Switch to promiscuous mode if more than 128 addrs 520 * are required 521 */ 522 value |= GMAC_PACKET_FILTER_PR; 523 } else { 524 struct netdev_hw_addr *ha; 525 int reg = 1; 526 527 netdev_for_each_uc_addr(ha, dev) { 528 dwmac4_set_umac_addr(hw, ha->addr, reg); 529 reg++; 530 } 531 532 while (reg < GMAC_MAX_PERFECT_ADDRESSES) { 533 writel(0, ioaddr + GMAC_ADDR_HIGH(reg)); 534 writel(0, ioaddr + GMAC_ADDR_LOW(reg)); 535 reg++; 536 } 537 } 538 539 /* VLAN filtering */ 540 if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) 541 value &= ~GMAC_PACKET_FILTER_VTFE; 542 else if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) 543 value |= GMAC_PACKET_FILTER_VTFE; 544 545 writel(value, ioaddr + GMAC_PACKET_FILTER); 546} 547 548static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, 549 unsigned int fc, unsigned int pause_time, 550 u32 tx_cnt) 551{ 552 void __iomem *ioaddr = hw->pcsr; 553 unsigned int flow = 0; 554 u32 queue = 0; 555 556 pr_debug("GMAC Flow-Control:\n"); 557 if (fc & FLOW_RX) { 558 pr_debug("\tReceive Flow-Control ON\n"); 559 flow |= GMAC_RX_FLOW_CTRL_RFE; 560 } else { 561 pr_debug("\tReceive Flow-Control OFF\n"); 562 } 563 writel(flow, ioaddr + GMAC_RX_FLOW_CTRL); 564 565 if (fc & FLOW_TX) { 566 pr_debug("\tTransmit Flow-Control ON\n"); 567 568 if (duplex) 569 pr_debug("\tduplex mode: PAUSE %d\n", pause_time); 570 571 for (queue = 0; queue < tx_cnt; queue++) { 572 flow = GMAC_TX_FLOW_CTRL_TFE; 573 574 if (duplex) 575 flow |= 576 (pause_time << GMAC_TX_FLOW_CTRL_PT_SHIFT); 577 578 writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(queue)); 579 } 580 } else { 581 for (queue = 0; queue < tx_cnt; queue++) 582 writel(0, ioaddr + GMAC_QX_TX_FLOW_CTRL(queue)); 583 } 584} 585 586static void dwmac4_ctrl_ane(struct stmmac_priv *priv, bool ane, bool srgmi_ral) 587{ 588 dwmac_ctrl_ane(priv->ioaddr, GMAC_PCS_BASE, ane, srgmi_ral); 589} 590 591static int dwmac4_irq_mtl_status(struct stmmac_priv *priv, 592 struct mac_device_info *hw, u32 chan) 593{ 594 const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; 595 void __iomem *ioaddr = hw->pcsr; 596 u32 mtl_int_qx_status; 597 int ret = 0; 598 599 mtl_int_qx_status = readl(ioaddr + MTL_INT_STATUS); 600 601 /* Check MTL Interrupt */ 602 if (mtl_int_qx_status & MTL_INT_QX(chan)) { 603 /* read Queue x Interrupt status */ 604 u32 status = readl(ioaddr + MTL_CHAN_INT_CTRL(dwmac4_addrs, 605 chan)); 606 607 if (status & MTL_RX_OVERFLOW_INT) { 608 /* clear Interrupt */ 609 writel(status | MTL_RX_OVERFLOW_INT, 610 ioaddr + MTL_CHAN_INT_CTRL(dwmac4_addrs, chan)); 611 ret = CORE_IRQ_MTL_RX_OVERFLOW; 612 } 613 } 614 615 return ret; 616} 617 618static int dwmac4_irq_status(struct mac_device_info *hw, 619 struct stmmac_extra_stats *x) 620{ 621 void __iomem *ioaddr = hw->pcsr; 622 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); 623 u32 intr_enable = readl(ioaddr + GMAC_INT_EN); 624 int ret = 0; 625 626 /* Discard disabled bits */ 627 intr_status &= intr_enable; 628 629 /* Not used events (e.g. MMC interrupts) are not handled. */ 630 if ((intr_status & mmc_tx_irq)) 631 x->mmc_tx_irq_n++; 632 if (unlikely(intr_status & mmc_rx_irq)) 633 x->mmc_rx_irq_n++; 634 if (unlikely(intr_status & mmc_rx_csum_offload_irq)) 635 x->mmc_rx_csum_offload_irq_n++; 636 /* Clear the PMT bits 5 and 6 by reading the PMT status reg */ 637 if (unlikely(intr_status & pmt_irq)) { 638 readl(ioaddr + GMAC_PMT); 639 x->irq_receive_pmt_irq_n++; 640 } 641 642 /* MAC tx/rx EEE LPI entry/exit interrupts */ 643 if (intr_status & lpi_irq) { 644 /* Clear LPI interrupt by reading MAC_LPI_Control_Status */ 645 u32 status = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); 646 647 if (status & LPI_CTRL_STATUS_TLPIEN) { 648 ret |= CORE_IRQ_TX_PATH_IN_LPI_MODE; 649 x->irq_tx_path_in_lpi_mode_n++; 650 } 651 if (status & LPI_CTRL_STATUS_TLPIEX) { 652 ret |= CORE_IRQ_TX_PATH_EXIT_LPI_MODE; 653 x->irq_tx_path_exit_lpi_mode_n++; 654 } 655 if (status & LPI_CTRL_STATUS_RLPIEN) 656 x->irq_rx_path_in_lpi_mode_n++; 657 if (status & LPI_CTRL_STATUS_RLPIEX) 658 x->irq_rx_path_exit_lpi_mode_n++; 659 } 660 661 dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); 662 663 return ret; 664} 665 666static void dwmac4_debug(struct stmmac_priv *priv, void __iomem *ioaddr, 667 struct stmmac_extra_stats *x, 668 u32 rx_queues, u32 tx_queues) 669{ 670 const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; 671 u32 value; 672 u32 queue; 673 674 for (queue = 0; queue < tx_queues; queue++) { 675 value = readl(ioaddr + MTL_CHAN_TX_DEBUG(dwmac4_addrs, queue)); 676 677 if (value & MTL_DEBUG_TXSTSFSTS) 678 x->mtl_tx_status_fifo_full++; 679 if (value & MTL_DEBUG_TXFSTS) 680 x->mtl_tx_fifo_not_empty++; 681 if (value & MTL_DEBUG_TWCSTS) 682 x->mmtl_fifo_ctrl++; 683 if (value & MTL_DEBUG_TRCSTS_MASK) { 684 u32 trcsts = (value & MTL_DEBUG_TRCSTS_MASK) 685 >> MTL_DEBUG_TRCSTS_SHIFT; 686 if (trcsts == MTL_DEBUG_TRCSTS_WRITE) 687 x->mtl_tx_fifo_read_ctrl_write++; 688 else if (trcsts == MTL_DEBUG_TRCSTS_TXW) 689 x->mtl_tx_fifo_read_ctrl_wait++; 690 else if (trcsts == MTL_DEBUG_TRCSTS_READ) 691 x->mtl_tx_fifo_read_ctrl_read++; 692 else 693 x->mtl_tx_fifo_read_ctrl_idle++; 694 } 695 if (value & MTL_DEBUG_TXPAUSED) 696 x->mac_tx_in_pause++; 697 } 698 699 for (queue = 0; queue < rx_queues; queue++) { 700 value = readl(ioaddr + MTL_CHAN_RX_DEBUG(dwmac4_addrs, queue)); 701 702 if (value & MTL_DEBUG_RXFSTS_MASK) { 703 u32 rxfsts = (value & MTL_DEBUG_RXFSTS_MASK) 704 >> MTL_DEBUG_RRCSTS_SHIFT; 705 706 if (rxfsts == MTL_DEBUG_RXFSTS_FULL) 707 x->mtl_rx_fifo_fill_level_full++; 708 else if (rxfsts == MTL_DEBUG_RXFSTS_AT) 709 x->mtl_rx_fifo_fill_above_thresh++; 710 else if (rxfsts == MTL_DEBUG_RXFSTS_BT) 711 x->mtl_rx_fifo_fill_below_thresh++; 712 else 713 x->mtl_rx_fifo_fill_level_empty++; 714 } 715 if (value & MTL_DEBUG_RRCSTS_MASK) { 716 u32 rrcsts = (value & MTL_DEBUG_RRCSTS_MASK) >> 717 MTL_DEBUG_RRCSTS_SHIFT; 718 719 if (rrcsts == MTL_DEBUG_RRCSTS_FLUSH) 720 x->mtl_rx_fifo_read_ctrl_flush++; 721 else if (rrcsts == MTL_DEBUG_RRCSTS_RSTAT) 722 x->mtl_rx_fifo_read_ctrl_read_data++; 723 else if (rrcsts == MTL_DEBUG_RRCSTS_RDATA) 724 x->mtl_rx_fifo_read_ctrl_status++; 725 else 726 x->mtl_rx_fifo_read_ctrl_idle++; 727 } 728 if (value & MTL_DEBUG_RWCSTS) 729 x->mtl_rx_fifo_ctrl_active++; 730 } 731 732 /* GMAC debug */ 733 value = readl(ioaddr + GMAC_DEBUG); 734 735 if (value & GMAC_DEBUG_TFCSTS_MASK) { 736 u32 tfcsts = (value & GMAC_DEBUG_TFCSTS_MASK) 737 >> GMAC_DEBUG_TFCSTS_SHIFT; 738 739 if (tfcsts == GMAC_DEBUG_TFCSTS_XFER) 740 x->mac_tx_frame_ctrl_xfer++; 741 else if (tfcsts == GMAC_DEBUG_TFCSTS_GEN_PAUSE) 742 x->mac_tx_frame_ctrl_pause++; 743 else if (tfcsts == GMAC_DEBUG_TFCSTS_WAIT) 744 x->mac_tx_frame_ctrl_wait++; 745 else 746 x->mac_tx_frame_ctrl_idle++; 747 } 748 if (value & GMAC_DEBUG_TPESTS) 749 x->mac_gmii_tx_proto_engine++; 750 if (value & GMAC_DEBUG_RFCFCSTS_MASK) 751 x->mac_rx_frame_ctrl_fifo = (value & GMAC_DEBUG_RFCFCSTS_MASK) 752 >> GMAC_DEBUG_RFCFCSTS_SHIFT; 753 if (value & GMAC_DEBUG_RPESTS) 754 x->mac_gmii_rx_proto_engine++; 755} 756 757static void dwmac4_set_mac_loopback(void __iomem *ioaddr, bool enable) 758{ 759 u32 value = readl(ioaddr + GMAC_CONFIG); 760 761 if (enable) 762 value |= GMAC_CONFIG_LM; 763 else 764 value &= ~GMAC_CONFIG_LM; 765 766 writel(value, ioaddr + GMAC_CONFIG); 767} 768 769static void dwmac4_sarc_configure(void __iomem *ioaddr, int val) 770{ 771 u32 value = readl(ioaddr + GMAC_CONFIG); 772 773 value &= ~GMAC_CONFIG_SARC; 774 value |= val << GMAC_CONFIG_SARC_SHIFT; 775 776 writel(value, ioaddr + GMAC_CONFIG); 777} 778 779static void dwmac4_set_arp_offload(struct mac_device_info *hw, bool en, 780 u32 addr) 781{ 782 void __iomem *ioaddr = hw->pcsr; 783 u32 value; 784 785 writel(addr, ioaddr + GMAC_ARP_ADDR); 786 787 value = readl(ioaddr + GMAC_CONFIG); 788 if (en) 789 value |= GMAC_CONFIG_ARPEN; 790 else 791 value &= ~GMAC_CONFIG_ARPEN; 792 writel(value, ioaddr + GMAC_CONFIG); 793} 794 795static int dwmac4_config_l3_filter(struct mac_device_info *hw, u32 filter_no, 796 bool en, bool ipv6, bool sa, bool inv, 797 u32 match) 798{ 799 void __iomem *ioaddr = hw->pcsr; 800 u32 value; 801 802 value = readl(ioaddr + GMAC_PACKET_FILTER); 803 value |= GMAC_PACKET_FILTER_IPFE; 804 writel(value, ioaddr + GMAC_PACKET_FILTER); 805 806 value = readl(ioaddr + GMAC_L3L4_CTRL(filter_no)); 807 808 /* For IPv6 not both SA/DA filters can be active */ 809 if (ipv6) { 810 value |= GMAC_L3PEN0; 811 value &= ~(GMAC_L3SAM0 | GMAC_L3SAIM0); 812 value &= ~(GMAC_L3DAM0 | GMAC_L3DAIM0); 813 if (sa) { 814 value |= GMAC_L3SAM0; 815 if (inv) 816 value |= GMAC_L3SAIM0; 817 } else { 818 value |= GMAC_L3DAM0; 819 if (inv) 820 value |= GMAC_L3DAIM0; 821 } 822 } else { 823 value &= ~GMAC_L3PEN0; 824 if (sa) { 825 value |= GMAC_L3SAM0; 826 if (inv) 827 value |= GMAC_L3SAIM0; 828 } else { 829 value |= GMAC_L3DAM0; 830 if (inv) 831 value |= GMAC_L3DAIM0; 832 } 833 } 834 835 writel(value, ioaddr + GMAC_L3L4_CTRL(filter_no)); 836 837 if (sa) { 838 writel(match, ioaddr + GMAC_L3_ADDR0(filter_no)); 839 } else { 840 writel(match, ioaddr + GMAC_L3_ADDR1(filter_no)); 841 } 842 843 if (!en) 844 writel(0, ioaddr + GMAC_L3L4_CTRL(filter_no)); 845 846 return 0; 847} 848 849static int dwmac4_config_l4_filter(struct mac_device_info *hw, u32 filter_no, 850 bool en, bool udp, bool sa, bool inv, 851 u32 match) 852{ 853 void __iomem *ioaddr = hw->pcsr; 854 u32 value; 855 856 value = readl(ioaddr + GMAC_PACKET_FILTER); 857 value |= GMAC_PACKET_FILTER_IPFE; 858 writel(value, ioaddr + GMAC_PACKET_FILTER); 859 860 value = readl(ioaddr + GMAC_L3L4_CTRL(filter_no)); 861 if (udp) { 862 value |= GMAC_L4PEN0; 863 } else { 864 value &= ~GMAC_L4PEN0; 865 } 866 867 value &= ~(GMAC_L4SPM0 | GMAC_L4SPIM0); 868 value &= ~(GMAC_L4DPM0 | GMAC_L4DPIM0); 869 if (sa) { 870 value |= GMAC_L4SPM0; 871 if (inv) 872 value |= GMAC_L4SPIM0; 873 } else { 874 value |= GMAC_L4DPM0; 875 if (inv) 876 value |= GMAC_L4DPIM0; 877 } 878 879 writel(value, ioaddr + GMAC_L3L4_CTRL(filter_no)); 880 881 if (sa) { 882 value = match & GMAC_L4SP0; 883 } else { 884 value = (match << GMAC_L4DP0_SHIFT) & GMAC_L4DP0; 885 } 886 887 writel(value, ioaddr + GMAC_L4_ADDR(filter_no)); 888 889 if (!en) 890 writel(0, ioaddr + GMAC_L3L4_CTRL(filter_no)); 891 892 return 0; 893} 894 895const struct stmmac_ops dwmac4_ops = { 896 .pcs_init = dwmac4_pcs_init, 897 .core_init = dwmac4_core_init, 898 .irq_modify = dwmac4_irq_modify, 899 .update_caps = dwmac4_update_caps, 900 .set_mac = stmmac_set_mac, 901 .rx_ipc = dwmac4_rx_ipc_enable, 902 .rx_queue_enable = dwmac4_rx_queue_enable, 903 .rx_queue_prio = dwmac4_rx_queue_priority, 904 .tx_queue_prio = dwmac4_tx_queue_priority, 905 .rx_queue_routing = dwmac4_rx_queue_routing, 906 .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, 907 .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, 908 .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, 909 .map_mtl_to_dma = dwmac4_map_mtl_dma, 910 .config_cbs = dwmac4_config_cbs, 911 .dump_regs = dwmac4_dump_regs, 912 .host_irq_status = dwmac4_irq_status, 913 .host_mtl_irq_status = dwmac4_irq_mtl_status, 914 .flow_ctrl = dwmac4_flow_ctrl, 915 .pmt = dwmac4_pmt, 916 .set_umac_addr = dwmac4_set_umac_addr, 917 .get_umac_addr = dwmac4_get_umac_addr, 918 .set_lpi_mode = dwmac4_set_lpi_mode, 919 .set_eee_timer = dwmac4_set_eee_timer, 920 .set_eee_pls = dwmac4_set_eee_pls, 921 .pcs_ctrl_ane = dwmac4_ctrl_ane, 922 .debug = dwmac4_debug, 923 .set_filter = dwmac4_set_filter, 924 .set_mac_loopback = dwmac4_set_mac_loopback, 925 .sarc_configure = dwmac4_sarc_configure, 926 .set_arp_offload = dwmac4_set_arp_offload, 927 .config_l3_filter = dwmac4_config_l3_filter, 928 .config_l4_filter = dwmac4_config_l4_filter, 929}; 930 931const struct stmmac_ops dwmac410_ops = { 932 .pcs_init = dwmac4_pcs_init, 933 .core_init = dwmac4_core_init, 934 .irq_modify = dwmac4_irq_modify, 935 .update_caps = dwmac4_update_caps, 936 .set_mac = stmmac_dwmac4_set_mac, 937 .rx_ipc = dwmac4_rx_ipc_enable, 938 .rx_queue_enable = dwmac4_rx_queue_enable, 939 .rx_queue_prio = dwmac4_rx_queue_priority, 940 .tx_queue_prio = dwmac4_tx_queue_priority, 941 .rx_queue_routing = dwmac4_rx_queue_routing, 942 .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, 943 .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, 944 .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, 945 .map_mtl_to_dma = dwmac4_map_mtl_dma, 946 .config_cbs = dwmac4_config_cbs, 947 .dump_regs = dwmac4_dump_regs, 948 .host_irq_status = dwmac4_irq_status, 949 .host_mtl_irq_status = dwmac4_irq_mtl_status, 950 .flow_ctrl = dwmac4_flow_ctrl, 951 .pmt = dwmac4_pmt, 952 .set_umac_addr = dwmac4_set_umac_addr, 953 .get_umac_addr = dwmac4_get_umac_addr, 954 .set_lpi_mode = dwmac4_set_lpi_mode, 955 .set_eee_timer = dwmac4_set_eee_timer, 956 .set_eee_pls = dwmac4_set_eee_pls, 957 .pcs_ctrl_ane = dwmac4_ctrl_ane, 958 .debug = dwmac4_debug, 959 .set_filter = dwmac4_set_filter, 960 .flex_pps_config = dwmac5_flex_pps_config, 961 .set_mac_loopback = dwmac4_set_mac_loopback, 962 .sarc_configure = dwmac4_sarc_configure, 963 .set_arp_offload = dwmac4_set_arp_offload, 964 .config_l3_filter = dwmac4_config_l3_filter, 965 .config_l4_filter = dwmac4_config_l4_filter, 966 .fpe_map_preemption_class = dwmac5_fpe_map_preemption_class, 967}; 968 969const struct stmmac_ops dwmac510_ops = { 970 .pcs_init = dwmac4_pcs_init, 971 .core_init = dwmac4_core_init, 972 .irq_modify = dwmac4_irq_modify, 973 .update_caps = dwmac4_update_caps, 974 .set_mac = stmmac_dwmac4_set_mac, 975 .rx_ipc = dwmac4_rx_ipc_enable, 976 .rx_queue_enable = dwmac4_rx_queue_enable, 977 .rx_queue_prio = dwmac4_rx_queue_priority, 978 .tx_queue_prio = dwmac4_tx_queue_priority, 979 .rx_queue_routing = dwmac4_rx_queue_routing, 980 .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, 981 .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, 982 .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, 983 .map_mtl_to_dma = dwmac4_map_mtl_dma, 984 .config_cbs = dwmac4_config_cbs, 985 .dump_regs = dwmac4_dump_regs, 986 .host_irq_status = dwmac4_irq_status, 987 .host_mtl_irq_status = dwmac4_irq_mtl_status, 988 .flow_ctrl = dwmac4_flow_ctrl, 989 .pmt = dwmac4_pmt, 990 .set_umac_addr = dwmac4_set_umac_addr, 991 .get_umac_addr = dwmac4_get_umac_addr, 992 .set_lpi_mode = dwmac4_set_lpi_mode, 993 .set_eee_timer = dwmac4_set_eee_timer, 994 .set_eee_pls = dwmac4_set_eee_pls, 995 .pcs_ctrl_ane = dwmac4_ctrl_ane, 996 .debug = dwmac4_debug, 997 .set_filter = dwmac4_set_filter, 998 .safety_feat_config = dwmac5_safety_feat_config, 999 .safety_feat_irq_status = dwmac5_safety_feat_irq_status, 1000 .safety_feat_dump = dwmac5_safety_feat_dump, 1001 .rxp_config = dwmac5_rxp_config, 1002 .flex_pps_config = dwmac5_flex_pps_config, 1003 .set_mac_loopback = dwmac4_set_mac_loopback, 1004 .sarc_configure = dwmac4_sarc_configure, 1005 .set_arp_offload = dwmac4_set_arp_offload, 1006 .config_l3_filter = dwmac4_config_l3_filter, 1007 .config_l4_filter = dwmac4_config_l4_filter, 1008 .fpe_map_preemption_class = dwmac5_fpe_map_preemption_class, 1009}; 1010 1011int dwmac4_setup(struct stmmac_priv *priv) 1012{ 1013 struct mac_device_info *mac = priv->hw; 1014 1015 dev_info(priv->device, "\tDWMAC4/5\n"); 1016 1017 priv->dev->priv_flags |= IFF_UNICAST_FLT; 1018 mac->pcsr = priv->ioaddr; 1019 mac->multicast_filter_bins = priv->plat->multicast_filter_bins; 1020 mac->unicast_filter_entries = priv->plat->unicast_filter_entries; 1021 mac->mcast_bits_log2 = 0; 1022 1023 if (mac->multicast_filter_bins) 1024 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins); 1025 1026 mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | 1027 MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; 1028 mac->link.duplex = GMAC_CONFIG_DM; 1029 mac->link.speed10 = GMAC_CONFIG_PS; 1030 mac->link.speed100 = GMAC_CONFIG_FES | GMAC_CONFIG_PS; 1031 mac->link.speed1000 = 0; 1032 mac->link.speed2500 = GMAC_CONFIG_FES; 1033 mac->link.speed_mask = GMAC_CONFIG_FES | GMAC_CONFIG_PS; 1034 mac->mii.addr = GMAC_MDIO_ADDR; 1035 mac->mii.data = GMAC_MDIO_DATA; 1036 mac->mii.addr_shift = 21; 1037 mac->mii.addr_mask = GENMASK(25, 21); 1038 mac->mii.reg_shift = 16; 1039 mac->mii.reg_mask = GENMASK(20, 16); 1040 mac->mii.clk_csr_shift = 8; 1041 mac->mii.clk_csr_mask = GENMASK(11, 8); 1042 mac->num_vlan = stmmac_get_num_vlan(priv->ioaddr); 1043 1044 return 0; 1045}
~/
Read-only file preview.