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 { ...@@ -239,6 +239,7 @@ struct efx_ptp_rxfilter {
* @reset_required: A serious error has occurred and the PTP task needs to be * @reset_required: A serious error has occurred and the PTP task needs to be
* reset (disable, enable). * reset (disable, enable).
* @rxfilters_mcast: Receive filters for multicast PTP packets * @rxfilters_mcast: Receive filters for multicast PTP packets
* @rxfilters_ucast: Receive filters for unicast PTP packets
* @config: Current timestamp configuration * @config: Current timestamp configuration
* @enabled: PTP operation enabled * @enabled: PTP operation enabled
* @mode: Mode in which PTP operating (PTP version) * @mode: Mode in which PTP operating (PTP version)
...@@ -308,6 +309,7 @@ struct efx_ptp_data { ...@@ -308,6 +309,7 @@ struct efx_ptp_data {
struct work_struct work; struct work_struct work;
bool reset_required; bool reset_required;
struct list_head rxfilters_mcast; struct list_head rxfilters_mcast;
struct list_head rxfilters_ucast;
struct hwtstamp_config config; struct hwtstamp_config config;
bool enabled; bool enabled;
unsigned int mode; unsigned int mode;
...@@ -1296,12 +1298,12 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb) ...@@ -1296,12 +1298,12 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb)
local_bh_enable(); 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; 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, efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
rxfilter->handle); rxfilter->handle);
list_del(&rxfilter->list); list_del(&rxfilter->list);
...@@ -1320,9 +1322,9 @@ static void efx_ptp_init_filter(struct efx_nic *efx, ...@@ -1320,9 +1322,9 @@ static void efx_ptp_init_filter(struct efx_nic *efx,
} }
static int efx_ptp_insert_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_filter_spec *spec)
{ {
struct efx_ptp_data *ptp = efx->ptp_data;
struct efx_ptp_rxfilter *rxfilter; struct efx_ptp_rxfilter *rxfilter;
int rc; int rc;
...@@ -1335,7 +1337,7 @@ static int efx_ptp_insert_filter(struct efx_nic *efx, ...@@ -1335,7 +1337,7 @@ static int efx_ptp_insert_filter(struct efx_nic *efx,
goto fail; goto fail;
rxfilter->handle = rc; rxfilter->handle = rc;
list_add(&rxfilter->list, &ptp->rxfilters_mcast); list_add(&rxfilter->list, filter_list);
return 0; return 0;
...@@ -1344,28 +1346,31 @@ static int efx_ptp_insert_filter(struct efx_nic *efx, ...@@ -1344,28 +1346,31 @@ static int efx_ptp_insert_filter(struct efx_nic *efx,
return rc; 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; struct efx_filter_spec spec;
efx_ptp_init_filter(efx, &spec); efx_ptp_init_filter(efx, &spec);
efx_filter_set_ipv4_local(&spec, IPPROTO_UDP, htonl(PTP_ADDR_IPV4), efx_filter_set_ipv4_local(&spec, IPPROTO_UDP, addr, htons(port));
htons(port)); return efx_ptp_insert_filter(efx, filter_list, &spec);
return efx_ptp_insert_filter(efx, &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; struct efx_filter_spec spec;
efx_ptp_init_filter(efx, &spec); efx_ptp_init_filter(efx, &spec);
efx_filter_set_ipv6_local(&spec, IPPROTO_UDP, &addr, htons(port)); efx_filter_set_ipv6_local(&spec, IPPROTO_UDP, addr, htons(port));
return efx_ptp_insert_filter(efx, &spec); 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; const u8 addr[ETH_ALEN] = PTP_ADDR_ETHER;
struct efx_filter_spec spec; struct efx_filter_spec spec;
...@@ -1373,7 +1378,7 @@ static int efx_ptp_insert_eth_filter(struct efx_nic *efx) ...@@ -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); efx_filter_set_eth_local(&spec, EFX_FILTER_VID_UNSPEC, addr);
spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
spec.ether_type = htons(ETH_P_1588); 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) 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) ...@@ -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 /* Must filter on both event and general ports to ensure
* that there is no packet re-ordering. * 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) if (rc < 0)
goto fail; 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) if (rc < 0)
goto fail; goto fail;
...@@ -1399,15 +1406,19 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) ...@@ -1399,15 +1406,19 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
* PTP over IPv6 and Ethernet * PTP over IPv6 and Ethernet
*/ */
if (efx_ptp_use_mac_tx_timestamps(efx)) { 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) if (rc < 0)
goto fail; 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) if (rc < 0)
goto fail; goto fail;
rc = efx_ptp_insert_eth_filter(efx); rc = efx_ptp_insert_eth_multicast_filter(efx);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
} }
...@@ -1415,7 +1426,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) ...@@ -1415,7 +1426,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
return 0; return 0;
fail: fail:
efx_ptp_remove_multicast_filters(efx); efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast);
return rc; return rc;
} }
...@@ -1440,7 +1451,7 @@ static int efx_ptp_start(struct efx_nic *efx) ...@@ -1440,7 +1451,7 @@ static int efx_ptp_start(struct efx_nic *efx)
return 0; return 0;
fail: fail:
efx_ptp_remove_multicast_filters(efx); efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast);
return rc; return rc;
} }
...@@ -1456,7 +1467,8 @@ static int efx_ptp_stop(struct efx_nic *efx) ...@@ -1456,7 +1467,8 @@ static int efx_ptp_stop(struct efx_nic *efx)
rc = efx_ptp_disable(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 */ /* Make sure RX packets are really delivered */
efx_ptp_deliver_rx_queue(&efx->ptp_data->rxq); 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) ...@@ -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); list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list);
INIT_LIST_HEAD(&ptp->rxfilters_mcast); INIT_LIST_HEAD(&ptp->rxfilters_mcast);
INIT_LIST_HEAD(&ptp->rxfilters_ucast);
/* Get the NIC PTP attributes and set up time conversions */ /* Get the NIC PTP attributes and set up time conversions */
rc = efx_ptp_get_attributes(efx); 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