#include "fbnic.h"
u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset)
{
u32 prev_upper, upper, lower, diff;
prev_upper = rd32(fbd, reg + offset);
lower = rd32(fbd, reg);
upper = rd32(fbd, reg + offset);
diff = upper - prev_upper;
if (!diff)
return ((u64)upper << 32) | lower;
if (diff > 1)
dev_warn_once(fbd->dev,
"Stats inconsistent, upper 32b of %#010x updating too quickly\n",
reg * 4);
/* Return only the upper bits as we cannot guarantee
* the accuracy of the lower bits. We will add them in
* when the counter slows down enough that we can get
* a snapshot with both upper values being the same
* between reads.
*/
return ((u64)upper << 32);
}