@@ -100,11 +100,15 @@ s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
s32 ngbe_init_phy_yt(struct ngbe_hw *hw)
{
+ rte_spinlock_init(&hw->phy_lock);
+
+ rte_spinlock_lock(&hw->phy_lock);
/* close sds area register */
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
/* enable interrupts */
ngbe_write_phy_reg_mdi(hw, YT_INTR, 0,
YT_INTR_ENA_MASK | YT_SDS_INTR_ENA_MASK);
+ rte_spinlock_unlock(&hw->phy_lock);
hw->phy.set_phy_power(hw, false);
@@ -123,7 +127,9 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
hw->phy.autoneg_advertised = 0;
/* check chip_mode first */
+ rte_spinlock_lock(&hw->phy_lock);
ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
+ rte_spinlock_unlock(&hw->phy_lock);
if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(0)) {
/* UTP to rgmii */
if (!hw->mac.autoneg) {
@@ -146,11 +152,14 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
}
/* duplex full */
value |= YT_BCR_DUPLEX | YT_BCR_RESET;
+ rte_spinlock_lock(&hw->phy_lock);
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
goto skip_an;
}
+ rte_spinlock_lock(&hw->phy_lock);
/*disable 100/10base-T Self-negotiation ability*/
ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
@@ -189,6 +198,7 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN;
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
skip_an:
hw->phy.set_phy_power(hw, true);
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(1)) {
@@ -199,6 +209,7 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
value = YT_RGMII_CONF1_RXDELAY |
YT_RGMII_CONF1_TXDELAY_FE |
YT_RGMII_CONF1_TXDELAY;
+ rte_spinlock_lock(&hw->phy_lock);
ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
value = YT_CHIP_MODE_SEL(1) |
YT_CHIP_SW_LDO_EN |
@@ -225,17 +236,21 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
value = YT_BCR_RESET | YT_BCR_DUPLEX |
YT_BCR_SPEED_SELECT1;
hw->phy.write_reg(hw, YT_BCR, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
hw->phy.set_phy_power(hw, true);
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(2)) {
hw->phy.set_phy_power(hw, true);
+ rte_spinlock_lock(&hw->phy_lock);
hw->phy.read_reg(hw, YT_SPST, 0, &value);
+ rte_spinlock_unlock(&hw->phy_lock);
if (value & YT_SPST_LINK) {
/* fiber up */
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
} else {
/* utp up */
+ rte_spinlock_lock(&hw->phy_lock);
/*disable 100/10base-T Self-negotiation ability*/
ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value);
value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
@@ -279,10 +294,12 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
value |= YT_BCR_RESET;
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
}
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(4)) {
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
+ rte_spinlock_lock(&hw->phy_lock);
ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, &value);
value |= YT_RGMII_CONF1_MODE;
ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
@@ -297,6 +314,7 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
value &= ~YT_SMI_PHY_SW_RST;
ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
hw->phy.set_phy_power(hw, true);
} else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(5)) {
@@ -320,7 +338,9 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
}
/* duplex full */
value |= YT_BCR_DUPLEX | YT_BCR_RESET;
+ rte_spinlock_lock(&hw->phy_lock);
hw->phy.write_reg(hw, YT_BCR, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
goto skip_an_sr;
}
@@ -339,19 +359,23 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
/* duplex full */
value |= YT_BCR_DUPLEX | YT_BCR_RESET;
+ rte_spinlock_lock(&hw->phy_lock);
hw->phy.write_reg(hw, YT_BCR, 0, value);
/* software reset to make the above configuration take effect */
hw->phy.read_reg(hw, YT_BCR, 0, &value);
value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN;
hw->phy.write_reg(hw, 0x0, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
skip_an_sr:
hw->phy.set_phy_power(hw, true);
}
+ rte_spinlock_lock(&hw->phy_lock);
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value);
+ rte_spinlock_unlock(&hw->phy_lock);
return 0;
}
@@ -366,6 +390,7 @@ s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
hw->phy.type != ngbe_phy_yt8521s_sfi)
return NGBE_ERR_PHY_TYPE;
+ rte_spinlock_lock(&hw->phy_lock);
/* check chip_mode first */
ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &ctrl);
if (ctrl & YT_CHIP_MODE_MASK) {
@@ -395,6 +420,7 @@ s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
msleep(1);
}
}
+ rte_spinlock_unlock(&hw->phy_lock);
if (i == YT_PHY_RST_WAIT_PERIOD) {
DEBUGOUT("PHY reset polling failed to complete.");
@@ -409,7 +435,9 @@ s32 ngbe_get_phy_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
u16 value;
s32 status = 0;
+ rte_spinlock_lock(&hw->phy_lock);
status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
+ rte_spinlock_unlock(&hw->phy_lock);
value &= YT_FANA_PAUSE_MASK;
*pause_bit = (u8)(value >> 7);
@@ -421,7 +449,9 @@ s32 ngbe_get_phy_lp_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
u16 value;
s32 status = 0;
+ rte_spinlock_lock(&hw->phy_lock);
status = hw->phy.read_reg(hw, YT_LPAR, 0, &value);
+ rte_spinlock_unlock(&hw->phy_lock);
value &= YT_FLPAR_PAUSE_MASK;
*pause_bit = (u8)(value >> 7);
@@ -433,10 +463,12 @@ s32 ngbe_set_phy_pause_adv_yt(struct ngbe_hw *hw, u16 pause_bit)
u16 value;
s32 status = 0;
+ rte_spinlock_lock(&hw->phy_lock);
status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
value &= ~YT_FANA_PAUSE_MASK;
value |= pause_bit;
status = hw->phy.write_reg(hw, YT_ANA, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
return status;
}
@@ -453,6 +485,7 @@ s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
/* Initialize speed and link to default case */
*link_up = false;
*speed = NGBE_LINK_SPEED_UNKNOWN;
+ rte_spinlock_lock(&hw->phy_lock);
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr);
@@ -472,6 +505,7 @@ s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
*link_up = true;
}
+ rte_spinlock_unlock(&hw->phy_lock);
if (*link_up) {
if (phy_speed == YT_SPST_SPEED_1000M)
*speed = NGBE_LINK_SPEED_1GB_FULL;
@@ -488,6 +522,7 @@ s32 ngbe_set_phy_power_yt(struct ngbe_hw *hw, bool on)
{
u16 value = 0;
+ rte_spinlock_lock(&hw->phy_lock);
/* power down/up in fiber mode */
hw->phy.read_reg(hw, YT_BCR, 0, &value);
if (on)
@@ -504,6 +539,7 @@ s32 ngbe_set_phy_power_yt(struct ngbe_hw *hw, bool on)
else
value |= YT_BCR_PWDN;
ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
+ rte_spinlock_unlock(&hw->phy_lock);
return 0;
}
@@ -433,6 +433,7 @@ struct ngbe_hw {
bool gpio_ctl;
u32 led_conf;
bool init_phy;
+ rte_spinlock_t phy_lock;
struct {
u64 rx_qp_packets;
u64 tx_qp_packets;