aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c')
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c73
1 files changed, 51 insertions, 22 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
index f27fb6f2a93b..05b817e56fde 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
@@ -21,6 +21,7 @@
21#include "xgene_enet_main.h" 21#include "xgene_enet_main.h"
22#include "xgene_enet_hw.h" 22#include "xgene_enet_hw.h"
23#include "xgene_enet_sgmac.h" 23#include "xgene_enet_sgmac.h"
24#include "xgene_enet_xgmac.h"
24 25
25static void xgene_enet_wr_csr(struct xgene_enet_pdata *p, u32 offset, u32 val) 26static void xgene_enet_wr_csr(struct xgene_enet_pdata *p, u32 offset, u32 val)
26{ 27{
@@ -39,6 +40,14 @@ static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *p,
39 iowrite32(val, p->eth_diag_csr_addr + offset); 40 iowrite32(val, p->eth_diag_csr_addr + offset);
40} 41}
41 42
43static void xgene_enet_wr_mcx_csr(struct xgene_enet_pdata *pdata,
44 u32 offset, u32 val)
45{
46 void __iomem *addr = pdata->mcx_mac_csr_addr + offset;
47
48 iowrite32(val, addr);
49}
50
42static bool xgene_enet_wr_indirect(struct xgene_indirect_ctl *ctl, 51static bool xgene_enet_wr_indirect(struct xgene_indirect_ctl *ctl,
43 u32 wr_addr, u32 wr_data) 52 u32 wr_addr, u32 wr_data)
44{ 53{
@@ -140,8 +149,9 @@ static int xgene_enet_ecc_init(struct xgene_enet_pdata *p)
140 149
141static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *p) 150static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *p)
142{ 151{
143 u32 val = 0xffffffff; 152 u32 val;
144 153
154 val = (p->enet_id == XGENE_ENET1) ? 0xffffffff : 0;
145 xgene_enet_wr_ring_if(p, ENET_CFGSSQMIWQASSOC_ADDR, val); 155 xgene_enet_wr_ring_if(p, ENET_CFGSSQMIWQASSOC_ADDR, val);
146 xgene_enet_wr_ring_if(p, ENET_CFGSSQMIFPQASSOC_ADDR, val); 156 xgene_enet_wr_ring_if(p, ENET_CFGSSQMIFPQASSOC_ADDR, val);
147} 157}
@@ -227,6 +237,8 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p)
227{ 237{
228 u32 data, loop = 10; 238 u32 data, loop = 10;
229 u32 offset = p->port_id * 4; 239 u32 offset = p->port_id * 4;
240 u32 enet_spare_cfg_reg, rsif_config_reg;
241 u32 cfg_bypass_reg, rx_dv_gate_reg;
230 242
231 xgene_sgmac_reset(p); 243 xgene_sgmac_reset(p);
232 244
@@ -239,7 +251,7 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p)
239 SGMII_STATUS_ADDR >> 2); 251 SGMII_STATUS_ADDR >> 2);
240 if ((data & AUTO_NEG_COMPLETE) && (data & LINK_STATUS)) 252 if ((data & AUTO_NEG_COMPLETE) && (data & LINK_STATUS))
241 break; 253 break;
242 usleep_range(10, 20); 254 usleep_range(1000, 2000);
243 } 255 }
244 if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS)) 256 if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS))
245 netdev_err(p->ndev, "Auto-negotiation failed\n"); 257 netdev_err(p->ndev, "Auto-negotiation failed\n");
@@ -249,33 +261,38 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p)
249 xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2); 261 xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2);
250 xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE); 262 xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE);
251 263
252 data = xgene_enet_rd_csr(p, ENET_SPARE_CFG_REG_ADDR); 264 if (p->enet_id == XGENE_ENET1) {
265 enet_spare_cfg_reg = ENET_SPARE_CFG_REG_ADDR;
266 rsif_config_reg = RSIF_CONFIG_REG_ADDR;
267 cfg_bypass_reg = CFG_BYPASS_ADDR;
268 rx_dv_gate_reg = SG_RX_DV_GATE_REG_0_ADDR;
269 } else {
270 enet_spare_cfg_reg = XG_ENET_SPARE_CFG_REG_ADDR;
271 rsif_config_reg = XG_RSIF_CONFIG_REG_ADDR;
272 cfg_bypass_reg = XG_CFG_BYPASS_ADDR;
273 rx_dv_gate_reg = XG_MCX_RX_DV_GATE_REG_0_ADDR;
274 }
275
276 data = xgene_enet_rd_csr(p, enet_spare_cfg_reg);
253 data |= MPA_IDLE_WITH_QMI_EMPTY; 277 data |= MPA_IDLE_WITH_QMI_EMPTY;
254 xgene_enet_wr_csr(p, ENET_SPARE_CFG_REG_ADDR, data); 278 xgene_enet_wr_csr(p, enet_spare_cfg_reg, data);
255 279
256 xgene_sgmac_set_mac_addr(p); 280 xgene_sgmac_set_mac_addr(p);
257 281
258 data = xgene_enet_rd_csr(p, DEBUG_REG_ADDR);
259 data |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
260 xgene_enet_wr_csr(p, DEBUG_REG_ADDR, data);
261
262 /* Adjust MDC clock frequency */ 282 /* Adjust MDC clock frequency */
263 data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR); 283 data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR);
264 MGMT_CLOCK_SEL_SET(&data, 7); 284 MGMT_CLOCK_SEL_SET(&data, 7);
265 xgene_enet_wr_mac(p, MII_MGMT_CONFIG_ADDR, data); 285 xgene_enet_wr_mac(p, MII_MGMT_CONFIG_ADDR, data);
266 286
267 /* Enable drop if bufpool not available */ 287 /* Enable drop if bufpool not available */
268 data = xgene_enet_rd_csr(p, RSIF_CONFIG_REG_ADDR); 288 data = xgene_enet_rd_csr(p, rsif_config_reg);
269 data |= CFG_RSIF_FPBUFF_TIMEOUT_EN; 289 data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
270 xgene_enet_wr_csr(p, RSIF_CONFIG_REG_ADDR, data); 290 xgene_enet_wr_csr(p, rsif_config_reg, data);
271
272 /* Rtype should be copied from FP */
273 xgene_enet_wr_csr(p, RSIF_RAM_DBG_REG0_ADDR, 0);
274 291
275 /* Bypass traffic gating */ 292 /* Bypass traffic gating */
276 xgene_enet_wr_csr(p, CFG_LINK_AGGR_RESUME_0_ADDR + offset, TX_PORT0); 293 xgene_enet_wr_csr(p, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x84);
277 xgene_enet_wr_csr(p, CFG_BYPASS_ADDR, RESUME_TX); 294 xgene_enet_wr_csr(p, cfg_bypass_reg, RESUME_TX);
278 xgene_enet_wr_csr(p, SG_RX_DV_GATE_REG_0_ADDR + offset, RESUME_RX0); 295 xgene_enet_wr_mcx_csr(p, rx_dv_gate_reg + offset, RESUME_RX0);
279} 296}
280 297
281static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set) 298static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set)
@@ -317,9 +334,11 @@ static int xgene_enet_reset(struct xgene_enet_pdata *p)
317 if (!xgene_ring_mgr_init(p)) 334 if (!xgene_ring_mgr_init(p))
318 return -ENODEV; 335 return -ENODEV;
319 336
320 clk_prepare_enable(p->clk); 337 if (!IS_ERR(p->clk)) {
321 clk_disable_unprepare(p->clk); 338 clk_prepare_enable(p->clk);
322 clk_prepare_enable(p->clk); 339 clk_disable_unprepare(p->clk);
340 clk_prepare_enable(p->clk);
341 }
323 342
324 xgene_enet_ecc_init(p); 343 xgene_enet_ecc_init(p);
325 xgene_enet_config_ring_if_assoc(p); 344 xgene_enet_config_ring_if_assoc(p);
@@ -331,19 +350,29 @@ static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p,
331 u32 dst_ring_num, u16 bufpool_id) 350 u32 dst_ring_num, u16 bufpool_id)
332{ 351{
333 u32 data, fpsel; 352 u32 data, fpsel;
353 u32 cle_bypass_reg0, cle_bypass_reg1;
334 u32 offset = p->port_id * MAC_OFFSET; 354 u32 offset = p->port_id * MAC_OFFSET;
335 355
356 if (p->enet_id == XGENE_ENET1) {
357 cle_bypass_reg0 = CLE_BYPASS_REG0_0_ADDR;
358 cle_bypass_reg1 = CLE_BYPASS_REG1_0_ADDR;
359 } else {
360 cle_bypass_reg0 = XCLE_BYPASS_REG0_ADDR;
361 cle_bypass_reg1 = XCLE_BYPASS_REG1_ADDR;
362 }
363
336 data = CFG_CLE_BYPASS_EN0; 364 data = CFG_CLE_BYPASS_EN0;
337 xgene_enet_wr_csr(p, CLE_BYPASS_REG0_0_ADDR + offset, data); 365 xgene_enet_wr_csr(p, cle_bypass_reg0 + offset, data);
338 366
339 fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20; 367 fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20;
340 data = CFG_CLE_DSTQID0(dst_ring_num) | CFG_CLE_FPSEL0(fpsel); 368 data = CFG_CLE_DSTQID0(dst_ring_num) | CFG_CLE_FPSEL0(fpsel);
341 xgene_enet_wr_csr(p, CLE_BYPASS_REG1_0_ADDR + offset, data); 369 xgene_enet_wr_csr(p, cle_bypass_reg1 + offset, data);
342} 370}
343 371
344static void xgene_enet_shutdown(struct xgene_enet_pdata *p) 372static void xgene_enet_shutdown(struct xgene_enet_pdata *p)
345{ 373{
346 clk_disable_unprepare(p->clk); 374 if (!IS_ERR(p->clk))
375 clk_disable_unprepare(p->clk);
347} 376}
348 377
349static void xgene_enet_link_state(struct work_struct *work) 378static void xgene_enet_link_state(struct work_struct *work)