aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorChien Tung <chien.tin.tung@intel.com>2009-04-08 17:27:18 -0400
committerRoland Dreier <rolandd@cisco.com>2009-04-08 17:27:18 -0400
commita4849fc157cdbe4fb68cfe37e7222697f003deb5 (patch)
tree315f1f55d5167b8006cf40d175b6eaae6914d43c /drivers/infiniband
parent1b9493248cf5e9f1ecc045488100cbf3ccd91be1 (diff)
RDMA/nes: Add wide_ppm_offset parm for switch compatibility
We have observed unstable link with a new BNT switch. Add wide_ppm_offset parameter to allow the user to control the clock ppm offset on the CX4 interface for better compatibility. Default is 100ppm, setting it to 1 will increase it to 300ppm. Change default SerDes1 reference clock to external source. Signed-off-by: Chien Tung <chien.tin.tung@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c97
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h1
2 files changed, 67 insertions, 31 deletions
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 466c730e6297..f797064315c2 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -46,6 +46,10 @@ static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
46module_param(nes_lro_max_aggr, uint, 0444); 46module_param(nes_lro_max_aggr, uint, 0444);
47MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation"); 47MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
48 48
49static int wide_ppm_offset;
50module_param(wide_ppm_offset, int, 0644);
51MODULE_PARM_DESC(wide_ppm_offset, "Increase CX4 interface clock ppm offset, 0=100ppm (default), 1=300ppm");
52
49static u32 crit_err_count; 53static u32 crit_err_count;
50u32 int_mod_timer_init; 54u32 int_mod_timer_init;
51u32 int_mod_cq_depth_256; 55u32 int_mod_cq_depth_256;
@@ -546,8 +550,11 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
546 msleep(1); 550 msleep(1);
547 } 551 }
548 if (int_cnt > 1) { 552 if (int_cnt > 1) {
553 u32 sds;
549 spin_lock_irqsave(&nesadapter->phy_lock, flags); 554 spin_lock_irqsave(&nesadapter->phy_lock, flags);
550 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088); 555 sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
556 sds |= 0x00000040;
557 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
551 mh_detected++; 558 mh_detected++;
552 reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); 559 reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
553 reset_value |= 0x0000003d; 560 reset_value |= 0x0000003d;
@@ -736,43 +743,48 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
736{ 743{
737 int i; 744 int i;
738 u32 u32temp; 745 u32 u32temp;
739 u32 serdes_common_control; 746 u32 sds;
740 747
741 if (hw_rev != NE020_REV) { 748 if (hw_rev != NE020_REV) {
742 /* init serdes 0 */ 749 /* init serdes 0 */
750 if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4))
751 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA);
752 else
753 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
743 754
744 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
745 if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { 755 if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
746 serdes_common_control = nes_read_indexed(nesdev, 756 sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
747 NES_IDX_ETH_SERDES_COMMON_CONTROL0); 757 sds |= 0x00000100;
748 serdes_common_control |= 0x000000100; 758 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds);
749 nes_write_indexed(nesdev,
750 NES_IDX_ETH_SERDES_COMMON_CONTROL0,
751 serdes_common_control);
752 } else if (!OneG_Mode) {
753 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
754 } 759 }
755 if (((port_count > 1) && 760 if (!OneG_Mode)
756 (nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) || 761 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
757 ((port_count > 2) && 762
758 (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) { 763 if (port_count < 2)
759 /* init serdes 1 */ 764 return 0;
760 if (nesadapter->phy_type[0] == NES_PHY_TYPE_ARGUS) { 765
761 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000); 766 /* init serdes 1 */
762 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000); 767 switch (nesadapter->phy_type[1]) {
763 } 768 case NES_PHY_TYPE_ARGUS:
764 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); 769 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000);
765 if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { 770 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000);
766 serdes_common_control = nes_read_indexed(nesdev, 771 break;
767 NES_IDX_ETH_SERDES_COMMON_CONTROL1); 772 case NES_PHY_TYPE_CX4:
768 serdes_common_control |= 0x000000100; 773 sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
769 nes_write_indexed(nesdev, 774 sds &= 0xFFFFFFBF;
770 NES_IDX_ETH_SERDES_COMMON_CONTROL1, 775 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
771 serdes_common_control); 776 if (wide_ppm_offset)
772 } else if (!OneG_Mode) { 777 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA);
773 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); 778 else
774 } 779 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
780 break;
781 case NES_PHY_TYPE_PUMA_1G:
782 sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
783 sds |= 0x000000100;
784 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
775 } 785 }
786 if (!OneG_Mode)
787 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
776 } else { 788 } else {
777 /* init serdes 0 */ 789 /* init serdes 0 */
778 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); 790 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008);
@@ -2315,6 +2327,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2315 u16 temp_phy_data; 2327 u16 temp_phy_data;
2316 u32 pcs_val = 0x0f0f0000; 2328 u32 pcs_val = 0x0f0f0000;
2317 u32 pcs_mask = 0x0f1f0000; 2329 u32 pcs_mask = 0x0f1f0000;
2330 u32 cdr_ctrl;
2318 2331
2319 spin_lock_irqsave(&nesadapter->phy_lock, flags); 2332 spin_lock_irqsave(&nesadapter->phy_lock, flags);
2320 if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { 2333 if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
@@ -2466,6 +2479,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2466 } 2479 }
2467 2480
2468 if (phy_data & 0x0004) { 2481 if (phy_data & 0x0004) {
2482 if (wide_ppm_offset &&
2483 (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
2484 (nesadapter->hw_rev != NE020_REV)) {
2485 cdr_ctrl = nes_read_indexed(nesdev,
2486 NES_IDX_ETH_SERDES_CDR_CONTROL0 +
2487 mac_index * 0x200);
2488 nes_write_indexed(nesdev,
2489 NES_IDX_ETH_SERDES_CDR_CONTROL0 +
2490 mac_index * 0x200,
2491 cdr_ctrl | 0x000F0000);
2492 }
2469 nesadapter->mac_link_down[mac_index] = 0; 2493 nesadapter->mac_link_down[mac_index] = 0;
2470 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { 2494 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2471 nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", 2495 nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n",
@@ -2480,6 +2504,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2480 } 2504 }
2481 } 2505 }
2482 } else { 2506 } else {
2507 if (wide_ppm_offset &&
2508 (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
2509 (nesadapter->hw_rev != NE020_REV)) {
2510 cdr_ctrl = nes_read_indexed(nesdev,
2511 NES_IDX_ETH_SERDES_CDR_CONTROL0 +
2512 mac_index * 0x200);
2513 nes_write_indexed(nesdev,
2514 NES_IDX_ETH_SERDES_CDR_CONTROL0 +
2515 mac_index * 0x200,
2516 cdr_ctrl & 0xFFF0FFFF);
2517 }
2483 nesadapter->mac_link_down[mac_index] = 1; 2518 nesadapter->mac_link_down[mac_index] = 1;
2484 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { 2519 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2485 nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", 2520 nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index f41a8710d2a8..13bc26a83159 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -35,6 +35,7 @@
35 35
36#include <linux/inet_lro.h> 36#include <linux/inet_lro.h>
37 37
38#define NES_PHY_TYPE_CX4 1
38#define NES_PHY_TYPE_1G 2 39#define NES_PHY_TYPE_1G 2
39#define NES_PHY_TYPE_IRIS 3 40#define NES_PHY_TYPE_IRIS 3
40#define NES_PHY_TYPE_ARGUS 4 41#define NES_PHY_TYPE_ARGUS 4