Skip to content

Commit ac36baf

Browse files
author
Ben Hutchings
committed
sfc: Remove dependency of PTP on having a dedicated channel
We need a dedicated channel on Siena to ensure we can match up the separate RX and timestamp events for each PTP packet. We won't do this for EF10 as timestamps are delivered inline. Pass a channel index of 0 to MC_CMD_PTP_OP_ENABLE when there is no dedicated channel. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
1 parent 62a1c70 commit ac36baf

File tree

3 files changed

+41
-24
lines changed

3 files changed

+41
-24
lines changed

drivers/net/ethernet/sfc/nic.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,9 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
554554
bool spoofchk);
555555

556556
struct ethtool_ts_info;
557-
void efx_ptp_probe(struct efx_nic *efx);
557+
int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel);
558+
void efx_ptp_defer_probe_with_channel(struct efx_nic *efx);
559+
void efx_ptp_remove(struct efx_nic *efx);
558560
int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr);
559561
int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
560562
void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);

drivers/net/ethernet/sfc/ptp.c

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ struct efx_ptp_timeset {
214214

215215
/**
216216
* struct efx_ptp_data - Precision Time Protocol (PTP) state
217-
* @channel: The PTP channel
217+
* @efx: The NIC context
218+
* @channel: The PTP channel (Siena only)
218219
* @rxq: Receive queue (awaiting timestamps)
219220
* @txq: Transmit queue
220221
* @evt_list: List of MC receive events awaiting packets
@@ -265,6 +266,7 @@ struct efx_ptp_timeset {
265266
* @timeset: Last set of synchronisation statistics.
266267
*/
267268
struct efx_ptp_data {
269+
struct efx_nic *efx;
268270
struct efx_channel *channel;
269271
struct sk_buff_head rxq;
270272
struct sk_buff_head txq;
@@ -319,7 +321,8 @@ static int efx_ptp_enable(struct efx_nic *efx)
319321
MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE);
320322
MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
321323
MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_QUEUE,
322-
efx->ptp_data->channel->channel);
324+
efx->ptp_data->channel ?
325+
efx->ptp_data->channel->channel : 0);
323326
MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode);
324327

325328
rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
@@ -774,7 +777,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
774777
struct efx_filter_spec rxfilter;
775778
int rc;
776779

777-
if (ptp->rxfilter_installed)
780+
if (!ptp->channel || ptp->rxfilter_installed)
778781
return 0;
779782

780783
/* Must filter on both event and general ports to ensure
@@ -882,7 +885,7 @@ static void efx_ptp_pps_worker(struct work_struct *work)
882885
{
883886
struct efx_ptp_data *ptp =
884887
container_of(work, struct efx_ptp_data, pps_work);
885-
struct efx_nic *efx = ptp->channel->efx;
888+
struct efx_nic *efx = ptp->efx;
886889
struct ptp_clock_event ptp_evt;
887890

888891
if (efx_ptp_synchronize(efx, PTP_SYNC_ATTEMPTS))
@@ -899,7 +902,7 @@ static void efx_ptp_worker(struct work_struct *work)
899902
{
900903
struct efx_ptp_data *ptp_data =
901904
container_of(work, struct efx_ptp_data, work);
902-
struct efx_nic *efx = ptp_data->channel->efx;
905+
struct efx_nic *efx = ptp_data->efx;
903906
struct sk_buff *skb;
904907
struct sk_buff_head tempq;
905908

@@ -923,31 +926,25 @@ static void efx_ptp_worker(struct work_struct *work)
923926
efx_ptp_process_rx(efx, skb);
924927
}
925928

926-
/* Initialise PTP channel and state.
927-
*
928-
* Setting core_index to zero causes the queue to be initialised and doesn't
929-
* overlap with 'rxq0' because ptp.c doesn't use skb_record_rx_queue.
930-
*/
931-
static int efx_ptp_probe_channel(struct efx_channel *channel)
929+
/* Initialise PTP state. */
930+
int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
932931
{
933-
struct efx_nic *efx = channel->efx;
934932
struct efx_ptp_data *ptp;
935933
int rc = 0;
936934
unsigned int pos;
937935

938-
channel->irq_moderation = 0;
939-
channel->rx_queue.core_index = 0;
940-
941936
ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL);
942937
efx->ptp_data = ptp;
943938
if (!efx->ptp_data)
944939
return -ENOMEM;
945940

