cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

igc_phy.c (21813B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (c)  2018 Intel Corporation */
      3
      4#include "igc_phy.h"
      5
      6/**
      7 * igc_check_reset_block - Check if PHY reset is blocked
      8 * @hw: pointer to the HW structure
      9 *
     10 * Read the PHY management control register and check whether a PHY reset
     11 * is blocked.  If a reset is not blocked return 0, otherwise
     12 * return IGC_ERR_BLK_PHY_RESET (12).
     13 */
     14s32 igc_check_reset_block(struct igc_hw *hw)
     15{
     16	u32 manc;
     17
     18	manc = rd32(IGC_MANC);
     19
     20	return (manc & IGC_MANC_BLK_PHY_RST_ON_IDE) ?
     21		IGC_ERR_BLK_PHY_RESET : 0;
     22}
     23
     24/**
     25 * igc_get_phy_id - Retrieve the PHY ID and revision
     26 * @hw: pointer to the HW structure
     27 *
     28 * Reads the PHY registers and stores the PHY ID and possibly the PHY
     29 * revision in the hardware structure.
     30 */
     31s32 igc_get_phy_id(struct igc_hw *hw)
     32{
     33	struct igc_phy_info *phy = &hw->phy;
     34	s32 ret_val = 0;
     35	u16 phy_id;
     36
     37	ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
     38	if (ret_val)
     39		goto out;
     40
     41	phy->id = (u32)(phy_id << 16);
     42	usleep_range(200, 500);
     43	ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
     44	if (ret_val)
     45		goto out;
     46
     47	phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
     48	phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
     49
     50out:
     51	return ret_val;
     52}
     53
     54/**
     55 * igc_phy_has_link - Polls PHY for link
     56 * @hw: pointer to the HW structure
     57 * @iterations: number of times to poll for link
     58 * @usec_interval: delay between polling attempts
     59 * @success: pointer to whether polling was successful or not
     60 *
     61 * Polls the PHY status register for link, 'iterations' number of times.
     62 */
     63s32 igc_phy_has_link(struct igc_hw *hw, u32 iterations,
     64		     u32 usec_interval, bool *success)
     65{
     66	u16 i, phy_status;
     67	s32 ret_val = 0;
     68
     69	for (i = 0; i < iterations; i++) {
     70		/* Some PHYs require the PHY_STATUS register to be read
     71		 * twice due to the link bit being sticky.  No harm doing
     72		 * it across the board.
     73		 */
     74		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
     75		if (ret_val && usec_interval > 0) {
     76			/* If the first read fails, another entity may have
     77			 * ownership of the resources, wait and try again to
     78			 * see if they have relinquished the resources yet.
     79			 */
     80			if (usec_interval >= 1000)
     81				mdelay(usec_interval / 1000);
     82			else
     83				udelay(usec_interval);
     84		}
     85		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
     86		if (ret_val)
     87			break;
     88		if (phy_status & MII_SR_LINK_STATUS)
     89			break;
     90		if (usec_interval >= 1000)
     91			mdelay(usec_interval / 1000);
     92		else
     93			udelay(usec_interval);
     94	}
     95
     96	*success = (i < iterations) ? true : false;
     97
     98	return ret_val;
     99}
    100
    101/**
    102 * igc_power_up_phy_copper - Restore copper link in case of PHY power down
    103 * @hw: pointer to the HW structure
    104 *
    105 * In the case of a PHY power down to save power, or to turn off link during a
    106 * driver unload, restore the link to previous settings.
    107 */
    108void igc_power_up_phy_copper(struct igc_hw *hw)
    109{
    110	u16 mii_reg = 0;
    111
    112	/* The PHY will retain its settings across a power down/up cycle */
    113	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
    114	mii_reg &= ~MII_CR_POWER_DOWN;
    115	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
    116}
    117
    118/**
    119 * igc_power_down_phy_copper - Power down copper PHY
    120 * @hw: pointer to the HW structure
    121 *
    122 * Power down PHY to save power when interface is down and wake on lan
    123 * is not enabled.
    124 */
    125void igc_power_down_phy_copper(struct igc_hw *hw)
    126{
    127	u16 mii_reg = 0;
    128
    129	/* The PHY will retain its settings across a power down/up cycle */
    130	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
    131	mii_reg |= MII_CR_POWER_DOWN;
    132
    133	/* Temporary workaround - should be removed when PHY will implement
    134	 * IEEE registers as properly
    135	 */
    136	/* hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);*/
    137	usleep_range(1000, 2000);
    138}
    139
    140/**
    141 * igc_check_downshift - Checks whether a downshift in speed occurred
    142 * @hw: pointer to the HW structure
    143 *
    144 * A downshift is detected by querying the PHY link health.
    145 */
    146void igc_check_downshift(struct igc_hw *hw)
    147{
    148	struct igc_phy_info *phy = &hw->phy;
    149
    150	/* speed downshift not supported */
    151	phy->speed_downgraded = false;
    152}
    153
    154/**
    155 * igc_phy_hw_reset - PHY hardware reset
    156 * @hw: pointer to the HW structure
    157 *
    158 * Verify the reset block is not blocking us from resetting.  Acquire
    159 * semaphore (if necessary) and read/set/write the device control reset
    160 * bit in the PHY.  Wait the appropriate delay time for the device to
    161 * reset and release the semaphore (if necessary).
    162 */
    163s32 igc_phy_hw_reset(struct igc_hw *hw)
    164{
    165	struct igc_phy_info *phy = &hw->phy;
    166	u32 phpm = 0, timeout = 10000;
    167	s32  ret_val;
    168	u32 ctrl;
    169
    170	ret_val = igc_check_reset_block(hw);
    171	if (ret_val) {
    172		ret_val = 0;
    173		goto out;
    174	}
    175
    176	ret_val = phy->ops.acquire(hw);
    177	if (ret_val)
    178		goto out;
    179
    180	phpm = rd32(IGC_I225_PHPM);
    181
    182	ctrl = rd32(IGC_CTRL);
    183	wr32(IGC_CTRL, ctrl | IGC_CTRL_PHY_RST);
    184	wrfl();
    185
    186	udelay(phy->reset_delay_us);
    187
    188	wr32(IGC_CTRL, ctrl);
    189	wrfl();
    190
    191	/* SW should guarantee 100us for the completion of the PHY reset */
    192	usleep_range(100, 150);
    193	do {
    194		phpm = rd32(IGC_I225_PHPM);
    195		timeout--;
    196		udelay(1);
    197	} while (!(phpm & IGC_PHY_RST_COMP) && timeout);
    198
    199	if (!timeout)
    200		hw_dbg("Timeout is expired after a phy reset\n");
    201
    202	usleep_range(100, 150);
    203
    204	phy->ops.release(hw);
    205
    206out:
    207	return ret_val;
    208}
    209
    210/**
    211 * igc_phy_setup_autoneg - Configure PHY for auto-negotiation
    212 * @hw: pointer to the HW structure
    213 *
    214 * Reads the MII auto-neg advertisement register and/or the 1000T control
    215 * register and if the PHY is already setup for auto-negotiation, then
    216 * return successful.  Otherwise, setup advertisement and flow control to
    217 * the appropriate values for the wanted auto-negotiation.
    218 */
    219static s32 igc_phy_setup_autoneg(struct igc_hw *hw)
    220{
    221	struct igc_phy_info *phy = &hw->phy;
    222	u16 aneg_multigbt_an_ctrl = 0;
    223	u16 mii_1000t_ctrl_reg = 0;
    224	u16 mii_autoneg_adv_reg;
    225	s32 ret_val;
    226
    227	phy->autoneg_advertised &= phy->autoneg_mask;
    228
    229	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
    230	ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
    231	if (ret_val)
    232		return ret_val;
    233
    234	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
    235		/* Read the MII 1000Base-T Control Register (Address 9). */
    236		ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
    237					    &mii_1000t_ctrl_reg);
    238		if (ret_val)
    239			return ret_val;
    240	}
    241
    242	if (phy->autoneg_mask & ADVERTISE_2500_FULL) {
    243		/* Read the MULTI GBT AN Control Register - reg 7.32 */
    244		ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
    245					    MMD_DEVADDR_SHIFT) |
    246					    ANEG_MULTIGBT_AN_CTRL,
    247					    &aneg_multigbt_an_ctrl);
    248
    249		if (ret_val)
    250			return ret_val;
    251	}
    252
    253	/* Need to parse both autoneg_advertised and fc and set up
    254	 * the appropriate PHY registers.  First we will parse for
    255	 * autoneg_advertised software override.  Since we can advertise
    256	 * a plethora of combinations, we need to check each bit
    257	 * individually.
    258	 */
    259
    260	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
    261	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
    262	 * the  1000Base-T Control Register (Address 9).
    263	 */
    264	mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
    265				 NWAY_AR_100TX_HD_CAPS |
    266				 NWAY_AR_10T_FD_CAPS   |
    267				 NWAY_AR_10T_HD_CAPS);
    268	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
    269
    270	hw_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
    271
    272	/* Do we want to advertise 10 Mb Half Duplex? */
    273	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
    274		hw_dbg("Advertise 10mb Half duplex\n");
    275		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
    276	}
    277
    278	/* Do we want to advertise 10 Mb Full Duplex? */
    279	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
    280		hw_dbg("Advertise 10mb Full duplex\n");
    281		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
    282	}
    283
    284	/* Do we want to advertise 100 Mb Half Duplex? */
    285	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
    286		hw_dbg("Advertise 100mb Half duplex\n");
    287		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
    288	}
    289
    290	/* Do we want to advertise 100 Mb Full Duplex? */
    291	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
    292		hw_dbg("Advertise 100mb Full duplex\n");
    293		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
    294	}
    295
    296	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
    297	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
    298		hw_dbg("Advertise 1000mb Half duplex request denied!\n");
    299
    300	/* Do we want to advertise 1000 Mb Full Duplex? */
    301	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
    302		hw_dbg("Advertise 1000mb Full duplex\n");
    303		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
    304	}
    305
    306	/* We do not allow the Phy to advertise 2500 Mb Half Duplex */
    307	if (phy->autoneg_advertised & ADVERTISE_2500_HALF)
    308		hw_dbg("Advertise 2500mb Half duplex request denied!\n");
    309
    310	/* Do we want to advertise 2500 Mb Full Duplex? */
    311	if (phy->autoneg_advertised & ADVERTISE_2500_FULL) {
    312		hw_dbg("Advertise 2500mb Full duplex\n");
    313		aneg_multigbt_an_ctrl |= CR_2500T_FD_CAPS;
    314	} else {
    315		aneg_multigbt_an_ctrl &= ~CR_2500T_FD_CAPS;
    316	}
    317
    318	/* Check for a software override of the flow control settings, and
    319	 * setup the PHY advertisement registers accordingly.  If
    320	 * auto-negotiation is enabled, then software will have to set the
    321	 * "PAUSE" bits to the correct value in the Auto-Negotiation
    322	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
    323	 * negotiation.
    324	 *
    325	 * The possible values of the "fc" parameter are:
    326	 *      0:  Flow control is completely disabled
    327	 *      1:  Rx flow control is enabled (we can receive pause frames
    328	 *          but not send pause frames).
    329	 *      2:  Tx flow control is enabled (we can send pause frames
    330	 *          but we do not support receiving pause frames).
    331	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
    332	 *  other:  No software override.  The flow control configuration
    333	 *          in the EEPROM is used.
    334	 */
    335	switch (hw->fc.current_mode) {
    336	case igc_fc_none:
    337		/* Flow control (Rx & Tx) is completely disabled by a
    338		 * software over-ride.
    339		 */
    340		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
    341		break;
    342	case igc_fc_rx_pause:
    343		/* Rx Flow control is enabled, and Tx Flow control is
    344		 * disabled, by a software over-ride.
    345		 *
    346		 * Since there really isn't a way to advertise that we are
    347		 * capable of Rx Pause ONLY, we will advertise that we
    348		 * support both symmetric and asymmetric Rx PAUSE.  Later
    349		 * (in igc_config_fc_after_link_up) we will disable the
    350		 * hw's ability to send PAUSE frames.
    351		 */
    352		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
    353		break;
    354	case igc_fc_tx_pause:
    355		/* Tx Flow control is enabled, and Rx Flow control is
    356		 * disabled, by a software over-ride.
    357		 */
    358		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
    359		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
    360		break;
    361	case igc_fc_full:
    362		/* Flow control (both Rx and Tx) is enabled by a software
    363		 * over-ride.
    364		 */
    365		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
    366		break;
    367	default:
    368		hw_dbg("Flow control param set incorrectly\n");
    369		return -IGC_ERR_CONFIG;
    370	}
    371
    372	ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
    373	if (ret_val)
    374		return ret_val;
    375
    376	hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
    377
    378	if (phy->autoneg_mask & ADVERTISE_1000_FULL)
    379		ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
    380					     mii_1000t_ctrl_reg);
    381
    382	if (phy->autoneg_mask & ADVERTISE_2500_FULL)
    383		ret_val = phy->ops.write_reg(hw,
    384					     (STANDARD_AN_REG_MASK <<
    385					     MMD_DEVADDR_SHIFT) |
    386					     ANEG_MULTIGBT_AN_CTRL,
    387					     aneg_multigbt_an_ctrl);
    388
    389	return ret_val;
    390}
    391
    392/**
    393 * igc_wait_autoneg - Wait for auto-neg completion
    394 * @hw: pointer to the HW structure
    395 *
    396 * Waits for auto-negotiation to complete or for the auto-negotiation time
    397 * limit to expire, which ever happens first.
    398 */
    399static s32 igc_wait_autoneg(struct igc_hw *hw)
    400{
    401	u16 i, phy_status;
    402	s32 ret_val = 0;
    403
    404	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
    405	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
    406		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
    407		if (ret_val)
    408			break;
    409		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
    410		if (ret_val)
    411			break;
    412		if (phy_status & MII_SR_AUTONEG_COMPLETE)
    413			break;
    414		msleep(100);
    415	}
    416
    417	/* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
    418	 * has completed.
    419	 */
    420	return ret_val;
    421}
    422
    423/**
    424 * igc_copper_link_autoneg - Setup/Enable autoneg for copper link
    425 * @hw: pointer to the HW structure
    426 *
    427 * Performs initial bounds checking on autoneg advertisement parameter, then
    428 * configure to advertise the full capability.  Setup the PHY to autoneg
    429 * and restart the negotiation process between the link partner.  If
    430 * autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
    431 */
    432static s32 igc_copper_link_autoneg(struct igc_hw *hw)
    433{
    434	struct igc_phy_info *phy = &hw->phy;
    435	u16 phy_ctrl;
    436	s32 ret_val;
    437
    438	/* Perform some bounds checking on the autoneg advertisement
    439	 * parameter.
    440	 */
    441	phy->autoneg_advertised &= phy->autoneg_mask;
    442
    443	/* If autoneg_advertised is zero, we assume it was not defaulted
    444	 * by the calling code so we set to advertise full capability.
    445	 */
    446	if (phy->autoneg_advertised == 0)
    447		phy->autoneg_advertised = phy->autoneg_mask;
    448
    449	hw_dbg("Reconfiguring auto-neg advertisement params\n");
    450	ret_val = igc_phy_setup_autoneg(hw);
    451	if (ret_val) {
    452		hw_dbg("Error Setting up Auto-Negotiation\n");
    453		goto out;
    454	}
    455	hw_dbg("Restarting Auto-Neg\n");
    456
    457	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
    458	 * the Auto Neg Restart bit in the PHY control register.
    459	 */
    460	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
    461	if (ret_val)
    462		goto out;
    463
    464	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
    465	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
    466	if (ret_val)
    467		goto out;
    468
    469	/* Does the user want to wait for Auto-Neg to complete here, or
    470	 * check at a later time (for example, callback routine).
    471	 */
    472	if (phy->autoneg_wait_to_complete) {
    473		ret_val = igc_wait_autoneg(hw);
    474		if (ret_val) {
    475			hw_dbg("Error while waiting for autoneg to complete\n");
    476			goto out;
    477		}
    478	}
    479
    480	hw->mac.get_link_status = true;
    481
    482out:
    483	return ret_val;
    484}
    485
    486/**
    487 * igc_setup_copper_link - Configure copper link settings
    488 * @hw: pointer to the HW structure
    489 *
    490 * Calls the appropriate function to configure the link for auto-neg or forced
    491 * speed and duplex.  Then we check for link, once link is established calls
    492 * to configure collision distance and flow control are called.  If link is
    493 * not established, we return -IGC_ERR_PHY (-2).
    494 */
    495s32 igc_setup_copper_link(struct igc_hw *hw)
    496{
    497	s32 ret_val = 0;
    498	bool link;
    499
    500	if (hw->mac.autoneg) {
    501		/* Setup autoneg and flow control advertisement and perform
    502		 * autonegotiation.
    503		 */
    504		ret_val = igc_copper_link_autoneg(hw);
    505		if (ret_val)
    506			goto out;
    507	} else {
    508		/* PHY will be set to 10H, 10F, 100H or 100F
    509		 * depending on user settings.
    510		 */
    511		hw_dbg("Forcing Speed and Duplex\n");
    512		ret_val = hw->phy.ops.force_speed_duplex(hw);
    513		if (ret_val) {
    514			hw_dbg("Error Forcing Speed and Duplex\n");
    515			goto out;
    516		}
    517	}
    518
    519	/* Check link status. Wait up to 100 microseconds for link to become
    520	 * valid.
    521	 */
    522	ret_val = igc_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link);
    523	if (ret_val)
    524		goto out;
    525
    526	if (link) {
    527		hw_dbg("Valid link established!!!\n");
    528		igc_config_collision_dist(hw);
    529		ret_val = igc_config_fc_after_link_up(hw);
    530	} else {
    531		hw_dbg("Unable to establish link!!!\n");
    532	}
    533
    534out:
    535	return ret_val;
    536}
    537
    538/**
    539 * igc_read_phy_reg_mdic - Read MDI control register
    540 * @hw: pointer to the HW structure
    541 * @offset: register offset to be read
    542 * @data: pointer to the read data
    543 *
    544 * Reads the MDI control register in the PHY at offset and stores the
    545 * information read to data.
    546 */
    547static s32 igc_read_phy_reg_mdic(struct igc_hw *hw, u32 offset, u16 *data)
    548{
    549	struct igc_phy_info *phy = &hw->phy;
    550	u32 i, mdic = 0;
    551	s32 ret_val = 0;
    552
    553	if (offset > MAX_PHY_REG_ADDRESS) {
    554		hw_dbg("PHY Address %d is out of range\n", offset);
    555		ret_val = -IGC_ERR_PARAM;
    556		goto out;
    557	}
    558
    559	/* Set up Op-code, Phy Address, and register offset in the MDI
    560	 * Control register.  The MAC will take care of interfacing with the
    561	 * PHY to retrieve the desired data.
    562	 */
    563	mdic = ((offset << IGC_MDIC_REG_SHIFT) |
    564		(phy->addr << IGC_MDIC_PHY_SHIFT) |
    565		(IGC_MDIC_OP_READ));
    566
    567	wr32(IGC_MDIC, mdic);
    568
    569	/* Poll the ready bit to see if the MDI read completed
    570	 * Increasing the time out as testing showed failures with
    571	 * the lower time out
    572	 */
    573	for (i = 0; i < IGC_GEN_POLL_TIMEOUT; i++) {
    574		udelay(50);
    575		mdic = rd32(IGC_MDIC);
    576		if (mdic & IGC_MDIC_READY)
    577			break;
    578	}
    579	if (!(mdic & IGC_MDIC_READY)) {
    580		hw_dbg("MDI Read did not complete\n");
    581		ret_val = -IGC_ERR_PHY;
    582		goto out;
    583	}
    584	if (mdic & IGC_MDIC_ERROR) {
    585		hw_dbg("MDI Error\n");
    586		ret_val = -IGC_ERR_PHY;
    587		goto out;
    588	}
    589	*data = (u16)mdic;
    590
    591out:
    592	return ret_val;
    593}
    594
    595/**
    596 * igc_write_phy_reg_mdic - Write MDI control register
    597 * @hw: pointer to the HW structure
    598 * @offset: register offset to write to
    599 * @data: data to write to register at offset
    600 *
    601 * Writes data to MDI control register in the PHY at offset.
    602 */
    603static s32 igc_write_phy_reg_mdic(struct igc_hw *hw, u32 offset, u16 data)
    604{
    605	struct igc_phy_info *phy = &hw->phy;
    606	u32 i, mdic = 0;
    607	s32 ret_val = 0;
    608
    609	if (offset > MAX_PHY_REG_ADDRESS) {
    610		hw_dbg("PHY Address %d is out of range\n", offset);
    611		ret_val = -IGC_ERR_PARAM;
    612		goto out;
    613	}
    614
    615	/* Set up Op-code, Phy Address, and register offset in the MDI
    616	 * Control register.  The MAC will take care of interfacing with the
    617	 * PHY to write the desired data.
    618	 */
    619	mdic = (((u32)data) |
    620		(offset << IGC_MDIC_REG_SHIFT) |
    621		(phy->addr << IGC_MDIC_PHY_SHIFT) |
    622		(IGC_MDIC_OP_WRITE));
    623
    624	wr32(IGC_MDIC, mdic);
    625
    626	/* Poll the ready bit to see if the MDI read completed
    627	 * Increasing the time out as testing showed failures with
    628	 * the lower time out
    629	 */
    630	for (i = 0; i < IGC_GEN_POLL_TIMEOUT; i++) {
    631		udelay(50);
    632		mdic = rd32(IGC_MDIC);
    633		if (mdic & IGC_MDIC_READY)
    634			break;
    635	}
    636	if (!(mdic & IGC_MDIC_READY)) {
    637		hw_dbg("MDI Write did not complete\n");
    638		ret_val = -IGC_ERR_PHY;
    639		goto out;
    640	}
    641	if (mdic & IGC_MDIC_ERROR) {
    642		hw_dbg("MDI Error\n");
    643		ret_val = -IGC_ERR_PHY;
    644		goto out;
    645	}
    646
    647out:
    648	return ret_val;
    649}
    650
    651/**
    652 * __igc_access_xmdio_reg - Read/write XMDIO register
    653 * @hw: pointer to the HW structure
    654 * @address: XMDIO address to program
    655 * @dev_addr: device address to program
    656 * @data: pointer to value to read/write from/to the XMDIO address
    657 * @read: boolean flag to indicate read or write
    658 */
    659static s32 __igc_access_xmdio_reg(struct igc_hw *hw, u16 address,
    660				  u8 dev_addr, u16 *data, bool read)
    661{
    662	s32 ret_val;
    663
    664	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, dev_addr);
    665	if (ret_val)
    666		return ret_val;
    667
    668	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, address);
    669	if (ret_val)
    670		return ret_val;
    671
    672	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, IGC_MMDAC_FUNC_DATA |
    673					dev_addr);
    674	if (ret_val)
    675		return ret_val;
    676
    677	if (read)
    678		ret_val = hw->phy.ops.read_reg(hw, IGC_MMDAAD, data);
    679	else
    680		ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, *data);
    681	if (ret_val)
    682		return ret_val;
    683
    684	/* Recalibrate the device back to 0 */
    685	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, 0);
    686	if (ret_val)
    687		return ret_val;
    688
    689	return ret_val;
    690}
    691
    692/**
    693 * igc_read_xmdio_reg - Read XMDIO register
    694 * @hw: pointer to the HW structure
    695 * @addr: XMDIO address to program
    696 * @dev_addr: device address to program
    697 * @data: value to be read from the EMI address
    698 */
    699static s32 igc_read_xmdio_reg(struct igc_hw *hw, u16 addr,
    700			      u8 dev_addr, u16 *data)
    701{
    702	return __igc_access_xmdio_reg(hw, addr, dev_addr, data, true);
    703}
    704
    705/**
    706 * igc_write_xmdio_reg - Write XMDIO register
    707 * @hw: pointer to the HW structure
    708 * @addr: XMDIO address to program
    709 * @dev_addr: device address to program
    710 * @data: value to be written to the XMDIO address
    711 */
    712static s32 igc_write_xmdio_reg(struct igc_hw *hw, u16 addr,
    713			       u8 dev_addr, u16 data)
    714{
    715	return __igc_access_xmdio_reg(hw, addr, dev_addr, &data, false);
    716}
    717
    718/**
    719 * igc_write_phy_reg_gpy - Write GPY PHY register
    720 * @hw: pointer to the HW structure
    721 * @offset: register offset to write to
    722 * @data: data to write at register offset
    723 *
    724 * Acquires semaphore, if necessary, then writes the data to PHY register
    725 * at the offset. Release any acquired semaphores before exiting.
    726 */
    727s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data)
    728{
    729	u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
    730	s32 ret_val;
    731
    732	offset = offset & GPY_REG_MASK;
    733
    734	if (!dev_addr) {
    735		ret_val = hw->phy.ops.acquire(hw);
    736		if (ret_val)
    737			return ret_val;
    738		ret_val = igc_write_phy_reg_mdic(hw, offset, data);
    739		hw->phy.ops.release(hw);
    740	} else {
    741		ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr,
    742					      data);
    743	}
    744
    745	return ret_val;
    746}
    747
    748/**
    749 * igc_read_phy_reg_gpy - Read GPY PHY register
    750 * @hw: pointer to the HW structure
    751 * @offset: lower half is register offset to read to
    752 * upper half is MMD to use.
    753 * @data: data to read at register offset
    754 *
    755 * Acquires semaphore, if necessary, then reads the data in the PHY register
    756 * at the offset. Release any acquired semaphores before exiting.
    757 */
    758s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data)
    759{
    760	u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
    761	s32 ret_val;
    762
    763	offset = offset & GPY_REG_MASK;
    764
    765	if (!dev_addr) {
    766		ret_val = hw->phy.ops.acquire(hw);
    767		if (ret_val)
    768			return ret_val;
    769		ret_val = igc_read_phy_reg_mdic(hw, offset, data);
    770		hw->phy.ops.release(hw);
    771	} else {
    772		ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr,
    773					     data);
    774	}
    775
    776	return ret_val;
    777}
    778
    779/**
    780 * igc_read_phy_fw_version - Read gPHY firmware version
    781 * @hw: pointer to the HW structure
    782 */
    783u16 igc_read_phy_fw_version(struct igc_hw *hw)
    784{
    785	struct igc_phy_info *phy = &hw->phy;
    786	u16 gphy_version = 0;
    787	u16 ret_val;
    788
    789	/* NVM image version is reported as firmware version for i225 device */
    790	ret_val = phy->ops.read_reg(hw, IGC_GPHY_VERSION, &gphy_version);
    791	if (ret_val)
    792		hw_dbg("igc_phy: read wrong gphy version\n");
    793
    794	return gphy_version;
    795}