aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/e1000e/netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/netdev.c')
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c66
1 files changed, 39 insertions, 27 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 02f443958f31..7017281ba2dc 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -4303,6 +4303,42 @@ void e1000e_reinit_locked(struct e1000_adapter *adapter)
4303} 4303}
4304 4304
4305/** 4305/**
4306 * e1000e_sanitize_systim - sanitize raw cycle counter reads
4307 * @hw: pointer to the HW structure
4308 * @systim: cycle_t value read, sanitized and returned
4309 *
4310 * Errata for 82574/82583 possible bad bits read from SYSTIMH/L:
4311 * check to see that the time is incrementing at a reasonable
4312 * rate and is a multiple of incvalue.
4313 **/
4314static cycle_t e1000e_sanitize_systim(struct e1000_hw *hw, cycle_t systim)
4315{
4316 u64 time_delta, rem, temp;
4317 cycle_t systim_next;
4318 u32 incvalue;
4319 int i;
4320
4321 incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
4322 for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
4323 /* latch SYSTIMH on read of SYSTIML */
4324 systim_next = (cycle_t)er32(SYSTIML);
4325 systim_next |= (cycle_t)er32(SYSTIMH) << 32;
4326
4327 time_delta = systim_next - systim;
4328 temp = time_delta;
4329 /* VMWare users have seen incvalue of zero, don't div / 0 */
4330 rem = incvalue ? do_div(temp, incvalue) : (time_delta != 0);
4331
4332 systim = systim_next;
4333
4334 if ((time_delta < E1000_82574_SYSTIM_EPSILON) && (rem == 0))
4335 break;
4336 }
4337
4338 return systim;
4339}
4340
4341/**
4306 * e1000e_cyclecounter_read - read raw cycle counter (used by time counter) 4342 * e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
4307 * @cc: cyclecounter structure 4343 * @cc: cyclecounter structure
4308 **/ 4344 **/
@@ -4312,7 +4348,7 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
4312 cc); 4348 cc);
4313 struct e1000_hw *hw = &adapter->hw; 4349 struct e1000_hw *hw = &adapter->hw;
4314 u32 systimel, systimeh; 4350 u32 systimel, systimeh;
4315 cycle_t systim, systim_next; 4351 cycle_t systim;
4316 /* SYSTIMH latching upon SYSTIML read does not work well. 4352 /* SYSTIMH latching upon SYSTIML read does not work well.
4317 * This means that if SYSTIML overflows after we read it but before 4353 * This means that if SYSTIML overflows after we read it but before
4318 * we read SYSTIMH, the value of SYSTIMH has been incremented and we 4354 * we read SYSTIMH, the value of SYSTIMH has been incremented and we
@@ -4335,33 +4371,9 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
4335 systim = (cycle_t)systimel; 4371 systim = (cycle_t)systimel;
4336 systim |= (cycle_t)systimeh << 32; 4372 systim |= (cycle_t)systimeh << 32;
4337 4373
4338 if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) { 4374 if (adapter->flags2 & FLAG2_CHECK_SYSTIM_OVERFLOW)
4339 u64 time_delta, rem, temp; 4375 systim = e1000e_sanitize_systim(hw, systim);
4340 u32 incvalue;
4341 int i;
4342
4343 /* errata for 82574/82583 possible bad bits read from SYSTIMH/L
4344 * check to see that the time is incrementing at a reasonable
4345 * rate and is a multiple of incvalue
4346 */
4347 incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
4348 for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
4349 /* latch SYSTIMH on read of SYSTIML */
4350 systim_next = (cycle_t)er32(SYSTIML);
4351 systim_next |= (cycle_t)er32(SYSTIMH) << 32;
4352
4353 time_delta = systim_next - systim;
4354 temp = time_delta;
4355 /* VMWare users have seen incvalue of zero, don't div / 0 */
4356 rem = incvalue ? do_div(temp, incvalue) : (time_delta != 0);
4357
4358 systim = systim_next;
4359 4376
4360 if ((time_delta < E1000_82574_SYSTIM_EPSILON) &&
4361 (rem == 0))
4362 break;
4363 }
4364 }
4365 return systim; 4377 return systim;
4366} 4378}
4367 4379