941+
ptp->efx = efx;
942+
ptp->channel = channel;
943+
946944
rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL);
947945
if (rc != 0)
948946
goto fail1;
949947

950-
ptp->channel = channel;
951948
skb_queue_head_init(&ptp->rxq);
952949
skb_queue_head_init(&ptp->txq);
953950
ptp->workwq = create_singlethread_workqueue("sfc_ptp");
@@ -1014,14 +1011,27 @@ static int efx_ptp_probe_channel(struct efx_channel *channel)
10141011
return rc;
10151012
}
10161013

1017-
static void efx_ptp_remove_channel(struct efx_channel *channel)
1014+
/* Initialise PTP channel.
1015+
*
1016+
* Setting core_index to zero causes the queue to be initialised and doesn't
1017+
* overlap with 'rxq0' because ptp.c doesn't use skb_record_rx_queue.
1018+
*/
1019+
static int efx_ptp_probe_channel(struct efx_channel *channel)
10181020
{
10191021
struct efx_nic *efx = channel->efx;
10201022

1023+
channel->irq_moderation = 0;
1024+
channel->rx_queue.core_index = 0;
1025+
1026+
return efx_ptp_probe(efx, channel);
1027+
}
1028+
1029+
void efx_ptp_remove(struct efx_nic *efx)
1030+
{
10211031
if (!efx->ptp_data)
10221032
return;
10231033

1024-
(void)efx_ptp_disable(channel->efx);
1034+
(void)efx_ptp_disable(efx);
10251035

10261036
cancel_work_sync(&efx->ptp_data->work);
10271037
cancel_work_sync(&efx->ptp_data->pps_work);
@@ -1038,6 +1048,11 @@ static void efx_ptp_remove_channel(struct efx_channel *channel)
10381048
kfree(efx->ptp_data);
10391049
}
10401050

1051+
static void efx_ptp_remove_channel(struct efx_channel *channel)
1052+
{
1053+
efx_ptp_remove(channel->efx);
1054+
}
1055+
10411056
static void efx_ptp_get_channel_name(struct efx_channel *channel,
10421057
char *buf, size_t len)
10431058
{
@@ -1449,7 +1464,7 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
14491464
struct efx_ptp_data *ptp_data = container_of(ptp,
14501465
struct efx_ptp_data,
14511466
phc_clock_info);
1452-
struct efx_nic *efx = ptp_data->channel->efx;
1467+
struct efx_nic *efx = ptp_data->efx;
14531468
MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN);
14541469
s64 adjustment_ns;
14551470
int rc;
@@ -1482,7 +1497,7 @@ static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
14821497
struct efx_ptp_data *ptp_data = container_of(ptp,
14831498
struct efx_ptp_data,
14841499
phc_clock_info);
1485-
struct efx_nic *efx = ptp_data->channel->efx;
1500+
struct efx_nic *efx = ptp_data->efx;
14861501
struct timespec delta_ts = ns_to_timespec(delta);
14871502
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ADJUST_LEN);
14881503

@@ -1500,7 +1515,7 @@ static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
15001515
struct efx_ptp_data *ptp_data = container_of(ptp,
15011516
struct efx_ptp_data,
15021517
phc_clock_info);
1503-
struct efx_nic *efx = ptp_data->channel->efx;
1518+
struct efx_nic *efx = ptp_data->efx;
15041519
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_READ_NIC_TIME_LEN);
15051520
MCDI_DECLARE_BUF(outbuf, MC_CMD_PTP_OUT_READ_NIC_TIME_LEN);
15061521
int rc;
@@ -1566,7 +1581,7 @@ static const struct efx_channel_type efx_ptp_channel_type = {
15661581
.keep_eventq = false,
15671582
};
15681583

1569-
void efx_ptp_probe(struct efx_nic *efx)
1584+
void efx_ptp_defer_probe_with_channel(struct efx_nic *efx)
15701585
{
15711586
/* Check whether PTP is implemented on this NIC. The DISABLE
15721587
* operation will succeed if and only if it is implemented.

drivers/net/ethernet/sfc/siena.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static int siena_probe_nic(struct efx_nic *efx)
259259
goto fail5;
260260

261261
efx_sriov_probe(efx);
262-
efx_ptp_probe(efx);
262+
efx_ptp_defer_probe_with_channel(efx);
263263

264264
return 0;
265265

0 commit comments

Comments
 (0)