Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  lan966x_ethtool.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0+

#include <linux/netdevice.h>

#include "lan966x_main.h"

/* Number of traffic classes */
#define LAN966X_NUM_TC   8
#define LAN966X_STATS_CHECK_DELAY (2 * HZ)

static const struct lan966x_stat_layout lan966x_stats_layout[] = {
 { .name = "rx_octets", .offset = 0x00, },
 { .name = "rx_unicast", .offset = 0x01, },
 { .name = "rx_multicast", .offset = 0x02 },
 { .name = "rx_broadcast", .offset = 0x03 },
 { .name = "rx_short", .offset = 0x04 },
 { .name = "rx_frag", .offset = 0x05 },
 { .name = "rx_jabber", .offset = 0x06 },
 { .name = "rx_crc", .offset = 0x07 },
 { .name = "rx_symbol_err", .offset = 0x08 },
 { .name = "rx_sz_64", .offset = 0x09 },
 { .name = "rx_sz_65_127", .offset = 0x0a},
 { .name = "rx_sz_128_255", .offset = 0x0b},
 { .name = "rx_sz_256_511", .offset = 0x0c },
 { .name = "rx_sz_512_1023", .offset = 0x0d },
 { .name = "rx_sz_1024_1526", .offset = 0x0e },
 { .name = "rx_sz_jumbo", .offset = 0x0f },
 { .name = "rx_pause", .offset = 0x10 },
 { .name = "rx_control", .offset = 0x11 },
 { .name = "rx_long", .offset = 0x12 },
 { .name = "rx_cat_drop", .offset = 0x13 },
 { .name = "rx_red_prio_0", .offset = 0x14 },
 { .name = "rx_red_prio_1", .offset = 0x15 },
 { .name = "rx_red_prio_2", .offset = 0x16 },
 { .name = "rx_red_prio_3", .offset = 0x17 },
 { .name = "rx_red_prio_4", .offset = 0x18 },
 { .name = "rx_red_prio_5", .offset = 0x19 },
 { .name = "rx_red_prio_6", .offset = 0x1a },
 { .name = "rx_red_prio_7", .offset = 0x1b },
 { .name = "rx_yellow_prio_0", .offset = 0x1c },
 { .name = "rx_yellow_prio_1", .offset = 0x1d },
 { .name = "rx_yellow_prio_2", .offset = 0x1e },
 { .name = "rx_yellow_prio_3", .offset = 0x1f },
 { .name = "rx_yellow_prio_4", .offset = 0x20 },
 { .name = "rx_yellow_prio_5", .offset = 0x21 },
 { .name = "rx_yellow_prio_6", .offset = 0x22 },
 { .name = "rx_yellow_prio_7", .offset = 0x23 },
 { .name = "rx_green_prio_0", .offset = 0x24 },
 { .name = "rx_green_prio_1", .offset = 0x25 },
 { .name = "rx_green_prio_2", .offset = 0x26 },
 { .name = "rx_green_prio_3", .offset = 0x27 },
 { .name = "rx_green_prio_4", .offset = 0x28 },
 { .name = "rx_green_prio_5", .offset = 0x29 },
 { .name = "rx_green_prio_6", .offset = 0x2a },
 { .name = "rx_green_prio_7", .offset = 0x2b },
 { .name = "rx_assembly_err", .offset = 0x2c },
 { .name = "rx_smd_err", .offset = 0x2d },
 { .name = "rx_assembly_ok", .offset = 0x2e },
 { .name = "rx_merge_frag", .offset = 0x2f },
 { .name = "rx_pmac_octets", .offset = 0x30, },
 { .name = "rx_pmac_unicast", .offset = 0x31, },
 { .name = "rx_pmac_multicast", .offset = 0x32 },
 { .name = "rx_pmac_broadcast", .offset = 0x33 },
 { .name = "rx_pmac_short", .offset = 0x34 },
 { .name = "rx_pmac_frag", .offset = 0x35 },
 { .name = "rx_pmac_jabber", .offset = 0x36 },
 { .name = "rx_pmac_crc", .offset = 0x37 },
 { .name = "rx_pmac_symbol_err", .offset = 0x38 },
 { .name = "rx_pmac_sz_64", .offset = 0x39 },
 { .name = "rx_pmac_sz_65_127", .offset = 0x3a },
 { .name = "rx_pmac_sz_128_255", .offset = 0x3b },
 { .name = "rx_pmac_sz_256_511", .offset = 0x3c },
 { .name = "rx_pmac_sz_512_1023", .offset = 0x3d },
 { .name = "rx_pmac_sz_1024_1526", .offset = 0x3e },
 { .name = "rx_pmac_sz_jumbo", .offset = 0x3f },
 { .name = "rx_pmac_pause", .offset = 0x40 },
 { .name = "rx_pmac_control", .offset = 0x41 },
 { .name = "rx_pmac_long", .offset = 0x42 },

 { .name = "tx_octets", .offset = 0x80, },
 { .name = "tx_unicast", .offset = 0x81, },
 { .name = "tx_multicast", .offset = 0x82 },
 { .name = "tx_broadcast", .offset = 0x83 },
 { .name = "tx_col", .offset = 0x84 },
 { .name = "tx_drop", .offset = 0x85 },
 { .name = "tx_pause", .offset = 0x86 },
 { .name = "tx_sz_64", .offset = 0x87 },
 { .name = "tx_sz_65_127", .offset = 0x88 },
 { .name = "tx_sz_128_255", .offset = 0x89 },
 { .name = "tx_sz_256_511", .offset = 0x8a },
 { .name = "tx_sz_512_1023", .offset = 0x8b },
 { .name = "tx_sz_1024_1526", .offset = 0x8c },
 { .name = "tx_sz_jumbo", .offset = 0x8d },
 { .name = "tx_yellow_prio_0", .offset = 0x8e },
 { .name = "tx_yellow_prio_1", .offset = 0x8f },
 { .name = "tx_yellow_prio_2", .offset = 0x90 },
 { .name = "tx_yellow_prio_3", .offset = 0x91 },
 { .name = "tx_yellow_prio_4", .offset = 0x92 },
 { .name = "tx_yellow_prio_5", .offset = 0x93 },
 { .name = "tx_yellow_prio_6", .offset = 0x94 },
 { .name = "tx_yellow_prio_7", .offset = 0x95 },
 { .name = "tx_green_prio_0", .offset = 0x96 },
 { .name = "tx_green_prio_1", .offset = 0x97 },
 { .name = "tx_green_prio_2", .offset = 0x98 },
 { .name = "tx_green_prio_3", .offset = 0x99 },
 { .name = "tx_green_prio_4", .offset = 0x9a },
 { .name = "tx_green_prio_5", .offset = 0x9b },
 { .name = "tx_green_prio_6", .offset = 0x9c },
 { .name = "tx_green_prio_7", .offset = 0x9d },
 { .name = "tx_aged", .offset = 0x9e },
 { .name = "tx_llct", .offset = 0x9f },
 { .name = "tx_ct", .offset = 0xa0 },
 { .name = "tx_mm_hold", .offset = 0xa1 },
 { .name = "tx_merge_frag", .offset = 0xa2 },
 { .name = "tx_pmac_octets", .offset = 0xa3, },
 { .name = "tx_pmac_unicast", .offset = 0xa4, },
 { .name = "tx_pmac_multicast", .offset = 0xa5 },
 { .name = "tx_pmac_broadcast", .offset = 0xa6 },
 { .name = "tx_pmac_pause", .offset = 0xa7 },
 { .name = "tx_pmac_sz_64", .offset = 0xa8 },
 { .name = "tx_pmac_sz_65_127", .offset = 0xa9 },
 { .name = "tx_pmac_sz_128_255", .offset = 0xaa },
 { .name = "tx_pmac_sz_256_511", .offset = 0xab },
 { .name = "tx_pmac_sz_512_1023", .offset = 0xac },
 { .name = "tx_pmac_sz_1024_1526", .offset = 0xad },
 { .name = "tx_pmac_sz_jumbo", .offset = 0xae },

 { .name = "dr_local", .offset = 0x100 },
 { .name = "dr_tail", .offset = 0x101 },
 { .name = "dr_yellow_prio_0", .offset = 0x102 },
 { .name = "dr_yellow_prio_1", .offset = 0x103 },
 { .name = "dr_yellow_prio_2", .offset = 0x104 },
 { .name = "dr_yellow_prio_3", .offset = 0x105 },
 { .name = "dr_yellow_prio_4", .offset = 0x106 },
 { .name = "dr_yellow_prio_5", .offset = 0x107 },
 { .name = "dr_yellow_prio_6", .offset = 0x108 },
 { .name = "dr_yellow_prio_7", .offset = 0x109 },
 { .name = "dr_green_prio_0", .offset = 0x10a },
 { .name = "dr_green_prio_1", .offset = 0x10b },
 { .name = "dr_green_prio_2", .offset = 0x10c },
 { .name = "dr_green_prio_3", .offset = 0x10d },
 { .name = "dr_green_prio_4", .offset = 0x10e },
 { .name = "dr_green_prio_5", .offset = 0x10f },
 { .name = "dr_green_prio_6", .offset = 0x110 },
 { .name = "dr_green_prio_7", .offset = 0x111 },
};

