|
106 | 106 | #define MVNETA_TX_IN_PRGRS BIT(1) |
107 | 107 | #define MVNETA_TX_FIFO_EMPTY BIT(8) |
108 | 108 | #define MVNETA_RX_MIN_FRAME_SIZE 0x247c |
| 109 | +/* Only exists on Armada XP and Armada 370 */ |
109 | 110 | #define MVNETA_SERDES_CFG 0x24A0 |
110 | 111 | #define MVNETA_SGMII_SERDES_PROTO 0x0cc7 |
111 | 112 | #define MVNETA_QSGMII_SERDES_PROTO 0x0667 |
@@ -3529,26 +3530,55 @@ static int mvneta_setup_txqs(struct mvneta_port *pp) |
3529 | 3530 | return 0; |
3530 | 3531 | } |
3531 | 3532 |
|
3532 | | -static int mvneta_comphy_init(struct mvneta_port *pp) |
| 3533 | +static int mvneta_comphy_init(struct mvneta_port *pp, phy_interface_t interface) |
3533 | 3534 | { |
3534 | 3535 | int ret; |
3535 | 3536 |
|
3536 | | - if (!pp->comphy) |
3537 | | - return 0; |
3538 | | - |
3539 | | - ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, |
3540 | | - pp->phy_interface); |
| 3537 | + ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, interface); |
3541 | 3538 | if (ret) |
3542 | 3539 | return ret; |
3543 | 3540 |
|
3544 | 3541 | return phy_power_on(pp->comphy); |
3545 | 3542 | } |
3546 | 3543 |
|
| 3544 | +static int mvneta_config_interface(struct mvneta_port *pp, |
| 3545 | + phy_interface_t interface) |
| 3546 | +{ |
| 3547 | + int ret = 0; |
| 3548 | + |
| 3549 | + if (pp->comphy) { |
| 3550 | + if (interface == PHY_INTERFACE_MODE_SGMII || |
| 3551 | + interface == PHY_INTERFACE_MODE_1000BASEX || |
| 3552 | + interface == PHY_INTERFACE_MODE_2500BASEX) { |
| 3553 | + ret = mvneta_comphy_init(pp, interface); |
| 3554 | + } |
| 3555 | + } else { |
| 3556 | + switch (interface) { |
| 3557 | + case PHY_INTERFACE_MODE_QSGMII: |
| 3558 | + mvreg_write(pp, MVNETA_SERDES_CFG, |
| 3559 | + MVNETA_QSGMII_SERDES_PROTO); |
| 3560 | + break; |
| 3561 | + |
| 3562 | + case PHY_INTERFACE_MODE_SGMII: |
| 3563 | + case PHY_INTERFACE_MODE_1000BASEX: |
| 3564 | + mvreg_write(pp, MVNETA_SERDES_CFG, |
| 3565 | + MVNETA_SGMII_SERDES_PROTO); |
| 3566 | + break; |
| 3567 | + default: |
| 3568 | + return -EINVAL; |
| 3569 | + } |
| 3570 | + } |
| 3571 | + |
| 3572 | + pp->phy_interface = interface; |
| 3573 | + |
| 3574 | + return ret; |
| 3575 | +} |
| 3576 | + |
3547 | 3577 | static void mvneta_start_dev(struct mvneta_port *pp) |
3548 | 3578 | { |
3549 | 3579 | int cpu; |
3550 | 3580 |
|
3551 | | - WARN_ON(mvneta_comphy_init(pp)); |
| 3581 | + WARN_ON(mvneta_config_interface(pp, pp->phy_interface)); |
3552 | 3582 |
|
3553 | 3583 | mvneta_max_rx_size_set(pp, pp->pkt_size); |
3554 | 3584 | mvneta_txq_max_tx_size_set(pp, pp->pkt_size); |
@@ -3926,14 +3956,10 @@ static void mvneta_mac_config(struct phylink_config *config, unsigned int mode, |
3926 | 3956 | if (state->speed == SPEED_2500) |
3927 | 3957 | new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; |
3928 | 3958 |
|
3929 | | - if (pp->comphy && pp->phy_interface != state->interface && |
3930 | | - (state->interface == PHY_INTERFACE_MODE_SGMII || |
3931 | | - state->interface == PHY_INTERFACE_MODE_1000BASEX || |
3932 | | - state->interface == PHY_INTERFACE_MODE_2500BASEX)) { |
3933 | | - pp->phy_interface = state->interface; |
3934 | | - |
3935 | | - WARN_ON(phy_power_off(pp->comphy)); |
3936 | | - WARN_ON(mvneta_comphy_init(pp)); |
| 3959 | + if (pp->phy_interface != state->interface) { |
| 3960 | + if (pp->comphy) |
| 3961 | + WARN_ON(phy_power_off(pp->comphy)); |
| 3962 | + WARN_ON(mvneta_config_interface(pp, state->interface)); |
3937 | 3963 | } |
3938 | 3964 |
|
3939 | 3965 | if (new_ctrl0 != gmac_ctrl0) |
@@ -4977,20 +5003,10 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp, |
4977 | 5003 | } |
4978 | 5004 |
|
4979 | 5005 | /* Power up the port */ |
4980 | | -static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) |
| 5006 | +static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) |
4981 | 5007 | { |
4982 | 5008 | /* MAC Cause register should be cleared */ |
4983 | 5009 | mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0); |
4984 | | - |
4985 | | - if (phy_mode == PHY_INTERFACE_MODE_QSGMII) |
4986 | | - mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); |
4987 | | - else if (phy_mode == PHY_INTERFACE_MODE_SGMII || |
4988 | | - phy_interface_mode_is_8023z(phy_mode)) |
4989 | | - mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); |
4990 | | - else if (!phy_interface_mode_is_rgmii(phy_mode)) |
4991 | | - return -EINVAL; |
4992 | | - |
4993 | | - return 0; |
4994 | 5010 | } |
4995 | 5011 |
|
4996 | 5012 | /* Device initialization routine */ |
@@ -5176,11 +5192,7 @@ static int mvneta_probe(struct platform_device *pdev) |
5176 | 5192 | if (err < 0) |
5177 | 5193 | goto err_netdev; |
5178 | 5194 |
|
5179 | | - err = mvneta_port_power_up(pp, phy_mode); |
5180 | | - if (err < 0) { |
5181 | | - dev_err(&pdev->dev, "can't power up port\n"); |
5182 | | - goto err_netdev; |
5183 | | - } |
| 5195 | + mvneta_port_power_up(pp, phy_mode); |
5184 | 5196 |
|
5185 | 5197 | /* Armada3700 network controller does not support per-cpu |
5186 | 5198 | * operation, so only single NAPI should be initialized. |
@@ -5334,11 +5346,7 @@ static int mvneta_resume(struct device *device) |
5334 | 5346 | } |
5335 | 5347 | } |
5336 | 5348 | mvneta_defaults_set(pp); |
5337 | | - err = mvneta_port_power_up(pp, pp->phy_interface); |
5338 | | - if (err < 0) { |
5339 | | - dev_err(device, "can't power up port\n"); |
5340 | | - return err; |
5341 | | - } |
| 5349 | + mvneta_port_power_up(pp, pp->phy_interface); |
5342 | 5350 |
|
5343 | 5351 | netif_device_attach(dev); |
5344 | 5352 |
|
|
0 commit comments