NIU: Add Sun CP3260 ATCA blade support

This patch adds support for the Sun CP3260 ATCA blade which is
a N2 based ATCA blade with 2 NIU ports. The NIU ports do not
have on-board PHY.

Signed-off-by: Santwona Behera <santwona.behera@sun.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Santwona Behera and committed by David S. Miller e3e081e1 e8f6fbf6

+293 -6
+280 -6
drivers/net/niu.c
··· 406 } 407 408 /* Mode is always 10G fiber. */ 409 - static int serdes_init_niu(struct niu *np) 410 { 411 struct niu_link_config *lp = &np->link_config; 412 u32 tx_cfg, rx_cfg; ··· 440 return err; 441 } 442 443 return 0; 444 } 445 ··· 2171 .link_status = link_status_10g_serdes, 2172 }; 2173 2174 static const struct niu_phy_ops phy_ops_1g_rgmii = { 2175 .xcvr_init = xcvr_init_1g_rgmii, 2176 .link_status = link_status_1g_rgmii, 2177 }; 2178 2179 static const struct niu_phy_ops phy_ops_10g_fiber_niu = { 2180 - .serdes_init = serdes_init_niu, 2181 .xcvr_init = xcvr_init_10g, 2182 .link_status = link_status_10g, 2183 }; ··· 2225 u32 phy_addr_base; 2226 }; 2227 2228 - static const struct niu_phy_template phy_template_niu = { 2229 .ops = &phy_ops_10g_fiber_niu, 2230 .phy_addr_base = 16, 2231 }; 2232 2233 static const struct niu_phy_template phy_template_10g_fiber = { ··· 2419 u32 phy_addr_off = 0; 2420 2421 if (plat_type == PLAT_TYPE_NIU) { 2422 - tp = &phy_template_niu; 2423 - phy_addr_off += np->port; 2424 } else { 2425 switch (np->flags & 2426 (NIU_FLAGS_10G | ··· 7467 np->flags |= NIU_FLAGS_10G; 7468 np->flags &= ~NIU_FLAGS_FIBER; 7469 np->mac_xcvr = MAC_XCVR_XPCS; 7470 } else { 7471 return -EINVAL; 7472 } ··· 8001 u32 val; 8002 int err; 8003 8004 if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || 8005 !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { 8006 num_10g = 0; ··· 8019 parent->num_ports = 2; 8020 val = (phy_encode(PORT_TYPE_10G, 0) | 8021 phy_encode(PORT_TYPE_10G, 1)); 8022 } else { 8023 err = fill_phy_probe_info(np, parent, info); 8024 if (err) ··· 8928 dev->name, 8929 (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), 8930 (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), 8931 - (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"), 8932 (np->mac_xcvr == MAC_XCVR_MII ? "MII" : 8933 (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), 8934 np->vpd.phy_type);
··· 406 } 407 408 /* Mode is always 10G fiber. */ 409 + static int serdes_init_niu_10g_fiber(struct niu *np) 410 { 411 struct niu_link_config *lp = &np->link_config; 412 u32 tx_cfg, rx_cfg; ··· 440 return err; 441 } 442 443 + return 0; 444 + } 445 + 446 + static int serdes_init_niu_1g_serdes(struct niu *np) 447 + { 448 + struct niu_link_config *lp = &np->link_config; 449 + u16 pll_cfg, pll_sts; 450 + int max_retry = 100; 451 + u64 sig, mask, val; 452 + u32 tx_cfg, rx_cfg; 453 + unsigned long i; 454 + int err; 455 + 456 + tx_cfg = (PLL_TX_CFG_ENTX | PLL_TX_CFG_SWING_1375MV | 457 + PLL_TX_CFG_RATE_HALF); 458 + rx_cfg = (PLL_RX_CFG_ENRX | PLL_RX_CFG_TERM_0P8VDDT | 459 + PLL_RX_CFG_ALIGN_ENA | PLL_RX_CFG_LOS_LTHRESH | 460 + PLL_RX_CFG_RATE_HALF); 461 + 462 + if (np->port == 0) 463 + rx_cfg |= PLL_RX_CFG_EQ_LP_ADAPTIVE; 464 + 465 + if (lp->loopback_mode == LOOPBACK_PHY) { 466 + u16 test_cfg = PLL_TEST_CFG_LOOPBACK_CML_DIS; 467 + 468 + mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, 469 + ESR2_TI_PLL_TEST_CFG_L, test_cfg); 470 + 471 + tx_cfg |= PLL_TX_CFG_ENTEST; 472 + rx_cfg |= PLL_RX_CFG_ENTEST; 473 + } 474 + 475 + /* Initialize PLL for 1G */ 476 + pll_cfg = (PLL_CFG_ENPLL | PLL_CFG_MPY_8X); 477 + 478 + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, 479 + ESR2_TI_PLL_CFG_L, pll_cfg); 480 + if (err) { 481 + dev_err(np->device, PFX "NIU Port %d " 482 + "serdes_init_niu_1g_serdes: " 483 + "mdio write to ESR2_TI_PLL_CFG_L failed", np->port); 484 + return err; 485 + } 486 + 487 + pll_sts = PLL_CFG_ENPLL; 488 + 489 + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, 490 + ESR2_TI_PLL_STS_L, pll_sts); 491 + if (err) { 492 + dev_err(np->device, PFX "NIU Port %d " 493 + "serdes_init_niu_1g_serdes: " 494 + "mdio write to ESR2_TI_PLL_STS_L failed", np->port); 495 + return err; 496 + } 497 + 498 + udelay(200); 499 + 500 + /* Initialize all 4 lanes of the SERDES. */ 501 + for (i = 0; i < 4; i++) { 502 + err = esr2_set_tx_cfg(np, i, tx_cfg); 503 + if (err) 504 + return err; 505 + } 506 + 507 + for (i = 0; i < 4; i++) { 508 + err = esr2_set_rx_cfg(np, i, rx_cfg); 509 + if (err) 510 + return err; 511 + } 512 + 513 + switch (np->port) { 514 + case 0: 515 + val = (ESR_INT_SRDY0_P0 | ESR_INT_DET0_P0); 516 + mask = val; 517 + break; 518 + 519 + case 1: 520 + val = (ESR_INT_SRDY0_P1 | ESR_INT_DET0_P1); 521 + mask = val; 522 + break; 523 + 524 + default: 525 + return -EINVAL; 526 + } 527 + 528 + while (max_retry--) { 529 + sig = nr64(ESR_INT_SIGNALS); 530 + if ((sig & mask) == val) 531 + break; 532 + 533 + mdelay(500); 534 + } 535 + 536 + if ((sig & mask) != val) { 537 + dev_err(np->device, PFX "Port %u signal bits [%08x] are not " 538 + "[%08x]\n", np->port, (int) (sig & mask), (int) val); 539 + return -ENODEV; 540 + } 541 + 542 + return 0; 543 + } 544 + 545 + static int serdes_init_niu_10g_serdes(struct niu *np) 546 + { 547 + struct niu_link_config *lp = &np->link_config; 548 + u32 tx_cfg, rx_cfg, pll_cfg, pll_sts; 549 + int max_retry = 100; 550 + u64 sig, mask, val; 551 + unsigned long i; 552 + int err; 553 + 554 + tx_cfg = (PLL_TX_CFG_ENTX | PLL_TX_CFG_SWING_1375MV); 555 + rx_cfg = (PLL_RX_CFG_ENRX | PLL_RX_CFG_TERM_0P8VDDT | 556 + PLL_RX_CFG_ALIGN_ENA | PLL_RX_CFG_LOS_LTHRESH | 557 + PLL_RX_CFG_EQ_LP_ADAPTIVE); 558 + 559 + if (lp->loopback_mode == LOOPBACK_PHY) { 560 + u16 test_cfg = PLL_TEST_CFG_LOOPBACK_CML_DIS; 561 + 562 + mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, 563 + ESR2_TI_PLL_TEST_CFG_L, test_cfg); 564 + 565 + tx_cfg |= PLL_TX_CFG_ENTEST; 566 + rx_cfg |= PLL_RX_CFG_ENTEST; 567 + } 568 + 569 + /* Initialize PLL for 10G */ 570 + pll_cfg = (PLL_CFG_ENPLL | PLL_CFG_MPY_10X); 571 + 572 + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, 573 + ESR2_TI_PLL_CFG_L, pll_cfg & 0xffff); 574 + if (err) { 575 + dev_err(np->device, PFX "NIU Port %d " 576 + "serdes_init_niu_10g_serdes: " 577 + "mdio write to ESR2_TI_PLL_CFG_L failed", np->port); 578 + return err; 579 + } 580 + 581 + pll_sts = PLL_CFG_ENPLL; 582 + 583 + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, 584 + ESR2_TI_PLL_STS_L, pll_sts & 0xffff); 585 + if (err) { 586 + dev_err(np->device, PFX "NIU Port %d " 587 + "serdes_init_niu_10g_serdes: " 588 + "mdio write to ESR2_TI_PLL_STS_L failed", np->port); 589 + return err; 590 + } 591 + 592 + udelay(200); 593 + 594 + /* Initialize all 4 lanes of the SERDES. */ 595 + for (i = 0; i < 4; i++) { 596 + err = esr2_set_tx_cfg(np, i, tx_cfg); 597 + if (err) 598 + return err; 599 + } 600 + 601 + for (i = 0; i < 4; i++) { 602 + err = esr2_set_rx_cfg(np, i, rx_cfg); 603 + if (err) 604 + return err; 605 + } 606 + 607 + /* check if serdes is ready */ 608 + 609 + switch (np->port) { 610 + case 0: 611 + mask = ESR_INT_SIGNALS_P0_BITS; 612 + val = (ESR_INT_SRDY0_P0 | 613 + ESR_INT_DET0_P0 | 614 + ESR_INT_XSRDY_P0 | 615 + ESR_INT_XDP_P0_CH3 | 616 + ESR_INT_XDP_P0_CH2 | 617 + ESR_INT_XDP_P0_CH1 | 618 + ESR_INT_XDP_P0_CH0); 619 + break; 620 + 621 + case 1: 622 + mask = ESR_INT_SIGNALS_P1_BITS; 623 + val = (ESR_INT_SRDY0_P1 | 624 + ESR_INT_DET0_P1 | 625 + ESR_INT_XSRDY_P1 | 626 + ESR_INT_XDP_P1_CH3 | 627 + ESR_INT_XDP_P1_CH2 | 628 + ESR_INT_XDP_P1_CH1 | 629 + ESR_INT_XDP_P1_CH0); 630 + break; 631 + 632 + default: 633 + return -EINVAL; 634 + } 635 + 636 + while (max_retry--) { 637 + sig = nr64(ESR_INT_SIGNALS); 638 + if ((sig & mask) == val) 639 + break; 640 + 641 + mdelay(500); 642 + } 643 + 644 + if ((sig & mask) != val) { 645 + pr_info(PFX "NIU Port %u signal bits [%08x] are not " 646 + "[%08x] for 10G...trying 1G\n", 647 + np->port, (int) (sig & mask), (int) val); 648 + 649 + /* 10G failed, try initializing at 1G */ 650 + err = serdes_init_niu_1g_serdes(np); 651 + if (!err) { 652 + np->flags &= ~NIU_FLAGS_10G; 653 + np->mac_xcvr = MAC_XCVR_PCS; 654 + } else { 655 + dev_err(np->device, PFX "Port %u 10G/1G SERDES " 656 + "Link Failed \n", np->port); 657 + return -ENODEV; 658 + } 659 + } 660 return 0; 661 } 662 ··· 1954 .link_status = link_status_10g_serdes, 1955 }; 1956 1957 + static const struct niu_phy_ops phy_ops_10g_serdes_niu = { 1958 + .serdes_init = serdes_init_niu_10g_serdes, 1959 + .link_status = link_status_10g_serdes, 1960 + }; 1961 + 1962 + static const struct niu_phy_ops phy_ops_1g_serdes_niu = { 1963 + .serdes_init = serdes_init_niu_1g_serdes, 1964 + .link_status = link_status_1g_serdes, 1965 + }; 1966 + 1967 static const struct niu_phy_ops phy_ops_1g_rgmii = { 1968 .xcvr_init = xcvr_init_1g_rgmii, 1969 .link_status = link_status_1g_rgmii, 1970 }; 1971 1972 static const struct niu_phy_ops phy_ops_10g_fiber_niu = { 1973 + .serdes_init = serdes_init_niu_10g_fiber, 1974 .xcvr_init = xcvr_init_10g, 1975 .link_status = link_status_10g, 1976 }; ··· 1998 u32 phy_addr_base; 1999 }; 2000 2001 + static const struct niu_phy_template phy_template_niu_10g_fiber = { 2002 .ops = &phy_ops_10g_fiber_niu, 2003 .phy_addr_base = 16, 2004 + }; 2005 + 2006 + static const struct niu_phy_template phy_template_niu_10g_serdes = { 2007 + .ops = &phy_ops_10g_serdes_niu, 2008 + .phy_addr_base = 0, 2009 + }; 2010 + 2011 + static const struct niu_phy_template phy_template_niu_1g_serdes = { 2012 + .ops = &phy_ops_1g_serdes_niu, 2013 + .phy_addr_base = 0, 2014 }; 2015 2016 static const struct niu_phy_template phy_template_10g_fiber = { ··· 2182 u32 phy_addr_off = 0; 2183 2184 if (plat_type == PLAT_TYPE_NIU) { 2185 + switch (np->flags & 2186 + (NIU_FLAGS_10G | 2187 + NIU_FLAGS_FIBER | 2188 + NIU_FLAGS_XCVR_SERDES)) { 2189 + case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: 2190 + /* 10G Serdes */ 2191 + tp = &phy_template_niu_10g_serdes; 2192 + break; 2193 + case NIU_FLAGS_XCVR_SERDES: 2194 + /* 1G Serdes */ 2195 + tp = &phy_template_niu_1g_serdes; 2196 + break; 2197 + case NIU_FLAGS_10G | NIU_FLAGS_FIBER: 2198 + /* 10G Fiber */ 2199 + default: 2200 + tp = &phy_template_niu_10g_fiber; 2201 + phy_addr_off += np->port; 2202 + break; 2203 + } 2204 } else { 2205 switch (np->flags & 2206 (NIU_FLAGS_10G | ··· 7213 np->flags |= NIU_FLAGS_10G; 7214 np->flags &= ~NIU_FLAGS_FIBER; 7215 np->mac_xcvr = MAC_XCVR_XPCS; 7216 + } else if (!strcmp(phy_prop, "xgsd") || !strcmp(phy_prop, "gsd")) { 7217 + /* 10G Serdes or 1G Serdes, default to 10G */ 7218 + np->flags |= NIU_FLAGS_10G; 7219 + np->flags &= ~NIU_FLAGS_FIBER; 7220 + np->flags |= NIU_FLAGS_XCVR_SERDES; 7221 + np->mac_xcvr = MAC_XCVR_XPCS; 7222 } else { 7223 return -EINVAL; 7224 } ··· 7741 u32 val; 7742 int err; 7743 7744 + num_10g = num_1g = 0; 7745 + 7746 if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || 7747 !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { 7748 num_10g = 0; ··· 7757 parent->num_ports = 2; 7758 val = (phy_encode(PORT_TYPE_10G, 0) | 7759 phy_encode(PORT_TYPE_10G, 1)); 7760 + } else if ((np->flags & NIU_FLAGS_XCVR_SERDES) && 7761 + (parent->plat_type == PLAT_TYPE_NIU)) { 7762 + /* this is the Monza case */ 7763 + if (np->flags & NIU_FLAGS_10G) { 7764 + val = (phy_encode(PORT_TYPE_10G, 0) | 7765 + phy_encode(PORT_TYPE_10G, 1)); 7766 + } else { 7767 + val = (phy_encode(PORT_TYPE_1G, 0) | 7768 + phy_encode(PORT_TYPE_1G, 1)); 7769 + } 7770 } else { 7771 err = fill_phy_probe_info(np, parent, info); 7772 if (err) ··· 8656 dev->name, 8657 (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), 8658 (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), 8659 + (np->flags & NIU_FLAGS_FIBER ? "FIBER" : 8660 + (np->flags & NIU_FLAGS_XCVR_SERDES ? "SERDES" : 8661 + "COPPER")), 8662 (np->mac_xcvr == MAC_XCVR_MII ? "MII" : 8663 (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), 8664 np->vpd.phy_type);
+13
drivers/net/niu.h
··· 1048 #define PLL_CFG_LD_SHIFT 8 1049 #define PLL_CFG_MPY 0x0000001e 1050 #define PLL_CFG_MPY_SHIFT 1 1051 #define PLL_CFG_ENPLL 0x00000001 1052 1053 #define ESR2_TI_PLL_STS_L (ESR2_BASE + 0x002) ··· 1100 #define PLL_TX_CFG_INVPAIR 0x00000080 1101 #define PLL_TX_CFG_RATE 0x00000060 1102 #define PLL_TX_CFG_RATE_SHIFT 5 1103 #define PLL_TX_CFG_BUSWIDTH 0x0000001c 1104 #define PLL_TX_CFG_BUSWIDTH_SHIFT 2 1105 #define PLL_TX_CFG_ENTEST 0x00000002 ··· 1142 #define PLL_RX_CFG_INVPAIR 0x00000080 1143 #define PLL_RX_CFG_RATE 0x00000060 1144 #define PLL_RX_CFG_RATE_SHIFT 5 1145 #define PLL_RX_CFG_BUSWIDTH 0x0000001c 1146 #define PLL_RX_CFG_BUSWIDTH_SHIFT 2 1147 #define PLL_RX_CFG_ENTEST 0x00000002
··· 1048 #define PLL_CFG_LD_SHIFT 8 1049 #define PLL_CFG_MPY 0x0000001e 1050 #define PLL_CFG_MPY_SHIFT 1 1051 + #define PLL_CFG_MPY_4X 0x0 1052 + #define PLL_CFG_MPY_5X 0x00000002 1053 + #define PLL_CFG_MPY_6X 0x00000004 1054 + #define PLL_CFG_MPY_8X 0x00000008 1055 + #define PLL_CFG_MPY_10X 0x0000000a 1056 + #define PLL_CFG_MPY_12X 0x0000000c 1057 + #define PLL_CFG_MPY_12P5X 0x0000000e 1058 #define PLL_CFG_ENPLL 0x00000001 1059 1060 #define ESR2_TI_PLL_STS_L (ESR2_BASE + 0x002) ··· 1093 #define PLL_TX_CFG_INVPAIR 0x00000080 1094 #define PLL_TX_CFG_RATE 0x00000060 1095 #define PLL_TX_CFG_RATE_SHIFT 5 1096 + #define PLL_TX_CFG_RATE_FULL 0x0 1097 + #define PLL_TX_CFG_RATE_HALF 0x20 1098 + #define PLL_TX_CFG_RATE_QUAD 0x40 1099 #define PLL_TX_CFG_BUSWIDTH 0x0000001c 1100 #define PLL_TX_CFG_BUSWIDTH_SHIFT 2 1101 #define PLL_TX_CFG_ENTEST 0x00000002 ··· 1132 #define PLL_RX_CFG_INVPAIR 0x00000080 1133 #define PLL_RX_CFG_RATE 0x00000060 1134 #define PLL_RX_CFG_RATE_SHIFT 5 1135 + #define PLL_RX_CFG_RATE_FULL 0x0 1136 + #define PLL_RX_CFG_RATE_HALF 0x20 1137 + #define PLL_RX_CFG_RATE_QUAD 0x40 1138 #define PLL_RX_CFG_BUSWIDTH 0x0000001c 1139 #define PLL_RX_CFG_BUSWIDTH_SHIFT 2 1140 #define PLL_RX_CFG_ENTEST 0x00000002