/* The following numbers are indexes into lan966x_stats_layout[] */
#define SYS_COUNT_RX_OCT    0
#define SYS_COUNT_RX_UC     1
#define SYS_COUNT_RX_MC     2
#define SYS_COUNT_RX_BC     3
#define SYS_COUNT_RX_SHORT    4
#define SYS_COUNT_RX_FRAG    5
#define SYS_COUNT_RX_JABBER    6
#define SYS_COUNT_RX_CRC    7
#define SYS_COUNT_RX_SYMBOL_ERR    8
#define SYS_COUNT_RX_SZ_64    9
#define SYS_COUNT_RX_SZ_65_127   10
#define SYS_COUNT_RX_SZ_128_255   11
#define SYS_COUNT_RX_SZ_256_511   12
#define SYS_COUNT_RX_SZ_512_1023  13
#define SYS_COUNT_RX_SZ_1024_1526  14
#define SYS_COUNT_RX_SZ_JUMBO   15
#define SYS_COUNT_RX_PAUSE   16
#define SYS_COUNT_RX_CONTROL   17
#define SYS_COUNT_RX_LONG   18
#define SYS_COUNT_RX_CAT_DROP   19
#define SYS_COUNT_RX_RED_PRIO_0   20
#define SYS_COUNT_RX_RED_PRIO_1   21
#define SYS_COUNT_RX_RED_PRIO_2   22
#define SYS_COUNT_RX_RED_PRIO_3   23
#define SYS_COUNT_RX_RED_PRIO_4   24
#define SYS_COUNT_RX_RED_PRIO_5   25
#define SYS_COUNT_RX_RED_PRIO_6   26
#define SYS_COUNT_RX_RED_PRIO_7   27
#define SYS_COUNT_RX_YELLOW_PRIO_0  28
#define SYS_COUNT_RX_YELLOW_PRIO_1  29
#define SYS_COUNT_RX_YELLOW_PRIO_2  30
#define SYS_COUNT_RX_YELLOW_PRIO_3  31
#define SYS_COUNT_RX_YELLOW_PRIO_4  32
#define SYS_COUNT_RX_YELLOW_PRIO_5  33
#define SYS_COUNT_RX_YELLOW_PRIO_6  34
#define SYS_COUNT_RX_YELLOW_PRIO_7  35
#define SYS_COUNT_RX_GREEN_PRIO_0  36
#define SYS_COUNT_RX_GREEN_PRIO_1  37
#define SYS_COUNT_RX_GREEN_PRIO_2  38
#define SYS_COUNT_RX_GREEN_PRIO_3  39
#define SYS_COUNT_RX_GREEN_PRIO_4  40
#define SYS_COUNT_RX_GREEN_PRIO_5  41
#define SYS_COUNT_RX_GREEN_PRIO_6  42
#define SYS_COUNT_RX_GREEN_PRIO_7  43
#define SYS_COUNT_RX_ASSEMBLY_ERR  44
#define SYS_COUNT_RX_SMD_ERR   45
#define SYS_COUNT_RX_ASSEMBLY_OK  46
#define SYS_COUNT_RX_MERGE_FRAG   47
#define SYS_COUNT_RX_PMAC_OCT   48
#define SYS_COUNT_RX_PMAC_UC   49
#define SYS_COUNT_RX_PMAC_MC   50
#define SYS_COUNT_RX_PMAC_BC   51
#define SYS_COUNT_RX_PMAC_SHORT   52
#define SYS_COUNT_RX_PMAC_FRAG   53
#define SYS_COUNT_RX_PMAC_JABBER  54
#define SYS_COUNT_RX_PMAC_CRC   55
#define SYS_COUNT_RX_PMAC_SYMBOL_ERR  56
#define SYS_COUNT_RX_PMAC_SZ_64   57
#define SYS_COUNT_RX_PMAC_SZ_65_127  58
#define SYS_COUNT_RX_PMAC_SZ_128_255  59
#define SYS_COUNT_RX_PMAC_SZ_256_511  60
#define SYS_COUNT_RX_PMAC_SZ_512_1023  61
#define SYS_COUNT_RX_PMAC_SZ_1024_1526  62
#define SYS_COUNT_RX_PMAC_SZ_JUMBO  63
#define SYS_COUNT_RX_PMAC_PAUSE   64
#define SYS_COUNT_RX_PMAC_CONTROL  65
#define SYS_COUNT_RX_PMAC_LONG   66

