0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/of_gpio.h>
0010 #include <linux/gpio.h>
0011 #include "xgene_enet_main.h"
0012 #include "xgene_enet_hw.h"
0013 #include "xgene_enet_xgmac.h"
0014
0015 static void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata,
0016 u32 offset, u32 val)
0017 {
0018 void __iomem *addr = pdata->eth_csr_addr + offset;
0019
0020 iowrite32(val, addr);
0021 }
0022
0023 static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *pdata,
0024 u32 offset, u32 val)
0025 {
0026 void __iomem *addr = pdata->eth_ring_if_addr + offset;
0027
0028 iowrite32(val, addr);
0029 }
0030
0031 static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *pdata,
0032 u32 offset, u32 val)
0033 {
0034 void __iomem *addr = pdata->eth_diag_csr_addr + offset;
0035
0036 iowrite32(val, addr);
0037 }
0038
0039 static bool xgene_enet_wr_indirect(void __iomem *addr, void __iomem *wr,
0040 void __iomem *cmd, void __iomem *cmd_done,
0041 u32 wr_addr, u32 wr_data)
0042 {
0043 u32 done;
0044 u8 wait = 10;
0045
0046 iowrite32(wr_addr, addr);
0047 iowrite32(wr_data, wr);
0048 iowrite32(XGENE_ENET_WR_CMD, cmd);
0049
0050
0051 while (!(done = ioread32(cmd_done)) && wait--)
0052 udelay(1);
0053
0054 if (!done)
0055 return false;
0056
0057 iowrite32(0, cmd);
0058
0059 return true;
0060 }
0061
0062 static void xgene_enet_wr_pcs(struct xgene_enet_pdata *pdata,
0063 u32 wr_addr, u32 wr_data)
0064 {
0065 void __iomem *addr, *wr, *cmd, *cmd_done;
0066
0067 addr = pdata->pcs_addr + PCS_ADDR_REG_OFFSET;
0068 wr = pdata->pcs_addr + PCS_WRITE_REG_OFFSET;
0069 cmd = pdata->pcs_addr + PCS_COMMAND_REG_OFFSET;
0070 cmd_done = pdata->pcs_addr + PCS_COMMAND_DONE_REG_OFFSET;
0071
0072 if (!xgene_enet_wr_indirect(addr, wr, cmd, cmd_done, wr_addr, wr_data))
0073 netdev_err(pdata->ndev, "PCS write failed, addr: %04x\n",
0074 wr_addr);
0075 }
0076
0077 static void xgene_enet_wr_axg_csr(struct xgene_enet_pdata *pdata,
0078 u32 offset, u32 val)
0079 {
0080 void __iomem *addr = pdata->mcx_mac_csr_addr + offset;
0081
0082 iowrite32(val, addr);
0083 }
0084
0085 static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,
0086 u32 offset, u32 *val)
0087 {
0088 void __iomem *addr = pdata->eth_csr_addr + offset;
0089
0090 *val = ioread32(addr);
0091 }
0092
0093 static void xgene_enet_rd_diag_csr(struct xgene_enet_pdata *pdata,
0094 u32 offset, u32 *val)
0095 {
0096 void __iomem *addr = pdata->eth_diag_csr_addr + offset;
0097
0098 *val = ioread32(addr);
0099 }
0100
0101 static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd,
0102 void __iomem *cmd, void __iomem *cmd_done,
0103 u32 rd_addr, u32 *rd_data)
0104 {
0105 u32 done;
0106 u8 wait = 10;
0107
0108 iowrite32(rd_addr, addr);
0109 iowrite32(XGENE_ENET_RD_CMD, cmd);
0110
0111
0112 while (!(done = ioread32(cmd_done)) && wait--)
0113 udelay(1);
0114
0115 if (!done)
0116 return false;
0117
0118 *rd_data = ioread32(rd);
0119 iowrite32(0, cmd);
0120
0121 return true;
0122 }
0123
0124 static bool xgene_enet_rd_pcs(struct xgene_enet_pdata *pdata,
0125 u32 rd_addr, u32 *rd_data)
0126 {
0127 void __iomem *addr, *rd, *cmd, *cmd_done;
0128 bool success;
0129
0130 addr = pdata->pcs_addr + PCS_ADDR_REG_OFFSET;
0131 rd = pdata->pcs_addr + PCS_READ_REG_OFFSET;
0132 cmd = pdata->pcs_addr + PCS_COMMAND_REG_OFFSET;
0133 cmd_done = pdata->pcs_addr + PCS_COMMAND_DONE_REG_OFFSET;
0134
0135 success = xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data);
0136 if (!success)
0137 netdev_err(pdata->ndev, "PCS read failed, addr: %04x\n",
0138 rd_addr);
0139
0140 return success;
0141 }
0142
0143 static void xgene_enet_rd_axg_csr(struct xgene_enet_pdata *pdata,
0144 u32 offset, u32 *val)
0145 {
0146 void __iomem *addr = pdata->mcx_mac_csr_addr + offset;
0147
0148 *val = ioread32(addr);
0149 }
0150
0151 static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
0152 {
0153 struct net_device *ndev = pdata->ndev;
0154 u32 data;
0155 u8 wait = 10;
0156
0157 xgene_enet_wr_diag_csr(pdata, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0x0);
0158 do {
0159 usleep_range(100, 110);
0160 xgene_enet_rd_diag_csr(pdata, ENET_BLOCK_MEM_RDY_ADDR, &data);
0161 } while ((data != 0xffffffff) && wait--);
0162
0163 if (data != 0xffffffff) {
0164 netdev_err(ndev, "Failed to release memory from shutdown\n");
0165 return -ENODEV;
0166 }
0167
0168 return 0;
0169 }
0170
0171 static void xgene_xgmac_get_drop_cnt(struct xgene_enet_pdata *pdata,
0172 u32 *rx, u32 *tx)
0173 {
0174 u32 count;
0175
0176 xgene_enet_rd_axg_csr(pdata, XGENET_ICM_ECM_DROP_COUNT_REG0, &count);
0177 *rx = ICM_DROP_COUNT(count);
0178 *tx = ECM_DROP_COUNT(count);
0179
0180 xgene_enet_rd_axg_csr(pdata, XGENET_ECM_CONFIG0_REG_0, &count);
0181 }
0182
0183 static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata)
0184 {
0185 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQASSOC_ADDR, 0);
0186 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPQASSOC_ADDR, 0);
0187 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEWQASSOC_ADDR, 0);
0188 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEFPQASSOC_ADDR, 0);
0189 }
0190
0191 static void xgene_xgmac_reset(struct xgene_enet_pdata *pdata)
0192 {
0193 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_0, HSTMACRST);
0194 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_0, 0);
0195 }
0196
0197 static void xgene_pcs_reset(struct xgene_enet_pdata *pdata)
0198 {
0199 u32 data;
0200
0201 if (!xgene_enet_rd_pcs(pdata, PCS_CONTROL_1, &data))
0202 return;
0203
0204 xgene_enet_wr_pcs(pdata, PCS_CONTROL_1, data | PCS_CTRL_PCS_RST);
0205 xgene_enet_wr_pcs(pdata, PCS_CONTROL_1, data & ~PCS_CTRL_PCS_RST);
0206 }
0207
0208 static void xgene_xgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
0209 {
0210 const u8 *dev_addr = pdata->ndev->dev_addr;
0211 u32 addr0, addr1;
0212
0213 addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
0214 (dev_addr[1] << 8) | dev_addr[0];
0215 addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16);
0216
0217 xgene_enet_wr_mac(pdata, HSTMACADR_LSW_ADDR, addr0);
0218 xgene_enet_wr_mac(pdata, HSTMACADR_MSW_ADDR, addr1);
0219 }
0220
0221 static void xgene_xgmac_set_mss(struct xgene_enet_pdata *pdata,
0222 u16 mss, u8 index)
0223 {
0224 u8 offset;
0225 u32 data;
0226
0227 offset = (index < 2) ? 0 : 4;
0228 xgene_enet_rd_csr(pdata, XG_TSIF_MSS_REG0_ADDR + offset, &data);
0229
0230 if (!(index & 0x1))
0231 data = SET_VAL(TSO_MSS1, data >> TSO_MSS1_POS) |
0232 SET_VAL(TSO_MSS0, mss);
0233 else
0234 data = SET_VAL(TSO_MSS1, mss) | SET_VAL(TSO_MSS0, data);
0235
0236 xgene_enet_wr_csr(pdata, XG_TSIF_MSS_REG0_ADDR + offset, data);
0237 }
0238
0239 static void xgene_xgmac_set_frame_size(struct xgene_enet_pdata *pdata, int size)
0240 {
0241 xgene_enet_wr_mac(pdata, HSTMAXFRAME_LENGTH_ADDR,
0242 ((((size + 2) >> 2) << 16) | size));
0243 }
0244
0245 static u32 xgene_enet_link_status(struct xgene_enet_pdata *pdata)
0246 {
0247 u32 data;
0248
0249 xgene_enet_rd_csr(pdata, XG_LINK_STATUS_ADDR, &data);
0250
0251 return data;
0252 }
0253
0254 static void xgene_xgmac_enable_tx_pause(struct xgene_enet_pdata *pdata,
0255 bool enable)
0256 {
0257 u32 data;
0258
0259 xgene_enet_rd_axg_csr(pdata, XGENET_CSR_ECM_CFG_0_ADDR, &data);
0260
0261 if (enable)
0262 data |= MULTI_DPF_AUTOCTRL | PAUSE_XON_EN;
0263 else
0264 data &= ~(MULTI_DPF_AUTOCTRL | PAUSE_XON_EN);
0265
0266 xgene_enet_wr_axg_csr(pdata, XGENET_CSR_ECM_CFG_0_ADDR, data);
0267 }
0268
0269 static void xgene_xgmac_flowctl_tx(struct xgene_enet_pdata *pdata, bool enable)
0270 {
0271 u32 data;
0272
0273 data = xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1);
0274
0275 if (enable)
0276 data |= HSTTCTLEN;
0277 else
0278 data &= ~HSTTCTLEN;
0279
0280 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
0281
0282 pdata->mac_ops->enable_tx_pause(pdata, enable);
0283 }
0284
0285 static void xgene_xgmac_flowctl_rx(struct xgene_enet_pdata *pdata, bool enable)
0286 {
0287 u32 data;
0288
0289 data = xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1);
0290
0291 if (enable)
0292 data |= HSTRCTLEN;
0293 else
0294 data &= ~HSTRCTLEN;
0295
0296 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
0297 }
0298
0299 static void xgene_xgmac_init(struct xgene_enet_pdata *pdata)
0300 {
0301 u32 data;
0302
0303 xgene_xgmac_reset(pdata);
0304
0305 data = xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1);
0306 data |= HSTPPEN;
0307 data &= ~HSTLENCHK;
0308 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
0309
0310 xgene_xgmac_set_mac_addr(pdata);
0311
0312 xgene_enet_rd_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, &data);
0313 data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
0314
0315 RSIF_CLE_BUFF_THRESH_SET(&data, XG_RSIF_CLE_BUFF_THRESH);
0316 xgene_enet_wr_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, data);
0317
0318
0319 xgene_enet_rd_csr(pdata, XG_RSIF_CONFIG1_REG_ADDR, &data);
0320 RSIF_PLC_CLE_BUFF_THRESH_SET(&data, XG_RSIF_PLC_CLE_BUFF_THRESH);
0321 xgene_enet_wr_csr(pdata, XG_RSIF_CONFIG1_REG_ADDR, data);
0322
0323 xgene_enet_rd_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, &data);
0324 data |= BIT(12);
0325 xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, data);
0326 xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x82);
0327 xgene_enet_wr_csr(pdata, XGENET_RX_DV_GATE_REG_0_ADDR, 0);
0328 xgene_enet_wr_csr(pdata, XG_CFG_BYPASS_ADDR, RESUME_TX);
0329
0330
0331 xgene_enet_rd_axg_csr(pdata, XGENET_CSR_MULTI_DPF0_ADDR, &data);
0332 data = (DEF_QUANTA << 16) | (data & 0xFFFF);
0333 xgene_enet_wr_axg_csr(pdata, XGENET_CSR_MULTI_DPF0_ADDR, data);
0334
0335 if (pdata->enet_id != XGENE_ENET1) {
0336 xgene_enet_rd_axg_csr(pdata, XGENET_CSR_MULTI_DPF1_ADDR, &data);
0337 data = (NORM_PAUSE_OPCODE << 16) | (data & 0xFFFF);
0338 xgene_enet_wr_axg_csr(pdata, XGENET_CSR_MULTI_DPF1_ADDR, data);
0339 }
0340
0341 data = (XG_DEF_PAUSE_OFF_THRES << 16) | XG_DEF_PAUSE_THRES;
0342 xgene_enet_wr_csr(pdata, XG_RXBUF_PAUSE_THRESH, data);
0343
0344 xgene_xgmac_flowctl_tx(pdata, pdata->tx_pause);
0345 xgene_xgmac_flowctl_rx(pdata, pdata->rx_pause);
0346 }
0347
0348 static void xgene_xgmac_rx_enable(struct xgene_enet_pdata *pdata)
0349 {
0350 u32 data;
0351
0352 data = xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1);
0353 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data | HSTRFEN);
0354 }
0355
0356 static void xgene_xgmac_tx_enable(struct xgene_enet_pdata *pdata)
0357 {
0358 u32 data;
0359
0360 data = xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1);
0361 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data | HSTTFEN);
0362 }
0363
0364 static void xgene_xgmac_rx_disable(struct xgene_enet_pdata *pdata)
0365 {
0366 u32 data;
0367
0368 data = xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1);
0369 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTRFEN);
0370 }
0371
0372 static void xgene_xgmac_tx_disable(struct xgene_enet_pdata *pdata)
0373 {
0374 u32 data;
0375
0376 data = xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1);
0377 xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTTFEN);
0378 }
0379
0380 static int xgene_enet_reset(struct xgene_enet_pdata *pdata)
0381 {
0382 struct device *dev = &pdata->pdev->dev;
0383
0384 if (!xgene_ring_mgr_init(pdata))
0385 return -ENODEV;
0386
0387 if (dev->of_node) {
0388 clk_prepare_enable(pdata->clk);
0389 udelay(5);
0390 clk_disable_unprepare(pdata->clk);
0391 udelay(5);
0392 clk_prepare_enable(pdata->clk);
0393 udelay(5);
0394 } else {
0395 #ifdef CONFIG_ACPI
0396 acpi_status status;
0397
0398 status = acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),
0399 "_RST", NULL, NULL);
0400 if (ACPI_FAILURE(status)) {
0401 acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),
0402 "_INI", NULL, NULL);
0403 }
0404 #endif
0405 }
0406
0407 xgene_enet_ecc_init(pdata);
0408 xgene_enet_config_ring_if_assoc(pdata);
0409
0410 return 0;
0411 }
0412
0413 static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata,
0414 u32 dst_ring_num, u16 bufpool_id,
0415 u16 nxtbufpool_id)
0416 {
0417 u32 cb, fpsel, nxtfpsel;
0418
0419 xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG0_ADDR, &cb);
0420 cb |= CFG_CLE_BYPASS_EN0;
0421 CFG_CLE_IP_PROTOCOL0_SET(&cb, 3);
0422 xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG0_ADDR, cb);
0423
0424 fpsel = xgene_enet_get_fpsel(bufpool_id);
0425 nxtfpsel = xgene_enet_get_fpsel(nxtbufpool_id);
0426 xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG1_ADDR, &cb);
0427 CFG_CLE_DSTQID0_SET(&cb, dst_ring_num);
0428 CFG_CLE_FPSEL0_SET(&cb, fpsel);
0429 CFG_CLE_NXTFPSEL0_SET(&cb, nxtfpsel);
0430 xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG1_ADDR, cb);
0431 pr_info("+ cle_bypass: fpsel: %d nxtfpsel: %d\n", fpsel, nxtfpsel);
0432 }
0433
0434 static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
0435 {
0436 struct device *dev = &pdata->pdev->dev;
0437
0438 if (dev->of_node) {
0439 if (!IS_ERR(pdata->clk))
0440 clk_disable_unprepare(pdata->clk);
0441 }
0442 }
0443
0444 static void xgene_enet_clear(struct xgene_enet_pdata *pdata,
0445 struct xgene_enet_desc_ring *ring)
0446 {
0447 u32 addr, data;
0448
0449 if (xgene_enet_is_bufpool(ring->id)) {
0450 addr = ENET_CFGSSQMIFPRESET_ADDR;
0451 data = BIT(xgene_enet_get_fpsel(ring->id));
0452 } else {
0453 addr = ENET_CFGSSQMIWQRESET_ADDR;
0454 data = BIT(xgene_enet_ring_bufnum(ring->id));
0455 }
0456
0457 xgene_enet_wr_ring_if(pdata, addr, data);
0458 }
0459
0460 static int xgene_enet_gpio_lookup(struct xgene_enet_pdata *pdata)
0461 {
0462 struct device *dev = &pdata->pdev->dev;
0463
0464 pdata->sfp_rdy = gpiod_get(dev, "rxlos", GPIOD_IN);
0465 if (IS_ERR(pdata->sfp_rdy))
0466 pdata->sfp_rdy = gpiod_get(dev, "sfp", GPIOD_IN);
0467
0468 if (IS_ERR(pdata->sfp_rdy))
0469 return -ENODEV;
0470
0471 return 0;
0472 }
0473
0474 static void xgene_enet_link_state(struct work_struct *work)
0475 {
0476 struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
0477 struct xgene_enet_pdata, link_work);
0478 struct net_device *ndev = pdata->ndev;
0479 u32 link_status, poll_interval;
0480
0481 link_status = xgene_enet_link_status(pdata);
0482 if (pdata->sfp_gpio_en && link_status &&
0483 (!IS_ERR(pdata->sfp_rdy) || !xgene_enet_gpio_lookup(pdata)) &&
0484 !gpiod_get_value(pdata->sfp_rdy))
0485 link_status = 0;
0486
0487 if (link_status) {
0488 if (!netif_carrier_ok(ndev)) {
0489 netif_carrier_on(ndev);
0490 xgene_xgmac_rx_enable(pdata);
0491 xgene_xgmac_tx_enable(pdata);
0492 netdev_info(ndev, "Link is Up - 10Gbps\n");
0493 }
0494 poll_interval = PHY_POLL_LINK_ON;
0495 } else {
0496 if (netif_carrier_ok(ndev)) {
0497 xgene_xgmac_rx_disable(pdata);
0498 xgene_xgmac_tx_disable(pdata);
0499 netif_carrier_off(ndev);
0500 netdev_info(ndev, "Link is Down\n");
0501 }
0502 poll_interval = PHY_POLL_LINK_OFF;
0503
0504 xgene_pcs_reset(pdata);
0505 }
0506
0507 schedule_delayed_work(&pdata->link_work, poll_interval);
0508 }
0509
0510 const struct xgene_mac_ops xgene_xgmac_ops = {
0511 .init = xgene_xgmac_init,
0512 .reset = xgene_xgmac_reset,
0513 .rx_enable = xgene_xgmac_rx_enable,
0514 .tx_enable = xgene_xgmac_tx_enable,
0515 .rx_disable = xgene_xgmac_rx_disable,
0516 .tx_disable = xgene_xgmac_tx_disable,
0517 .set_mac_addr = xgene_xgmac_set_mac_addr,
0518 .set_framesize = xgene_xgmac_set_frame_size,
0519 .set_mss = xgene_xgmac_set_mss,
0520 .get_drop_cnt = xgene_xgmac_get_drop_cnt,
0521 .link_state = xgene_enet_link_state,
0522 .enable_tx_pause = xgene_xgmac_enable_tx_pause,
0523 .flowctl_rx = xgene_xgmac_flowctl_rx,
0524 .flowctl_tx = xgene_xgmac_flowctl_tx
0525 };
0526
0527 const struct xgene_port_ops xgene_xgport_ops = {
0528 .reset = xgene_enet_reset,
0529 .clear = xgene_enet_clear,
0530 .cle_bypass = xgene_enet_xgcle_bypass,
0531 .shutdown = xgene_enet_shutdown,
0532 };