diff options
Diffstat (limited to 'drivers/net/e1000e/ethtool.c')
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 123 |
1 files changed, 63 insertions, 60 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 4ae00567bba6..6d1b257bbda6 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -641,10 +641,17 @@ static int e1000_set_ringparam(struct net_device *netdev, | |||
641 | tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | 641 | tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); |
642 | if (!tx_ring) | 642 | if (!tx_ring) |
643 | goto err_alloc_tx; | 643 | goto err_alloc_tx; |
644 | /* | ||
645 | * use a memcpy to save any previously configured | ||
646 | * items like napi structs from having to be | ||
647 | * reinitialized | ||
648 | */ | ||
649 | memcpy(tx_ring, tx_old, sizeof(struct e1000_ring)); | ||
644 | 650 | ||
645 | rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | 651 | rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); |
646 | if (!rx_ring) | 652 | if (!rx_ring) |
647 | goto err_alloc_rx; | 653 | goto err_alloc_rx; |
654 | memcpy(rx_ring, rx_old, sizeof(struct e1000_ring)); | ||
648 | 655 | ||
649 | adapter->tx_ring = tx_ring; | 656 | adapter->tx_ring = tx_ring; |
650 | adapter->rx_ring = rx_ring; | 657 | adapter->rx_ring = rx_ring; |
@@ -700,61 +707,55 @@ err_setup: | |||
700 | return err; | 707 | return err; |
701 | } | 708 | } |
702 | 709 | ||
703 | static bool reg_pattern_test_array(struct e1000_adapter *adapter, u64 *data, | 710 | static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, |
704 | int reg, int offset, u32 mask, u32 write) | 711 | int reg, int offset, u32 mask, u32 write) |
705 | { | 712 | { |
706 | int i; | 713 | u32 pat, val; |
707 | u32 read; | ||
708 | static const u32 test[] = | 714 | static const u32 test[] = |
709 | {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; | 715 | {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; |
710 | for (i = 0; i < ARRAY_SIZE(test); i++) { | 716 | for (pat = 0; pat < ARRAY_SIZE(test); pat++) { |
711 | E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, | 717 | E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, |
712 | (test[i] & write)); | 718 | (test[pat] & write)); |
713 | read = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset); | 719 | val = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset); |
714 | if (read != (test[i] & write & mask)) { | 720 | if (val != (test[pat] & write & mask)) { |
715 | ndev_err(adapter->netdev, "pattern test reg %04X " | 721 | ndev_err(adapter->netdev, "pattern test reg %04X " |
716 | "failed: got 0x%08X expected 0x%08X\n", | 722 | "failed: got 0x%08X expected 0x%08X\n", |
717 | reg + offset, | 723 | reg + offset, |
718 | read, (test[i] & write & mask)); | 724 | val, (test[pat] & write & mask)); |
719 | *data = reg; | 725 | *data = reg; |
720 | return true; | 726 | return 1; |
721 | } | 727 | } |
722 | } | 728 | } |
723 | return false; | 729 | return 0; |
724 | } | 730 | } |
725 | 731 | ||
726 | static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, | 732 | static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, |
727 | int reg, u32 mask, u32 write) | 733 | int reg, u32 mask, u32 write) |
728 | { | 734 | { |
729 | u32 read; | 735 | u32 val; |
730 | __ew32(&adapter->hw, reg, write & mask); | 736 | __ew32(&adapter->hw, reg, write & mask); |
731 | read = __er32(&adapter->hw, reg); | 737 | val = __er32(&adapter->hw, reg); |
732 | if ((write & mask) != (read & mask)) { | 738 | if ((write & mask) != (val & mask)) { |
733 | ndev_err(adapter->netdev, "set/check reg %04X test failed: " | 739 | ndev_err(adapter->netdev, "set/check reg %04X test failed: " |
734 | "got 0x%08X expected 0x%08X\n", reg, (read & mask), | 740 | "got 0x%08X expected 0x%08X\n", reg, (val & mask), |
735 | (write & mask)); | 741 | (write & mask)); |
736 | *data = reg; | 742 | *data = reg; |
737 | return true; | 743 | return 1; |
738 | } | 744 | } |
739 | return false; | 745 | return 0; |
740 | } | 746 | } |
741 | 747 | #define REG_PATTERN_TEST_ARRAY(reg, offset, mask, write) \ | |
742 | #define REG_PATTERN_TEST(R, M, W) \ | 748 | do { \ |
743 | do { \ | 749 | if (reg_pattern_test(adapter, data, reg, offset, mask, write)) \ |
744 | if (reg_pattern_test_array(adapter, data, R, 0, M, W)) \ | 750 | return 1; \ |
745 | return 1; \ | ||
746 | } while (0) | 751 | } while (0) |
752 | #define REG_PATTERN_TEST(reg, mask, write) \ | ||
753 | REG_PATTERN_TEST_ARRAY(reg, 0, mask, write) | ||
747 | 754 | ||
748 | #define REG_PATTERN_TEST_ARRAY(R, offset, M, W) \ | 755 | #define REG_SET_AND_CHECK(reg, mask, write) \ |
749 | do { \ | 756 | do { \ |
750 | if (reg_pattern_test_array(adapter, data, R, offset, M, W)) \ | 757 | if (reg_set_and_check(adapter, data, reg, mask, write)) \ |
751 | return 1; \ | 758 | return 1; \ |
752 | } while (0) | ||
753 | |||
754 | #define REG_SET_AND_CHECK(R, M, W) \ | ||
755 | do { \ | ||
756 | if (reg_set_and_check(adapter, data, R, M, W)) \ | ||
757 | return 1; \ | ||
758 | } while (0) | 759 | } while (0) |
759 | 760 | ||
760 | static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) | 761 | static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) |
@@ -1038,7 +1039,6 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1038 | struct pci_dev *pdev = adapter->pdev; | 1039 | struct pci_dev *pdev = adapter->pdev; |
1039 | struct e1000_hw *hw = &adapter->hw; | 1040 | struct e1000_hw *hw = &adapter->hw; |
1040 | u32 rctl; | 1041 | u32 rctl; |
1041 | int size; | ||
1042 | int i; | 1042 | int i; |
1043 | int ret_val; | 1043 | int ret_val; |
1044 | 1044 | ||
@@ -1047,13 +1047,13 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1047 | if (!tx_ring->count) | 1047 | if (!tx_ring->count) |
1048 | tx_ring->count = E1000_DEFAULT_TXD; | 1048 | tx_ring->count = E1000_DEFAULT_TXD; |
1049 | 1049 | ||
1050 | size = tx_ring->count * sizeof(struct e1000_buffer); | 1050 | tx_ring->buffer_info = kcalloc(tx_ring->count, |
1051 | tx_ring->buffer_info = kmalloc(size, GFP_KERNEL); | 1051 | sizeof(struct e1000_buffer), |
1052 | if (!tx_ring->buffer_info) { | 1052 | GFP_KERNEL); |
1053 | if (!(tx_ring->buffer_info)) { | ||
1053 | ret_val = 1; | 1054 | ret_val = 1; |
1054 | goto err_nomem; | 1055 | goto err_nomem; |
1055 | } | 1056 | } |
1056 | memset(tx_ring->buffer_info, 0, size); | ||
1057 | 1057 | ||
1058 | tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); | 1058 | tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); |
1059 | tx_ring->size = ALIGN(tx_ring->size, 4096); | 1059 | tx_ring->size = ALIGN(tx_ring->size, 4096); |
@@ -1063,21 +1063,17 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1063 | ret_val = 2; | 1063 | ret_val = 2; |
1064 | goto err_nomem; | 1064 | goto err_nomem; |
1065 | } | 1065 | } |
1066 | memset(tx_ring->desc, 0, tx_ring->size); | ||
1067 | tx_ring->next_to_use = 0; | 1066 | tx_ring->next_to_use = 0; |
1068 | tx_ring->next_to_clean = 0; | 1067 | tx_ring->next_to_clean = 0; |
1069 | 1068 | ||
1070 | ew32(TDBAL, | 1069 | ew32(TDBAL, ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); |
1071 | ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); | ||
1072 | ew32(TDBAH, ((u64) tx_ring->dma >> 32)); | 1070 | ew32(TDBAH, ((u64) tx_ring->dma >> 32)); |
1073 | ew32(TDLEN, | 1071 | ew32(TDLEN, tx_ring->count * sizeof(struct e1000_tx_desc)); |
1074 | tx_ring->count * sizeof(struct e1000_tx_desc)); | ||
1075 | ew32(TDH, 0); | 1072 | ew32(TDH, 0); |
1076 | ew32(TDT, 0); | 1073 | ew32(TDT, 0); |
1077 | ew32(TCTL, | 1074 | ew32(TCTL, E1000_TCTL_PSP | E1000_TCTL_EN | E1000_TCTL_MULR | |
1078 | E1000_TCTL_PSP | E1000_TCTL_EN | | 1075 | E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT | |
1079 | E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT | | 1076 | E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT); |
1080 | E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT); | ||
1081 | 1077 | ||
1082 | for (i = 0; i < tx_ring->count; i++) { | 1078 | for (i = 0; i < tx_ring->count; i++) { |
1083 | struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); | 1079 | struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); |
@@ -1099,12 +1095,11 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1099 | ret_val = 4; | 1095 | ret_val = 4; |
1100 | goto err_nomem; | 1096 | goto err_nomem; |
1101 | } | 1097 | } |
1102 | tx_desc->buffer_addr = cpu_to_le64( | 1098 | tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); |
1103 | tx_ring->buffer_info[i].dma); | ||
1104 | tx_desc->lower.data = cpu_to_le32(skb->len); | 1099 | tx_desc->lower.data = cpu_to_le32(skb->len); |
1105 | tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | | 1100 | tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | |
1106 | E1000_TXD_CMD_IFCS | | 1101 | E1000_TXD_CMD_IFCS | |
1107 | E1000_TXD_CMD_RPS); | 1102 | E1000_TXD_CMD_RS); |
1108 | tx_desc->upper.data = 0; | 1103 | tx_desc->upper.data = 0; |
1109 | } | 1104 | } |
1110 | 1105 | ||
@@ -1113,13 +1108,13 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1113 | if (!rx_ring->count) | 1108 | if (!rx_ring->count) |
1114 | rx_ring->count = E1000_DEFAULT_RXD; | 1109 | rx_ring->count = E1000_DEFAULT_RXD; |
1115 | 1110 | ||
1116 | size = rx_ring->count * sizeof(struct e1000_buffer); | 1111 | rx_ring->buffer_info = kcalloc(rx_ring->count, |
1117 | rx_ring->buffer_info = kmalloc(size, GFP_KERNEL); | 1112 | sizeof(struct e1000_buffer), |
1118 | if (!rx_ring->buffer_info) { | 1113 | GFP_KERNEL); |
1114 | if (!(rx_ring->buffer_info)) { | ||
1119 | ret_val = 5; | 1115 | ret_val = 5; |
1120 | goto err_nomem; | 1116 | goto err_nomem; |
1121 | } | 1117 | } |
1122 | memset(rx_ring->buffer_info, 0, size); | ||
1123 | 1118 | ||
1124 | rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc); | 1119 | rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc); |
1125 | rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, | 1120 | rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, |
@@ -1128,7 +1123,6 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1128 | ret_val = 6; | 1123 | ret_val = 6; |
1129 | goto err_nomem; | 1124 | goto err_nomem; |
1130 | } | 1125 | } |
1131 | memset(rx_ring->desc, 0, rx_ring->size); | ||
1132 | rx_ring->next_to_use = 0; | 1126 | rx_ring->next_to_use = 0; |
1133 | rx_ring->next_to_clean = 0; | 1127 | rx_ring->next_to_clean = 0; |
1134 | 1128 | ||
@@ -1140,6 +1134,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1140 | ew32(RDH, 0); | 1134 | ew32(RDH, 0); |
1141 | ew32(RDT, 0); | 1135 | ew32(RDT, 0); |
1142 | rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | | 1136 | rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | |
1137 | E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_LPE | | ||
1138 | E1000_RCTL_SBP | E1000_RCTL_SECRC | | ||
1143 | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | | 1139 | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | |
1144 | (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); | 1140 | (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); |
1145 | ew32(RCTL, rctl); | 1141 | ew32(RCTL, rctl); |
@@ -1203,7 +1199,8 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1203 | 1199 | ||
1204 | ctrl_reg = er32(CTRL); | 1200 | ctrl_reg = er32(CTRL); |
1205 | 1201 | ||
1206 | if (hw->phy.type == e1000_phy_ife) { | 1202 | switch (hw->phy.type) { |
1203 | case e1000_phy_ife: | ||
1207 | /* force 100, set loopback */ | 1204 | /* force 100, set loopback */ |
1208 | e1e_wphy(hw, PHY_CONTROL, 0x6100); | 1205 | e1e_wphy(hw, PHY_CONTROL, 0x6100); |
1209 | 1206 | ||
@@ -1213,9 +1210,11 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1213 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ | 1210 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ |
1214 | E1000_CTRL_SPD_100 |/* Force Speed to 100 */ | 1211 | E1000_CTRL_SPD_100 |/* Force Speed to 100 */ |
1215 | E1000_CTRL_FD); /* Force Duplex to FULL */ | 1212 | E1000_CTRL_FD); /* Force Duplex to FULL */ |
1216 | } else { | 1213 | break; |
1214 | default: | ||
1217 | /* force 1000, set loopback */ | 1215 | /* force 1000, set loopback */ |
1218 | e1e_wphy(hw, PHY_CONTROL, 0x4140); | 1216 | e1e_wphy(hw, PHY_CONTROL, 0x4140); |
1217 | mdelay(250); | ||
1219 | 1218 | ||
1220 | /* Now set up the MAC to the same speed/duplex as the PHY. */ | 1219 | /* Now set up the MAC to the same speed/duplex as the PHY. */ |
1221 | ctrl_reg = er32(CTRL); | 1220 | ctrl_reg = er32(CTRL); |
@@ -1224,6 +1223,10 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1224 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ | 1223 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ |
1225 | E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ | 1224 | E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ |
1226 | E1000_CTRL_FD); /* Force Duplex to FULL */ | 1225 | E1000_CTRL_FD); /* Force Duplex to FULL */ |
1226 | |||
1227 | if ((adapter->hw.mac.type == e1000_ich8lan) || | ||
1228 | (adapter->hw.mac.type == e1000_ich9lan)) | ||
1229 | ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ | ||
1227 | } | 1230 | } |
1228 | 1231 | ||
1229 | if (hw->phy.media_type == e1000_media_type_copper && | 1232 | if (hw->phy.media_type == e1000_media_type_copper && |
@@ -1325,7 +1328,7 @@ static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter) | |||
1325 | #define KMRNCTRLSTA_OPMODE (0x1F << 16) | 1328 | #define KMRNCTRLSTA_OPMODE (0x1F << 16) |
1326 | #define KMRNCTRLSTA_OPMODE_1GB_FD_GMII 0x0582 | 1329 | #define KMRNCTRLSTA_OPMODE_1GB_FD_GMII 0x0582 |
1327 | ew32(KMRNCTRLSTA, | 1330 | ew32(KMRNCTRLSTA, |
1328 | (KMRNCTRLSTA_OPMODE | KMRNCTRLSTA_OPMODE_1GB_FD_GMII)); | 1331 | (KMRNCTRLSTA_OPMODE | KMRNCTRLSTA_OPMODE_1GB_FD_GMII)); |
1329 | 1332 | ||
1330 | return 0; | 1333 | return 0; |
1331 | } | 1334 | } |
@@ -1451,8 +1454,8 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) | |||
1451 | l = 0; | 1454 | l = 0; |
1452 | for (j = 0; j <= lc; j++) { /* loop count loop */ | 1455 | for (j = 0; j <= lc; j++) { /* loop count loop */ |
1453 | for (i = 0; i < 64; i++) { /* send the packets */ | 1456 | for (i = 0; i < 64; i++) { /* send the packets */ |
1454 | e1000_create_lbtest_frame( | 1457 | e1000_create_lbtest_frame(tx_ring->buffer_info[k].skb, |
1455 | tx_ring->buffer_info[i].skb, 1024); | 1458 | 1024); |
1456 | pci_dma_sync_single_for_device(pdev, | 1459 | pci_dma_sync_single_for_device(pdev, |
1457 | tx_ring->buffer_info[k].dma, | 1460 | tx_ring->buffer_info[k].dma, |
1458 | tx_ring->buffer_info[k].length, | 1461 | tx_ring->buffer_info[k].length, |
@@ -1487,7 +1490,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) | |||
1487 | ret_val = 13; /* ret_val is the same as mis-compare */ | 1490 | ret_val = 13; /* ret_val is the same as mis-compare */ |
1488 | break; | 1491 | break; |
1489 | } | 1492 | } |
1490 | if (jiffies >= (time + 2)) { | 1493 | if (jiffies >= (time + 20)) { |
1491 | ret_val = 14; /* error code for time out error */ | 1494 | ret_val = 14; /* error code for time out error */ |
1492 | break; | 1495 | break; |
1493 | } | 1496 | } |