diff options
Diffstat (limited to 'drivers/net/sfc/sfe4001.c')
-rw-r--r-- | drivers/net/sfc/sfe4001.c | 116 |
1 files changed, 53 insertions, 63 deletions
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index fe4e3fd22330..aa576c559ec8 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "falcon_hwdefs.h" | 21 | #include "falcon_hwdefs.h" |
22 | #include "falcon_io.h" | 22 | #include "falcon_io.h" |
23 | #include "mac.h" | 23 | #include "mac.h" |
24 | #include "workarounds.h" | ||
24 | 25 | ||
25 | /************************************************************************** | 26 | /************************************************************************** |
26 | * | 27 | * |
@@ -65,48 +66,9 @@ | |||
65 | #define P1_SPARE_LBN 4 | 66 | #define P1_SPARE_LBN 4 |
66 | #define P1_SPARE_WIDTH 4 | 67 | #define P1_SPARE_WIDTH 4 |
67 | 68 | ||
68 | 69 | /* Temperature Sensor */ | |
69 | /************************************************************************** | 70 | #define MAX664X_REG_RSL 0x02 |
70 | * | 71 | #define MAX664X_REG_WLHO 0x0B |
71 | * Temperature Sensor | ||
72 | * | ||
73 | **************************************************************************/ | ||
74 | #define MAX6647 0x4e | ||
75 | |||
76 | #define RLTS 0x00 | ||
77 | #define RLTE 0x01 | ||
78 | #define RSL 0x02 | ||
79 | #define RCL 0x03 | ||
80 | #define RCRA 0x04 | ||
81 | #define RLHN 0x05 | ||
82 | #define RLLI 0x06 | ||
83 | #define RRHI 0x07 | ||
84 | #define RRLS 0x08 | ||
85 | #define WCRW 0x0a | ||
86 | #define WLHO 0x0b | ||
87 | #define WRHA 0x0c | ||
88 | #define WRLN 0x0e | ||
89 | #define OSHT 0x0f | ||
90 | #define REET 0x10 | ||
91 | #define RIET 0x11 | ||
92 | #define RWOE 0x19 | ||
93 | #define RWOI 0x20 | ||
94 | #define HYS 0x21 | ||
95 | #define QUEUE 0x22 | ||
96 | #define MFID 0xfe | ||
97 | #define REVID 0xff | ||
98 | |||
99 | /* Status bits */ | ||
100 | #define MAX6647_BUSY (1 << 7) /* ADC is converting */ | ||
101 | #define MAX6647_LHIGH (1 << 6) /* Local high temp. alarm */ | ||
102 | #define MAX6647_LLOW (1 << 5) /* Local low temp. alarm */ | ||
103 | #define MAX6647_RHIGH (1 << 4) /* Remote high temp. alarm */ | ||
104 | #define MAX6647_RLOW (1 << 3) /* Remote low temp. alarm */ | ||
105 | #define MAX6647_FAULT (1 << 2) /* DXN/DXP short/open circuit */ | ||
106 | #define MAX6647_EOT (1 << 1) /* Remote junction overtemp. */ | ||
107 | #define MAX6647_IOT (1 << 0) /* Local junction overtemp. */ | ||
108 | |||
109 | static const u8 xgphy_max_temperature = 90; | ||
110 | 72 | ||
111 | static void sfe4001_poweroff(struct efx_nic *efx) | 73 | static void sfe4001_poweroff(struct efx_nic *efx) |
112 | { | 74 | { |
@@ -119,7 +81,7 @@ static void sfe4001_poweroff(struct efx_nic *efx) | |||
119 | i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); | 81 | i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); |
120 | 82 | ||
121 | /* Clear any over-temperature alert */ | 83 | /* Clear any over-temperature alert */ |
122 | i2c_smbus_read_byte_data(hwmon_client, RSL); | 84 | i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); |
123 | } | 85 | } |
124 | 86 | ||
125 | static int sfe4001_poweron(struct efx_nic *efx) | 87 | static int sfe4001_poweron(struct efx_nic *efx) |
@@ -131,7 +93,7 @@ static int sfe4001_poweron(struct efx_nic *efx) | |||
131 | u8 out; | 93 | u8 out; |
132 | 94 | ||
133 | /* Clear any previous over-temperature alert */ | 95 | /* Clear any previous over-temperature alert */ |
134 | rc = i2c_smbus_read_byte_data(hwmon_client, RSL); | 96 | rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); |
135 | if (rc < 0) | 97 | if (rc < 0) |
136 | return rc; | 98 | return rc; |
137 | 99 | ||
@@ -209,6 +171,34 @@ fail_on: | |||
209 | return rc; | 171 | return rc; |
210 | } | 172 | } |
211 | 173 | ||
174 | static int sfe4001_check_hw(struct efx_nic *efx) | ||
175 | { | ||
176 | s32 status; | ||
177 | |||
178 | /* If XAUI link is up then do not monitor */ | ||
179 | if (EFX_WORKAROUND_7884(efx) && falcon_xaui_link_ok(efx)) | ||
180 | return 0; | ||
181 | |||
182 | /* Check the powered status of the PHY. Lack of power implies that | ||
183 | * the MAX6647 has shut down power to it, probably due to a temp. | ||
184 | * alarm. Reading the power status rather than the MAX6647 status | ||
185 | * directly because the later is read-to-clear and would thus | ||
186 | * start to power up the PHY again when polled, causing us to blip | ||
187 | * the power undesirably. | ||
188 | * We know we can read from the IO expander because we did | ||
189 | * it during power-on. Assume failure now is bad news. */ | ||
190 | status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN); | ||
191 | if (status >= 0 && | ||
192 | (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0) | ||
193 | return 0; | ||
194 | |||
195 | /* Use board power control, not PHY power control */ | ||
196 | sfe4001_poweroff(efx); | ||
197 | efx->phy_mode = PHY_MODE_OFF; | ||
198 | |||
199 | return (status < 0) ? -EIO : -ERANGE; | ||
200 | } | ||
201 | |||
212 | /* On SFE4001 rev A2 and later, we can control the FLASH_CFG_1 pin | 202 | /* On SFE4001 rev A2 and later, we can control the FLASH_CFG_1 pin |
213 | * using the 3V3X output of the IO-expander. Allow the user to set | 203 | * using the 3V3X output of the IO-expander. Allow the user to set |
214 | * this when the device is stopped, and keep it stopped then. | 204 | * this when the device is stopped, and keep it stopped then. |
@@ -261,35 +251,34 @@ static void sfe4001_fini(struct efx_nic *efx) | |||
261 | i2c_unregister_device(efx->board_info.hwmon_client); | 251 | i2c_unregister_device(efx->board_info.hwmon_client); |
262 | } | 252 | } |
263 | 253 | ||
254 | static struct i2c_board_info sfe4001_hwmon_info = { | ||
255 | I2C_BOARD_INFO("max6647", 0x4e), | ||
256 | .irq = -1, | ||
257 | }; | ||
258 | |||
264 | /* This board uses an I2C expander to provider power to the PHY, which needs to | 259 | /* This board uses an I2C expander to provider power to the PHY, which needs to |
265 | * be turned on before the PHY can be used. | 260 | * be turned on before the PHY can be used. |
266 | * Context: Process context, rtnl lock held | 261 | * Context: Process context, rtnl lock held |
267 | */ | 262 | */ |
268 | int sfe4001_init(struct efx_nic *efx) | 263 | int sfe4001_init(struct efx_nic *efx) |
269 | { | 264 | { |
270 | struct i2c_client *hwmon_client; | ||
271 | int rc; | 265 | int rc; |
272 | 266 | ||
273 | hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647); | 267 | #if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE) |
274 | if (!hwmon_client) | 268 | efx->board_info.hwmon_client = |
269 | i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info); | ||
270 | #else | ||
271 | efx->board_info.hwmon_client = | ||
272 | i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr); | ||
273 | #endif | ||
274 | if (!efx->board_info.hwmon_client) | ||
275 | return -EIO; | 275 | return -EIO; |
276 | efx->board_info.hwmon_client = hwmon_client; | ||
277 | 276 | ||
278 | /* Set DSP over-temperature alert threshold */ | 277 | /* Raise board/PHY high limit from 85 to 90 degrees Celsius */ |
279 | EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature); | 278 | rc = i2c_smbus_write_byte_data(efx->board_info.hwmon_client, |
280 | rc = i2c_smbus_write_byte_data(hwmon_client, WLHO, | 279 | MAX664X_REG_WLHO, 90); |
281 | xgphy_max_temperature); | ||
282 | if (rc) | 280 | if (rc) |
283 | goto fail_ioexp; | 281 | goto fail_hwmon; |
284 | |||
285 | /* Read it back and verify */ | ||
286 | rc = i2c_smbus_read_byte_data(hwmon_client, RLHN); | ||
287 | if (rc < 0) | ||
288 | goto fail_ioexp; | ||
289 | if (rc != xgphy_max_temperature) { | ||
290 | rc = -EFAULT; | ||
291 | goto fail_ioexp; | ||
292 | } | ||
293 | 282 | ||
294 | efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539); | 283 | efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539); |
295 | if (!efx->board_info.ioexp_client) { | 284 | if (!efx->board_info.ioexp_client) { |
@@ -301,6 +290,7 @@ int sfe4001_init(struct efx_nic *efx) | |||
301 | * blink code. */ | 290 | * blink code. */ |
302 | efx->board_info.blink = tenxpress_phy_blink; | 291 | efx->board_info.blink = tenxpress_phy_blink; |
303 | 292 | ||
293 | efx->board_info.monitor = sfe4001_check_hw; | ||
304 | efx->board_info.fini = sfe4001_fini; | 294 | efx->board_info.fini = sfe4001_fini; |
305 | 295 | ||
306 | rc = sfe4001_poweron(efx); | 296 | rc = sfe4001_poweron(efx); |
@@ -319,6 +309,6 @@ fail_on: | |||
319 | fail_ioexp: | 309 | fail_ioexp: |
320 | i2c_unregister_device(efx->board_info.ioexp_client); | 310 | i2c_unregister_device(efx->board_info.ioexp_client); |
321 | fail_hwmon: | 311 | fail_hwmon: |
322 | i2c_unregister_device(hwmon_client); | 312 | i2c_unregister_device(efx->board_info.hwmon_client); |
323 | return rc; | 313 | return rc; |
324 | } | 314 | } |