aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/net/apm-xgene-mdio.txt37
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm64/boot/dts/apm/apm-merlin.dts6
-rw-r--r--arch/arm64/boot/dts/apm/apm-mustang.dts12
-rw-r--r--arch/arm64/boot/dts/apm/apm-shadowcat.dtsi11
-rw-r--r--arch/arm64/boot/dts/apm/apm-storm.dtsi26
-rw-r--r--drivers/net/ethernet/apm/xgene/Kconfig1
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c22
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_hw.c255
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_hw.h11
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c215
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.h33
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c239
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h8
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c66
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h3
-rw-r--r--drivers/net/phy/Kconfig6
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/mdio-xgene.c477
-rw-r--r--drivers/net/phy/mdio-xgene.h143
20 files changed, 1291 insertions, 283 deletions
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-mdio.txt b/Documentation/devicetree/bindings/net/apm-xgene-mdio.txt
new file mode 100644
index 000000000000..78722d74cea8
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/apm-xgene-mdio.txt
@@ -0,0 +1,37 @@
1APM X-Gene SoC MDIO node
2
3MDIO node is defined to describe on-chip MDIO controller.
4
5Required properties:
6 - compatible: Must be "apm,xgene-mdio-rgmii" or "apm,xgene-mdio-xfi"
7 - #address-cells: Must be <1>.
8 - #size-cells: Must be <0>.
9 - reg: Address and length of the register set
10 - clocks: Reference to the clock entry
11
12For the phys on the mdio bus, there must be a node with the following fields:
13 - compatible: PHY identifier. Please refer ./phy.txt for the format.
14 - reg: The ID number for the phy.
15
16Example:
17
18 mdio: mdio@17020000 {
19 compatible = "apm,xgene-mdio-rgmii";
20 #address-cells = <1>;
21 #size-cells = <0>;
22 reg = <0x0 0x17020000 0x0 0xd100>;
23 clocks = <&menetclk 0>;
24 };
25
26 /* Board-specific peripheral configurations */
27 &mdio {
28 menetphy: phy@3 {
29 reg = <0x3>;
30 };
31 sgenet0phy: phy@4 {
32 reg = <0x4>;
33 };
34 sgenet1phy: phy@5 {
35 reg = <0x5>;
36 };
37 };
diff --git a/MAINTAINERS b/MAINTAINERS
index dc3481d7c80d..a9bdba0484d1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -839,7 +839,9 @@ M: Iyappan Subramanian <isubramanian@apm.com>
839M: Keyur Chudgar <kchudgar@apm.com> 839M: Keyur Chudgar <kchudgar@apm.com>
840S: Supported 840S: Supported
841F: drivers/net/ethernet/apm/xgene/ 841F: drivers/net/ethernet/apm/xgene/
842F: drivers/net/phy/mdio-xgene.c
842F: Documentation/devicetree/bindings/net/apm-xgene-enet.txt 843F: Documentation/devicetree/bindings/net/apm-xgene-enet.txt
844F: Documentation/devicetree/bindings/net/apm-xgene-mdio.txt
843 845
844APTINA CAMERA SENSOR PLL 846APTINA CAMERA SENSOR PLL
845M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com> 847M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
diff --git a/arch/arm64/boot/dts/apm/apm-merlin.dts b/arch/arm64/boot/dts/apm/apm-merlin.dts
index 387c6a8d0da9..b0f64414c1b0 100644
--- a/arch/arm64/boot/dts/apm/apm-merlin.dts
+++ b/arch/arm64/boot/dts/apm/apm-merlin.dts
@@ -83,3 +83,9 @@
83 status = "ok"; 83 status = "ok";
84 }; 84 };
85}; 85};
86
87&mdio {
88 sgenet0phy: phy@0 {
89 reg = <0x0>;
90 };
91};
diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts
index 44db32ec5e9c..b7fb5d9295c2 100644
--- a/arch/arm64/boot/dts/apm/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm/apm-mustang.dts
@@ -79,3 +79,15 @@
79&mmc0 { 79&mmc0 {
80 status = "ok"; 80 status = "ok";
81}; 81};
82
83&mdio {
84 menet0phy: phy@3 {
85 reg = <0x3>;
86 };
87 sgenet0phy: phy@4 {
88 reg = <0x4>;
89 };
90 sgenet1phy: phy@5 {
91 reg = <0x5>;
92 };
93};
diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
index c569f761d090..2e1e5daa1dc7 100644
--- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
@@ -625,10 +625,18 @@
625 apm,irq-start = <8>; 625 apm,irq-start = <8>;
626 }; 626 };
627 627
628 mdio: mdio@1f610000 {
629 compatible = "apm,xgene-mdio-xfi";
630 #address-cells = <1>;
631 #size-cells = <0>;
632 reg = <0x0 0x1f610000 0x0 0xd100>;
633 clocks = <&xge0clk 0>;
634 };
635
628 sgenet0: ethernet@1f610000 { 636 sgenet0: ethernet@1f610000 {
629 compatible = "apm,xgene2-sgenet"; 637 compatible = "apm,xgene2-sgenet";
630 status = "disabled"; 638 status = "disabled";
631 reg = <0x0 0x1f610000 0x0 0x10000>, 639 reg = <0x0 0x1f610000 0x0 0xd100>,
632 <0x0 0x1f600000 0x0 0Xd100>, 640 <0x0 0x1f600000 0x0 0Xd100>,
633 <0x0 0x20000000 0x0 0X20000>; 641 <0x0 0x20000000 0x0 0X20000>;
634 interrupts = <0 96 4>, 642 interrupts = <0 96 4>,
@@ -637,6 +645,7 @@
637 clocks = <&xge0clk 0>; 645 clocks = <&xge0clk 0>;
638 local-mac-address = [00 01 73 00 00 01]; 646 local-mac-address = [00 01 73 00 00 01];
639 phy-connection-type = "sgmii"; 647 phy-connection-type = "sgmii";
648 phy-handle = <&sgenet0phy>;
640 }; 649 };
641 650
642 xgenet1: ethernet@1f620000 { 651 xgenet1: ethernet@1f620000 {
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index 5147d7698924..6bf7cbe2e72d 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -237,20 +237,11 @@
237 clocks = <&socplldiv2 0>; 237 clocks = <&socplldiv2 0>;
238 reg = <0x0 0x1f21c000 0x0 0x1000>; 238 reg = <0x0 0x1f21c000 0x0 0x1000>;
239 reg-names = "csr-reg"; 239 reg-names = "csr-reg";
240 csr-mask = <0x3>; 240 csr-mask = <0xa>;
241 enable-mask = <0xf>;
241 clock-output-names = "sge0clk"; 242 clock-output-names = "sge0clk";
242 }; 243 };
243 244
244 sge1clk: sge1clk@1f21c000 {
245 compatible = "apm,xgene-device-clock";
246 #clock-cells = <1>;
247 clocks = <&socplldiv2 0>;
248 reg = <0x0 0x1f21c000 0x0 0x1000>;
249 reg-names = "csr-reg";
250 csr-mask = <0xc>;
251 clock-output-names = "sge1clk";
252 };
253
254 xge0clk: xge0clk@1f61c000 { 245 xge0clk: xge0clk@1f61c000 {
255 compatible = "apm,xgene-device-clock"; 246 compatible = "apm,xgene-device-clock";
256 #clock-cells = <1>; 247 #clock-cells = <1>;
@@ -921,6 +912,14 @@
921 clocks = <&rtcclk 0>; 912 clocks = <&rtcclk 0>;
922 }; 913 };
923 914
915 mdio: mdio@17020000 {
916 compatible = "apm,xgene-mdio-rgmii";
917 #address-cells = <1>;
918 #size-cells = <0>;
919 reg = <0x0 0x17020000 0x0 0xd100>;
920 clocks = <&menetclk 0>;
921 };
922
924 menet: ethernet@17020000 { 923 menet: ethernet@17020000 {
925 compatible = "apm,xgene-enet"; 924 compatible = "apm,xgene-enet";
926 status = "disabled"; 925 status = "disabled";
@@ -934,7 +933,7 @@
934 /* mac address will be overwritten by the bootloader */ 933 /* mac address will be overwritten by the bootloader */
935 local-mac-address = [00 00 00 00 00 00]; 934 local-mac-address = [00 00 00 00 00 00];
936 phy-connection-type = "rgmii"; 935 phy-connection-type = "rgmii";
937 phy-handle = <&menetphy>; 936 phy-handle = <&menet0phy>,<&menetphy>;
938 mdio { 937 mdio {
939 compatible = "apm,xgene-mdio"; 938 compatible = "apm,xgene-mdio";
940 #address-cells = <1>; 939 #address-cells = <1>;
@@ -960,6 +959,7 @@
960 clocks = <&sge0clk 0>; 959 clocks = <&sge0clk 0>;
961 local-mac-address = [00 00 00 00 00 00]; 960 local-mac-address = [00 00 00 00 00 00];
962 phy-connection-type = "sgmii"; 961 phy-connection-type = "sgmii";
962 phy-handle = <&sgenet0phy>;
963 }; 963 };
964 964
965 sgenet1: ethernet@1f210030 { 965 sgenet1: ethernet@1f210030 {
@@ -973,9 +973,9 @@
973 <0x0 0xAD 0x4>; 973 <0x0 0xAD 0x4>;
974 port-id = <1>; 974 port-id = <1>;
975 dma-coherent; 975 dma-coherent;
976 clocks = <&sge1clk 0>;
977 local-mac-address = [00 00 00 00 00 00]; 976 local-mac-address = [00 00 00 00 00 00];
978 phy-connection-type = "sgmii"; 977 phy-connection-type = "sgmii";
978 phy-handle = <&sgenet1phy>;
979 }; 979 };
980 980
981 xgenet: ethernet@1f610000 { 981 xgenet: ethernet@1f610000 {
diff --git a/drivers/net/ethernet/apm/xgene/Kconfig b/drivers/net/ethernet/apm/xgene/Kconfig
index 19e38afbc5ee..300e3b5c54e0 100644
--- a/drivers/net/ethernet/apm/xgene/Kconfig
+++ b/drivers/net/ethernet/apm/xgene/Kconfig
@@ -3,6 +3,7 @@ config NET_XGENE
3 depends on HAS_DMA 3 depends on HAS_DMA
4 depends on ARCH_XGENE || COMPILE_TEST 4 depends on ARCH_XGENE || COMPILE_TEST
5 select PHYLIB 5 select PHYLIB
6 select MDIO_XGENE
6 help 7 help
7 This is the Ethernet driver for the on-chip ethernet interface on the 8 This is the Ethernet driver for the on-chip ethernet interface on the
8 APM X-Gene SoC. 9 APM X-Gene SoC.
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
index 416d6ebfc2ce..22a7b26ca1d6 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
@@ -65,8 +65,15 @@ static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
65 65
66 return phy_ethtool_gset(phydev, cmd); 66 return phy_ethtool_gset(phydev, cmd);
67 } else if (pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) { 67 } else if (pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) {
68 cmd->supported = SUPPORTED_1000baseT_Full | 68 if (pdata->mdio_driver) {
69 SUPPORTED_Autoneg | SUPPORTED_MII; 69 if (!phydev)
70 return -ENODEV;
71
72 return phy_ethtool_gset(phydev, cmd);
73 }
74
75 cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
76 SUPPORTED_MII;
70 cmd->advertising = cmd->supported; 77 cmd->advertising = cmd->supported;
71 ethtool_cmd_speed_set(cmd, SPEED_1000); 78 ethtool_cmd_speed_set(cmd, SPEED_1000);
72 cmd->duplex = DUPLEX_FULL; 79 cmd->duplex = DUPLEX_FULL;
@@ -92,12 +99,21 @@ static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
92 struct phy_device *phydev = pdata->phy_dev; 99 struct phy_device *phydev = pdata->phy_dev;
93 100
94 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) { 101 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
95 if (phydev == NULL) 102 if (!phydev)
96 return -ENODEV; 103 return -ENODEV;
97 104
98 return phy_ethtool_sset(phydev, cmd); 105 return phy_ethtool_sset(phydev, cmd);
99 } 106 }
100 107
108 if (pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) {
109 if (pdata->mdio_driver) {
110 if (!phydev)
111 return -ENODEV;
112
113 return phy_ethtool_sset(phydev, cmd);
114 }
115 }
116
101 return -EINVAL; 117 return -EINVAL;
102} 118}
103 119
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index 2f5638f7f864..8a2a221a9838 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -381,59 +381,6 @@ static void xgene_enet_rd_mcx_mac(struct xgene_enet_pdata *pdata,
381 rd_addr); 381 rd_addr);
382} 382}
383 383
384static int xgene_mii_phy_write(struct xgene_enet_pdata *pdata, int phy_id,
385 u32 reg, u16 data)
386{
387 u32 addr = 0, wr_data = 0;
388 u32 done;
389 u8 wait = 10;
390
391 PHY_ADDR_SET(&addr, phy_id);
392 REG_ADDR_SET(&addr, reg);
393 xgene_enet_wr_mcx_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
394
395 PHY_CONTROL_SET(&wr_data, data);
396 xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONTROL_ADDR, wr_data);
397 do {
398 usleep_range(5, 10);
399 xgene_enet_rd_mcx_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
400 } while ((done & BUSY_MASK) && wait--);
401
402 if (done & BUSY_MASK) {
403 netdev_err(pdata->ndev, "MII_MGMT write failed\n");
404 return -EBUSY;
405 }
406
407 return 0;
408}
409
410static int xgene_mii_phy_read(struct xgene_enet_pdata *pdata,
411 u8 phy_id, u32 reg)
412{
413 u32 addr = 0;
414 u32 data, done;
415 u8 wait = 10;
416
417 PHY_ADDR_SET(&addr, phy_id);
418 REG_ADDR_SET(&addr, reg);
419 xgene_enet_wr_mcx_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
420 xgene_enet_wr_mcx_mac(pdata, MII_MGMT_COMMAND_ADDR, READ_CYCLE_MASK);
421 do {
422 usleep_range(5, 10);
423 xgene_enet_rd_mcx_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
424 } while ((done & BUSY_MASK) && wait--);
425
426 if (done & BUSY_MASK) {
427 netdev_err(pdata->ndev, "MII_MGMT read failed\n");
428 return -EBUSY;
429 }
430
431 xgene_enet_rd_mcx_mac(pdata, MII_MGMT_STATUS_ADDR, &data);
432 xgene_enet_wr_mcx_mac(pdata, MII_MGMT_COMMAND_ADDR, 0);
433
434 return data;
435}
436
437static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata) 384static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
438{ 385{
439 u32 addr0, addr1; 386 u32 addr0, addr1;
@@ -512,14 +459,11 @@ static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
512#endif 459#endif
513} 460}
514 461
515static void xgene_gmac_init(struct xgene_enet_pdata *pdata) 462static void xgene_gmac_set_speed(struct xgene_enet_pdata *pdata)
516{ 463{
517 struct device *dev = &pdata->pdev->dev; 464 struct device *dev = &pdata->pdev->dev;
518 u32 value, mc2; 465 u32 icm0, icm2, mc2;
519 u32 intf_ctl, rgmii; 466 u32 intf_ctl, rgmii, value;
520 u32 icm0, icm2;
521
522 xgene_gmac_reset(pdata);
523 467
524 xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, &icm0); 468 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); 469 xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, &icm2);
@@ -564,7 +508,21 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
564 mc2 |= FULL_DUPLEX2 | PAD_CRC; 508 mc2 |= FULL_DUPLEX2 | PAD_CRC;
565 xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2); 509 xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
566 xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl); 510 xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
511 xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii);
512 xgene_enet_configure_clock(pdata);
513
514 xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, icm0);
515 xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, icm2);
516}
517
518static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
519{
520 u32 value;
567 521
522 if (!pdata->mdio_driver)
523 xgene_gmac_reset(pdata);
524
525 xgene_gmac_set_speed(pdata);
568 xgene_gmac_set_mac_addr(pdata); 526 xgene_gmac_set_mac_addr(pdata);
569 527
570 /* Adjust MDC clock frequency */ 528 /* Adjust MDC clock frequency */
@@ -579,15 +537,10 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
579 537
580 /* Rtype should be copied from FP */ 538 /* Rtype should be copied from FP */
581 xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0); 539 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 540
585 /* Rx-Tx traffic resume */ 541 /* Rx-Tx traffic resume */
586 xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); 542 xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);
587 543
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); 544 xgene_enet_rd_mcx_csr(pdata, RX_DV_GATE_REG_0_ADDR, &value);
592 value &= ~TX_DV_GATE_EN0; 545 value &= ~TX_DV_GATE_EN0;
593 value &= ~RX_DV_GATE_EN0; 546 value &= ~RX_DV_GATE_EN0;
@@ -671,92 +624,154 @@ bool xgene_ring_mgr_init(struct xgene_enet_pdata *p)
671 624
672static int xgene_enet_reset(struct xgene_enet_pdata *pdata) 625static int xgene_enet_reset(struct xgene_enet_pdata *pdata)
673{ 626{
674 u32 val; 627 struct device *dev = &pdata->pdev->dev;
675 628
676 if (!xgene_ring_mgr_init(pdata)) 629 if (!xgene_ring_mgr_init(pdata))
677 return -ENODEV; 630 return -ENODEV;
678 631
679 if (!IS_ERR(pdata->clk)) { 632 if (pdata->mdio_driver) {
633 xgene_enet_config_ring_if_assoc(pdata);
634 return 0;
635 }
636
637 if (dev->of_node) {
680 clk_prepare_enable(pdata->clk); 638 clk_prepare_enable(pdata->clk);
639 udelay(5);
681 clk_disable_unprepare(pdata->clk); 640 clk_disable_unprepare(pdata->clk);
641 udelay(5);
682 clk_prepare_enable(pdata->clk); 642 clk_prepare_enable(pdata->clk);
683 xgene_enet_ecc_init(pdata); 643 udelay(5);
644 } else {
645#ifdef CONFIG_ACPI
646 if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev), "_RST")) {
647 acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),
648 "_RST", NULL, NULL);
649 } else if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev),
650 "_INI")) {
651 acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),
652 "_INI", NULL, NULL);
653 }
654#endif
684 } 655 }
685 xgene_enet_config_ring_if_assoc(pdata);
686 656
687 /* Enable auto-incr for scanning */ 657 xgene_enet_ecc_init(pdata);
688 xgene_enet_rd_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, &val); 658 xgene_enet_config_ring_if_assoc(pdata);
689 val |= SCAN_AUTO_INCR;
690 MGMT_CLOCK_SEL_SET(&val, 1);
691 xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val);
692 659
693 return 0; 660 return 0;
694} 661}
695 662
696static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata) 663static void xgene_enet_clear(struct xgene_enet_pdata *pdata,
664 struct xgene_enet_desc_ring *ring)
697{ 665{
698 if (!IS_ERR(pdata->clk)) 666 u32 addr, val, data;
699 clk_disable_unprepare(pdata->clk);
700}
701 667
702static int xgene_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 668 val = xgene_enet_ring_bufnum(ring->id);
703{
704 struct xgene_enet_pdata *pdata = bus->priv;
705 u32 val;
706 669
707 val = xgene_mii_phy_read(pdata, mii_id, regnum); 670 if (xgene_enet_is_bufpool(ring->id)) {
708 netdev_dbg(pdata->ndev, "mdio_rd: bus=%d reg=%d val=%x\n", 671 addr = ENET_CFGSSQMIFPRESET_ADDR;
709 mii_id, regnum, val); 672 data = BIT(val - 0x20);
673 } else {
674 addr = ENET_CFGSSQMIWQRESET_ADDR;
675 data = BIT(val);
676 }
710 677
711 return val; 678 xgene_enet_wr_ring_if(pdata, addr, data);
712} 679}
713 680
714static int xgene_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, 681static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
715 u16 val)
716{ 682{
717 struct xgene_enet_pdata *pdata = bus->priv; 683 struct device *dev = &pdata->pdev->dev;
684 struct xgene_enet_desc_ring *ring;
685 u32 pb, val;
686 int i;
687
688 pb = 0;
689 for (i = 0; i < pdata->rxq_cnt; i++) {
690 ring = pdata->rx_ring[i]->buf_pool;
691
692 val = xgene_enet_ring_bufnum(ring->id);
693 pb |= BIT(val - 0x20);
694 }
695 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPRESET_ADDR, pb);
696
697 pb = 0;
698 for (i = 0; i < pdata->txq_cnt; i++) {
699 ring = pdata->tx_ring[i];
700
701 val = xgene_enet_ring_bufnum(ring->id);
702 pb |= BIT(val);
703 }
704 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQRESET_ADDR, pb);
718 705
719 netdev_dbg(pdata->ndev, "mdio_wr: bus=%d reg=%d val=%x\n", 706 if (dev->of_node) {
720 mii_id, regnum, val); 707 if (!IS_ERR(pdata->clk))
721 return xgene_mii_phy_write(pdata, mii_id, regnum, val); 708 clk_disable_unprepare(pdata->clk);
709 }
722} 710}
723 711
724static void xgene_enet_adjust_link(struct net_device *ndev) 712static void xgene_enet_adjust_link(struct net_device *ndev)
725{ 713{
726 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 714 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
715 const struct xgene_mac_ops *mac_ops = pdata->mac_ops;
727 struct phy_device *phydev = pdata->phy_dev; 716 struct phy_device *phydev = pdata->phy_dev;
728 717
729 if (phydev->link) { 718 if (phydev->link) {
730 if (pdata->phy_speed != phydev->speed) { 719 if (pdata->phy_speed != phydev->speed) {
731 pdata->phy_speed = phydev->speed; 720 pdata->phy_speed = phydev->speed;
732 xgene_gmac_init(pdata); 721 mac_ops->set_speed(pdata);
733 xgene_gmac_rx_enable(pdata); 722 mac_ops->rx_enable(pdata);
734 xgene_gmac_tx_enable(pdata); 723 mac_ops->tx_enable(pdata);
735 phy_print_status(phydev); 724 phy_print_status(phydev);
736 } 725 }
737 } else { 726 } else {
738 xgene_gmac_rx_disable(pdata); 727 mac_ops->rx_disable(pdata);
739 xgene_gmac_tx_disable(pdata); 728 mac_ops->tx_disable(pdata);
740 pdata->phy_speed = SPEED_UNKNOWN; 729 pdata->phy_speed = SPEED_UNKNOWN;
741 phy_print_status(phydev); 730 phy_print_status(phydev);
742 } 731 }
743} 732}
744 733
745static int xgene_enet_phy_connect(struct net_device *ndev) 734#ifdef CONFIG_ACPI
735static struct acpi_device *acpi_phy_find_device(struct device *dev)
736{
737 struct acpi_reference_args args;
738 struct fwnode_handle *fw_node;
739 int status;
740
741 fw_node = acpi_fwnode_handle(ACPI_COMPANION(dev));
742 status = acpi_node_get_property_reference(fw_node, "phy-handle", 0,
743 &args);
744 if (ACPI_FAILURE(status)) {
745 dev_dbg(dev, "No matching phy in ACPI table\n");
746 return NULL;
747 }
748
749 return args.adev;
750}
751#endif
752
753int xgene_enet_phy_connect(struct net_device *ndev)
746{ 754{
747 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 755 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
748 struct device_node *phy_np; 756 struct device_node *np;
749 struct phy_device *phy_dev; 757 struct phy_device *phy_dev;
750 struct device *dev = &pdata->pdev->dev; 758 struct device *dev = &pdata->pdev->dev;
759 struct acpi_device *adev;
760 int i;
751 761
752 if (dev->of_node) { 762 if (dev->of_node) {
753 phy_np = of_parse_phandle(dev->of_node, "phy-handle", 0); 763 for (i = 0 ; i < 2; i++) {
754 if (!phy_np) { 764 np = of_parse_phandle(dev->of_node, "phy-handle", i);
765 if (np)
766 break;
767 }
768
769 if (!np) {
755 netdev_dbg(ndev, "No phy-handle found in DT\n"); 770 netdev_dbg(ndev, "No phy-handle found in DT\n");
756 return -ENODEV; 771 return -ENODEV;
757 } 772 }
758 773
759 phy_dev = of_phy_connect(ndev, phy_np, &xgene_enet_adjust_link, 774 phy_dev = of_phy_connect(ndev, np, &xgene_enet_adjust_link,
760 0, pdata->phy_mode); 775 0, pdata->phy_mode);
761 if (!phy_dev) { 776 if (!phy_dev) {
762 netdev_err(ndev, "Could not connect to PHY\n"); 777 netdev_err(ndev, "Could not connect to PHY\n");
@@ -765,6 +780,11 @@ static int xgene_enet_phy_connect(struct net_device *ndev)
765 780
766 pdata->phy_dev = phy_dev; 781 pdata->phy_dev = phy_dev;
767 } else { 782 } else {
783#ifdef CONFIG_ACPI
784 adev = acpi_phy_find_device(dev);
785 if (adev)
786 pdata->phy_dev = adev->driver_data;
787
768 phy_dev = pdata->phy_dev; 788 phy_dev = pdata->phy_dev;
769 789
770 if (!phy_dev || 790 if (!phy_dev ||
@@ -773,6 +793,7 @@ static int xgene_enet_phy_connect(struct net_device *ndev)
773 netdev_err(ndev, "Could not connect to PHY\n"); 793 netdev_err(ndev, "Could not connect to PHY\n");
774 return -ENODEV; 794 return -ENODEV;
775 } 795 }
796#endif
776 } 797 }
777 798
778 pdata->phy_speed = SPEED_UNKNOWN; 799 pdata->phy_speed = SPEED_UNKNOWN;
@@ -792,8 +813,8 @@ static int xgene_mdiobus_register(struct xgene_enet_pdata *pdata,
792 struct phy_device *phy; 813 struct phy_device *phy;
793 struct device_node *child_np; 814 struct device_node *child_np;
794 struct device_node *mdio_np = NULL; 815 struct device_node *mdio_np = NULL;
816 u32 phy_addr;
795 int ret; 817 int ret;
796 u32 phy_id;
797 818
798 if (dev->of_node) { 819 if (dev->of_node) {
799 for_each_child_of_node(dev->of_node, child_np) { 820 for_each_child_of_node(dev->of_node, child_np) {
@@ -820,21 +841,17 @@ static int xgene_mdiobus_register(struct xgene_enet_pdata *pdata,
820 if (ret) 841 if (ret)
821 return ret; 842 return ret;
822 843
823 ret = device_property_read_u32(dev, "phy-channel", &phy_id); 844 ret = device_property_read_u32(dev, "phy-channel", &phy_addr);
824 if (ret) 845 if (ret)
825 ret = device_property_read_u32(dev, "phy-addr", &phy_id); 846 ret = device_property_read_u32(dev, "phy-addr", &phy_addr);
826 if (ret) 847 if (ret)
827 return -EINVAL; 848 return -EINVAL;
828 849
829 phy = get_phy_device(mdio, phy_id, false); 850 phy = xgene_enet_phy_register(mdio, phy_addr);
830 if (IS_ERR(phy)) 851 if (!phy)
831 return -EIO; 852 return -EIO;
832 853
833 ret = phy_device_register(phy); 854 pdata->phy_dev = phy;
834 if (ret)
835 phy_device_free(phy);
836 else
837 pdata->phy_dev = phy;
838 855
839 return ret; 856 return ret;
840} 857}
@@ -850,13 +867,13 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
850 return -ENOMEM; 867 return -ENOMEM;
851 868
852 mdio_bus->name = "APM X-Gene MDIO bus"; 869 mdio_bus->name = "APM X-Gene MDIO bus";
853 mdio_bus->read = xgene_enet_mdio_read; 870 mdio_bus->read = xgene_mdio_rgmii_read;
854 mdio_bus->write = xgene_enet_mdio_write; 871 mdio_bus->write = xgene_mdio_rgmii_write;
855 snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%s", "xgene-mii", 872 snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%s", "xgene-mii",
856 ndev->name); 873 ndev->name);
857 874
858 mdio_bus->priv = pdata; 875 mdio_bus->priv = (void __force *)pdata->mcx_mac_addr;
859 mdio_bus->parent = &ndev->dev; 876 mdio_bus->parent = &pdata->pdev->dev;
860 877
861 ret = xgene_mdiobus_register(pdata, mdio_bus); 878 ret = xgene_mdiobus_register(pdata, mdio_bus);
862 if (ret) { 879 if (ret) {
@@ -873,6 +890,12 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
873 return ret; 890 return ret;
874} 891}
875 892
893void xgene_enet_phy_disconnect(struct xgene_enet_pdata *pdata)
894{
895 if (pdata->phy_dev)
896 phy_disconnect(pdata->phy_dev);
897}
898
876void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata) 899void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata)
877{ 900{
878 if (pdata->phy_dev) 901 if (pdata->phy_dev)
@@ -890,11 +913,13 @@ const struct xgene_mac_ops xgene_gmac_ops = {
890 .tx_enable = xgene_gmac_tx_enable, 913 .tx_enable = xgene_gmac_tx_enable,
891 .rx_disable = xgene_gmac_rx_disable, 914 .rx_disable = xgene_gmac_rx_disable,
892 .tx_disable = xgene_gmac_tx_disable, 915 .tx_disable = xgene_gmac_tx_disable,
916 .set_speed = xgene_gmac_set_speed,
893 .set_mac_addr = xgene_gmac_set_mac_addr, 917 .set_mac_addr = xgene_gmac_set_mac_addr,
894}; 918};
895 919
896const struct xgene_port_ops xgene_gport_ops = { 920const struct xgene_port_ops xgene_gport_ops = {
897 .reset = xgene_enet_reset, 921 .reset = xgene_enet_reset,
922 .clear = xgene_enet_clear,
898 .cle_bypass = xgene_enet_cle_bypass, 923 .cle_bypass = xgene_enet_cle_bypass,
899 .shutdown = xgene_gport_shutdown, 924 .shutdown = xgene_gport_shutdown,
900}; 925};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 45220be3122f..179a44dceb29 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
@@ -165,6 +167,8 @@ enum xgene_enet_rm {
165#define TX_DV_GATE_EN0 BIT(2) 167#define TX_DV_GATE_EN0 BIT(2)
166#define RX_DV_GATE_EN0 BIT(1) 168#define RX_DV_GATE_EN0 BIT(1)
167#define RESUME_RX0 BIT(0) 169#define RESUME_RX0 BIT(0)
170#define ENET_CFGSSQMIFPRESET_ADDR 0x14
171#define ENET_CFGSSQMIWQRESET_ADDR 0x1c
168#define ENET_CFGSSQMIWQASSOC_ADDR 0xe0 172#define ENET_CFGSSQMIWQASSOC_ADDR 0xe0
169#define ENET_CFGSSQMIFPQASSOC_ADDR 0xdc 173#define ENET_CFGSSQMIFPQASSOC_ADDR 0xdc
170#define ENET_CFGSSQMIQMLITEFPQASSOC_ADDR 0xf0 174#define ENET_CFGSSQMIQMLITEFPQASSOC_ADDR 0xf0
@@ -297,11 +301,6 @@ enum xgene_enet_ring_bufnum {
297 RING_BUFNUM_INVALID 301 RING_BUFNUM_INVALID
298}; 302};
299 303
300enum xgene_enet_cmd {
301 XGENE_ENET_WR_CMD = BIT(31),
302 XGENE_ENET_RD_CMD = BIT(30)
303};
304
305enum xgene_enet_err_code { 304enum xgene_enet_err_code {
306 HBF_READ_DATA = 3, 305 HBF_READ_DATA = 3,
307 HBF_LL_READ = 4, 306 HBF_LL_READ = 4,
@@ -347,6 +346,8 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
347int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata); 346int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata);
348void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata); 347void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata);
349bool xgene_ring_mgr_init(struct xgene_enet_pdata *p); 348bool xgene_ring_mgr_init(struct xgene_enet_pdata *p);
349int xgene_enet_phy_connect(struct net_device *ndev);
350void xgene_enet_phy_disconnect(struct xgene_enet_pdata *pdata);
350 351
351extern const struct xgene_mac_ops xgene_gmac_ops; 352extern const struct xgene_mac_ops xgene_gmac_ops;
352extern const struct xgene_port_ops xgene_gport_ops; 353extern const struct xgene_port_ops xgene_gport_ops;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index d208b172f4d7..d1d6b5eeb613 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -102,25 +102,13 @@ static u8 xgene_enet_hdr_len(const void *data)
102 102
103static void xgene_enet_delete_bufpool(struct xgene_enet_desc_ring *buf_pool) 103static void xgene_enet_delete_bufpool(struct xgene_enet_desc_ring *buf_pool)
104{ 104{
105 struct xgene_enet_pdata *pdata = netdev_priv(buf_pool->ndev); 105 int i;
106 struct xgene_enet_raw_desc16 *raw_desc;
107 u32 slots = buf_pool->slots - 1;
108 u32 tail = buf_pool->tail;
109 u32 userinfo;
110 int i, len;
111
112 len = pdata->ring_ops->len(buf_pool);
113 for (i = 0; i < len; i++) {
114 tail = (tail - 1) & slots;
115 raw_desc = &buf_pool->raw_desc16[tail];
116 106
117 /* Hardware stores descriptor in little endian format */ 107 /* Free up the buffers held by hardware */
118 userinfo = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0)); 108 for (i = 0; i < buf_pool->slots; i++) {
119 dev_kfree_skb_any(buf_pool->rx_skb[userinfo]); 109 if (buf_pool->rx_skb[i])
110 dev_kfree_skb_any(buf_pool->rx_skb[i]);
120 } 111 }
121
122 pdata->ring_ops->wr_cmd(buf_pool, -len);
123 buf_pool->tail = tail;
124} 112}
125 113
126static irqreturn_t xgene_enet_rx_irq(const int irq, void *data) 114static irqreturn_t xgene_enet_rx_irq(const int irq, void *data)
@@ -481,6 +469,7 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
481 XGENE_ENET_MAX_MTU, DMA_FROM_DEVICE); 469 XGENE_ENET_MAX_MTU, DMA_FROM_DEVICE);
482 skb_index = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0)); 470 skb_index = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0));
483 skb = buf_pool->rx_skb[skb_index]; 471 skb = buf_pool->rx_skb[skb_index];
472 buf_pool->rx_skb[skb_index] = NULL;
484 473
485 /* checking for error */ 474 /* checking for error */
486 status = (GET_VAL(ELERR, le64_to_cpu(raw_desc->m0)) << LERR_LEN) || 475 status = (GET_VAL(ELERR, le64_to_cpu(raw_desc->m0)) << LERR_LEN) ||
@@ -619,6 +608,30 @@ static void xgene_enet_timeout(struct net_device *ndev)
619 } 608 }
620} 609}
621 610
611static void xgene_enet_set_irq_name(struct net_device *ndev)
612{
613 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
614 struct xgene_enet_desc_ring *ring;
615 int i;
616
617 for (i = 0; i < pdata->rxq_cnt; i++) {
618 ring = pdata->rx_ring[i];
619 if (!pdata->cq_cnt) {
620 snprintf(ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
621 ndev->name);
622 } else {
623 snprintf(ring->irq_name, IRQ_ID_SIZE, "%s-rx-%d",
624 ndev->name, i);
625 }
626 }
627
628 for (i = 0; i < pdata->cq_cnt; i++) {
629 ring = pdata->tx_ring[i]->cp_ring;
630 snprintf(ring->irq_name, IRQ_ID_SIZE, "%s-txc-%d",
631 ndev->name, i);
632 }
633}
634
622static int xgene_enet_register_irq(struct net_device *ndev) 635static int xgene_enet_register_irq(struct net_device *ndev)
623{ 636{
624 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 637 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
@@ -626,6 +639,7 @@ static int xgene_enet_register_irq(struct net_device *ndev)
626 struct xgene_enet_desc_ring *ring; 639 struct xgene_enet_desc_ring *ring;
627 int ret = 0, i; 640 int ret = 0, i;
628 641
642 xgene_enet_set_irq_name(ndev);
629 for (i = 0; i < pdata->rxq_cnt; i++) { 643 for (i = 0; i < pdata->rxq_cnt; i++) {
630 ring = pdata->rx_ring[i]; 644 ring = pdata->rx_ring[i];
631 irq_set_status_flags(ring->irq, IRQ_DISABLE_UNLAZY); 645 irq_set_status_flags(ring->irq, IRQ_DISABLE_UNLAZY);
@@ -720,20 +734,21 @@ static int xgene_enet_open(struct net_device *ndev)
720 if (ret) 734 if (ret)
721 return ret; 735 return ret;
722 736
723 mac_ops->tx_enable(pdata);
724 mac_ops->rx_enable(pdata);
725
726 xgene_enet_napi_enable(pdata); 737 xgene_enet_napi_enable(pdata);
727 ret = xgene_enet_register_irq(ndev); 738 ret = xgene_enet_register_irq(ndev);
728 if (ret) 739 if (ret)
729 return ret; 740 return ret;
730 741
731 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) 742 if (pdata->phy_dev) {
732 phy_start(pdata->phy_dev); 743 phy_start(pdata->phy_dev);
733 else 744 } else {
734 schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF); 745 schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF);
746 netif_carrier_off(ndev);
747 }
735 748
736 netif_start_queue(ndev); 749 mac_ops->tx_enable(pdata);
750 mac_ops->rx_enable(pdata);
751 netif_tx_start_all_queues(ndev);
737 752
738 return ret; 753 return ret;
739} 754}
@@ -744,16 +759,15 @@ static int xgene_enet_close(struct net_device *ndev)
744 const struct xgene_mac_ops *mac_ops = pdata->mac_ops; 759 const struct xgene_mac_ops *mac_ops = pdata->mac_ops;
745 int i; 760 int i;
746 761
747 netif_stop_queue(ndev); 762 netif_tx_stop_all_queues(ndev);
763 mac_ops->tx_disable(pdata);
764 mac_ops->rx_disable(pdata);
748 765
749 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) 766 if (pdata->phy_dev)
750 phy_stop(pdata->phy_dev); 767 phy_stop(pdata->phy_dev);
751 else 768 else
752 cancel_delayed_work_sync(&pdata->link_work); 769 cancel_delayed_work_sync(&pdata->link_work);
753 770
754 mac_ops->tx_disable(pdata);
755 mac_ops->rx_disable(pdata);
756
757 xgene_enet_free_irq(ndev); 771 xgene_enet_free_irq(ndev);
758 xgene_enet_napi_disable(pdata); 772 xgene_enet_napi_disable(pdata);
759 for (i = 0; i < pdata->rxq_cnt; i++) 773 for (i = 0; i < pdata->rxq_cnt; i++)
@@ -761,7 +775,6 @@ static int xgene_enet_close(struct net_device *ndev)
761 775
762 return 0; 776 return 0;
763} 777}
764
765static void xgene_enet_delete_ring(struct xgene_enet_desc_ring *ring) 778static void xgene_enet_delete_ring(struct xgene_enet_desc_ring *ring)
766{ 779{
767 struct xgene_enet_pdata *pdata; 780 struct xgene_enet_pdata *pdata;
@@ -771,7 +784,7 @@ static void xgene_enet_delete_ring(struct xgene_enet_desc_ring *ring)
771 dev = ndev_to_dev(ring->ndev); 784 dev = ndev_to_dev(ring->ndev);
772 785
773 pdata->ring_ops->clear(ring); 786 pdata->ring_ops->clear(ring);
774 dma_free_coherent(dev, ring->size, ring->desc_addr, ring->dma); 787 dmam_free_coherent(dev, ring->size, ring->desc_addr, ring->dma);
775} 788}
776 789
777static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata) 790static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata)
@@ -784,6 +797,9 @@ static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata)
784 ring = pdata->tx_ring[i]; 797 ring = pdata->tx_ring[i];
785 if (ring) { 798 if (ring) {
786 xgene_enet_delete_ring(ring); 799 xgene_enet_delete_ring(ring);
800 pdata->port_ops->clear(pdata, ring);
801 if (pdata->cq_cnt)
802 xgene_enet_delete_ring(ring->cp_ring);
787 pdata->tx_ring[i] = NULL; 803 pdata->tx_ring[i] = NULL;
788 } 804 }
789 } 805 }
@@ -794,6 +810,7 @@ static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata)
794 buf_pool = ring->buf_pool; 810 buf_pool = ring->buf_pool;
795 xgene_enet_delete_bufpool(buf_pool); 811 xgene_enet_delete_bufpool(buf_pool);
796 xgene_enet_delete_ring(buf_pool); 812 xgene_enet_delete_ring(buf_pool);
813 pdata->port_ops->clear(pdata, buf_pool);
797 xgene_enet_delete_ring(ring); 814 xgene_enet_delete_ring(ring);
798 pdata->rx_ring[i] = NULL; 815 pdata->rx_ring[i] = NULL;
799 } 816 }
@@ -842,7 +859,7 @@ static void xgene_enet_free_desc_ring(struct xgene_enet_desc_ring *ring)
842 859
843 if (ring->desc_addr) { 860 if (ring->desc_addr) {
844 pdata->ring_ops->clear(ring); 861 pdata->ring_ops->clear(ring);
845 dma_free_coherent(dev, ring->size, ring->desc_addr, ring->dma); 862 dmam_free_coherent(dev, ring->size, ring->desc_addr, ring->dma);
846 } 863 }
847 devm_kfree(dev, ring); 864 devm_kfree(dev, ring);
848} 865}
@@ -900,9 +917,10 @@ static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
900 struct net_device *ndev, u32 ring_num, 917 struct net_device *ndev, u32 ring_num,
901 enum xgene_enet_ring_cfgsize cfgsize, u32 ring_id) 918 enum xgene_enet_ring_cfgsize cfgsize, u32 ring_id)
902{ 919{
903 struct xgene_enet_desc_ring *ring;
904 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 920 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
905 struct device *dev = ndev_to_dev(ndev); 921 struct device *dev = ndev_to_dev(ndev);
922 struct xgene_enet_desc_ring *ring;
923 void *irq_mbox_addr;
906 int size; 924 int size;
907 925
908 size = xgene_enet_get_ring_size(dev, cfgsize); 926 size = xgene_enet_get_ring_size(dev, cfgsize);
@@ -919,8 +937,8 @@ static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
919 ring->cfgsize = cfgsize; 937 ring->cfgsize = cfgsize;
920 ring->id = ring_id; 938 ring->id = ring_id;
921 939
922 ring->desc_addr = dma_zalloc_coherent(dev, size, &ring->dma, 940 ring->desc_addr = dmam_alloc_coherent(dev, size, &ring->dma,
923 GFP_KERNEL); 941 GFP_KERNEL | __GFP_ZERO);
924 if (!ring->desc_addr) { 942 if (!ring->desc_addr) {
925 devm_kfree(dev, ring); 943 devm_kfree(dev, ring);
926 return NULL; 944 return NULL;
@@ -928,14 +946,16 @@ static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
928 ring->size = size; 946 ring->size = size;
929 947
930 if (is_irq_mbox_required(pdata, ring)) { 948 if (is_irq_mbox_required(pdata, ring)) {
931 ring->irq_mbox_addr = dma_zalloc_coherent(dev, INTR_MBOX_SIZE, 949 irq_mbox_addr = dmam_alloc_coherent(dev, INTR_MBOX_SIZE,
932 &ring->irq_mbox_dma, GFP_KERNEL); 950 &ring->irq_mbox_dma,
933 if (!ring->irq_mbox_addr) { 951 GFP_KERNEL | __GFP_ZERO);
934 dma_free_coherent(dev, size, ring->desc_addr, 952 if (!irq_mbox_addr) {
935 ring->dma); 953 dmam_free_coherent(dev, size, ring->desc_addr,
954 ring->dma);
936 devm_kfree(dev, ring); 955 devm_kfree(dev, ring);
937 return NULL; 956 return NULL;
938 } 957 }
958 ring->irq_mbox_addr = irq_mbox_addr;
939 } 959 }
940 960
941 ring->cmd_base = xgene_enet_ring_cmd_base(pdata, ring); 961 ring->cmd_base = xgene_enet_ring_cmd_base(pdata, ring);
@@ -996,6 +1016,7 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
996 u8 eth_bufnum = pdata->eth_bufnum; 1016 u8 eth_bufnum = pdata->eth_bufnum;
997 u8 bp_bufnum = pdata->bp_bufnum; 1017 u8 bp_bufnum = pdata->bp_bufnum;
998 u16 ring_num = pdata->ring_num; 1018 u16 ring_num = pdata->ring_num;
1019 __le64 *exp_bufs;
999 u16 ring_id; 1020 u16 ring_id;
1000 int i, ret, size; 1021 int i, ret, size;
1001 1022
@@ -1027,13 +1048,6 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
1027 rx_ring->nbufpool = NUM_BUFPOOL; 1048 rx_ring->nbufpool = NUM_BUFPOOL;
1028 rx_ring->buf_pool = buf_pool; 1049 rx_ring->buf_pool = buf_pool;
1029 rx_ring->irq = pdata->irqs[i]; 1050 rx_ring->irq = pdata->irqs[i];
1030 if (!pdata->cq_cnt) {
1031 snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
1032 ndev->name);
1033 } else {
1034 snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx%d",
1035 ndev->name, i);
1036 }
1037 buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots, 1051 buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
1038 sizeof(struct sk_buff *), 1052 sizeof(struct sk_buff *),
1039 GFP_KERNEL); 1053 GFP_KERNEL);
@@ -1060,13 +1074,13 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
1060 } 1074 }
1061 1075
1062 size = (tx_ring->slots / 2) * sizeof(__le64) * MAX_EXP_BUFFS; 1076 size = (tx_ring->slots / 2) * sizeof(__le64) * MAX_EXP_BUFFS;
1063 tx_ring->exp_bufs = dma_zalloc_coherent(dev, size, 1077 exp_bufs = dmam_alloc_coherent(dev, size, &dma_exp_bufs,
1064 &dma_exp_bufs, 1078 GFP_KERNEL | __GFP_ZERO);
1065 GFP_KERNEL); 1079 if (!exp_bufs) {
1066 if (!tx_ring->exp_bufs) {
1067 ret = -ENOMEM; 1080 ret = -ENOMEM;
1068 goto err; 1081 goto err;
1069 } 1082 }
1083 tx_ring->exp_bufs = exp_bufs;
1070 1084
1071 pdata->tx_ring[i] = tx_ring; 1085 pdata->tx_ring[i] = tx_ring;
1072 1086
@@ -1086,8 +1100,6 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
1086 1100
1087 cp_ring->irq = pdata->irqs[pdata->rxq_cnt + i]; 1101 cp_ring->irq = pdata->irqs[pdata->rxq_cnt + i];
1088 cp_ring->index = i; 1102 cp_ring->index = i;
1089 snprintf(cp_ring->irq_name, IRQ_ID_SIZE, "%s-txc%d",
1090 ndev->name, i);
1091 } 1103 }
1092 1104
1093 cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots, 1105 cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots,
@@ -1283,6 +1295,23 @@ static int xgene_enet_get_irqs(struct xgene_enet_pdata *pdata)
1283 return 0; 1295 return 0;
1284} 1296}
1285 1297
1298static int xgene_enet_check_phy_handle(struct xgene_enet_pdata *pdata)
1299{
1300 int ret;
1301
1302 if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII)
1303 return 0;
1304
1305 if (!IS_ENABLED(CONFIG_MDIO_XGENE))
1306 return 0;
1307
1308 ret = xgene_enet_phy_connect(pdata->ndev);
1309 if (!ret)
1310 pdata->mdio_driver = true;
1311
1312 return 0;
1313}
1314
1286static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) 1315static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
1287{ 1316{
1288 struct platform_device *pdev; 1317 struct platform_device *pdev;
@@ -1368,6 +1397,10 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
1368 if (ret) 1397 if (ret)
1369 return ret; 1398 return ret;
1370 1399
1400 ret = xgene_enet_check_phy_handle(pdata);
1401 if (ret)
1402 return ret;
1403
1371 pdata->clk = devm_clk_get(&pdev->dev, NULL); 1404 pdata->clk = devm_clk_get(&pdev->dev, NULL);
1372 if (IS_ERR(pdata->clk)) { 1405 if (IS_ERR(pdata->clk)) {
1373 /* Firmware may have set up the clock already. */ 1406 /* Firmware may have set up the clock already. */
@@ -1447,6 +1480,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); 1480 pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
1448 } 1481 }
1449 1482
1483 pdata->phy_speed = SPEED_UNKNOWN;
1450 pdata->mac_ops->init(pdata); 1484 pdata->mac_ops->init(pdata);
1451 1485
1452 return ret; 1486 return ret;
@@ -1556,28 +1590,12 @@ static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata)
1556 } 1590 }
1557} 1591}
1558 1592
1559static void xgene_enet_napi_del(struct xgene_enet_pdata *pdata)
1560{
1561 struct napi_struct *napi;
1562 int i;
1563
1564 for (i = 0; i < pdata->rxq_cnt; i++) {
1565 napi = &pdata->rx_ring[i]->napi;
1566 netif_napi_del(napi);
1567 }
1568
1569 for (i = 0; i < pdata->cq_cnt; i++) {
1570 napi = &pdata->tx_ring[i]->cp_ring->napi;
1571 netif_napi_del(napi);
1572 }
1573}
1574
1575static int xgene_enet_probe(struct platform_device *pdev) 1593static int xgene_enet_probe(struct platform_device *pdev)
1576{ 1594{
1577 struct net_device *ndev; 1595 struct net_device *ndev;
1578 struct xgene_enet_pdata *pdata; 1596 struct xgene_enet_pdata *pdata;
1579 struct device *dev = &pdev->dev; 1597 struct device *dev = &pdev->dev;
1580 const struct xgene_mac_ops *mac_ops; 1598 void (*link_state)(struct work_struct *);
1581 const struct of_device_id *of_id; 1599 const struct of_device_id *of_id;
1582 int ret; 1600 int ret;
1583 1601
@@ -1635,27 +1653,31 @@ static int xgene_enet_probe(struct platform_device *pdev)
1635 goto err; 1653 goto err;
1636 } 1654 }
1637 1655
1638 ret = register_netdev(ndev);
1639 if (ret) {
1640 netdev_err(ndev, "Failed to register netdev\n");
1641 goto err;
1642 }
1643
1644 ret = xgene_enet_init_hw(pdata); 1656 ret = xgene_enet_init_hw(pdata);
1645 if (ret) 1657 if (ret)
1646 goto err_netdev; 1658 goto err_netdev;
1647 1659
1648 mac_ops = pdata->mac_ops; 1660 link_state = pdata->mac_ops->link_state;
1649 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) { 1661 if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
1650 ret = xgene_enet_mdio_config(pdata); 1662 INIT_DELAYED_WORK(&pdata->link_work, link_state);
1651 if (ret) 1663 } else if (!pdata->mdio_driver) {
1652 goto err_netdev; 1664 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
1653 } else { 1665 ret = xgene_enet_mdio_config(pdata);
1654 INIT_DELAYED_WORK(&pdata->link_work, mac_ops->link_state); 1666 else
1667 INIT_DELAYED_WORK(&pdata->link_work, link_state);
1655 } 1668 }
1669 if (ret)
1670 goto err;
1656 1671
1657 xgene_enet_napi_add(pdata); 1672 xgene_enet_napi_add(pdata);
1673 ret = register_netdev(ndev);
1674 if (ret) {
1675 netdev_err(ndev, "Failed to register netdev\n");
1676 goto err;
1677 }
1678
1658 return 0; 1679 return 0;
1680
1659err_netdev: 1681err_netdev:
1660 unregister_netdev(ndev); 1682 unregister_netdev(ndev);
1661err: 1683err:
@@ -1673,20 +1695,38 @@ static int xgene_enet_remove(struct platform_device *pdev)
1673 mac_ops = pdata->mac_ops; 1695 mac_ops = pdata->mac_ops;
1674 ndev = pdata->ndev; 1696 ndev = pdata->ndev;
1675 1697
1676 mac_ops->rx_disable(pdata); 1698 rtnl_lock();
1677 mac_ops->tx_disable(pdata); 1699 if (netif_running(ndev))
1700 dev_close(ndev);
1701 rtnl_unlock();
1678 1702
1679 xgene_enet_napi_del(pdata); 1703 if (pdata->mdio_driver)
1680 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) 1704 xgene_enet_phy_disconnect(pdata);
1705 else if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
1681 xgene_enet_mdio_remove(pdata); 1706 xgene_enet_mdio_remove(pdata);
1707
1682 unregister_netdev(ndev); 1708 unregister_netdev(ndev);
1683 xgene_enet_delete_desc_rings(pdata);
1684 pdata->port_ops->shutdown(pdata); 1709 pdata->port_ops->shutdown(pdata);
1710 xgene_enet_delete_desc_rings(pdata);
1685 free_netdev(ndev); 1711 free_netdev(ndev);
1686 1712
1687 return 0; 1713 return 0;
1688} 1714}
1689 1715
1716static void xgene_enet_shutdown(struct platform_device *pdev)
1717{
1718 struct xgene_enet_pdata *pdata;
1719
1720 pdata = platform_get_drvdata(pdev);
1721 if (!pdata)
1722 return;
1723
1724 if (!pdata->ndev)
1725 return;
1726
1727 xgene_enet_remove(pdev);
1728}
1729
1690#ifdef CONFIG_ACPI 1730#ifdef CONFIG_ACPI
1691static const struct acpi_device_id xgene_enet_acpi_match[] = { 1731static const struct acpi_device_id xgene_enet_acpi_match[] = {
1692 { "APMC0D05", XGENE_ENET1}, 1732 { "APMC0D05", XGENE_ENET1},
@@ -1721,6 +1761,7 @@ static struct platform_driver xgene_enet_driver = {
1721 }, 1761 },
1722 .probe = xgene_enet_probe, 1762 .probe = xgene_enet_probe,
1723 .remove = xgene_enet_remove, 1763 .remove = xgene_enet_remove,
1764 .shutdown = xgene_enet_shutdown,
1724}; 1765};
1725 1766
1726module_platform_driver(xgene_enet_driver); 1767module_platform_driver(xgene_enet_driver);
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 092fbeccaa20..217546e5714a 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -38,6 +38,7 @@
38#include "xgene_enet_hw.h" 38#include "xgene_enet_hw.h"
39#include "xgene_enet_cle.h" 39#include "xgene_enet_cle.h"
40#include "xgene_enet_ring2.h" 40#include "xgene_enet_ring2.h"
41#include "../../../phy/mdio-xgene.h"
41 42
42#define XGENE_DRV_VERSION "v1.0" 43#define XGENE_DRV_VERSION "v1.0"
43#define XGENE_ENET_MAX_MTU 1536 44#define XGENE_ENET_MAX_MTU 1536
@@ -140,6 +141,7 @@ struct xgene_mac_ops {
140 void (*rx_enable)(struct xgene_enet_pdata *pdata); 141 void (*rx_enable)(struct xgene_enet_pdata *pdata);
141 void (*tx_disable)(struct xgene_enet_pdata *pdata); 142 void (*tx_disable)(struct xgene_enet_pdata *pdata);
142 void (*rx_disable)(struct xgene_enet_pdata *pdata); 143 void (*rx_disable)(struct xgene_enet_pdata *pdata);
144 void (*set_speed)(struct xgene_enet_pdata *pdata);
143 void (*set_mac_addr)(struct xgene_enet_pdata *pdata); 145 void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
144 void (*set_mss)(struct xgene_enet_pdata *pdata); 146 void (*set_mss)(struct xgene_enet_pdata *pdata);
145 void (*link_state)(struct work_struct *work); 147 void (*link_state)(struct work_struct *work);
@@ -147,6 +149,8 @@ struct xgene_mac_ops {
147 149
148struct xgene_port_ops { 150struct xgene_port_ops {
149 int (*reset)(struct xgene_enet_pdata *pdata); 151 int (*reset)(struct xgene_enet_pdata *pdata);
152 void (*clear)(struct xgene_enet_pdata *pdata,
153 struct xgene_enet_desc_ring *ring);
150 void (*cle_bypass)(struct xgene_enet_pdata *pdata, 154 void (*cle_bypass)(struct xgene_enet_pdata *pdata,
151 u32 dst_ring_num, u16 bufpool_id); 155 u32 dst_ring_num, u16 bufpool_id);
152 void (*shutdown)(struct xgene_enet_pdata *pdata); 156 void (*shutdown)(struct xgene_enet_pdata *pdata);
@@ -211,6 +215,7 @@ struct xgene_enet_pdata {
211 u32 mss; 215 u32 mss;
212 u8 tx_delay; 216 u8 tx_delay;
213 u8 rx_delay; 217 u8 rx_delay;
218 bool mdio_driver;
214}; 219};
215 220
216struct xgene_indirect_ctl { 221struct xgene_indirect_ctl {
@@ -220,34 +225,6 @@ struct xgene_indirect_ctl {
220 void __iomem *cmd_done; 225 void __iomem *cmd_done;
221}; 226};
222 227
223/* Set the specified value into a bit-field defined by its starting position
224 * and length within a single u64.
225 */
226static inline u64 xgene_enet_set_field_value(int pos, int len, u64 val)
227{
228 return (val & ((1ULL << len) - 1)) << pos;
229}
230
231#define SET_VAL(field, val) \
232 xgene_enet_set_field_value(field ## _POS, field ## _LEN, val)
233
234#define SET_BIT(field) \
235 xgene_enet_set_field_value(field ## _POS, 1, 1)
236
237/* Get the value from a bit-field defined by its starting position
238 * and length within the specified u64.
239 */
240static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src)
241{
242 return (src >> pos) & ((1ULL << len) - 1);
243}
244
245#define GET_VAL(field, src) \
246 xgene_enet_get_field_value(field ## _POS, field ## _LEN, src)
247
248#define GET_BIT(field, src) \
249 xgene_enet_get_field_value(field ## _POS, 1, src)
250
251static inline struct device *ndev_to_dev(struct net_device *ndev) 228static inline struct device *ndev_to_dev(struct net_device *ndev)
252{ 229{
253 return ndev->dev.parent; 230 return ndev->dev.parent;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
index 78475512b683..d12e9cbae820 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
@@ -28,6 +28,12 @@ static void xgene_enet_wr_csr(struct xgene_enet_pdata *p, u32 offset, u32 val)
28 iowrite32(val, p->eth_csr_addr + offset); 28 iowrite32(val, p->eth_csr_addr + offset);
29} 29}
30 30
31static void xgene_enet_wr_clkrst_csr(struct xgene_enet_pdata *p, u32 offset,
32 u32 val)
33{
34 iowrite32(val, p->base_addr + offset);
35}
36
31static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *p, 37static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *p,
32 u32 offset, u32 val) 38 u32 offset, u32 val)
33{ 39{
@@ -93,6 +99,11 @@ static u32 xgene_enet_rd_diag_csr(struct xgene_enet_pdata *p, u32 offset)
93 return ioread32(p->eth_diag_csr_addr + offset); 99 return ioread32(p->eth_diag_csr_addr + offset);
94} 100}
95 101
102static u32 xgene_enet_rd_mcx_csr(struct xgene_enet_pdata *p, u32 offset)
103{
104 return ioread32(p->mcx_mac_csr_addr + offset);
105}
106
96static u32 xgene_enet_rd_indirect(struct xgene_indirect_ctl *ctl, u32 rd_addr) 107static u32 xgene_enet_rd_indirect(struct xgene_indirect_ctl *ctl, u32 rd_addr)
97{ 108{
98 u32 rd_data; 109 u32 rd_data;
@@ -132,9 +143,17 @@ static u32 xgene_enet_rd_mac(struct xgene_enet_pdata *p, u32 rd_addr)
132static int xgene_enet_ecc_init(struct xgene_enet_pdata *p) 143static int xgene_enet_ecc_init(struct xgene_enet_pdata *p)
133{ 144{
134 struct net_device *ndev = p->ndev; 145 struct net_device *ndev = p->ndev;
135 u32 data; 146 u32 data, shutdown;
136 int i = 0; 147 int i = 0;
137 148
149 shutdown = xgene_enet_rd_diag_csr(p, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR);
150 data = xgene_enet_rd_diag_csr(p, ENET_BLOCK_MEM_RDY_ADDR);
151
152 if (!shutdown && data == ~0U) {
153 netdev_dbg(ndev, "+ ecc_init done, skipping\n");
154 return 0;
155 }
156
138 xgene_enet_wr_diag_csr(p, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0); 157 xgene_enet_wr_diag_csr(p, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0);
139 do { 158 do {
140 usleep_range(100, 110); 159 usleep_range(100, 110);
@@ -230,21 +249,105 @@ static u32 xgene_enet_link_status(struct xgene_enet_pdata *p)
230 data = xgene_mii_phy_read(p, INT_PHY_ADDR, 249 data = xgene_mii_phy_read(p, INT_PHY_ADDR,
231 SGMII_BASE_PAGE_ABILITY_ADDR >> 2); 250 SGMII_BASE_PAGE_ABILITY_ADDR >> 2);
232 251
252 if (LINK_SPEED(data) == PHY_SPEED_1000)
253 p->phy_speed = SPEED_1000;
254 else if (LINK_SPEED(data) == PHY_SPEED_100)
255 p->phy_speed = SPEED_100;
256 else
257 p->phy_speed = SPEED_10;
258
233 return data & LINK_UP; 259 return data & LINK_UP;
234} 260}
235 261
236static void xgene_sgmac_init(struct xgene_enet_pdata *p) 262static void xgene_sgmii_configure(struct xgene_enet_pdata *p)
237{ 263{
238 u32 data, loop = 10; 264 xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2,
239 u32 offset = p->port_id * 4; 265 0x8000);
240 u32 enet_spare_cfg_reg, rsif_config_reg; 266 xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_CONTROL_ADDR >> 2, 0x9000);
241 u32 cfg_bypass_reg, rx_dv_gate_reg; 267 xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0);
242 268}
243 xgene_sgmac_reset(p);
244 269
245 /* Enable auto-negotiation */ 270static 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); 271{
272 xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2,
273 0x8000);
247 xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0); 274 xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0);
275}
276
277static void xgene_sgmii_reset(struct xgene_enet_pdata *p)
278{
279 u32 value;
280
281 if (p->phy_speed == SPEED_UNKNOWN)
282 return;
283
284 value = xgene_mii_phy_read(p, INT_PHY_ADDR,
285 SGMII_BASE_PAGE_ABILITY_ADDR >> 2);
286 if (!(value & LINK_UP))
287 xgene_sgmii_tbi_control_reset(p);
288}
289
290static void xgene_sgmac_set_speed(struct xgene_enet_pdata *p)
291{
292 u32 icm0_addr, icm2_addr, debug_addr;
293 u32 icm0, icm2, intf_ctl;
294 u32 mc2, value;
295
296 xgene_sgmii_reset(p);
297
298 if (p->enet_id == XGENE_ENET1) {
299 icm0_addr = ICM_CONFIG0_REG_0_ADDR + p->port_id * OFFSET_8;
300 icm2_addr = ICM_CONFIG2_REG_0_ADDR + p->port_id * OFFSET_4;
301 debug_addr = DEBUG_REG_ADDR;
302 } else {
303 icm0_addr = XG_MCX_ICM_CONFIG0_REG_0_ADDR;
304 icm2_addr = XG_MCX_ICM_CONFIG2_REG_0_ADDR;
305 debug_addr = XG_DEBUG_REG_ADDR;
306 }
307
308 icm0 = xgene_enet_rd_mcx_csr(p, icm0_addr);
309 icm2 = xgene_enet_rd_mcx_csr(p, icm2_addr);
310 mc2 = xgene_enet_rd_mac(p, MAC_CONFIG_2_ADDR);
311 intf_ctl = xgene_enet_rd_mac(p, INTERFACE_CONTROL_ADDR);
312
313 switch (p->phy_speed) {
314 case SPEED_10:
315 ENET_INTERFACE_MODE2_SET(&mc2, 1);
316 intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE);
317 CFG_MACMODE_SET(&icm0, 0);
318 CFG_WAITASYNCRD_SET(&icm2, 500);
319 break;
320 case SPEED_100:
321 ENET_INTERFACE_MODE2_SET(&mc2, 1);
322 intf_ctl &= ~ENET_GHD_MODE;
323 intf_ctl |= ENET_LHD_MODE;
324 CFG_MACMODE_SET(&icm0, 1);
325 CFG_WAITASYNCRD_SET(&icm2, 80);
326 break;
327 default:
328 ENET_INTERFACE_MODE2_SET(&mc2, 2);
329 intf_ctl &= ~ENET_LHD_MODE;
330 intf_ctl |= ENET_GHD_MODE;
331 CFG_MACMODE_SET(&icm0, 2);
332 CFG_WAITASYNCRD_SET(&icm2, 16);
333 value = xgene_enet_rd_csr(p, debug_addr);
334 value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
335 xgene_enet_wr_csr(p, debug_addr, value);
336 break;
337 }
338
339 mc2 |= FULL_DUPLEX2 | PAD_CRC;
340 xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, mc2);
341 xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, intf_ctl);
342 xgene_enet_wr_mcx_csr(p, icm0_addr, icm0);
343 xgene_enet_wr_mcx_csr(p, icm2_addr, icm2);
344}
345
346static void xgene_sgmii_enable_autoneg(struct xgene_enet_pdata *p)
347{
348 u32 data, loop = 10;
349
350 xgene_sgmii_configure(p);
248 351
249 while (loop--) { 352 while (loop--) {
250 data = xgene_mii_phy_read(p, INT_PHY_ADDR, 353 data = xgene_mii_phy_read(p, INT_PHY_ADDR,
@@ -255,17 +358,27 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p)
255 } 358 }
256 if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS)) 359 if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS))
257 netdev_err(p->ndev, "Auto-negotiation failed\n"); 360 netdev_err(p->ndev, "Auto-negotiation failed\n");
361}
362
363static void xgene_sgmac_init(struct xgene_enet_pdata *p)
364{
365 u32 enet_spare_cfg_reg, rsif_config_reg;
366 u32 cfg_bypass_reg, rx_dv_gate_reg;
367 u32 data, offset;
258 368
259 data = xgene_enet_rd_mac(p, MAC_CONFIG_2_ADDR); 369 if (!(p->enet_id == XGENE_ENET2 && p->mdio_driver))
260 ENET_INTERFACE_MODE2_SET(&data, 2); 370 xgene_sgmac_reset(p);
261 xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2); 371
262 xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE); 372 xgene_sgmii_enable_autoneg(p);
373 xgene_sgmac_set_speed(p);
374 xgene_sgmac_set_mac_addr(p);
263 375
264 if (p->enet_id == XGENE_ENET1) { 376 if (p->enet_id == XGENE_ENET1) {
265 enet_spare_cfg_reg = ENET_SPARE_CFG_REG_ADDR; 377 enet_spare_cfg_reg = ENET_SPARE_CFG_REG_ADDR;
266 rsif_config_reg = RSIF_CONFIG_REG_ADDR; 378 rsif_config_reg = RSIF_CONFIG_REG_ADDR;
267 cfg_bypass_reg = CFG_BYPASS_ADDR; 379 cfg_bypass_reg = CFG_BYPASS_ADDR;
268 rx_dv_gate_reg = SG_RX_DV_GATE_REG_0_ADDR; 380 offset = p->port_id * OFFSET_4;
381 rx_dv_gate_reg = SG_RX_DV_GATE_REG_0_ADDR + offset;
269 } else { 382 } else {
270 enet_spare_cfg_reg = XG_ENET_SPARE_CFG_REG_ADDR; 383 enet_spare_cfg_reg = XG_ENET_SPARE_CFG_REG_ADDR;
271 rsif_config_reg = XG_RSIF_CONFIG_REG_ADDR; 384 rsif_config_reg = XG_RSIF_CONFIG_REG_ADDR;
@@ -277,8 +390,6 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p)
277 data |= MPA_IDLE_WITH_QMI_EMPTY; 390 data |= MPA_IDLE_WITH_QMI_EMPTY;
278 xgene_enet_wr_csr(p, enet_spare_cfg_reg, data); 391 xgene_enet_wr_csr(p, enet_spare_cfg_reg, data);
279 392
280 xgene_sgmac_set_mac_addr(p);
281
282 /* Adjust MDC clock frequency */ 393 /* Adjust MDC clock frequency */
283 data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR); 394 data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR);
284 MGMT_CLOCK_SEL_SET(&data, 7); 395 MGMT_CLOCK_SEL_SET(&data, 7);
@@ -292,7 +403,7 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p)
292 /* Bypass traffic gating */ 403 /* Bypass traffic gating */
293 xgene_enet_wr_csr(p, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x84); 404 xgene_enet_wr_csr(p, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x84);
294 xgene_enet_wr_csr(p, cfg_bypass_reg, RESUME_TX); 405 xgene_enet_wr_csr(p, cfg_bypass_reg, RESUME_TX);
295 xgene_enet_wr_mcx_csr(p, rx_dv_gate_reg + offset, RESUME_RX0); 406 xgene_enet_wr_mcx_csr(p, rx_dv_gate_reg, RESUME_RX0);
296} 407}
297 408
298static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set) 409static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set)
@@ -331,17 +442,43 @@ static void xgene_sgmac_tx_disable(struct xgene_enet_pdata *p)
331 442
332static int xgene_enet_reset(struct xgene_enet_pdata *p) 443static int xgene_enet_reset(struct xgene_enet_pdata *p)
333{ 444{
445 struct device *dev = &p->pdev->dev;
446
334 if (!xgene_ring_mgr_init(p)) 447 if (!xgene_ring_mgr_init(p))
335 return -ENODEV; 448 return -ENODEV;
336 449
337 if (!IS_ERR(p->clk)) { 450 if (p->mdio_driver && p->enet_id == XGENE_ENET2) {
338 clk_prepare_enable(p->clk); 451 xgene_enet_config_ring_if_assoc(p);
339 clk_disable_unprepare(p->clk); 452 return 0;
340 clk_prepare_enable(p->clk);
341 } 453 }
342 454
343 xgene_enet_ecc_init(p); 455 if (p->enet_id == XGENE_ENET2)
344 xgene_enet_config_ring_if_assoc(p); 456 xgene_enet_wr_clkrst_csr(p, XGENET_CONFIG_REG_ADDR, SGMII_EN);
457
458 if (dev->of_node) {
459 if (!IS_ERR(p->clk)) {
460 clk_prepare_enable(p->clk);
461 udelay(5);
462 clk_disable_unprepare(p->clk);
463 udelay(5);
464 clk_prepare_enable(p->clk);
465 udelay(5);
466 }
467 } else {
468#ifdef CONFIG_ACPI
469 if (acpi_has_method(ACPI_HANDLE(&p->pdev->dev), "_RST"))
470 acpi_evaluate_object(ACPI_HANDLE(&p->pdev->dev),
471 "_RST", NULL, NULL);
472 else if (acpi_has_method(ACPI_HANDLE(&p->pdev->dev), "_INI"))
473 acpi_evaluate_object(ACPI_HANDLE(&p->pdev->dev),
474 "_INI", NULL, NULL);
475#endif
476 }
477
478 if (!p->port_id) {
479 xgene_enet_ecc_init(p);
480 xgene_enet_config_ring_if_assoc(p);
481 }
345 482
346 return 0; 483 return 0;
347} 484}
@@ -369,10 +506,53 @@ static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p,
369 xgene_enet_wr_csr(p, cle_bypass_reg1 + offset, data); 506 xgene_enet_wr_csr(p, cle_bypass_reg1 + offset, data);
370} 507}
371 508
509static void xgene_enet_clear(struct xgene_enet_pdata *pdata,
510 struct xgene_enet_desc_ring *ring)
511{
512 u32 addr, val, data;
513
514 val = xgene_enet_ring_bufnum(ring->id);
515
516 if (xgene_enet_is_bufpool(ring->id)) {
517 addr = ENET_CFGSSQMIFPRESET_ADDR;
518 data = BIT(val - 0x20);
519 } else {
520 addr = ENET_CFGSSQMIWQRESET_ADDR;
521 data = BIT(val);
522 }
523
524 xgene_enet_wr_ring_if(pdata, addr, data);
525}
526
372static void xgene_enet_shutdown(struct xgene_enet_pdata *p) 527static void xgene_enet_shutdown(struct xgene_enet_pdata *p)
373{ 528{
374 if (!IS_ERR(p->clk)) 529 struct device *dev = &p->pdev->dev;
375 clk_disable_unprepare(p->clk); 530 struct xgene_enet_desc_ring *ring;
531 u32 pb, val;
532 int i;
533
534 pb = 0;
535 for (i = 0; i < p->rxq_cnt; i++) {
536 ring = p->rx_ring[i]->buf_pool;
537
538 val = xgene_enet_ring_bufnum(ring->id);
539 pb |= BIT(val - 0x20);
540 }
541 xgene_enet_wr_ring_if(p, ENET_CFGSSQMIFPRESET_ADDR, pb);
542
543 pb = 0;
544 for (i = 0; i < p->txq_cnt; i++) {
545 ring = p->tx_ring[i];
546
547 val = xgene_enet_ring_bufnum(ring->id);
548 pb |= BIT(val);
549 }
550 xgene_enet_wr_ring_if(p, ENET_CFGSSQMIWQRESET_ADDR, pb);
551
552 if (dev->of_node) {
553 if (!IS_ERR(p->clk))
554 clk_disable_unprepare(p->clk);
555 }
376} 556}
377 557
378static void xgene_enet_link_state(struct work_struct *work) 558static void xgene_enet_link_state(struct work_struct *work)
@@ -386,10 +566,11 @@ static void xgene_enet_link_state(struct work_struct *work)
386 if (link) { 566 if (link) {
387 if (!netif_carrier_ok(ndev)) { 567 if (!netif_carrier_ok(ndev)) {
388 netif_carrier_on(ndev); 568 netif_carrier_on(ndev);
389 xgene_sgmac_init(p); 569 xgene_sgmac_set_speed(p);
390 xgene_sgmac_rx_enable(p); 570 xgene_sgmac_rx_enable(p);
391 xgene_sgmac_tx_enable(p); 571 xgene_sgmac_tx_enable(p);
392 netdev_info(ndev, "Link is Up - 1Gbps\n"); 572 netdev_info(ndev, "Link is Up - %dMbps\n",
573 p->phy_speed);
393 } 574 }
394 poll_interval = PHY_POLL_LINK_ON; 575 poll_interval = PHY_POLL_LINK_ON;
395 } else { 576 } else {
@@ -412,12 +593,14 @@ const struct xgene_mac_ops xgene_sgmac_ops = {
412 .tx_enable = xgene_sgmac_tx_enable, 593 .tx_enable = xgene_sgmac_tx_enable,
413 .rx_disable = xgene_sgmac_rx_disable, 594 .rx_disable = xgene_sgmac_rx_disable,
414 .tx_disable = xgene_sgmac_tx_disable, 595 .tx_disable = xgene_sgmac_tx_disable,
596 .set_speed = xgene_sgmac_set_speed,
415 .set_mac_addr = xgene_sgmac_set_mac_addr, 597 .set_mac_addr = xgene_sgmac_set_mac_addr,
416 .link_state = xgene_enet_link_state 598 .link_state = xgene_enet_link_state
417}; 599};
418 600
419const struct xgene_port_ops xgene_sgport_ops = { 601const struct xgene_port_ops xgene_sgport_ops = {
420 .reset = xgene_enet_reset, 602 .reset = xgene_enet_reset,
603 .clear = xgene_enet_clear,
421 .cle_bypass = xgene_enet_cle_bypass, 604 .cle_bypass = xgene_enet_cle_bypass,
422 .shutdown = xgene_enet_shutdown 605 .shutdown = xgene_enet_shutdown
423}; 606};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
index 002df5a6756e..3d0ba374491b 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
@@ -34,6 +35,13 @@
34#define LINK_UP BIT(15) 35#define LINK_UP BIT(15)
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
38#define SGMII_EN 0x1
39
40enum xgene_phy_speed {
41 PHY_SPEED_10,
42 PHY_SPEED_100,
43 PHY_SPEED_1000
44};
37 45
38extern const struct xgene_mac_ops xgene_sgmac_ops; 46extern const struct xgene_mac_ops xgene_sgmac_ops;
39extern const struct xgene_port_ops xgene_sgport_ops; 47extern const struct xgene_port_ops xgene_sgport_ops;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
index ba030dc1940b..9c6ad0dce00f 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -258,13 +258,29 @@ static void xgene_xgmac_tx_disable(struct xgene_enet_pdata *pdata)
258 258
259static int xgene_enet_reset(struct xgene_enet_pdata *pdata) 259static int xgene_enet_reset(struct xgene_enet_pdata *pdata)
260{ 260{
261 struct device *dev = &pdata->pdev->dev;
262
261 if (!xgene_ring_mgr_init(pdata)) 263 if (!xgene_ring_mgr_init(pdata))
262 return -ENODEV; 264 return -ENODEV;
263 265
264 if (!IS_ERR(pdata->clk)) { 266 if (dev->of_node) {
265 clk_prepare_enable(pdata->clk); 267 clk_prepare_enable(pdata->clk);
268 udelay(5);
266 clk_disable_unprepare(pdata->clk); 269 clk_disable_unprepare(pdata->clk);
270 udelay(5);
267 clk_prepare_enable(pdata->clk); 271 clk_prepare_enable(pdata->clk);
272 udelay(5);
273 } else {
274#ifdef CONFIG_ACPI
275 if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev), "_RST")) {
276 acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),
277 "_RST", NULL, NULL);
278 } else if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev),
279 "_INI")) {
280 acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev),
281 "_INI", NULL, NULL);
282 }
283#endif
268 } 284 }
269 285
270 xgene_enet_ecc_init(pdata); 286 xgene_enet_ecc_init(pdata);
@@ -292,8 +308,51 @@ static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata,
292 308
293static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata) 309static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
294{ 310{
295 if (!IS_ERR(pdata->clk)) 311 struct device *dev = &pdata->pdev->dev;
296 clk_disable_unprepare(pdata->clk); 312 struct xgene_enet_desc_ring *ring;
313 u32 pb, val;
314 int i;
315
316 pb = 0;
317 for (i = 0; i < pdata->rxq_cnt; i++) {
318 ring = pdata->rx_ring[i]->buf_pool;
319
320 val = xgene_enet_ring_bufnum(ring->id);
321 pb |= BIT(val - 0x20);
322 }
323 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPRESET_ADDR, pb);
324
325 pb = 0;
326 for (i = 0; i < pdata->txq_cnt; i++) {
327 ring = pdata->tx_ring[i];
328
329 val = xgene_enet_ring_bufnum(ring->id);
330 pb |= BIT(val);
331 }
332 xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQRESET_ADDR, pb);
333
334 if (dev->of_node) {
335 if (!IS_ERR(pdata->clk))
336 clk_disable_unprepare(pdata->clk);
337 }
338}
339
340static void xgene_enet_clear(struct xgene_enet_pdata *pdata,
341 struct xgene_enet_desc_ring *ring)
342{
343 u32 addr, val, data;
344
345 val = xgene_enet_ring_bufnum(ring->id);
346
347 if (xgene_enet_is_bufpool(ring->id)) {
348 addr = ENET_CFGSSQMIFPRESET_ADDR;
349 data = BIT(val - 0x20);
350 } else {
351 addr = ENET_CFGSSQMIWQRESET_ADDR;
352 data = BIT(val);
353 }
354
355 xgene_enet_wr_ring_if(pdata, addr, data);
297} 356}
298 357
299static void xgene_enet_link_state(struct work_struct *work) 358static void xgene_enet_link_state(struct work_struct *work)
@@ -340,6 +399,7 @@ const struct xgene_mac_ops xgene_xgmac_ops = {
340 399
341const struct xgene_port_ops xgene_xgport_ops = { 400const struct xgene_port_ops xgene_xgport_ops = {
342 .reset = xgene_enet_reset, 401 .reset = xgene_enet_reset,
402 .clear = xgene_enet_clear,
343 .cle_bypass = xgene_enet_xgcle_bypass, 403 .cle_bypass = xgene_enet_xgcle_bypass,
344 .shutdown = xgene_enet_shutdown, 404 .shutdown = xgene_enet_shutdown,
345}; 405};
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
72extern const struct xgene_mac_ops xgene_xgmac_ops; 75extern const struct xgene_mac_ops xgene_xgmac_ops;
73extern const struct xgene_port_ops xgene_xgport_ops; 76extern const struct xgene_port_ops xgene_xgport_ops;
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 1d7b208b1629..47a64342cc16 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -301,6 +301,12 @@ config MDIO_HISI_FEMAC
301 This module provides a driver for the MDIO busses found in the 301 This module provides a driver for the MDIO busses found in the
302 Hisilicon SoC that have an Fast Ethernet MAC. 302 Hisilicon SoC that have an Fast Ethernet MAC.
303 303
304config MDIO_XGENE
305 tristate "APM X-Gene SoC MDIO bus controller"
306 help
307 This module provides a driver for the MDIO busses found in the
308 APM X-Gene SoC's.
309
304endif # PHYLIB 310endif # PHYLIB
305 311
306config MICREL_KS8995MA 312config MICREL_KS8995MA
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 19e38a97963a..534dfa74d5a2 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -48,3 +48,4 @@ obj-$(CONFIG_MICROCHIP_PHY) += microchip.o
48obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o 48obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o
49obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o 49obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o
50obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o 50obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o
51obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c
new file mode 100644
index 000000000000..d94a978024d9
--- /dev/null
+++ b/drivers/net/phy/mdio-xgene.c
@@ -0,0 +1,477 @@
1/* Applied Micro X-Gene SoC MDIO Driver
2 *
3 * Copyright (c) 2016, Applied Micro Circuits Corporation
4 * Author: Iyappan Subramanian <isubramanian@apm.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/acpi.h>
21#include <linux/clk.h>
22#include <linux/device.h>
23#include <linux/efi.h>
24#include <linux/if_vlan.h>
25#include <linux/io.h>
26#include <linux/module.h>
27#include <linux/of_platform.h>
28#include <linux/of_net.h>
29#include <linux/of_mdio.h>
30#include <linux/prefetch.h>
31#include <linux/phy.h>
32#include <net/ip.h>
33#include "mdio-xgene.h"
34
35static bool xgene_mdio_status;
36
37static u32 xgene_enet_rd_mac(void __iomem *base_addr, u32 rd_addr)
38{
39 void __iomem *addr, *rd, *cmd, *cmd_done;
40 u32 done, rd_data = BUSY_MASK;
41 u8 wait = 10;
42
43 addr = base_addr + MAC_ADDR_REG_OFFSET;
44 rd = base_addr + MAC_READ_REG_OFFSET;
45 cmd = base_addr + MAC_COMMAND_REG_OFFSET;
46 cmd_done = base_addr + MAC_COMMAND_DONE_REG_OFFSET;
47
48 iowrite32(rd_addr, addr);
49 iowrite32(XGENE_ENET_RD_CMD, cmd);
50
51 while (wait--) {
52 done = ioread32(cmd_done);
53 if (done)
54 break;
55 udelay(1);
56 }
57
58 if (!done)
59 return rd_data;
60
61 rd_data = ioread32(rd);
62 iowrite32(0, cmd);
63
64 return rd_data;
65}
66
67static void xgene_enet_wr_mac(void __iomem *base_addr, u32 wr_addr, u32 wr_data)
68{
69 void __iomem *addr, *wr, *cmd, *cmd_done;
70 u8 wait = 10;
71 u32 done;
72
73 addr = base_addr + MAC_ADDR_REG_OFFSET;
74 wr = base_addr + MAC_WRITE_REG_OFFSET;
75 cmd = base_addr + MAC_COMMAND_REG_OFFSET;
76 cmd_done = base_addr + MAC_COMMAND_DONE_REG_OFFSET;
77
78 iowrite32(wr_addr, addr);
79 iowrite32(wr_data, wr);
80 iowrite32(XGENE_ENET_WR_CMD, cmd);
81
82 while (wait--) {
83 done = ioread32(cmd_done);
84 if (done)
85 break;
86 udelay(1);
87 }
88
89 if (!done)
90 pr_err("MCX mac write failed, addr: 0x%04x\n", wr_addr);
91
92 iowrite32(0, cmd);
93}
94
95int xgene_mdio_rgmii_read(struct mii_bus *bus, int phy_id, int reg)
96{
97 void __iomem *addr = (void __iomem *)bus->priv;
98 u32 data, done;
99 u8 wait = 10;
100
101 data = SET_VAL(PHY_ADDR, phy_id) | SET_VAL(REG_ADDR, reg);
102 xgene_enet_wr_mac(addr, MII_MGMT_ADDRESS_ADDR, data);
103 xgene_enet_wr_mac(addr, MII_MGMT_COMMAND_ADDR, READ_CYCLE_MASK);
104 do {
105 usleep_range(5, 10);
106 done = xgene_enet_rd_mac(addr, MII_MGMT_INDICATORS_ADDR);
107 } while ((done & BUSY_MASK) && wait--);
108
109 if (done & BUSY_MASK) {
110 dev_err(&bus->dev, "MII_MGMT read failed\n");
111 return -EBUSY;
112 }
113
114 data = xgene_enet_rd_mac(addr, MII_MGMT_STATUS_ADDR);
115 xgene_enet_wr_mac(addr, MII_MGMT_COMMAND_ADDR, 0);
116
117 return data;
118}
119EXPORT_SYMBOL(xgene_mdio_rgmii_read);
120
121int xgene_mdio_rgmii_write(struct mii_bus *bus, int phy_id, int reg, u16 data)
122{
123 void __iomem *addr = (void __iomem *)bus->priv;
124 u32 val, done;
125 u8 wait = 10;
126
127 val = SET_VAL(PHY_ADDR, phy_id) | SET_VAL(REG_ADDR, reg);
128 xgene_enet_wr_mac(addr, MII_MGMT_ADDRESS_ADDR, val);
129
130 xgene_enet_wr_mac(addr, MII_MGMT_CONTROL_ADDR, data);
131 do {
132 usleep_range(5, 10);
133 done = xgene_enet_rd_mac(addr, MII_MGMT_INDICATORS_ADDR);
134 } while ((done & BUSY_MASK) && wait--);
135
136 if (done & BUSY_MASK) {
137 dev_err(&bus->dev, "MII_MGMT write failed\n");
138 return -EBUSY;
139 }
140
141 return 0;
142}
143EXPORT_SYMBOL(xgene_mdio_rgmii_write);
144
145static u32 xgene_menet_rd_diag_csr(struct xgene_mdio_pdata *pdata, u32 offset)
146{
147 return ioread32(pdata->diag_csr_addr + offset);
148}
149
150static void xgene_menet_wr_diag_csr(struct xgene_mdio_pdata *pdata,
151 u32 offset, u32 val)
152{
153 iowrite32(val, pdata->diag_csr_addr + offset);
154}
155
156static int xgene_enet_ecc_init(struct xgene_mdio_pdata *pdata)
157{
158 u32 data;
159 u8 wait = 10;
160
161 xgene_menet_wr_diag_csr(pdata, MENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0x0);
162 do {
163 usleep_range(100, 110);
164 data = xgene_menet_rd_diag_csr(pdata, MENET_BLOCK_MEM_RDY_ADDR);
165 } while ((data != 0xffffffff) && wait--);
166
167 if (data != 0xffffffff) {
168 dev_err(pdata->dev, "Failed to release memory from shutdown\n");
169 return -ENODEV;
170 }
171
172 return 0;
173}
174
175static void xgene_gmac_reset(struct xgene_mdio_pdata *pdata)
176{
177 xgene_enet_wr_mac(pdata->mac_csr_addr, MAC_CONFIG_1_ADDR, SOFT_RESET);
178 xgene_enet_wr_mac(pdata->mac_csr_addr, MAC_CONFIG_1_ADDR, 0);
179}
180
181static int xgene_mdio_reset(struct xgene_mdio_pdata *pdata)
182{
183 int ret;
184
185 if (pdata->dev->of_node) {
186 clk_prepare_enable(pdata->clk);
187 udelay(5);
188 clk_disable_unprepare(pdata->clk);
189 udelay(5);
190 clk_prepare_enable(pdata->clk);
191 udelay(5);
192 } else {
193#ifdef CONFIG_ACPI
194 acpi_evaluate_object(ACPI_HANDLE(pdata->dev),
195 "_RST", NULL, NULL);
196#endif
197 }
198
199 ret = xgene_enet_ecc_init(pdata);
200 if (ret)
201 return ret;
202 xgene_gmac_reset(pdata);
203
204 return 0;
205}
206
207static void xgene_enet_rd_mdio_csr(void __iomem *base_addr,
208 u32 offset, u32 *val)
209{
210 void __iomem *addr = base_addr + offset;
211
212 *val = ioread32(addr);
213}
214
215static void xgene_enet_wr_mdio_csr(void __iomem *base_addr,
216 u32 offset, u32 val)
217{
218 void __iomem *addr = base_addr + offset;
219
220 iowrite32(val, addr);
221}
222
223static int xgene_xfi_mdio_write(struct mii_bus *bus, int phy_id,
224 int reg, u16 data)
225{
226 void __iomem *addr = (void __iomem *)bus->priv;
227 int timeout = 100;
228 u32 status, val;
229
230 val = SET_VAL(HSTPHYADX, phy_id) | SET_VAL(HSTREGADX, reg) |
231 SET_VAL(HSTMIIMWRDAT, data);
232 xgene_enet_wr_mdio_csr(addr, MIIM_FIELD_ADDR, data);
233
234 val = HSTLDCMD | SET_VAL(HSTMIIMCMD, MIIM_CMD_LEGACY_WRITE);
235 xgene_enet_wr_mdio_csr(addr, MIIM_COMMAND_ADDR, val);
236
237 do {
238 usleep_range(5, 10);
239 xgene_enet_rd_mdio_csr(addr, MIIM_INDICATOR_ADDR, &status);
240 } while ((status & BUSY_MASK) && timeout--);
241
242 xgene_enet_wr_mdio_csr(addr, MIIM_COMMAND_ADDR, 0);
243
244 return 0;
245}
246
247static int xgene_xfi_mdio_read(struct mii_bus *bus, int phy_id, int reg)
248{
249 void __iomem *addr = (void __iomem *)bus->priv;
250 u32 data, status, val;
251 int timeout = 100;
252
253 val = SET_VAL(HSTPHYADX, phy_id) | SET_VAL(HSTREGADX, reg);
254 xgene_enet_wr_mdio_csr(addr, MIIM_FIELD_ADDR, val);
255
256 val = HSTLDCMD | SET_VAL(HSTMIIMCMD, MIIM_CMD_LEGACY_READ);
257 xgene_enet_wr_mdio_csr(addr, MIIM_COMMAND_ADDR, val);
258
259 do {
260 usleep_range(5, 10);
261 xgene_enet_rd_mdio_csr(addr, MIIM_INDICATOR_ADDR, &status);
262 } while ((status & BUSY_MASK) && timeout--);
263
264 if (status & BUSY_MASK) {
265 pr_err("XGENET_MII_MGMT write failed\n");
266 return -EBUSY;
267 }
268
269 xgene_enet_rd_mdio_csr(addr, MIIMRD_FIELD_ADDR, &data);
270 xgene_enet_wr_mdio_csr(addr, MIIM_COMMAND_ADDR, 0);
271
272 return data;
273}
274
275struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr)
276{
277 struct phy_device *phy_dev;
278
279 phy_dev = get_phy_device(bus, phy_addr, false);
280 if (!phy_dev || IS_ERR(phy_dev))
281 return NULL;
282
283 if (phy_device_register(phy_dev))
284 phy_device_free(phy_dev);
285
286 return phy_dev;
287}
288EXPORT_SYMBOL(xgene_enet_phy_register);
289
290#ifdef CONFIG_ACPI
291static acpi_status acpi_register_phy(acpi_handle handle, u32 lvl,
292 void *context, void **ret)
293{
294 struct mii_bus *mdio = context;
295 struct acpi_device *adev;
296 struct phy_device *phy_dev;
297 const union acpi_object *obj;
298 u32 phy_addr;
299
300 if (acpi_bus_get_device(handle, &adev))
301 return AE_OK;
302
303 if (acpi_dev_get_property(adev, "phy-channel", ACPI_TYPE_INTEGER, &obj))
304 return AE_OK;
305 phy_addr = obj->integer.value;
306
307 phy_dev = xgene_enet_phy_register(mdio, phy_addr);
308 adev->driver_data = phy_dev;
309
310 return AE_OK;
311}
312#endif
313
314static int xgene_mdio_probe(struct platform_device *pdev)
315{
316 struct device *dev = &pdev->dev;
317 struct mii_bus *mdio_bus;
318 const struct of_device_id *of_id;
319 struct resource *res;
320 struct xgene_mdio_pdata *pdata;
321 void __iomem *csr_base;
322 int mdio_id = 0, ret = 0;
323
324 of_id = of_match_device(xgene_mdio_of_match, &pdev->dev);
325 if (of_id) {
326 mdio_id = (enum xgene_mdio_id)of_id->data;
327 } else {
328#ifdef CONFIG_ACPI
329 const struct acpi_device_id *acpi_id;
330
331 acpi_id = acpi_match_device(xgene_mdio_acpi_match, &pdev->dev);
332 if (acpi_id)
333 mdio_id = (enum xgene_mdio_id)acpi_id->driver_data;
334#endif
335 }
336
337 if (!mdio_id)
338 return -ENODEV;
339
340 pdata = devm_kzalloc(dev, sizeof(struct xgene_mdio_pdata), GFP_KERNEL);
341 if (!pdata)
342 return -ENOMEM;
343 pdata->mdio_id = mdio_id;
344 pdata->dev = dev;
345
346 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
347 csr_base = devm_ioremap_resource(dev, res);
348 if (IS_ERR(csr_base)) {
349 dev_err(dev, "Unable to retrieve mac CSR region\n");
350 return PTR_ERR(csr_base);
351 }
352 pdata->mac_csr_addr = csr_base;
353 pdata->mdio_csr_addr = csr_base + BLOCK_XG_MDIO_CSR_OFFSET;
354 pdata->diag_csr_addr = csr_base + BLOCK_DIAG_CSR_OFFSET;
355
356 if (dev->of_node) {
357 pdata->clk = devm_clk_get(dev, NULL);
358 if (IS_ERR(pdata->clk)) {
359 dev_err(dev, "Unable to retrieve clk\n");
360 return PTR_ERR(pdata->clk);
361 }
362 }
363
364 ret = xgene_mdio_reset(pdata);
365 if (ret)
366 return ret;
367
368 mdio_bus = mdiobus_alloc();
369 if (!mdio_bus)
370 return -ENOMEM;
371
372 mdio_bus->name = "APM X-Gene MDIO bus";
373
374 if (mdio_id == XGENE_MDIO_RGMII) {
375 mdio_bus->read = xgene_mdio_rgmii_read;
376 mdio_bus->write = xgene_mdio_rgmii_write;
377 mdio_bus->priv = (void __force *)pdata->mac_csr_addr;
378 snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s",
379 "xgene-mii-rgmii");
380 } else {
381 mdio_bus->read = xgene_xfi_mdio_read;
382 mdio_bus->write = xgene_xfi_mdio_write;
383 mdio_bus->priv = (void __force *)pdata->mdio_csr_addr;
384 snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s",
385 "xgene-mii-xfi");
386 }
387
388 mdio_bus->parent = dev;
389 platform_set_drvdata(pdev, pdata);
390
391 if (dev->of_node) {
392 ret = of_mdiobus_register(mdio_bus, dev->of_node);
393 } else {
394#ifdef CONFIG_ACPI
395 /* Mask out all PHYs from auto probing. */
396 mdio_bus->phy_mask = ~0;
397 ret = mdiobus_register(mdio_bus);
398 if (ret)
399 goto out;
400
401 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1,
402 acpi_register_phy, NULL, mdio_bus, NULL);
403#endif
404 }
405
406 if (ret)
407 goto out;
408
409 pdata->mdio_bus = mdio_bus;
410 xgene_mdio_status = true;
411
412 return 0;
413
414out:
415 mdiobus_free(mdio_bus);
416
417 return ret;
418}
419
420static int xgene_mdio_remove(struct platform_device *pdev)
421{
422 struct xgene_mdio_pdata *pdata = platform_get_drvdata(pdev);
423 struct mii_bus *mdio_bus = pdata->mdio_bus;
424 struct device *dev = &pdev->dev;
425
426 mdiobus_unregister(mdio_bus);
427 mdiobus_free(mdio_bus);
428
429 if (dev->of_node) {
430 if (IS_ERR(pdata->clk))
431 clk_disable_unprepare(pdata->clk);
432 }
433
434 return 0;
435}
436
437#ifdef CONFIG_OF
438static const struct of_device_id xgene_mdio_of_match[] = {
439 {
440 .compatible = "apm,xgene-mdio-rgmii",
441 .data = (void *)XGENE_MDIO_RGMII
442 },
443 {
444 .compatible = "apm,xgene-mdio-xfi",
445 .data = (void *)XGENE_MDIO_XFI
446 },
447 {},
448};
449
450MODULE_DEVICE_TABLE(of, xgene_mdio_of_match);
451#endif
452
453#ifdef CONFIG_ACPI
454static const struct acpi_device_id xgene_mdio_acpi_match[] = {
455 { "APMC0D65", XGENE_MDIO_RGMII },
456 { "APMC0D66", XGENE_MDIO_XFI },
457 { }
458};
459
460MODULE_DEVICE_TABLE(acpi, xgene_mdio_acpi_match);
461#endif
462
463static struct platform_driver xgene_mdio_driver = {
464 .driver = {
465 .name = "xgene-mdio",
466 .of_match_table = of_match_ptr(xgene_mdio_of_match),
467 .acpi_match_table = ACPI_PTR(xgene_mdio_acpi_match),
468 },
469 .probe = xgene_mdio_probe,
470 .remove = xgene_mdio_remove,
471};
472
473module_platform_driver(xgene_mdio_driver);
474
475MODULE_DESCRIPTION("APM X-Gene SoC MDIO driver");
476MODULE_AUTHOR("Iyappan Subramanian <isubramanian@apm.com>");
477MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/mdio-xgene.h b/drivers/net/phy/mdio-xgene.h
new file mode 100644
index 000000000000..354241b53c1d
--- /dev/null
+++ b/drivers/net/phy/mdio-xgene.h
@@ -0,0 +1,143 @@
1/* Applied Micro X-Gene SoC MDIO Driver
2 *
3 * Copyright (c) 2016, Applied Micro Circuits Corporation
4 * Author: Iyappan Subramanian <isubramanian@apm.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef __MDIO_XGENE_H__
21#define __MDIO_XGENE_H__
22
23#define BLOCK_XG_MDIO_CSR_OFFSET 0x5000
24#define BLOCK_DIAG_CSR_OFFSET 0xd000
25#define XGENET_CONFIG_REG_ADDR 0x20
26
27#define MAC_ADDR_REG_OFFSET 0x00
28#define MAC_COMMAND_REG_OFFSET 0x04
29#define MAC_WRITE_REG_OFFSET 0x08
30#define MAC_READ_REG_OFFSET 0x0c
31#define MAC_COMMAND_DONE_REG_OFFSET 0x10
32
33#define CLKEN_OFFSET 0x08
34#define SRST_OFFSET 0x00
35
36#define MENET_CFG_MEM_RAM_SHUTDOWN_ADDR 0x70
37#define MENET_BLOCK_MEM_RDY_ADDR 0x74
38
39#define MAC_CONFIG_1_ADDR 0x00
40#define MII_MGMT_COMMAND_ADDR 0x24
41#define MII_MGMT_ADDRESS_ADDR 0x28
42#define MII_MGMT_CONTROL_ADDR 0x2c
43#define MII_MGMT_STATUS_ADDR 0x30
44#define MII_MGMT_INDICATORS_ADDR 0x34
45#define SOFT_RESET BIT(31)
46
47#define MII_MGMT_CONFIG_ADDR 0x20
48#define MII_MGMT_COMMAND_ADDR 0x24
49#define MII_MGMT_ADDRESS_ADDR 0x28
50#define MII_MGMT_CONTROL_ADDR 0x2c
51#define MII_MGMT_STATUS_ADDR 0x30
52#define MII_MGMT_INDICATORS_ADDR 0x34
53
54#define MIIM_COMMAND_ADDR 0x20
55#define MIIM_FIELD_ADDR 0x24
56#define MIIM_CONFIGURATION_ADDR 0x28
57#define MIIM_LINKFAILVECTOR_ADDR 0x2c
58#define MIIM_INDICATOR_ADDR 0x30
59#define MIIMRD_FIELD_ADDR 0x34
60
61#define MDIO_CSR_OFFSET 0x5000
62
63#define REG_ADDR_POS 0
64#define REG_ADDR_LEN 5
65#define PHY_ADDR_POS 8
66#define PHY_ADDR_LEN 5
67
68#define HSTMIIMWRDAT_POS 0
69#define HSTMIIMWRDAT_LEN 16
70#define HSTPHYADX_POS 23
71#define HSTPHYADX_LEN 5
72#define HSTREGADX_POS 18
73#define HSTREGADX_LEN 5
74#define HSTLDCMD BIT(3)
75#define HSTMIIMCMD_POS 0
76#define HSTMIIMCMD_LEN 3
77
78#define BUSY_MASK BIT(0)
79#define READ_CYCLE_MASK BIT(0)
80
81enum xgene_enet_cmd {
82 XGENE_ENET_WR_CMD = BIT(31),
83 XGENE_ENET_RD_CMD = BIT(30)
84};
85
86enum {
87 MIIM_CMD_IDLE,
88 MIIM_CMD_LEGACY_WRITE,
89 MIIM_CMD_LEGACY_READ,
90};
91
92enum xgene_mdio_id {
93 XGENE_MDIO_RGMII = 1,
94 XGENE_MDIO_XFI
95};
96
97struct xgene_mdio_pdata {
98 struct clk *clk;
99 struct device *dev;
100 void __iomem *mac_csr_addr;
101 void __iomem *diag_csr_addr;
102 void __iomem *mdio_csr_addr;
103 struct mii_bus *mdio_bus;
104 int mdio_id;
105};
106
107/* Set the specified value into a bit-field defined by its starting position
108 * and length within a single u64.
109 */
110static inline u64 xgene_enet_set_field_value(int pos, int len, u64 val)
111{
112 return (val & ((1ULL << len) - 1)) << pos;
113}
114
115#define SET_VAL(field, val) \
116 xgene_enet_set_field_value(field ## _POS, field ## _LEN, val)
117
118#define SET_BIT(field) \
119 xgene_enet_set_field_value(field ## _POS, 1, 1)
120
121/* Get the value from a bit-field defined by its starting position
122 * and length within the specified u64.
123 */
124static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src)
125{
126 return (src >> pos) & ((1ULL << len) - 1);
127}
128
129#define GET_VAL(field, src) \
130 xgene_enet_get_field_value(field ## _POS, field ## _LEN, src)
131
132#define GET_BIT(field, src) \
133 xgene_enet_get_field_value(field ## _POS, 1, src)
134
135static const struct of_device_id xgene_mdio_of_match[];
136#ifdef CONFIG_ACPI
137static const struct acpi_device_id xgene_mdio_acpi_match[];
138#endif
139int xgene_mdio_rgmii_read(struct mii_bus *bus, int phy_id, int reg);
140int xgene_mdio_rgmii_write(struct mii_bus *bus, int phy_id, int reg, u16 data);
141struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr);
142
143#endif /* __MDIO_XGENE_H__ */