Commit 75687cd0 authored by Íñigo Huguet's avatar Íñigo Huguet Committed by Jakub Kicinski

sfc: allow insertion of filters for unicast PTP

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: default avatarYalin Li <yalli@redhat.com>
Signed-off-by: default avatarÍñigo Huguet <ihuguet@redhat.com>
Reviewed-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e790fc15
......@@ -239,6 +239,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)
......@@ -308,6 +309,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;
......@@ -1296,12 +1298,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 *filter_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, filter_list, list) {
efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
rxfilter->handle);
list_del(&rxfilter->list);
......@@ -1320,9 +1322,9 @@ static void efx_ptp_init_filter(struct efx_nic *efx,
}
static int efx_ptp_insert_filter(struct efx_nic *efx,
struct list_head *filter_list,
struct efx_filter_spec *spec)
{
struct efx_ptp_data *ptp = efx->ptp_data;
struct efx_ptp_rxfilter *rxfilter;
int rc;
......@@ -1335,7 +1337,7 @@ static int efx_ptp_insert_filter(struct efx_nic *efx,
goto fail;
rxfilter->handle = rc;
list_add(&rxfilter->list, &ptp->rxfilters_mcast);
list_add(&rxfilter->list, filter_list);
return 0;
......@@ -1344,28 +1346,31 @@ static int efx_ptp_insert_filter(struct efx_nic *efx,
return rc;
}
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 *filter_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, filter_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 *filter_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, filter_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)
{
struct efx_ptp_data *ptp = efx->ptp_data;
const u8 addr[ETH_ALEN] = PTP_ADDR_ETHER;
struct efx_filter_spec spec;
......@@ -1373,7 +1378,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, &ptp->rxfilters_mcast, &spec);
}
static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
......@@ -1387,11 +1392,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;
......@@ -1399,15 +1406,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;
}
......@@ -1415,7 +1426,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;
}
......@@ -1440,7 +1451,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;
}
......@@ -1456,7 +1467,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);
......@@ -1588,6 +1600,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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment