Skip to content

Commit 51045ec

Browse files
Todd FujinakaJeff Kirsher
authored andcommitted
igb: add support for 1512 PHY
This patch adds support for Marvell PHY 1512 (required for I354). Submitted by: Maciej Szwed <[email protected]> Signed-off-by: Todd Fujinaka <[email protected]> Tested-by: Aaron Brown <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 30c7291 commit 51045ec

File tree

4 files changed

+114
-5
lines changed

4 files changed

+114
-5
lines changed

drivers/net/ethernet/intel/igb/e1000_82575.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
231231
/* Verify phy id and set remaining function pointers */
232232
switch (phy->id) {
233233
case M88E1543_E_PHY_ID:
234+
case M88E1512_E_PHY_ID:
234235
case I347AT4_E_PHY_ID:
235236
case M88E1112_E_PHY_ID:
236237
case M88E1111_I_PHY_ID:
@@ -243,7 +244,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
243244
else
244245
phy->ops.get_cable_length = igb_get_cable_length_m88;
245246
phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
246-
/* Check if this PHY is confgured for media swap. */
247+
/* Check if this PHY is configured for media swap. */
247248
if (phy->id == M88E1112_E_PHY_ID) {
248249
u16 data;
249250

@@ -266,6 +267,11 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
266267
hw->mac.ops.check_for_link =
267268
igb_check_for_link_media_swap;
268269
}
270+
if (phy->id == M88E1512_E_PHY_ID) {
271+
ret_val = igb_initialize_M88E1512_phy(hw);
272+
if (ret_val)
273+
goto out;
274+
}
269275
break;
270276
case IGP03E1000_E_PHY_ID:
271277
phy->type = e1000_phy_igp_3;
@@ -897,6 +903,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
897903
**/
898904
static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
899905
{
906+
struct e1000_phy_info *phy = &hw->phy;
900907
s32 ret_val;
901908

902909
/* This isn't a true "hard" reset, but is the only reset
@@ -913,7 +920,11 @@ static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
913920
goto out;
914921

915922
ret_val = igb_phy_sw_reset(hw);
923+
if (ret_val)
924+
goto out;
916925

926+
if (phy->id == M88E1512_E_PHY_ID)
927+
ret_val = igb_initialize_M88E1512_phy(hw);
917928
out:
918929
return ret_val;
919930
}
@@ -1587,6 +1598,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
15871598
case I347AT4_E_PHY_ID:
15881599
case M88E1112_E_PHY_ID:
15891600
case M88E1543_E_PHY_ID:
1601+
case M88E1512_E_PHY_ID:
15901602
case I210_I_PHY_ID:
15911603
ret_val = igb_copper_link_setup_m88_gen2(hw);
15921604
break;
@@ -2629,7 +2641,8 @@ s32 igb_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
26292641
u16 phy_data;
26302642

26312643
if ((hw->phy.media_type != e1000_media_type_copper) ||
2632-
(phy->id != M88E1543_E_PHY_ID))
2644+
((phy->id != M88E1543_E_PHY_ID) &&
2645+
(phy->id != M88E1512_E_PHY_ID)))
26332646
goto out;
26342647

26352648
if (!hw->dev_spec._82575.eee_disable) {
@@ -2709,7 +2722,8 @@ s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status)
27092722

27102723
/* Check if EEE is supported on this device. */
27112724
if ((hw->phy.media_type != e1000_media_type_copper) ||
2712-
(phy->id != M88E1543_E_PHY_ID))
2725+
((phy->id != M88E1543_E_PHY_ID) &&
2726+
(phy->id != M88E1512_E_PHY_ID)))
27132727
goto out;
27142728

27152729
ret_val = igb_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,

drivers/net/ethernet/intel/igb/e1000_defines.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,10 @@
604604
#define E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT 7
605605
#define E1000_M88E1112_PAGE_ADDR 0x16
606606
#define E1000_M88E1112_STATUS 0x01
607+
#define E1000_M88E1512_CFG_REG_1 0x0010
608+
#define E1000_M88E1512_CFG_REG_2 0x0011
609+
#define E1000_M88E1512_CFG_REG_3 0x0007
610+
#define E1000_M88E1512_MODE 0x0014
607611

608612
/* PCI Express Control */
609613
#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000
@@ -861,6 +865,7 @@
861865
#define M88_VENDOR 0x0141
862866
#define I210_I_PHY_ID 0x01410C00
863867
#define M88E1543_E_PHY_ID 0x01410EA0
868+
#define M88E1512_E_PHY_ID 0x01410DD0
864869

865870
/* M88E1000 Specific Registers */
866871
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */

drivers/net/ethernet/intel/igb/e1000_phy.c

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,8 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
12621262
switch (hw->phy.id) {
12631263
case I347AT4_E_PHY_ID:
12641264
case M88E1112_E_PHY_ID:
1265+
case M88E1543_E_PHY_ID:
1266+
case M88E1512_E_PHY_ID:
12651267
case I210_I_PHY_ID:
12661268
reset_dsp = false;
12671269
break;
@@ -1270,9 +1272,9 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
12701272
reset_dsp = false;
12711273
break;
12721274
}
1273-
if (!reset_dsp)
1275+
if (!reset_dsp) {
12741276
hw_dbg("Link taking longer than expected.\n");
1275-
else {
1277+
} else {
12761278
/* We didn't get link.
12771279
* Reset the DSP and cross our fingers.
12781280
*/
@@ -1297,6 +1299,8 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
12971299
if (hw->phy.type != e1000_phy_m88 ||
12981300
hw->phy.id == I347AT4_E_PHY_ID ||
12991301
hw->phy.id == M88E1112_E_PHY_ID ||
1302+
hw->phy.id == M88E1543_E_PHY_ID ||
1303+
hw->phy.id == M88E1512_E_PHY_ID ||
13001304
hw->phy.id == I210_I_PHY_ID)
13011305
goto out;
13021306

@@ -1737,6 +1741,7 @@ s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
17371741
phy->cable_length = phy_data / (is_cm ? 100 : 1);
17381742
break;
17391743
case M88E1543_E_PHY_ID:
1744+
case M88E1512_E_PHY_ID:
17401745
case I347AT4_E_PHY_ID:
17411746
/* Remember the original page select and set it to 7 */
17421747
ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
@@ -2188,6 +2193,90 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
21882193
return 0;
21892194
}
21902195

2196+
/**
2197+
* igb_initialize_M88E1512_phy - Initialize M88E1512 PHY
2198+
* @hw: pointer to the HW structure
2199+
*
2200+
* Initialize Marvel 1512 to work correctly with Avoton.
2201+
**/
2202+
s32 igb_initialize_M88E1512_phy(struct e1000_hw *hw)
2203+
{
2204+
struct e1000_phy_info *phy = &hw->phy;
2205+
s32 ret_val = 0;
2206+
2207+
/* Switch to PHY page 0xFF. */
2208+
ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
2209+
if (ret_val)
2210+
goto out;
2211+
2212+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
2213+
if (ret_val)
2214+
goto out;
2215+
2216+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
2217+
if (ret_val)
2218+
goto out;
2219+
2220+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
2221+
if (ret_val)
2222+
goto out;
2223+
2224+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
2225+
if (ret_val)
2226+
goto out;
2227+
2228+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
2229+
if (ret_val)
2230+
goto out;
2231+
2232+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
2233+
if (ret_val)
2234+
goto out;
2235+
2236+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
2237+
if (ret_val)
2238+
goto out;
2239+
2240+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
2241+
if (ret_val)
2242+
goto out;
2243+
2244+
/* Switch to PHY page 0xFB. */
2245+
ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
2246+
if (ret_val)
2247+
goto out;
2248+
2249+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
2250+
if (ret_val)
2251+
goto out;
2252+
2253+
/* Switch to PHY page 0x12. */
2254+
ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
2255+
if (ret_val)
2256+
goto out;
2257+
2258+
/* Change mode to SGMII-to-Copper */
2259+
ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
2260+
if (ret_val)
2261+
goto out;
2262+
2263+
/* Return the PHY to page 0. */
2264+
ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
2265+
if (ret_val)
2266+
goto out;
2267+
2268+
ret_val = igb_phy_sw_reset(hw);
2269+
if (ret_val) {
2270+
hw_dbg("Error committing the PHY changes\n");
2271+
return ret_val;
2272+
}
2273+
2274+
/* msec_delay(1000); */
2275+
usleep_range(1000, 2000);
2276+
out:
2277+
return ret_val;
2278+
}
2279+
21912280
/**
21922281
* igb_power_up_phy_copper - Restore copper link in case of PHY power down
21932282
* @hw: pointer to the HW structure

drivers/net/ethernet/intel/igb/e1000_phy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
6161
void igb_power_up_phy_copper(struct e1000_hw *hw);
6262
void igb_power_down_phy_copper(struct e1000_hw *hw);
6363
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
64+
s32 igb_initialize_M88E1512_phy(struct e1000_hw *hw);
6465
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
6566
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
6667
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);

0 commit comments

Comments
 (0)