aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/fm10k
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2014-09-20 19:54:07 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-09-23 06:59:23 -0400
commita211e0136c9a3653acba13ec3b9a2f49c3c44f5e (patch)
tree9e7d5171d96efa1a0e7a2b95022a98a36619146f /drivers/net/ethernet/intel/fm10k
parent5f226ddb5b0c477bd512085b0b1d1052a24f0020 (diff)
fm10k: Add support for PTP
This change adds support for the Linux PTP Hardware clock and timestamping functionality provided by the hardware. There are actually two cases that this timestamping is meant to support. The first case would be an ordinary clock scenario. In this configuration the host interface does not have access to BAR 4. However all of the host interfaces should be locked into the same boundary clock region and as such they are all on the same clock anyway. With this being the case they can synchronize among themselves and only need to adjust the offset since they are all on the same clock with the same frequency. The second case is a boundary clock scenario. This is a special case and would require both BAR 4 access, and a means of presenting a netdev per boundary region. The current plan is to use DSA at some point in the future to provide these interfaces, but the DSA portion is still under development. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Acked-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/fm10k')
-rw-r--r--drivers/net/ethernet/intel/fm10k/Makefile2
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k.h37
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c30
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_main.c20
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_netdev.c20
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c112
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_ptp.c463
7 files changed, 683 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/Makefile b/drivers/net/ethernet/intel/fm10k/Makefile
index fbc0e092077c..08859dd220a8 100644
--- a/drivers/net/ethernet/intel/fm10k/Makefile
+++ b/drivers/net/ethernet/intel/fm10k/Makefile
@@ -30,4 +30,4 @@ obj-$(CONFIG_FM10K) += fm10k.o
30fm10k-objs := fm10k_main.o fm10k_common.o fm10k_pci.o \ 30fm10k-objs := fm10k_main.o fm10k_common.o fm10k_pci.o \
31 fm10k_netdev.o fm10k_ethtool.o fm10k_pf.o fm10k_vf.o \ 31 fm10k_netdev.o fm10k_ethtool.o fm10k_pf.o fm10k_vf.o \
32 fm10k_mbx.o fm10k_iov.o fm10k_tlv.o \ 32 fm10k_mbx.o fm10k_iov.o fm10k_tlv.o \
33 fm10k_debugfs.o fm10k_dcbnl.o 33 fm10k_debugfs.o fm10k_ptp.o fm10k_dcbnl.o
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h
index 10454834176a..05658275ba17 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k.h
@@ -26,6 +26,9 @@
26#include <linux/rtnetlink.h> 26#include <linux/rtnetlink.h>
27#include <linux/if_vlan.h> 27#include <linux/if_vlan.h>
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <linux/net_tstamp.h>
30#include <linux/clocksource.h>
31#include <linux/ptp_clock_kernel.h>
29 32
30#include "fm10k_pf.h" 33#include "fm10k_pf.h"
31#include "fm10k_vf.h" 34#include "fm10k_vf.h"
@@ -293,6 +296,7 @@ struct fm10k_intfc {
293 struct fm10k_hw_stats stats; 296 struct fm10k_hw_stats stats;
294 struct fm10k_hw hw; 297 struct fm10k_hw hw;
295 u32 __iomem *uc_addr; 298 u32 __iomem *uc_addr;
299 u32 __iomem *sw_addr;
296 u16 msg_enable; 300 u16 msg_enable;
297 u16 tx_ring_count; 301 u16 tx_ring_count;
298 u16 rx_ring_count; 302 u16 rx_ring_count;
@@ -314,6 +318,20 @@ struct fm10k_intfc {
314 struct dentry *dbg_intfc; 318 struct dentry *dbg_intfc;
315 319
316#endif /* CONFIG_DEBUG_FS */ 320#endif /* CONFIG_DEBUG_FS */
321 struct ptp_clock_info ptp_caps;
322 struct ptp_clock *ptp_clock;
323
324 struct sk_buff_head ts_tx_skb_queue;
325 u32 tx_hwtstamp_timeouts;
326
327 struct hwtstamp_config ts_config;
328 /* We are unable to actually adjust the clock beyond the frequency
329 * value. Once the clock is started there is no resetting it. As
330 * such we maintain a separate offset from the actual hardware clock
331 * to allow for offset adjustment.
332 */
333 s64 ptp_adjust;
334 rwlock_t systime_lock;
317#ifdef CONFIG_DCB 335#ifdef CONFIG_DCB
318 u8 pfc_en; 336 u8 pfc_en;
319#endif 337#endif
@@ -411,6 +429,10 @@ union fm10k_ftag_info {
411}; 429};
412 430
413struct fm10k_cb { 431struct fm10k_cb {
432 union {
433 __le64 tstamp;
434 unsigned long ts_tx_timeout;
435 };
414 union fm10k_ftag_info fi; 436 union fm10k_ftag_info fi;
415}; 437};
416 438
@@ -492,6 +514,21 @@ static inline void fm10k_dbg_init(void) {}
492static inline void fm10k_dbg_exit(void) {} 514static inline void fm10k_dbg_exit(void) {}
493#endif /* CONFIG_DEBUG_FS */ 515#endif /* CONFIG_DEBUG_FS */
494 516
517/* Time Stamping */
518void fm10k_systime_to_hwtstamp(struct fm10k_intfc *interface,
519 struct skb_shared_hwtstamps *hwtstamp,
520 u64 systime);
521void fm10k_ts_tx_enqueue(struct fm10k_intfc *interface, struct sk_buff *skb);
522void fm10k_ts_tx_hwtstamp(struct fm10k_intfc *interface, __le16 dglort,
523 u64 systime);
524void fm10k_ts_reset(struct fm10k_intfc *interface);
525void fm10k_ts_init(struct fm10k_intfc *interface);
526void fm10k_ts_tx_subtask(struct fm10k_intfc *interface);
527void fm10k_ptp_register(struct fm10k_intfc *interface);
528void fm10k_ptp_unregister(struct fm10k_intfc *interface);
529int fm10k_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
530int fm10k_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
531
495/* DCB */ 532/* DCB */
496void fm10k_dcbnl_set_ops(struct net_device *dev); 533void fm10k_dcbnl_set_ops(struct net_device *dev);
497#endif /* _FM10K_H_ */ 534#endif /* _FM10K_H_ */
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
index 42beb89ae15d..a9bbe60347d8 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
@@ -91,6 +91,8 @@ static const struct fm10k_stats fm10k_gstrings_stats[] = {
91 FM10K_STAT("mbx_rx_messages", hw.mbx.rx_messages), 91 FM10K_STAT("mbx_rx_messages", hw.mbx.rx_messages),
92 FM10K_STAT("mbx_rx_dwords", hw.mbx.rx_dwords), 92 FM10K_STAT("mbx_rx_dwords", hw.mbx.rx_dwords),
93 FM10K_STAT("mbx_rx_parse_err", hw.mbx.rx_parse_err), 93 FM10K_STAT("mbx_rx_parse_err", hw.mbx.rx_parse_err),
94
95 FM10K_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
94}; 96};
95 97
96#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_stats) 98#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_stats)
@@ -1006,6 +1008,33 @@ static int fm10k_set_channels(struct net_device *dev,
1006 return fm10k_setup_tc(dev, netdev_get_num_tc(dev)); 1008 return fm10k_setup_tc(dev, netdev_get_num_tc(dev));
1007} 1009}
1008 1010
1011static int fm10k_get_ts_info(struct net_device *dev,
1012 struct ethtool_ts_info *info)
1013{
1014 struct fm10k_intfc *interface = netdev_priv(dev);
1015
1016 info->so_timestamping =
1017 SOF_TIMESTAMPING_TX_SOFTWARE |
1018 SOF_TIMESTAMPING_RX_SOFTWARE |
1019 SOF_TIMESTAMPING_SOFTWARE |
1020 SOF_TIMESTAMPING_TX_HARDWARE |
1021 SOF_TIMESTAMPING_RX_HARDWARE |
1022 SOF_TIMESTAMPING_RAW_HARDWARE;
1023
1024 if (interface->ptp_clock)
1025 info->phc_index = ptp_clock_index(interface->ptp_clock);
1026 else
1027 info->phc_index = -1;
1028
1029 info->tx_types = (1 << HWTSTAMP_TX_OFF) |
1030 (1 << HWTSTAMP_TX_ON);
1031
1032 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
1033 (1 << HWTSTAMP_FILTER_ALL);
1034
1035 return 0;
1036}
1037
1009static const struct ethtool_ops fm10k_ethtool_ops = { 1038static const struct ethtool_ops fm10k_ethtool_ops = {
1010 .get_strings = fm10k_get_strings, 1039 .get_strings = fm10k_get_strings,
1011 .get_sset_count = fm10k_get_sset_count, 1040 .get_sset_count = fm10k_get_sset_count,
@@ -1031,6 +1060,7 @@ static const struct ethtool_ops fm10k_ethtool_ops = {
1031 .set_rxfh = fm10k_set_rssh, 1060 .set_rxfh = fm10k_set_rssh,
1032 .get_channels = fm10k_get_channels, 1061 .get_channels = fm10k_get_channels,
1033 .set_channels = fm10k_set_channels, 1062 .set_channels = fm10k_set_channels,
1063 .get_ts_info = fm10k_get_ts_info,
1034}; 1064};
1035 1065
1036void fm10k_set_ethtool_ops(struct net_device *dev) 1066void fm10k_set_ethtool_ops(struct net_device *dev)
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index d9987331387e..6c800a330d66 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -399,6 +399,19 @@ static inline void fm10k_rx_hash(struct fm10k_ring *ring,
399 PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); 399 PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
400} 400}
401 401
402static void fm10k_rx_hwtstamp(struct fm10k_ring *rx_ring,
403 union fm10k_rx_desc *rx_desc,
404 struct sk_buff *skb)
405{
406 struct fm10k_intfc *interface = rx_ring->q_vector->interface;
407
408 FM10K_CB(skb)->tstamp = rx_desc->q.timestamp;
409
410 if (unlikely(interface->flags & FM10K_FLAG_RX_TS_ENABLED))
411 fm10k_systime_to_hwtstamp(interface, skb_hwtstamps(skb),
412 le64_to_cpu(rx_desc->q.timestamp));
413}
414
402static void fm10k_type_trans(struct fm10k_ring *rx_ring, 415static void fm10k_type_trans(struct fm10k_ring *rx_ring,
403 union fm10k_rx_desc *rx_desc, 416 union fm10k_rx_desc *rx_desc,
404 struct sk_buff *skb) 417 struct sk_buff *skb)
@@ -448,6 +461,8 @@ static unsigned int fm10k_process_skb_fields(struct fm10k_ring *rx_ring,
448 461
449 fm10k_rx_checksum(rx_ring, rx_desc, skb); 462 fm10k_rx_checksum(rx_ring, rx_desc, skb);
450 463
464 fm10k_rx_hwtstamp(rx_ring, rx_desc, skb);
465
451 FM10K_CB(skb)->fi.w.vlan = rx_desc->w.vlan; 466 FM10K_CB(skb)->fi.w.vlan = rx_desc->w.vlan;
452 467
453 skb_record_rx_queue(skb, rx_ring->queue_index); 468 skb_record_rx_queue(skb, rx_ring->queue_index);
@@ -886,6 +901,11 @@ static u8 fm10k_tx_desc_flags(struct sk_buff *skb, u32 tx_flags)
886 /* set type for advanced descriptor with frame checksum insertion */ 901 /* set type for advanced descriptor with frame checksum insertion */
887 u32 desc_flags = 0; 902 u32 desc_flags = 0;
888 903
904 /* set timestamping bits */
905 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
906 likely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
907 desc_flags |= FM10K_TXD_FLAG_TIME;
908
889 /* set checksum offload bits */ 909 /* set checksum offload bits */
890 desc_flags |= FM10K_SET_FLAG(tx_flags, FM10K_TX_FLAGS_CSUM, 910 desc_flags |= FM10K_SET_FLAG(tx_flags, FM10K_TX_FLAGS_CSUM,
891 FM10K_TXD_FLAG_CSUM); 911 FM10K_TXD_FLAG_CSUM);
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index 991abb25451e..dcec000bdb68 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -243,6 +243,9 @@ void fm10k_clean_all_tx_rings(struct fm10k_intfc *interface)
243 243
244 for (i = 0; i < interface->num_tx_queues; i++) 244 for (i = 0; i < interface->num_tx_queues; i++)
245 fm10k_clean_tx_ring(interface->tx_ring[i]); 245 fm10k_clean_tx_ring(interface->tx_ring[i]);
246
247 /* remove any stale timestamp buffers and free them */
248 skb_queue_purge(&interface->ts_tx_skb_queue);
246} 249}
247 250
248/** 251/**
@@ -651,6 +654,10 @@ static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
651 __skb_put(skb, pad_len); 654 __skb_put(skb, pad_len);
652 } 655 }
653 656
657 /* prepare packet for hardware time stamping */
658 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
659 fm10k_ts_tx_enqueue(interface, skb);
660
654 if (r_idx >= interface->num_tx_queues) 661 if (r_idx >= interface->num_tx_queues)
655 r_idx %= interface->num_tx_queues; 662 r_idx %= interface->num_tx_queues;
656 663
@@ -1177,6 +1184,18 @@ int fm10k_setup_tc(struct net_device *dev, u8 tc)
1177 return 0; 1184 return 0;
1178} 1185}
1179 1186
1187static int fm10k_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
1188{
1189 switch (cmd) {
1190 case SIOCGHWTSTAMP:
1191 return fm10k_get_ts_config(netdev, ifr);
1192 case SIOCSHWTSTAMP:
1193 return fm10k_set_ts_config(netdev, ifr);
1194 default:
1195 return -EOPNOTSUPP;
1196 }
1197}
1198
1180static void fm10k_assign_l2_accel(struct fm10k_intfc *interface, 1199static void fm10k_assign_l2_accel(struct fm10k_intfc *interface,
1181 struct fm10k_l2_accel *l2_accel) 1200 struct fm10k_l2_accel *l2_accel)
1182{ 1201{
@@ -1345,6 +1364,7 @@ static const struct net_device_ops fm10k_netdev_ops = {
1345 .ndo_get_vf_config = fm10k_ndo_get_vf_config, 1364 .ndo_get_vf_config = fm10k_ndo_get_vf_config,
1346 .ndo_add_vxlan_port = fm10k_add_vxlan_port, 1365 .ndo_add_vxlan_port = fm10k_add_vxlan_port,
1347 .ndo_del_vxlan_port = fm10k_del_vxlan_port, 1366 .ndo_del_vxlan_port = fm10k_del_vxlan_port,
1367 .ndo_do_ioctl = fm10k_ioctl,
1348 .ndo_dfwd_add_station = fm10k_dfwd_add_station, 1368 .ndo_dfwd_add_station = fm10k_dfwd_add_station,
1349 .ndo_dfwd_del_station = fm10k_dfwd_del_station, 1369 .ndo_dfwd_del_station = fm10k_dfwd_del_station,
1350}; 1370};
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index 74d7d473d113..e02036c427b9 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -170,6 +170,9 @@ static void fm10k_reinit(struct fm10k_intfc *interface)
170 /* reassociate interrupts */ 170 /* reassociate interrupts */
171 fm10k_mbx_request_irq(interface); 171 fm10k_mbx_request_irq(interface);
172 172
173 /* reset clock */
174 fm10k_ts_reset(interface);
175
173 if (netif_running(netdev)) 176 if (netif_running(netdev))
174 fm10k_open(netdev); 177 fm10k_open(netdev);
175 178
@@ -490,6 +493,7 @@ static void fm10k_service_task(struct work_struct *work)
490 /* tasks only run when interface is up */ 493 /* tasks only run when interface is up */
491 fm10k_watchdog_subtask(interface); 494 fm10k_watchdog_subtask(interface);
492 fm10k_check_hang_subtask(interface); 495 fm10k_check_hang_subtask(interface);
496 fm10k_ts_tx_subtask(interface);
493 497
494 /* release lock on service events to allow scheduling next event */ 498 /* release lock on service events to allow scheduling next event */
495 fm10k_service_event_complete(interface); 499 fm10k_service_event_complete(interface);
@@ -1064,6 +1068,25 @@ static s32 fm10k_mbx_mac_addr(struct fm10k_hw *hw, u32 **results,
1064 return 0; 1068 return 0;
1065} 1069}
1066 1070
1071static s32 fm10k_1588_msg_vf(struct fm10k_hw *hw, u32 **results,
1072 struct fm10k_mbx_info *mbx)
1073{
1074 struct fm10k_intfc *interface;
1075 u64 timestamp;
1076 s32 err;
1077
1078 err = fm10k_tlv_attr_get_u64(results[FM10K_1588_MSG_TIMESTAMP],
1079 &timestamp);
1080 if (err)
1081 return err;
1082
1083 interface = container_of(hw, struct fm10k_intfc, hw);
1084
1085 fm10k_ts_tx_hwtstamp(interface, 0, timestamp);
1086
1087 return 0;
1088}
1089
1067/* generic error handler for mailbox issues */ 1090/* generic error handler for mailbox issues */
1068static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results, 1091static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results,
1069 struct fm10k_mbx_info *mbx) 1092 struct fm10k_mbx_info *mbx)
@@ -1084,6 +1107,7 @@ static const struct fm10k_msg_data vf_mbx_data[] = {
1084 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test), 1107 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
1085 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_mbx_mac_addr), 1108 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_mbx_mac_addr),
1086 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf), 1109 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
1110 FM10K_VF_MSG_1588_HANDLER(fm10k_1588_msg_vf),
1087 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_mbx_error), 1111 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_mbx_error),
1088}; 1112};
1089 1113
@@ -1181,6 +1205,68 @@ static s32 fm10k_update_pvid(struct fm10k_hw *hw, u32 **results,
1181 return 0; 1205 return 0;
1182} 1206}
1183 1207
1208static s32 fm10k_1588_msg_pf(struct fm10k_hw *hw, u32 **results,
1209 struct fm10k_mbx_info *mbx)
1210{
1211 struct fm10k_swapi_1588_timestamp timestamp;
1212 struct fm10k_iov_data *iov_data;
1213 struct fm10k_intfc *interface;
1214 u16 sglort, vf_idx;
1215 s32 err;
1216
1217 err = fm10k_tlv_attr_get_le_struct(
1218 results[FM10K_PF_ATTR_ID_1588_TIMESTAMP],
1219 &timestamp, sizeof(timestamp));
1220 if (err)
1221 return err;
1222
1223 interface = container_of(hw, struct fm10k_intfc, hw);
1224
1225 if (timestamp.dglort) {
1226 fm10k_ts_tx_hwtstamp(interface, timestamp.dglort,
1227 le64_to_cpu(timestamp.egress));
1228 return 0;
1229 }
1230
1231 /* either dglort or sglort must be set */
1232 if (!timestamp.sglort)
1233 return FM10K_ERR_PARAM;
1234
1235 /* verify GLORT is at least one of the ones we own */
1236 sglort = le16_to_cpu(timestamp.sglort);
1237 if (!fm10k_glort_valid_pf(hw, sglort))
1238 return FM10K_ERR_PARAM;
1239
1240 if (sglort == interface->glort) {
1241 fm10k_ts_tx_hwtstamp(interface, 0,
1242 le64_to_cpu(timestamp.ingress));
1243 return 0;
1244 }
1245
1246 /* if there is no iov_data then there is no mailboxes to process */
1247 if (!ACCESS_ONCE(interface->iov_data))
1248 return FM10K_ERR_PARAM;
1249
1250 rcu_read_lock();
1251
1252 /* notify VF if this timestamp belongs to it */
1253 iov_data = interface->iov_data;
1254 vf_idx = (hw->mac.dglort_map & FM10K_DGLORTMAP_NONE) - sglort;
1255
1256 if (!iov_data || vf_idx >= iov_data->num_vfs) {
1257 err = FM10K_ERR_PARAM;
1258 goto err_unlock;
1259 }
1260
1261 err = hw->iov.ops.report_timestamp(hw, &iov_data->vf_info[vf_idx],
1262 le64_to_cpu(timestamp.ingress));
1263
1264err_unlock:
1265 rcu_read_unlock();
1266
1267 return err;
1268}
1269
1184static const struct fm10k_msg_data pf_mbx_data[] = { 1270static const struct fm10k_msg_data pf_mbx_data[] = {
1185 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf), 1271 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
1186 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf), 1272 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
@@ -1188,6 +1274,7 @@ static const struct fm10k_msg_data pf_mbx_data[] = {
1188 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf), 1274 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
1189 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf), 1275 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
1190 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_update_pvid), 1276 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_update_pvid),
1277 FM10K_PF_MSG_1588_TIMESTAMP_HANDLER(fm10k_1588_msg_pf),
1191 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_mbx_error), 1278 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_mbx_error),
1192}; 1279};
1193 1280
@@ -1549,6 +1636,12 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
1549 return -EIO; 1636 return -EIO;
1550 } 1637 }
1551 1638
1639 /* assign BAR 4 resources for use with PTP */
1640 if (fm10k_read_reg(hw, FM10K_CTRL) & FM10K_CTRL_BAR4_ALLOWED)
1641 interface->sw_addr = ioremap(pci_resource_start(pdev, 4),
1642 pci_resource_len(pdev, 4));
1643 hw->sw_addr = interface->sw_addr;
1644
1552 /* Only the PF can support VXLAN and NVGRE offloads */ 1645 /* Only the PF can support VXLAN and NVGRE offloads */
1553 if (hw->mac.type != fm10k_mac_pf) { 1646 if (hw->mac.type != fm10k_mac_pf) {
1554 netdev->hw_enc_features = 0; 1647 netdev->hw_enc_features = 0;
@@ -1565,6 +1658,9 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
1565 (unsigned long)interface); 1658 (unsigned long)interface);
1566 INIT_WORK(&interface->service_task, fm10k_service_task); 1659 INIT_WORK(&interface->service_task, fm10k_service_task);
1567 1660
1661 /* Intitialize timestamp data */
1662 fm10k_ts_init(interface);
1663
1568 /* set default ring sizes */ 1664 /* set default ring sizes */
1569 interface->tx_ring_count = FM10K_DEFAULT_TXD; 1665 interface->tx_ring_count = FM10K_DEFAULT_TXD;
1570 interface->rx_ring_count = FM10K_DEFAULT_RXD; 1666 interface->rx_ring_count = FM10K_DEFAULT_RXD;
@@ -1716,6 +1812,9 @@ static int fm10k_probe(struct pci_dev *pdev,
1716 /* stop all the transmit queues from transmitting until link is up */ 1812 /* stop all the transmit queues from transmitting until link is up */
1717 netif_tx_stop_all_queues(netdev); 1813 netif_tx_stop_all_queues(netdev);
1718 1814
1815 /* Register PTP interface */
1816 fm10k_ptp_register(interface);
1817
1719 /* print bus type/speed/width info */ 1818 /* print bus type/speed/width info */
1720 dev_info(&pdev->dev, "(PCI Express:%s Width: %s Payload: %s)\n", 1819 dev_info(&pdev->dev, "(PCI Express:%s Width: %s Payload: %s)\n",
1721 (hw->bus.speed == fm10k_bus_speed_8000 ? "8.0GT/s" : 1820 (hw->bus.speed == fm10k_bus_speed_8000 ? "8.0GT/s" :
@@ -1747,6 +1846,8 @@ err_register:
1747err_mbx_interrupt: 1846err_mbx_interrupt:
1748 fm10k_clear_queueing_scheme(interface); 1847 fm10k_clear_queueing_scheme(interface);
1749err_sw_init: 1848err_sw_init:
1849 if (interface->sw_addr)
1850 iounmap(interface->sw_addr);
1750 iounmap(interface->uc_addr); 1851 iounmap(interface->uc_addr);
1751err_ioremap: 1852err_ioremap:
1752 free_netdev(netdev); 1853 free_netdev(netdev);
@@ -1780,6 +1881,9 @@ static void fm10k_remove(struct pci_dev *pdev)
1780 if (netdev->reg_state == NETREG_REGISTERED) 1881 if (netdev->reg_state == NETREG_REGISTERED)
1781 unregister_netdev(netdev); 1882 unregister_netdev(netdev);
1782 1883
1884 /* cleanup timestamp handling */
1885 fm10k_ptp_unregister(interface);
1886
1783 /* release VFs */ 1887 /* release VFs */
1784 fm10k_iov_disable(pdev); 1888 fm10k_iov_disable(pdev);
1785 1889
@@ -1792,6 +1896,8 @@ static void fm10k_remove(struct pci_dev *pdev)
1792 /* remove any debugfs interfaces */ 1896 /* remove any debugfs interfaces */
1793 fm10k_dbg_intfc_exit(interface); 1897 fm10k_dbg_intfc_exit(interface);
1794 1898
1899 if (interface->sw_addr)
1900 iounmap(interface->sw_addr);
1795 iounmap(interface->uc_addr); 1901 iounmap(interface->uc_addr);
1796 1902
1797 free_netdev(netdev); 1903 free_netdev(netdev);
@@ -1848,6 +1954,9 @@ static int fm10k_resume(struct pci_dev *pdev)
1848 /* reset statistics starting values */ 1954 /* reset statistics starting values */
1849 hw->mac.ops.rebind_hw_stats(hw, &interface->stats); 1955 hw->mac.ops.rebind_hw_stats(hw, &interface->stats);
1850 1956
1957 /* reset clock */
1958 fm10k_ts_reset(interface);
1959
1851 rtnl_lock(); 1960 rtnl_lock();
1852 1961
1853 err = fm10k_init_queueing_scheme(interface); 1962 err = fm10k_init_queueing_scheme(interface);
@@ -2004,6 +2113,9 @@ static void fm10k_io_resume(struct pci_dev *pdev)
2004 /* reassociate interrupts */ 2113 /* reassociate interrupts */
2005 fm10k_mbx_request_irq(interface); 2114 fm10k_mbx_request_irq(interface);
2006 2115
2116 /* reset clock */
2117 fm10k_ts_reset(interface);
2118
2007 if (netif_running(netdev)) 2119 if (netif_running(netdev))
2008 err = fm10k_open(netdev); 2120 err = fm10k_open(netdev);
2009 2121
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c b/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c
new file mode 100644
index 000000000000..7822809436a3
--- /dev/null
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c
@@ -0,0 +1,463 @@
1/* Intel Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2014 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 *
16 * Contact Information:
17 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
18 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
19 */
20
21#include <linux/ptp_classify.h>
22#include <linux/ptp_clock_kernel.h>
23
24#include "fm10k.h"
25
26#define FM10K_TS_TX_TIMEOUT (HZ * 15)
27
28void fm10k_systime_to_hwtstamp(struct fm10k_intfc *interface,
29 struct skb_shared_hwtstamps *hwtstamp,
30 u64 systime)
31{
32 unsigned long flags;
33
34 read_lock_irqsave(&interface->systime_lock, flags);
35 systime += interface->ptp_adjust;
36 read_unlock_irqrestore(&interface->systime_lock, flags);
37
38 hwtstamp->hwtstamp = ns_to_ktime(systime);
39}
40
41static struct sk_buff *fm10k_ts_tx_skb(struct fm10k_intfc *interface,
42 __le16 dglort)
43{
44 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
45 struct sk_buff *skb;
46
47 skb_queue_walk(list, skb) {
48 if (FM10K_CB(skb)->fi.w.dglort == dglort)
49 return skb;
50 }
51
52 return NULL;
53}
54
55void fm10k_ts_tx_enqueue(struct fm10k_intfc *interface, struct sk_buff *skb)
56{
57 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
58 struct sk_buff *clone;
59 unsigned long flags;
60 __le16 dglort;
61
62 /* create clone for us to return on the Tx path */
63 clone = skb_clone_sk(skb);
64 if (!clone)
65 return;
66
67 FM10K_CB(clone)->ts_tx_timeout = jiffies + FM10K_TS_TX_TIMEOUT;
68 dglort = FM10K_CB(clone)->fi.w.dglort;
69
70 spin_lock_irqsave(&list->lock, flags);
71
72 /* attempt to locate any buffers with the same dglort,
73 * if none are present then insert skb in tail of list
74 */
75 skb = fm10k_ts_tx_skb(interface, FM10K_CB(clone)->fi.w.dglort);
76 if (!skb)
77 __skb_queue_tail(list, clone);
78
79 spin_unlock_irqrestore(&list->lock, flags);
80
81 /* if list is already has one then we just free the clone */
82 if (skb)
83 kfree_skb(skb);
84 else
85 skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
86}
87
88void fm10k_ts_tx_hwtstamp(struct fm10k_intfc *interface, __le16 dglort,
89 u64 systime)
90{
91 struct skb_shared_hwtstamps shhwtstamps;
92 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
93 struct sk_buff *skb;
94 unsigned long flags;
95
96 spin_lock_irqsave(&list->lock, flags);
97
98 /* attempt to locate and pull the sk_buff out of the list */
99 skb = fm10k_ts_tx_skb(interface, dglort);
100 if (skb)
101 __skb_unlink(skb, list);
102
103 spin_unlock_irqrestore(&list->lock, flags);
104
105 /* if not found do nothing */
106 if (!skb)
107 return;
108
109 /* timestamp the sk_buff and return it to the socket */
110 fm10k_systime_to_hwtstamp(interface, &shhwtstamps, systime);
111 skb_complete_tx_timestamp(skb, &shhwtstamps);
112}
113
114void fm10k_ts_tx_subtask(struct fm10k_intfc *interface)
115{
116 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
117 struct sk_buff *skb, *tmp;
118 unsigned long flags;
119
120 /* If we're down or resetting, just bail */
121 if (test_bit(__FM10K_DOWN, &interface->state) ||
122 test_bit(__FM10K_RESETTING, &interface->state))
123 return;
124
125 spin_lock_irqsave(&list->lock, flags);
126
127 /* walk though the list and flush any expired timestamp packets */
128 skb_queue_walk_safe(list, skb, tmp) {
129 if (!time_is_after_jiffies(FM10K_CB(skb)->ts_tx_timeout))
130 continue;
131 __skb_unlink(skb, list);
132 kfree_skb(skb);
133 interface->tx_hwtstamp_timeouts++;
134 }
135
136 spin_unlock_irqrestore(&list->lock, flags);
137}
138
139static u64 fm10k_systime_read(struct fm10k_intfc *interface)
140{
141 struct fm10k_hw *hw = &interface->hw;
142
143 return hw->mac.ops.read_systime(hw);
144}
145
146void fm10k_ts_reset(struct fm10k_intfc *interface)
147{
148 s64 ns = ktime_to_ns(ktime_get_real());
149 unsigned long flags;
150
151 /* reinitialize the clock */
152 write_lock_irqsave(&interface->systime_lock, flags);
153 interface->ptp_adjust = fm10k_systime_read(interface) - ns;
154 write_unlock_irqrestore(&interface->systime_lock, flags);
155}
156
157void fm10k_ts_init(struct fm10k_intfc *interface)
158{
159 /* Initialize lock protecting systime access */
160 rwlock_init(&interface->systime_lock);
161
162 /* Initialize skb queue for pending timestamp requests */
163 skb_queue_head_init(&interface->ts_tx_skb_queue);
164
165 /* reset the clock to current kernel time */
166 fm10k_ts_reset(interface);
167}
168
169/**
170 * fm10k_get_ts_config - get current hardware timestamping configuration
171 * @netdev: network interface device structure
172 * @ifreq: ioctl data
173 *
174 * This function returns the current timestamping settings. Rather than
175 * attempt to deconstruct registers to fill in the values, simply keep a copy
176 * of the old settings around, and return a copy when requested.
177 */
178int fm10k_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
179{
180 struct fm10k_intfc *interface = netdev_priv(netdev);
181 struct hwtstamp_config *config = &interface->ts_config;
182
183 return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
184 -EFAULT : 0;
185}
186
187/**
188 * fm10k_set_ts_config - control hardware time stamping
189 * @netdev: network interface device structure
190 * @ifreq: ioctl data
191 *
192 * Outgoing time stamping can be enabled and disabled. Play nice and
193 * disable it when requested, although it shouldn't cause any overhead
194 * when no packet needs it. At most one packet in the queue may be
195 * marked for time stamping, otherwise it would be impossible to tell
196 * for sure to which packet the hardware time stamp belongs.
197 *
198 * Incoming time stamping has to be configured via the hardware
199 * filters. Not all combinations are supported, in particular event
200 * type has to be specified. Matching the kind of event packet is
201 * not supported, with the exception of "all V2 events regardless of
202 * level 2 or 4".
203 *
204 * Since hardware always timestamps Path delay packets when timestamping V2
205 * packets, regardless of the type specified in the register, only use V2
206 * Event mode. This more accurately tells the user what the hardware is going
207 * to do anyways.
208 */
209int fm10k_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
210{
211 struct fm10k_intfc *interface = netdev_priv(netdev);
212 struct hwtstamp_config ts_config;
213
214 if (copy_from_user(&ts_config, ifr->ifr_data, sizeof(ts_config)))
215 return -EFAULT;
216
217 /* reserved for future extensions */
218 if (ts_config.flags)
219 return -EINVAL;
220
221 switch (ts_config.tx_type) {
222 case HWTSTAMP_TX_OFF:
223 break;
224 case HWTSTAMP_TX_ON:
225 /* we likely need some check here to see if this is supported */
226 break;
227 default:
228 return -ERANGE;
229 }
230
231 switch (ts_config.rx_filter) {
232 case HWTSTAMP_FILTER_NONE:
233 interface->flags &= ~FM10K_FLAG_RX_TS_ENABLED;
234 break;
235 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
236 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
237 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
238 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
239 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
240 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
241 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
242 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
243 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
244 case HWTSTAMP_FILTER_PTP_V2_EVENT:
245 case HWTSTAMP_FILTER_PTP_V2_SYNC:
246 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
247 case HWTSTAMP_FILTER_ALL:
248 interface->flags |= FM10K_FLAG_RX_TS_ENABLED;
249 ts_config.rx_filter = HWTSTAMP_FILTER_ALL;
250 break;
251 default:
252 return -ERANGE;
253 }
254
255 /* save these settings for future reference */
256 interface->ts_config = ts_config;
257
258 return copy_to_user(ifr->ifr_data, &ts_config, sizeof(ts_config)) ?
259 -EFAULT : 0;
260}
261
262static int fm10k_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
263{
264 struct fm10k_intfc *interface;
265 struct fm10k_hw *hw;
266 int err;
267
268 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
269 hw = &interface->hw;
270
271 err = hw->mac.ops.adjust_systime(hw, ppb);
272
273 /* the only error we should see is if the value is out of range */
274 return (err == FM10K_ERR_PARAM) ? -ERANGE : err;
275}
276
277static int fm10k_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
278{
279 struct fm10k_intfc *interface;
280 unsigned long flags;
281
282 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
283
284 write_lock_irqsave(&interface->systime_lock, flags);
285 interface->ptp_adjust += delta;
286 write_unlock_irqrestore(&interface->systime_lock, flags);
287
288 return 0;
289}
290
291static int fm10k_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
292{
293 struct fm10k_intfc *interface;
294 unsigned long flags;
295 u64 now;
296
297 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
298
299 read_lock_irqsave(&interface->systime_lock, flags);
300 now = fm10k_systime_read(interface) + interface->ptp_adjust;
301 read_unlock_irqrestore(&interface->systime_lock, flags);
302
303 *ts = ns_to_timespec(now);
304
305 return 0;
306}
307
308static int fm10k_ptp_settime(struct ptp_clock_info *ptp,
309 const struct timespec *ts)
310{
311 struct fm10k_intfc *interface;
312 unsigned long flags;
313 u64 ns = timespec_to_ns(ts);
314
315 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
316
317 write_lock_irqsave(&interface->systime_lock, flags);
318 interface->ptp_adjust = fm10k_systime_read(interface) - ns;
319 write_unlock_irqrestore(&interface->systime_lock, flags);
320
321 return 0;
322}
323
324static int fm10k_ptp_enable(struct ptp_clock_info *ptp,
325 struct ptp_clock_request *rq, int on)
326{
327 struct ptp_clock_time *t = &rq->perout.period;
328 struct fm10k_intfc *interface;
329 struct fm10k_hw *hw;
330 u64 period;
331 u32 step;
332
333 /* we can only support periodic output */
334 if (rq->type != PTP_CLK_REQ_PEROUT)
335 return -EINVAL;
336
337 /* verify the requested channel is there */
338 if (rq->perout.index >= ptp->n_per_out)
339 return -EINVAL;
340
341 /* we cannot enforce start time as there is no
342 * mechanism for that in the hardware, we can only control
343 * the period.
344 */
345
346 /* we cannot support periods greater than 4 seconds due to reg limit */
347 if (t->sec > 4 || t->sec < 0)
348 return -ERANGE;
349
350 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
351 hw = &interface->hw;
352
353 /* we simply cannot support the operation if we don't have BAR4 */
354 if (!hw->sw_addr)
355 return -ENOTSUPP;
356
357 /* convert to unsigned 64b ns, verify we can put it in a 32b register */
358 period = t->sec * 1000000000LL + t->nsec;
359
360 /* determine the minimum size for period */
361 step = 2 * (fm10k_read_reg(hw, FM10K_SYSTIME_CFG) &
362 FM10K_SYSTIME_CFG_STEP_MASK);
363
364 /* verify the value is in range supported by hardware */
365 if ((period && (period < step)) || (period > U32_MAX))
366 return -ERANGE;
367
368 /* notify hardware of request to being sending pulses */
369 fm10k_write_sw_reg(hw, FM10K_SW_SYSTIME_PULSE(rq->perout.index),
370 (u32)period);
371
372 return 0;
373}
374
375static struct ptp_pin_desc fm10k_ptp_pd[2] = {
376 {
377 .name = "IEEE1588_PULSE0",
378 .index = 0,
379 .func = PTP_PF_PEROUT,
380 .chan = 0
381 },
382 {
383 .name = "IEEE1588_PULSE1",
384 .index = 1,
385 .func = PTP_PF_PEROUT,
386 .chan = 1
387 }
388};
389
390static int fm10k_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
391 enum ptp_pin_function func, unsigned int chan)
392{
393 /* verify the requested pin is there */
394 if (pin >= ptp->n_pins || !ptp->pin_config)
395 return -EINVAL;
396
397 /* enforce locked channels, no changing them */
398 if (chan != ptp->pin_config[pin].chan)
399 return -EINVAL;
400
401 /* we want to keep the functions locked as well */
402 if (func != ptp->pin_config[pin].func)
403 return -EINVAL;
404
405 return 0;
406}
407
408void fm10k_ptp_register(struct fm10k_intfc *interface)
409{
410 struct ptp_clock_info *ptp_caps = &interface->ptp_caps;
411 struct device *dev = &interface->pdev->dev;
412 struct ptp_clock *ptp_clock;
413
414 snprintf(ptp_caps->name, sizeof(ptp_caps->name),
415 "%s", interface->netdev->name);
416 ptp_caps->owner = THIS_MODULE;
417 /* This math is simply the inverse of the math in
418 * fm10k_adjust_systime_pf applied to an adjustment value
419 * of 2^30 - 1 which is the maximum value of the register:
420 * max_ppb == ((2^30 - 1) * 5^9) / 2^31
421 */
422 ptp_caps->max_adj = 976562;
423 ptp_caps->adjfreq = fm10k_ptp_adjfreq;
424 ptp_caps->adjtime = fm10k_ptp_adjtime;
425 ptp_caps->gettime = fm10k_ptp_gettime;
426 ptp_caps->settime = fm10k_ptp_settime;
427
428 /* provide pins if BAR4 is accessible */
429 if (interface->sw_addr) {
430 /* enable periodic outputs */
431 ptp_caps->n_per_out = 2;
432 ptp_caps->enable = fm10k_ptp_enable;
433
434 /* enable clock pins */
435 ptp_caps->verify = fm10k_ptp_verify;
436 ptp_caps->n_pins = 2;
437 ptp_caps->pin_config = fm10k_ptp_pd;
438 }
439
440 ptp_clock = ptp_clock_register(ptp_caps, dev);
441 if (IS_ERR(ptp_clock)) {
442 ptp_clock = NULL;
443 dev_err(dev, "ptp_clock_register failed\n");
444 } else {
445 dev_info(dev, "registered PHC device %s\n", ptp_caps->name);
446 }
447
448 interface->ptp_clock = ptp_clock;
449}
450
451void fm10k_ptp_unregister(struct fm10k_intfc *interface)
452{
453 struct ptp_clock *ptp_clock = interface->ptp_clock;
454 struct device *dev = &interface->pdev->dev;
455
456 if (!ptp_clock)
457 return;
458
459 interface->ptp_clock = NULL;
460
461 ptp_clock_unregister(ptp_clock);
462 dev_info(dev, "removed PHC %s\n", interface->ptp_caps.name);
463}