#define SYS_COUNT_TX_OCT   67
#define SYS_COUNT_TX_UC    68
#define SYS_COUNT_TX_MC    69
#define SYS_COUNT_TX_BC    70
#define SYS_COUNT_TX_COL   71
#define SYS_COUNT_TX_DROP   72
#define SYS_COUNT_TX_PAUSE   73
#define SYS_COUNT_TX_SZ_64   74
#define SYS_COUNT_TX_SZ_65_127   75
#define SYS_COUNT_TX_SZ_128_255   76
#define SYS_COUNT_TX_SZ_256_511   77
#define SYS_COUNT_TX_SZ_512_1023  78
#define SYS_COUNT_TX_SZ_1024_1526  79
#define SYS_COUNT_TX_SZ_JUMBO   80
#define SYS_COUNT_TX_YELLOW_PRIO_0  81
#define SYS_COUNT_TX_YELLOW_PRIO_1  82
#define SYS_COUNT_TX_YELLOW_PRIO_2  83
#define SYS_COUNT_TX_YELLOW_PRIO_3  84
#define SYS_COUNT_TX_YELLOW_PRIO_4  85
#define SYS_COUNT_TX_YELLOW_PRIO_5  86
#define SYS_COUNT_TX_YELLOW_PRIO_6  87
#define SYS_COUNT_TX_YELLOW_PRIO_7  88
#define SYS_COUNT_TX_GREEN_PRIO_0  89
#define SYS_COUNT_TX_GREEN_PRIO_1  90
#define SYS_COUNT_TX_GREEN_PRIO_2  91
#define SYS_COUNT_TX_GREEN_PRIO_3  92
#define SYS_COUNT_TX_GREEN_PRIO_4  93
#define SYS_COUNT_TX_GREEN_PRIO_5  94
#define SYS_COUNT_TX_GREEN_PRIO_6  95
#define SYS_COUNT_TX_GREEN_PRIO_7  96
#define SYS_COUNT_TX_AGED   97
#define SYS_COUNT_TX_LLCT   98
#define SYS_COUNT_TX_CT    99
#define SYS_COUNT_TX_MM_HOLD  100
#define SYS_COUNT_TX_MERGE_FRAG  101
#define SYS_COUNT_TX_PMAC_OCT  102
#define SYS_COUNT_TX_PMAC_UC  103
#define SYS_COUNT_TX_PMAC_MC  104
#define SYS_COUNT_TX_PMAC_BC  105
#define SYS_COUNT_TX_PMAC_PAUSE  106
#define SYS_COUNT_TX_PMAC_SZ_64  107
#define SYS_COUNT_TX_PMAC_SZ_65_127 108
#define SYS_COUNT_TX_PMAC_SZ_128_255 109
#define SYS_COUNT_TX_PMAC_SZ_256_511 110
#define SYS_COUNT_TX_PMAC_SZ_512_1023 111
#define SYS_COUNT_TX_PMAC_SZ_1024_1526 112
#define SYS_COUNT_TX_PMAC_SZ_JUMBO 113

