aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMatheos Worku <matheos.worku@sun.com>2008-02-29 00:25:43 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-29 00:25:43 -0500
commit5fbd7e24da874a1c7b06ae6b10bbf2d71c1b6a11 (patch)
treeeea0d38248c108aeca60d04e468ad8287487ad16 /drivers/net
parent99cd07a537bf4c7c954f31611e30064407104410 (diff)
[NIU]: Add Support for Sun ATCA Blade Server.
Ports 0 and 1 of the NIU device are connected to extended fabric through SERDES. Ports 2 and 3 are connected using RGMII Fiber mode. [ Coding style cleanups... -DaveM ] Signed-off-by: Matheos Worku <matheos.worku@sun.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/niu.c701
-rw-r--r--drivers/net/niu.h4
2 files changed, 631 insertions, 74 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index d11ba61baa4f..7565c2d7f30e 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -113,6 +113,8 @@ do { if ((np)->msg_enable & NETIF_MSG_##TYPE) \
113#define niu_unlock_parent(np, flags) \ 113#define niu_unlock_parent(np, flags) \
114 spin_unlock_irqrestore(&np->parent->lock, flags) 114 spin_unlock_irqrestore(&np->parent->lock, flags)
115 115
116static int serdes_init_10g_serdes(struct niu *np);
117
116static int __niu_wait_bits_clear_mac(struct niu *np, unsigned long reg, 118static int __niu_wait_bits_clear_mac(struct niu *np, unsigned long reg,
117 u64 bits, int limit, int delay) 119 u64 bits, int limit, int delay)
118{ 120{
@@ -706,6 +708,251 @@ static int serdes_init_1g(struct niu *np)
706 return 0; 708 return 0;
707} 709}
708 710
711static int serdes_init_1g_serdes(struct niu *np)
712{
713 struct niu_link_config *lp = &np->link_config;
714 unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i;
715 u64 ctrl_val, test_cfg_val, sig, mask, val;
716 int err;
717 u64 reset_val, val_rd;
718
719 val = ENET_SERDES_PLL_HRATE0 | ENET_SERDES_PLL_HRATE1 |
720 ENET_SERDES_PLL_HRATE2 | ENET_SERDES_PLL_HRATE3 |
721 ENET_SERDES_PLL_FBDIV0;
722 switch (np->port) {
723 case 0:
724 reset_val = ENET_SERDES_RESET_0;
725 ctrl_reg = ENET_SERDES_0_CTRL_CFG;
726 test_cfg_reg = ENET_SERDES_0_TEST_CFG;
727 pll_cfg = ENET_SERDES_0_PLL_CFG;
728 break;
729 case 1:
730 reset_val = ENET_SERDES_RESET_1;
731 ctrl_reg = ENET_SERDES_1_CTRL_CFG;
732 test_cfg_reg = ENET_SERDES_1_TEST_CFG;
733 pll_cfg = ENET_SERDES_1_PLL_CFG;
734 break;
735
736 default:
737 return -EINVAL;
738 }
739 ctrl_val = (ENET_SERDES_CTRL_SDET_0 |
740 ENET_SERDES_CTRL_SDET_1 |
741 ENET_SERDES_CTRL_SDET_2 |
742 ENET_SERDES_CTRL_SDET_3 |
743 (0x5 << ENET_SERDES_CTRL_EMPH_0_SHIFT) |
744 (0x5 << ENET_SERDES_CTRL_EMPH_1_SHIFT) |
745 (0x5 << ENET_SERDES_CTRL_EMPH_2_SHIFT) |
746 (0x5 << ENET_SERDES_CTRL_EMPH_3_SHIFT) |
747 (0x1 << ENET_SERDES_CTRL_LADJ_0_SHIFT) |
748 (0x1 << ENET_SERDES_CTRL_LADJ_1_SHIFT) |
749 (0x1 << ENET_SERDES_CTRL_LADJ_2_SHIFT) |
750 (0x1 << ENET_SERDES_CTRL_LADJ_3_SHIFT));
751 test_cfg_val = 0;
752
753 if (lp->loopback_mode == LOOPBACK_PHY) {
754 test_cfg_val |= ((ENET_TEST_MD_PAD_LOOPBACK <<
755 ENET_SERDES_TEST_MD_0_SHIFT) |
756 (ENET_TEST_MD_PAD_LOOPBACK <<
757 ENET_SERDES_TEST_MD_1_SHIFT) |
758 (ENET_TEST_MD_PAD_LOOPBACK <<
759 ENET_SERDES_TEST_MD_2_SHIFT) |
760 (ENET_TEST_MD_PAD_LOOPBACK <<
761 ENET_SERDES_TEST_MD_3_SHIFT));
762 }
763
764 nw64(ENET_SERDES_RESET, reset_val);
765 mdelay(20);
766 val_rd = nr64(ENET_SERDES_RESET);
767 val_rd &= ~reset_val;
768 nw64(pll_cfg, val);
769 nw64(ctrl_reg, ctrl_val);
770 nw64(test_cfg_reg, test_cfg_val);
771 nw64(ENET_SERDES_RESET, val_rd);
772 mdelay(2000);
773
774 /* Initialize all 4 lanes of the SERDES. */
775 for (i = 0; i < 4; i++) {
776 u32 rxtx_ctrl, glue0;
777
778 err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl);
779 if (err)
780 return err;
781 err = esr_read_glue0(np, i, &glue0);
782 if (err)
783 return err;
784
785 rxtx_ctrl &= ~(ESR_RXTX_CTRL_VMUXLO);
786 rxtx_ctrl |= (ESR_RXTX_CTRL_ENSTRETCH |
787 (2 << ESR_RXTX_CTRL_VMUXLO_SHIFT));
788
789 glue0 &= ~(ESR_GLUE_CTRL0_SRATE |
790 ESR_GLUE_CTRL0_THCNT |
791 ESR_GLUE_CTRL0_BLTIME);
792 glue0 |= (ESR_GLUE_CTRL0_RXLOSENAB |
793 (0xf << ESR_GLUE_CTRL0_SRATE_SHIFT) |
794 (0xff << ESR_GLUE_CTRL0_THCNT_SHIFT) |
795 (BLTIME_300_CYCLES <<
796 ESR_GLUE_CTRL0_BLTIME_SHIFT));
797
798 err = esr_write_rxtx_ctrl(np, i, rxtx_ctrl);
799 if (err)
800 return err;
801 err = esr_write_glue0(np, i, glue0);
802 if (err)
803 return err;
804 }
805
806
807 sig = nr64(ESR_INT_SIGNALS);
808 switch (np->port) {
809 case 0:
810 val = (ESR_INT_SRDY0_P0 | ESR_INT_DET0_P0);
811 mask = val;
812 break;
813
814 case 1:
815 val = (ESR_INT_SRDY0_P1 | ESR_INT_DET0_P1);
816 mask = val;
817 break;
818
819 default:
820 return -EINVAL;
821 }
822
823 if ((sig & mask) != val) {
824 dev_err(np->device, PFX "Port %u signal bits [%08x] are not "
825 "[%08x]\n", np->port, (int) (sig & mask), (int) val);
826 return -ENODEV;
827 }
828
829 return 0;
830}
831
832static int link_status_1g_serdes(struct niu *np, int *link_up_p)
833{
834 struct niu_link_config *lp = &np->link_config;
835 int link_up;
836 u64 val;
837 u16 current_speed;
838 unsigned long flags;
839 u8 current_duplex;
840
841 link_up = 0;
842 current_speed = SPEED_INVALID;
843 current_duplex = DUPLEX_INVALID;
844
845 spin_lock_irqsave(&np->lock, flags);
846
847 val = nr64_pcs(PCS_MII_STAT);
848
849 if (val & PCS_MII_STAT_LINK_STATUS) {
850 link_up = 1;
851 current_speed = SPEED_1000;
852 current_duplex = DUPLEX_FULL;
853 }
854
855 lp->active_speed = current_speed;
856 lp->active_duplex = current_duplex;
857 spin_unlock_irqrestore(&np->lock, flags);
858
859 *link_up_p = link_up;
860 return 0;
861}
862
863
864static int link_status_10g_serdes(struct niu *np, int *link_up_p)
865{
866 unsigned long flags;
867 struct niu_link_config *lp = &np->link_config;
868 int link_up = 0;
869 int link_ok = 1;
870 u64 val, val2;
871 u16 current_speed;
872 u8 current_duplex;
873
874 if (!(np->flags & NIU_FLAGS_10G))
875 return link_status_1g_serdes(np, link_up_p);
876
877 current_speed = SPEED_INVALID;
878 current_duplex = DUPLEX_INVALID;
879 spin_lock_irqsave(&np->lock, flags);
880
881 val = nr64_xpcs(XPCS_STATUS(0));
882 val2 = nr64_mac(XMAC_INTER2);
883 if (val2 & 0x01000000)
884 link_ok = 0;
885
886 if ((val & 0x1000ULL) && link_ok) {
887 link_up = 1;
888 current_speed = SPEED_10000;
889 current_duplex = DUPLEX_FULL;
890 }
891 lp->active_speed = current_speed;
892 lp->active_duplex = current_duplex;
893 spin_unlock_irqrestore(&np->lock, flags);
894 *link_up_p = link_up;
895 return 0;
896}
897
898
899static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
900{
901 struct niu_link_config *lp = &np->link_config;
902 u16 current_speed, bmsr;
903 unsigned long flags;
904 u8 current_duplex;
905 int err, link_up;
906
907 link_up = 0;
908 current_speed = SPEED_INVALID;
909 current_duplex = DUPLEX_INVALID;
910
911 spin_lock_irqsave(&np->lock, flags);
912
913 err = -EINVAL;
914
915 err = mii_read(np, np->phy_addr, MII_BMSR);
916 if (err < 0)
917 goto out;
918
919 bmsr = err;
920 if (bmsr & BMSR_LSTATUS) {
921 u16 adv, lpa, common, estat;
922
923 err = mii_read(np, np->phy_addr, MII_ADVERTISE);
924 if (err < 0)
925 goto out;
926 adv = err;
927
928 err = mii_read(np, np->phy_addr, MII_LPA);
929 if (err < 0)
930 goto out;
931 lpa = err;
932
933 common = adv & lpa;
934
935 err = mii_read(np, np->phy_addr, MII_ESTATUS);
936 if (err < 0)
937 goto out;
938 estat = err;
939 link_up = 1;
940 current_speed = SPEED_1000;
941 current_duplex = DUPLEX_FULL;
942
943 }
944 lp->active_speed = current_speed;
945 lp->active_duplex = current_duplex;
946 err = 0;
947
948out:
949 spin_unlock_irqrestore(&np->lock, flags);
950
951 *link_up_p = link_up;
952 return err;
953}
954
955
709static int bcm8704_reset(struct niu *np) 956static int bcm8704_reset(struct niu *np)
710{ 957{
711 int err, limit; 958 int err, limit;
@@ -1022,6 +1269,69 @@ static int mii_reset(struct niu *np)
1022 return 0; 1269 return 0;
1023} 1270}
1024 1271
1272
1273
1274static int xcvr_init_1g_rgmii(struct niu *np)
1275{
1276 int err;
1277 u64 val;
1278 u16 bmcr, bmsr, estat;
1279
1280 val = nr64(MIF_CONFIG);
1281 val &= ~MIF_CONFIG_INDIRECT_MODE;
1282 nw64(MIF_CONFIG, val);
1283
1284 err = mii_reset(np);
1285 if (err)
1286 return err;
1287
1288 err = mii_read(np, np->phy_addr, MII_BMSR);
1289 if (err < 0)
1290 return err;
1291 bmsr = err;
1292
1293 estat = 0;
1294 if (bmsr & BMSR_ESTATEN) {
1295 err = mii_read(np, np->phy_addr, MII_ESTATUS);
1296 if (err < 0)
1297 return err;
1298 estat = err;
1299 }
1300
1301 bmcr = 0;
1302 err = mii_write(np, np->phy_addr, MII_BMCR, bmcr);
1303 if (err)
1304 return err;
1305
1306 if (bmsr & BMSR_ESTATEN) {
1307 u16 ctrl1000 = 0;
1308
1309 if (estat & ESTATUS_1000_TFULL)
1310 ctrl1000 |= ADVERTISE_1000FULL;
1311 err = mii_write(np, np->phy_addr, MII_CTRL1000, ctrl1000);
1312 if (err)
1313 return err;
1314 }
1315
1316 bmcr = (BMCR_SPEED1000 | BMCR_FULLDPLX);
1317
1318 err = mii_write(np, np->phy_addr, MII_BMCR, bmcr);
1319 if (err)
1320 return err;
1321
1322 err = mii_read(np, np->phy_addr, MII_BMCR);
1323 if (err < 0)
1324 return err;
1325 bmcr = mii_read(np, np->phy_addr, MII_BMCR);
1326
1327 err = mii_read(np, np->phy_addr, MII_BMSR);
1328 if (err < 0)
1329 return err;
1330
1331 return 0;
1332}
1333
1334
1025static int mii_init_common(struct niu *np) 1335static int mii_init_common(struct niu *np)
1026{ 1336{
1027 struct niu_link_config *lp = &np->link_config; 1337 struct niu_link_config *lp = &np->link_config;
@@ -1429,6 +1739,16 @@ static void niu_timer(unsigned long __opaque)
1429 add_timer(&np->timer); 1739 add_timer(&np->timer);
1430} 1740}
1431 1741
1742static const struct niu_phy_ops phy_ops_10g_serdes = {
1743 .serdes_init = serdes_init_10g_serdes,
1744 .link_status = link_status_10g_serdes,
1745};
1746
1747static const struct niu_phy_ops phy_ops_1g_rgmii = {
1748 .xcvr_init = xcvr_init_1g_rgmii,
1749 .link_status = link_status_1g_rgmii,
1750};
1751
1432static const struct niu_phy_ops phy_ops_10g_fiber_niu = { 1752static const struct niu_phy_ops phy_ops_10g_fiber_niu = {
1433 .serdes_init = serdes_init_niu, 1753 .serdes_init = serdes_init_niu,
1434 .xcvr_init = xcvr_init_10g, 1754 .xcvr_init = xcvr_init_10g,
@@ -1487,6 +1807,152 @@ static const struct niu_phy_template phy_template_1g_copper = {
1487 .phy_addr_base = 0, 1807 .phy_addr_base = 0,
1488}; 1808};
1489 1809
1810static const struct niu_phy_template phy_template_1g_rgmii = {
1811 .ops = &phy_ops_1g_rgmii,
1812 .phy_addr_base = 0,
1813};
1814
1815static const struct niu_phy_template phy_template_10g_serdes = {
1816 .ops = &phy_ops_10g_serdes,
1817 .phy_addr_base = 0,
1818};
1819
1820static int niu_atca_port_num[4] = {
1821 0, 0, 11, 10
1822};
1823
1824static int serdes_init_10g_serdes(struct niu *np)
1825{
1826 struct niu_link_config *lp = &np->link_config;
1827 unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i;
1828 u64 ctrl_val, test_cfg_val, sig, mask, val;
1829 int err;
1830 u64 reset_val;
1831
1832 switch (np->port) {
1833 case 0:
1834 reset_val = ENET_SERDES_RESET_0;
1835 ctrl_reg = ENET_SERDES_0_CTRL_CFG;
1836 test_cfg_reg = ENET_SERDES_0_TEST_CFG;
1837 pll_cfg = ENET_SERDES_0_PLL_CFG;
1838 break;
1839 case 1:
1840 reset_val = ENET_SERDES_RESET_1;
1841 ctrl_reg = ENET_SERDES_1_CTRL_CFG;
1842 test_cfg_reg = ENET_SERDES_1_TEST_CFG;
1843 pll_cfg = ENET_SERDES_1_PLL_CFG;
1844 break;
1845
1846 default:
1847 return -EINVAL;
1848 }
1849 ctrl_val = (ENET_SERDES_CTRL_SDET_0 |
1850 ENET_SERDES_CTRL_SDET_1 |
1851 ENET_SERDES_CTRL_SDET_2 |
1852 ENET_SERDES_CTRL_SDET_3 |
1853 (0x5 << ENET_SERDES_CTRL_EMPH_0_SHIFT) |
1854 (0x5 << ENET_SERDES_CTRL_EMPH_1_SHIFT) |
1855 (0x5 << ENET_SERDES_CTRL_EMPH_2_SHIFT) |
1856 (0x5 << ENET_SERDES_CTRL_EMPH_3_SHIFT) |
1857 (0x1 << ENET_SERDES_CTRL_LADJ_0_SHIFT) |
1858 (0x1 << ENET_SERDES_CTRL_LADJ_1_SHIFT) |
1859 (0x1 << ENET_SERDES_CTRL_LADJ_2_SHIFT) |
1860 (0x1 << ENET_SERDES_CTRL_LADJ_3_SHIFT));
1861 test_cfg_val = 0;
1862
1863 if (lp->loopback_mode == LOOPBACK_PHY) {
1864 test_cfg_val |= ((ENET_TEST_MD_PAD_LOOPBACK <<
1865 ENET_SERDES_TEST_MD_0_SHIFT) |
1866 (ENET_TEST_MD_PAD_LOOPBACK <<
1867 ENET_SERDES_TEST_MD_1_SHIFT) |
1868 (ENET_TEST_MD_PAD_LOOPBACK <<
1869 ENET_SERDES_TEST_MD_2_SHIFT) |
1870 (ENET_TEST_MD_PAD_LOOPBACK <<
1871 ENET_SERDES_TEST_MD_3_SHIFT));
1872 }
1873
1874 esr_reset(np);
1875 nw64(pll_cfg, ENET_SERDES_PLL_FBDIV2);
1876 nw64(ctrl_reg, ctrl_val);
1877 nw64(test_cfg_reg, test_cfg_val);
1878
1879 /* Initialize all 4 lanes of the SERDES. */
1880 for (i = 0; i < 4; i++) {
1881 u32 rxtx_ctrl, glue0;
1882
1883 err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl);
1884 if (err)
1885 return err;
1886 err = esr_read_glue0(np, i, &glue0);
1887 if (err)
1888 return err;
1889
1890 rxtx_ctrl &= ~(ESR_RXTX_CTRL_VMUXLO);
1891 rxtx_ctrl |= (ESR_RXTX_CTRL_ENSTRETCH |
1892 (2 << ESR_RXTX_CTRL_VMUXLO_SHIFT));
1893
1894 glue0 &= ~(ESR_GLUE_CTRL0_SRATE |
1895 ESR_GLUE_CTRL0_THCNT |
1896 ESR_GLUE_CTRL0_BLTIME);
1897 glue0 |= (ESR_GLUE_CTRL0_RXLOSENAB |
1898 (0xf << ESR_GLUE_CTRL0_SRATE_SHIFT) |
1899 (0xff << ESR_GLUE_CTRL0_THCNT_SHIFT) |
1900 (BLTIME_300_CYCLES <<
1901 ESR_GLUE_CTRL0_BLTIME_SHIFT));
1902
1903 err = esr_write_rxtx_ctrl(np, i, rxtx_ctrl);
1904 if (err)
1905 return err;
1906 err = esr_write_glue0(np, i, glue0);
1907 if (err)
1908 return err;
1909 }
1910
1911
1912 sig = nr64(ESR_INT_SIGNALS);
1913 switch (np->port) {
1914 case 0:
1915 mask = ESR_INT_SIGNALS_P0_BITS;
1916 val = (ESR_INT_SRDY0_P0 |
1917 ESR_INT_DET0_P0 |
1918 ESR_INT_XSRDY_P0 |
1919 ESR_INT_XDP_P0_CH3 |
1920 ESR_INT_XDP_P0_CH2 |
1921 ESR_INT_XDP_P0_CH1 |
1922 ESR_INT_XDP_P0_CH0);
1923 break;
1924
1925 case 1:
1926 mask = ESR_INT_SIGNALS_P1_BITS;
1927 val = (ESR_INT_SRDY0_P1 |
1928 ESR_INT_DET0_P1 |
1929 ESR_INT_XSRDY_P1 |
1930 ESR_INT_XDP_P1_CH3 |
1931 ESR_INT_XDP_P1_CH2 |
1932 ESR_INT_XDP_P1_CH1 |
1933 ESR_INT_XDP_P1_CH0);
1934 break;
1935
1936 default:
1937 return -EINVAL;
1938 }
1939
1940 if ((sig & mask) != val) {
1941 int err;
1942 err = serdes_init_1g_serdes(np);
1943 if (!err) {
1944 np->flags &= ~NIU_FLAGS_10G;
1945 np->mac_xcvr = MAC_XCVR_PCS;
1946 } else {
1947 dev_err(np->device, PFX "Port %u 10G/1G SERDES Link Failed \n",
1948 np->port);
1949 return -ENODEV;
1950 }
1951 }
1952
1953 return 0;
1954}
1955
1490static int niu_determine_phy_disposition(struct niu *np) 1956static int niu_determine_phy_disposition(struct niu *np)
1491{ 1957{
1492 struct niu_parent *parent = np->parent; 1958 struct niu_parent *parent = np->parent;
@@ -1498,7 +1964,10 @@ static int niu_determine_phy_disposition(struct niu *np)
1498 tp = &phy_template_niu; 1964 tp = &phy_template_niu;
1499 phy_addr_off += np->port; 1965 phy_addr_off += np->port;
1500 } else { 1966 } else {
1501 switch (np->flags & (NIU_FLAGS_10G | NIU_FLAGS_FIBER)) { 1967 switch (np->flags &
1968 (NIU_FLAGS_10G |
1969 NIU_FLAGS_FIBER |
1970 NIU_FLAGS_XCVR_SERDES)) {
1502 case 0: 1971 case 0:
1503 /* 1G copper */ 1972 /* 1G copper */
1504 tp = &phy_template_1g_copper; 1973 tp = &phy_template_1g_copper;
@@ -1529,6 +1998,25 @@ static int niu_determine_phy_disposition(struct niu *np)
1529 phy_addr_off += np->port; 1998 phy_addr_off += np->port;
1530 break; 1999 break;
1531 2000
2001 case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES:
2002 case NIU_FLAGS_XCVR_SERDES | NIU_FLAGS_FIBER:
2003 case NIU_FLAGS_XCVR_SERDES:
2004 switch(np->port) {
2005 case 0:
2006 case 1:
2007 tp = &phy_template_10g_serdes;
2008 break;
2009 case 2:
2010 case 3:
2011 tp = &phy_template_1g_rgmii;
2012 break;
2013 default:
2014 return -EINVAL;
2015 break;
2016 }
2017 phy_addr_off = niu_atca_port_num[np->port];
2018 break;
2019
1532 default: 2020 default:
1533 return -EINVAL; 2021 return -EINVAL;
1534 } 2022 }
@@ -4139,6 +4627,12 @@ static void niu_init_xif_xmac(struct niu *np)
4139 struct niu_link_config *lp = &np->link_config; 4627 struct niu_link_config *lp = &np->link_config;
4140 u64 val; 4628 u64 val;
4141 4629
4630 if (np->flags & NIU_FLAGS_XCVR_SERDES) {
4631 val = nr64(MIF_CONFIG);
4632 val |= MIF_CONFIG_ATCA_GE;
4633 nw64(MIF_CONFIG, val);
4634 }
4635
4142 val = nr64_mac(XMAC_CONFIG); 4636 val = nr64_mac(XMAC_CONFIG);
4143 val &= ~XMAC_CONFIG_SEL_POR_CLK_SRC; 4637 val &= ~XMAC_CONFIG_SEL_POR_CLK_SRC;
4144 4638
@@ -4155,7 +4649,8 @@ static void niu_init_xif_xmac(struct niu *np)
4155 val &= ~XMAC_CONFIG_LFS_DISABLE; 4649 val &= ~XMAC_CONFIG_LFS_DISABLE;
4156 } else { 4650 } else {
4157 val |= XMAC_CONFIG_LFS_DISABLE; 4651 val |= XMAC_CONFIG_LFS_DISABLE;
4158 if (!(np->flags & NIU_FLAGS_FIBER)) 4652 if (!(np->flags & NIU_FLAGS_FIBER) &&
4653 !(np->flags & NIU_FLAGS_XCVR_SERDES))
4159 val |= XMAC_CONFIG_1G_PCS_BYPASS; 4654 val |= XMAC_CONFIG_1G_PCS_BYPASS;
4160 else 4655 else
4161 val &= ~XMAC_CONFIG_1G_PCS_BYPASS; 4656 val &= ~XMAC_CONFIG_1G_PCS_BYPASS;
@@ -4224,16 +4719,26 @@ static void niu_init_xif(struct niu *np)
4224 4719
4225static void niu_pcs_mii_reset(struct niu *np) 4720static void niu_pcs_mii_reset(struct niu *np)
4226{ 4721{
4722 int limit = 1000;
4227 u64 val = nr64_pcs(PCS_MII_CTL); 4723 u64 val = nr64_pcs(PCS_MII_CTL);
4228 val |= PCS_MII_CTL_RST; 4724 val |= PCS_MII_CTL_RST;
4229 nw64_pcs(PCS_MII_CTL, val); 4725 nw64_pcs(PCS_MII_CTL, val);
4726 while ((--limit >= 0) && (val & PCS_MII_CTL_RST)) {
4727 udelay(100);
4728 val = nr64_pcs(PCS_MII_CTL);
4729 }
4230} 4730}
4231 4731
4232static void niu_xpcs_reset(struct niu *np) 4732static void niu_xpcs_reset(struct niu *np)
4233{ 4733{
4734 int limit = 1000;
4234 u64 val = nr64_xpcs(XPCS_CONTROL1); 4735 u64 val = nr64_xpcs(XPCS_CONTROL1);
4235 val |= XPCS_CONTROL1_RESET; 4736 val |= XPCS_CONTROL1_RESET;
4236 nw64_xpcs(XPCS_CONTROL1, val); 4737 nw64_xpcs(XPCS_CONTROL1, val);
4738 while ((--limit >= 0) && (val & XPCS_CONTROL1_RESET)) {
4739 udelay(100);
4740 val = nr64_xpcs(XPCS_CONTROL1);
4741 }
4237} 4742}
4238 4743
4239static int niu_init_pcs(struct niu *np) 4744static int niu_init_pcs(struct niu *np)
@@ -4241,7 +4746,9 @@ static int niu_init_pcs(struct niu *np)
4241 struct niu_link_config *lp = &np->link_config; 4746 struct niu_link_config *lp = &np->link_config;
4242 u64 val; 4747 u64 val;
4243 4748
4244 switch (np->flags & (NIU_FLAGS_10G | NIU_FLAGS_FIBER)) { 4749 switch (np->flags & (NIU_FLAGS_10G |
4750 NIU_FLAGS_FIBER |
4751 NIU_FLAGS_XCVR_SERDES)) {
4245 case NIU_FLAGS_FIBER: 4752 case NIU_FLAGS_FIBER:
4246 /* 1G fiber */ 4753 /* 1G fiber */
4247 nw64_pcs(PCS_CONF, PCS_CONF_MASK | PCS_CONF_ENABLE); 4754 nw64_pcs(PCS_CONF, PCS_CONF_MASK | PCS_CONF_ENABLE);
@@ -4251,6 +4758,8 @@ static int niu_init_pcs(struct niu *np)
4251 4758
4252 case NIU_FLAGS_10G: 4759 case NIU_FLAGS_10G:
4253 case NIU_FLAGS_10G | NIU_FLAGS_FIBER: 4760 case NIU_FLAGS_10G | NIU_FLAGS_FIBER:
4761 case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES:
4762 /* 10G SERDES */
4254 if (!(np->flags & NIU_FLAGS_XMAC)) 4763 if (!(np->flags & NIU_FLAGS_XMAC))
4255 return -EINVAL; 4764 return -EINVAL;
4256 4765
@@ -4273,8 +4782,18 @@ static int niu_init_pcs(struct niu *np)
4273 (void) nr64_xpcs(XPCS_SYMERR_CNT23); 4782 (void) nr64_xpcs(XPCS_SYMERR_CNT23);
4274 break; 4783 break;
4275 4784
4785
4786 case NIU_FLAGS_XCVR_SERDES:
4787 /* 1G SERDES */
4788 niu_pcs_mii_reset(np);
4789 nw64_pcs(PCS_CONF, PCS_CONF_MASK | PCS_CONF_ENABLE);
4790 nw64_pcs(PCS_DPATH_MODE, 0);
4791 break;
4792
4276 case 0: 4793 case 0:
4277 /* 1G copper */ 4794 /* 1G copper */
4795 case NIU_FLAGS_XCVR_SERDES | NIU_FLAGS_FIBER:
4796 /* 1G RGMII FIBER */
4278 nw64_pcs(PCS_DPATH_MODE, PCS_DPATH_MODE_MII); 4797 nw64_pcs(PCS_DPATH_MODE, PCS_DPATH_MODE_MII);
4279 niu_pcs_mii_reset(np); 4798 niu_pcs_mii_reset(np);
4280 break; 4799 break;
@@ -6268,7 +6787,19 @@ static void __devinit niu_pci_vpd_validate(struct niu *np)
6268 return; 6787 return;
6269 } 6788 }
6270 6789
6271 if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { 6790 if (!strcmp(np->vpd.model, "SUNW,CP3220") ||
6791 !strcmp(np->vpd.model, "SUNW,CP3260")) {
6792 np->flags |= NIU_FLAGS_10G;
6793 np->flags &= ~NIU_FLAGS_FIBER;
6794 np->flags |= NIU_FLAGS_XCVR_SERDES;
6795 np->mac_xcvr = MAC_XCVR_PCS;
6796 if (np->port > 1) {
6797 np->flags |= NIU_FLAGS_FIBER;
6798 np->flags &= ~NIU_FLAGS_10G;
6799 }
6800 if (np->flags & NIU_FLAGS_10G)
6801 np->mac_xcvr = MAC_XCVR_XPCS;
6802 } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) {
6272 dev_err(np->device, PFX "Illegal phy string [%s].\n", 6803 dev_err(np->device, PFX "Illegal phy string [%s].\n",
6273 np->vpd.phy_type); 6804 np->vpd.phy_type);
6274 dev_err(np->device, PFX "Falling back to SPROM.\n"); 6805 dev_err(np->device, PFX "Falling back to SPROM.\n");
@@ -6731,80 +7262,93 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent)
6731 u32 val; 7262 u32 val;
6732 int err; 7263 int err;
6733 7264
6734 err = fill_phy_probe_info(np, parent, info);
6735 if (err)
6736 return err;
6737 7265
6738 num_10g = count_10g_ports(info, &lowest_10g); 7266 if (!strcmp(np->vpd.model, "SUNW,CP3220") ||
6739 num_1g = count_1g_ports(info, &lowest_1g); 7267 !strcmp(np->vpd.model, "SUNW,CP3260")) {
6740 7268 num_10g = 0;
6741 switch ((num_10g << 4) | num_1g) { 7269 num_1g = 2;
6742 case 0x24: 7270 parent->plat_type = PLAT_TYPE_ATCA_CP3220;
6743 if (lowest_1g == 10) 7271 parent->num_ports = 4;
6744 parent->plat_type = PLAT_TYPE_VF_P0; 7272 val = (phy_encode(PORT_TYPE_1G, 0) |
6745 else if (lowest_1g == 26) 7273 phy_encode(PORT_TYPE_1G, 1) |
6746 parent->plat_type = PLAT_TYPE_VF_P1;
6747 else
6748 goto unknown_vg_1g_port;
6749
6750 /* fallthru */
6751 case 0x22:
6752 val = (phy_encode(PORT_TYPE_10G, 0) |
6753 phy_encode(PORT_TYPE_10G, 1) |
6754 phy_encode(PORT_TYPE_1G, 2) | 7274 phy_encode(PORT_TYPE_1G, 2) |
6755 phy_encode(PORT_TYPE_1G, 3)); 7275 phy_encode(PORT_TYPE_1G, 3));
6756 break; 7276 } else {
6757 7277 err = fill_phy_probe_info(np, parent, info);
6758 case 0x20: 7278 if (err)
6759 val = (phy_encode(PORT_TYPE_10G, 0) | 7279 return err;
6760 phy_encode(PORT_TYPE_10G, 1));
6761 break;
6762 7280
6763 case 0x10: 7281 num_10g = count_10g_ports(info, &lowest_10g);
6764 val = phy_encode(PORT_TYPE_10G, np->port); 7282 num_1g = count_1g_ports(info, &lowest_1g);
6765 break;
6766 7283
6767 case 0x14: 7284 switch ((num_10g << 4) | num_1g) {
6768 if (lowest_1g == 10) 7285 case 0x24:
6769 parent->plat_type = PLAT_TYPE_VF_P0; 7286 if (lowest_1g == 10)
6770 else if (lowest_1g == 26) 7287 parent->plat_type = PLAT_TYPE_VF_P0;
6771 parent->plat_type = PLAT_TYPE_VF_P1; 7288 else if (lowest_1g == 26)
6772 else 7289 parent->plat_type = PLAT_TYPE_VF_P1;
6773 goto unknown_vg_1g_port; 7290 else
7291 goto unknown_vg_1g_port;
6774 7292
6775 /* fallthru */ 7293 /* fallthru */
6776 case 0x13: 7294 case 0x22:
6777 if ((lowest_10g & 0x7) == 0)
6778 val = (phy_encode(PORT_TYPE_10G, 0) | 7295 val = (phy_encode(PORT_TYPE_10G, 0) |
6779 phy_encode(PORT_TYPE_1G, 1) |
6780 phy_encode(PORT_TYPE_1G, 2) |
6781 phy_encode(PORT_TYPE_1G, 3));
6782 else
6783 val = (phy_encode(PORT_TYPE_1G, 0) |
6784 phy_encode(PORT_TYPE_10G, 1) | 7296 phy_encode(PORT_TYPE_10G, 1) |
6785 phy_encode(PORT_TYPE_1G, 2) | 7297 phy_encode(PORT_TYPE_1G, 2) |
6786 phy_encode(PORT_TYPE_1G, 3)); 7298 phy_encode(PORT_TYPE_1G, 3));
6787 break; 7299 break;
6788 7300
6789 case 0x04: 7301 case 0x20:
6790 if (lowest_1g == 10) 7302 val = (phy_encode(PORT_TYPE_10G, 0) |
6791 parent->plat_type = PLAT_TYPE_VF_P0; 7303 phy_encode(PORT_TYPE_10G, 1));
6792 else if (lowest_1g == 26) 7304 break;
6793 parent->plat_type = PLAT_TYPE_VF_P1;
6794 else
6795 goto unknown_vg_1g_port;
6796 7305
6797 val = (phy_encode(PORT_TYPE_1G, 0) | 7306 case 0x10:
6798 phy_encode(PORT_TYPE_1G, 1) | 7307 val = phy_encode(PORT_TYPE_10G, np->port);
6799 phy_encode(PORT_TYPE_1G, 2) | 7308 break;
6800 phy_encode(PORT_TYPE_1G, 3));
6801 break;
6802 7309
6803 default: 7310 case 0x14:
6804 printk(KERN_ERR PFX "Unsupported port config " 7311 if (lowest_1g == 10)
6805 "10G[%d] 1G[%d]\n", 7312 parent->plat_type = PLAT_TYPE_VF_P0;
6806 num_10g, num_1g); 7313 else if (lowest_1g == 26)
6807 return -EINVAL; 7314 parent->plat_type = PLAT_TYPE_VF_P1;
7315 else
7316 goto unknown_vg_1g_port;
7317
7318 /* fallthru */
7319 case 0x13:
7320 if ((lowest_10g & 0x7) == 0)
7321 val = (phy_encode(PORT_TYPE_10G, 0) |
7322 phy_encode(PORT_TYPE_1G, 1) |
7323 phy_encode(PORT_TYPE_1G, 2) |
7324 phy_encode(PORT_TYPE_1G, 3));
7325 else
7326 val = (phy_encode(PORT_TYPE_1G, 0) |
7327 phy_encode(PORT_TYPE_10G, 1) |
7328 phy_encode(PORT_TYPE_1G, 2) |
7329 phy_encode(PORT_TYPE_1G, 3));
7330 break;
7331
7332 case 0x04:
7333 if (lowest_1g == 10)
7334 parent->plat_type = PLAT_TYPE_VF_P0;
7335 else if (lowest_1g == 26)
7336 parent->plat_type = PLAT_TYPE_VF_P1;
7337 else
7338 goto unknown_vg_1g_port;
7339
7340 val = (phy_encode(PORT_TYPE_1G, 0) |
7341 phy_encode(PORT_TYPE_1G, 1) |
7342 phy_encode(PORT_TYPE_1G, 2) |
7343 phy_encode(PORT_TYPE_1G, 3));
7344 break;
7345
7346 default:
7347 printk(KERN_ERR PFX "Unsupported port config "
7348 "10G[%d] 1G[%d]\n",
7349 num_10g, num_1g);
7350 return -EINVAL;
7351 }
6808 } 7352 }
6809 7353
6810 parent->port_phy = val; 7354 parent->port_phy = val;
@@ -7599,14 +8143,25 @@ static void __devinit niu_device_announce(struct niu *np)
7599 pr_info("%s: NIU Ethernet %s\n", 8143 pr_info("%s: NIU Ethernet %s\n",
7600 dev->name, print_mac(mac, dev->dev_addr)); 8144 dev->name, print_mac(mac, dev->dev_addr));
7601 8145
7602 pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n", 8146 if (np->parent->plat_type == PLAT_TYPE_ATCA_CP3220) {
7603 dev->name, 8147 pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n",
7604 (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), 8148 dev->name,
7605 (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), 8149 (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"),
7606 (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"), 8150 (np->flags & NIU_FLAGS_10G ? "10G" : "1G"),
7607 (np->mac_xcvr == MAC_XCVR_MII ? "MII" : 8151 (np->flags & NIU_FLAGS_FIBER ? "RGMII FIBER" : "SERDES"),
7608 (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), 8152 (np->mac_xcvr == MAC_XCVR_MII ? "MII" :
7609 np->vpd.phy_type); 8153 (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")),
8154 np->vpd.phy_type);
8155 } else {
8156 pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n",
8157 dev->name,
8158 (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"),
8159 (np->flags & NIU_FLAGS_10G ? "10G" : "1G"),
8160 (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"),
8161 (np->mac_xcvr == MAC_XCVR_MII ? "MII" :
8162 (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")),
8163 np->vpd.phy_type);
8164 }
7610} 8165}
7611 8166
7612static int __devinit niu_pci_init_one(struct pci_dev *pdev, 8167static int __devinit niu_pci_init_one(struct pci_dev *pdev,
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 59dc05fcd371..336aed08b275 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -3061,6 +3061,7 @@ struct niu_parent {
3061#define PLAT_TYPE_NIU 0x02 3061#define PLAT_TYPE_NIU 0x02
3062#define PLAT_TYPE_VF_P0 0x03 3062#define PLAT_TYPE_VF_P0 0x03
3063#define PLAT_TYPE_VF_P1 0x04 3063#define PLAT_TYPE_VF_P1 0x04
3064#define PLAT_TYPE_ATCA_CP3220 0x08
3064 3065
3065 u8 num_ports; 3066 u8 num_ports;
3066 3067
@@ -3198,10 +3199,11 @@ struct niu {
3198 struct niu_parent *parent; 3199 struct niu_parent *parent;
3199 3200
3200 u32 flags; 3201 u32 flags;
3202#define NIU_FLAGS_VPD_VALID 0x00800000 /* VPD has valid version */
3201#define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */ 3203#define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */
3202#define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */ 3204#define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */
3203#define NIU_FLAGS_PROMISC 0x00100000 /* PROMISC enabled */ 3205#define NIU_FLAGS_PROMISC 0x00100000 /* PROMISC enabled */
3204#define NIU_FLAGS_VPD_VALID 0x00080000 /* VPD has valid version */ 3206#define NIU_FLAGS_XCVR_SERDES 0x00080000 /* 0=PHY 1=SERDES */
3205#define NIU_FLAGS_10G 0x00040000 /* 0=1G 1=10G */ 3207#define NIU_FLAGS_10G 0x00040000 /* 0=1G 1=10G */
3206#define NIU_FLAGS_FIBER 0x00020000 /* 0=COPPER 1=FIBER */ 3208#define NIU_FLAGS_FIBER 0x00020000 /* 0=COPPER 1=FIBER */
3207#define NIU_FLAGS_XMAC 0x00010000 /* 0=BMAC 1=XMAC */ 3209#define NIU_FLAGS_XMAC 0x00010000 /* 0=BMAC 1=XMAC */