diff options
Diffstat (limited to 'drivers/net/cxgb3/t3_hw.c')
-rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 133 |
1 files changed, 67 insertions, 66 deletions
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index fa0a4b4fb5cb..f7ced324227d 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -194,21 +194,18 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n, | |||
194 | static void mi1_init(struct adapter *adap, const struct adapter_info *ai) | 194 | static void mi1_init(struct adapter *adap, const struct adapter_info *ai) |
195 | { | 195 | { |
196 | u32 clkdiv = adap->params.vpd.cclk / (2 * adap->params.vpd.mdc) - 1; | 196 | u32 clkdiv = adap->params.vpd.cclk / (2 * adap->params.vpd.mdc) - 1; |
197 | u32 val = F_PREEN | V_MDIINV(ai->mdiinv) | V_MDIEN(ai->mdien) | | 197 | u32 val = F_PREEN | V_CLKDIV(clkdiv); |
198 | V_CLKDIV(clkdiv); | ||
199 | 198 | ||
200 | if (!(ai->caps & SUPPORTED_10000baseT_Full)) | ||
201 | val |= V_ST(1); | ||
202 | t3_write_reg(adap, A_MI1_CFG, val); | 199 | t3_write_reg(adap, A_MI1_CFG, val); |
203 | } | 200 | } |
204 | 201 | ||
205 | #define MDIO_ATTEMPTS 10 | 202 | #define MDIO_ATTEMPTS 20 |
206 | 203 | ||
207 | /* | 204 | /* |
208 | * MI1 read/write operations for direct-addressed PHYs. | 205 | * MI1 read/write operations for clause 22 PHYs. |
209 | */ | 206 | */ |
210 | static int mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, | 207 | static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, |
211 | int reg_addr, unsigned int *valp) | 208 | int reg_addr, unsigned int *valp) |
212 | { | 209 | { |
213 | int ret; | 210 | int ret; |
214 | u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); | 211 | u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); |
@@ -217,16 +214,17 @@ static int mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, | |||
217 | return -EINVAL; | 214 | return -EINVAL; |
218 | 215 | ||
219 | mutex_lock(&adapter->mdio_lock); | 216 | mutex_lock(&adapter->mdio_lock); |
217 | t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); | ||
220 | t3_write_reg(adapter, A_MI1_ADDR, addr); | 218 | t3_write_reg(adapter, A_MI1_ADDR, addr); |
221 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); | 219 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); |
222 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); | 220 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); |
223 | if (!ret) | 221 | if (!ret) |
224 | *valp = t3_read_reg(adapter, A_MI1_DATA); | 222 | *valp = t3_read_reg(adapter, A_MI1_DATA); |
225 | mutex_unlock(&adapter->mdio_lock); | 223 | mutex_unlock(&adapter->mdio_lock); |
226 | return ret; | 224 | return ret; |
227 | } | 225 | } |
228 | 226 | ||
229 | static int mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, | 227 | static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, |
230 | int reg_addr, unsigned int val) | 228 | int reg_addr, unsigned int val) |
231 | { | 229 | { |
232 | int ret; | 230 | int ret; |
@@ -236,37 +234,51 @@ static int mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, | |||
236 | return -EINVAL; | 234 | return -EINVAL; |
237 | 235 | ||
238 | mutex_lock(&adapter->mdio_lock); | 236 | mutex_lock(&adapter->mdio_lock); |
237 | t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); | ||
239 | t3_write_reg(adapter, A_MI1_ADDR, addr); | 238 | t3_write_reg(adapter, A_MI1_ADDR, addr); |
240 | t3_write_reg(adapter, A_MI1_DATA, val); | 239 | t3_write_reg(adapter, A_MI1_DATA, val); |
241 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); | 240 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); |
242 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); | 241 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); |
243 | mutex_unlock(&adapter->mdio_lock); | 242 | mutex_unlock(&adapter->mdio_lock); |
244 | return ret; | 243 | return ret; |
245 | } | 244 | } |
246 | 245 | ||
247 | static const struct mdio_ops mi1_mdio_ops = { | 246 | static const struct mdio_ops mi1_mdio_ops = { |
248 | mi1_read, | 247 | t3_mi1_read, |
249 | mi1_write | 248 | t3_mi1_write |
250 | }; | 249 | }; |
251 | 250 | ||
252 | /* | 251 | /* |
252 | * Performs the address cycle for clause 45 PHYs. | ||
253 | * Must be called with the MDIO_LOCK held. | ||
254 | */ | ||
255 | static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr, | ||
256 | int reg_addr) | ||
257 | { | ||
258 | u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr); | ||
259 | |||
260 | t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), 0); | ||
261 | t3_write_reg(adapter, A_MI1_ADDR, addr); | ||
262 | t3_write_reg(adapter, A_MI1_DATA, reg_addr); | ||
263 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0)); | ||
264 | return t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, | ||
265 | MDIO_ATTEMPTS, 10); | ||
266 | } | ||
267 | |||
268 | /* | ||
253 | * MI1 read/write operations for indirect-addressed PHYs. | 269 | * MI1 read/write operations for indirect-addressed PHYs. |
254 | */ | 270 | */ |
255 | static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, | 271 | static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, |
256 | int reg_addr, unsigned int *valp) | 272 | int reg_addr, unsigned int *valp) |
257 | { | 273 | { |
258 | int ret; | 274 | int ret; |
259 | u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr); | ||
260 | 275 | ||
261 | mutex_lock(&adapter->mdio_lock); | 276 | mutex_lock(&adapter->mdio_lock); |
262 | t3_write_reg(adapter, A_MI1_ADDR, addr); | 277 | ret = mi1_wr_addr(adapter, phy_addr, mmd_addr, reg_addr); |
263 | t3_write_reg(adapter, A_MI1_DATA, reg_addr); | ||
264 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0)); | ||
265 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); | ||
266 | if (!ret) { | 278 | if (!ret) { |
267 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3)); | 279 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3)); |
268 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, | 280 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, |
269 | MDIO_ATTEMPTS, 20); | 281 | MDIO_ATTEMPTS, 10); |
270 | if (!ret) | 282 | if (!ret) |
271 | *valp = t3_read_reg(adapter, A_MI1_DATA); | 283 | *valp = t3_read_reg(adapter, A_MI1_DATA); |
272 | } | 284 | } |
@@ -278,18 +290,14 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, | |||
278 | int reg_addr, unsigned int val) | 290 | int reg_addr, unsigned int val) |
279 | { | 291 | { |
280 | int ret; | 292 | int ret; |
281 | u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr); | ||
282 | 293 | ||
283 | mutex_lock(&adapter->mdio_lock); | 294 | mutex_lock(&adapter->mdio_lock); |
284 | t3_write_reg(adapter, A_MI1_ADDR, addr); | 295 | ret = mi1_wr_addr(adapter, phy_addr, mmd_addr, reg_addr); |
285 | t3_write_reg(adapter, A_MI1_DATA, reg_addr); | ||
286 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0)); | ||
287 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); | ||
288 | if (!ret) { | 296 | if (!ret) { |
289 | t3_write_reg(adapter, A_MI1_DATA, val); | 297 | t3_write_reg(adapter, A_MI1_DATA, val); |
290 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); | 298 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); |
291 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, | 299 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, |
292 | MDIO_ATTEMPTS, 20); | 300 | MDIO_ATTEMPTS, 10); |
293 | } | 301 | } |
294 | mutex_unlock(&adapter->mdio_lock); | 302 | mutex_unlock(&adapter->mdio_lock); |
295 | return ret; | 303 | return ret; |
@@ -435,22 +443,22 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) | |||
435 | } | 443 | } |
436 | 444 | ||
437 | static const struct adapter_info t3_adap_info[] = { | 445 | static const struct adapter_info t3_adap_info[] = { |
438 | {2, 0, 0, 0, | 446 | {2, 0, |
439 | F_GPIO2_OEN | F_GPIO4_OEN | | 447 | F_GPIO2_OEN | F_GPIO4_OEN | |
440 | F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, | 448 | F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, |
441 | 0, | 449 | 0, |
442 | &mi1_mdio_ops, "Chelsio PE9000"}, | 450 | &mi1_mdio_ops, "Chelsio PE9000"}, |
443 | {2, 0, 0, 0, | 451 | {2, 0, |
444 | F_GPIO2_OEN | F_GPIO4_OEN | | 452 | F_GPIO2_OEN | F_GPIO4_OEN | |
445 | F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, | 453 | F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, |
446 | 0, | 454 | 0, |
447 | &mi1_mdio_ops, "Chelsio T302"}, | 455 | &mi1_mdio_ops, "Chelsio T302"}, |
448 | {1, 0, 0, 0, | 456 | {1, 0, |
449 | F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN | | 457 | F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN | |
450 | F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, | 458 | F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, |
451 | 0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, | 459 | 0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, |
452 | &mi1_mdio_ext_ops, "Chelsio T310"}, | 460 | &mi1_mdio_ext_ops, "Chelsio T310"}, |
453 | {2, 0, 0, 0, | 461 | {2, 0, |
454 | F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN | | 462 | F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN | |
455 | F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL | | 463 | F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL | |
456 | F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0, | 464 | F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0, |
@@ -467,29 +475,23 @@ const struct adapter_info *t3_get_adapter_info(unsigned int id) | |||
467 | return id < ARRAY_SIZE(t3_adap_info) ? &t3_adap_info[id] : NULL; | 475 | return id < ARRAY_SIZE(t3_adap_info) ? &t3_adap_info[id] : NULL; |
468 | } | 476 | } |
469 | 477 | ||
470 | #define CAPS_1G (SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | \ | 478 | struct port_type_info { |
471 | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII) | 479 | int (*phy_prep)(struct cphy *phy, struct adapter *adapter, |
472 | #define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI) | 480 | int phy_addr, const struct mdio_ops *ops); |
481 | }; | ||
473 | 482 | ||
474 | static const struct port_type_info port_types[] = { | 483 | static const struct port_type_info port_types[] = { |
475 | {NULL}, | 484 | { NULL }, |
476 | {t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE, | 485 | { t3_ael1002_phy_prep }, |
477 | "10GBASE-XR"}, | 486 | { t3_vsc8211_phy_prep }, |
478 | {t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ, | 487 | { NULL}, |
479 | "10/100/1000BASE-T"}, | 488 | { t3_xaui_direct_phy_prep }, |
480 | {NULL, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ, | 489 | { NULL }, |
481 | "10/100/1000BASE-T"}, | 490 | { t3_qt2045_phy_prep }, |
482 | {t3_xaui_direct_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"}, | 491 | { t3_ael1006_phy_prep }, |
483 | {NULL, CAPS_10G, "10GBASE-KX4"}, | 492 | { NULL }, |
484 | {t3_qt2045_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"}, | ||
485 | {t3_ael1006_phy_prep, CAPS_10G | SUPPORTED_FIBRE, | ||
486 | "10GBASE-SR"}, | ||
487 | {NULL, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"}, | ||
488 | }; | 493 | }; |
489 | 494 | ||
490 | #undef CAPS_1G | ||
491 | #undef CAPS_10G | ||
492 | |||
493 | #define VPD_ENTRY(name, len) \ | 495 | #define VPD_ENTRY(name, len) \ |
494 | u8 name##_kword[2]; u8 name##_len; u8 name##_data[len] | 496 | u8 name##_kword[2]; u8 name##_len; u8 name##_data[len] |
495 | 497 | ||
@@ -1691,7 +1693,7 @@ int t3_phy_intr_handler(struct adapter *adapter) | |||
1691 | mask = gpi - (gpi & (gpi - 1)); | 1693 | mask = gpi - (gpi & (gpi - 1)); |
1692 | gpi -= mask; | 1694 | gpi -= mask; |
1693 | 1695 | ||
1694 | if (!(p->port_type->caps & SUPPORTED_IRQ)) | 1696 | if (!(p->phy.caps & SUPPORTED_IRQ)) |
1695 | continue; | 1697 | continue; |
1696 | 1698 | ||
1697 | if (cause & mask) { | 1699 | if (cause & mask) { |
@@ -3556,7 +3558,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
3556 | int reset) | 3558 | int reset) |
3557 | { | 3559 | { |
3558 | int ret; | 3560 | int ret; |
3559 | unsigned int i, j = 0; | 3561 | unsigned int i, j = -1; |
3560 | 3562 | ||
3561 | get_pci_mode(adapter, &adapter->params.pci); | 3563 | get_pci_mode(adapter, &adapter->params.pci); |
3562 | 3564 | ||
@@ -3620,19 +3622,18 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
3620 | 3622 | ||
3621 | for_each_port(adapter, i) { | 3623 | for_each_port(adapter, i) { |
3622 | u8 hw_addr[6]; | 3624 | u8 hw_addr[6]; |
3625 | const struct port_type_info *pti; | ||
3623 | struct port_info *p = adap2pinfo(adapter, i); | 3626 | struct port_info *p = adap2pinfo(adapter, i); |
3624 | 3627 | ||
3625 | while (!adapter->params.vpd.port_type[j]) | 3628 | while (!adapter->params.vpd.port_type[++j]) |
3626 | ++j; | 3629 | ; |
3627 | 3630 | ||
3628 | p->port_type = &port_types[adapter->params.vpd.port_type[j]]; | 3631 | pti = &port_types[adapter->params.vpd.port_type[j]]; |
3629 | ret = p->port_type->phy_prep(&p->phy, adapter, | 3632 | ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, |
3630 | ai->phy_base_addr + j, | 3633 | ai->mdio_ops); |
3631 | ai->mdio_ops); | ||
3632 | if (ret) | 3634 | if (ret) |
3633 | return ret; | 3635 | return ret; |
3634 | mac_prep(&p->mac, adapter, j); | 3636 | mac_prep(&p->mac, adapter, j); |
3635 | ++j; | ||
3636 | 3637 | ||
3637 | /* | 3638 | /* |
3638 | * The VPD EEPROM stores the base Ethernet address for the | 3639 | * The VPD EEPROM stores the base Ethernet address for the |
@@ -3646,9 +3647,9 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
3646 | ETH_ALEN); | 3647 | ETH_ALEN); |
3647 | memcpy(adapter->port[i]->perm_addr, hw_addr, | 3648 | memcpy(adapter->port[i]->perm_addr, hw_addr, |
3648 | ETH_ALEN); | 3649 | ETH_ALEN); |
3649 | init_link_config(&p->link_config, p->port_type->caps); | 3650 | init_link_config(&p->link_config, p->phy.caps); |
3650 | p->phy.ops->power_down(&p->phy, 1); | 3651 | p->phy.ops->power_down(&p->phy, 1); |
3651 | if (!(p->port_type->caps & SUPPORTED_IRQ)) | 3652 | if (!(p->phy.caps & SUPPORTED_IRQ)) |
3652 | adapter->params.linkpoll_period = 10; | 3653 | adapter->params.linkpoll_period = 10; |
3653 | } | 3654 | } |
3654 | 3655 | ||
@@ -3664,7 +3665,7 @@ void t3_led_ready(struct adapter *adapter) | |||
3664 | int t3_replay_prep_adapter(struct adapter *adapter) | 3665 | int t3_replay_prep_adapter(struct adapter *adapter) |
3665 | { | 3666 | { |
3666 | const struct adapter_info *ai = adapter->params.info; | 3667 | const struct adapter_info *ai = adapter->params.info; |
3667 | unsigned int i, j = 0; | 3668 | unsigned int i, j = -1; |
3668 | int ret; | 3669 | int ret; |
3669 | 3670 | ||
3670 | early_hw_init(adapter, ai); | 3671 | early_hw_init(adapter, ai); |
@@ -3673,17 +3674,17 @@ int t3_replay_prep_adapter(struct adapter *adapter) | |||
3673 | return ret; | 3674 | return ret; |
3674 | 3675 | ||
3675 | for_each_port(adapter, i) { | 3676 | for_each_port(adapter, i) { |
3677 | const struct port_type_info *pti; | ||
3676 | struct port_info *p = adap2pinfo(adapter, i); | 3678 | struct port_info *p = adap2pinfo(adapter, i); |
3677 | while (!adapter->params.vpd.port_type[j]) | ||
3678 | ++j; | ||
3679 | 3679 | ||
3680 | ret = p->port_type->phy_prep(&p->phy, adapter, | 3680 | while (!adapter->params.vpd.port_type[++j]) |
3681 | ai->phy_base_addr + j, | 3681 | ; |
3682 | ai->mdio_ops); | 3682 | |
3683 | pti = &port_types[adapter->params.vpd.port_type[j]]; | ||
3684 | ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL); | ||
3683 | if (ret) | 3685 | if (ret) |
3684 | return ret; | 3686 | return ret; |
3685 | p->phy.ops->power_down(&p->phy, 1); | 3687 | p->phy.ops->power_down(&p->phy, 1); |
3686 | ++j; | ||
3687 | } | 3688 | } |
3688 | 3689 | ||
3689 | return 0; | 3690 | return 0; |