diff options
Diffstat (limited to 'drivers/net/atl1c/atl1c_hw.c')
-rw-r--r-- | drivers/net/atl1c/atl1c_hw.c | 83 |
1 files changed, 71 insertions, 12 deletions
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c index 3e69b940b8f..f1389d664a2 100644 --- a/drivers/net/atl1c/atl1c_hw.c +++ b/drivers/net/atl1c/atl1c_hw.c | |||
@@ -70,17 +70,39 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) | |||
70 | u32 otp_ctrl_data; | 70 | u32 otp_ctrl_data; |
71 | u32 twsi_ctrl_data; | 71 | u32 twsi_ctrl_data; |
72 | u8 eth_addr[ETH_ALEN]; | 72 | u8 eth_addr[ETH_ALEN]; |
73 | u16 phy_data; | ||
74 | bool raise_vol = false; | ||
73 | 75 | ||
74 | /* init */ | 76 | /* init */ |
75 | addr[0] = addr[1] = 0; | 77 | addr[0] = addr[1] = 0; |
76 | AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); | 78 | AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); |
77 | if (atl1c_check_eeprom_exist(hw)) { | 79 | if (atl1c_check_eeprom_exist(hw)) { |
78 | /* Enable OTP CLK */ | 80 | if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) { |
79 | if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) { | 81 | /* Enable OTP CLK */ |
80 | otp_ctrl_data |= OTP_CTRL_CLK_EN; | 82 | if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) { |
81 | AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); | 83 | otp_ctrl_data |= OTP_CTRL_CLK_EN; |
82 | AT_WRITE_FLUSH(hw); | 84 | AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); |
83 | msleep(1); | 85 | AT_WRITE_FLUSH(hw); |
86 | msleep(1); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | if (hw->nic_type == athr_l2c_b || | ||
91 | hw->nic_type == athr_l2c_b2 || | ||
92 | hw->nic_type == athr_l1d) { | ||
93 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00); | ||
94 | if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data)) | ||
95 | goto out; | ||
96 | phy_data &= 0xFF7F; | ||
97 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data); | ||
98 | |||
99 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B); | ||
100 | if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data)) | ||
101 | goto out; | ||
102 | phy_data |= 0x8; | ||
103 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data); | ||
104 | udelay(20); | ||
105 | raise_vol = true; | ||
84 | } | 106 | } |
85 | 107 | ||
86 | AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); | 108 | AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); |
@@ -96,11 +118,31 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) | |||
96 | return -1; | 118 | return -1; |
97 | } | 119 | } |
98 | /* Disable OTP_CLK */ | 120 | /* Disable OTP_CLK */ |
99 | if (otp_ctrl_data & OTP_CTRL_CLK_EN) { | 121 | if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) { |
100 | otp_ctrl_data &= ~OTP_CTRL_CLK_EN; | 122 | if (otp_ctrl_data & OTP_CTRL_CLK_EN) { |
101 | AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); | 123 | otp_ctrl_data &= ~OTP_CTRL_CLK_EN; |
102 | AT_WRITE_FLUSH(hw); | 124 | AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); |
103 | msleep(1); | 125 | AT_WRITE_FLUSH(hw); |
126 | msleep(1); | ||
127 | } | ||
128 | } | ||
129 | if (raise_vol) { | ||
130 | if (hw->nic_type == athr_l2c_b || | ||
131 | hw->nic_type == athr_l2c_b2 || | ||
132 | hw->nic_type == athr_l1d) { | ||
133 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00); | ||
134 | if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data)) | ||
135 | goto out; | ||
136 | phy_data |= 0x80; | ||
137 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data); | ||
138 | |||
139 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B); | ||
140 | if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data)) | ||
141 | goto out; | ||
142 | phy_data &= 0xFFF7; | ||
143 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data); | ||
144 | udelay(20); | ||
145 | } | ||
104 | } | 146 | } |
105 | 147 | ||
106 | /* maybe MAC-address is from BIOS */ | 148 | /* maybe MAC-address is from BIOS */ |
@@ -114,6 +156,7 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) | |||
114 | return 0; | 156 | return 0; |
115 | } | 157 | } |
116 | 158 | ||
159 | out: | ||
117 | return -1; | 160 | return -1; |
118 | } | 161 | } |
119 | 162 | ||
@@ -307,7 +350,7 @@ static int atl1c_phy_setup_adv(struct atl1c_hw *hw) | |||
307 | mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL | | 350 | mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL | |
308 | ADVERTISE_100HALF | ADVERTISE_100FULL; | 351 | ADVERTISE_100HALF | ADVERTISE_100FULL; |
309 | 352 | ||
310 | if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) { | 353 | if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) { |
311 | if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half) | 354 | if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half) |
312 | mii_giga_ctrl_data |= ADVERTISE_1000HALF; | 355 | mii_giga_ctrl_data |= ADVERTISE_1000HALF; |
313 | if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full) | 356 | if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full) |
@@ -389,6 +432,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw) | |||
389 | { | 432 | { |
390 | struct atl1c_adapter *adapter = hw->adapter; | 433 | struct atl1c_adapter *adapter = hw->adapter; |
391 | struct pci_dev *pdev = adapter->pdev; | 434 | struct pci_dev *pdev = adapter->pdev; |
435 | u16 phy_data; | ||
392 | u32 phy_ctrl_data = GPHY_CTRL_DEFAULT; | 436 | u32 phy_ctrl_data = GPHY_CTRL_DEFAULT; |
393 | u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN; | 437 | u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN; |
394 | int err; | 438 | int err; |
@@ -404,6 +448,21 @@ int atl1c_phy_reset(struct atl1c_hw *hw) | |||
404 | AT_WRITE_FLUSH(hw); | 448 | AT_WRITE_FLUSH(hw); |
405 | msleep(10); | 449 | msleep(10); |
406 | 450 | ||
451 | if (hw->nic_type == athr_l2c_b) { | ||
452 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x0A); | ||
453 | atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data); | ||
454 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xDFFF); | ||
455 | } | ||
456 | |||
457 | if (hw->nic_type == athr_l2c_b || | ||
458 | hw->nic_type == athr_l2c_b2 || | ||
459 | hw->nic_type == athr_l1d) { | ||
460 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B); | ||
461 | atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data); | ||
462 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7); | ||
463 | msleep(20); | ||
464 | } | ||
465 | |||
407 | /*Enable PHY LinkChange Interrupt */ | 466 | /*Enable PHY LinkChange Interrupt */ |
408 | err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data); | 467 | err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data); |
409 | if (err) { | 468 | if (err) { |