diff options
author | Iyappan Subramanian <isubramanian@apm.com> | 2016-07-25 20:12:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-26 00:51:42 -0400 |
commit | 9a8c5ddedd9805cf52744ef6bdf591326684f88c (patch) | |
tree | 757a38eb81905e88c492a2725fa62d5b0a79fd02 | |
parent | c43212bb7bebe24a93a7a7d86e767e1ce295d72a (diff) |
drivers: net: xgene: Separate set_speed from mac_init
Since mac_init is too heavy to be called when the link changes,
moved the speed_set configuration to a new function and added
mac_ops->set_speed function pointer. This function will be
called from adjust_link callback.
Added cases for 10/100 support for SGMII based 1G interface.
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Tested-by: Fushen Chen <fchen@apm.com>
Tested-by: Toan Le <toanle@apm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | 135 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | 3 |
7 files changed, 151 insertions, 33 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index 2f5638f7f864..725109b964c3 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | |||
@@ -512,14 +512,11 @@ static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata) | |||
512 | #endif | 512 | #endif |
513 | } | 513 | } |
514 | 514 | ||
515 | static void xgene_gmac_init(struct xgene_enet_pdata *pdata) | 515 | static void xgene_gmac_set_speed(struct xgene_enet_pdata *pdata) |
516 | { | 516 | { |
517 | struct device *dev = &pdata->pdev->dev; | 517 | struct device *dev = &pdata->pdev->dev; |
518 | u32 value, mc2; | 518 | u32 icm0, icm2, mc2; |
519 | u32 intf_ctl, rgmii; | 519 | u32 intf_ctl, rgmii, value; |
520 | u32 icm0, icm2; | ||
521 | |||
522 | xgene_gmac_reset(pdata); | ||
523 | 520 | ||
524 | xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, &icm0); | 521 | xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, &icm0); |
525 | xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, &icm2); | 522 | xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, &icm2); |
@@ -564,7 +561,19 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) | |||
564 | mc2 |= FULL_DUPLEX2 | PAD_CRC; | 561 | mc2 |= FULL_DUPLEX2 | PAD_CRC; |
565 | xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2); | 562 | xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2); |
566 | xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl); | 563 | xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl); |
564 | xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii); | ||
565 | xgene_enet_configure_clock(pdata); | ||
566 | |||
567 | xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, icm0); | ||
568 | xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, icm2); | ||
569 | } | ||
567 | 570 | ||
571 | static void xgene_gmac_init(struct xgene_enet_pdata *pdata) | ||
572 | { | ||
573 | u32 value; | ||
574 | |||
575 | xgene_gmac_reset(pdata); | ||
576 | xgene_gmac_set_speed(pdata); | ||
568 | xgene_gmac_set_mac_addr(pdata); | 577 | xgene_gmac_set_mac_addr(pdata); |
569 | 578 | ||
570 | /* Adjust MDC clock frequency */ | 579 | /* Adjust MDC clock frequency */ |
@@ -579,15 +588,10 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) | |||
579 | 588 | ||
580 | /* Rtype should be copied from FP */ | 589 | /* Rtype should be copied from FP */ |
581 | xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0); | 590 | xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0); |
582 | xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii); | ||
583 | xgene_enet_configure_clock(pdata); | ||
584 | 591 | ||
585 | /* Rx-Tx traffic resume */ | 592 | /* Rx-Tx traffic resume */ |
586 | xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); | 593 | xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); |
587 | 594 | ||
588 | xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, icm0); | ||
589 | xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, icm2); | ||
590 | |||
591 | xgene_enet_rd_mcx_csr(pdata, RX_DV_GATE_REG_0_ADDR, &value); | 595 | xgene_enet_rd_mcx_csr(pdata, RX_DV_GATE_REG_0_ADDR, &value); |
592 | value &= ~TX_DV_GATE_EN0; | 596 | value &= ~TX_DV_GATE_EN0; |
593 | value &= ~RX_DV_GATE_EN0; | 597 | value &= ~RX_DV_GATE_EN0; |
@@ -724,12 +728,13 @@ static int xgene_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, | |||
724 | static void xgene_enet_adjust_link(struct net_device *ndev) | 728 | static void xgene_enet_adjust_link(struct net_device *ndev) |
725 | { | 729 | { |
726 | struct xgene_enet_pdata *pdata = netdev_priv(ndev); | 730 | struct xgene_enet_pdata *pdata = netdev_priv(ndev); |
731 | const struct xgene_mac_ops *mac_ops = pdata->mac_ops; | ||
727 | struct phy_device *phydev = pdata->phy_dev; | 732 | struct phy_device *phydev = pdata->phy_dev; |
728 | 733 | ||
729 | if (phydev->link) { | 734 | if (phydev->link) { |
730 | if (pdata->phy_speed != phydev->speed) { | 735 | if (pdata->phy_speed != phydev->speed) { |
731 | pdata->phy_speed = phydev->speed; | 736 | pdata->phy_speed = phydev->speed; |
732 | xgene_gmac_init(pdata); | 737 | mac_ops->set_speed(pdata); |
733 | xgene_gmac_rx_enable(pdata); | 738 | xgene_gmac_rx_enable(pdata); |
734 | xgene_gmac_tx_enable(pdata); | 739 | xgene_gmac_tx_enable(pdata); |
735 | phy_print_status(phydev); | 740 | phy_print_status(phydev); |
@@ -890,6 +895,7 @@ const struct xgene_mac_ops xgene_gmac_ops = { | |||
890 | .tx_enable = xgene_gmac_tx_enable, | 895 | .tx_enable = xgene_gmac_tx_enable, |
891 | .rx_disable = xgene_gmac_rx_disable, | 896 | .rx_disable = xgene_gmac_rx_disable, |
892 | .tx_disable = xgene_gmac_tx_disable, | 897 | .tx_disable = xgene_gmac_tx_disable, |
898 | .set_speed = xgene_gmac_set_speed, | ||
893 | .set_mac_addr = xgene_gmac_set_mac_addr, | 899 | .set_mac_addr = xgene_gmac_set_mac_addr, |
894 | }; | 900 | }; |
895 | 901 | ||
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h index 45220be3122f..e840f9633734 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | |||
@@ -104,6 +104,8 @@ enum xgene_enet_rm { | |||
104 | #define RECOMBBUF BIT(27) | 104 | #define RECOMBBUF BIT(27) |
105 | 105 | ||
106 | #define MAC_OFFSET 0x30 | 106 | #define MAC_OFFSET 0x30 |
107 | #define OFFSET_4 0x04 | ||
108 | #define OFFSET_8 0x08 | ||
107 | 109 | ||
108 | #define BLOCK_ETH_CSR_OFFSET 0x2000 | 110 | #define BLOCK_ETH_CSR_OFFSET 0x2000 |
109 | #define BLOCK_ETH_CLE_CSR_OFFSET 0x6000 | 111 | #define BLOCK_ETH_CLE_CSR_OFFSET 0x6000 |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index d208b172f4d7..8da3860691ee 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c | |||
@@ -730,8 +730,10 @@ static int xgene_enet_open(struct net_device *ndev) | |||
730 | 730 | ||
731 | if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) | 731 | if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) |
732 | phy_start(pdata->phy_dev); | 732 | phy_start(pdata->phy_dev); |
733 | else | 733 | else { |
734 | schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF); | 734 | schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF); |
735 | netif_carrier_off(ndev); | ||
736 | } | ||
735 | 737 | ||
736 | netif_start_queue(ndev); | 738 | netif_start_queue(ndev); |
737 | 739 | ||
@@ -761,7 +763,6 @@ static int xgene_enet_close(struct net_device *ndev) | |||
761 | 763 | ||
762 | return 0; | 764 | return 0; |
763 | } | 765 | } |
764 | |||
765 | static void xgene_enet_delete_ring(struct xgene_enet_desc_ring *ring) | 766 | static void xgene_enet_delete_ring(struct xgene_enet_desc_ring *ring) |
766 | { | 767 | { |
767 | struct xgene_enet_pdata *pdata; | 768 | struct xgene_enet_pdata *pdata; |
@@ -1447,6 +1448,7 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata) | |||
1447 | pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id); | 1448 | pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id); |
1448 | } | 1449 | } |
1449 | 1450 | ||
1451 | pdata->phy_speed = SPEED_UNKNOWN; | ||
1450 | pdata->mac_ops->init(pdata); | 1452 | pdata->mac_ops->init(pdata); |
1451 | 1453 | ||
1452 | return ret; | 1454 | return ret; |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h index 092fbeccaa20..aed9f430e0bc 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h | |||
@@ -140,6 +140,7 @@ struct xgene_mac_ops { | |||
140 | void (*rx_enable)(struct xgene_enet_pdata *pdata); | 140 | void (*rx_enable)(struct xgene_enet_pdata *pdata); |
141 | void (*tx_disable)(struct xgene_enet_pdata *pdata); | 141 | void (*tx_disable)(struct xgene_enet_pdata *pdata); |
142 | void (*rx_disable)(struct xgene_enet_pdata *pdata); | 142 | void (*rx_disable)(struct xgene_enet_pdata *pdata); |
143 | void (*set_speed)(struct xgene_enet_pdata *pdata); | ||
143 | void (*set_mac_addr)(struct xgene_enet_pdata *pdata); | 144 | void (*set_mac_addr)(struct xgene_enet_pdata *pdata); |
144 | void (*set_mss)(struct xgene_enet_pdata *pdata); | 145 | void (*set_mss)(struct xgene_enet_pdata *pdata); |
145 | void (*link_state)(struct work_struct *work); | 146 | void (*link_state)(struct work_struct *work); |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c index 78475512b683..a3063fd7681f 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | |||
@@ -93,6 +93,11 @@ static u32 xgene_enet_rd_diag_csr(struct xgene_enet_pdata *p, u32 offset) | |||
93 | return ioread32(p->eth_diag_csr_addr + offset); | 93 | return ioread32(p->eth_diag_csr_addr + offset); |
94 | } | 94 | } |
95 | 95 | ||
96 | static u32 xgene_enet_rd_mcx_csr(struct xgene_enet_pdata *p, u32 offset) | ||
97 | { | ||
98 | return ioread32(p->mcx_mac_csr_addr + offset); | ||
99 | } | ||
100 | |||
96 | static u32 xgene_enet_rd_indirect(struct xgene_indirect_ctl *ctl, u32 rd_addr) | 101 | static u32 xgene_enet_rd_indirect(struct xgene_indirect_ctl *ctl, u32 rd_addr) |
97 | { | 102 | { |
98 | u32 rd_data; | 103 | u32 rd_data; |
@@ -230,21 +235,105 @@ static u32 xgene_enet_link_status(struct xgene_enet_pdata *p) | |||
230 | data = xgene_mii_phy_read(p, INT_PHY_ADDR, | 235 | data = xgene_mii_phy_read(p, INT_PHY_ADDR, |
231 | SGMII_BASE_PAGE_ABILITY_ADDR >> 2); | 236 | SGMII_BASE_PAGE_ABILITY_ADDR >> 2); |
232 | 237 | ||
238 | if (LINK_SPEED(data) == PHY_SPEED_1000) | ||
239 | p->phy_speed = SPEED_1000; | ||
240 | else if (LINK_SPEED(data) == PHY_SPEED_100) | ||
241 | p->phy_speed = SPEED_100; | ||
242 | else | ||
243 | p->phy_speed = SPEED_10; | ||
244 | |||
233 | return data & LINK_UP; | 245 | return data & LINK_UP; |
234 | } | 246 | } |
235 | 247 | ||
236 | static void xgene_sgmac_init(struct xgene_enet_pdata *p) | 248 | static void xgene_sgmii_configure(struct xgene_enet_pdata *p) |
237 | { | 249 | { |
238 | u32 data, loop = 10; | 250 | xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, |
239 | u32 offset = p->port_id * 4; | 251 | 0x8000); |
240 | u32 enet_spare_cfg_reg, rsif_config_reg; | 252 | xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_CONTROL_ADDR >> 2, 0x9000); |
241 | u32 cfg_bypass_reg, rx_dv_gate_reg; | 253 | xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0); |
242 | 254 | } | |
243 | xgene_sgmac_reset(p); | ||
244 | 255 | ||
245 | /* Enable auto-negotiation */ | 256 | static void xgene_sgmii_tbi_control_reset(struct xgene_enet_pdata *p) |
246 | xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_CONTROL_ADDR >> 2, 0x1000); | 257 | { |
258 | xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, | ||
259 | 0x8000); | ||
247 | xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0); | 260 | xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0); |
261 | } | ||
262 | |||
263 | static void xgene_sgmii_reset(struct xgene_enet_pdata *p) | ||
264 | { | ||
265 | u32 value; | ||
266 | |||
267 | if (p->phy_speed == SPEED_UNKNOWN) | ||
268 | return; | ||
269 | |||
270 | value = xgene_mii_phy_read(p, INT_PHY_ADDR, | ||
271 | SGMII_BASE_PAGE_ABILITY_ADDR >> 2); | ||
272 | if (!(value & LINK_UP)) | ||
273 | xgene_sgmii_tbi_control_reset(p); | ||
274 | } | ||
275 | |||
276 | static void xgene_sgmac_set_speed(struct xgene_enet_pdata *p) | ||
277 | { | ||
278 | u32 icm0_addr, icm2_addr, debug_addr; | ||
279 | u32 icm0, icm2, intf_ctl; | ||
280 | u32 mc2, value; | ||
281 | |||
282 | xgene_sgmii_reset(p); | ||
283 | |||
284 | if (p->enet_id == XGENE_ENET1) { | ||
285 | icm0_addr = ICM_CONFIG0_REG_0_ADDR + p->port_id * OFFSET_8; | ||
286 | icm2_addr = ICM_CONFIG2_REG_0_ADDR + p->port_id * OFFSET_4; | ||
287 | debug_addr = DEBUG_REG_ADDR; | ||
288 | } else { | ||
289 | icm0_addr = XG_MCX_ICM_CONFIG0_REG_0_ADDR; | ||
290 | icm2_addr = XG_MCX_ICM_CONFIG2_REG_0_ADDR; | ||
291 | debug_addr = XG_DEBUG_REG_ADDR; | ||
292 | } | ||
293 | |||
294 | icm0 = xgene_enet_rd_mcx_csr(p, icm0_addr); | ||
295 | icm2 = xgene_enet_rd_mcx_csr(p, icm2_addr); | ||
296 | mc2 = xgene_enet_rd_mac(p, MAC_CONFIG_2_ADDR); | ||
297 | intf_ctl = xgene_enet_rd_mac(p, INTERFACE_CONTROL_ADDR); | ||
298 | |||
299 | switch (p->phy_speed) { | ||
300 | case SPEED_10: | ||
301 | ENET_INTERFACE_MODE2_SET(&mc2, 1); | ||
302 | intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE); | ||
303 | CFG_MACMODE_SET(&icm0, 0); | ||
304 | CFG_WAITASYNCRD_SET(&icm2, 500); | ||
305 | break; | ||
306 | case SPEED_100: | ||
307 | ENET_INTERFACE_MODE2_SET(&mc2, 1); | ||
308 | intf_ctl &= ~ENET_GHD_MODE; | ||
309 | intf_ctl |= ENET_LHD_MODE; | ||
310 | CFG_MACMODE_SET(&icm0, 1); | ||
311 | CFG_WAITASYNCRD_SET(&icm2, 80); | ||
312 | break; | ||
313 | default: | ||
314 | ENET_INTERFACE_MODE2_SET(&mc2, 2); | ||
315 | intf_ctl &= ~ENET_LHD_MODE; | ||
316 | intf_ctl |= ENET_GHD_MODE; | ||
317 | CFG_MACMODE_SET(&icm0, 2); | ||
318 | CFG_WAITASYNCRD_SET(&icm2, 16); | ||
319 | value = xgene_enet_rd_csr(p, debug_addr); | ||
320 | value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX; | ||
321 | xgene_enet_wr_csr(p, debug_addr, value); | ||
322 | break; | ||
323 | } | ||
324 | |||
325 | mc2 |= FULL_DUPLEX2 | PAD_CRC; | ||
326 | xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, mc2); | ||
327 | xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, intf_ctl); | ||
328 | xgene_enet_wr_mcx_csr(p, icm0_addr, icm0); | ||
329 | xgene_enet_wr_mcx_csr(p, icm2_addr, icm2); | ||
330 | } | ||
331 | |||
332 | static void xgene_sgmii_enable_autoneg(struct xgene_enet_pdata *p) | ||
333 | { | ||
334 | u32 data, loop = 10; | ||
335 | |||
336 | xgene_sgmii_configure(p); | ||
248 | 337 | ||
249 | while (loop--) { | 338 | while (loop--) { |
250 | data = xgene_mii_phy_read(p, INT_PHY_ADDR, | 339 | data = xgene_mii_phy_read(p, INT_PHY_ADDR, |
@@ -255,17 +344,25 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p) | |||
255 | } | 344 | } |
256 | if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS)) | 345 | if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS)) |
257 | netdev_err(p->ndev, "Auto-negotiation failed\n"); | 346 | netdev_err(p->ndev, "Auto-negotiation failed\n"); |
347 | } | ||
258 | 348 | ||
259 | data = xgene_enet_rd_mac(p, MAC_CONFIG_2_ADDR); | 349 | static void xgene_sgmac_init(struct xgene_enet_pdata *p) |
260 | ENET_INTERFACE_MODE2_SET(&data, 2); | 350 | { |
261 | xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2); | 351 | u32 enet_spare_cfg_reg, rsif_config_reg; |
262 | xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE); | 352 | u32 cfg_bypass_reg, rx_dv_gate_reg; |
353 | u32 data, offset; | ||
354 | |||
355 | xgene_sgmac_reset(p); | ||
356 | xgene_sgmii_enable_autoneg(p); | ||
357 | xgene_sgmac_set_speed(p); | ||
358 | xgene_sgmac_set_mac_addr(p); | ||
263 | 359 | ||
264 | if (p->enet_id == XGENE_ENET1) { | 360 | if (p->enet_id == XGENE_ENET1) { |
265 | enet_spare_cfg_reg = ENET_SPARE_CFG_REG_ADDR; | 361 | enet_spare_cfg_reg = ENET_SPARE_CFG_REG_ADDR; |
266 | rsif_config_reg = RSIF_CONFIG_REG_ADDR; | 362 | rsif_config_reg = RSIF_CONFIG_REG_ADDR; |
267 | cfg_bypass_reg = CFG_BYPASS_ADDR; | 363 | cfg_bypass_reg = CFG_BYPASS_ADDR; |
268 | rx_dv_gate_reg = SG_RX_DV_GATE_REG_0_ADDR; | 364 | offset = p->port_id * OFFSET_4; |
365 | rx_dv_gate_reg = SG_RX_DV_GATE_REG_0_ADDR + offset; | ||
269 | } else { | 366 | } else { |
270 | enet_spare_cfg_reg = XG_ENET_SPARE_CFG_REG_ADDR; | 367 | enet_spare_cfg_reg = XG_ENET_SPARE_CFG_REG_ADDR; |
271 | rsif_config_reg = XG_RSIF_CONFIG_REG_ADDR; | 368 | rsif_config_reg = XG_RSIF_CONFIG_REG_ADDR; |
@@ -277,8 +374,6 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p) | |||
277 | data |= MPA_IDLE_WITH_QMI_EMPTY; | 374 | data |= MPA_IDLE_WITH_QMI_EMPTY; |
278 | xgene_enet_wr_csr(p, enet_spare_cfg_reg, data); | 375 | xgene_enet_wr_csr(p, enet_spare_cfg_reg, data); |
279 | 376 | ||
280 | xgene_sgmac_set_mac_addr(p); | ||
281 | |||
282 | /* Adjust MDC clock frequency */ | 377 | /* Adjust MDC clock frequency */ |
283 | data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR); | 378 | data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR); |
284 | MGMT_CLOCK_SEL_SET(&data, 7); | 379 | MGMT_CLOCK_SEL_SET(&data, 7); |
@@ -292,7 +387,7 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p) | |||
292 | /* Bypass traffic gating */ | 387 | /* Bypass traffic gating */ |
293 | xgene_enet_wr_csr(p, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x84); | 388 | xgene_enet_wr_csr(p, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x84); |
294 | xgene_enet_wr_csr(p, cfg_bypass_reg, RESUME_TX); | 389 | xgene_enet_wr_csr(p, cfg_bypass_reg, RESUME_TX); |
295 | xgene_enet_wr_mcx_csr(p, rx_dv_gate_reg + offset, RESUME_RX0); | 390 | xgene_enet_wr_mcx_csr(p, rx_dv_gate_reg, RESUME_RX0); |
296 | } | 391 | } |
297 | 392 | ||
298 | static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set) | 393 | static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set) |
@@ -386,10 +481,11 @@ static void xgene_enet_link_state(struct work_struct *work) | |||
386 | if (link) { | 481 | if (link) { |
387 | if (!netif_carrier_ok(ndev)) { | 482 | if (!netif_carrier_ok(ndev)) { |
388 | netif_carrier_on(ndev); | 483 | netif_carrier_on(ndev); |
389 | xgene_sgmac_init(p); | 484 | xgene_sgmac_set_speed(p); |
390 | xgene_sgmac_rx_enable(p); | 485 | xgene_sgmac_rx_enable(p); |
391 | xgene_sgmac_tx_enable(p); | 486 | xgene_sgmac_tx_enable(p); |
392 | netdev_info(ndev, "Link is Up - 1Gbps\n"); | 487 | netdev_info(ndev, "Link is Up - %dMbps\n", |
488 | p->phy_speed); | ||
393 | } | 489 | } |
394 | poll_interval = PHY_POLL_LINK_ON; | 490 | poll_interval = PHY_POLL_LINK_ON; |
395 | } else { | 491 | } else { |
@@ -412,6 +508,7 @@ const struct xgene_mac_ops xgene_sgmac_ops = { | |||
412 | .tx_enable = xgene_sgmac_tx_enable, | 508 | .tx_enable = xgene_sgmac_tx_enable, |
413 | .rx_disable = xgene_sgmac_rx_disable, | 509 | .rx_disable = xgene_sgmac_rx_disable, |
414 | .tx_disable = xgene_sgmac_tx_disable, | 510 | .tx_disable = xgene_sgmac_tx_disable, |
511 | .set_speed = xgene_sgmac_set_speed, | ||
415 | .set_mac_addr = xgene_sgmac_set_mac_addr, | 512 | .set_mac_addr = xgene_sgmac_set_mac_addr, |
416 | .link_state = xgene_enet_link_state | 513 | .link_state = xgene_enet_link_state |
417 | }; | 514 | }; |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h index 002df5a6756e..32f140ab49d8 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define PHY_ADDR(src) (((src)<<8) & GENMASK(12, 8)) | 24 | #define PHY_ADDR(src) (((src)<<8) & GENMASK(12, 8)) |
25 | #define REG_ADDR(src) ((src) & GENMASK(4, 0)) | 25 | #define REG_ADDR(src) ((src) & GENMASK(4, 0)) |
26 | #define PHY_CONTROL(src) ((src) & GENMASK(15, 0)) | 26 | #define PHY_CONTROL(src) ((src) & GENMASK(15, 0)) |
27 | #define LINK_SPEED(src) (((src) & GENMASK(11, 10)) >> 10) | ||
27 | #define INT_PHY_ADDR 0x1e | 28 | #define INT_PHY_ADDR 0x1e |
28 | #define SGMII_TBI_CONTROL_ADDR 0x44 | 29 | #define SGMII_TBI_CONTROL_ADDR 0x44 |
29 | #define SGMII_CONTROL_ADDR 0x00 | 30 | #define SGMII_CONTROL_ADDR 0x00 |
@@ -35,6 +36,12 @@ | |||
35 | #define MPA_IDLE_WITH_QMI_EMPTY BIT(12) | 36 | #define MPA_IDLE_WITH_QMI_EMPTY BIT(12) |
36 | #define SG_RX_DV_GATE_REG_0_ADDR 0x05fc | 37 | #define SG_RX_DV_GATE_REG_0_ADDR 0x05fc |
37 | 38 | ||
39 | enum xgene_phy_speed { | ||
40 | PHY_SPEED_10, | ||
41 | PHY_SPEED_100, | ||
42 | PHY_SPEED_1000 | ||
43 | }; | ||
44 | |||
38 | extern const struct xgene_mac_ops xgene_sgmac_ops; | 45 | extern const struct xgene_mac_ops xgene_sgmac_ops; |
39 | extern const struct xgene_port_ops xgene_sgport_ops; | 46 | extern const struct xgene_port_ops xgene_sgport_ops; |
40 | 47 | ||
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h index 0a2dca8a1725..f1ea485f916b 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | |||
@@ -65,9 +65,12 @@ | |||
65 | #define XG_CFG_LINK_AGGR_RESUME_0_ADDR 0x0214 | 65 | #define XG_CFG_LINK_AGGR_RESUME_0_ADDR 0x0214 |
66 | #define XG_LINK_STATUS_ADDR 0x0228 | 66 | #define XG_LINK_STATUS_ADDR 0x0228 |
67 | #define XG_TSIF_MSS_REG0_ADDR 0x02a4 | 67 | #define XG_TSIF_MSS_REG0_ADDR 0x02a4 |
68 | #define XG_DEBUG_REG_ADDR 0x0400 | ||
68 | #define XG_ENET_SPARE_CFG_REG_ADDR 0x040c | 69 | #define XG_ENET_SPARE_CFG_REG_ADDR 0x040c |
69 | #define XG_ENET_SPARE_CFG_REG_1_ADDR 0x0410 | 70 | #define XG_ENET_SPARE_CFG_REG_1_ADDR 0x0410 |
70 | #define XGENET_RX_DV_GATE_REG_0_ADDR 0x0804 | 71 | #define XGENET_RX_DV_GATE_REG_0_ADDR 0x0804 |
72 | #define XG_MCX_ICM_CONFIG0_REG_0_ADDR 0x00e0 | ||
73 | #define XG_MCX_ICM_CONFIG2_REG_0_ADDR 0x00e8 | ||
71 | 74 | ||
72 | extern const struct xgene_mac_ops xgene_xgmac_ops; | 75 | extern const struct xgene_mac_ops xgene_xgmac_ops; |
73 | extern const struct xgene_port_ops xgene_xgport_ops; | 76 | extern const struct xgene_port_ops xgene_xgport_ops; |