#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); }