diff options
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 355 |
1 files changed, 138 insertions, 217 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index c29e187f90c6..68de7f748a81 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -621,16 +621,8 @@ static void skge_led_on(struct skge_hw *hw, int port) | |||
621 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); | 621 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); |
622 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | 622 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); |
623 | 623 | ||
624 | switch (hw->phy_type) { | 624 | /* For Broadcom Phy only */ |
625 | case SK_PHY_BCOM: | 625 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); |
626 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, | ||
627 | PHY_B_PEC_LED_ON); | ||
628 | break; | ||
629 | default: | ||
630 | skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON); | ||
631 | skge_write32(hw, SK_REG(port, TX_LED_VAL), 100); | ||
632 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); | ||
633 | } | ||
634 | } else { | 626 | } else { |
635 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 627 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); |
636 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 628 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
@@ -651,15 +643,8 @@ static void skge_led_off(struct skge_hw *hw, int port) | |||
651 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); | 643 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); |
652 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); | 644 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); |
653 | 645 | ||
654 | switch (hw->phy_type) { | 646 | /* Broadcom only */ |
655 | case SK_PHY_BCOM: | 647 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); |
656 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, | ||
657 | PHY_B_PEC_LED_OFF); | ||
658 | break; | ||
659 | default: | ||
660 | skge_write32(hw, SK_REG(port, TX_LED_VAL), 0); | ||
661 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF); | ||
662 | } | ||
663 | } else { | 648 | } else { |
664 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 649 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); |
665 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 650 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
@@ -887,21 +872,21 @@ static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) | |||
887 | 872 | ||
888 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); | 873 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); |
889 | v = xm_read16(hw, port, XM_PHY_DATA); | 874 | v = xm_read16(hw, port, XM_PHY_DATA); |
890 | if (hw->phy_type != SK_PHY_XMAC) { | ||
891 | for (i = 0; i < PHY_RETRIES; i++) { | ||
892 | udelay(1); | ||
893 | if (xm_read16(hw, port, XM_MMU_CMD) | ||
894 | & XM_MMU_PHY_RDY) | ||
895 | goto ready; | ||
896 | } | ||
897 | 875 | ||
898 | printk(KERN_WARNING PFX "%s: phy read timed out\n", | 876 | /* Need to wait for external PHY */ |
899 | hw->dev[port]->name); | 877 | for (i = 0; i < PHY_RETRIES; i++) { |
900 | return 0; | 878 | udelay(1); |
901 | ready: | 879 | if (xm_read16(hw, port, XM_MMU_CMD) |
902 | v = xm_read16(hw, port, XM_PHY_DATA); | 880 | & XM_MMU_PHY_RDY) |
881 | goto ready; | ||
903 | } | 882 | } |
904 | 883 | ||
884 | printk(KERN_WARNING PFX "%s: phy read timed out\n", | ||
885 | hw->dev[port]->name); | ||
886 | return 0; | ||
887 | ready: | ||
888 | v = xm_read16(hw, port, XM_PHY_DATA); | ||
889 | |||
905 | return v; | 890 | return v; |
906 | } | 891 | } |
907 | 892 | ||
@@ -913,7 +898,7 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) | |||
913 | for (i = 0; i < PHY_RETRIES; i++) { | 898 | for (i = 0; i < PHY_RETRIES; i++) { |
914 | if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) | 899 | if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) |
915 | goto ready; | 900 | goto ready; |
916 | cpu_relax(); | 901 | udelay(1); |
917 | } | 902 | } |
918 | printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", | 903 | printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", |
919 | hw->dev[port]->name); | 904 | hw->dev[port]->name); |
@@ -970,9 +955,8 @@ static void genesis_reset(struct skge_hw *hw, int port) | |||
970 | xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ | 955 | xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ |
971 | xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ | 956 | xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ |
972 | 957 | ||
973 | /* disable all PHY IRQs */ | 958 | /* disable Broadcom PHY IRQ */ |
974 | if (hw->phy_type == SK_PHY_BCOM) | 959 | xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); |
975 | xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); | ||
976 | 960 | ||
977 | xm_outhash(hw, port, XM_HSM, (u8 *) &zero); | 961 | xm_outhash(hw, port, XM_HSM, (u8 *) &zero); |
978 | for (i = 0; i < 15; i++) | 962 | for (i = 0; i < 15; i++) |
@@ -1020,54 +1004,55 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1020 | * GMII mode. | 1004 | * GMII mode. |
1021 | */ | 1005 | */ |
1022 | spin_lock_bh(&hw->phy_lock); | 1006 | spin_lock_bh(&hw->phy_lock); |
1023 | if (hw->phy_type != SK_PHY_XMAC) { | ||
1024 | /* Take PHY out of reset. */ | ||
1025 | r = skge_read32(hw, B2_GP_IO); | ||
1026 | if (port == 0) | ||
1027 | r |= GP_DIR_0|GP_IO_0; | ||
1028 | else | ||
1029 | r |= GP_DIR_2|GP_IO_2; | ||
1030 | |||
1031 | skge_write32(hw, B2_GP_IO, r); | ||
1032 | skge_read32(hw, B2_GP_IO); | ||
1033 | |||
1034 | /* Enable GMII mode on the XMAC. */ | ||
1035 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | ||
1036 | |||
1037 | id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); | ||
1038 | |||
1039 | /* Optimize MDIO transfer by suppressing preamble. */ | ||
1040 | xm_write16(hw, port, XM_MMU_CMD, | ||
1041 | xm_read16(hw, port, XM_MMU_CMD) | ||
1042 | | XM_MMU_NO_PRE); | ||
1043 | |||
1044 | if (id1 == PHY_BCOM_ID1_C0) { | ||
1045 | /* | ||
1046 | * Workaround BCOM Errata for the C0 type. | ||
1047 | * Write magic patterns to reserved registers. | ||
1048 | */ | ||
1049 | for (i = 0; i < ARRAY_SIZE(C0hack); i++) | ||
1050 | xm_phy_write(hw, port, | ||
1051 | C0hack[i].reg, C0hack[i].val); | ||
1052 | |||
1053 | } else if (id1 == PHY_BCOM_ID1_A1) { | ||
1054 | /* | ||
1055 | * Workaround BCOM Errata for the A1 type. | ||
1056 | * Write magic patterns to reserved registers. | ||
1057 | */ | ||
1058 | for (i = 0; i < ARRAY_SIZE(A1hack); i++) | ||
1059 | xm_phy_write(hw, port, | ||
1060 | A1hack[i].reg, A1hack[i].val); | ||
1061 | } | ||
1062 | 1007 | ||
1008 | /* External Phy Handling */ | ||
1009 | /* Take PHY out of reset. */ | ||
1010 | r = skge_read32(hw, B2_GP_IO); | ||
1011 | if (port == 0) | ||
1012 | r |= GP_DIR_0|GP_IO_0; | ||
1013 | else | ||
1014 | r |= GP_DIR_2|GP_IO_2; | ||
1015 | |||
1016 | skge_write32(hw, B2_GP_IO, r); | ||
1017 | skge_read32(hw, B2_GP_IO); | ||
1018 | |||
1019 | /* Enable GMII mode on the XMAC. */ | ||
1020 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | ||
1021 | |||
1022 | id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); | ||
1023 | |||
1024 | /* Optimize MDIO transfer by suppressing preamble. */ | ||
1025 | xm_write16(hw, port, XM_MMU_CMD, | ||
1026 | xm_read16(hw, port, XM_MMU_CMD) | ||
1027 | | XM_MMU_NO_PRE); | ||
1028 | |||
1029 | if (id1 == PHY_BCOM_ID1_C0) { | ||
1063 | /* | 1030 | /* |
1064 | * Workaround BCOM Errata (#10523) for all BCom PHYs. | 1031 | * Workaround BCOM Errata for the C0 type. |
1065 | * Disable Power Management after reset. | 1032 | * Write magic patterns to reserved registers. |
1066 | */ | 1033 | */ |
1067 | r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); | 1034 | for (i = 0; i < ARRAY_SIZE(C0hack); i++) |
1068 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); | 1035 | xm_phy_write(hw, port, |
1036 | C0hack[i].reg, C0hack[i].val); | ||
1037 | |||
1038 | } else if (id1 == PHY_BCOM_ID1_A1) { | ||
1039 | /* | ||
1040 | * Workaround BCOM Errata for the A1 type. | ||
1041 | * Write magic patterns to reserved registers. | ||
1042 | */ | ||
1043 | for (i = 0; i < ARRAY_SIZE(A1hack); i++) | ||
1044 | xm_phy_write(hw, port, | ||
1045 | A1hack[i].reg, A1hack[i].val); | ||
1069 | } | 1046 | } |
1070 | 1047 | ||
1048 | /* | ||
1049 | * Workaround BCOM Errata (#10523) for all BCom PHYs. | ||
1050 | * Disable Power Management after reset. | ||
1051 | */ | ||
1052 | r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); | ||
1053 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); | ||
1054 | |||
1055 | |||
1071 | /* Dummy read */ | 1056 | /* Dummy read */ |
1072 | xm_read16(hw, port, XM_ISRC); | 1057 | xm_read16(hw, port, XM_ISRC); |
1073 | 1058 | ||
@@ -1098,8 +1083,8 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1098 | */ | 1083 | */ |
1099 | r = xm_read32(hw, port, XM_MODE); | 1084 | r = xm_read32(hw, port, XM_MODE); |
1100 | xm_write32(hw, port, XM_MODE, | 1085 | xm_write32(hw, port, XM_MODE, |
1101 | XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| | 1086 | XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| |
1102 | XM_MD_RX_ERR|XM_MD_RX_IRLE); | 1087 | XM_MD_RX_ERR|XM_MD_RX_IRLE); |
1103 | 1088 | ||
1104 | xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); | 1089 | xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); |
1105 | xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); | 1090 | xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); |
@@ -1150,103 +1135,70 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1150 | else | 1135 | else |
1151 | xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); | 1136 | xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); |
1152 | 1137 | ||
1153 | switch (hw->phy_type) { | 1138 | /* Broadcom phy initialization */ |
1154 | case SK_PHY_XMAC: | 1139 | ctrl1 = PHY_CT_SP1000; |
1155 | if (skge->autoneg == AUTONEG_ENABLE) { | 1140 | ctrl2 = 0; |
1156 | ctrl1 = PHY_X_AN_FD | PHY_X_AN_HD; | 1141 | ctrl3 = PHY_AN_CSMA; |
1142 | ctrl4 = PHY_B_PEC_EN_LTR; | ||
1143 | ctrl5 = PHY_B_AC_TX_TST; | ||
1157 | 1144 | ||
1158 | switch (skge->flow_control) { | 1145 | if (skge->autoneg == AUTONEG_ENABLE) { |
1159 | case FLOW_MODE_NONE: | 1146 | /* |
1160 | ctrl1 |= PHY_X_P_NO_PAUSE; | 1147 | * Workaround BCOM Errata #1 for the C5 type. |
1161 | break; | 1148 | * 1000Base-T Link Acquisition Failure in Slave Mode |
1162 | case FLOW_MODE_LOC_SEND: | 1149 | * Set Repeater/DTE bit 10 of the 1000Base-T Control Register |
1163 | ctrl1 |= PHY_X_P_ASYM_MD; | 1150 | */ |
1164 | break; | 1151 | ctrl2 |= PHY_B_1000C_RD; |
1165 | case FLOW_MODE_SYMMETRIC: | 1152 | if (skge->advertising & ADVERTISED_1000baseT_Half) |
1166 | ctrl1 |= PHY_X_P_SYM_MD; | 1153 | ctrl2 |= PHY_B_1000C_AHD; |
1167 | break; | 1154 | if (skge->advertising & ADVERTISED_1000baseT_Full) |
1168 | case FLOW_MODE_REM_SEND: | 1155 | ctrl2 |= PHY_B_1000C_AFD; |
1169 | ctrl1 |= PHY_X_P_BOTH_MD; | 1156 | |
1170 | break; | 1157 | /* Set Flow-control capabilities */ |
1171 | } | 1158 | switch (skge->flow_control) { |
1172 | 1159 | case FLOW_MODE_NONE: | |
1173 | xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1); | 1160 | ctrl3 |= PHY_B_P_NO_PAUSE; |
1174 | ctrl2 = PHY_CT_ANE | PHY_CT_RE_CFG; | 1161 | break; |
1175 | } else { | 1162 | case FLOW_MODE_LOC_SEND: |
1176 | ctrl2 = 0; | 1163 | ctrl3 |= PHY_B_P_ASYM_MD; |
1177 | if (skge->duplex == DUPLEX_FULL) | 1164 | break; |
1178 | ctrl2 |= PHY_CT_DUP_MD; | 1165 | case FLOW_MODE_SYMMETRIC: |
1166 | ctrl3 |= PHY_B_P_SYM_MD; | ||
1167 | break; | ||
1168 | case FLOW_MODE_REM_SEND: | ||
1169 | ctrl3 |= PHY_B_P_BOTH_MD; | ||
1170 | break; | ||
1179 | } | 1171 | } |
1180 | 1172 | ||
1181 | xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2); | 1173 | /* Restart Auto-negotiation */ |
1182 | break; | 1174 | ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; |
1183 | 1175 | } else { | |
1184 | case SK_PHY_BCOM: | 1176 | if (skge->duplex == DUPLEX_FULL) |
1185 | ctrl1 = PHY_CT_SP1000; | 1177 | ctrl1 |= PHY_CT_DUP_MD; |
1186 | ctrl2 = 0; | ||
1187 | ctrl3 = PHY_AN_CSMA; | ||
1188 | ctrl4 = PHY_B_PEC_EN_LTR; | ||
1189 | ctrl5 = PHY_B_AC_TX_TST; | ||
1190 | |||
1191 | if (skge->autoneg == AUTONEG_ENABLE) { | ||
1192 | /* | ||
1193 | * Workaround BCOM Errata #1 for the C5 type. | ||
1194 | * 1000Base-T Link Acquisition Failure in Slave Mode | ||
1195 | * Set Repeater/DTE bit 10 of the 1000Base-T Control Register | ||
1196 | */ | ||
1197 | ctrl2 |= PHY_B_1000C_RD; | ||
1198 | if (skge->advertising & ADVERTISED_1000baseT_Half) | ||
1199 | ctrl2 |= PHY_B_1000C_AHD; | ||
1200 | if (skge->advertising & ADVERTISED_1000baseT_Full) | ||
1201 | ctrl2 |= PHY_B_1000C_AFD; | ||
1202 | |||
1203 | /* Set Flow-control capabilities */ | ||
1204 | switch (skge->flow_control) { | ||
1205 | case FLOW_MODE_NONE: | ||
1206 | ctrl3 |= PHY_B_P_NO_PAUSE; | ||
1207 | break; | ||
1208 | case FLOW_MODE_LOC_SEND: | ||
1209 | ctrl3 |= PHY_B_P_ASYM_MD; | ||
1210 | break; | ||
1211 | case FLOW_MODE_SYMMETRIC: | ||
1212 | ctrl3 |= PHY_B_P_SYM_MD; | ||
1213 | break; | ||
1214 | case FLOW_MODE_REM_SEND: | ||
1215 | ctrl3 |= PHY_B_P_BOTH_MD; | ||
1216 | break; | ||
1217 | } | ||
1218 | |||
1219 | /* Restart Auto-negotiation */ | ||
1220 | ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; | ||
1221 | } else { | ||
1222 | if (skge->duplex == DUPLEX_FULL) | ||
1223 | ctrl1 |= PHY_CT_DUP_MD; | ||
1224 | |||
1225 | ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ | ||
1226 | } | ||
1227 | 1178 | ||
1228 | xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); | 1179 | ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ |
1229 | xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); | 1180 | } |
1230 | 1181 | ||
1231 | if (skge->netdev->mtu > ETH_DATA_LEN) { | 1182 | xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); |
1232 | ctrl4 |= PHY_B_PEC_HIGH_LA; | 1183 | xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); |
1233 | ctrl5 |= PHY_B_AC_LONG_PACK; | ||
1234 | 1184 | ||
1235 | xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); | 1185 | if (skge->netdev->mtu > ETH_DATA_LEN) { |
1236 | } | 1186 | ctrl4 |= PHY_B_PEC_HIGH_LA; |
1187 | ctrl5 |= PHY_B_AC_LONG_PACK; | ||
1237 | 1188 | ||
1238 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); | 1189 | xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); |
1239 | xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); | ||
1240 | break; | ||
1241 | } | 1190 | } |
1191 | |||
1192 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); | ||
1193 | xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); | ||
1242 | spin_unlock_bh(&hw->phy_lock); | 1194 | spin_unlock_bh(&hw->phy_lock); |
1243 | 1195 | ||
1244 | /* Clear MIB counters */ | 1196 | /* Clear MIB counters */ |
1245 | xm_write16(hw, port, XM_STAT_CMD, | 1197 | xm_write16(hw, port, XM_STAT_CMD, |
1246 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | 1198 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); |
1247 | /* Clear two times according to Errata #3 */ | 1199 | /* Clear two times according to Errata #3 */ |
1248 | xm_write16(hw, port, XM_STAT_CMD, | 1200 | xm_write16(hw, port, XM_STAT_CMD, |
1249 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | 1201 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); |
1250 | 1202 | ||
1251 | /* Start polling for link status */ | 1203 | /* Start polling for link status */ |
1252 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | 1204 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); |
@@ -1256,6 +1208,7 @@ static void genesis_stop(struct skge_port *skge) | |||
1256 | { | 1208 | { |
1257 | struct skge_hw *hw = skge->hw; | 1209 | struct skge_hw *hw = skge->hw; |
1258 | int port = skge->port; | 1210 | int port = skge->port; |
1211 | u32 reg; | ||
1259 | 1212 | ||
1260 | /* Clear Tx packet arbiter timeout IRQ */ | 1213 | /* Clear Tx packet arbiter timeout IRQ */ |
1261 | skge_write16(hw, B3_PA_CTRL, | 1214 | skge_write16(hw, B3_PA_CTRL, |
@@ -1273,19 +1226,16 @@ static void genesis_stop(struct skge_port *skge) | |||
1273 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); | 1226 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); |
1274 | 1227 | ||
1275 | /* For external PHYs there must be special handling */ | 1228 | /* For external PHYs there must be special handling */ |
1276 | if (hw->phy_type != SK_PHY_XMAC) { | 1229 | reg = skge_read32(hw, B2_GP_IO); |
1277 | u32 reg = skge_read32(hw, B2_GP_IO); | 1230 | if (port == 0) { |
1278 | 1231 | reg |= GP_DIR_0; | |
1279 | if (port == 0) { | 1232 | reg &= ~GP_IO_0; |
1280 | reg |= GP_DIR_0; | 1233 | } else { |
1281 | reg &= ~GP_IO_0; | 1234 | reg |= GP_DIR_2; |
1282 | } else { | 1235 | reg &= ~GP_IO_2; |
1283 | reg |= GP_DIR_2; | ||
1284 | reg &= ~GP_IO_2; | ||
1285 | } | ||
1286 | skge_write32(hw, B2_GP_IO, reg); | ||
1287 | skge_read32(hw, B2_GP_IO); | ||
1288 | } | 1236 | } |
1237 | skge_write32(hw, B2_GP_IO, reg); | ||
1238 | skge_read32(hw, B2_GP_IO); | ||
1289 | 1239 | ||
1290 | xm_write16(hw, port, XM_MMU_CMD, | 1240 | xm_write16(hw, port, XM_MMU_CMD, |
1291 | xm_read16(hw, port, XM_MMU_CMD) | 1241 | xm_read16(hw, port, XM_MMU_CMD) |
@@ -1329,16 +1279,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) | |||
1329 | u16 status = xm_read16(hw, port, XM_ISRC); | 1279 | u16 status = xm_read16(hw, port, XM_ISRC); |
1330 | 1280 | ||
1331 | pr_debug("genesis_intr status %x\n", status); | 1281 | pr_debug("genesis_intr status %x\n", status); |
1332 | if (hw->phy_type == SK_PHY_XMAC) { | ||
1333 | /* LInk down, start polling for state change */ | ||
1334 | if (status & XM_IS_INP_ASS) { | ||
1335 | xm_write16(hw, port, XM_IMSK, | ||
1336 | xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS); | ||
1337 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1338 | } | ||
1339 | else if (status & XM_IS_AND) | ||
1340 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1341 | } | ||
1342 | 1282 | ||
1343 | if (status & XM_IS_TXF_UR) { | 1283 | if (status & XM_IS_TXF_UR) { |
1344 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); | 1284 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); |
@@ -1458,28 +1398,25 @@ static void genesis_link_up(struct skge_port *skge) | |||
1458 | xm_write32(hw, port, XM_MODE, mode); | 1398 | xm_write32(hw, port, XM_MODE, mode); |
1459 | 1399 | ||
1460 | msk = XM_DEF_MSK; | 1400 | msk = XM_DEF_MSK; |
1461 | if (hw->phy_type != SK_PHY_XMAC) | 1401 | /* disable GP0 interrupt bit for external Phy */ |
1462 | msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ | 1402 | msk |= XM_IS_INP_ASS; |
1463 | 1403 | ||
1464 | xm_write16(hw, port, XM_IMSK, msk); | 1404 | xm_write16(hw, port, XM_IMSK, msk); |
1465 | xm_read16(hw, port, XM_ISRC); | 1405 | xm_read16(hw, port, XM_ISRC); |
1466 | 1406 | ||
1467 | /* get MMU Command Reg. */ | 1407 | /* get MMU Command Reg. */ |
1468 | cmd = xm_read16(hw, port, XM_MMU_CMD); | 1408 | cmd = xm_read16(hw, port, XM_MMU_CMD); |
1469 | if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL) | 1409 | if (skge->duplex == DUPLEX_FULL) |
1470 | cmd |= XM_MMU_GMII_FD; | 1410 | cmd |= XM_MMU_GMII_FD; |
1471 | 1411 | ||
1472 | if (hw->phy_type == SK_PHY_BCOM) { | 1412 | /* |
1473 | /* | 1413 | * Workaround BCOM Errata (#10523) for all BCom Phys |
1474 | * Workaround BCOM Errata (#10523) for all BCom Phys | 1414 | * Enable Power Management after link up |
1475 | * Enable Power Management after link up | 1415 | */ |
1476 | */ | 1416 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, |
1477 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, | 1417 | xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) |
1478 | xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) | 1418 | & ~PHY_B_AC_DIS_PM); |
1479 | & ~PHY_B_AC_DIS_PM); | 1419 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); |
1480 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, | ||
1481 | PHY_B_DEF_MSK); | ||
1482 | } | ||
1483 | 1420 | ||
1484 | /* enable Rx/Tx */ | 1421 | /* enable Rx/Tx */ |
1485 | xm_write16(hw, port, XM_MMU_CMD, | 1422 | xm_write16(hw, port, XM_MMU_CMD, |
@@ -1551,25 +1488,12 @@ static void skge_link_timer(unsigned long __arg) | |||
1551 | { | 1488 | { |
1552 | struct skge_port *skge = (struct skge_port *) __arg; | 1489 | struct skge_port *skge = (struct skge_port *) __arg; |
1553 | struct skge_hw *hw = skge->hw; | 1490 | struct skge_hw *hw = skge->hw; |
1554 | int port = skge->port; | ||
1555 | 1491 | ||
1556 | if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev)) | 1492 | if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev)) |
1557 | return; | 1493 | return; |
1558 | 1494 | ||
1559 | spin_lock_bh(&hw->phy_lock); | 1495 | spin_lock_bh(&hw->phy_lock); |
1560 | if (hw->phy_type == SK_PHY_BCOM) | 1496 | genesis_bcom_intr(skge); |
1561 | genesis_bcom_intr(skge); | ||
1562 | else { | ||
1563 | int i; | ||
1564 | for (i = 0; i < 3; i++) | ||
1565 | if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) | ||
1566 | break; | ||
1567 | |||
1568 | if (i == 3) | ||
1569 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1570 | else | ||
1571 | genesis_link_up(skge); | ||
1572 | } | ||
1573 | spin_unlock_bh(&hw->phy_lock); | 1497 | spin_unlock_bh(&hw->phy_lock); |
1574 | } | 1498 | } |
1575 | 1499 | ||
@@ -2737,7 +2661,7 @@ static void skge_extirq(unsigned long data) | |||
2737 | 2661 | ||
2738 | if (hw->chip_id != CHIP_ID_GENESIS) | 2662 | if (hw->chip_id != CHIP_ID_GENESIS) |
2739 | yukon_phy_intr(skge); | 2663 | yukon_phy_intr(skge); |
2740 | else if (hw->phy_type == SK_PHY_BCOM) | 2664 | else |
2741 | genesis_bcom_intr(skge); | 2665 | genesis_bcom_intr(skge); |
2742 | } | 2666 | } |
2743 | } | 2667 | } |
@@ -2886,9 +2810,6 @@ static int skge_reset(struct skge_hw *hw) | |||
2886 | switch (hw->chip_id) { | 2810 | switch (hw->chip_id) { |
2887 | case CHIP_ID_GENESIS: | 2811 | case CHIP_ID_GENESIS: |
2888 | switch (hw->phy_type) { | 2812 | switch (hw->phy_type) { |
2889 | case SK_PHY_XMAC: | ||
2890 | hw->phy_addr = PHY_ADDR_XMAC; | ||
2891 | break; | ||
2892 | case SK_PHY_BCOM: | 2813 | case SK_PHY_BCOM: |
2893 | hw->phy_addr = PHY_ADDR_BCOM; | 2814 | hw->phy_addr = PHY_ADDR_BCOM; |
2894 | break; | 2815 | break; |