Skip to content

Commit 1adb156

Browse files
lcieplixanguy11
authored andcommitted
i40e: Fix dropped jumbo frames statistics
Dropped packets caused by too large frames were not included in dropped RX packets statistics. Issue was caused by not reading the GL_RXERR1 register. That register stores count of packet which was have been dropped due to too large size. Fix it by reading GL_RXERR1 register for each interface. Repro steps: Send a packet larger than the set MTU to SUT Observe rx statists: ethtool -S <interface> | grep rx | grep -v ": 0" Fixes: 41a9e55 ("i40e: add missing VSI statistics") Signed-off-by: Lukasz Cieplicki <[email protected]> Signed-off-by: Jedrzej Jagielski <[email protected]> Tested-by: Gurucharan <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]>
1 parent 58bf4db commit 1adb156

File tree

4 files changed

+103
-0
lines changed

4 files changed

+103
-0
lines changed

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <net/tc_act/tc_mirred.h>
3838
#include <net/udp_tunnel.h>
3939
#include <net/xdp_sock.h>
40+
#include <linux/bitfield.h>
4041
#include "i40e_type.h"
4142
#include "i40e_prototype.h"
4243
#include <linux/net/intel/i40e_client.h>
@@ -1092,6 +1093,21 @@ static inline void i40e_write_fd_input_set(struct i40e_pf *pf,
10921093
(u32)(val & 0xFFFFFFFFULL));
10931094
}
10941095

1096+
/**
1097+
* i40e_get_pf_count - get PCI PF count.
1098+
* @hw: pointer to a hw.
1099+
*
1100+
* Reports the function number of the highest PCI physical
1101+
* function plus 1 as it is loaded from the NVM.
1102+
*
1103+
* Return: PCI PF count.
1104+
**/
1105+
static inline u32 i40e_get_pf_count(struct i40e_hw *hw)
1106+
{
1107+
return FIELD_GET(I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK,
1108+
rd32(hw, I40E_GLGEN_PCIFCNCNT));
1109+
}
1110+
10951111
/* needed by i40e_ethtool.c */
10961112
int i40e_up(struct i40e_vsi *vsi);
10971113
void i40e_down(struct i40e_vsi *vsi);

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,47 @@ void i40e_pf_reset_stats(struct i40e_pf *pf)
550550
pf->hw_csum_rx_error = 0;
551551
}
552552

