0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include "common.h"
0034 #include "regs.h"
0035
0036 enum {
0037
0038 AQ_LINK_STAT = 0xe800,
0039 AQ_IMASK_PMA = 0xf000,
0040
0041
0042 AQ_XAUI_RX_CFG = 0xc400,
0043 AQ_XAUI_TX_CFG = 0xe400,
0044
0045
0046 AQ_1G_CTRL = 0xc400,
0047 AQ_ANEG_STAT = 0xc800,
0048
0049
0050 AQ_FW_VERSION = 0x0020,
0051 AQ_IFLAG_GLOBAL = 0xfc00,
0052 AQ_IMASK_GLOBAL = 0xff00,
0053 };
0054
0055 enum {
0056 IMASK_PMA = 1 << 2,
0057 IMASK_GLOBAL = 1 << 15,
0058 ADV_1G_FULL = 1 << 15,
0059 ADV_1G_HALF = 1 << 14,
0060 ADV_10G_FULL = 1 << 12,
0061 AQ_RESET = (1 << 14) | (1 << 15),
0062 AQ_LOWPOWER = 1 << 12,
0063 };
0064
0065 static int aq100x_reset(struct cphy *phy, int wait)
0066 {
0067
0068
0069
0070
0071 int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000);
0072
0073 if (err)
0074 CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n",
0075 phy->mdio.prtad, err);
0076
0077 return err;
0078 }
0079
0080 static int aq100x_intr_enable(struct cphy *phy)
0081 {
0082 int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA);
0083 if (err)
0084 return err;
0085
0086 err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL);
0087 return err;
0088 }
0089
0090 static int aq100x_intr_disable(struct cphy *phy)
0091 {
0092 return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0);
0093 }
0094
0095 static int aq100x_intr_clear(struct cphy *phy)
0096 {
0097 unsigned int v;
0098
0099 t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v);
0100 t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
0101
0102 return 0;
0103 }
0104
0105 static int aq100x_intr_handler(struct cphy *phy)
0106 {
0107 int err;
0108 unsigned int cause, v;
0109
0110 err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause);
0111 if (err)
0112 return err;
0113
0114
0115 t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
0116
0117 return cphy_cause_link_change;
0118 }
0119
0120 static int aq100x_power_down(struct cphy *phy, int off)
0121 {
0122 return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
0123 MDIO_MMD_PMAPMD, MDIO_CTRL1,
0124 MDIO_CTRL1_LPOWER, off);
0125 }
0126
0127 static int aq100x_autoneg_enable(struct cphy *phy)
0128 {
0129 int err;
0130
0131 err = aq100x_power_down(phy, 0);
0132 if (!err)
0133 err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
0134 MDIO_MMD_AN, MDIO_CTRL1,
0135 BMCR_ANENABLE | BMCR_ANRESTART, 1);
0136
0137 return err;
0138 }
0139
0140 static int aq100x_autoneg_restart(struct cphy *phy)
0141 {
0142 int err;
0143
0144 err = aq100x_power_down(phy, 0);
0145 if (!err)
0146 err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
0147 MDIO_MMD_AN, MDIO_CTRL1,
0148 BMCR_ANENABLE | BMCR_ANRESTART, 1);
0149
0150 return err;
0151 }
0152
0153 static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map)
0154 {
0155 unsigned int adv;
0156 int err;
0157
0158
0159 adv = 0;
0160 if (advertise_map & ADVERTISED_10000baseT_Full)
0161 adv |= ADV_10G_FULL;
0162 err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
0163 ADV_10G_FULL, adv);
0164 if (err)
0165 return err;
0166
0167
0168 adv = 0;
0169 if (advertise_map & ADVERTISED_1000baseT_Full)
0170 adv |= ADV_1G_FULL;
0171 if (advertise_map & ADVERTISED_1000baseT_Half)
0172 adv |= ADV_1G_HALF;
0173 err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL,
0174 ADV_1G_FULL | ADV_1G_HALF, adv);
0175 if (err)
0176 return err;
0177
0178
0179 adv = 0;
0180 if (advertise_map & ADVERTISED_100baseT_Half)
0181 adv |= ADVERTISE_100HALF;
0182 if (advertise_map & ADVERTISED_100baseT_Full)
0183 adv |= ADVERTISE_100FULL;
0184 if (advertise_map & ADVERTISED_Pause)
0185 adv |= ADVERTISE_PAUSE_CAP;
0186 if (advertise_map & ADVERTISED_Asym_Pause)
0187 adv |= ADVERTISE_PAUSE_ASYM;
0188 err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
0189 0xfe0, adv);
0190
0191 return err;
0192 }
0193
0194 static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable)
0195 {
0196 return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
0197 MDIO_MMD_PMAPMD, MDIO_CTRL1,
0198 BMCR_LOOPBACK, enable);
0199 }
0200
0201 static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex)
0202 {
0203
0204 return -1;
0205 }
0206
0207 static int aq100x_get_link_status(struct cphy *phy, int *link_ok,
0208 int *speed, int *duplex, int *fc)
0209 {
0210 int err;
0211 unsigned int v;
0212
0213 if (link_ok) {
0214 err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v);
0215 if (err)
0216 return err;
0217
0218 *link_ok = v & 1;
0219 if (!*link_ok)
0220 return 0;
0221 }
0222
0223 err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v);
0224 if (err)
0225 return err;
0226
0227 if (speed) {
0228 switch (v & 0x6) {
0229 case 0x6:
0230 *speed = SPEED_10000;
0231 break;
0232 case 0x4:
0233 *speed = SPEED_1000;
0234 break;
0235 case 0x2:
0236 *speed = SPEED_100;
0237 break;
0238 case 0x0:
0239 *speed = SPEED_10;
0240 break;
0241 }
0242 }
0243
0244 if (duplex)
0245 *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF;
0246
0247 return 0;
0248 }
0249
0250 static const struct cphy_ops aq100x_ops = {
0251 .reset = aq100x_reset,
0252 .intr_enable = aq100x_intr_enable,
0253 .intr_disable = aq100x_intr_disable,
0254 .intr_clear = aq100x_intr_clear,
0255 .intr_handler = aq100x_intr_handler,
0256 .autoneg_enable = aq100x_autoneg_enable,
0257 .autoneg_restart = aq100x_autoneg_restart,
0258 .advertise = aq100x_advertise,
0259 .set_loopback = aq100x_set_loopback,
0260 .set_speed_duplex = aq100x_set_speed_duplex,
0261 .get_link_status = aq100x_get_link_status,
0262 .power_down = aq100x_power_down,
0263 .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
0264 };
0265
0266 int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
0267 const struct mdio_ops *mdio_ops)
0268 {
0269 unsigned int v, v2, gpio, wait;
0270 int err;
0271
0272 cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
0273 SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
0274 SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI,
0275 "1000/10GBASE-T");
0276
0277
0278
0279
0280
0281 gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
0282 t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
0283 msleep(1);
0284 t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);
0285
0286
0287
0288
0289 msleep(1000);
0290 wait = 500;
0291 do {
0292 err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
0293 if (err || v == 0xffff) {
0294
0295
0296
0297 CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
0298 phy_addr, err, v);
0299 goto done;
0300 }
0301
0302 v &= AQ_RESET;
0303 if (v)
0304 msleep(10);
0305 } while (v && --wait);
0306 if (v) {
0307 CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
0308 phy_addr, v);
0309
0310 goto done;
0311 }
0312
0313
0314 wait = (500 - wait) * 10 + 1000;
0315 if (wait > 3000)
0316 CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);
0317
0318
0319 t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
0320 if (v != 101)
0321 CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
0322 phy_addr, v);
0323
0324
0325
0326
0327
0328 err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
0329 if (err)
0330 return err;
0331 if (v & AQ_LOWPOWER) {
0332 err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1,
0333 AQ_LOWPOWER, 0);
0334 if (err)
0335 return err;
0336 msleep(10);
0337 } else
0338 CH_WARN(adapter, "PHY%d does not start in low power mode.\n",
0339 phy_addr);
0340
0341
0342
0343
0344 v = v2 = 0;
0345 t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v);
0346 t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2);
0347 if (v != 0x1b || v2 != 0x1b)
0348 CH_WARN(adapter,
0349 "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n",
0350 phy_addr, v, v2);
0351
0352 done:
0353 return err;
0354 }