#define SYS_COUNT_DR_LOCAL  114
#define SYS_COUNT_DR_TAIL  115
#define SYS_COUNT_DR_YELLOW_PRIO_0 116
#define SYS_COUNT_DR_YELLOW_PRIO_1 117
#define SYS_COUNT_DR_YELLOW_PRIO_2 118
#define SYS_COUNT_DR_YELLOW_PRIO_3 119
#define SYS_COUNT_DR_YELLOW_PRIO_4 120
#define SYS_COUNT_DR_YELLOW_PRIO_5 121
#define SYS_COUNT_DR_YELLOW_PRIO_6 122
#define SYS_COUNT_DR_YELLOW_PRIO_7 123
#define SYS_COUNT_DR_GREEN_PRIO_0 124
#define SYS_COUNT_DR_GREEN_PRIO_1 125
#define SYS_COUNT_DR_GREEN_PRIO_2 126
#define SYS_COUNT_DR_GREEN_PRIO_3 127
#define SYS_COUNT_DR_GREEN_PRIO_4 128
#define SYS_COUNT_DR_GREEN_PRIO_5 129
#define SYS_COUNT_DR_GREEN_PRIO_6 130
#define SYS_COUNT_DR_GREEN_PRIO_7 131

/* Add a possibly wrapping 32 bit value to a 64 bit counter */
static void lan966x_add_cnt(u64 *cnt, u32 val)
{
 if (val < (*cnt & U32_MAX))
  *cnt += (u64)1 << 32; /* value has wrapped */

 *cnt = (*cnt & ~(u64)U32_MAX) + val;
}