553+
/**
554+
* i40e_compute_pci_to_hw_id - compute index form PCI function.
555+
* @vsi: ptr to the VSI to read from.
556+
* @hw: ptr to the hardware info.
557+
**/
558+
static u32 i40e_compute_pci_to_hw_id(struct i40e_vsi *vsi, struct i40e_hw *hw)
559+
{
560+
int pf_count = i40e_get_pf_count(hw);
561+
562+
if (vsi->type == I40E_VSI_SRIOV)
563+
return (hw->port * BIT(7)) / pf_count + vsi->vf_id;
564+
565+
return hw->port + BIT(7);
566+
}
567+
568+
/**
569+
* i40e_stat_update64 - read and update a 64 bit stat from the chip.
570+
* @hw: ptr to the hardware info.
571+
* @hireg: the high 32 bit reg to read.
572+
* @loreg: the low 32 bit reg to read.
573+
* @offset_loaded: has the initial offset been loaded yet.
574+
* @offset: ptr to current offset value.
575+
* @stat: ptr to the stat.
576+
*
577+
* Since the device stats are not reset at PFReset, they will not
578+
* be zeroed when the driver starts. We'll save the first values read
579+
* and use them as offsets to be subtracted from the raw values in order
580+
* to report stats that count from zero.
581+
**/
582+
static void i40e_stat_update64(struct i40e_hw *hw, u32 hireg, u32 loreg,
583+
bool offset_loaded, u64 *offset, u64 *stat)
584+
{
585+
u64 new_data;
586+
587+
new_data = rd64(hw, loreg);
588+
589+
if (!offset_loaded || new_data < *offset)
590+
*offset = new_data;
591+
*stat = new_data - *offset;
592+
}
593+
553594
/**
554595
* i40e_stat_update48 - read and update a 48 bit stat from the chip
555596
* @hw: ptr to the hardware info
@@ -621,6 +662,34 @@ static void i40e_stat_update_and_clear32(struct i40e_hw *hw, u32 reg, u64 *stat)
621662
*stat += new_data;
622663
}
623664

665+
/**
666+
* i40e_stats_update_rx_discards - update rx_discards.
667+
* @vsi: ptr to the VSI to be updated.
668+
* @hw: ptr to the hardware info.
669+
* @stat_idx: VSI's stat_counter_idx.
670+
* @offset_loaded: ptr to the VSI's stat_offsets_loaded.
671+
* @stat_offset: ptr to stat_offset to store first read of specific register.
672+
* @stat: ptr to VSI's stat to be updated.
673+
**/
674+
static void
675+
i40e_stats_update_rx_discards(struct i40e_vsi *vsi, struct i40e_hw *hw,
676+
int stat_idx, bool offset_loaded,
677+
struct i40e_eth_stats *stat_offset,
678+
struct i40e_eth_stats *stat)
679+
{
680+
u64 rx_rdpc, rx_rxerr;
681+
682+
i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), offset_loaded,
683+
&stat_offset->rx_discards, &rx_rdpc);
684+
i40e_stat_update64(hw,
685+
I40E_GL_RXERR1H(i40e_compute_pci_to_hw_id(vsi, hw)),
686+
I40E_GL_RXERR1L(i40e_compute_pci_to_hw_id(vsi, hw)),
687+
offset_loaded, &stat_offset->rx_discards_other,
688+
&rx_rxerr);
689+
690+
stat->rx_discards = rx_rdpc + rx_rxerr;
691+
}
692+
624693
/**
625694
* i40e_update_eth_stats - Update VSI-specific ethernet statistics counters.
626695
* @vsi: the VSI to be updated
@@ -680,6 +749,10 @@ void i40e_update_eth_stats(struct i40e_vsi *vsi)
680749
I40E_GLV_BPTCL(stat_idx),
681750
vsi->stat_offsets_loaded,
682751
&oes->tx_broadcast, &es->tx_broadcast);
752+
753+
i40e_stats_update_rx_discards(vsi, hw, stat_idx,
754+
vsi->stat_offsets_loaded, oes, es);
755+
683756
vsi->stat_offsets_loaded = true;
684757
}
685758

drivers/net/ethernet/intel/i40e/i40e_register.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@
211211
#define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0
212212
#define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16
213213
#define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
214+
#define I40E_GLGEN_PCIFCNCNT 0x001C0AB4 /* Reset: PCIR */
215+
#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0
216+
#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
217+
#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16
218+
#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
214219
#define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */
215220
#define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0
216221
#define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
@@ -643,6 +648,14 @@
643648
#define I40E_VFQF_HKEY1_MAX_INDEX 12
644649
#define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */
645650
#define I40E_VFQF_HLUT1_MAX_INDEX 15
651+
#define I40E_GL_RXERR1H(_i) (0x00318004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
652+
#define I40E_GL_RXERR1H_MAX_INDEX 143
653+
#define I40E_GL_RXERR1H_RXERR1H_SHIFT 0
654+
#define I40E_GL_RXERR1H_RXERR1H_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1H_RXERR1H_SHIFT)
655+
#define I40E_GL_RXERR1L(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
656+
#define I40E_GL_RXERR1L_MAX_INDEX 143
657+
#define I40E_GL_RXERR1L_RXERR1L_SHIFT 0
658+
#define I40E_GL_RXERR1L_RXERR1L_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1L_RXERR1L_SHIFT)
646659
#define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
647660
#define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
648661
#define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */

drivers/net/ethernet/intel/i40e/i40e_type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,7 @@ struct i40e_eth_stats {
11721172
u64 tx_broadcast; /* bptc */
11731173
u64 tx_discards; /* tdpc */
11741174
u64 tx_errors; /* tepc */
1175+
u64 rx_discards_other; /* rxerr1 */
11751176
};
11761177

11771178
/* Statistics collected per VEB per TC */

0 commit comments

Comments
 (0)