aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/ef10.c123
-rw-r--r--drivers/net/ethernet/sfc/efx.c2
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c3
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h22
-rw-r--r--drivers/net/ethernet/sfc/nic.h9
-rw-r--r--drivers/net/ethernet/sfc/ptp.c131
-rw-r--r--drivers/net/ethernet/sfc/rx.c2
7 files changed, 277 insertions, 15 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index ca922b958a2e..a3d891764030 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1469,8 +1469,9 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue)
1469 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_LABEL, efx_rx_queue_index(rx_queue)); 1469 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_LABEL, efx_rx_queue_index(rx_queue));
1470 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_INSTANCE, 1470 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_INSTANCE,
1471 efx_rx_queue_index(rx_queue)); 1471 efx_rx_queue_index(rx_queue));
1472 MCDI_POPULATE_DWORD_1(inbuf, INIT_RXQ_IN_FLAGS, 1472 MCDI_POPULATE_DWORD_2(inbuf, INIT_RXQ_IN_FLAGS,
1473 INIT_RXQ_IN_FLAG_PREFIX, 1); 1473 INIT_RXQ_IN_FLAG_PREFIX, 1,
1474 INIT_RXQ_IN_FLAG_TIMESTAMP, 1);
1474 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_OWNER_ID, 0); 1475 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_OWNER_ID, 0);
1475 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED); 1476 MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
1476 1477
@@ -3406,6 +3407,119 @@ static void efx_ef10_ptp_write_host_time(struct efx_nic *efx, u32 host_time)
3406 _efx_writed(efx, cpu_to_le32(host_time), ER_DZ_MC_DB_LWRD); 3407 _efx_writed(efx, cpu_to_le32(host_time), ER_DZ_MC_DB_LWRD);
3407} 3408}
3408 3409
3410static int efx_ef10_rx_enable_timestamping(struct efx_channel *channel,
3411 bool temp)
3412{
3413 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_LEN);
3414 int rc;
3415
3416 if (channel->sync_events_state == SYNC_EVENTS_REQUESTED ||
3417 channel->sync_events_state == SYNC_EVENTS_VALID ||
3418 (temp && channel->sync_events_state == SYNC_EVENTS_DISABLED))
3419 return 0;
3420 channel->sync_events_state = SYNC_EVENTS_REQUESTED;
3421
3422 MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_TIME_EVENT_SUBSCRIBE);
3423 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
3424 MCDI_SET_DWORD(inbuf, PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE,
3425 channel->channel);
3426
3427 rc = efx_mcdi_rpc(channel->efx, MC_CMD_PTP,
3428 inbuf, sizeof(inbuf), NULL, 0, NULL);
3429
3430 if (rc != 0)
3431 channel->sync_events_state = temp ? SYNC_EVENTS_QUIESCENT :
3432 SYNC_EVENTS_DISABLED;
3433
3434 return rc;
3435}
3436
3437static int efx_ef10_rx_disable_timestamping(struct efx_channel *channel,
3438 bool temp)
3439{
3440 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_LEN);
3441 int rc;
3442
3443 if (channel->sync_events_state == SYNC_EVENTS_DISABLED ||
3444 (temp && channel->sync_events_state == SYNC_EVENTS_QUIESCENT))
3445 return 0;
3446 if (channel->sync_events_state == SYNC_EVENTS_QUIESCENT) {
3447 channel->sync_events_state = SYNC_EVENTS_DISABLED;
3448 return 0;
3449 }
3450 channel->sync_events_state = temp ? SYNC_EVENTS_QUIESCENT :
3451 SYNC_EVENTS_DISABLED;
3452
3453 MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_TIME_EVENT_UNSUBSCRIBE);
3454 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
3455 MCDI_SET_DWORD(inbuf, PTP_IN_TIME_EVENT_UNSUBSCRIBE_CONTROL,
3456 MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_SINGLE);
3457 MCDI_SET_DWORD(inbuf, PTP_IN_TIME_EVENT_UNSUBSCRIBE_QUEUE,
3458 channel->channel);
3459
3460 rc = efx_mcdi_rpc(channel->efx, MC_CMD_PTP,
3461 inbuf, sizeof(inbuf), NULL, 0, NULL);
3462
3463 return rc;
3464}
3465
3466static int efx_ef10_ptp_set_ts_sync_events(struct efx_nic *efx, bool en,
3467 bool temp)
3468{
3469 int (*set)(struct efx_channel *channel, bool temp);
3470 struct efx_channel *channel;
3471
3472 set = en ?
3473 efx_ef10_rx_enable_timestamping :
3474 efx_ef10_rx_disable_timestamping;
3475
3476 efx_for_each_channel(channel, efx) {
3477 int rc = set(channel, temp);
3478 if (en && rc != 0) {
3479 efx_ef10_ptp_set_ts_sync_events(efx, false, temp);
3480 return rc;
3481 }
3482 }
3483
3484 return 0;
3485}
3486
3487static int efx_ef10_ptp_set_ts_config(struct efx_nic *efx,
3488 struct hwtstamp_config *init)
3489{
3490 int rc;
3491
3492 switch (init->rx_filter) {
3493 case HWTSTAMP_FILTER_NONE:
3494 efx_ef10_ptp_set_ts_sync_events(efx, false, false);
3495 /* if TX timestamping is still requested then leave PTP on */
3496 return efx_ptp_change_mode(efx,
3497 init->tx_type != HWTSTAMP_TX_OFF, 0);
3498 case HWTSTAMP_FILTER_ALL:
3499 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
3500 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
3501 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
3502 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
3503 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
3504 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
3505 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
3506 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
3507 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
3508 case HWTSTAMP_FILTER_PTP_V2_EVENT:
3509 case HWTSTAMP_FILTER_PTP_V2_SYNC:
3510 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
3511 init->rx_filter = HWTSTAMP_FILTER_ALL;
3512 rc = efx_ptp_change_mode(efx, true, 0);
3513 if (!rc)
3514 rc = efx_ef10_ptp_set_ts_sync_events(efx, true, false);
3515 if (rc)
3516 efx_ptp_change_mode(efx, false, 0);
3517 return rc;
3518 default:
3519 return -ERANGE;
3520 }
3521}
3522
3409const struct efx_nic_type efx_hunt_a0_nic_type = { 3523const struct efx_nic_type efx_hunt_a0_nic_type = {
3410 .mem_map_size = efx_ef10_mem_map_size, 3524 .mem_map_size = efx_ef10_mem_map_size,
3411 .probe = efx_ef10_probe, 3525 .probe = efx_ef10_probe,
@@ -3484,11 +3598,14 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
3484 .mtd_sync = efx_mcdi_mtd_sync, 3598 .mtd_sync = efx_mcdi_mtd_sync,
3485#endif 3599#endif
3486 .ptp_write_host_time = efx_ef10_ptp_write_host_time, 3600 .ptp_write_host_time = efx_ef10_ptp_write_host_time,
3601 .ptp_set_ts_sync_events = efx_ef10_ptp_set_ts_sync_events,
3602 .ptp_set_ts_config = efx_ef10_ptp_set_ts_config,
3487 3603
3488 .revision = EFX_REV_HUNT_A0, 3604 .revision = EFX_REV_HUNT_A0,
3489 .max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH), 3605 .max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH),
3490 .rx_prefix_size = ES_DZ_RX_PREFIX_SIZE, 3606 .rx_prefix_size = ES_DZ_RX_PREFIX_SIZE,
3491 .rx_hash_offset = ES_DZ_RX_PREFIX_HASH_OFST, 3607 .rx_hash_offset = ES_DZ_RX_PREFIX_HASH_OFST,
3608 .rx_ts_offset = ES_DZ_RX_PREFIX_TSTAMP_OFST,
3492 .can_rx_scatter = true, 3609 .can_rx_scatter = true,
3493 .always_rx_scatter = true, 3610 .always_rx_scatter = true,
3494 .max_interrupt_mode = EFX_INT_MODE_MSIX, 3611 .max_interrupt_mode = EFX_INT_MODE_MSIX,
@@ -3497,4 +3614,6 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
3497 NETIF_F_RXHASH | NETIF_F_NTUPLE), 3614 NETIF_F_RXHASH | NETIF_F_NTUPLE),
3498 .mcdi_max_ver = 2, 3615 .mcdi_max_ver = 2,
3499 .max_rx_ip_filters = HUNT_FILTER_TBL_ROWS, 3616 .max_rx_ip_filters = HUNT_FILTER_TBL_ROWS,
3617 .hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
3618 1 << HWTSTAMP_FILTER_ALL,
3500}; 3619};
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 893cd78c3a6c..b9929d9ed69d 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2586,6 +2586,8 @@ static int efx_init_struct(struct efx_nic *efx,
2586 NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0; 2586 NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
2587 efx->rx_packet_hash_offset = 2587 efx->rx_packet_hash_offset =
2588 efx->type->rx_hash_offset - efx->type->rx_prefix_size; 2588 efx->type->rx_hash_offset - efx->type->rx_prefix_size;
2589 efx->rx_packet_ts_offset =
2590 efx->type->rx_ts_offset - efx->type->rx_prefix_size;
2589 spin_lock_init(&efx->stats_lock); 2591 spin_lock_init(&efx->stats_lock);
2590 mutex_init(&efx->mac_lock); 2592 mutex_init(&efx->mac_lock);
2591 efx->phy_op = &efx_dummy_phy_operations; 2593 efx->phy_op = &efx_dummy_phy_operations;
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index d608838f6729..540f57915d6f 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -1018,6 +1018,9 @@ void efx_mcdi_process_event(struct efx_channel *channel,
1018 case MCDI_EVENT_CODE_PTP_PPS: 1018 case MCDI_EVENT_CODE_PTP_PPS:
1019 efx_ptp_event(efx, event); 1019 efx_ptp_event(efx, event);
1020 break; 1020 break;
1021 case MCDI_EVENT_CODE_PTP_TIME:
1022 efx_time_sync_event(channel, event);
1023 break;
1021 case MCDI_EVENT_CODE_TX_FLUSH: 1024 case MCDI_EVENT_CODE_TX_FLUSH:
1022 case MCDI_EVENT_CODE_RX_FLUSH: 1025 case MCDI_EVENT_CODE_RX_FLUSH:
1023 /* Two flush events will be sent: one to the same event 1026 /* Two flush events will be sent: one to the same event
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 1a3e4972c68f..0d0e8eb88332 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -369,6 +369,13 @@ enum efx_rx_alloc_method {
369 RX_ALLOC_METHOD_PAGE = 2, 369 RX_ALLOC_METHOD_PAGE = 2,
370}; 370};
371 371
372enum efx_sync_events_state {
373 SYNC_EVENTS_DISABLED = 0,
374 SYNC_EVENTS_QUIESCENT,
375 SYNC_EVENTS_REQUESTED,
376 SYNC_EVENTS_VALID,
377};
378
372/** 379/**
373 * struct efx_channel - An Efx channel 380 * struct efx_channel - An Efx channel
374 * 381 *
@@ -408,6 +415,9 @@ enum efx_rx_alloc_method {
408 * by __efx_rx_packet(), if @rx_pkt_n_frags != 0 415 * by __efx_rx_packet(), if @rx_pkt_n_frags != 0
409 * @rx_queue: RX queue for this channel 416 * @rx_queue: RX queue for this channel
410 * @tx_queue: TX queues for this channel 417 * @tx_queue: TX queues for this channel
418 * @sync_events_state: Current state of sync events on this channel
419 * @sync_timestamp_major: Major part of the last ptp sync event
420 * @sync_timestamp_minor: Minor part of the last ptp sync event
411 */ 421 */
412struct efx_channel { 422struct efx_channel {
413 struct efx_nic *efx; 423 struct efx_nic *efx;
@@ -446,6 +456,10 @@ struct efx_channel {
446 456
447 struct efx_rx_queue rx_queue; 457 struct efx_rx_queue rx_queue;
448 struct efx_tx_queue tx_queue[EFX_TXQ_TYPES]; 458 struct efx_tx_queue tx_queue[EFX_TXQ_TYPES];
459
460 enum efx_sync_events_state sync_events_state;
461 u32 sync_timestamp_major;
462 u32 sync_timestamp_minor;
449}; 463};
450 464
451/** 465/**
@@ -686,6 +700,8 @@ struct vfdi_status;
686 * (valid only if @rx_prefix_size != 0; always negative) 700 * (valid only if @rx_prefix_size != 0; always negative)
687 * @rx_packet_len_offset: Offset of RX packet length from start of packet data 701 * @rx_packet_len_offset: Offset of RX packet length from start of packet data
688 * (valid only for NICs that set %EFX_RX_PKT_PREFIX_LEN; always negative) 702 * (valid only for NICs that set %EFX_RX_PKT_PREFIX_LEN; always negative)
703 * @rx_packet_ts_offset: Offset of timestamp from start of packet data
704 * (valid only if channel->sync_timestamps_enabled; always negative)
689 * @rx_hash_key: Toeplitz hash key for RSS 705 * @rx_hash_key: Toeplitz hash key for RSS
690 * @rx_indir_table: Indirection table for RSS 706 * @rx_indir_table: Indirection table for RSS
691 * @rx_scatter: Scatter mode enabled for receives 707 * @rx_scatter: Scatter mode enabled for receives
@@ -820,6 +836,7 @@ struct efx_nic {
820 unsigned int rx_prefix_size; 836 unsigned int rx_prefix_size;
821 int rx_packet_hash_offset; 837 int rx_packet_hash_offset;
822 int rx_packet_len_offset; 838 int rx_packet_len_offset;
839 int rx_packet_ts_offset;
823 u8 rx_hash_key[40]; 840 u8 rx_hash_key[40];
824 u32 rx_indir_table[128]; 841 u32 rx_indir_table[128];
825 bool rx_scatter; 842 bool rx_scatter;
@@ -1035,6 +1052,8 @@ struct efx_mtd_partition {
1035 * also notifies the driver that a writer has finished using this 1052 * also notifies the driver that a writer has finished using this
1036 * partition. 1053 * partition.
1037 * @ptp_write_host_time: Send host time to MC as part of sync protocol 1054 * @ptp_write_host_time: Send host time to MC as part of sync protocol
1055 * @ptp_set_ts_sync_events: Enable or disable sync events for inline RX
1056 * timestamping, possibly only temporarily for the purposes of a reset.
1038 * @ptp_set_ts_config: Set hardware timestamp configuration. The flags 1057 * @ptp_set_ts_config: Set hardware timestamp configuration. The flags
1039 * and tx_type will already have been validated but this operation 1058 * and tx_type will already have been validated but this operation
1040 * must validate and update rx_filter. 1059 * must validate and update rx_filter.
@@ -1047,6 +1066,7 @@ struct efx_mtd_partition {
1047 * @max_dma_mask: Maximum possible DMA mask 1066 * @max_dma_mask: Maximum possible DMA mask
1048 * @rx_prefix_size: Size of RX prefix before packet data 1067 * @rx_prefix_size: Size of RX prefix before packet data
1049 * @rx_hash_offset: Offset of RX flow hash within prefix 1068 * @rx_hash_offset: Offset of RX flow hash within prefix
1069 * @rx_ts_offset: Offset of timestamp within prefix
1050 * @rx_buffer_padding: Size of padding at end of RX packet 1070 * @rx_buffer_padding: Size of padding at end of RX packet
1051 * @can_rx_scatter: NIC is able to scatter packets to multiple buffers 1071 * @can_rx_scatter: NIC is able to scatter packets to multiple buffers
1052 * @always_rx_scatter: NIC will always scatter packets to multiple buffers 1072 * @always_rx_scatter: NIC will always scatter packets to multiple buffers
@@ -1158,6 +1178,7 @@ struct efx_nic_type {
1158 int (*mtd_sync)(struct mtd_info *mtd); 1178 int (*mtd_sync)(struct mtd_info *mtd);
1159#endif 1179#endif
1160 void (*ptp_write_host_time)(struct efx_nic *efx, u32 host_time); 1180 void (*ptp_write_host_time)(struct efx_nic *efx, u32 host_time);
1181 int (*ptp_set_ts_sync_events)(struct efx_nic *efx, bool en, bool temp);
1161 int (*ptp_set_ts_config)(struct efx_nic *efx, 1182 int (*ptp_set_ts_config)(struct efx_nic *efx,
1162 struct hwtstamp_config *init); 1183 struct hwtstamp_config *init);
1163 1184
@@ -1170,6 +1191,7 @@ struct efx_nic_type {
1170 u64 max_dma_mask; 1191 u64 max_dma_mask;
1171 unsigned int rx_prefix_size; 1192 unsigned int rx_prefix_size;
1172 unsigned int rx_hash_offset; 1193 unsigned int rx_hash_offset;
1194 unsigned int rx_ts_offset;
1173 unsigned int rx_buffer_padding; 1195 unsigned int rx_buffer_padding;
1174 bool can_rx_scatter; 1196 bool can_rx_scatter;
1175 bool always_rx_scatter; 1197 bool always_rx_scatter;
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 999ef285662d..5d9e2dc121f7 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -566,6 +566,15 @@ int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
566 unsigned int new_mode); 566 unsigned int new_mode);
567int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); 567int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
568void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); 568void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
569void efx_time_sync_event(struct efx_channel *channel, efx_qword_t *ev);
570void __efx_rx_skb_attach_timestamp(struct efx_channel *channel,
571 struct sk_buff *skb);
572static inline void efx_rx_skb_attach_timestamp(struct efx_channel *channel,
573 struct sk_buff *skb)
574{
575 if (channel->sync_events_state == SYNC_EVENTS_VALID)
576 __efx_rx_skb_attach_timestamp(channel, skb);
577}
569void efx_ptp_start_datapath(struct efx_nic *efx); 578void efx_ptp_start_datapath(struct efx_nic *efx);
570void efx_ptp_stop_datapath(struct efx_nic *efx); 579void efx_ptp_stop_datapath(struct efx_nic *efx);
571 580
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 1d1a6f7325da..843e98dfb1b2 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -216,6 +216,8 @@ struct efx_ptp_timeset {
216 * struct efx_ptp_data - Precision Time Protocol (PTP) state 216 * struct efx_ptp_data - Precision Time Protocol (PTP) state
217 * @efx: The NIC context 217 * @efx: The NIC context
218 * @channel: The PTP channel (Siena only) 218 * @channel: The PTP channel (Siena only)
219 * @rx_ts_inline: Flag for whether RX timestamps are inline (else they are
220 * separate events)
219 * @rxq: Receive queue (awaiting timestamps) 221 * @rxq: Receive queue (awaiting timestamps)
220 * @txq: Transmit queue 222 * @txq: Transmit queue
221 * @evt_list: List of MC receive events awaiting packets 223 * @evt_list: List of MC receive events awaiting packets
@@ -258,6 +260,7 @@ struct efx_ptp_timeset {
258struct efx_ptp_data { 260struct efx_ptp_data {
259 struct efx_nic *efx; 261 struct efx_nic *efx;
260 struct efx_channel *channel; 262 struct efx_channel *channel;
263 bool rx_ts_inline;
261 struct sk_buff_head rxq; 264 struct sk_buff_head rxq;
262 struct sk_buff_head txq; 265 struct sk_buff_head txq;
263 struct list_head evt_list; 266 struct list_head evt_list;
@@ -317,8 +320,8 @@ static void efx_ptp_ns_to_s_ns(s64 ns, u32 *nic_major, u32 *nic_minor)
317 *nic_minor = ts.tv_nsec; 320 *nic_minor = ts.tv_nsec;
318} 321}
319 322
320static ktime_t efx_ptp_s_ns_to_ktime(u32 nic_major, u32 nic_minor, 323static ktime_t efx_ptp_s_ns_to_ktime_correction(u32 nic_major, u32 nic_minor,
321 s32 correction) 324 s32 correction)
322{ 325{
323 ktime_t kt = ktime_set(nic_major, nic_minor); 326 ktime_t kt = ktime_set(nic_major, nic_minor);
324 if (correction >= 0) 327 if (correction >= 0)
@@ -359,11 +362,16 @@ static void efx_ptp_ns_to_s27(s64 ns, u32 *nic_major, u32 *nic_minor)
359 *nic_minor = min; 362 *nic_minor = min;
360} 363}
361 364
362static ktime_t efx_ptp_s27_to_ktime(u32 nic_major, u32 nic_minor, 365static inline ktime_t efx_ptp_s27_to_ktime(u32 nic_major, u32 nic_minor)
363 s32 correction)
364{ 366{
365 u32 ns; 367 u32 ns = (u32)(((u64)nic_minor * NSEC_PER_SEC +
368 (1ULL << (S27_TO_NS_SHIFT - 1))) >> S27_TO_NS_SHIFT);
369 return ktime_set(nic_major, ns);
370}
366 371
372static ktime_t efx_ptp_s27_to_ktime_correction(u32 nic_major, u32 nic_minor,
373 s32 correction)
374{
367 /* Apply the correction and deal with carry */ 375 /* Apply the correction and deal with carry */
368 nic_minor += correction; 376 nic_minor += correction;
369 if ((s32)nic_minor < 0) { 377 if ((s32)nic_minor < 0) {
@@ -374,10 +382,7 @@ static ktime_t efx_ptp_s27_to_ktime(u32 nic_major, u32 nic_minor,
374 nic_major++; 382 nic_major++;
375 } 383 }
376 384
377 ns = (u32)(((u64)nic_minor * NSEC_PER_SEC + 385 return efx_ptp_s27_to_ktime(nic_major, nic_minor);
378 (1ULL << (S27_TO_NS_SHIFT - 1))) >> S27_TO_NS_SHIFT);
379
380 return ktime_set(nic_major, ns);
381} 386}
382 387
383/* Get PTP attributes and set up time conversions */ 388/* Get PTP attributes and set up time conversions */
@@ -407,10 +412,10 @@ static int efx_ptp_get_attributes(struct efx_nic *efx)
407 412
408 if (fmt == MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_27FRACTION) { 413 if (fmt == MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_27FRACTION) {
409 ptp->ns_to_nic_time = efx_ptp_ns_to_s27; 414 ptp->ns_to_nic_time = efx_ptp_ns_to_s27;
410 ptp->nic_to_kernel_time = efx_ptp_s27_to_ktime; 415 ptp->nic_to_kernel_time = efx_ptp_s27_to_ktime_correction;
411 } else if (fmt == MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_NANOSECONDS) { 416 } else if (fmt == MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_NANOSECONDS) {
412 ptp->ns_to_nic_time = efx_ptp_ns_to_s_ns; 417 ptp->ns_to_nic_time = efx_ptp_ns_to_s_ns;
413 ptp->nic_to_kernel_time = efx_ptp_s_ns_to_ktime; 418 ptp->nic_to_kernel_time = efx_ptp_s_ns_to_ktime_correction;
414 } else { 419 } else {
415 return -ERANGE; 420 return -ERANGE;
416 } 421 }
@@ -806,6 +811,9 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx)
806 struct list_head *cursor; 811 struct list_head *cursor;
807 struct list_head *next; 812 struct list_head *next;
808 813
814 if (ptp->rx_ts_inline)
815 return;
816
809 /* Drop time-expired events */ 817 /* Drop time-expired events */
810 spin_lock_bh(&ptp->evt_lock); 818 spin_lock_bh(&ptp->evt_lock);
811 if (!list_empty(&ptp->evt_list)) { 819 if (!list_empty(&ptp->evt_list)) {
@@ -839,6 +847,8 @@ static enum ptp_packet_state efx_ptp_match_rx(struct efx_nic *efx,
839 struct efx_ptp_match *match; 847 struct efx_ptp_match *match;
840 enum ptp_packet_state rc = PTP_PACKET_STATE_UNMATCHED; 848 enum ptp_packet_state rc = PTP_PACKET_STATE_UNMATCHED;
841 849
850 WARN_ON_ONCE(ptp->rx_ts_inline);
851
842 spin_lock_bh(&ptp->evt_lock); 852 spin_lock_bh(&ptp->evt_lock);
843 evts_waiting = !list_empty(&ptp->evt_list); 853 evts_waiting = !list_empty(&ptp->evt_list);
844 spin_unlock_bh(&ptp->evt_lock); 854 spin_unlock_bh(&ptp->evt_lock);
@@ -1061,8 +1071,6 @@ static void efx_ptp_pps_worker(struct work_struct *work)
1061 ptp_clock_event(ptp->phc_clock, &ptp_evt); 1071 ptp_clock_event(ptp->phc_clock, &ptp_evt);
1062} 1072}
1063 1073
1064/* Process any pending transmissions and timestamp any received packets.
1065 */
1066static void efx_ptp_worker(struct work_struct *work) 1074static void efx_ptp_worker(struct work_struct *work)
1067{ 1075{
1068 struct efx_ptp_data *ptp_data = 1076 struct efx_ptp_data *ptp_data =
@@ -1120,6 +1128,7 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
1120 1128
1121 ptp->efx = efx; 1129 ptp->efx = efx;
1122 ptp->channel = channel; 1130 ptp->channel = channel;
1131 ptp->rx_ts_inline = efx_nic_rev(efx) >= EFX_REV_HUNT_A0;
1123 1132
1124 rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL); 1133 rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL);
1125 if (rc != 0) 1134 if (rc != 0)
@@ -1491,6 +1500,9 @@ static void ptp_event_rx(struct efx_nic *efx, struct efx_ptp_data *ptp)
1491{ 1500{
1492 struct efx_ptp_event_rx *evt = NULL; 1501 struct efx_ptp_event_rx *evt = NULL;
1493 1502
1503 if (WARN_ON_ONCE(ptp->rx_ts_inline))
1504 return;
1505
1494 if (ptp->evt_frag_idx != 3) { 1506 if (ptp->evt_frag_idx != 3) {
1495 ptp_event_failure(efx, 3); 1507 ptp_event_failure(efx, 3);
1496 return; 1508 return;
@@ -1587,6 +1599,93 @@ void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev)
1587 } 1599 }
1588} 1600}
1589 1601
1602void efx_time_sync_event(struct efx_channel *channel, efx_qword_t *ev)
1603{
1604 channel->sync_timestamp_major = MCDI_EVENT_FIELD(*ev, PTP_TIME_MAJOR);
1605 channel->sync_timestamp_minor =
1606 MCDI_EVENT_FIELD(*ev, PTP_TIME_MINOR_26_19) << 19;
1607 /* if sync events have been disabled then we want to silently ignore
1608 * this event, so throw away result.
1609 */
1610 (void) cmpxchg(&channel->sync_events_state, SYNC_EVENTS_REQUESTED,
1611 SYNC_EVENTS_VALID);
1612}
1613
1614/* make some assumptions about the time representation rather than abstract it,
1615 * since we currently only support one type of inline timestamping and only on
1616 * EF10.
1617 */
1618#define MINOR_TICKS_PER_SECOND 0x8000000
1619/* Fuzz factor for sync events to be out of order with RX events */
1620#define FUZZ (MINOR_TICKS_PER_SECOND / 10)
1621#define EXPECTED_SYNC_EVENTS_PER_SECOND 4
1622
1623static inline u32 efx_rx_buf_timestamp_minor(struct efx_nic *efx, const u8 *eh)
1624{
1625#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
1626 return __le32_to_cpup((const __le32 *)(eh + efx->rx_packet_ts_offset));
1627#else
1628 const u8 *data = eh + efx->rx_packet_ts_offset;
1629 return (u32)data[0] |
1630 (u32)data[1] << 8 |
1631 (u32)data[2] << 16 |
1632 (u32)data[3] << 24;
1633#endif
1634}
1635
1636void __efx_rx_skb_attach_timestamp(struct efx_channel *channel,
1637 struct sk_buff *skb)
1638{
1639 struct efx_nic *efx = channel->efx;
1640 u32 pkt_timestamp_major, pkt_timestamp_minor;
1641 u32 diff, carry;
1642 struct skb_shared_hwtstamps *timestamps;
1643
1644 pkt_timestamp_minor = (efx_rx_buf_timestamp_minor(efx,
1645 skb_mac_header(skb)) +
1646 (u32) efx->ptp_data->ts_corrections.rx) &
1647 (MINOR_TICKS_PER_SECOND - 1);
1648
1649 /* get the difference between the packet and sync timestamps,
1650 * modulo one second
1651 */
1652 diff = (pkt_timestamp_minor - channel->sync_timestamp_minor) &
1653 (MINOR_TICKS_PER_SECOND - 1);
1654 /* do we roll over a second boundary and need to carry the one? */
1655 carry = channel->sync_timestamp_minor + diff > MINOR_TICKS_PER_SECOND ?
1656 1 : 0;
1657
1658 if (diff <= MINOR_TICKS_PER_SECOND / EXPECTED_SYNC_EVENTS_PER_SECOND +
1659 FUZZ) {
1660 /* packet is ahead of the sync event by a quarter of a second or
1661 * less (allowing for fuzz)
1662 */
1663 pkt_timestamp_major = channel->sync_timestamp_major + carry;
1664 } else if (diff >= MINOR_TICKS_PER_SECOND - FUZZ) {
1665 /* packet is behind the sync event but within the fuzz factor.
1666 * This means the RX packet and sync event crossed as they were
1667 * placed on the event queue, which can sometimes happen.
1668 */
1669 pkt_timestamp_major = channel->sync_timestamp_major - 1 + carry;
1670 } else {
1671 /* it's outside tolerance in both directions. this might be
1672 * indicative of us missing sync events for some reason, so
1673 * we'll call it an error rather than risk giving a bogus
1674 * timestamp.
1675 */
1676 netif_vdbg(efx, drv, efx->net_dev,
1677 "packet timestamp %x too far from sync event %x:%x\n",
1678 pkt_timestamp_minor, channel->sync_timestamp_major,
1679 channel->sync_timestamp_minor);
1680 return;
1681 }
1682
1683 /* attach the timestamps to the skb */
1684 timestamps = skb_hwtstamps(skb);
1685 timestamps->hwtstamp =
1686 efx_ptp_s27_to_ktime(pkt_timestamp_major, pkt_timestamp_minor);
1687}
1688
1590static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) 1689static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
1591{ 1690{
1592 struct efx_ptp_data *ptp_data = container_of(ptp, 1691 struct efx_ptp_data *ptp_data = container_of(ptp,
@@ -1728,9 +1827,15 @@ void efx_ptp_start_datapath(struct efx_nic *efx)
1728{ 1827{
1729 if (efx_ptp_restart(efx)) 1828 if (efx_ptp_restart(efx))
1730 netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n"); 1829 netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n");
1830 /* re-enable timestamping if it was previously enabled */
1831 if (efx->type->ptp_set_ts_sync_events)
1832 efx->type->ptp_set_ts_sync_events(efx, true, true);
1731} 1833}
1732 1834
1733void efx_ptp_stop_datapath(struct efx_nic *efx) 1835void efx_ptp_stop_datapath(struct efx_nic *efx)
1734{ 1836{
1837 /* temporarily disable timestamping */
1838 if (efx->type->ptp_set_ts_sync_events)
1839 efx->type->ptp_set_ts_sync_events(efx, false, true);
1735 efx_ptp_stop(efx); 1840 efx_ptp_stop(efx);
1736} 1841}
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index d12abc543975..1fde9b8ac456 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -624,6 +624,8 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh,
624 if (likely(rx_buf->flags & EFX_RX_PKT_CSUMMED)) 624 if (likely(rx_buf->flags & EFX_RX_PKT_CSUMMED))
625 skb->ip_summed = CHECKSUM_UNNECESSARY; 625 skb->ip_summed = CHECKSUM_UNNECESSARY;
626 626
627 efx_rx_skb_attach_timestamp(channel, skb);
628
627 if (channel->type->receive_skb) 629 if (channel->type->receive_skb)
628 if (channel->type->receive_skb(channel, skb)) 630 if (channel->type->receive_skb(channel, skb))
629 return; 631 return;