static void lan966x_stats_update(struct lan966x *lan966x)
{
 int i, j;

 spin_lock(&lan966x->stats_lock);

 for (i = 0; i < lan966x->num_phys_ports; i++) {
  uint idx = i * lan966x->num_stats;

  lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(i),
         lan966x, SYS_STAT_CFG);

  for (j = 0; j < lan966x->num_stats; j++) {
   u32 offset = lan966x->stats_layout[j].offset;

   lan966x_add_cnt(&lan966x->stats[idx++],
     lan_rd(lan966x, SYS_CNT(offset)));
  }
 }

 spin_unlock(&lan966x->stats_lock);
}

static int lan966x_get_sset_count(struct net_device *dev, int sset)
{
 struct lan966x_port *port = netdev_priv(dev);
 struct lan966x *lan966x = port->lan966x;

 if (sset != ETH_SS_STATS)
  return -EOPNOTSUPP;

 return lan966x->num_stats;
}

static void lan966x_get_strings(struct net_device *netdev, u32 sset, u8 *data)
{
 struct lan966x_port *port = netdev_priv(netdev);
 struct lan966x *lan966x = port->lan966x;
 int i;

 if (sset != ETH_SS_STATS)
  return;

 for (i = 0; i < lan966x->num_stats; i++)
  memcpy(data + i * ETH_GSTRING_LEN,
         lan966x->stats_layout[i].name, ETH_GSTRING_LEN);
}

