Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 170431
b: refs/heads/master
c: bf6f7a9
h: refs/heads/master
i:
  170429: 5a0fbb8
  170427: 97f8a84
  170423: cbd53da
  170415: d30e7a0
  170399: 79fe305
  170367: 84777e6
v: v3
  • Loading branch information
Alexander Duyck authored and David S. Miller committed Oct 6, 2009
1 parent c938dce commit fea1266
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 66 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 008c3422d48b217792789bdea822dbc2efe2165c
refs/heads/master: bf6f7a928d313ddecb0a16ea60fa6b45ac1414a7
85 changes: 20 additions & 65 deletions trunk/drivers/net/igb/e1000_82575.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,45 +277,23 @@ static void igb_release_phy_82575(struct e1000_hw *hw)
static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 *data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, i2ccmd = 0;
s32 ret_val = -E1000_ERR_PARAM;

if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
hw_dbg("PHY Address %u is out of range\n", offset);
return -E1000_ERR_PARAM;
goto out;
}

/*
* Set up Op-code, Phy Address, and register address in the I2CCMD
* register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
(phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
(E1000_I2CCMD_OPCODE_READ));
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;

wr32(E1000_I2CCMD, i2ccmd);
ret_val = igb_read_phy_reg_i2c(hw, offset, data);

/* Poll the ready bit to see if the I2C read completed */
for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
udelay(50);
i2ccmd = rd32(E1000_I2CCMD);
if (i2ccmd & E1000_I2CCMD_READY)
break;
}
if (!(i2ccmd & E1000_I2CCMD_READY)) {
hw_dbg("I2CCMD Read did not complete\n");
return -E1000_ERR_PHY;
}
if (i2ccmd & E1000_I2CCMD_ERROR) {
hw_dbg("I2CCMD Error bit set\n");
return -E1000_ERR_PHY;
}

/* Need to byte-swap the 16-bit value. */
*data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
hw->phy.ops.release(hw);

return 0;
out:
return ret_val;
}

/**
Expand All @@ -330,47 +308,24 @@ static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, i2ccmd = 0;
u16 phy_data_swapped;
s32 ret_val = -E1000_ERR_PARAM;


if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
hw_dbg("PHY Address %d is out of range\n", offset);
return -E1000_ERR_PARAM;
goto out;
}

/* Swap the data bytes for the I2C interface */
phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;

/*
* Set up Op-code, Phy Address, and register address in the I2CCMD
* register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
(phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
E1000_I2CCMD_OPCODE_WRITE |
phy_data_swapped);

wr32(E1000_I2CCMD, i2ccmd);

/* Poll the ready bit to see if the I2C read completed */
for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
udelay(50);
i2ccmd = rd32(E1000_I2CCMD);
if (i2ccmd & E1000_I2CCMD_READY)
break;
}
if (!(i2ccmd & E1000_I2CCMD_READY)) {
hw_dbg("I2CCMD Write did not complete\n");
return -E1000_ERR_PHY;
}
if (i2ccmd & E1000_I2CCMD_ERROR) {
hw_dbg("I2CCMD Error bit set\n");
return -E1000_ERR_PHY;
}
ret_val = igb_write_phy_reg_i2c(hw, offset, data);

return 0;
hw->phy.ops.release(hw);

out:
return ret_val;
}

/**
Expand Down
97 changes: 97 additions & 0 deletions trunk/drivers/net/igb/e1000_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,103 @@ static s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
return ret_val;
}

/**
* igb_read_phy_reg_i2c - Read PHY register using i2c
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
*
* Reads the PHY register at offset using the i2c interface and stores the
* retrieved information in data.
**/
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, i2ccmd = 0;


/*
* Set up Op-code, Phy Address, and register address in the I2CCMD
* register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
(phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
(E1000_I2CCMD_OPCODE_READ));

wr32(E1000_I2CCMD, i2ccmd);

/* Poll the ready bit to see if the I2C read completed */
for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
udelay(50);
i2ccmd = rd32(E1000_I2CCMD);
if (i2ccmd & E1000_I2CCMD_READY)
break;
}
if (!(i2ccmd & E1000_I2CCMD_READY)) {
hw_dbg("I2CCMD Read did not complete\n");
return -E1000_ERR_PHY;
}
if (i2ccmd & E1000_I2CCMD_ERROR) {
hw_dbg("I2CCMD Error bit set\n");
return -E1000_ERR_PHY;
}

/* Need to byte-swap the 16-bit value. */
*data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);

return 0;
}

/**
* igb_write_phy_reg_i2c - Write PHY register using i2c
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
*
* Writes the data to PHY register at the offset using the i2c interface.
**/
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, i2ccmd = 0;
u16 phy_data_swapped;


/* Swap the data bytes for the I2C interface */
phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);

/*
* Set up Op-code, Phy Address, and register address in the I2CCMD
* register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
(phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
E1000_I2CCMD_OPCODE_WRITE |
phy_data_swapped);

wr32(E1000_I2CCMD, i2ccmd);

/* Poll the ready bit to see if the I2C read completed */
for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
udelay(50);
i2ccmd = rd32(E1000_I2CCMD);
if (i2ccmd & E1000_I2CCMD_READY)
break;
}
if (!(i2ccmd & E1000_I2CCMD_READY)) {
hw_dbg("I2CCMD Write did not complete\n");
return -E1000_ERR_PHY;
}
if (i2ccmd & E1000_I2CCMD_ERROR) {
hw_dbg("I2CCMD Error bit set\n");
return -E1000_ERR_PHY;
}

return 0;
}

/**
* igb_read_phy_reg_igp - Read igp PHY register
* @hw: pointer to the HW structure
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/igb/e1000_phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);

/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
Expand Down

0 comments on commit fea1266

Please sign in to comment.