@@ -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
0 commit comments