static void lan966x_get_ethtool_stats(struct net_device *dev,
          struct ethtool_stats *stats, u64 *data)
{
 struct lan966x_port *port = netdev_priv(dev);
 struct lan966x *lan966x = port->lan966x;
 int i;

 /* check and update now */
 lan966x_stats_update(lan966x);

 /* Copy all counters */
 for (i = 0; i < lan966x->num_stats; i++)
  *data++ = lan966x->stats[port->chip_port *
      lan966x->num_stats + i];
}

static void lan966x_get_eth_mac_stats(struct net_device *dev,
          struct ethtool_eth_mac_stats *mac_stats)
{
 struct lan966x_port *port = netdev_priv(dev);
 struct lan966x *lan966x = port->lan966x;
 u32 idx;

 lan966x_stats_update(lan966x);

 idx = port->chip_port * lan966x->num_stats;

 spin_lock(&lan966x->stats_lock);

 mac_stats->FramesTransmittedOK =
  lan966x->stats[idx + SYS_COUNT_TX_UC] +
  lan966x->stats[idx + SYS_COUNT_TX_MC] +
  lan966x->stats[idx + SYS_COUNT_TX_BC] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_UC] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
 mac_stats->SingleCollisionFrames =
  lan966x->stats[idx + SYS_COUNT_TX_COL];
 mac_stats->FramesReceivedOK =
  lan966x->stats[idx + SYS_COUNT_RX_UC] +
  lan966x->stats[idx + SYS_COUNT_RX_MC] +
  lan966x->stats[idx + SYS_COUNT_RX_BC];
 mac_stats->FrameCheckSequenceErrors =
  lan966x->stats[idx + SYS_COUNT_RX_CRC] +
  lan966x->stats[idx + SYS_COUNT_RX_CRC];
 mac_stats->OctetsTransmittedOK =
  lan966x->stats[idx + SYS_COUNT_TX_OCT] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
 mac_stats->FramesWithDeferredXmissions =
  lan966x->stats[idx + SYS_COUNT_TX_MM_HOLD];
 mac_stats->OctetsReceivedOK =
  lan966x->stats[idx + SYS_COUNT_RX_OCT];
 mac_stats->MulticastFramesXmittedOK =
  lan966x->stats[idx + SYS_COUNT_TX_MC] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC];
 mac_stats->BroadcastFramesXmittedOK =
  lan966x->stats[idx + SYS_COUNT_TX_BC] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
 mac_stats->MulticastFramesReceivedOK =
  lan966x->stats[idx + SYS_COUNT_RX_MC];
 mac_stats->BroadcastFramesReceivedOK =
  lan966x->stats[idx + SYS_COUNT_RX_BC];
 mac_stats->InRangeLengthErrors =
  lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
  lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
  lan966x->stats[idx + SYS_COUNT_RX_CRC] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_CRC];
 mac_stats->OutOfRangeLengthField =
  lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
  lan966x->stats[idx + SYS_COUNT_RX_LONG] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
 mac_stats->FrameTooLongErrors =
  lan966x->stats[idx + SYS_COUNT_RX_LONG] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];

 spin_unlock(&lan966x->stats_lock);
}

static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {
 {    0,    64 },
 {   65,   127 },
 {  128,   255 },
 {  256,   511 },
 {  512,  1023 },
 { 1024,  1518 },
 { 1519, 10239 },
 {}
};

