Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Applied Micro X-Gene SoC Ethernet Driver
0003  *
0004  * Copyright (c) 2014, Applied Micro Circuits Corporation
0005  * Authors: Iyappan Subramanian <isubramanian@apm.com>
0006  *      Keyur Chudgar <kchudgar@apm.com>
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     /* wait for write command to complete */
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     /* wait for read command to complete */
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     /* Errata: 10GE_4 - ICM_ECM_DROP_COUNT not clear-on-read */
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     /* Errata 10GE_1 - FIFO threshold default value incorrect */
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     /* Errata 10GE_1 - FIFO threshold default value incorrect */
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     /* Configure HW pause frame generation */
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 };