aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2005-06-27 14:33:12 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-06-27 18:05:06 -0400
commit45bada65c2a0bcc00729646071e66042ced64998 (patch)
tree91cc168686042f41149ea782ae91e8f8276b4402
parent31b619c5abaa5512e7b41f190f9b7903b902f29a (diff)
[PATCH] skge: make Genesis/Broadcom code work
Rewrite the code for handling the Broadcom PHY to something that works. Remove link polling because Broadcom and Yukon don't need it. When I wrote initial code, didn't have a genesis chipset based board to test, so it was a non-working guess. Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
-rw-r--r--drivers/net/skge.c516
-rw-r--r--drivers/net/skge.h15
2 files changed, 274 insertions, 257 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 81b8fe9581c7..f11e0e1a3d0e 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -54,7 +54,6 @@
54#define TX_WATCHDOG (5 * HZ) 54#define TX_WATCHDOG (5 * HZ)
55#define NAPI_WEIGHT 64 55#define NAPI_WEIGHT 64
56#define BLINK_HZ (HZ/4) 56#define BLINK_HZ (HZ/4)
57#define LINK_POLL_HZ (HZ/10)
58 57
59MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); 58MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
60MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); 59MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
@@ -96,6 +95,7 @@ static void yukon_init(struct skge_hw *hw, int port);
96static void yukon_reset(struct skge_hw *hw, int port); 95static void yukon_reset(struct skge_hw *hw, int port);
97static void genesis_mac_init(struct skge_hw *hw, int port); 96static void genesis_mac_init(struct skge_hw *hw, int port);
98static void genesis_reset(struct skge_hw *hw, int port); 97static void genesis_reset(struct skge_hw *hw, int port);
98static void genesis_link_up(struct skge_port *skge);
99 99
100static const int txqaddr[] = { Q_XA1, Q_XA2 }; 100static const int txqaddr[] = { Q_XA1, Q_XA2 };
101static const int rxqaddr[] = { Q_R1, Q_R2 }; 101static const int rxqaddr[] = { Q_R1, Q_R2 };
@@ -950,8 +950,7 @@ static void genesis_init(struct skge_hw *hw)
950 950
951static void genesis_reset(struct skge_hw *hw, int port) 951static void genesis_reset(struct skge_hw *hw, int port)
952{ 952{
953 int i; 953 const u8 zero[8] = { 0 };
954 u64 zero = 0;
955 954
956 /* reset the statistics module */ 955 /* reset the statistics module */
957 xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); 956 xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
@@ -963,20 +962,100 @@ static void genesis_reset(struct skge_hw *hw, int port)
963 /* disable Broadcom PHY IRQ */ 962 /* disable Broadcom PHY IRQ */
964 xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); 963 xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
965 964
966 xm_outhash(hw, port, XM_HSM, (u8 *) &zero); 965 xm_outhash(hw, port, XM_HSM, zero);
967 for (i = 0; i < 15; i++)
968 xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero);
969 xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero);
970} 966}
971 967
972 968
973static void genesis_mac_init(struct skge_hw *hw, int port) 969/* Convert mode to MII values */
970static const u16 phy_pause_map[] = {
971 [FLOW_MODE_NONE] = 0,
972 [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM,
973 [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP,
974 [FLOW_MODE_REM_SEND] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
975};
976
977
978/* Check status of Broadcom phy link */
979static void bcom_check_link(struct skge_hw *hw, int port)
974{ 980{
975 struct skge_port *skge = netdev_priv(hw->dev[port]); 981 struct net_device *dev = hw->dev[port];
982 struct skge_port *skge = netdev_priv(dev);
983 u16 status;
984
985 /* read twice because of latch */
986 (void) xm_phy_read(hw, port, PHY_BCOM_STAT);
987 status = xm_phy_read(hw, port, PHY_BCOM_STAT);
988
989 pr_debug("bcom_check_link status=0x%x\n", status);
990
991 if ((status & PHY_ST_LSYNC) == 0) {
992 u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
993 cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
994 xm_write16(hw, port, XM_MMU_CMD, cmd);
995 /* dummy read to ensure writing */
996 (void) xm_read16(hw, port, XM_MMU_CMD);
997
998 if (netif_carrier_ok(dev))
999 skge_link_down(skge);
1000 } else {
1001 if (skge->autoneg == AUTONEG_ENABLE &&
1002 (status & PHY_ST_AN_OVER)) {
1003 u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP);
1004 u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
1005
1006 if (lpa & PHY_B_AN_RF) {
1007 printk(KERN_NOTICE PFX "%s: remote fault\n",
1008 dev->name);
1009 return;
1010 }
1011
1012 /* Check Duplex mismatch */
1013 switch(aux & PHY_B_AS_AN_RES_MSK) {
1014 case PHY_B_RES_1000FD:
1015 skge->duplex = DUPLEX_FULL;
1016 break;
1017 case PHY_B_RES_1000HD:
1018 skge->duplex = DUPLEX_HALF;
1019 break;
1020 default:
1021 printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
1022 dev->name);
1023 return;
1024 }
1025
1026
1027 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
1028 switch (aux & PHY_B_AS_PAUSE_MSK) {
1029 case PHY_B_AS_PAUSE_MSK:
1030 skge->flow_control = FLOW_MODE_SYMMETRIC;
1031 break;
1032 case PHY_B_AS_PRR:
1033 skge->flow_control = FLOW_MODE_REM_SEND;
1034 break;
1035 case PHY_B_AS_PRT:
1036 skge->flow_control = FLOW_MODE_LOC_SEND;
1037 break;
1038 default:
1039 skge->flow_control = FLOW_MODE_NONE;
1040 }
1041
1042 skge->speed = SPEED_1000;
1043 }
1044
1045 if (!netif_carrier_ok(dev))
1046 genesis_link_up(skge);
1047 }
1048}
1049
1050/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
1051 * Phy on for 100 or 10Mbit operation
1052 */
1053static void bcom_phy_init(struct skge_port *skge, int jumbo)
1054{
1055 struct skge_hw *hw = skge->hw;
1056 int port = skge->port;
976 int i; 1057 int i;
977 u32 r; 1058 u16 id1, r, ext, ctl;
978 u16 id1;
979 u16 ctrl1, ctrl2, ctrl3, ctrl4, ctrl5;
980 1059
981 /* magic workaround patterns for Broadcom */ 1060 /* magic workaround patterns for Broadcom */
982 static const struct { 1061 static const struct {
@@ -992,6 +1071,110 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
992 { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, 1071 { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
993 }; 1072 };
994 1073
1074 pr_debug("bcom_phy_init\n");
1075
1076 /* read Id from external PHY (all have the same address) */
1077 id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
1078
1079 /* Optimize MDIO transfer by suppressing preamble. */
1080 r = xm_read16(hw, port, XM_MMU_CMD);
1081 r |= XM_MMU_NO_PRE;
1082 xm_write16(hw, port, XM_MMU_CMD,r);
1083
1084 switch(id1) {
1085 case PHY_BCOM_ID1_C0:
1086 /*
1087 * Workaround BCOM Errata for the C0 type.
1088 * Write magic patterns to reserved registers.
1089 */
1090 for (i = 0; i < ARRAY_SIZE(C0hack); i++)
1091 xm_phy_write(hw, port,
1092 C0hack[i].reg, C0hack[i].val);
1093
1094 break;
1095 case PHY_BCOM_ID1_A1:
1096 /*
1097 * Workaround BCOM Errata for the A1 type.
1098 * Write magic patterns to reserved registers.
1099 */
1100 for (i = 0; i < ARRAY_SIZE(A1hack); i++)
1101 xm_phy_write(hw, port,
1102 A1hack[i].reg, A1hack[i].val);
1103 break;
1104 }
1105
1106 /*
1107 * Workaround BCOM Errata (#10523) for all BCom PHYs.
1108 * Disable Power Management after reset.
1109 */
1110 r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
1111 r |= PHY_B_AC_DIS_PM;
1112 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r);
1113
1114 /* Dummy read */
1115 xm_read16(hw, port, XM_ISRC);
1116
1117 ext = PHY_B_PEC_EN_LTR; /* enable tx led */
1118 ctl = PHY_CT_SP1000; /* always 1000mbit */
1119
1120 if (skge->autoneg == AUTONEG_ENABLE) {
1121 /*
1122 * Workaround BCOM Errata #1 for the C5 type.
1123 * 1000Base-T Link Acquisition Failure in Slave Mode
1124 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
1125 */
1126 u16 adv = PHY_B_1000C_RD;
1127 if (skge->advertising & ADVERTISED_1000baseT_Half)
1128 adv |= PHY_B_1000C_AHD;
1129 if (skge->advertising & ADVERTISED_1000baseT_Full)
1130 adv |= PHY_B_1000C_AFD;
1131 xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv);
1132
1133 ctl |= PHY_CT_ANE | PHY_CT_RE_CFG;
1134 } else {
1135 if (skge->duplex == DUPLEX_FULL)
1136 ctl |= PHY_CT_DUP_MD;
1137 /* Force to slave */
1138 xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE);
1139 }
1140
1141 /* Set autonegotiation pause parameters */
1142 xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV,
1143 phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
1144
1145 /* Handle Jumbo frames */
1146 if (jumbo) {
1147 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
1148 PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);
1149
1150 ext |= PHY_B_PEC_HIGH_LA;
1151
1152 }
1153
1154 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
1155 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
1156
1157 /* Use link status change interrrupt */
1158 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1159
1160 bcom_check_link(hw, port);
1161}
1162
1163static void genesis_mac_init(struct skge_hw *hw, int port)
1164{
1165 struct net_device *dev = hw->dev[port];
1166 struct skge_port *skge = netdev_priv(dev);
1167 int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
1168 int i;
1169 u32 r;
1170 const u8 zero[6] = { 0 };
1171
1172 /* Clear MIB counters */
1173 xm_write16(hw, port, XM_STAT_CMD,
1174 XM_SC_CLR_RXC | XM_SC_CLR_TXC);
1175 /* Clear two times according to Errata #3 */
1176 xm_write16(hw, port, XM_STAT_CMD,
1177 XM_SC_CLR_RXC | XM_SC_CLR_TXC);
995 1178
996 /* initialize Rx, Tx and Link LED */ 1179 /* initialize Rx, Tx and Link LED */
997 skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); 1180 skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
@@ -1009,9 +1192,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1009 * GMII mode. 1192 * GMII mode.
1010 */ 1193 */
1011 spin_lock_bh(&hw->phy_lock); 1194 spin_lock_bh(&hw->phy_lock);
1012 1195 /* Take external Phy out of reset */
1013 /* External Phy Handling */
1014 /* Take PHY out of reset. */
1015 r = skge_read32(hw, B2_GP_IO); 1196 r = skge_read32(hw, B2_GP_IO);
1016 if (port == 0) 1197 if (port == 0)
1017 r |= GP_DIR_0|GP_IO_0; 1198 r |= GP_DIR_0|GP_IO_0;
@@ -1020,57 +1201,47 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1020 1201
1021 skge_write32(hw, B2_GP_IO, r); 1202 skge_write32(hw, B2_GP_IO, r);
1022 skge_read32(hw, B2_GP_IO); 1203 skge_read32(hw, B2_GP_IO);
1204 spin_unlock_bh(&hw->phy_lock);
1023 1205
1024 /* Enable GMII mode on the XMAC. */ 1206 /* Enable GMII interfac */
1025 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); 1207 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1026 1208
1027 id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); 1209 bcom_phy_init(skge, jumbo);
1028 1210
1029 /* Optimize MDIO transfer by suppressing preamble. */ 1211 /* Set Station Address */
1030 xm_write16(hw, port, XM_MMU_CMD, 1212 xm_outaddr(hw, port, XM_SA, dev->dev_addr);
1031 xm_read16(hw, port, XM_MMU_CMD)
1032 | XM_MMU_NO_PRE);
1033 1213
1034 if (id1 == PHY_BCOM_ID1_C0) { 1214 /* We don't use match addresses so clear */
1035 /* 1215 for (i = 1; i < 16; i++)
1036 * Workaround BCOM Errata for the C0 type. 1216 xm_outaddr(hw, port, XM_EXM(i), zero);
1037 * Write magic patterns to reserved registers. 1217
1038 */ 1218 /* configure Rx High Water Mark (XM_RX_HI_WM) */
1039 for (i = 0; i < ARRAY_SIZE(C0hack); i++) 1219 xm_write16(hw, port, XM_RX_HI_WM, 1450);
1040 xm_phy_write(hw, port, 1220
1041 C0hack[i].reg, C0hack[i].val); 1221 /* We don't need the FCS appended to the packet. */
1222 r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS;
1223 if (jumbo)
1224 r |= XM_RX_BIG_PK_OK;
1042 1225
1043 } else if (id1 == PHY_BCOM_ID1_A1) { 1226 if (skge->duplex == DUPLEX_HALF) {
1044 /* 1227 /*
1045 * Workaround BCOM Errata for the A1 type. 1228 * If in manual half duplex mode the other side might be in
1046 * Write magic patterns to reserved registers. 1229 * full duplex mode, so ignore if a carrier extension is not seen
1230 * on frames received
1047 */ 1231 */
1048 for (i = 0; i < ARRAY_SIZE(A1hack); i++) 1232 r |= XM_RX_DIS_CEXT;
1049 xm_phy_write(hw, port,
1050 A1hack[i].reg, A1hack[i].val);
1051 } 1233 }
1234 xm_write16(hw, port, XM_RX_CMD, r);
1052 1235
1053 /*
1054 * Workaround BCOM Errata (#10523) for all BCom PHYs.
1055 * Disable Power Management after reset.
1056 */
1057 r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
1058 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM);
1059
1060
1061 /* Dummy read */
1062 xm_read16(hw, port, XM_ISRC);
1063
1064 r = xm_read32(hw, port, XM_MODE);
1065 xm_write32(hw, port, XM_MODE, r|XM_MD_CSA);
1066
1067 /* We don't need the FCS appended to the packet. */
1068 r = xm_read16(hw, port, XM_RX_CMD);
1069 xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS);
1070 1236
1071 /* We want short frames padded to 60 bytes. */ 1237 /* We want short frames padded to 60 bytes. */
1072 r = xm_read16(hw, port, XM_TX_CMD); 1238 xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD);
1073 xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD); 1239
1240 /*
1241 * Bump up the transmit threshold. This helps hold off transmit
1242 * underruns when we're blasting traffic from both ports at once.
1243 */
1244 xm_write16(hw, port, XM_TX_THR, 512);
1074 1245
1075 /* 1246 /*
1076 * Enable the reception of all error frames. This is is 1247 * Enable the reception of all error frames. This is is
@@ -1086,19 +1257,22 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1086 * case the XMAC will start transfering frames out of the 1257 * case the XMAC will start transfering frames out of the
1087 * RX FIFO as soon as the FIFO threshold is reached. 1258 * RX FIFO as soon as the FIFO threshold is reached.
1088 */ 1259 */
1089 r = xm_read32(hw, port, XM_MODE); 1260 xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
1090 xm_write32(hw, port, XM_MODE,
1091 XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT|
1092 XM_MD_RX_ERR|XM_MD_RX_IRLE);
1093 1261
1094 xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr);
1095 xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr);
1096 1262
1097 /* 1263 /*
1098 * Bump up the transmit threshold. This helps hold off transmit 1264 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
1099 * underruns when we're blasting traffic from both ports at once. 1265 * - Enable all bits excepting 'Octets Rx OK Low CntOv'
1266 * and 'Octets Rx OK Hi Cnt Ov'.
1100 */ 1267 */
1101 xm_write16(hw, port, XM_TX_THR, 512); 1268 xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK);
1269
1270 /*
1271 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
1272 * - Enable all bits excepting 'Octets Tx OK Low CntOv'
1273 * and 'Octets Tx OK Hi Cnt Ov'.
1274 */
1275 xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK);
1102 1276
1103 /* Configure MAC arbiter */ 1277 /* Configure MAC arbiter */
1104 skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR); 1278 skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);
@@ -1124,89 +1298,14 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1124 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); 1298 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
1125 skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); 1299 skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
1126 1300
1127 if (hw->dev[port]->mtu > ETH_DATA_LEN) { 1301 if (jumbo) {
1128 /* Enable frame flushing if jumbo frames used */ 1302 /* Enable frame flushing if jumbo frames used */
1129 skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); 1303 skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH);
1130 } else { 1304 } else {
1131 /* enable timeout timers if normal frames */ 1305 /* enable timeout timers if normal frames */
1132 skge_write16(hw, B3_PA_CTRL, 1306 skge_write16(hw, B3_PA_CTRL,
1133 port == 0 ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2); 1307 (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
1134 } 1308 }
1135
1136
1137 r = xm_read16(hw, port, XM_RX_CMD);
1138 if (hw->dev[port]->mtu > ETH_DATA_LEN)
1139 xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK);
1140 else
1141 xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK));
1142
1143 /* Broadcom phy initialization */
1144 ctrl1 = PHY_CT_SP1000;
1145 ctrl2 = 0;
1146 ctrl3 = PHY_AN_CSMA;
1147 ctrl4 = PHY_B_PEC_EN_LTR;
1148 ctrl5 = PHY_B_AC_TX_TST;
1149
1150 if (skge->autoneg == AUTONEG_ENABLE) {
1151 /*
1152 * Workaround BCOM Errata #1 for the C5 type.
1153 * 1000Base-T Link Acquisition Failure in Slave Mode
1154 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
1155 */
1156 ctrl2 |= PHY_B_1000C_RD;
1157 if (skge->advertising & ADVERTISED_1000baseT_Half)
1158 ctrl2 |= PHY_B_1000C_AHD;
1159 if (skge->advertising & ADVERTISED_1000baseT_Full)
1160 ctrl2 |= PHY_B_1000C_AFD;
1161
1162 /* Set Flow-control capabilities */
1163 switch (skge->flow_control) {
1164 case FLOW_MODE_NONE:
1165 ctrl3 |= PHY_B_P_NO_PAUSE;
1166 break;
1167 case FLOW_MODE_LOC_SEND:
1168 ctrl3 |= PHY_B_P_ASYM_MD;
1169 break;
1170 case FLOW_MODE_SYMMETRIC:
1171 ctrl3 |= PHY_B_P_SYM_MD;
1172 break;
1173 case FLOW_MODE_REM_SEND:
1174 ctrl3 |= PHY_B_P_BOTH_MD;
1175 break;
1176 }
1177
1178 /* Restart Auto-negotiation */
1179 ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
1180 } else {
1181 if (skge->duplex == DUPLEX_FULL)
1182 ctrl1 |= PHY_CT_DUP_MD;
1183
1184 ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
1185 }
1186
1187 xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2);
1188 xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3);
1189
1190 if (skge->netdev->mtu > ETH_DATA_LEN) {
1191 ctrl4 |= PHY_B_PEC_HIGH_LA;
1192 ctrl5 |= PHY_B_AC_LONG_PACK;
1193
1194 xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5);
1195 }
1196
1197 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4);
1198 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1);
1199 spin_unlock_bh(&hw->phy_lock);
1200
1201 /* Clear MIB counters */
1202 xm_write16(hw, port, XM_STAT_CMD,
1203 XM_SC_CLR_RXC | XM_SC_CLR_TXC);
1204 /* Clear two times according to Errata #3 */
1205 xm_write16(hw, port, XM_STAT_CMD,
1206 XM_SC_CLR_RXC | XM_SC_CLR_TXC);
1207
1208 /* Start polling for link status */
1209 mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
1210} 1309}
1211 1310
1212static void genesis_stop(struct skge_port *skge) 1311static void genesis_stop(struct skge_port *skge)
@@ -1331,23 +1430,6 @@ static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1331 return gma_read16(hw, port, GM_SMI_DATA); 1430 return gma_read16(hw, port, GM_SMI_DATA);
1332} 1431}
1333 1432
1334static void genesis_link_down(struct skge_port *skge)
1335{
1336 struct skge_hw *hw = skge->hw;
1337 int port = skge->port;
1338
1339 pr_debug("genesis_link_down\n");
1340
1341 xm_write16(hw, port, XM_MMU_CMD,
1342 xm_read16(hw, port, XM_MMU_CMD)
1343 & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
1344
1345 /* dummy read to ensure writing */
1346 (void) xm_read16(hw, port, XM_MMU_CMD);
1347
1348 skge_link_down(skge);
1349}
1350
1351static void genesis_link_up(struct skge_port *skge) 1433static void genesis_link_up(struct skge_port *skge)
1352{ 1434{
1353 struct skge_hw *hw = skge->hw; 1435 struct skge_hw *hw = skge->hw;
@@ -1430,18 +1512,23 @@ static void genesis_link_up(struct skge_port *skge)
1430} 1512}
1431 1513
1432 1514
1433static void genesis_bcom_intr(struct skge_port *skge) 1515static inline void bcom_phy_intr(struct skge_port *skge)
1434{ 1516{
1435 struct skge_hw *hw = skge->hw; 1517 struct skge_hw *hw = skge->hw;
1436 int port = skge->port; 1518 int port = skge->port;
1437 u16 stat = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); 1519 u16 isrc;
1520
1521 isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
1522 pr_debug("bcom_phy_interrupt status=0x%x\n", isrc);
1438 1523
1439 pr_debug("genesis_bcom intr stat=%x\n", stat); 1524 if (isrc & PHY_B_IS_PSE)
1525 printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n",
1526 hw->dev[port]->name);
1440 1527
1441 /* Workaround BCom Errata: 1528 /* Workaround BCom Errata:
1442 * enable and disable loopback mode if "NO HCD" occurs. 1529 * enable and disable loopback mode if "NO HCD" occurs.
1443 */ 1530 */
1444 if (stat & PHY_B_IS_NO_HDCL) { 1531 if (isrc & PHY_B_IS_NO_HDCL) {
1445 u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL); 1532 u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL);
1446 xm_phy_write(hw, port, PHY_BCOM_CTRL, 1533 xm_phy_write(hw, port, PHY_BCOM_CTRL,
1447 ctrl | PHY_CT_LOOP); 1534 ctrl | PHY_CT_LOOP);
@@ -1449,57 +1536,9 @@ static void genesis_bcom_intr(struct skge_port *skge)
1449 ctrl & ~PHY_CT_LOOP); 1536 ctrl & ~PHY_CT_LOOP);
1450 } 1537 }
1451 1538
1452 stat = xm_phy_read(hw, port, PHY_BCOM_STAT); 1539 if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
1453 if (stat & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) { 1540 bcom_check_link(hw, port);
1454 u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
1455 if ( !(aux & PHY_B_AS_LS) && netif_carrier_ok(skge->netdev))
1456 genesis_link_down(skge);
1457
1458 else if (stat & PHY_B_IS_LST_CHANGE) {
1459 if (aux & PHY_B_AS_AN_C) {
1460 switch (aux & PHY_B_AS_AN_RES_MSK) {
1461 case PHY_B_RES_1000FD:
1462 skge->duplex = DUPLEX_FULL;
1463 break;
1464 case PHY_B_RES_1000HD:
1465 skge->duplex = DUPLEX_HALF;
1466 break;
1467 }
1468
1469 switch (aux & PHY_B_AS_PAUSE_MSK) {
1470 case PHY_B_AS_PAUSE_MSK:
1471 skge->flow_control = FLOW_MODE_SYMMETRIC;
1472 break;
1473 case PHY_B_AS_PRR:
1474 skge->flow_control = FLOW_MODE_REM_SEND;
1475 break;
1476 case PHY_B_AS_PRT:
1477 skge->flow_control = FLOW_MODE_LOC_SEND;
1478 break;
1479 default:
1480 skge->flow_control = FLOW_MODE_NONE;
1481 }
1482 skge->speed = SPEED_1000;
1483 }
1484 genesis_link_up(skge);
1485 }
1486 else
1487 mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
1488 }
1489}
1490
1491/* Perodic poll of phy status to check for link transistion */
1492static void skge_link_timer(unsigned long __arg)
1493{
1494 struct skge_port *skge = (struct skge_port *) __arg;
1495 struct skge_hw *hw = skge->hw;
1496
1497 if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev))
1498 return;
1499 1541
1500 spin_lock_bh(&hw->phy_lock);
1501 genesis_bcom_intr(skge);
1502 spin_unlock_bh(&hw->phy_lock);
1503} 1542}
1504 1543
1505/* Marvell Phy Initailization */ 1544/* Marvell Phy Initailization */
@@ -1547,41 +1586,12 @@ static void yukon_init(struct skge_hw *hw, int port)
1547 adv |= PHY_M_AN_10_FD; 1586 adv |= PHY_M_AN_10_FD;
1548 if (skge->advertising & ADVERTISED_10baseT_Half) 1587 if (skge->advertising & ADVERTISED_10baseT_Half)
1549 adv |= PHY_M_AN_10_HD; 1588 adv |= PHY_M_AN_10_HD;
1550 1589 } else /* special defines for FIBER (88E1011S only) */
1551 /* Set Flow-control capabilities */
1552 switch (skge->flow_control) {
1553 case FLOW_MODE_NONE:
1554 adv |= PHY_B_P_NO_PAUSE;
1555 break;
1556 case FLOW_MODE_LOC_SEND:
1557 adv |= PHY_B_P_ASYM_MD;
1558 break;
1559 case FLOW_MODE_SYMMETRIC:
1560 adv |= PHY_B_P_SYM_MD;
1561 break;
1562 case FLOW_MODE_REM_SEND:
1563 adv |= PHY_B_P_BOTH_MD;
1564 break;
1565 }
1566 } else { /* special defines for FIBER (88E1011S only) */
1567 adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; 1590 adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
1568 1591
1569 /* Set Flow-control capabilities */ 1592 /* Set Flow-control capabilities */
1570 switch (skge->flow_control) { 1593 adv |= phy_pause_map[skge->flow_control];
1571 case FLOW_MODE_NONE: 1594
1572 adv |= PHY_M_P_NO_PAUSE_X;
1573 break;
1574 case FLOW_MODE_LOC_SEND:
1575 adv |= PHY_M_P_ASYM_MD_X;
1576 break;
1577 case FLOW_MODE_SYMMETRIC:
1578 adv |= PHY_M_P_SYM_MD_X;
1579 break;
1580 case FLOW_MODE_REM_SEND:
1581 adv |= PHY_M_P_BOTH_MD_X;
1582 break;
1583 }
1584 }
1585 /* Restart Auto-negotiation */ 1595 /* Restart Auto-negotiation */
1586 ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; 1596 ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
1587 } else { 1597 } else {
@@ -2090,7 +2100,6 @@ static int skge_down(struct net_device *dev)
2090 netif_stop_queue(dev); 2100 netif_stop_queue(dev);
2091 2101
2092 del_timer_sync(&skge->led_blink); 2102 del_timer_sync(&skge->led_blink);
2093 del_timer_sync(&skge->link_check);
2094 2103
2095 /* Stop transmitter */ 2104 /* Stop transmitter */
2096 skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); 2105 skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
@@ -2325,6 +2334,8 @@ static void genesis_set_multicast(struct net_device *dev)
2325 u32 mode; 2334 u32 mode;
2326 u8 filter[8]; 2335 u8 filter[8];
2327 2336
2337 pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count);
2338
2328 mode = xm_read32(hw, port, XM_MODE); 2339 mode = xm_read32(hw, port, XM_MODE);
2329 mode |= XM_MD_ENA_HASH; 2340 mode |= XM_MD_ENA_HASH;
2330 if (dev->flags & IFF_PROMISC) 2341 if (dev->flags & IFF_PROMISC)
@@ -2337,16 +2348,15 @@ static void genesis_set_multicast(struct net_device *dev)
2337 else { 2348 else {
2338 memset(filter, 0, sizeof(filter)); 2349 memset(filter, 0, sizeof(filter));
2339 for (i = 0; list && i < count; i++, list = list->next) { 2350 for (i = 0; list && i < count; i++, list = list->next) {
2340 u32 crc = crc32_le(~0, list->dmi_addr, ETH_ALEN); 2351 u32 crc, bit;
2341 u8 bit = 63 - (crc & 63); 2352 crc = ether_crc_le(ETH_ALEN, list->dmi_addr);
2342 2353 bit = ~crc & 0x3f;
2343 filter[bit/8] |= 1 << (bit%8); 2354 filter[bit/8] |= 1 << (bit%8);
2344 } 2355 }
2345 } 2356 }
2346 2357
2347 xm_outhash(hw, port, XM_HSM, filter);
2348
2349 xm_write32(hw, port, XM_MODE, mode); 2358 xm_write32(hw, port, XM_MODE, mode);
2359 xm_outhash(hw, port, XM_HSM, filter);
2350} 2360}
2351 2361
2352static void yukon_set_multicast(struct net_device *dev) 2362static void yukon_set_multicast(struct net_device *dev)
@@ -2667,7 +2677,7 @@ static void skge_extirq(unsigned long data)
2667 if (hw->chip_id != CHIP_ID_GENESIS) 2677 if (hw->chip_id != CHIP_ID_GENESIS)
2668 yukon_phy_intr(skge); 2678 yukon_phy_intr(skge);
2669 else 2679 else
2670 genesis_bcom_intr(skge); 2680 bcom_phy_intr(skge);
2671 } 2681 }
2672 } 2682 }
2673 spin_unlock(&hw->phy_lock); 2683 spin_unlock(&hw->phy_lock);
@@ -2986,10 +2996,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
2986 2996
2987 spin_lock_init(&skge->tx_lock); 2997 spin_lock_init(&skge->tx_lock);
2988 2998
2989 init_timer(&skge->link_check);
2990 skge->link_check.function = skge_link_timer;
2991 skge->link_check.data = (unsigned long) skge;
2992
2993 init_timer(&skge->led_blink); 2999 init_timer(&skge->led_blink);
2994 skge->led_blink.function = skge_blink_timer; 3000 skge->led_blink.function = skge_blink_timer;
2995 skge->led_blink.data = (unsigned long) skge; 3001 skge->led_blink.data = (unsigned long) skge;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 6f3a4b56a671..6b9a2ebbab28 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -1225,6 +1225,16 @@ enum {
1225 PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */ 1225 PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */
1226}; 1226};
1227 1227
1228/* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
1229/* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
1230enum {
1231 PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */
1232
1233 PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */
1234 PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */
1235};
1236
1237
1228/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ 1238/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
1229enum { 1239enum {
1230 PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */ 1240 PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */
@@ -1285,7 +1295,9 @@ enum {
1285 PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */ 1295 PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */
1286 PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */ 1296 PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */
1287}; 1297};
1288#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) 1298#define PHY_B_DEF_MSK \
1299 (~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \
1300 PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE))
1289 1301
1290/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */ 1302/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
1291enum { 1303enum {
@@ -2489,7 +2501,6 @@ struct skge_port {
2489 dma_addr_t dma; 2501 dma_addr_t dma;
2490 unsigned long mem_size; 2502 unsigned long mem_size;
2491 2503
2492 struct timer_list link_check;
2493 struct timer_list led_blink; 2504 struct timer_list led_blink;
2494}; 2505};
2495 2506