static void lan966x_get_eth_rmon_stats(struct net_device *dev,
           struct ethtool_rmon_stats *rmon_stats,
           const struct ethtool_rmon_hist_range **ranges)
{
 struct lan966x_port *port = netdev_priv(dev);
 struct lan966x *lan966x = port->lan966x;
 u32 idx;

 lan966x_stats_update(lan966x);

 idx = port->chip_port * lan966x->num_stats;

 spin_lock(&lan966x->stats_lock);

 rmon_stats->undersize_pkts =
  lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT];
 rmon_stats->oversize_pkts =
  lan966x->stats[idx + SYS_COUNT_RX_LONG] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
 rmon_stats->fragments =
  lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG];
 rmon_stats->jabbers =
  lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER];
 rmon_stats->hist[0] =
  lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64];
 rmon_stats->hist[1] =
  lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127];
 rmon_stats->hist[2] =
  lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255];
 rmon_stats->hist[3] =
  lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511];
 rmon_stats->hist[4] =
  lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023];
 rmon_stats->hist[5] =
  lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
 rmon_stats->hist[6] =
  lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];

 rmon_stats->hist_tx[0] =
  lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64];
 rmon_stats->hist_tx[1] =
  lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127];
 rmon_stats->hist_tx[2] =
  lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255];
 rmon_stats->hist_tx[3] =
  lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511];
 rmon_stats->hist_tx[4] =
  lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023];
 rmon_stats->hist_tx[5] =
  lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
 rmon_stats->hist_tx[6] =
  lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];

 spin_unlock(&lan966x->stats_lock);

 *ranges = lan966x_rmon_ranges;
}

static int lan966x_get_link_ksettings(struct net_device *ndev,
          struct ethtool_link_ksettings *cmd)
{
 struct lan966x_port *port = netdev_priv(ndev);

 return phylink_ethtool_ksettings_get(port->phylink, cmd);
}

static int lan966x_set_link_ksettings(struct net_device *ndev,
          const struct ethtool_link_ksettings *cmd)
{
 struct lan966x_port *port = netdev_priv(ndev);

 return phylink_ethtool_ksettings_set(port->phylink, cmd);
}

static void lan966x_get_pauseparam(struct net_device *dev,
       struct ethtool_pauseparam *pause)
{
 struct lan966x_port *port = netdev_priv(dev);

 phylink_ethtool_get_pauseparam(port->phylink, pause);
}

static int lan966x_set_pauseparam(struct net_device *dev,
      struct ethtool_pauseparam *pause)
{
 struct lan966x_port *port = netdev_priv(dev);

 return phylink_ethtool_set_pauseparam(port->phylink, pause);
}

static int lan966x_get_ts_info(struct net_device *dev,
          struct kernel_ethtool_ts_info *info)
{
 struct lan966x_port *port = netdev_priv(dev);
 struct lan966x *lan966x = port->lan966x;
 struct lan966x_phc *phc;

 if (!lan966x->ptp)
  return ethtool_op_get_ts_info(dev, info);

 phc = &lan966x->phc[LAN966X_PHC_PORT];

 if (phc->clock) {
  info->phc_index = ptp_clock_index(phc->clock);
 } else {
  info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;
  return 0;
 }
 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
     SOF_TIMESTAMPING_TX_HARDWARE |
     SOF_TIMESTAMPING_RX_HARDWARE |
     SOF_TIMESTAMPING_RAW_HARDWARE;
 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
    BIT(HWTSTAMP_TX_ONESTEP_SYNC);
 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
      BIT(HWTSTAMP_FILTER_ALL);

 return 0;
}

