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(ð_mac_stats->FramesTransmittedOK, 69 &mac_stats->eth_mac.FramesTransmittedOK); 70 fbnic_set_counter(ð_mac_stats->FramesReceivedOK, 71 &mac_stats->eth_mac.FramesReceivedOK); 72 fbnic_set_counter(ð_mac_stats->FrameCheckSequenceErrors, 73 &mac_stats->eth_mac.FrameCheckSequenceErrors); 74 fbnic_set_counter(ð_mac_stats->AlignmentErrors, 75 &mac_stats->eth_mac.AlignmentErrors); 76 fbnic_set_counter(ð_mac_stats->OctetsTransmittedOK, 77 &mac_stats->eth_mac.OctetsTransmittedOK); 78 fbnic_set_counter(ð_mac_stats->FramesLostDueToIntMACXmitError, 79 &mac_stats->eth_mac.FramesLostDueToIntMACXmitError); 80 fbnic_set_counter(ð_mac_stats->OctetsReceivedOK, 81 &mac_stats->eth_mac.OctetsReceivedOK); 82 fbnic_set_counter(ð_mac_stats->FramesLostDueToIntMACRcvError, 83 &mac_stats->eth_mac.FramesLostDueToIntMACRcvError); 84 fbnic_set_counter(ð_mac_stats->MulticastFramesXmittedOK, 85 &mac_stats->eth_mac.MulticastFramesXmittedOK); 86 fbnic_set_counter(ð_mac_stats->BroadcastFramesXmittedOK, 87 &mac_stats->eth_mac.BroadcastFramesXmittedOK); 88 fbnic_set_counter(ð_mac_stats->MulticastFramesReceivedOK, 89 &mac_stats->eth_mac.MulticastFramesReceivedOK); 90 fbnic_set_counter(ð_mac_stats->BroadcastFramesReceivedOK, 91 &mac_stats->eth_mac.BroadcastFramesReceivedOK); 92 fbnic_set_counter(ð_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, ®s->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