1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* 3 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates. 4 * stmmac XGMAC support. 5 */ 6 7 #include "stmmac.h" 8 #include "dwxgmac2.h" 9 10 static void dwxgmac2_core_init(struct mac_device_info *hw, 11 struct net_device *dev) 12 { 13 void __iomem *ioaddr = hw->pcsr; 14 int mtu = dev->mtu; 15 u32 tx, rx; 16 17 tx = readl(ioaddr + XGMAC_TX_CONFIG); 18 rx = readl(ioaddr + XGMAC_RX_CONFIG); 19 20 tx |= XGMAC_CORE_INIT_TX; 21 rx |= XGMAC_CORE_INIT_RX; 22 23 if (mtu >= 9000) { 24 rx |= XGMAC_CONFIG_GPSLCE; 25 rx |= XGMAC_JUMBO_LEN << XGMAC_CONFIG_GPSL_SHIFT; 26 rx |= XGMAC_CONFIG_WD; 27 } else if (mtu > 2000) { 28 rx |= XGMAC_CONFIG_JE; 29 } else if (mtu > 1500) { 30 rx |= XGMAC_CONFIG_S2KP; 31 } 32 33 if (hw->ps) { 34 tx |= XGMAC_CONFIG_TE; 35 tx &= ~hw->link.speed_mask; 36 37 switch (hw->ps) { 38 case SPEED_10000: 39 tx |= hw->link.xgmii.speed10000; 40 break; 41 case SPEED_2500: 42 tx |= hw->link.speed2500; 43 break; 44 case SPEED_1000: 45 default: 46 tx |= hw->link.speed1000; 47 break; 48 } 49 } 50 51 writel(tx, ioaddr + XGMAC_TX_CONFIG); 52 writel(rx, ioaddr + XGMAC_RX_CONFIG); 53 writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN); 54 } 55 56 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable) 57 { 58 u32 tx = readl(ioaddr + XGMAC_TX_CONFIG); 59 u32 rx = readl(ioaddr + XGMAC_RX_CONFIG); 60 61 if (enable) { 62 tx |= XGMAC_CONFIG_TE; 63 rx |= XGMAC_CONFIG_RE; 64 } else { 65 tx &= ~XGMAC_CONFIG_TE; 66 rx &= ~XGMAC_CONFIG_RE; 67 } 68 69 writel(tx, ioaddr + XGMAC_TX_CONFIG); 70 writel(rx, ioaddr + XGMAC_RX_CONFIG); 71 } 72 73 static int dwxgmac2_rx_ipc(struct mac_device_info *hw) 74 { 75 void __iomem *ioaddr = hw->pcsr; 76 u32 value; 77 78 value = readl(ioaddr + XGMAC_RX_CONFIG); 79 if (hw->rx_csum) 80 value |= XGMAC_CONFIG_IPC; 81 else 82 value &= ~XGMAC_CONFIG_IPC; 83 writel(value, ioaddr + XGMAC_RX_CONFIG); 84 85 return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC); 86 } 87 88 static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode, 89 u32 queue) 90 { 91 void __iomem *ioaddr = hw->pcsr; 92 u32 value; 93 94 value = readl(ioaddr + XGMAC_RXQ_CTRL0) & ~XGMAC_RXQEN(queue); 95 if (mode == MTL_QUEUE_AVB) 96 value |= 0x1 << XGMAC_RXQEN_SHIFT(queue); 97 else if (mode == MTL_QUEUE_DCB) 98 value |= 0x2 << XGMAC_RXQEN_SHIFT(queue); 99 writel(value, ioaddr + XGMAC_RXQ_CTRL0); 100 } 101 102 static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio, 103 u32 queue) 104 { 105 void __iomem *ioaddr = hw->pcsr; 106 u32 value, reg; 107 108 reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3; 109 110 value = readl(ioaddr + reg); 111 value &= ~XGMAC_PSRQ(queue); 112 value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue); 113 114 writel(value, ioaddr + reg); 115 } 116 117 static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw, 118 u32 rx_alg) 119 { 120 void __iomem *ioaddr = hw->pcsr; 121 u32 value; 122 123 value = readl(ioaddr + XGMAC_MTL_OPMODE); 124 value &= ~XGMAC_RAA; 125 126 switch (rx_alg) { 127 case MTL_RX_ALGORITHM_SP: 128 break; 129 case MTL_RX_ALGORITHM_WSP: 130 value |= XGMAC_RAA; 131 break; 132 default: 133 break; 134 } 135 136 writel(value, ioaddr + XGMAC_MTL_OPMODE); 137 } 138 139 static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw, 140 u32 tx_alg) 141 { 142 void __iomem *ioaddr = hw->pcsr; 143 u32 value; 144 145 value = readl(ioaddr + XGMAC_MTL_OPMODE); 146 value &= ~XGMAC_ETSALG; 147 148 switch (tx_alg) { 149 case MTL_TX_ALGORITHM_WRR: 150 value |= XGMAC_WRR; 151 break; 152 case MTL_TX_ALGORITHM_WFQ: 153 value |= XGMAC_WFQ; 154 break; 155 case MTL_TX_ALGORITHM_DWRR: 156 value |= XGMAC_DWRR; 157 break; 158 default: 159 break; 160 } 161 162 writel(value, ioaddr + XGMAC_MTL_OPMODE); 163 } 164 165 static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue, 166 u32 chan) 167 { 168 void __iomem *ioaddr = hw->pcsr; 169 u32 value, reg; 170 171 reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1; 172 173 value = readl(ioaddr + reg); 174 value &= ~XGMAC_QxMDMACH(queue); 175 value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue); 176 177 writel(value, ioaddr + reg); 178 } 179 180 static void dwxgmac2_config_cbs(struct mac_device_info *hw, 181 u32 send_slope, u32 idle_slope, 182 u32 high_credit, u32 low_credit, u32 queue) 183 { 184 void __iomem *ioaddr = hw->pcsr; 185 u32 value; 186 187 writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue)); 188 writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue)); 189 writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue)); 190 writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue)); 191 192 value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue)); 193 value |= XGMAC_CC | XGMAC_CBS; 194 writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue)); 195 } 196 197 static int dwxgmac2_host_irq_status(struct mac_device_info *hw, 198 struct stmmac_extra_stats *x) 199 { 200 void __iomem *ioaddr = hw->pcsr; 201 u32 stat, en; 202 203 en = readl(ioaddr + XGMAC_INT_EN); 204 stat = readl(ioaddr + XGMAC_INT_STATUS); 205 206 stat &= en; 207 208 if (stat & XGMAC_PMTIS) { 209 x->irq_receive_pmt_irq_n++; 210 readl(ioaddr + XGMAC_PMT); 211 } 212 213 return 0; 214 } 215 216 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan) 217 { 218 void __iomem *ioaddr = hw->pcsr; 219 int ret = 0; 220 u32 status; 221 222 status = readl(ioaddr + XGMAC_MTL_INT_STATUS); 223 if (status & BIT(chan)) { 224 u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan)); 225 226 if (chan_status & XGMAC_RXOVFIS) 227 ret |= CORE_IRQ_MTL_RX_OVERFLOW; 228 229 writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan)); 230 } 231 232 return ret; 233 } 234 235 static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, 236 unsigned int fc, unsigned int pause_time, 237 u32 tx_cnt) 238 { 239 void __iomem *ioaddr = hw->pcsr; 240 u32 i; 241 242 if (fc & FLOW_RX) 243 writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL); 244 if (fc & FLOW_TX) { 245 for (i = 0; i < tx_cnt; i++) { 246 u32 value = XGMAC_TFE; 247 248 if (duplex) 249 value |= pause_time << XGMAC_PT_SHIFT; 250 251 writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i)); 252 } 253 } 254 } 255 256 static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode) 257 { 258 void __iomem *ioaddr = hw->pcsr; 259 u32 val = 0x0; 260 261 if (mode & WAKE_MAGIC) 262 val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN; 263 if (mode & WAKE_UCAST) 264 val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN; 265 if (val) { 266 u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG); 267 cfg |= XGMAC_CONFIG_RE; 268 writel(cfg, ioaddr + XGMAC_RX_CONFIG); 269 } 270 271 writel(val, ioaddr + XGMAC_PMT); 272 } 273 274 static void dwxgmac2_set_umac_addr(struct mac_device_info *hw, 275 unsigned char *addr, unsigned int reg_n) 276 { 277 void __iomem *ioaddr = hw->pcsr; 278 u32 value; 279 280 value = (addr[5] << 8) | addr[4]; 281 writel(value | XGMAC_AE, ioaddr + XGMAC_ADDR0_HIGH); 282 283 value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 284 writel(value, ioaddr + XGMAC_ADDR0_LOW); 285 } 286 287 static void dwxgmac2_get_umac_addr(struct mac_device_info *hw, 288 unsigned char *addr, unsigned int reg_n) 289 { 290 void __iomem *ioaddr = hw->pcsr; 291 u32 hi_addr, lo_addr; 292 293 /* Read the MAC address from the hardware */ 294 hi_addr = readl(ioaddr + XGMAC_ADDR0_HIGH); 295 lo_addr = readl(ioaddr + XGMAC_ADDR0_LOW); 296 297 /* Extract the MAC address from the high and low words */ 298 addr[0] = lo_addr & 0xff; 299 addr[1] = (lo_addr >> 8) & 0xff; 300 addr[2] = (lo_addr >> 16) & 0xff; 301 addr[3] = (lo_addr >> 24) & 0xff; 302 addr[4] = hi_addr & 0xff; 303 addr[5] = (hi_addr >> 8) & 0xff; 304 } 305 306 static void dwxgmac2_set_filter(struct mac_device_info *hw, 307 struct net_device *dev) 308 { 309 void __iomem *ioaddr = (void __iomem *)dev->base_addr; 310 u32 value = XGMAC_FILTER_RA; 311 312 if (dev->flags & IFF_PROMISC) { 313 value |= XGMAC_FILTER_PR | XGMAC_FILTER_PCF; 314 } else if ((dev->flags & IFF_ALLMULTI) || 315 (netdev_mc_count(dev) > HASH_TABLE_SIZE)) { 316 value |= XGMAC_FILTER_PM; 317 writel(~0x0, ioaddr + XGMAC_HASH_TABLE(0)); 318 writel(~0x0, ioaddr + XGMAC_HASH_TABLE(1)); 319 } 320 321 writel(value, ioaddr + XGMAC_PACKET_FILTER); 322 } 323 324 static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable) 325 { 326 u32 value = readl(ioaddr + XGMAC_RX_CONFIG); 327 328 if (enable) 329 value |= XGMAC_CONFIG_LM; 330 else 331 value &= ~XGMAC_CONFIG_LM; 332 333 writel(value, ioaddr + XGMAC_RX_CONFIG); 334 } 335 336 const struct stmmac_ops dwxgmac210_ops = { 337 .core_init = dwxgmac2_core_init, 338 .set_mac = dwxgmac2_set_mac, 339 .rx_ipc = dwxgmac2_rx_ipc, 340 .rx_queue_enable = dwxgmac2_rx_queue_enable, 341 .rx_queue_prio = dwxgmac2_rx_queue_prio, 342 .tx_queue_prio = NULL, 343 .rx_queue_routing = NULL, 344 .prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms, 345 .prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms, 346 .set_mtl_tx_queue_weight = NULL, 347 .map_mtl_to_dma = dwxgmac2_map_mtl_to_dma, 348 .config_cbs = dwxgmac2_config_cbs, 349 .dump_regs = NULL, 350 .host_irq_status = dwxgmac2_host_irq_status, 351 .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status, 352 .flow_ctrl = dwxgmac2_flow_ctrl, 353 .pmt = dwxgmac2_pmt, 354 .set_umac_addr = dwxgmac2_set_umac_addr, 355 .get_umac_addr = dwxgmac2_get_umac_addr, 356 .set_eee_mode = NULL, 357 .reset_eee_mode = NULL, 358 .set_eee_timer = NULL, 359 .set_eee_pls = NULL, 360 .pcs_ctrl_ane = NULL, 361 .pcs_rane = NULL, 362 .pcs_get_adv_lp = NULL, 363 .debug = NULL, 364 .set_filter = dwxgmac2_set_filter, 365 .set_mac_loopback = dwxgmac2_set_mac_loopback, 366 }; 367 368 int dwxgmac2_setup(struct stmmac_priv *priv) 369 { 370 struct mac_device_info *mac = priv->hw; 371 372 dev_info(priv->device, "\tXGMAC2\n"); 373 374 priv->dev->priv_flags |= IFF_UNICAST_FLT; 375 mac->pcsr = priv->ioaddr; 376 mac->multicast_filter_bins = priv->plat->multicast_filter_bins; 377 mac->unicast_filter_entries = priv->plat->unicast_filter_entries; 378 mac->mcast_bits_log2 = 0; 379 380 if (mac->multicast_filter_bins) 381 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins); 382 383 mac->link.duplex = 0; 384 mac->link.speed10 = XGMAC_CONFIG_SS_10_MII; 385 mac->link.speed100 = XGMAC_CONFIG_SS_100_MII; 386 mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII; 387 mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII; 388 mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500; 389 mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000; 390 mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000; 391 mac->link.speed_mask = XGMAC_CONFIG_SS_MASK; 392 393 mac->mii.addr = XGMAC_MDIO_ADDR; 394 mac->mii.data = XGMAC_MDIO_DATA; 395 mac->mii.addr_shift = 16; 396 mac->mii.addr_mask = GENMASK(20, 16); 397 mac->mii.reg_shift = 0; 398 mac->mii.reg_mask = GENMASK(15, 0); 399 mac->mii.clk_csr_shift = 19; 400 mac->mii.clk_csr_mask = GENMASK(21, 19); 401 402 return 0; 403 } 404