1 /* 2 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> 3 * 4 * Intel Platform Controller Hub EG20T (codename Topcliff) GMAC Driver 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <errno.h> 11 #include <asm/io.h> 12 #include <pci.h> 13 #include <malloc.h> 14 #include <miiphy.h> 15 #include "pch_gbe.h" 16 17 #if !defined(CONFIG_PHYLIB) 18 # error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB" 19 #endif 20 21 static struct pci_device_id supported[] = { 22 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_GBE }, 23 { } 24 }; 25 26 static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr) 27 { 28 u32 macid_hi, macid_lo; 29 30 macid_hi = readl(&mac_regs->mac_adr[0].high); 31 macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff; 32 debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo); 33 34 addr[0] = (u8)(macid_hi & 0xff); 35 addr[1] = (u8)((macid_hi >> 8) & 0xff); 36 addr[2] = (u8)((macid_hi >> 16) & 0xff); 37 addr[3] = (u8)((macid_hi >> 24) & 0xff); 38 addr[4] = (u8)(macid_lo & 0xff); 39 addr[5] = (u8)((macid_lo >> 8) & 0xff); 40 } 41 42 static int pch_gbe_mac_write(struct pch_gbe_regs *mac_regs, u8 *addr) 43 { 44 u32 macid_hi, macid_lo; 45 ulong start; 46 47 macid_hi = addr[0] + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24); 48 macid_lo = addr[4] + (addr[5] << 8); 49 50 writel(macid_hi, &mac_regs->mac_adr[0].high); 51 writel(macid_lo, &mac_regs->mac_adr[0].low); 52 writel(0xfffe, &mac_regs->addr_mask); 53 54 start = get_timer(0); 55 while (get_timer(start) < PCH_GBE_TIMEOUT) { 56 if (!(readl(&mac_regs->addr_mask) & PCH_GBE_BUSY)) 57 return 0; 58 59 udelay(10); 60 } 61 62 return -ETIME; 63 } 64 65 static int pch_gbe_reset(struct eth_device *dev) 66 { 67 struct pch_gbe_priv *priv = dev->priv; 68 struct pch_gbe_regs *mac_regs = priv->mac_regs; 69 ulong start; 70 71 priv->rx_idx = 0; 72 priv->tx_idx = 0; 73 74 writel(PCH_GBE_ALL_RST, &mac_regs->reset); 75 76 /* 77 * Configure the MAC to RGMII mode after reset 78 * 79 * For some unknown reason, we must do the configuration here right 80 * after resetting the whole MAC, otherwise the reset bit in the RESET 81 * register will never be cleared by the hardware. And there is another 82 * way of having the same magic, that is to configure the MODE register 83 * to have the MAC work in MII/GMII mode, which is how current Linux 84 * pch_gbe driver does. Since anyway we need program the MAC to RGMII 85 * mode in the driver, we just do it here. 86 * 87 * Note: this behavior is not documented in the hardware manual. 88 */ 89 writel(PCH_GBE_RGMII_MODE_RGMII | PCH_GBE_CHIP_TYPE_INTERNAL, 90 &mac_regs->rgmii_ctrl); 91 92 start = get_timer(0); 93 while (get_timer(start) < PCH_GBE_TIMEOUT) { 94 if (!(readl(&mac_regs->reset) & PCH_GBE_ALL_RST)) { 95 /* 96 * Soft reset clears hardware MAC address registers, 97 * so we have to reload MAC address here in order to 98 * make linux pch_gbe driver happy. 99 */ 100 return pch_gbe_mac_write(mac_regs, dev->enetaddr); 101 } 102 103 udelay(10); 104 } 105 106 debug("pch_gbe: reset timeout\n"); 107 return -ETIME; 108 } 109 110 static void pch_gbe_rx_descs_init(struct eth_device *dev) 111 { 112 struct pch_gbe_priv *priv = dev->priv; 113 struct pch_gbe_regs *mac_regs = priv->mac_regs; 114 struct pch_gbe_rx_desc *rx_desc = &priv->rx_desc[0]; 115 int i; 116 117 memset(rx_desc, 0, sizeof(struct pch_gbe_rx_desc) * PCH_GBE_DESC_NUM); 118 for (i = 0; i < PCH_GBE_DESC_NUM; i++) 119 rx_desc->buffer_addr = pci_phys_to_mem(priv->bdf, 120 (u32)(priv->rx_buff[i])); 121 122 writel(pci_phys_to_mem(priv->bdf, (u32)rx_desc), 123 &mac_regs->rx_dsc_base); 124 writel(sizeof(struct pch_gbe_rx_desc) * (PCH_GBE_DESC_NUM - 1), 125 &mac_regs->rx_dsc_size); 126 127 writel(pci_phys_to_mem(priv->bdf, (u32)(rx_desc + 1)), 128 &mac_regs->rx_dsc_sw_p); 129 } 130 131 static void pch_gbe_tx_descs_init(struct eth_device *dev) 132 { 133 struct pch_gbe_priv *priv = dev->priv; 134 struct pch_gbe_regs *mac_regs = priv->mac_regs; 135 struct pch_gbe_tx_desc *tx_desc = &priv->tx_desc[0]; 136 137 memset(tx_desc, 0, sizeof(struct pch_gbe_tx_desc) * PCH_GBE_DESC_NUM); 138 139 writel(pci_phys_to_mem(priv->bdf, (u32)tx_desc), 140 &mac_regs->tx_dsc_base); 141 writel(sizeof(struct pch_gbe_tx_desc) * (PCH_GBE_DESC_NUM - 1), 142 &mac_regs->tx_dsc_size); 143 writel(pci_phys_to_mem(priv->bdf, (u32)(tx_desc + 1)), 144 &mac_regs->tx_dsc_sw_p); 145 } 146 147 static void pch_gbe_adjust_link(struct pch_gbe_regs *mac_regs, 148 struct phy_device *phydev) 149 { 150 if (!phydev->link) { 151 printf("%s: No link.\n", phydev->dev->name); 152 return; 153 } 154 155 clrbits_le32(&mac_regs->rgmii_ctrl, 156 PCH_GBE_RGMII_RATE_2_5M | PCH_GBE_CRS_SEL); 157 clrbits_le32(&mac_regs->mode, 158 PCH_GBE_MODE_GMII_ETHER | PCH_GBE_MODE_FULL_DUPLEX); 159 160 switch (phydev->speed) { 161 case 1000: 162 setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_125M); 163 setbits_le32(&mac_regs->mode, PCH_GBE_MODE_GMII_ETHER); 164 break; 165 case 100: 166 setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_25M); 167 setbits_le32(&mac_regs->mode, PCH_GBE_MODE_MII_ETHER); 168 break; 169 case 10: 170 setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_2_5M); 171 setbits_le32(&mac_regs->mode, PCH_GBE_MODE_MII_ETHER); 172 break; 173 } 174 175 if (phydev->duplex) { 176 setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_CRS_SEL); 177 setbits_le32(&mac_regs->mode, PCH_GBE_MODE_FULL_DUPLEX); 178 } 179 180 printf("Speed: %d, %s duplex\n", phydev->speed, 181 (phydev->duplex) ? "full" : "half"); 182 183 return; 184 } 185 186 static int pch_gbe_init(struct eth_device *dev, bd_t *bis) 187 { 188 struct pch_gbe_priv *priv = dev->priv; 189 struct pch_gbe_regs *mac_regs = priv->mac_regs; 190 191 if (pch_gbe_reset(dev)) 192 return -1; 193 194 pch_gbe_rx_descs_init(dev); 195 pch_gbe_tx_descs_init(dev); 196 197 /* Enable frame bursting */ 198 writel(PCH_GBE_MODE_FR_BST, &mac_regs->mode); 199 /* Disable TCP/IP accelerator */ 200 writel(PCH_GBE_RX_TCPIPACC_OFF, &mac_regs->tcpip_acc); 201 /* Disable RX flow control */ 202 writel(0, &mac_regs->rx_fctrl); 203 /* Configure RX/TX mode */ 204 writel(PCH_GBE_RH_ALM_EMP_16 | PCH_GBE_RH_ALM_FULL_16 | 205 PCH_GBE_RH_RD_TRG_32, &mac_regs->rx_mode); 206 writel(PCH_GBE_TM_TH_TX_STRT_32 | PCH_GBE_TM_TH_ALM_EMP_16 | 207 PCH_GBE_TM_TH_ALM_FULL_32 | PCH_GBE_TM_ST_AND_FD | 208 PCH_GBE_TM_SHORT_PKT, &mac_regs->tx_mode); 209 210 /* Start up the PHY */ 211 if (phy_startup(priv->phydev)) { 212 printf("Could not initialize PHY %s\n", 213 priv->phydev->dev->name); 214 return -1; 215 } 216 217 pch_gbe_adjust_link(mac_regs, priv->phydev); 218 219 if (!priv->phydev->link) 220 return -1; 221 222 /* Enable TX & RX */ 223 writel(PCH_GBE_RX_DMA_EN | PCH_GBE_TX_DMA_EN, &mac_regs->dma_ctrl); 224 writel(PCH_GBE_MRE_MAC_RX_EN, &mac_regs->mac_rx_en); 225 226 return 0; 227 } 228 229 static void pch_gbe_halt(struct eth_device *dev) 230 { 231 struct pch_gbe_priv *priv = dev->priv; 232 233 pch_gbe_reset(dev); 234 235 phy_shutdown(priv->phydev); 236 } 237 238 static int pch_gbe_send(struct eth_device *dev, void *packet, int length) 239 { 240 struct pch_gbe_priv *priv = dev->priv; 241 struct pch_gbe_regs *mac_regs = priv->mac_regs; 242 struct pch_gbe_tx_desc *tx_head, *tx_desc; 243 u16 frame_ctrl = 0; 244 u32 int_st; 245 ulong start; 246 247 tx_head = &priv->tx_desc[0]; 248 tx_desc = &priv->tx_desc[priv->tx_idx]; 249 250 if (length < 64) 251 frame_ctrl |= PCH_GBE_TXD_CTRL_APAD; 252 253 tx_desc->buffer_addr = pci_phys_to_mem(priv->bdf, (u32)packet); 254 tx_desc->length = length; 255 tx_desc->tx_words_eob = length + 3; 256 tx_desc->tx_frame_ctrl = frame_ctrl; 257 tx_desc->dma_status = 0; 258 tx_desc->gbec_status = 0; 259 260 /* Test the wrap-around condition */ 261 if (++priv->tx_idx >= PCH_GBE_DESC_NUM) 262 priv->tx_idx = 0; 263 264 writel(pci_phys_to_mem(priv->bdf, (u32)(tx_head + priv->tx_idx)), 265 &mac_regs->tx_dsc_sw_p); 266 267 start = get_timer(0); 268 while (get_timer(start) < PCH_GBE_TIMEOUT) { 269 int_st = readl(&mac_regs->int_st); 270 if (int_st & PCH_GBE_INT_TX_CMPLT) 271 return 0; 272 273 udelay(10); 274 } 275 276 debug("pch_gbe: sent failed\n"); 277 return -ETIME; 278 } 279 280 static int pch_gbe_recv(struct eth_device *dev) 281 { 282 struct pch_gbe_priv *priv = dev->priv; 283 struct pch_gbe_regs *mac_regs = priv->mac_regs; 284 struct pch_gbe_rx_desc *rx_head, *rx_desc; 285 u32 hw_desc, buffer_addr, length; 286 int rx_swp; 287 288 rx_head = &priv->rx_desc[0]; 289 rx_desc = &priv->rx_desc[priv->rx_idx]; 290 291 readl(&mac_regs->int_st); 292 hw_desc = readl(&mac_regs->rx_dsc_hw_p_hld); 293 294 /* Just return if not receiving any packet */ 295 if ((u32)rx_desc == hw_desc) 296 return 0; 297 298 buffer_addr = pci_mem_to_phys(priv->bdf, rx_desc->buffer_addr); 299 length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN; 300 NetReceive((uchar *)buffer_addr, length); 301 302 /* Test the wrap-around condition */ 303 if (++priv->rx_idx >= PCH_GBE_DESC_NUM) 304 priv->rx_idx = 0; 305 rx_swp = priv->rx_idx; 306 if (++rx_swp >= PCH_GBE_DESC_NUM) 307 rx_swp = 0; 308 309 writel(pci_phys_to_mem(priv->bdf, (u32)(rx_head + rx_swp)), 310 &mac_regs->rx_dsc_sw_p); 311 312 return length; 313 } 314 315 static int pch_gbe_mdio_ready(struct pch_gbe_regs *mac_regs) 316 { 317 ulong start = get_timer(0); 318 319 while (get_timer(start) < PCH_GBE_TIMEOUT) { 320 if (readl(&mac_regs->miim) & PCH_GBE_MIIM_OPER_READY) 321 return 0; 322 323 udelay(10); 324 } 325 326 return -ETIME; 327 } 328 329 static int pch_gbe_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) 330 { 331 struct pch_gbe_regs *mac_regs = bus->priv; 332 u32 miim; 333 334 if (pch_gbe_mdio_ready(mac_regs)) 335 return -ETIME; 336 337 miim = (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) | 338 (reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) | 339 PCH_GBE_MIIM_OPER_READ; 340 writel(miim, &mac_regs->miim); 341 342 if (pch_gbe_mdio_ready(mac_regs)) 343 return -ETIME; 344 345 return readl(&mac_regs->miim) & 0xffff; 346 } 347 348 static int pch_gbe_mdio_write(struct mii_dev *bus, int addr, int devad, 349 int reg, u16 val) 350 { 351 struct pch_gbe_regs *mac_regs = bus->priv; 352 u32 miim; 353 354 if (pch_gbe_mdio_ready(mac_regs)) 355 return -ETIME; 356 357 miim = (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) | 358 (reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) | 359 PCH_GBE_MIIM_OPER_WRITE | val; 360 writel(miim, &mac_regs->miim); 361 362 if (pch_gbe_mdio_ready(mac_regs)) 363 return -ETIME; 364 else 365 return 0; 366 } 367 368 static int pch_gbe_mdio_init(char *name, struct pch_gbe_regs *mac_regs) 369 { 370 struct mii_dev *bus; 371 372 bus = mdio_alloc(); 373 if (!bus) { 374 debug("pch_gbe: failed to allocate MDIO bus\n"); 375 return -ENOMEM; 376 } 377 378 bus->read = pch_gbe_mdio_read; 379 bus->write = pch_gbe_mdio_write; 380 sprintf(bus->name, name); 381 382 bus->priv = (void *)mac_regs; 383 384 return mdio_register(bus); 385 } 386 387 static int pch_gbe_phy_init(struct eth_device *dev) 388 { 389 struct pch_gbe_priv *priv = dev->priv; 390 struct phy_device *phydev; 391 int mask = 0xffffffff; 392 393 phydev = phy_find_by_mask(priv->bus, mask, priv->interface); 394 if (!phydev) { 395 printf("pch_gbe: cannot find the phy\n"); 396 return -1; 397 } 398 399 phy_connect_dev(phydev, dev); 400 401 phydev->supported &= PHY_GBIT_FEATURES; 402 phydev->advertising = phydev->supported; 403 404 priv->phydev = phydev; 405 phy_config(phydev); 406 407 return 1; 408 } 409 410 int pch_gbe_register(bd_t *bis) 411 { 412 struct eth_device *dev; 413 struct pch_gbe_priv *priv; 414 pci_dev_t devno; 415 u32 iobase; 416 417 devno = pci_find_devices(supported, 0); 418 if (devno == -1) 419 return -ENODEV; 420 421 dev = (struct eth_device *)malloc(sizeof(*dev)); 422 if (!dev) 423 return -ENOMEM; 424 memset(dev, 0, sizeof(*dev)); 425 426 /* 427 * The priv structure contains the descriptors and frame buffers which 428 * need a strict buswidth alignment (64 bytes) 429 */ 430 priv = (struct pch_gbe_priv *)memalign(PCH_GBE_ALIGN_SIZE, 431 sizeof(*priv)); 432 if (!priv) { 433 free(dev); 434 return -ENOMEM; 435 } 436 memset(priv, 0, sizeof(*priv)); 437 438 dev->priv = priv; 439 priv->dev = dev; 440 priv->bdf = devno; 441 442 pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); 443 iobase &= PCI_BASE_ADDRESS_MEM_MASK; 444 iobase = pci_mem_to_phys(devno, iobase); 445 446 dev->iobase = iobase; 447 priv->mac_regs = (struct pch_gbe_regs *)iobase; 448 449 sprintf(dev->name, "pch_gbe.%x", iobase); 450 451 /* Read MAC address from SROM and initialize dev->enetaddr with it */ 452 pch_gbe_mac_read(priv->mac_regs, dev->enetaddr); 453 454 dev->init = pch_gbe_init; 455 dev->halt = pch_gbe_halt; 456 dev->send = pch_gbe_send; 457 dev->recv = pch_gbe_recv; 458 459 eth_register(dev); 460 461 priv->interface = PHY_INTERFACE_MODE_RGMII; 462 pch_gbe_mdio_init(dev->name, priv->mac_regs); 463 priv->bus = miiphy_get_dev_by_name(dev->name); 464 465 return pch_gbe_phy_init(dev); 466 } 467