]> Pileus Git - ~andy/linux/blobdiff - drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[~andy/linux] / drivers / net / ethernet / broadcom / bnx2x / bnx2x_stats.c
index a1d0446b39b356dd69e0b77e69f6285ba37edb63..348ed02d3c69928c3991d7c8de046ccf95c0a3c9 100644 (file)
@@ -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;
 }