提交 9ec06595 编写于 作者: D Daniel Pieczko 提交者: Ben Hutchings

sfc: split setup of hardware timestamping into NIC-type operation

I added efx_ptp_get_mode() to avoid moving the definition for
efx_ptp_data, since the current PTP mode is needed for
siena.c:siena_set_ptp_hwtstamp.

[bwh: Also move the rx_filters mask, and add kernel-doc]
Signed-off-by: NBen Hutchings <bhutchings@solarflare.com>
上级 a6f73460
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
/* Forward declare Precision Time Protocol (PTP) support structure. */ /* Forward declare Precision Time Protocol (PTP) support structure. */
struct efx_ptp_data; struct efx_ptp_data;
struct hwtstamp_config;
struct efx_self_tests; struct efx_self_tests;
...@@ -1042,6 +1043,10 @@ struct efx_mtd_partition { ...@@ -1042,6 +1043,10 @@ struct efx_mtd_partition {
* @mtd_sync: Wait for write-back to complete on MTD partition. This * @mtd_sync: Wait for write-back to complete on MTD partition. This
* also notifies the driver that a writer has finished using this * also notifies the driver that a writer has finished using this
* partition. * partition.
* @ptp_write_host_time: Send host time to MC as part of sync protocol
* @ptp_set_ts_config: Set hardware timestamp configuration. The flags
* and tx_type will already have been validated but this operation
* must validate and update rx_filter.
* @revision: Hardware architecture revision * @revision: Hardware architecture revision
* @txd_ptr_tbl_base: TX descriptor ring base address * @txd_ptr_tbl_base: TX descriptor ring base address
* @rxd_ptr_tbl_base: RX descriptor ring base address * @rxd_ptr_tbl_base: RX descriptor ring base address
...@@ -1060,6 +1065,7 @@ struct efx_mtd_partition { ...@@ -1060,6 +1065,7 @@ struct efx_mtd_partition {
* @offload_features: net_device feature flags for protocol offload * @offload_features: net_device feature flags for protocol offload
* features implemented in hardware * features implemented in hardware
* @mcdi_max_ver: Maximum MCDI version supported * @mcdi_max_ver: Maximum MCDI version supported
* @hwtstamp_filters: Mask of hardware timestamp filter types supported
*/ */
struct efx_nic_type { struct efx_nic_type {
unsigned int (*mem_map_size)(struct efx_nic *efx); unsigned int (*mem_map_size)(struct efx_nic *efx);
...@@ -1161,6 +1167,8 @@ struct efx_nic_type { ...@@ -1161,6 +1167,8 @@ struct efx_nic_type {
int (*mtd_sync)(struct mtd_info *mtd); int (*mtd_sync)(struct mtd_info *mtd);
#endif #endif
void (*ptp_write_host_time)(struct efx_nic *efx, u32 host_time); void (*ptp_write_host_time)(struct efx_nic *efx, u32 host_time);
int (*ptp_set_ts_config)(struct efx_nic *efx,
struct hwtstamp_config *init);
int revision; int revision;
unsigned int txd_ptr_tbl_base; unsigned int txd_ptr_tbl_base;
...@@ -1179,6 +1187,7 @@ struct efx_nic_type { ...@@ -1179,6 +1187,7 @@ struct efx_nic_type {
netdev_features_t offload_features; netdev_features_t offload_features;
int mcdi_max_ver; int mcdi_max_ver;
unsigned int max_rx_ip_filters; unsigned int max_rx_ip_filters;
u32 hwtstamp_filters;
}; };
/************************************************************************** /**************************************************************************
......
...@@ -561,6 +561,9 @@ int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr); ...@@ -561,6 +561,9 @@ int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr);
int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
int efx_ptp_get_mode(struct efx_nic *efx);
int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
unsigned int new_mode);
int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
void efx_ptp_start_datapath(struct efx_nic *efx); void efx_ptp_start_datapath(struct efx_nic *efx);
......
...@@ -1361,7 +1361,12 @@ int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) ...@@ -1361,7 +1361,12 @@ int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb)
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, int efx_ptp_get_mode(struct efx_nic *efx)
{
return efx->ptp_data->mode;
}
int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
unsigned int new_mode) unsigned int new_mode)
{ {
if ((enable_wanted != efx->ptp_data->enabled) || if ((enable_wanted != efx->ptp_data->enabled) ||
...@@ -1406,8 +1411,6 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, ...@@ -1406,8 +1411,6 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init)
{ {
bool enable_wanted = false;
unsigned int new_mode;
int rc; int rc;
if (init->flags) if (init->flags)
...@@ -1417,57 +1420,11 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) ...@@ -1417,57 +1420,11 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init)
(init->tx_type != HWTSTAMP_TX_ON)) (init->tx_type != HWTSTAMP_TX_ON))
return -ERANGE; return -ERANGE;
new_mode = efx->ptp_data->mode; rc = efx->type->ptp_set_ts_config(efx, init);
/* Determine whether any PTP HW operations are required */ if (rc)
switch (init->rx_filter) {
case HWTSTAMP_FILTER_NONE:
break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
init->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
new_mode = MC_CMD_PTP_MODE_V1;
enable_wanted = true;
break;
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
/* Although these three are accepted only IPV4 packets will be
* timestamped
*/
init->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
new_mode = MC_CMD_PTP_MODE_V2_ENHANCED;
enable_wanted = true;
break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
/* Non-IP + IPv6 timestamping not supported */
return -ERANGE;
break;
default:
return -ERANGE;
}
if (init->tx_type != HWTSTAMP_TX_OFF)
enable_wanted = true;
/* Old versions of the firmware do not support the improved
* UUID filtering option (SF bug 33070). If the firmware does
* not accept the enhanced mode, fall back to the standard PTP
* v2 UUID filtering.
*/
rc = efx_ptp_change_mode(efx, enable_wanted, new_mode);
if ((rc != 0) && (new_mode == MC_CMD_PTP_MODE_V2_ENHANCED))
rc = efx_ptp_change_mode(efx, enable_wanted, MC_CMD_PTP_MODE_V2);
if (rc != 0)
return rc; return rc;
efx->ptp_data->config = *init; efx->ptp_data->config = *init;
return 0; return 0;
} }
...@@ -1483,13 +1440,7 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info) ...@@ -1483,13 +1440,7 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info)
SOF_TIMESTAMPING_RAW_HARDWARE); SOF_TIMESTAMPING_RAW_HARDWARE);
ts_info->phc_index = ptp_clock_index(ptp->phc_clock); ts_info->phc_index = ptp_clock_index(ptp->phc_clock);
ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON;
ts_info->rx_filters = (1 << HWTSTAMP_FILTER_NONE | ts_info->rx_filters = ptp->efx->type->hwtstamp_filters;
1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT |
1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC |
1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ |
1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT |
1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC |
1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
} }
int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr) int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr)
......
...@@ -116,6 +116,54 @@ static int siena_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) ...@@ -116,6 +116,54 @@ static int siena_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
return rc ? rc : rc2; return rc ? rc : rc2;
} }
/**************************************************************************
*
* PTP
*
**************************************************************************
*/
static void siena_ptp_write_host_time(struct efx_nic *efx, u32 host_time)
{
_efx_writed(efx, cpu_to_le32(host_time),
FR_CZ_MC_TREG_SMEM + MC_SMEM_P0_PTP_TIME_OFST);
}
static int siena_ptp_set_ts_config(struct efx_nic *efx,
struct hwtstamp_config *init)
{
int rc;
switch (init->rx_filter) {
case HWTSTAMP_FILTER_NONE:
/* if TX timestamping is still requested then leave PTP on */
return efx_ptp_change_mode(efx,
init->tx_type != HWTSTAMP_TX_OFF,
efx_ptp_get_mode(efx));
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
init->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
return efx_ptp_change_mode(efx, true, MC_CMD_PTP_MODE_V1);
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
init->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
rc = efx_ptp_change_mode(efx, true,
MC_CMD_PTP_MODE_V2_ENHANCED);
/* bug 33070 - old versions of the firmware do not support the
* improved UUID filtering option. Similarly old versions of the
* application do not expect it to be enabled. If the firmware
* does not accept the enhanced mode, fall back to the standard
* PTP v2 UUID filtering. */
if (rc != 0)
rc = efx_ptp_change_mode(efx, true, MC_CMD_PTP_MODE_V2);
return rc;
default:
return -ERANGE;
}
}
/************************************************************************** /**************************************************************************
* *
* Device reset * Device reset
...@@ -837,19 +885,6 @@ static int siena_mtd_probe(struct efx_nic *efx) ...@@ -837,19 +885,6 @@ static int siena_mtd_probe(struct efx_nic *efx)
#endif /* CONFIG_SFC_MTD */ #endif /* CONFIG_SFC_MTD */
/**************************************************************************
*
* PTP
*
**************************************************************************
*/
static void siena_ptp_write_host_time(struct efx_nic *efx, u32 host_time)
{
_efx_writed(efx, cpu_to_le32(host_time),
FR_CZ_MC_TREG_SMEM + MC_SMEM_P0_PTP_TIME_OFST);
}
/************************************************************************** /**************************************************************************
* *
* Revision-dependent attributes used by efx.c and nic.c * Revision-dependent attributes used by efx.c and nic.c
...@@ -942,6 +977,7 @@ const struct efx_nic_type siena_a0_nic_type = { ...@@ -942,6 +977,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.mtd_sync = efx_mcdi_mtd_sync, .mtd_sync = efx_mcdi_mtd_sync,
#endif #endif
.ptp_write_host_time = siena_ptp_write_host_time, .ptp_write_host_time = siena_ptp_write_host_time,
.ptp_set_ts_config = siena_ptp_set_ts_config,
.revision = EFX_REV_SIENA_A0, .revision = EFX_REV_SIENA_A0,
.txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
...@@ -960,4 +996,11 @@ const struct efx_nic_type siena_a0_nic_type = { ...@@ -960,4 +996,11 @@ const struct efx_nic_type siena_a0_nic_type = {
NETIF_F_RXHASH | NETIF_F_NTUPLE), NETIF_F_RXHASH | NETIF_F_NTUPLE),
.mcdi_max_ver = 1, .mcdi_max_ver = 1,
.max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS, .max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS,
.hwtstamp_filters = (1 << HWTSTAMP_FILTER_NONE |
1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT |
1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC |
1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ |
1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT |
1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC |
1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ),
}; };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册