Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2ee56fd authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan
Browse files

net: qualcomm: rmnet: Add support for ethtool private stats for port



Add ethtool private stats handler to debug the handling of packets
with downlink header and trailer. This functionality is added
as part of a new private structure for statistics in the rmnet
port structure.

CRs-Fixed: 2233026
Change-Id: Iefd3687b7d61d314e363be556e71ac419b5119ea
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent 26758ac6
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -27,6 +27,20 @@ struct rmnet_endpoint {
	struct hlist_node hlnode;
};

struct rmnet_port_priv_stats {
	u64 dl_hdr_last_seq;
	u64 dl_hdr_last_bytes;
	u64 dl_hdr_last_pkts;
	u64 dl_hdr_last_flows;
	u64 dl_hdr_count;
	u64 dl_hdr_total_bytes;
	u64 dl_hdr_total_pkts;
	u64 dl_hdr_avg_bytes;
	u64 dl_hdr_avg_pkts;
	u64 dl_trl_last_seq;
	u64 dl_trl_count;
};

/* One instance of this structure is instantiated for each real_dev associated
 * with rmnet.
 */
@@ -56,6 +70,7 @@ struct rmnet_port {
	/* dl marker elements */
	spinlock_t dl_list_lock;
	struct list_head dl_list;
	struct rmnet_port_priv_stats stats;
};

extern struct rtnl_link_ops rmnet_link_ops;
+20 −0
Original line number Diff line number Diff line
@@ -132,6 +132,23 @@ static void rmnet_map_process_flow_start(struct sk_buff *skb,

	dlhdr = (struct rmnet_map_dl_ind_hdr *)skb->data;

	port->stats.dl_hdr_last_seq = dlhdr->le.seq;
	port->stats.dl_hdr_last_bytes = dlhdr->le.bytes;
	port->stats.dl_hdr_last_pkts = dlhdr->le.pkts;
	port->stats.dl_hdr_last_flows = dlhdr->le.flows;
	port->stats.dl_hdr_total_bytes += port->stats.dl_hdr_last_bytes;
	port->stats.dl_hdr_total_pkts += port->stats.dl_hdr_last_pkts;
	port->stats.dl_hdr_count++;

	if (unlikely(!(port->stats.dl_hdr_count)))
		port->stats.dl_hdr_count = 1;

	port->stats.dl_hdr_avg_bytes = port->stats.dl_hdr_total_bytes /
				       port->stats.dl_hdr_count;

	port->stats.dl_hdr_avg_pkts = port->stats.dl_hdr_total_pkts /
				      port->stats.dl_hdr_count;

	rmnet_map_dl_hdr_notify(port, dlhdr);
}

@@ -147,6 +164,9 @@ static void rmnet_map_process_flow_end(struct sk_buff *skb,

	dltrl = (struct rmnet_map_dl_ind_trl *)skb->data;

	port->stats.dl_trl_last_seq = dltrl->seq_le;
	port->stats.dl_trl_count++;

	rmnet_map_dl_trl_notify(port, dltrl);
}

+28 −2
Original line number Diff line number Diff line
@@ -170,12 +170,29 @@ static const char rmnet_gstrings_stats[][ETH_GSTRING_LEN] = {
	"Checksum computed in software",
};

static const char rmnet_port_gstrings_stats[][ETH_GSTRING_LEN] = {
	"DL header last seen sequence",
	"DL header last seen bytes",
	"DL header last seen packets",
	"DL header last seen flows",
	"DL header pkts received",
	"DL header total bytes received",
	"DL header total pkts received",
	"DL header average bytes",
	"DL header average packets",
	"DL trailer last seen sequence",
	"DL trailer pkts received",
};

static void rmnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{
	switch (stringset) {
	case ETH_SS_STATS:
		memcpy(buf, &rmnet_gstrings_stats,
		       sizeof(rmnet_gstrings_stats));
		memcpy(buf + sizeof(rmnet_gstrings_stats),
		       &rmnet_port_gstrings_stats,
		       sizeof(rmnet_port_gstrings_stats));
		break;
	}
}
@@ -184,7 +201,8 @@ static int rmnet_get_sset_count(struct net_device *dev, int sset)
{
	switch (sset) {
	case ETH_SS_STATS:
		return ARRAY_SIZE(rmnet_gstrings_stats);
		return ARRAY_SIZE(rmnet_gstrings_stats) +
		       ARRAY_SIZE(rmnet_port_gstrings_stats);
	default:
		return -EOPNOTSUPP;
	}
@@ -195,11 +213,19 @@ static void rmnet_get_ethtool_stats(struct net_device *dev,
{
	struct rmnet_priv *priv = netdev_priv(dev);
	struct rmnet_priv_stats *st = &priv->stats;
	struct rmnet_port_priv_stats *stp;
	struct rmnet_port *port;

	if (!data)
	port = rmnet_get_port(priv->real_dev);

	if (!data || !port)
		return;

	stp = &port->stats;

	memcpy(data, st, ARRAY_SIZE(rmnet_gstrings_stats) * sizeof(u64));
	memcpy(data + ARRAY_SIZE(rmnet_gstrings_stats), stp,
	       ARRAY_SIZE(rmnet_port_gstrings_stats) * sizeof(u64));
}

static const struct ethtool_ops rmnet_ethtool_ops = {