|
@@ -39,14 +39,39 @@ static inline long bnx2x_hilo(u32 *hiref)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-static u16 bnx2x_get_port_stats_dma_len(struct bnx2x *bp)
|
|
|
+static inline u16 bnx2x_get_port_stats_dma_len(struct bnx2x *bp)
|
|
|
{
|
|
|
- u16 res = sizeof(struct host_port_stats) >> 2;
|
|
|
+ u16 res = 0;
|
|
|
|
|
|
- /* if PFC stats are not supported by the MFW, don't DMA them */
|
|
|
- if (!(bp->flags & BC_SUPPORTS_PFC_STATS))
|
|
|
- res -= (sizeof(u32)*4) >> 2;
|
|
|
+ /* 'newest' convention - shmem2 cotains the size of the port stats */
|
|
|
+ if (SHMEM2_HAS(bp, sizeof_port_stats)) {
|
|
|
+ u32 size = SHMEM2_RD(bp, sizeof_port_stats);
|
|
|
+ if (size)
|
|
|
+ res = size;
|
|
|
|
|
|
+ /* prevent newer BC from causing buffer overflow */
|
|
|
+ if (res > sizeof(struct host_port_stats))
|
|
|
+ res = sizeof(struct host_port_stats);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Older convention - all BCs support the port stats' fields up until
|
|
|
+ * the 'not_used' field
|
|
|
+ */
|
|
|
+ if (!res) {
|
|
|
+ res = offsetof(struct host_port_stats, not_used) + 4;
|
|
|
+
|
|
|
+ /* if PFC stats are supported by the MFW, DMA them as well */
|
|
|
+ if (bp->flags & BC_SUPPORTS_PFC_STATS) {
|
|
|
+ res += offsetof(struct host_port_stats,
|
|
|
+ pfc_frames_rx_lo) -
|
|
|
+ offsetof(struct host_port_stats,
|
|
|
+ pfc_frames_tx_hi) + 4 ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ res >>= 2;
|
|
|
+
|
|
|
+ WARN_ON(res > 2 * DMAE_LEN32_RD_MAX);
|
|
|
return res;
|
|
|
}
|
|
|
|