Commit 0de45db8 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
parents f85cd6ae 550ee90a
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -278,6 +278,26 @@ patternProperties:

    additionalProperties: false

  ^pa-stats@[a-f0-9]+$:
    description: |
      PA-STATS sub-module represented as a SysCon. PA_STATS is a set of
      registers where different statistics related to ICSSG, are dumped by
      ICSSG firmware. This syscon sub-module will help the device to
      access/read/write those statistics.

    type: object

    additionalProperties: false

    properties:
      compatible:
        items:
          - const: ti,pruss-pa-st
          - const: syscon

      reg:
        maxItems: 1

  interrupt-controller@[a-f0-9]+$:
    description: |
      PRUSS INTC Node. Each PRUSS has a single interrupt controller instance
+10 −9
Original line number Diff line number Diff line
@@ -83,13 +83,11 @@ static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data)

	switch (stringset) {
	case ETH_SS_STATS:
		for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) {
			if (!icssg_all_stats[i].standard_stats) {
				memcpy(p, icssg_all_stats[i].name,
				       ETH_GSTRING_LEN);
				p += ETH_GSTRING_LEN;
			}
		}
		for (i = 0; i < ARRAY_SIZE(icssg_all_miig_stats); i++)
			if (!icssg_all_miig_stats[i].standard_stats)
				ethtool_puts(&p, icssg_all_miig_stats[i].name);
		for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++)
			ethtool_puts(&p, icssg_all_pa_stats[i].name);
		break;
	default:
		break;
@@ -104,9 +102,12 @@ static void emac_get_ethtool_stats(struct net_device *ndev,

	emac_update_hardware_stats(emac);

	for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++)
		if (!icssg_all_stats[i].standard_stats)
	for (i = 0; i < ARRAY_SIZE(icssg_all_miig_stats); i++)
		if (!icssg_all_miig_stats[i].standard_stats)
			*(data++) = emac->stats[i];

	for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++)
		*(data++) = emac->pa_stats[i];
}

static int emac_get_ts_info(struct net_device *ndev,
+6 −0
Original line number Diff line number Diff line
@@ -1182,6 +1182,12 @@ static int prueth_probe(struct platform_device *pdev)
		return -ENODEV;
	}

	prueth->pa_stats = syscon_regmap_lookup_by_phandle(np, "ti,pa-stats");
	if (IS_ERR(prueth->pa_stats)) {
		dev_err(dev, "couldn't get ti,pa-stats syscon regmap\n");
		return -ENODEV;
	}

	if (eth0_node) {
		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
		if (ret)
+7 −2
Original line number Diff line number Diff line
@@ -50,8 +50,10 @@

#define ICSSG_MAX_RFLOWS	8	/* per slice */

#define ICSSG_NUM_PA_STATS	4
#define ICSSG_NUM_MIIG_STATS	60
/* Number of ICSSG related stats */
#define ICSSG_NUM_STATS 60
#define ICSSG_NUM_STATS (ICSSG_NUM_MIIG_STATS + ICSSG_NUM_PA_STATS)
#define ICSSG_NUM_STANDARD_STATS 31
#define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS)

@@ -190,7 +192,8 @@ struct prueth_emac {
	int port_vlan;

	struct delayed_work stats_work;
	u64 stats[ICSSG_NUM_STATS];
	u64 stats[ICSSG_NUM_MIIG_STATS];
	u64 pa_stats[ICSSG_NUM_PA_STATS];

	/* RX IRQ Coalescing Related */
	struct hrtimer rx_hrtimer;
@@ -230,6 +233,7 @@ struct icssg_firmwares {
 * @registered_netdevs: list of registered netdevs
 * @miig_rt: regmap to mii_g_rt block
 * @mii_rt: regmap to mii_rt block
 * @pa_stats: regmap to pa_stats block
 * @pru_id: ID for each of the PRUs
 * @pdev: pointer to ICSSG platform device
 * @pdata: pointer to platform data for ICSSG driver
@@ -263,6 +267,7 @@ struct prueth {
	struct net_device *registered_netdevs[PRUETH_NUM_MACS];
	struct regmap *miig_rt;
	struct regmap *mii_rt;
	struct regmap *pa_stats;

	enum pruss_pru_id pru_id[PRUSS_NUM_PRUS];
	struct platform_device *pdev;
+22 −9
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@

#define ICSSG_TX_PACKET_OFFSET	0xA0
#define ICSSG_TX_BYTE_OFFSET	0xEC
#define ICSSG_FW_STATS_BASE	0x0248

static u32 stats_base[] = {	0x54c,	/* Slice 0 stats start */
				0xb18,	/* Slice 1 stats start */
@@ -22,24 +23,31 @@ void emac_update_hardware_stats(struct prueth_emac *emac)
	int slice = prueth_emac_slice(emac);
	u32 base = stats_base[slice];
	u32 tx_pkt_cnt = 0;
	u32 val;
	u32 val, reg;
	int i;

	for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) {
	for (i = 0; i < ARRAY_SIZE(icssg_all_miig_stats); i++) {
		regmap_read(prueth->miig_rt,
			    base + icssg_all_stats[i].offset,
			    base + icssg_all_miig_stats[i].offset,
			    &val);
		regmap_write(prueth->miig_rt,
			     base + icssg_all_stats[i].offset,
			     base + icssg_all_miig_stats[i].offset,
			     val);

		if (icssg_all_stats[i].offset == ICSSG_TX_PACKET_OFFSET)
		if (icssg_all_miig_stats[i].offset == ICSSG_TX_PACKET_OFFSET)
			tx_pkt_cnt = val;

		emac->stats[i] += val;
		if (icssg_all_stats[i].offset == ICSSG_TX_BYTE_OFFSET)
		if (icssg_all_miig_stats[i].offset == ICSSG_TX_BYTE_OFFSET)
			emac->stats[i] -= tx_pkt_cnt * 8;
	}

	for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
		reg = ICSSG_FW_STATS_BASE + icssg_all_pa_stats[i].offset *
		      PRUETH_NUM_MACS + slice * sizeof(u32);
		regmap_read(prueth->pa_stats, reg, &val);
		emac->pa_stats[i] += val;
	}
}

void icssg_stats_work_handler(struct work_struct *work)
@@ -57,9 +65,14 @@ int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) {
		if (!strcmp(icssg_all_stats[i].name, stat_name))
			return emac->stats[icssg_all_stats[i].offset / sizeof(u32)];
	for (i = 0; i < ARRAY_SIZE(icssg_all_miig_stats); i++) {
		if (!strcmp(icssg_all_miig_stats[i].name, stat_name))
			return emac->stats[icssg_all_miig_stats[i].offset / sizeof(u32)];
	}

	for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
		if (!strcmp(icssg_all_pa_stats[i].name, stat_name))
			return emac->pa_stats[icssg_all_pa_stats[i].offset / sizeof(u32)];
	}

	netdev_err(emac->ndev, "Invalid stats %s\n", stat_name);
Loading