xref: /linux/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c (revision a79993b5fce69e97f900bb975f6127e25cebf130)
1 #include <linux/ethtool.h>
2 #include <linux/netdevice.h>
3 #include <linux/pci.h>
4 
5 #include "fbnic.h"
6 #include "fbnic_netdev.h"
7 #include "fbnic_tlv.h"
8 
9 static int
10 fbnic_get_ts_info(struct net_device *netdev,
11 		  struct kernel_ethtool_ts_info *tsinfo)
12 {
13 	struct fbnic_net *fbn = netdev_priv(netdev);
14 
15 	tsinfo->phc_index = ptp_clock_index(fbn->fbd->ptp);
16 
17 	tsinfo->so_timestamping =
18 		SOF_TIMESTAMPING_TX_SOFTWARE |
19 		SOF_TIMESTAMPING_TX_HARDWARE |
20 		SOF_TIMESTAMPING_RX_HARDWARE |
21 		SOF_TIMESTAMPING_RAW_HARDWARE;
22 
23 	tsinfo->tx_types =
24 		BIT(HWTSTAMP_TX_OFF) |
25 		BIT(HWTSTAMP_TX_ON);
26 
27 	tsinfo->rx_filters =
28 		BIT(HWTSTAMP_FILTER_NONE) |
29 		BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
30 		BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
31 		BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
32 		BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
33 		BIT(HWTSTAMP_FILTER_ALL);
34 
35 	return 0;
36 }
37 
38 static void
39 fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
40 {
41 	struct fbnic_net *fbn = netdev_priv(netdev);
42 	struct fbnic_dev *fbd = fbn->fbd;
43 
44 	fbnic_get_fw_ver_commit_str(fbd, drvinfo->fw_version,
45 				    sizeof(drvinfo->fw_version));
46 }
47 
48 static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
49 {
50 	if (counter->reported)
51 		*stat = counter->value;
52 }
53 
54 static void
55 fbnic_get_eth_mac_stats(struct net_device *netdev,
56 			struct ethtool_eth_mac_stats *eth_mac_stats)
57 {
58 	struct fbnic_net *fbn = netdev_priv(netdev);
59 	struct fbnic_mac_stats *mac_stats;
60 	struct fbnic_dev *fbd = fbn->fbd;
61 	const struct fbnic_mac *mac;
62 
63 	mac_stats = &fbd->hw_stats.mac;
64 	mac = fbd->mac;
65 
66 	mac->get_eth_mac_stats(fbd, false, &mac_stats->eth_mac);
67 
68 	fbnic_set_counter(&eth_mac_stats->FramesTransmittedOK,
69 			  &mac_stats->eth_mac.FramesTransmittedOK);
70 	fbnic_set_counter(&eth_mac_stats->FramesReceivedOK,
71 			  &mac_stats->eth_mac.FramesReceivedOK);
72 	fbnic_set_counter(&eth_mac_stats->FrameCheckSequenceErrors,
73 			  &mac_stats->eth_mac.FrameCheckSequenceErrors);
74 	fbnic_set_counter(&eth_mac_stats->AlignmentErrors,
75 			  &mac_stats->eth_mac.AlignmentErrors);
76 	fbnic_set_counter(&eth_mac_stats->OctetsTransmittedOK,
77 			  &mac_stats->eth_mac.OctetsTransmittedOK);
78 	fbnic_set_counter(&eth_mac_stats->FramesLostDueToIntMACXmitError,
79 			  &mac_stats->eth_mac.FramesLostDueToIntMACXmitError);
80 	fbnic_set_counter(&eth_mac_stats->OctetsReceivedOK,
81 			  &mac_stats->eth_mac.OctetsReceivedOK);
82 	fbnic_set_counter(&eth_mac_stats->FramesLostDueToIntMACRcvError,
83 			  &mac_stats->eth_mac.FramesLostDueToIntMACRcvError);
84 	fbnic_set_counter(&eth_mac_stats->MulticastFramesXmittedOK,
85 			  &mac_stats->eth_mac.MulticastFramesXmittedOK);
86 	fbnic_set_counter(&eth_mac_stats->BroadcastFramesXmittedOK,
87 			  &mac_stats->eth_mac.BroadcastFramesXmittedOK);
88 	fbnic_set_counter(&eth_mac_stats->MulticastFramesReceivedOK,
89 			  &mac_stats->eth_mac.MulticastFramesReceivedOK);
90 	fbnic_set_counter(&eth_mac_stats->BroadcastFramesReceivedOK,
91 			  &mac_stats->eth_mac.BroadcastFramesReceivedOK);
92 	fbnic_set_counter(&eth_mac_stats->FrameTooLongErrors,
93 			  &mac_stats->eth_mac.FrameTooLongErrors);
94 }
95 
96 static void fbnic_get_ts_stats(struct net_device *netdev,
97 			       struct ethtool_ts_stats *ts_stats)
98 {
99 	struct fbnic_net *fbn = netdev_priv(netdev);
100 	u64 ts_packets, ts_lost;
101 	struct fbnic_ring *ring;
102 	unsigned int start;
103 	int i;
104 
105 	ts_stats->pkts = fbn->tx_stats.ts_packets;
106 	ts_stats->lost = fbn->tx_stats.ts_lost;
107 	for (i = 0; i < fbn->num_tx_queues; i++) {
108 		ring = fbn->tx[i];
109 		do {
110 			start = u64_stats_fetch_begin(&ring->stats.syncp);
111 			ts_packets = ring->stats.ts_packets;
112 			ts_lost = ring->stats.ts_lost;
113 		} while (u64_stats_fetch_retry(&ring->stats.syncp, start));
114 		ts_stats->pkts += ts_packets;
115 		ts_stats->lost += ts_lost;
116 	}
117 }
118 
119 static void fbnic_get_regs(struct net_device *netdev,
120 			   struct ethtool_regs *regs, void *data)
121 {
122 	struct fbnic_net *fbn = netdev_priv(netdev);
123 
124 	fbnic_csr_get_regs(fbn->fbd, data, &regs->version);
125 }
126 
127 static int fbnic_get_regs_len(struct net_device *netdev)
128 {
129 	struct fbnic_net *fbn = netdev_priv(netdev);
130 
131 	return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32);
132 }
133 
134 static const struct ethtool_ops fbnic_ethtool_ops = {
135 	.get_drvinfo		= fbnic_get_drvinfo,
136 	.get_regs_len		= fbnic_get_regs_len,
137 	.get_regs		= fbnic_get_regs,
138 	.get_ts_info		= fbnic_get_ts_info,
139 	.get_ts_stats		= fbnic_get_ts_stats,
140 	.get_eth_mac_stats	= fbnic_get_eth_mac_stats,
141 };
142 
143 void fbnic_set_ethtool_ops(struct net_device *dev)
144 {
145 	dev->ethtool_ops = &fbnic_ethtool_ops;
146 }
147