diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-08-12 04:23:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-13 02:02:32 -0400 |
commit | f57a60256d02daba1316c98da472f02cd98a58d3 (patch) | |
tree | c927a54bf16050d43418c11404afc1fd78370940 /drivers/net/bnx2x_main.c | |
parent | 01cd452846c98609dd3efbee0deea050e6706f02 (diff) |
bnx2x: Supporting PHY FW upgrade
There are 3 operations that the driver needs to support to allow applications to
access the PHY FW (on top of the MDC/MDIO access). Since those are essentially
nvram access commands, adding them to the ethtool -E interface.
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 145866764d46..7853977b8de2 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -9353,7 +9353,8 @@ static int bnx2x_set_eeprom(struct net_device *dev, | |||
9353 | struct ethtool_eeprom *eeprom, u8 *eebuf) | 9353 | struct ethtool_eeprom *eeprom, u8 *eebuf) |
9354 | { | 9354 | { |
9355 | struct bnx2x *bp = netdev_priv(dev); | 9355 | struct bnx2x *bp = netdev_priv(dev); |
9356 | int rc; | 9356 | int port = BP_PORT(bp); |
9357 | int rc = 0; | ||
9357 | 9358 | ||
9358 | if (!netif_running(dev)) | 9359 | if (!netif_running(dev)) |
9359 | return -EAGAIN; | 9360 | return -EAGAIN; |
@@ -9365,27 +9366,62 @@ static int bnx2x_set_eeprom(struct net_device *dev, | |||
9365 | 9366 | ||
9366 | /* parameters already validated in ethtool_set_eeprom */ | 9367 | /* parameters already validated in ethtool_set_eeprom */ |
9367 | 9368 | ||
9368 | /* If the magic number is PHY (0x00504859) upgrade the PHY FW */ | 9369 | /* PHY eeprom can be accessed only by the PMF */ |
9369 | if (eeprom->magic == 0x00504859) | 9370 | if ((eeprom->magic >= 0x50485900) && (eeprom->magic <= 0x504859FF) && |
9370 | if (bp->port.pmf) { | 9371 | !bp->port.pmf) |
9372 | return -EINVAL; | ||
9373 | |||
9374 | if (eeprom->magic == 0x50485950) { | ||
9375 | /* 'PHYP' (0x50485950): prepare phy for FW upgrade */ | ||
9376 | bnx2x_stats_handle(bp, STATS_EVENT_STOP); | ||
9371 | 9377 | ||
9378 | bnx2x_acquire_phy_lock(bp); | ||
9379 | rc |= bnx2x_link_reset(&bp->link_params, | ||
9380 | &bp->link_vars, 0); | ||
9381 | if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == | ||
9382 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) | ||
9383 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, | ||
9384 | MISC_REGISTERS_GPIO_HIGH, port); | ||
9385 | bnx2x_release_phy_lock(bp); | ||
9386 | bnx2x_link_report(bp); | ||
9387 | |||
9388 | } else if (eeprom->magic == 0x50485952) { | ||
9389 | /* 'PHYR' (0x50485952): re-init link after FW upgrade */ | ||
9390 | if ((bp->state == BNX2X_STATE_OPEN) || | ||
9391 | (bp->state == BNX2X_STATE_DISABLED)) { | ||
9372 | bnx2x_acquire_phy_lock(bp); | 9392 | bnx2x_acquire_phy_lock(bp); |
9373 | rc = bnx2x_flash_download(bp, BP_PORT(bp), | 9393 | rc |= bnx2x_link_reset(&bp->link_params, |
9374 | bp->link_params.ext_phy_config, | 9394 | &bp->link_vars, 1); |
9375 | (bp->state != BNX2X_STATE_CLOSED), | 9395 | |
9376 | eebuf, eeprom->len); | 9396 | rc |= bnx2x_phy_init(&bp->link_params, |
9377 | if ((bp->state == BNX2X_STATE_OPEN) || | 9397 | &bp->link_vars); |
9378 | (bp->state == BNX2X_STATE_DISABLED)) { | ||
9379 | rc |= bnx2x_link_reset(&bp->link_params, | ||
9380 | &bp->link_vars, 1); | ||
9381 | rc |= bnx2x_phy_init(&bp->link_params, | ||
9382 | &bp->link_vars); | ||
9383 | } | ||
9384 | bnx2x_release_phy_lock(bp); | 9398 | bnx2x_release_phy_lock(bp); |
9399 | bnx2x_calc_fc_adv(bp); | ||
9400 | } | ||
9401 | } else if (eeprom->magic == 0x53985943) { | ||
9402 | /* 'PHYC' (0x53985943): PHY FW upgrade completed */ | ||
9403 | if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == | ||
9404 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) { | ||
9405 | u8 ext_phy_addr = | ||
9406 | (bp->link_params.ext_phy_config & | ||
9407 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
9408 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT; | ||
9409 | |||
9410 | /* DSP Remove Download Mode */ | ||
9411 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, | ||
9412 | MISC_REGISTERS_GPIO_LOW, port); | ||
9385 | 9413 | ||
9386 | } else /* Only the PMF can access the PHY */ | 9414 | bnx2x_acquire_phy_lock(bp); |
9387 | return -EINVAL; | 9415 | |
9388 | else | 9416 | bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); |
9417 | |||
9418 | /* wait 0.5 sec to allow it to run */ | ||
9419 | msleep(500); | ||
9420 | bnx2x_ext_phy_hw_reset(bp, port); | ||
9421 | msleep(500); | ||
9422 | bnx2x_release_phy_lock(bp); | ||
9423 | } | ||
9424 | } else | ||
9389 | rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); | 9425 | rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); |
9390 | 9426 | ||
9391 | return rc; | 9427 | return rc; |