From patchwork Tue Jan 31 16:05:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= X-Patchwork-Id: 13123142 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C3A5EC38142 for ; Tue, 31 Jan 2023 16:06:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231877AbjAaQG3 (ORCPT ); Tue, 31 Jan 2023 11:06:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231730AbjAaQG0 (ORCPT ); Tue, 31 Jan 2023 11:06:26 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B1C6212C for ; Tue, 31 Jan 2023 08:05:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675181142; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hlcsKLNA2wTDQ8gNIAxEjA0aN93UuUpfQr4erKan12U=; b=cI+skwDc6fjFV+H/aoCLT4AEA99owoUecKL+RQBYdbx3JuJcNTp/ZTHaOcc2uIl8oNPRJO kiD6La4tLSlLzHrnwYJX7BxQIizrtLv5gHjjXgey44l3XgOMYECCzEk5e8tIwuoJTikgP4 ictlc30DjpjQN36CRnQ2eMbH6EcrDvA= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-537-ltirPfqZMOS-eWNlu0fSNg-1; Tue, 31 Jan 2023 11:05:24 -0500 X-MC-Unique: ltirPfqZMOS-eWNlu0fSNg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 004743811F3D; Tue, 31 Jan 2023 16:05:19 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.136]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2AE65492B05; Tue, 31 Jan 2023 16:05:17 +0000 (UTC) From: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= To: ecree.xilinx@gmail.com, habetsm.xilinx@gmail.com, richardcochran@gmail.com Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= , Yalin Li Subject: [PATCH net 1/4] sfc: store PTP filters in a list Date: Tue, 31 Jan 2023 17:05:03 +0100 Message-Id: <20230131160506.47552-2-ihuguet@redhat.com> In-Reply-To: <20230131160506.47552-1-ihuguet@redhat.com> References: <20230131160506.47552-1-ihuguet@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Instead of using a fixed sized array for the PTP filters, use a list. This is not actually necessary at this point because the filters for multicast PTP are a fixed number, but this is a preparation for the following patches adding support for unicast PTP. To avoid confusion with the new struct type efx_ptp_rxfilter, change the name of some local variables from rxfilter to spec, given they're of the type efx_filter_spec. Reported-by: Yalin Li Signed-off-by: Íñigo Huguet --- drivers/net/ethernet/sfc/ptp.c | 72 ++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 9f07e1ba7780..53817b4350a5 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -213,6 +214,16 @@ struct efx_ptp_timeset { u32 window; /* Derived: end - start, allowing for wrap */ }; +/** + * struct efx_ptp_rxfilter - Filter for PTP packets + * @list: Node of the list where the filter is added + * @handle: Handle ID for the MCDI filters table + */ +struct efx_ptp_rxfilter { + struct list_head list; + int handle; +}; + /** * struct efx_ptp_data - Precision Time Protocol (PTP) state * @efx: The NIC context @@ -229,8 +240,7 @@ struct efx_ptp_timeset { * @work: Work task * @reset_required: A serious error has occurred and the PTP task needs to be * reset (disable, enable). - * @rxfilters: Receive filters when operating - * @rxfilters_count: Num of installed rxfilters, should be == PTP_RXFILTERS_LEN + * @rxfilters_mcast: Receive filters for multicast PTP packets * @config: Current timestamp configuration * @enabled: PTP operation enabled * @mode: Mode in which PTP operating (PTP version) @@ -299,8 +309,7 @@ struct efx_ptp_data { struct workqueue_struct *workwq; struct work_struct work; bool reset_required; - u32 rxfilters[PTP_RXFILTERS_LEN]; - size_t rxfilters_count; + struct list_head rxfilters_mcast; struct hwtstamp_config config; bool enabled; unsigned int mode; @@ -1292,11 +1301,13 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb) static void efx_ptp_remove_multicast_filters(struct efx_nic *efx) { struct efx_ptp_data *ptp = efx->ptp_data; + struct efx_ptp_rxfilter *rxfilter, *tmp; - while (ptp->rxfilters_count) { - ptp->rxfilters_count--; + list_for_each_entry_safe(rxfilter, tmp, &ptp->rxfilters_mcast, list) { efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, - ptp->rxfilters[ptp->rxfilters_count]); + rxfilter->handle); + list_del(&rxfilter->list); + kfree(rxfilter); } } @@ -1311,48 +1322,55 @@ static void efx_ptp_init_filter(struct efx_nic *efx, } static int efx_ptp_insert_filter(struct efx_nic *efx, - struct efx_filter_spec *rxfilter) + struct efx_filter_spec *spec) { struct efx_ptp_data *ptp = efx->ptp_data; + struct efx_ptp_rxfilter *rxfilter; - int rc = efx_filter_insert_filter(efx, rxfilter, true); + int rc = efx_filter_insert_filter(efx, spec, true); if (rc < 0) return rc; - ptp->rxfilters[ptp->rxfilters_count] = rc; - ptp->rxfilters_count++; + + rxfilter = kzalloc(sizeof(*rxfilter), GFP_KERNEL); + if (!rxfilter) + return -ENOMEM; + + rxfilter->handle = rc; + list_add(&rxfilter->list, &ptp->rxfilters_mcast); + return 0; } static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx, u16 port) { - struct efx_filter_spec rxfilter; + struct efx_filter_spec spec; - efx_ptp_init_filter(efx, &rxfilter); - efx_filter_set_ipv4_local(&rxfilter, IPPROTO_UDP, htonl(PTP_ADDR_IPV4), + efx_ptp_init_filter(efx, &spec); + efx_filter_set_ipv4_local(&spec, IPPROTO_UDP, htonl(PTP_ADDR_IPV4), htons(port)); - return efx_ptp_insert_filter(efx, &rxfilter); + return efx_ptp_insert_filter(efx, &spec); } static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx, u16 port) { const struct in6_addr addr = {{PTP_ADDR_IPV6}}; - struct efx_filter_spec rxfilter; + struct efx_filter_spec spec; - efx_ptp_init_filter(efx, &rxfilter); - efx_filter_set_ipv6_local(&rxfilter, IPPROTO_UDP, &addr, htons(port)); - return efx_ptp_insert_filter(efx, &rxfilter); + efx_ptp_init_filter(efx, &spec); + efx_filter_set_ipv6_local(&spec, IPPROTO_UDP, &addr, htons(port)); + return efx_ptp_insert_filter(efx, &spec); } static int efx_ptp_insert_eth_filter(struct efx_nic *efx) { const u8 addr[ETH_ALEN] = PTP_ADDR_ETHER; - struct efx_filter_spec rxfilter; + struct efx_filter_spec spec; - efx_ptp_init_filter(efx, &rxfilter); - efx_filter_set_eth_local(&rxfilter, EFX_FILTER_VID_UNSPEC, addr); - rxfilter.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; - rxfilter.ether_type = htons(ETH_P_1588); - return efx_ptp_insert_filter(efx, &rxfilter); + efx_ptp_init_filter(efx, &spec); + efx_filter_set_eth_local(&spec, EFX_FILTER_VID_UNSPEC, addr); + spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; + spec.ether_type = htons(ETH_P_1588); + return efx_ptp_insert_filter(efx, &spec); } static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) @@ -1360,7 +1378,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) struct efx_ptp_data *ptp = efx->ptp_data; int rc; - if (!ptp->channel || ptp->rxfilters_count) + if (!ptp->channel || !list_empty(&ptp->rxfilters_mcast)) return 0; /* Must filter on both event and general ports to ensure @@ -1566,6 +1584,8 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++) list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); + INIT_LIST_HEAD(&ptp->rxfilters_mcast); + /* Get the NIC PTP attributes and set up time conversions */ rc = efx_ptp_get_attributes(efx); if (rc < 0) From patchwork Tue Jan 31 16:05:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= X-Patchwork-Id: 13123141 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8790DC636CC for ; Tue, 31 Jan 2023 16:06:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231802AbjAaQG0 (ORCPT ); Tue, 31 Jan 2023 11:06:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231880AbjAaQGY (ORCPT ); Tue, 31 Jan 2023 11:06:24 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29BB94B181 for ; Tue, 31 Jan 2023 08:05:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675181134; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mM/FM6F3MoFvxO3sYAPq4pF8Rz+Ytq6xa0yo4jEkyJs=; b=Ybv522ujqqQ1pq1SyeykZB0eL51KZGpPx1kPL1yaiXDpAngY8OtnL5BIyaq0HH2sPXGFak 1OYXwzDCaXixF861F36toqp6J6Cedj8xz87TNCprXq84A+5mFaoramAycZkvEmKpWAsA17 kUvV5i88i8IofBPeMDJ2wNWbn4Ik8Aw= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-307-tzdfiLDRMD2bTN570a6zyg-1; Tue, 31 Jan 2023 11:05:28 -0500 X-MC-Unique: tzdfiLDRMD2bTN570a6zyg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 22A261C087B5; Tue, 31 Jan 2023 16:05:21 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.136]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4D604492B05; Tue, 31 Jan 2023 16:05:19 +0000 (UTC) From: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= To: ecree.xilinx@gmail.com, habetsm.xilinx@gmail.com, richardcochran@gmail.com Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= , Yalin Li Subject: [PATCH net 2/4] sfc: allow insertion of filters for unicast PTP Date: Tue, 31 Jan 2023 17:05:04 +0100 Message-Id: <20230131160506.47552-3-ihuguet@redhat.com> In-Reply-To: <20230131160506.47552-1-ihuguet@redhat.com> References: <20230131160506.47552-1-ihuguet@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add a second list for unicast filters and generalize the efx_ptp_insert/remove_filters functions to allow acting in any of the 2 lists. No filters for unicast are inserted yet. That will be done in the next patch. The reason to use 2 different lists instead of a single one is that, in next patches, we will want to check if unicast filters are already added and if they're expired. We don't need that for multicast filters. Reported-by: Yalin Li Signed-off-by: Íñigo Huguet --- drivers/net/ethernet/sfc/ptp.c | 58 ++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 53817b4350a5..5d5f70c56048 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -241,6 +241,7 @@ struct efx_ptp_rxfilter { * @reset_required: A serious error has occurred and the PTP task needs to be * reset (disable, enable). * @rxfilters_mcast: Receive filters for multicast PTP packets + * @rxfilters_ucast: Receive filters for unicast PTP packets * @config: Current timestamp configuration * @enabled: PTP operation enabled * @mode: Mode in which PTP operating (PTP version) @@ -310,6 +311,7 @@ struct efx_ptp_data { struct work_struct work; bool reset_required; struct list_head rxfilters_mcast; + struct list_head rxfilters_ucast; struct hwtstamp_config config; bool enabled; unsigned int mode; @@ -1298,12 +1300,12 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb) local_bh_enable(); } -static void efx_ptp_remove_multicast_filters(struct efx_nic *efx) +static void efx_ptp_remove_filters(struct efx_nic *efx, + struct list_head *ptp_list) { - struct efx_ptp_data *ptp = efx->ptp_data; struct efx_ptp_rxfilter *rxfilter, *tmp; - list_for_each_entry_safe(rxfilter, tmp, &ptp->rxfilters_mcast, list) { + list_for_each_entry_safe(rxfilter, tmp, ptp_list, list) { efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, rxfilter->handle); list_del(&rxfilter->list); @@ -1322,9 +1324,9 @@ static void efx_ptp_init_filter(struct efx_nic *efx, } static int efx_ptp_insert_filter(struct efx_nic *efx, + struct list_head *ptp_list, struct efx_filter_spec *spec) { - struct efx_ptp_data *ptp = efx->ptp_data; struct efx_ptp_rxfilter *rxfilter; int rc = efx_filter_insert_filter(efx, spec, true); @@ -1336,32 +1338,34 @@ static int efx_ptp_insert_filter(struct efx_nic *efx, return -ENOMEM; rxfilter->handle = rc; - list_add(&rxfilter->list, &ptp->rxfilters_mcast); + list_add(&rxfilter->list, ptp_list); return 0; } -static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx, u16 port) +static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx, + struct list_head *ptp_list, + __be32 addr, u16 port) { struct efx_filter_spec spec; efx_ptp_init_filter(efx, &spec); - efx_filter_set_ipv4_local(&spec, IPPROTO_UDP, htonl(PTP_ADDR_IPV4), - htons(port)); - return efx_ptp_insert_filter(efx, &spec); + efx_filter_set_ipv4_local(&spec, IPPROTO_UDP, addr, htons(port)); + return efx_ptp_insert_filter(efx, ptp_list, &spec); } -static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx, u16 port) +static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx, + struct list_head *ptp_list, + struct in6_addr *addr, u16 port) { - const struct in6_addr addr = {{PTP_ADDR_IPV6}}; struct efx_filter_spec spec; efx_ptp_init_filter(efx, &spec); - efx_filter_set_ipv6_local(&spec, IPPROTO_UDP, &addr, htons(port)); - return efx_ptp_insert_filter(efx, &spec); + efx_filter_set_ipv6_local(&spec, IPPROTO_UDP, addr, htons(port)); + return efx_ptp_insert_filter(efx, ptp_list, &spec); } -static int efx_ptp_insert_eth_filter(struct efx_nic *efx) +static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx) { const u8 addr[ETH_ALEN] = PTP_ADDR_ETHER; struct efx_filter_spec spec; @@ -1370,7 +1374,7 @@ static int efx_ptp_insert_eth_filter(struct efx_nic *efx) efx_filter_set_eth_local(&spec, EFX_FILTER_VID_UNSPEC, addr); spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; spec.ether_type = htons(ETH_P_1588); - return efx_ptp_insert_filter(efx, &spec); + return efx_ptp_insert_filter(efx, &efx->ptp_data->rxfilters_mcast, &spec); } static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) @@ -1384,11 +1388,13 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) /* Must filter on both event and general ports to ensure * that there is no packet re-ordering. */ - rc = efx_ptp_insert_ipv4_filter(efx, PTP_EVENT_PORT); + rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast, + htonl(PTP_ADDR_IPV4), PTP_EVENT_PORT); if (rc < 0) goto fail; - rc = efx_ptp_insert_ipv4_filter(efx, PTP_GENERAL_PORT); + rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast, + htonl(PTP_ADDR_IPV4), PTP_GENERAL_PORT); if (rc < 0) goto fail; @@ -1396,15 +1402,19 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) * PTP over IPv6 and Ethernet */ if (efx_ptp_use_mac_tx_timestamps(efx)) { - rc = efx_ptp_insert_ipv6_filter(efx, PTP_EVENT_PORT); + struct in6_addr ipv6_addr = {{PTP_ADDR_IPV6}}; + + rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast, + &ipv6_addr, PTP_EVENT_PORT); if (rc < 0) goto fail; - rc = efx_ptp_insert_ipv6_filter(efx, PTP_GENERAL_PORT); + rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast, + &ipv6_addr, PTP_GENERAL_PORT); if (rc < 0) goto fail; - rc = efx_ptp_insert_eth_filter(efx); + rc = efx_ptp_insert_eth_multicast_filter(efx); if (rc < 0) goto fail; } @@ -1412,7 +1422,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) return 0; fail: - efx_ptp_remove_multicast_filters(efx); + efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast); return rc; } @@ -1437,7 +1447,7 @@ static int efx_ptp_start(struct efx_nic *efx) return 0; fail: - efx_ptp_remove_multicast_filters(efx); + efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast); return rc; } @@ -1453,7 +1463,8 @@ static int efx_ptp_stop(struct efx_nic *efx) rc = efx_ptp_disable(efx); - efx_ptp_remove_multicast_filters(efx); + efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast); + efx_ptp_remove_filters(efx, &ptp->rxfilters_ucast); /* Make sure RX packets are really delivered */ efx_ptp_deliver_rx_queue(&efx->ptp_data->rxq); @@ -1585,6 +1596,7 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); INIT_LIST_HEAD(&ptp->rxfilters_mcast); + INIT_LIST_HEAD(&ptp->rxfilters_ucast); /* Get the NIC PTP attributes and set up time conversions */ rc = efx_ptp_get_attributes(efx); From patchwork Tue Jan 31 16:05:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= X-Patchwork-Id: 13123140 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A08B3C38142 for ; Tue, 31 Jan 2023 16:06:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231617AbjAaQGV (ORCPT ); Tue, 31 Jan 2023 11:06:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230135AbjAaQGU (ORCPT ); Tue, 31 Jan 2023 11:06:20 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C59043A597 for ; Tue, 31 Jan 2023 08:05:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675181133; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QJUfBg5WUyDRR7XeuomJTWwLxnFnbdVZzYikPHmQJC0=; b=BcjIcwmTD6m1Ny0JFPu16JQCmnLL8+RzXydzgeNm+i5Be14+zlNktYBwPyTBOvAJ7Hv7gz DEIheHh3iZImWmn02fKO1tyKI5bV3p39EYbC/B9B+thPt/TcVaBvb3c/0GNLNDBGLC8HsX lurfcvaP3SzafZ5ZBQtC1OWQWf5OXko= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-325-dcnhL_6EM4iE8QqYit-JHg-1; Tue, 31 Jan 2023 11:05:25 -0500 X-MC-Unique: dcnhL_6EM4iE8QqYit-JHg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 35CC1100DEA3; Tue, 31 Jan 2023 16:05:23 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.136]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6D799492B05; Tue, 31 Jan 2023 16:05:21 +0000 (UTC) From: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= To: ecree.xilinx@gmail.com, habetsm.xilinx@gmail.com, richardcochran@gmail.com Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= , Yalin Li Subject: [PATCH net 3/4] sfc: support unicast PTP Date: Tue, 31 Jan 2023 17:05:05 +0100 Message-Id: <20230131160506.47552-4-ihuguet@redhat.com> In-Reply-To: <20230131160506.47552-1-ihuguet@redhat.com> References: <20230131160506.47552-1-ihuguet@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org When sending a PTP event packet, add the correct filters that will make that future incoming unicast PTP event packets will be timestamped. The unicast address for the filter is gotten from the outgoing skb before sending it. Until now they were not timestamped because only filters that match with the PTP multicast addressed were being configured into the NIC for the PTP special channel. Packets received through different channels are not timestamped, getting "received SYNC without timestamp" error in ptp4l. Note that the inserted filters are never removed unless the NIC is stopped or reconfigured, so efx_ptp_stop is called. Removal of old filters will be handled by the next patch. Reported-by: Yalin Li Signed-off-by: Íñigo Huguet --- drivers/net/ethernet/sfc/ptp.c | 104 ++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 5d5f70c56048..f9342e21bf31 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -217,10 +217,15 @@ struct efx_ptp_timeset { /** * struct efx_ptp_rxfilter - Filter for PTP packets * @list: Node of the list where the filter is added + * @ether_type: Network protocol of the filter (ETHER_P_IP / ETHER_P_IPV6) + * @loc_host: IPv4/v6 address of the filter * @handle: Handle ID for the MCDI filters table */ struct efx_ptp_rxfilter { struct list_head list; + __be16 ether_type; + __be16 loc_port; + __be32 loc_host[4]; int handle; }; @@ -369,6 +374,8 @@ static int efx_phc_settime(struct ptp_clock_info *ptp, const struct timespec64 *e_ts); static int efx_phc_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on); +static int efx_ptp_insert_unicast_filter(struct efx_nic *efx, + struct sk_buff *skb); bool efx_ptp_use_mac_tx_timestamps(struct efx_nic *efx) { @@ -1114,6 +1121,8 @@ static void efx_ptp_xmit_skb_queue(struct efx_nic *efx, struct sk_buff *skb) tx_queue = efx_channel_get_tx_queue(ptp_data->channel, type); if (tx_queue && tx_queue->timestamping) { + skb_get(skb); + /* 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 @@ -1137,6 +1146,13 @@ static void efx_ptp_xmit_skb_queue(struct efx_nic *efx, struct sk_buff *skb) local_bh_disable(); efx_enqueue_skb(tx_queue, skb); local_bh_enable(); + + /* We need to add the filters after enqueuing the packet. + * Otherwise, there's high latency in sending back the + * timestamp, causing ptp4l timeouts + */ + efx_ptp_insert_unicast_filter(efx, skb); + dev_consume_skb_any(skb); } else { WARN_ONCE(1, "PTP channel has no timestamped tx queue\n"); dev_kfree_skb_any(skb); @@ -1148,7 +1164,7 @@ static void efx_ptp_xmit_skb_mc(struct efx_nic *efx, struct sk_buff *skb) { struct efx_ptp_data *ptp_data = efx->ptp_data; struct skb_shared_hwtstamps timestamps; - int rc = -EIO; + int rc; MCDI_DECLARE_BUF(txtime, MC_CMD_PTP_OUT_TRANSMIT_LEN); size_t len; @@ -1184,7 +1200,10 @@ static void efx_ptp_xmit_skb_mc(struct efx_nic *efx, struct sk_buff *skb) skb_tstamp_tx(skb, ×tamps); - rc = 0; + /* Add the filters after sending back the timestamp to avoid delaying it + * or ptp4l may timeout. + */ + efx_ptp_insert_unicast_filter(efx, skb); fail: dev_kfree_skb_any(skb); @@ -1300,6 +1319,21 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb) local_bh_enable(); } +static bool efx_ptp_filter_exists(struct list_head *ptp_list, + struct efx_filter_spec *spec) +{ + struct efx_ptp_rxfilter *rxfilter; + + list_for_each_entry(rxfilter, ptp_list, list) { + if (rxfilter->ether_type == spec->ether_type && + rxfilter->loc_port == spec->loc_port && + !memcmp(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host))) + return true; + } + + return false; +} + static void efx_ptp_remove_filters(struct efx_nic *efx, struct list_head *ptp_list) { @@ -1328,8 +1362,12 @@ static int efx_ptp_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec) { struct efx_ptp_rxfilter *rxfilter; + int rc; + + if (efx_ptp_filter_exists(ptp_list, spec)) + return 0; - int rc = efx_filter_insert_filter(efx, spec, true); + rc = efx_filter_insert_filter(efx, spec, true); if (rc < 0) return rc; @@ -1338,6 +1376,9 @@ static int efx_ptp_insert_filter(struct efx_nic *efx, return -ENOMEM; rxfilter->handle = rc; + rxfilter->ether_type = spec->ether_type; + rxfilter->loc_port = spec->loc_port; + memcpy(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host)); list_add(&rxfilter->list, ptp_list); return 0; @@ -1426,6 +1467,63 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) return rc; } +static bool efx_ptp_valid_unicast_event_pkt(struct sk_buff *skb) +{ + if (skb->protocol == htons(ETH_P_IP)) { + return ip_hdr(skb)->protocol == IPPROTO_UDP && + udp_hdr(skb)->source == htons(PTP_EVENT_PORT); + } else if (skb->protocol == htons(ETH_P_IPV6)) { + return ipv6_hdr(skb)->nexthdr == IPPROTO_UDP && + udp_hdr(skb)->source == htons(PTP_EVENT_PORT); + } + return false; +} + +static int efx_ptp_insert_unicast_filter(struct efx_nic *efx, + struct sk_buff *skb) +{ + struct efx_ptp_data *ptp = efx->ptp_data; + int rc; + + if (!efx_ptp_valid_unicast_event_pkt(skb)) + return -EINVAL; + + if (skb->protocol == htons(ETH_P_IP)) { + __be32 addr = ip_hdr(skb)->saddr; + + rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_EVENT_PORT); + if (rc < 0) + goto fail; + + rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_GENERAL_PORT); + if (rc < 0) + goto fail; + } else if (efx_ptp_use_mac_tx_timestamps(efx)) { + /* IPv6 PTP only supported by devices with MAC hw timestamp */ + struct in6_addr *addr = &ipv6_hdr(skb)->saddr; + + rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_EVENT_PORT); + if (rc < 0) + goto fail; + + rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_GENERAL_PORT); + if (rc < 0) + goto fail; + } else { + return -EOPNOTSUPP; + } + + return 0; + +fail: + efx_ptp_remove_filters(efx, &ptp->rxfilters_ucast); + return rc; +} + static int efx_ptp_start(struct efx_nic *efx) { struct efx_ptp_data *ptp = efx->ptp_data; From patchwork Tue Jan 31 16:05:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= X-Patchwork-Id: 13123143 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C294C38142 for ; Tue, 31 Jan 2023 16:06:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232408AbjAaQGc (ORCPT ); Tue, 31 Jan 2023 11:06:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45152 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230014AbjAaQG2 (ORCPT ); Tue, 31 Jan 2023 11:06:28 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5BC994DBF7 for ; Tue, 31 Jan 2023 08:05:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675181135; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=M15miINuBv6FsNuNApYKWaWafj4pvjnY1ZlJNI6mzg4=; b=h3kRLZidUaf/jcU43bUJ9eT781YhHZfVCeTYC3/gE60qUMQz2YjysG4KioKH6gfpFtk3kN Q/6AyZQfNumGarpPZk2K3p75xaDRX1rRcQQdF9R3bMUwUhyBf7hKztlkvRzE3FG95Ml1yi a48W6bSFF7rx1CqpjncqR9h4gFMRjCM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-424-LNKkWdxtPcmCuMAXXhh66Q-1; Tue, 31 Jan 2023 11:05:28 -0500 X-MC-Unique: LNKkWdxtPcmCuMAXXhh66Q-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4863B85CAB4; Tue, 31 Jan 2023 16:05:25 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.136]) by smtp.corp.redhat.com (Postfix) with ESMTP id 80081492B05; Tue, 31 Jan 2023 16:05:23 +0000 (UTC) From: =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= To: ecree.xilinx@gmail.com, habetsm.xilinx@gmail.com, richardcochran@gmail.com Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, =?utf-8?b?w43DsWlnbyBIdWd1ZXQ=?= , Yalin Li Subject: [PATCH net 4/4] sfc: remove expired unicast PTP filters Date: Tue, 31 Jan 2023 17:05:06 +0100 Message-Id: <20230131160506.47552-5-ihuguet@redhat.com> In-Reply-To: <20230131160506.47552-1-ihuguet@redhat.com> References: <20230131160506.47552-1-ihuguet@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Filters inserted to support unicast PTP mode might become unused after some time, so we need to remove them to avoid accumulating many of them. Actually, it would be a very unusual situation that many different addresses are used, normally only a small set of predefined addresses are tried. Anyway, some cleanup is necessary because maintaining old filters forever makes very little sense. Reported-by: Yalin Li Signed-off-by: Íñigo Huguet --- drivers/net/ethernet/sfc/ptp.c | 120 +++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index f9342e21bf31..fd37a61058e7 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -75,6 +75,9 @@ /* How long an unmatched event or packet can be held */ #define PKT_EVENT_LIFETIME_MS 10 +/* How long unused unicast filters can be held */ +#define UCAST_FILTER_EXPIRY_JIFFIES msecs_to_jiffies(30000) + /* Offsets into PTP packet for identification. These offsets are from the * start of the IP header, not the MAC header. Note that neither PTP V1 nor * PTP V2 permit the use of IPV4 options. @@ -226,6 +229,7 @@ struct efx_ptp_rxfilter { __be16 ether_type; __be16 loc_port; __be32 loc_host[4]; + unsigned long expiry; int handle; }; @@ -1319,8 +1323,8 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb) local_bh_enable(); } -static bool efx_ptp_filter_exists(struct list_head *ptp_list, - struct efx_filter_spec *spec) +static struct efx_ptp_rxfilter * +efx_ptp_find_filter(struct list_head *ptp_list, struct efx_filter_spec *spec) { struct efx_ptp_rxfilter *rxfilter; @@ -1328,10 +1332,19 @@ static bool efx_ptp_filter_exists(struct list_head *ptp_list, if (rxfilter->ether_type == spec->ether_type && rxfilter->loc_port == spec->loc_port && !memcmp(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host))) - return true; + return rxfilter; } - return false; + return NULL; +} + +static inline void efx_ptp_remove_one_filter(struct efx_nic *efx, + struct efx_ptp_rxfilter *rxfilter) +{ + efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, + rxfilter->handle); + list_del(&rxfilter->list); + kfree(rxfilter); } static void efx_ptp_remove_filters(struct efx_nic *efx, @@ -1340,10 +1353,7 @@ static void efx_ptp_remove_filters(struct efx_nic *efx, struct efx_ptp_rxfilter *rxfilter, *tmp; list_for_each_entry_safe(rxfilter, tmp, ptp_list, list) { - efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, - rxfilter->handle); - list_del(&rxfilter->list); - kfree(rxfilter); + efx_ptp_remove_one_filter(efx, rxfilter); } } @@ -1357,23 +1367,24 @@ static void efx_ptp_init_filter(struct efx_nic *efx, efx_rx_queue_index(queue)); } -static int efx_ptp_insert_filter(struct efx_nic *efx, - struct list_head *ptp_list, - struct efx_filter_spec *spec) +static struct efx_ptp_rxfilter * +efx_ptp_insert_filter(struct efx_nic *efx, struct list_head *ptp_list, + struct efx_filter_spec *spec) { struct efx_ptp_rxfilter *rxfilter; int rc; - if (efx_ptp_filter_exists(ptp_list, spec)) - return 0; + rxfilter = efx_ptp_find_filter(ptp_list, spec); + if (rxfilter) + return rxfilter; rc = efx_filter_insert_filter(efx, spec, true); if (rc < 0) - return rc; + return ERR_PTR(rc); rxfilter = kzalloc(sizeof(*rxfilter), GFP_KERNEL); if (!rxfilter) - return -ENOMEM; + return ERR_PTR(-ENOMEM); rxfilter->handle = rc; rxfilter->ether_type = spec->ether_type; @@ -1381,12 +1392,12 @@ static int efx_ptp_insert_filter(struct efx_nic *efx, memcpy(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host)); list_add(&rxfilter->list, ptp_list); - return 0; + return rxfilter; } -static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx, - struct list_head *ptp_list, - __be32 addr, u16 port) +static struct efx_ptp_rxfilter * +efx_ptp_insert_ipv4_filter(struct efx_nic *efx, struct list_head *ptp_list, + __be32 addr, u16 port) { struct efx_filter_spec spec; @@ -1395,9 +1406,9 @@ static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx, return efx_ptp_insert_filter(efx, ptp_list, &spec); } -static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx, - struct list_head *ptp_list, - struct in6_addr *addr, u16 port) +static struct efx_ptp_rxfilter * +efx_ptp_insert_ipv6_filter(struct efx_nic *efx, struct list_head *ptp_list, + struct in6_addr *addr, u16 port) { struct efx_filter_spec spec; @@ -1406,7 +1417,8 @@ static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx, return efx_ptp_insert_filter(efx, ptp_list, &spec); } -static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx) +static struct efx_ptp_rxfilter * +efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx) { const u8 addr[ETH_ALEN] = PTP_ADDR_ETHER; struct efx_filter_spec spec; @@ -1421,7 +1433,7 @@ static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx) static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) { struct efx_ptp_data *ptp = efx->ptp_data; - int rc; + struct efx_ptp_rxfilter *rc; if (!ptp->channel || !list_empty(&ptp->rxfilters_mcast)) return 0; @@ -1431,12 +1443,12 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) */ rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast, htonl(PTP_ADDR_IPV4), PTP_EVENT_PORT); - if (rc < 0) + if (IS_ERR(rc)) goto fail; rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast, htonl(PTP_ADDR_IPV4), PTP_GENERAL_PORT); - if (rc < 0) + if (IS_ERR(rc)) goto fail; /* if the NIC supports hw timestamps by the MAC, we can support @@ -1447,16 +1459,16 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast, &ipv6_addr, PTP_EVENT_PORT); - if (rc < 0) + if (IS_ERR(rc)) goto fail; rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast, &ipv6_addr, PTP_GENERAL_PORT); - if (rc < 0) + if (IS_ERR(rc)) goto fail; rc = efx_ptp_insert_eth_multicast_filter(efx); - if (rc < 0) + if (IS_ERR(rc)) goto fail; } @@ -1464,7 +1476,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) fail: efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast); - return rc; + return PTR_ERR(rc); } static bool efx_ptp_valid_unicast_event_pkt(struct sk_buff *skb) @@ -1483,7 +1495,7 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx, struct sk_buff *skb) { struct efx_ptp_data *ptp = efx->ptp_data; - int rc; + struct efx_ptp_rxfilter *rxfilter; if (!efx_ptp_valid_unicast_event_pkt(skb)) return -EINVAL; @@ -1491,28 +1503,36 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx, if (skb->protocol == htons(ETH_P_IP)) { __be32 addr = ip_hdr(skb)->saddr; - rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, - addr, PTP_EVENT_PORT); - if (rc < 0) + rxfilter = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_EVENT_PORT); + if (IS_ERR(rxfilter)) goto fail; - rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, - addr, PTP_GENERAL_PORT); - if (rc < 0) + rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES; + + rxfilter = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_GENERAL_PORT); + if (rxfilter < 0) goto fail; + + rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES; } else if (efx_ptp_use_mac_tx_timestamps(efx)) { /* IPv6 PTP only supported by devices with MAC hw timestamp */ struct in6_addr *addr = &ipv6_hdr(skb)->saddr; - rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, - addr, PTP_EVENT_PORT); - if (rc < 0) + rxfilter = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_EVENT_PORT); + if (IS_ERR(rxfilter)) goto fail; - rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, - addr, PTP_GENERAL_PORT); - if (rc < 0) + rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES; + + rxfilter = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, + addr, PTP_GENERAL_PORT); + if (IS_ERR(rxfilter)) goto fail; + + rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES; } else { return -EOPNOTSUPP; } @@ -1521,7 +1541,18 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx, fail: efx_ptp_remove_filters(efx, &ptp->rxfilters_ucast); - return rc; + return PTR_ERR(rxfilter); +} + +static void efx_ptp_drop_expired_unicast_filters(struct efx_nic *efx) +{ + struct efx_ptp_data *ptp = efx->ptp_data; + struct efx_ptp_rxfilter *rxfilter, *tmp; + + list_for_each_entry_safe(rxfilter, tmp, &ptp->rxfilters_ucast, list) { + if (time_is_before_jiffies(rxfilter->expiry)) + efx_ptp_remove_one_filter(efx, rxfilter); + } } static int efx_ptp_start(struct efx_nic *efx) @@ -1615,6 +1646,7 @@ static void efx_ptp_worker(struct work_struct *work) } efx_ptp_drop_time_expired_events(efx); + efx_ptp_drop_expired_unicast_filters(efx); __skb_queue_head_init(&tempq); efx_ptp_process_events(efx, &tempq);