From 6778948f9de86c3cfaf36725a7c87dcff9ba247f Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 08:20:59 +0000 Subject: [PATCH] kernel_5.10 no rt --- kernel/drivers/net/ethernet/sfc/ptp.c | 81 +++++++++++++++++++++++++++------------- 1 files changed, 55 insertions(+), 26 deletions(-) diff --git a/kernel/drivers/net/ethernet/sfc/ptp.c b/kernel/drivers/net/ethernet/sfc/ptp.c index c0a810f..a2b4e3b 100644 --- a/kernel/drivers/net/ethernet/sfc/ptp.c +++ b/kernel/drivers/net/ethernet/sfc/ptp.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** * Driver for Solarflare network controllers and boards * Copyright 2011-2013 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. */ /* Theory of operation: @@ -38,7 +35,6 @@ #include <linux/time.h> #include <linux/ktime.h> #include <linux/module.h> -#include <linux/net_tstamp.h> #include <linux/pps_kernel.h> #include <linux/ptp_clock_kernel.h> #include "net_driver.h" @@ -47,7 +43,9 @@ #include "mcdi_pcol.h" #include "io.h" #include "farch_regs.h" -#include "nic.h" +#include "tx.h" +#include "nic.h" /* indirectly includes ptp.h */ +#include "efx_channels.h" /* Maximum number of events expected to make up a PTP event */ #define MAX_EVENT_FRAGS 3 @@ -176,9 +174,11 @@ /** * struct efx_ptp_event_rx - A PTP receive event (from MC) + * @link: list of events * @seq0: First part of (PTP) UUID * @seq1: Second part of (PTP) UUID and sequence number * @hwtimestamp: Event timestamp + * @expiry: Time which the packet arrived */ struct efx_ptp_event_rx { struct list_head link; @@ -226,11 +226,13 @@ * reset (disable, enable). * @rxfilter_event: Receive filter when operating * @rxfilter_general: Receive filter when operating + * @rxfilter_installed: Receive filter installed * @config: Current timestamp configuration * @enabled: PTP operation enabled * @mode: Mode in which PTP operating (PTP version) * @ns_to_nic_time: Function to convert from scalar nanoseconds to NIC time * @nic_to_kernel_time: Function to convert from NIC to kernel time + * @nic_time: contains time details * @nic_time.minor_max: Wrap point for NIC minor times * @nic_time.sync_event_diff_min: Minimum acceptable difference between time * in packet prefix and last MCDI time sync event i.e. how much earlier than @@ -242,6 +244,7 @@ * field in MCDI time sync event. * @min_synchronisation_ns: Minimum acceptable corrected sync window * @capabilities: Capabilities flags from the NIC + * @ts_corrections: contains corrections details * @ts_corrections.ptp_tx: Required driver correction of PTP packet transmit * timestamps * @ts_corrections.ptp_rx: Required driver correction of PTP packet receive @@ -329,7 +332,7 @@ struct work_struct pps_work; struct workqueue_struct *pps_workwq; bool nic_ts_enabled; - _MCDI_DECLARE_BUF(txbuf, MC_CMD_PTP_IN_TRANSMIT_LENMAX); + efx_dword_t txbuf[MCDI_TX_BUF_LEN(MC_CMD_PTP_IN_TRANSMIT_LENMAX)]; unsigned int good_syncs; unsigned int fast_syncs; @@ -355,12 +358,7 @@ bool efx_ptp_use_mac_tx_timestamps(struct efx_nic *efx) { - struct efx_ef10_nic_data *nic_data = efx->nic_data; - - return ((efx_nic_rev(efx) >= EFX_REV_HUNT_A0) && - (nic_data->datapath_caps2 & - (1 << MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MAC_TIMESTAMPING_LBN) - )); + return efx_has_cap(efx, TX_MAC_TIMESTAMPING); } /* PTP 'extra' channel is still a traffic channel, but we only create TX queues @@ -542,6 +540,12 @@ struct efx_channel *efx_ptp_channel(struct efx_nic *efx) { return efx->ptp_data ? efx->ptp_data->channel : NULL; +} + +void efx_ptp_update_channel(struct efx_nic *efx, struct efx_channel *channel) +{ + if (efx->ptp_data) + efx->ptp_data->channel = channel; } static u32 last_sync_timestamp_major(struct efx_nic *efx) @@ -1091,12 +1095,34 @@ static void efx_ptp_xmit_skb_queue(struct efx_nic *efx, struct sk_buff *skb) { struct efx_ptp_data *ptp_data = efx->ptp_data; + u8 type = efx_tx_csum_type_skb(skb); struct efx_tx_queue *tx_queue; - u8 type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0; - tx_queue = &ptp_data->channel->tx_queue[type]; + tx_queue = efx_channel_get_tx_queue(ptp_data->channel, type); if (tx_queue && tx_queue->timestamping) { + /* This code invokes normal driver TX code which is always + * protected from softirqs when called from generic TX code, + * which in turn disables preemption. Look at __dev_queue_xmit + * which uses rcu_read_lock_bh disabling preemption for RCU + * plus disabling softirqs. We do not need RCU reader + * protection here. + * + * Although it is theoretically safe for current PTP TX/RX code + * running without disabling softirqs, there are three good + * reasond for doing so: + * + * 1) The code invoked is mainly implemented for non-PTP + * packets and it is always executed with softirqs + * disabled. + * 2) This being a single PTP packet, better to not + * interrupt its processing by softirqs which can lead + * to high latencies. + * 3) netdev_xmit_more checks preemption is disabled and + * triggers a BUG_ON if not. + */ + local_bh_disable(); efx_enqueue_skb(tx_queue, skb); + local_bh_enable(); } else { WARN_ONCE(1, "PTP channel has no timestamped tx queue\n"); dev_kfree_skb_any(skb); @@ -1163,17 +1189,15 @@ /* Drop time-expired events */ spin_lock_bh(&ptp->evt_lock); - if (!list_empty(&ptp->evt_list)) { - list_for_each_safe(cursor, next, &ptp->evt_list) { - struct efx_ptp_event_rx *evt; + list_for_each_safe(cursor, next, &ptp->evt_list) { + struct efx_ptp_event_rx *evt; - evt = list_entry(cursor, struct efx_ptp_event_rx, - link); - if (time_after(jiffies, evt->expiry)) { - list_move(&evt->link, &ptp->evt_free_list); - netif_warn(efx, hw, efx->net_dev, - "PTP rx event dropped\n"); - } + evt = list_entry(cursor, struct efx_ptp_event_rx, + link); + if (time_after(jiffies, evt->expiry)) { + list_move(&evt->link, &ptp->evt_free_list); + netif_warn(efx, hw, efx->net_dev, + "PTP rx event dropped\n"); } } spin_unlock_bh(&ptp->evt_lock); @@ -1447,6 +1471,11 @@ struct efx_ptp_data *ptp; int rc = 0; unsigned int pos; + + if (efx->ptp_data) { + efx->ptp_data->channel = channel; + return 0; + } ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); efx->ptp_data = ptp; @@ -2184,7 +2213,7 @@ .pre_probe = efx_ptp_probe_channel, .post_remove = efx_ptp_remove_channel, .get_name = efx_ptp_get_channel_name, - /* no copy operation; there is no need to reallocate this channel */ + .copy = efx_copy_channel, .receive_skb = efx_ptp_rx, .want_txqs = efx_ptp_want_txqs, .keep_eventq = false, -- Gitblit v1.6.2