1028 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* Applied Micro X-Gene SoC Ethernet Driver3 *4 * Copyright (c) 2014, Applied Micro Circuits Corporation5 * Authors: Iyappan Subramanian <isubramanian@apm.com>6 * Ravi Patel <rapatel@apm.com>7 * Keyur Chudgar <kchudgar@apm.com>8 */9 10#include "xgene_enet_main.h"11#include "xgene_enet_hw.h"12 13static void xgene_enet_ring_init(struct xgene_enet_desc_ring *ring)14{15 u32 *ring_cfg = ring->state;16 u64 addr = ring->dma;17 enum xgene_enet_ring_cfgsize cfgsize = ring->cfgsize;18 19 ring_cfg[4] |= (1 << SELTHRSH_POS) &20 CREATE_MASK(SELTHRSH_POS, SELTHRSH_LEN);21 ring_cfg[3] |= ACCEPTLERR;22 ring_cfg[2] |= QCOHERENT;23 24 addr >>= 8;25 ring_cfg[2] |= (addr << RINGADDRL_POS) &26 CREATE_MASK_ULL(RINGADDRL_POS, RINGADDRL_LEN);27 addr >>= RINGADDRL_LEN;28 ring_cfg[3] |= addr & CREATE_MASK_ULL(RINGADDRH_POS, RINGADDRH_LEN);29 ring_cfg[3] |= ((u32)cfgsize << RINGSIZE_POS) &30 CREATE_MASK(RINGSIZE_POS, RINGSIZE_LEN);31}32 33static void xgene_enet_ring_set_type(struct xgene_enet_desc_ring *ring)34{35 u32 *ring_cfg = ring->state;36 bool is_bufpool;37 u32 val;38 39 is_bufpool = xgene_enet_is_bufpool(ring->id);40 val = (is_bufpool) ? RING_BUFPOOL : RING_REGULAR;41 ring_cfg[4] |= (val << RINGTYPE_POS) &42 CREATE_MASK(RINGTYPE_POS, RINGTYPE_LEN);43 44 if (is_bufpool) {45 ring_cfg[3] |= (BUFPOOL_MODE << RINGMODE_POS) &46 CREATE_MASK(RINGMODE_POS, RINGMODE_LEN);47 }48}49 50static void xgene_enet_ring_set_recombbuf(struct xgene_enet_desc_ring *ring)51{52 u32 *ring_cfg = ring->state;53 54 ring_cfg[3] |= RECOMBBUF;55 ring_cfg[3] |= (0xf << RECOMTIMEOUTL_POS) &56 CREATE_MASK(RECOMTIMEOUTL_POS, RECOMTIMEOUTL_LEN);57 ring_cfg[4] |= 0x7 & CREATE_MASK(RECOMTIMEOUTH_POS, RECOMTIMEOUTH_LEN);58}59 60static void xgene_enet_ring_wr32(struct xgene_enet_desc_ring *ring,61 u32 offset, u32 data)62{63 struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);64 65 iowrite32(data, pdata->ring_csr_addr + offset);66}67 68static void xgene_enet_ring_rd32(struct xgene_enet_desc_ring *ring,69 u32 offset, u32 *data)70{71 struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);72 73 *data = ioread32(pdata->ring_csr_addr + offset);74}75 76static void xgene_enet_write_ring_state(struct xgene_enet_desc_ring *ring)77{78 struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);79 int i;80 81 xgene_enet_ring_wr32(ring, CSR_RING_CONFIG, ring->num);82 for (i = 0; i < pdata->ring_ops->num_ring_config; i++) {83 xgene_enet_ring_wr32(ring, CSR_RING_WR_BASE + (i * 4),84 ring->state[i]);85 }86}87 88static void xgene_enet_clr_ring_state(struct xgene_enet_desc_ring *ring)89{90 memset(ring->state, 0, sizeof(ring->state));91 xgene_enet_write_ring_state(ring);92}93 94static void xgene_enet_set_ring_state(struct xgene_enet_desc_ring *ring)95{96 xgene_enet_ring_set_type(ring);97 98 if (xgene_enet_ring_owner(ring->id) == RING_OWNER_ETH0 ||99 xgene_enet_ring_owner(ring->id) == RING_OWNER_ETH1)100 xgene_enet_ring_set_recombbuf(ring);101 102 xgene_enet_ring_init(ring);103 xgene_enet_write_ring_state(ring);104}105 106static void xgene_enet_set_ring_id(struct xgene_enet_desc_ring *ring)107{108 u32 ring_id_val, ring_id_buf;109 bool is_bufpool;110 111 is_bufpool = xgene_enet_is_bufpool(ring->id);112 113 ring_id_val = ring->id & GENMASK(9, 0);114 ring_id_val |= OVERWRITE;115 116 ring_id_buf = (ring->num << 9) & GENMASK(18, 9);117 ring_id_buf |= PREFETCH_BUF_EN;118 if (is_bufpool)119 ring_id_buf |= IS_BUFFER_POOL;120 121 xgene_enet_ring_wr32(ring, CSR_RING_ID, ring_id_val);122 xgene_enet_ring_wr32(ring, CSR_RING_ID_BUF, ring_id_buf);123}124 125static void xgene_enet_clr_desc_ring_id(struct xgene_enet_desc_ring *ring)126{127 u32 ring_id;128 129 ring_id = ring->id | OVERWRITE;130 xgene_enet_ring_wr32(ring, CSR_RING_ID, ring_id);131 xgene_enet_ring_wr32(ring, CSR_RING_ID_BUF, 0);132}133 134static struct xgene_enet_desc_ring *xgene_enet_setup_ring(135 struct xgene_enet_desc_ring *ring)136{137 u32 size = ring->size;138 u32 i, data;139 bool is_bufpool;140 141 xgene_enet_clr_ring_state(ring);142 xgene_enet_set_ring_state(ring);143 xgene_enet_set_ring_id(ring);144 145 ring->slots = xgene_enet_get_numslots(ring->id, size);146 147 is_bufpool = xgene_enet_is_bufpool(ring->id);148 if (is_bufpool || xgene_enet_ring_owner(ring->id) != RING_OWNER_CPU)149 return ring;150 151 for (i = 0; i < ring->slots; i++)152 xgene_enet_mark_desc_slot_empty(&ring->raw_desc[i]);153 154 xgene_enet_ring_rd32(ring, CSR_RING_NE_INT_MODE, &data);155 data |= BIT(31 - xgene_enet_ring_bufnum(ring->id));156 xgene_enet_ring_wr32(ring, CSR_RING_NE_INT_MODE, data);157 158 return ring;159}160 161static void xgene_enet_clear_ring(struct xgene_enet_desc_ring *ring)162{163 u32 data;164 bool is_bufpool;165 166 is_bufpool = xgene_enet_is_bufpool(ring->id);167 if (is_bufpool || xgene_enet_ring_owner(ring->id) != RING_OWNER_CPU)168 goto out;169 170 xgene_enet_ring_rd32(ring, CSR_RING_NE_INT_MODE, &data);171 data &= ~BIT(31 - xgene_enet_ring_bufnum(ring->id));172 xgene_enet_ring_wr32(ring, CSR_RING_NE_INT_MODE, data);173 174out:175 xgene_enet_clr_desc_ring_id(ring);176 xgene_enet_clr_ring_state(ring);177}178 179static void xgene_enet_wr_cmd(struct xgene_enet_desc_ring *ring, int count)180{181 iowrite32(count, ring->cmd);182}183 184static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring)185{186 u32 __iomem *cmd_base = ring->cmd_base;187 u32 ring_state, num_msgs;188 189 ring_state = ioread32(&cmd_base[1]);190 num_msgs = GET_VAL(NUMMSGSINQ, ring_state);191 192 return num_msgs;193}194 195void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,196 enum xgene_enet_err_code status)197{198 switch (status) {199 case INGRESS_CRC:200 ring->rx_crc_errors++;201 break;202 case INGRESS_CHECKSUM:203 case INGRESS_CHECKSUM_COMPUTE:204 ring->rx_errors++;205 break;206 case INGRESS_TRUNC_FRAME:207 ring->rx_frame_errors++;208 break;209 case INGRESS_PKT_LEN:210 ring->rx_length_errors++;211 break;212 case INGRESS_PKT_UNDER:213 ring->rx_frame_errors++;214 break;215 case INGRESS_FIFO_OVERRUN:216 ring->rx_fifo_errors++;217 break;218 default:219 break;220 }221}222 223static void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata,224 u32 offset, u32 val)225{226 void __iomem *addr = pdata->eth_csr_addr + offset;227 228 iowrite32(val, addr);229}230 231static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *pdata,232 u32 offset, u32 val)233{234 void __iomem *addr = pdata->eth_ring_if_addr + offset;235 236 iowrite32(val, addr);237}238 239static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *pdata,240 u32 offset, u32 val)241{242 void __iomem *addr = pdata->eth_diag_csr_addr + offset;243 244 iowrite32(val, addr);245}246 247static void xgene_enet_wr_mcx_csr(struct xgene_enet_pdata *pdata,248 u32 offset, u32 val)249{250 void __iomem *addr = pdata->mcx_mac_csr_addr + offset;251 252 iowrite32(val, addr);253}254 255void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata, u32 wr_addr, u32 wr_data)256{257 void __iomem *addr, *wr, *cmd, *cmd_done;258 struct net_device *ndev = pdata->ndev;259 u8 wait = 10;260 u32 done;261 262 if (pdata->mdio_driver && ndev->phydev &&263 phy_interface_mode_is_rgmii(pdata->phy_mode)) {264 struct mii_bus *bus = ndev->phydev->mdio.bus;265 266 return xgene_mdio_wr_mac(bus->priv, wr_addr, wr_data);267 }268 269 addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;270 wr = pdata->mcx_mac_addr + MAC_WRITE_REG_OFFSET;271 cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;272 cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;273 274 spin_lock(&pdata->mac_lock);275 iowrite32(wr_addr, addr);276 iowrite32(wr_data, wr);277 iowrite32(XGENE_ENET_WR_CMD, cmd);278 279 while (!(done = ioread32(cmd_done)) && wait--)280 udelay(1);281 282 if (!done)283 netdev_err(ndev, "mac write failed, addr: %04x data: %08x\n",284 wr_addr, wr_data);285 286 iowrite32(0, cmd);287 spin_unlock(&pdata->mac_lock);288}289 290static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,291 u32 offset, u32 *val)292{293 void __iomem *addr = pdata->eth_csr_addr + offset;294 295 *val = ioread32(addr);296}297 298static void xgene_enet_rd_diag_csr(struct xgene_enet_pdata *pdata,299 u32 offset, u32 *val)300{301 void __iomem *addr = pdata->eth_diag_csr_addr + offset;302 303 *val = ioread32(addr);304}305 306static void xgene_enet_rd_mcx_csr(struct xgene_enet_pdata *pdata,307 u32 offset, u32 *val)308{309 void __iomem *addr = pdata->mcx_mac_csr_addr + offset;310 311 *val = ioread32(addr);312}313 314u32 xgene_enet_rd_mac(struct xgene_enet_pdata *pdata, u32 rd_addr)315{316 void __iomem *addr, *rd, *cmd, *cmd_done;317 struct net_device *ndev = pdata->ndev;318 u32 done, rd_data;319 u8 wait = 10;320 321 if (pdata->mdio_driver && ndev->phydev &&322 phy_interface_mode_is_rgmii(pdata->phy_mode)) {323 struct mii_bus *bus = ndev->phydev->mdio.bus;324 325 return xgene_mdio_rd_mac(bus->priv, rd_addr);326 }327 328 addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;329 rd = pdata->mcx_mac_addr + MAC_READ_REG_OFFSET;330 cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;331 cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;332 333 spin_lock(&pdata->mac_lock);334 iowrite32(rd_addr, addr);335 iowrite32(XGENE_ENET_RD_CMD, cmd);336 337 while (!(done = ioread32(cmd_done)) && wait--)338 udelay(1);339 340 if (!done)341 netdev_err(ndev, "mac read failed, addr: %04x\n", rd_addr);342 343 rd_data = ioread32(rd);344 iowrite32(0, cmd);345 spin_unlock(&pdata->mac_lock);346 347 return rd_data;348}349 350u32 xgene_enet_rd_stat(struct xgene_enet_pdata *pdata, u32 rd_addr)351{352 void __iomem *addr, *rd, *cmd, *cmd_done;353 u32 done, rd_data;354 u8 wait = 10;355 356 addr = pdata->mcx_stats_addr + STAT_ADDR_REG_OFFSET;357 rd = pdata->mcx_stats_addr + STAT_READ_REG_OFFSET;358 cmd = pdata->mcx_stats_addr + STAT_COMMAND_REG_OFFSET;359 cmd_done = pdata->mcx_stats_addr + STAT_COMMAND_DONE_REG_OFFSET;360 361 spin_lock(&pdata->stats_lock);362 iowrite32(rd_addr, addr);363 iowrite32(XGENE_ENET_RD_CMD, cmd);364 365 while (!(done = ioread32(cmd_done)) && wait--)366 udelay(1);367 368 if (!done)369 netdev_err(pdata->ndev, "mac stats read failed, addr: %04x\n",370 rd_addr);371 372 rd_data = ioread32(rd);373 iowrite32(0, cmd);374 spin_unlock(&pdata->stats_lock);375 376 return rd_data;377}378 379static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)380{381 const u8 *dev_addr = pdata->ndev->dev_addr;382 u32 addr0, addr1;383 384 addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |385 (dev_addr[1] << 8) | dev_addr[0];386 addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16);387 388 xgene_enet_wr_mac(pdata, STATION_ADDR0_ADDR, addr0);389 xgene_enet_wr_mac(pdata, STATION_ADDR1_ADDR, addr1);390}391 392static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)393{394 struct net_device *ndev = pdata->ndev;395 u32 data;396 u8 wait = 10;397 398 xgene_enet_wr_diag_csr(pdata, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0x0);399 do {400 usleep_range(100, 110);401 xgene_enet_rd_diag_csr(pdata, ENET_BLOCK_MEM_RDY_ADDR, &data);402 } while ((data != 0xffffffff) && wait--);403 404 if (data != 0xffffffff) {405 netdev_err(ndev, "Failed to release memory from shutdown\n");406 return -ENODEV;407 }408 409 return 0;410}411 412static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)413{414 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);415 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, 0);416}417 418static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)419{420 struct device *dev = &pdata->pdev->dev;421 422 if (dev->of_node) {423 struct clk *parent = clk_get_parent(pdata->clk);424 425 switch (pdata->phy_speed) {426 case SPEED_10:427 clk_set_rate(parent, 2500000);428 break;429 case SPEED_100:430 clk_set_rate(parent, 25000000);431 break;432 default:433 clk_set_rate(parent, 125000000);434 break;435 }436 }437#ifdef CONFIG_ACPI438 else {439 switch (pdata->phy_speed) {440 case SPEED_10:441 acpi_evaluate_object(ACPI_HANDLE(dev),442 "S10", NULL, NULL);443 break;444 case SPEED_100:445 acpi_evaluate_object(ACPI_HANDLE(dev),446 "S100", NULL, NULL);447 break;448 default:449 acpi_evaluate_object(ACPI_HANDLE(dev),450 "S1G", NULL, NULL);451 break;452 }453 }454#endif455}456 457static void xgene_gmac_set_speed(struct xgene_enet_pdata *pdata)458{459 u32 icm0, icm2, mc2;460 u32 intf_ctl, rgmii, value;461 462 xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, &icm0);463 xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, &icm2);464 mc2 = xgene_enet_rd_mac(pdata, MAC_CONFIG_2_ADDR);465 intf_ctl = xgene_enet_rd_mac(pdata, INTERFACE_CONTROL_ADDR);466 xgene_enet_rd_csr(pdata, RGMII_REG_0_ADDR, &rgmii);467 468 switch (pdata->phy_speed) {469 case SPEED_10:470 ENET_INTERFACE_MODE2_SET(&mc2, 1);471 intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE);472 CFG_MACMODE_SET(&icm0, 0);473 CFG_WAITASYNCRD_SET(&icm2, 500);474 rgmii &= ~CFG_SPEED_1250;475 break;476 case SPEED_100:477 ENET_INTERFACE_MODE2_SET(&mc2, 1);478 intf_ctl &= ~ENET_GHD_MODE;479 intf_ctl |= ENET_LHD_MODE;480 CFG_MACMODE_SET(&icm0, 1);481 CFG_WAITASYNCRD_SET(&icm2, 80);482 rgmii &= ~CFG_SPEED_1250;483 break;484 default:485 ENET_INTERFACE_MODE2_SET(&mc2, 2);486 intf_ctl &= ~ENET_LHD_MODE;487 intf_ctl |= ENET_GHD_MODE;488 CFG_MACMODE_SET(&icm0, 2);489 CFG_WAITASYNCRD_SET(&icm2, 0);490 CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay);491 CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay);492 rgmii |= CFG_SPEED_1250;493 494 xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value);495 value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;496 xgene_enet_wr_csr(pdata, DEBUG_REG_ADDR, value);497 break;498 }499 500 mc2 |= FULL_DUPLEX2 | PAD_CRC | LENGTH_CHK;501 xgene_enet_wr_mac(pdata, MAC_CONFIG_2_ADDR, mc2);502 xgene_enet_wr_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);503 xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii);504 xgene_enet_configure_clock(pdata);505 506 xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, icm0);507 xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, icm2);508}509 510static void xgene_enet_set_frame_size(struct xgene_enet_pdata *pdata, int size)511{512 xgene_enet_wr_mac(pdata, MAX_FRAME_LEN_ADDR, size);513}514 515static void xgene_gmac_enable_tx_pause(struct xgene_enet_pdata *pdata,516 bool enable)517{518 u32 data;519 520 xgene_enet_rd_mcx_csr(pdata, CSR_ECM_CFG_0_ADDR, &data);521 522 if (enable)523 data |= MULTI_DPF_AUTOCTRL | PAUSE_XON_EN;524 else525 data &= ~(MULTI_DPF_AUTOCTRL | PAUSE_XON_EN);526 527 xgene_enet_wr_mcx_csr(pdata, CSR_ECM_CFG_0_ADDR, data);528}529 530static void xgene_gmac_flowctl_tx(struct xgene_enet_pdata *pdata, bool enable)531{532 u32 data;533 534 data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);535 536 if (enable)537 data |= TX_FLOW_EN;538 else539 data &= ~TX_FLOW_EN;540 541 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data);542 543 pdata->mac_ops->enable_tx_pause(pdata, enable);544}545 546static void xgene_gmac_flowctl_rx(struct xgene_enet_pdata *pdata, bool enable)547{548 u32 data;549 550 data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);551 552 if (enable)553 data |= RX_FLOW_EN;554 else555 data &= ~RX_FLOW_EN;556 557 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data);558}559 560static void xgene_gmac_init(struct xgene_enet_pdata *pdata)561{562 u32 value;563 564 if (!pdata->mdio_driver)565 xgene_gmac_reset(pdata);566 567 xgene_gmac_set_speed(pdata);568 xgene_gmac_set_mac_addr(pdata);569 570 /* Adjust MDC clock frequency */571 value = xgene_enet_rd_mac(pdata, MII_MGMT_CONFIG_ADDR);572 MGMT_CLOCK_SEL_SET(&value, 7);573 xgene_enet_wr_mac(pdata, MII_MGMT_CONFIG_ADDR, value);574 575 /* Enable drop if bufpool not available */576 xgene_enet_rd_csr(pdata, RSIF_CONFIG_REG_ADDR, &value);577 value |= CFG_RSIF_FPBUFF_TIMEOUT_EN;578 xgene_enet_wr_csr(pdata, RSIF_CONFIG_REG_ADDR, value);579 580 /* Rtype should be copied from FP */581 xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0);582 583 /* Configure HW pause frame generation */584 xgene_enet_rd_mcx_csr(pdata, CSR_MULTI_DPF0_ADDR, &value);585 value = (DEF_QUANTA << 16) | (value & 0xFFFF);586 xgene_enet_wr_mcx_csr(pdata, CSR_MULTI_DPF0_ADDR, value);587 588 xgene_enet_wr_csr(pdata, RXBUF_PAUSE_THRESH, DEF_PAUSE_THRES);589 xgene_enet_wr_csr(pdata, RXBUF_PAUSE_OFF_THRESH, DEF_PAUSE_OFF_THRES);590 591 xgene_gmac_flowctl_tx(pdata, pdata->tx_pause);592 xgene_gmac_flowctl_rx(pdata, pdata->rx_pause);593 594 /* Rx-Tx traffic resume */595 xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);596 597 xgene_enet_rd_mcx_csr(pdata, RX_DV_GATE_REG_0_ADDR, &value);598 value &= ~TX_DV_GATE_EN0;599 value &= ~RX_DV_GATE_EN0;600 value |= RESUME_RX0;601 xgene_enet_wr_mcx_csr(pdata, RX_DV_GATE_REG_0_ADDR, value);602 603 xgene_enet_wr_csr(pdata, CFG_BYPASS_ADDR, RESUME_TX);604}605 606static void xgene_gmac_get_drop_cnt(struct xgene_enet_pdata *pdata,607 u32 *rx, u32 *tx)608{609 u32 count;610 611 xgene_enet_rd_mcx_csr(pdata, ICM_ECM_DROP_COUNT_REG0_ADDR, &count);612 *rx = ICM_DROP_COUNT(count);613 *tx = ECM_DROP_COUNT(count);614 /* Errata: 10GE_4 - Fix ICM_ECM_DROP_COUNT not clear-on-read */615 xgene_enet_rd_mcx_csr(pdata, ECM_CONFIG0_REG_0_ADDR, &count);616}617 618static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata)619{620 u32 val = 0xffffffff;621 622 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQASSOC_ADDR, val);623 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPQASSOC_ADDR, val);624 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEWQASSOC_ADDR, val);625 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEFPQASSOC_ADDR, val);626}627 628static void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,629 u32 dst_ring_num, u16 bufpool_id,630 u16 nxtbufpool_id)631{632 u32 cb;633 u32 fpsel, nxtfpsel;634 635 fpsel = xgene_enet_get_fpsel(bufpool_id);636 nxtfpsel = xgene_enet_get_fpsel(nxtbufpool_id);637 638 xgene_enet_rd_csr(pdata, CLE_BYPASS_REG0_0_ADDR, &cb);639 cb |= CFG_CLE_BYPASS_EN0;640 CFG_CLE_IP_PROTOCOL0_SET(&cb, 3);641 CFG_CLE_IP_HDR_LEN_SET(&cb, 0);642 xgene_enet_wr_csr(pdata, CLE_BYPASS_REG0_0_ADDR, cb);643 644 xgene_enet_rd_csr(pdata, CLE_BYPASS_REG1_0_ADDR, &cb);645 CFG_CLE_DSTQID0_SET(&cb, dst_ring_num);646 CFG_CLE_FPSEL0_SET(&cb, fpsel);647 CFG_CLE_NXTFPSEL0_SET(&cb, nxtfpsel);648 xgene_enet_wr_csr(pdata, CLE_BYPASS_REG1_0_ADDR, cb);649}650 651static void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)652{653 u32 data;654 655 data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);656 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);657}658 659static void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)660{661 u32 data;662 663 data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);664 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);665}666 667static void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)668{669 u32 data;670 671 data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);672 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);673}674 675static void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)676{677 u32 data;678 679 data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);680 xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);681}682 683bool xgene_ring_mgr_init(struct xgene_enet_pdata *p)684{685 if (!ioread32(p->ring_csr_addr + CLKEN_ADDR))686 return false;687 688 if (ioread32(p->ring_csr_addr + SRST_ADDR))689 return false;690 691 return true;692}693 694static int xgene_enet_reset(struct xgene_enet_pdata *pdata)695{696 struct device *dev = &pdata->pdev->dev;697 698 if (!xgene_ring_mgr_init(pdata))699 return -ENODEV;700 701 if (pdata->mdio_driver) {702 xgene_enet_config_ring_if_assoc(pdata);703 return 0;704 }705 706 if (dev->of_node) {707 clk_prepare_enable(pdata->clk);708 udelay(5);709 clk_disable_unprepare(pdata->clk);710 udelay(5);711 clk_prepare_enable(pdata->clk);712 udelay(5);713 } else {714#ifdef CONFIG_ACPI715 acpi_status status;716 717 status = acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),718 "_RST", NULL, NULL);719 if (ACPI_FAILURE(status)) {720 acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),721 "_INI", NULL, NULL);722 }723#endif724 }725 726 xgene_enet_ecc_init(pdata);727 xgene_enet_config_ring_if_assoc(pdata);728 729 return 0;730}731 732static void xgene_enet_clear(struct xgene_enet_pdata *pdata,733 struct xgene_enet_desc_ring *ring)734{735 u32 addr, data;736 737 if (xgene_enet_is_bufpool(ring->id)) {738 addr = ENET_CFGSSQMIFPRESET_ADDR;739 data = BIT(xgene_enet_get_fpsel(ring->id));740 } else {741 addr = ENET_CFGSSQMIWQRESET_ADDR;742 data = BIT(xgene_enet_ring_bufnum(ring->id));743 }744 745 xgene_enet_wr_ring_if(pdata, addr, data);746}747 748static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)749{750 struct device *dev = &pdata->pdev->dev;751 752 if (dev->of_node) {753 if (!IS_ERR(pdata->clk))754 clk_disable_unprepare(pdata->clk);755 }756}757 758static u32 xgene_enet_flowctrl_cfg(struct net_device *ndev)759{760 struct xgene_enet_pdata *pdata = netdev_priv(ndev);761 struct phy_device *phydev = ndev->phydev;762 u16 lcladv, rmtadv = 0;763 u32 rx_pause, tx_pause;764 u8 flowctl = 0;765 766 if (!phydev->duplex || !pdata->pause_autoneg)767 return 0;768 769 if (pdata->tx_pause)770 flowctl |= FLOW_CTRL_TX;771 772 if (pdata->rx_pause)773 flowctl |= FLOW_CTRL_RX;774 775 lcladv = mii_advertise_flowctrl(flowctl);776 777 if (phydev->pause)778 rmtadv = LPA_PAUSE_CAP;779 780 if (phydev->asym_pause)781 rmtadv |= LPA_PAUSE_ASYM;782 783 flowctl = mii_resolve_flowctrl_fdx(lcladv, rmtadv);784 tx_pause = !!(flowctl & FLOW_CTRL_TX);785 rx_pause = !!(flowctl & FLOW_CTRL_RX);786 787 if (tx_pause != pdata->tx_pause) {788 pdata->tx_pause = tx_pause;789 pdata->mac_ops->flowctl_tx(pdata, pdata->tx_pause);790 }791 792 if (rx_pause != pdata->rx_pause) {793 pdata->rx_pause = rx_pause;794 pdata->mac_ops->flowctl_rx(pdata, pdata->rx_pause);795 }796 797 return 0;798}799 800static void xgene_enet_adjust_link(struct net_device *ndev)801{802 struct xgene_enet_pdata *pdata = netdev_priv(ndev);803 const struct xgene_mac_ops *mac_ops = pdata->mac_ops;804 struct phy_device *phydev = ndev->phydev;805 806 if (phydev->link) {807 if (pdata->phy_speed != phydev->speed) {808 pdata->phy_speed = phydev->speed;809 mac_ops->set_speed(pdata);810 mac_ops->rx_enable(pdata);811 mac_ops->tx_enable(pdata);812 phy_print_status(phydev);813 }814 815 xgene_enet_flowctrl_cfg(ndev);816 } else {817 mac_ops->rx_disable(pdata);818 mac_ops->tx_disable(pdata);819 pdata->phy_speed = SPEED_UNKNOWN;820 phy_print_status(phydev);821 }822}823 824#ifdef CONFIG_ACPI825static struct acpi_device *acpi_phy_find_device(struct device *dev)826{827 struct fwnode_reference_args args;828 struct fwnode_handle *fw_node;829 int status;830 831 fw_node = acpi_fwnode_handle(ACPI_COMPANION(dev));832 status = acpi_node_get_property_reference(fw_node, "phy-handle", 0,833 &args);834 if (ACPI_FAILURE(status) || !is_acpi_device_node(args.fwnode)) {835 dev_dbg(dev, "No matching phy in ACPI table\n");836 return NULL;837 }838 839 return to_acpi_device_node(args.fwnode);840}841#endif842 843int xgene_enet_phy_connect(struct net_device *ndev)844{845 struct xgene_enet_pdata *pdata = netdev_priv(ndev);846 struct device_node *np;847 struct phy_device *phy_dev;848 struct device *dev = &pdata->pdev->dev;849 int i;850 851 if (dev->of_node) {852 for (i = 0 ; i < 2; i++) {853 np = of_parse_phandle(dev->of_node, "phy-handle", i);854 phy_dev = of_phy_connect(ndev, np,855 &xgene_enet_adjust_link,856 0, pdata->phy_mode);857 of_node_put(np);858 if (phy_dev)859 break;860 }861 862 if (!phy_dev) {863 netdev_err(ndev, "Could not connect to PHY\n");864 return -ENODEV;865 }866 } else {867#ifdef CONFIG_ACPI868 struct acpi_device *adev = acpi_phy_find_device(dev);869 if (adev)870 phy_dev = adev->driver_data;871 else872 phy_dev = NULL;873 874 if (!phy_dev ||875 phy_connect_direct(ndev, phy_dev, &xgene_enet_adjust_link,876 pdata->phy_mode)) {877 netdev_err(ndev, "Could not connect to PHY\n");878 return -ENODEV;879 }880#else881 return -ENODEV;882#endif883 }884 885 pdata->phy_speed = SPEED_UNKNOWN;886 phy_remove_link_mode(phy_dev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);887 phy_remove_link_mode(phy_dev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);888 phy_remove_link_mode(phy_dev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);889 phy_support_asym_pause(phy_dev);890 891 return 0;892}893 894static int xgene_mdiobus_register(struct xgene_enet_pdata *pdata,895 struct mii_bus *mdio)896{897 struct device *dev = &pdata->pdev->dev;898 struct net_device *ndev = pdata->ndev;899 struct phy_device *phy;900 struct device_node *child_np;901 struct device_node *mdio_np = NULL;902 u32 phy_addr;903 int ret;904 905 if (dev->of_node) {906 for_each_child_of_node(dev->of_node, child_np) {907 if (of_device_is_compatible(child_np,908 "apm,xgene-mdio")) {909 mdio_np = child_np;910 break;911 }912 }913 914 if (!mdio_np) {915 netdev_dbg(ndev, "No mdio node in the dts\n");916 return -ENXIO;917 }918 919 return of_mdiobus_register(mdio, mdio_np);920 }921 922 /* Mask out all PHYs from auto probing. */923 mdio->phy_mask = ~0;924 925 /* Register the MDIO bus */926 ret = mdiobus_register(mdio);927 if (ret)928 return ret;929 930 ret = device_property_read_u32(dev, "phy-channel", &phy_addr);931 if (ret)932 ret = device_property_read_u32(dev, "phy-addr", &phy_addr);933 if (ret)934 return -EINVAL;935 936 phy = xgene_enet_phy_register(mdio, phy_addr);937 if (!phy)938 return -EIO;939 940 return ret;941}942 943int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)944{945 struct net_device *ndev = pdata->ndev;946 struct mii_bus *mdio_bus;947 int ret;948 949 mdio_bus = mdiobus_alloc();950 if (!mdio_bus)951 return -ENOMEM;952 953 mdio_bus->name = "APM X-Gene MDIO bus";954 mdio_bus->read = xgene_mdio_rgmii_read;955 mdio_bus->write = xgene_mdio_rgmii_write;956 snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%s", "xgene-mii",957 ndev->name);958 959 mdio_bus->priv = (void __force *)pdata->mcx_mac_addr;960 mdio_bus->parent = &pdata->pdev->dev;961 962 ret = xgene_mdiobus_register(pdata, mdio_bus);963 if (ret) {964 netdev_err(ndev, "Failed to register MDIO bus\n");965 mdiobus_free(mdio_bus);966 return ret;967 }968 pdata->mdio_bus = mdio_bus;969 970 ret = xgene_enet_phy_connect(ndev);971 if (ret)972 xgene_enet_mdio_remove(pdata);973 974 return ret;975}976 977void xgene_enet_phy_disconnect(struct xgene_enet_pdata *pdata)978{979 struct net_device *ndev = pdata->ndev;980 981 if (ndev->phydev)982 phy_disconnect(ndev->phydev);983}984 985void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata)986{987 struct net_device *ndev = pdata->ndev;988 989 if (ndev->phydev)990 phy_disconnect(ndev->phydev);991 992 mdiobus_unregister(pdata->mdio_bus);993 mdiobus_free(pdata->mdio_bus);994 pdata->mdio_bus = NULL;995}996 997const struct xgene_mac_ops xgene_gmac_ops = {998 .init = xgene_gmac_init,999 .reset = xgene_gmac_reset,1000 .rx_enable = xgene_gmac_rx_enable,1001 .tx_enable = xgene_gmac_tx_enable,1002 .rx_disable = xgene_gmac_rx_disable,1003 .tx_disable = xgene_gmac_tx_disable,1004 .get_drop_cnt = xgene_gmac_get_drop_cnt,1005 .set_speed = xgene_gmac_set_speed,1006 .set_mac_addr = xgene_gmac_set_mac_addr,1007 .set_framesize = xgene_enet_set_frame_size,1008 .enable_tx_pause = xgene_gmac_enable_tx_pause,1009 .flowctl_tx = xgene_gmac_flowctl_tx,1010 .flowctl_rx = xgene_gmac_flowctl_rx,1011};1012 1013const struct xgene_port_ops xgene_gport_ops = {1014 .reset = xgene_enet_reset,1015 .clear = xgene_enet_clear,1016 .cle_bypass = xgene_enet_cle_bypass,1017 .shutdown = xgene_gport_shutdown,1018};1019 1020struct xgene_ring_ops xgene_ring1_ops = {1021 .num_ring_config = NUM_RING_CONFIG,1022 .num_ring_id_shift = 6,1023 .setup = xgene_enet_setup_ring,1024 .clear = xgene_enet_clear_ring,1025 .wr_cmd = xgene_enet_wr_cmd,1026 .len = xgene_enet_ring_len,1027};1028