const struct ethtool_ops lan966x_ethtool_ops = {
 .get_link_ksettings     = lan966x_get_link_ksettings,
 .set_link_ksettings     = lan966x_set_link_ksettings,
 .get_pauseparam  = lan966x_get_pauseparam,
 .set_pauseparam  = lan966x_set_pauseparam,
 .get_sset_count  = lan966x_get_sset_count,
 .get_strings  = lan966x_get_strings,
 .get_ethtool_stats = lan966x_get_ethtool_stats,
 .get_eth_mac_stats      = lan966x_get_eth_mac_stats,
 .get_rmon_stats  = lan966x_get_eth_rmon_stats,
 .get_link  = ethtool_op_get_link,
 .get_ts_info  = lan966x_get_ts_info,
};

static void lan966x_check_stats_work(struct work_struct *work)
{
 struct delayed_work *del_work = to_delayed_work(work);
 struct lan966x *lan966x = container_of(del_work, struct lan966x,
            stats_work);

 lan966x_stats_update(lan966x);

 queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
      LAN966X_STATS_CHECK_DELAY);
}

void lan966x_stats_get(struct net_device *dev,
         struct rtnl_link_stats64 *stats)
{
 struct lan966x_port *port = netdev_priv(dev);
 struct lan966x *lan966x = port->lan966x;
 u32 idx;
 int i;

 idx = port->chip_port * lan966x->num_stats;

 spin_lock(&lan966x->stats_lock);

 stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT];

 stats->rx_packets = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
  lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
  lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
  lan966x->stats[idx + SYS_COUNT_RX_CRC] +
  lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
  lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
  lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
  lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
  lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
  lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
  lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_RX_SZ_JUMBO] +
  lan966x->stats[idx + SYS_COUNT_RX_LONG] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_JUMBO];

 stats->multicast = lan966x->stats[idx + SYS_COUNT_RX_MC] +
  lan966x->stats[idx + SYS_COUNT_RX_PMAC_MC];

 stats->rx_errors = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
  lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
  lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
  lan966x->stats[idx + SYS_COUNT_RX_CRC] +
  lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
  lan966x->stats[idx + SYS_COUNT_RX_LONG];

 stats->rx_dropped = dev->stats.rx_dropped +
  lan966x->stats[idx + SYS_COUNT_RX_LONG] +
  lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
  lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
  lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];

 for (i = 0; i < LAN966X_NUM_TC; i++) {
  stats->rx_dropped +=
   (lan966x->stats[idx + SYS_COUNT_DR_YELLOW_PRIO_0 + i] +
    lan966x->stats[idx + SYS_COUNT_DR_GREEN_PRIO_0 + i]);
 }

 /* Get Tx stats */
 stats->tx_bytes = lan966x->stats[idx + SYS_COUNT_TX_OCT] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];

 stats->tx_packets = lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
  lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
  lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
  lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
  lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
  lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_TX_SZ_JUMBO] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526] +
  lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_JUMBO];

 stats->tx_dropped = lan966x->stats[idx + SYS_COUNT_TX_DROP] +
  lan966x->stats[idx + SYS_COUNT_TX_AGED];

 stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL];

 spin_unlock(&lan966x->stats_lock);
}

int lan966x_stats_init(struct lan966x *lan966x)
{
 char queue_name[32];

 lan966x->stats_layout = lan966x_stats_layout;
 lan966x->num_stats = ARRAY_SIZE(lan966x_stats_layout);
 lan966x->stats = devm_kcalloc(lan966x->dev, lan966x->num_phys_ports *
          lan966x->num_stats,
          sizeof(u64), GFP_KERNEL);
 if (!lan966x->stats)
  return -ENOMEM;

 /* Init stats worker */
 spin_lock_init(&lan966x->stats_lock);
 snprintf(queue_name, sizeof(queue_name), "%s-stats",
   dev_name(lan966x->dev));
 lan966x->stats_queue = create_singlethread_workqueue(queue_name);
 if (!lan966x->stats_queue)
  return -ENOMEM;

 INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);
 queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
      LAN966X_STATS_CHECK_DELAY);

 return 0;
}

Messung V0.5
C=87 H=92 G=89

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge