diff options
author | Daniel Pieczko <dpieczko@solarflare.com> | 2013-11-21 12:11:25 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-12-12 17:07:11 -0500 |
commit | 9ec0659595c8020f1efa55aa00870e8773f8ee89 (patch) | |
tree | d4b4fc24a45ac681182b426b68445fbb94702ed2 /drivers/net/ethernet | |
parent | a6f73460b592404cca4ceafa69a835a61cdc20d8 (diff) |
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: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ptp.c | 69 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena.c | 69 |
4 files changed, 78 insertions, 72 deletions
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index f47bac78b92c..01ffbe849683 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -91,6 +91,7 @@ | |||
91 | 91 | ||
92 | /* Forward declare Precision Time Protocol (PTP) support structure. */ | 92 | /* Forward declare Precision Time Protocol (PTP) support structure. */ |
93 | struct efx_ptp_data; | 93 | struct efx_ptp_data; |
94 | struct hwtstamp_config; | ||
94 | 95 | ||
95 | struct efx_self_tests; | 96 | struct efx_self_tests; |
96 | 97 | ||
@@ -1042,6 +1043,10 @@ struct efx_mtd_partition { | |||
1042 | * @mtd_sync: Wait for write-back to complete on MTD partition. This | 1043 | * @mtd_sync: Wait for write-back to complete on MTD partition. This |
1043 | * also notifies the driver that a writer has finished using this | 1044 | * also notifies the driver that a writer has finished using this |
1044 | * partition. | 1045 | * partition. |
1046 | * @ptp_write_host_time: Send host time to MC as part of sync protocol | ||
1047 | * @ptp_set_ts_config: Set hardware timestamp configuration. The flags | ||
1048 | * and tx_type will already have been validated but this operation | ||
1049 | * must validate and update rx_filter. | ||
1045 | * @revision: Hardware architecture revision | 1050 | * @revision: Hardware architecture revision |
1046 | * @txd_ptr_tbl_base: TX descriptor ring base address | 1051 | * @txd_ptr_tbl_base: TX descriptor ring base address |
1047 | * @rxd_ptr_tbl_base: RX descriptor ring base address | 1052 | * @rxd_ptr_tbl_base: RX descriptor ring base address |
@@ -1060,6 +1065,7 @@ struct efx_mtd_partition { | |||
1060 | * @offload_features: net_device feature flags for protocol offload | 1065 | * @offload_features: net_device feature flags for protocol offload |
1061 | * features implemented in hardware | 1066 | * features implemented in hardware |
1062 | * @mcdi_max_ver: Maximum MCDI version supported | 1067 | * @mcdi_max_ver: Maximum MCDI version supported |
1068 | * @hwtstamp_filters: Mask of hardware timestamp filter types supported | ||
1063 | */ | 1069 | */ |
1064 | struct efx_nic_type { | 1070 | struct efx_nic_type { |
1065 | unsigned int (*mem_map_size)(struct efx_nic *efx); | 1071 | unsigned int (*mem_map_size)(struct efx_nic *efx); |
@@ -1161,6 +1167,8 @@ struct efx_nic_type { | |||
1161 | int (*mtd_sync)(struct mtd_info *mtd); | 1167 | int (*mtd_sync)(struct mtd_info *mtd); |
1162 | #endif | 1168 | #endif |
1163 | void (*ptp_write_host_time)(struct efx_nic *efx, u32 host_time); | 1169 | void (*ptp_write_host_time)(struct efx_nic *efx, u32 host_time); |
1170 | int (*ptp_set_ts_config)(struct efx_nic *efx, | ||
1171 | struct hwtstamp_config *init); | ||
1164 | 1172 | ||
1165 | int revision; | 1173 | int revision; |
1166 | unsigned int txd_ptr_tbl_base; | 1174 | unsigned int txd_ptr_tbl_base; |
@@ -1179,6 +1187,7 @@ struct efx_nic_type { | |||
1179 | netdev_features_t offload_features; | 1187 | netdev_features_t offload_features; |
1180 | int mcdi_max_ver; | 1188 | int mcdi_max_ver; |
1181 | unsigned int max_rx_ip_filters; | 1189 | unsigned int max_rx_ip_filters; |
1190 | u32 hwtstamp_filters; | ||
1182 | }; | 1191 | }; |
1183 | 1192 | ||
1184 | /************************************************************************** | 1193 | /************************************************************************** |
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 25178536f053..999ef285662d 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h | |||
@@ -561,6 +561,9 @@ int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr); | |||
561 | int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); | 561 | int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); |
562 | void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); | 562 | void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); |
563 | bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 563 | bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
564 | int efx_ptp_get_mode(struct efx_nic *efx); | ||
565 | int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | ||
566 | unsigned int new_mode); | ||
564 | int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 567 | int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
565 | void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); | 568 | void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); |
566 | void efx_ptp_start_datapath(struct efx_nic *efx); | 569 | void efx_ptp_start_datapath(struct efx_nic *efx); |
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index cf2ae11b13f1..1d1a6f7325da 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c | |||
@@ -1361,8 +1361,13 @@ int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) | |||
1361 | return NETDEV_TX_OK; | 1361 | return NETDEV_TX_OK; |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | 1364 | int efx_ptp_get_mode(struct efx_nic *efx) |
1365 | unsigned int new_mode) | 1365 | { |
1366 | return efx->ptp_data->mode; | ||
1367 | } | ||
1368 | |||
1369 | int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | ||
1370 | unsigned int new_mode) | ||
1366 | { | 1371 | { |
1367 | if ((enable_wanted != efx->ptp_data->enabled) || | 1372 | if ((enable_wanted != efx->ptp_data->enabled) || |
1368 | (enable_wanted && (efx->ptp_data->mode != new_mode))) { | 1373 | (enable_wanted && (efx->ptp_data->mode != new_mode))) { |
@@ -1406,8 +1411,6 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | |||
1406 | 1411 | ||
1407 | static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) | 1412 | static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) |
1408 | { | 1413 | { |
1409 | bool enable_wanted = false; | ||
1410 | unsigned int new_mode; | ||
1411 | int rc; | 1414 | int rc; |
1412 | 1415 | ||
1413 | if (init->flags) | 1416 | if (init->flags) |
@@ -1417,57 +1420,11 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) | |||
1417 | (init->tx_type != HWTSTAMP_TX_ON)) | 1420 | (init->tx_type != HWTSTAMP_TX_ON)) |
1418 | return -ERANGE; | 1421 | return -ERANGE; |
1419 | 1422 | ||
1420 | new_mode = efx->ptp_data->mode; | 1423 | rc = efx->type->ptp_set_ts_config(efx, init); |
1421 | /* Determine whether any PTP HW operations are required */ | 1424 | if (rc) |
1422 | switch (init->rx_filter) { | ||
1423 | case HWTSTAMP_FILTER_NONE: | ||
1424 | break; | ||
1425 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
1426 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
1427 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
1428 | init->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; | ||
1429 | new_mode = MC_CMD_PTP_MODE_V1; | ||
1430 | enable_wanted = true; | ||
1431 | break; | ||
1432 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
1433 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
1434 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
1435 | /* Although these three are accepted only IPV4 packets will be | ||
1436 | * timestamped | ||
1437 | */ | ||
1438 | init->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; | ||
1439 | new_mode = MC_CMD_PTP_MODE_V2_ENHANCED; | ||
1440 | enable_wanted = true; | ||
1441 | break; | ||
1442 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
1443 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
1444 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
1445 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
1446 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
1447 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
1448 | /* Non-IP + IPv6 timestamping not supported */ | ||
1449 | return -ERANGE; | ||
1450 | break; | ||
1451 | default: | ||
1452 | return -ERANGE; | ||
1453 | } | ||
1454 | |||
1455 | if (init->tx_type != HWTSTAMP_TX_OFF) | ||
1456 | enable_wanted = true; | ||
1457 | |||
1458 | /* Old versions of the firmware do not support the improved | ||
1459 | * UUID filtering option (SF bug 33070). If the firmware does | ||
1460 | * not accept the enhanced mode, fall back to the standard PTP | ||
1461 | * v2 UUID filtering. | ||
1462 | */ | ||
1463 | rc = efx_ptp_change_mode(efx, enable_wanted, new_mode); | ||
1464 | if ((rc != 0) && (new_mode == MC_CMD_PTP_MODE_V2_ENHANCED)) | ||
1465 | rc = efx_ptp_change_mode(efx, enable_wanted, MC_CMD_PTP_MODE_V2); | ||
1466 | if (rc != 0) | ||
1467 | return rc; | 1425 | return rc; |
1468 | 1426 | ||
1469 | efx->ptp_data->config = *init; | 1427 | efx->ptp_data->config = *init; |
1470 | |||
1471 | return 0; | 1428 | return 0; |
1472 | } | 1429 | } |
1473 | 1430 | ||
@@ -1483,13 +1440,7 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info) | |||
1483 | SOF_TIMESTAMPING_RAW_HARDWARE); | 1440 | SOF_TIMESTAMPING_RAW_HARDWARE); |
1484 | ts_info->phc_index = ptp_clock_index(ptp->phc_clock); | 1441 | ts_info->phc_index = ptp_clock_index(ptp->phc_clock); |
1485 | ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; | 1442 | ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; |
1486 | ts_info->rx_filters = (1 << HWTSTAMP_FILTER_NONE | | 1443 | ts_info->rx_filters = ptp->efx->type->hwtstamp_filters; |
1487 | 1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT | | ||
1488 | 1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC | | ||
1489 | 1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ | | ||
1490 | 1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT | | ||
1491 | 1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC | | ||
1492 | 1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ); | ||
1493 | } | 1444 | } |
1494 | 1445 | ||
1495 | int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr) | 1446 | int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr) |
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 53b4ce67be0e..f65db356fe09 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c | |||
@@ -118,6 +118,54 @@ out: | |||
118 | 118 | ||
119 | /************************************************************************** | 119 | /************************************************************************** |
120 | * | 120 | * |
121 | * PTP | ||
122 | * | ||
123 | ************************************************************************** | ||
124 | */ | ||
125 | |||
126 | static void siena_ptp_write_host_time(struct efx_nic *efx, u32 host_time) | ||
127 | { | ||
128 | _efx_writed(efx, cpu_to_le32(host_time), | ||
129 | FR_CZ_MC_TREG_SMEM + MC_SMEM_P0_PTP_TIME_OFST); | ||
130 | } | ||
131 | |||
132 | static int siena_ptp_set_ts_config(struct efx_nic *efx, | ||
133 | struct hwtstamp_config *init) | ||
134 | { | ||
135 | int rc; | ||
136 | |||
137 | switch (init->rx_filter) { | ||
138 | case HWTSTAMP_FILTER_NONE: | ||
139 | /* if TX timestamping is still requested then leave PTP on */ | ||
140 | return efx_ptp_change_mode(efx, | ||
141 | init->tx_type != HWTSTAMP_TX_OFF, | ||
142 | efx_ptp_get_mode(efx)); | ||
143 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
144 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
145 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
146 | init->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; | ||
147 | return efx_ptp_change_mode(efx, true, MC_CMD_PTP_MODE_V1); | ||
148 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
149 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
150 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
151 | init->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; | ||
152 | rc = efx_ptp_change_mode(efx, true, | ||
153 | MC_CMD_PTP_MODE_V2_ENHANCED); | ||
154 | /* bug 33070 - old versions of the firmware do not support the | ||
155 | * improved UUID filtering option. Similarly old versions of the | ||
156 | * application do not expect it to be enabled. If the firmware | ||
157 | * does not accept the enhanced mode, fall back to the standard | ||
158 | * PTP v2 UUID filtering. */ | ||
159 | if (rc != 0) | ||
160 | rc = efx_ptp_change_mode(efx, true, MC_CMD_PTP_MODE_V2); | ||
161 | return rc; | ||
162 | default: | ||
163 | return -ERANGE; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /************************************************************************** | ||
168 | * | ||
121 | * Device reset | 169 | * Device reset |
122 | * | 170 | * |
123 | ************************************************************************** | 171 | ************************************************************************** |
@@ -839,19 +887,6 @@ fail: | |||
839 | 887 | ||
840 | /************************************************************************** | 888 | /************************************************************************** |
841 | * | 889 | * |
842 | * PTP | ||
843 | * | ||
844 | ************************************************************************** | ||
845 | */ | ||
846 | |||
847 | static void siena_ptp_write_host_time(struct efx_nic *efx, u32 host_time) | ||
848 | { | ||
849 | _efx_writed(efx, cpu_to_le32(host_time), | ||
850 | FR_CZ_MC_TREG_SMEM + MC_SMEM_P0_PTP_TIME_OFST); | ||
851 | } | ||
852 | |||
853 | /************************************************************************** | ||
854 | * | ||
855 | * Revision-dependent attributes used by efx.c and nic.c | 890 | * Revision-dependent attributes used by efx.c and nic.c |
856 | * | 891 | * |
857 | ************************************************************************** | 892 | ************************************************************************** |
@@ -942,6 +977,7 @@ const struct efx_nic_type siena_a0_nic_type = { | |||
942 | .mtd_sync = efx_mcdi_mtd_sync, | 977 | .mtd_sync = efx_mcdi_mtd_sync, |
943 | #endif | 978 | #endif |
944 | .ptp_write_host_time = siena_ptp_write_host_time, | 979 | .ptp_write_host_time = siena_ptp_write_host_time, |
980 | .ptp_set_ts_config = siena_ptp_set_ts_config, | ||
945 | 981 | ||
946 | .revision = EFX_REV_SIENA_A0, | 982 | .revision = EFX_REV_SIENA_A0, |
947 | .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, | 983 | .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, |
@@ -960,4 +996,11 @@ const struct efx_nic_type siena_a0_nic_type = { | |||
960 | NETIF_F_RXHASH | NETIF_F_NTUPLE), | 996 | NETIF_F_RXHASH | NETIF_F_NTUPLE), |
961 | .mcdi_max_ver = 1, | 997 | .mcdi_max_ver = 1, |
962 | .max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS, | 998 | .max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS, |
999 | .hwtstamp_filters = (1 << HWTSTAMP_FILTER_NONE | | ||
1000 | 1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT | | ||
1001 | 1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC | | ||
1002 | 1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ | | ||
1003 | 1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT | | ||
1004 | 1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC | | ||
1005 | 1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ), | ||
963 | }; | 1006 | }; |