aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorDaniel Pieczko <dpieczko@solarflare.com>2013-11-21 12:11:25 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-12-12 17:07:11 -0500
commit9ec0659595c8020f1efa55aa00870e8773f8ee89 (patch)
treed4b4fc24a45ac681182b426b68445fbb94702ed2 /drivers/net/ethernet
parenta6f73460b592404cca4ceafa69a835a61cdc20d8 (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.h9
-rw-r--r--drivers/net/ethernet/sfc/nic.h3
-rw-r--r--drivers/net/ethernet/sfc/ptp.c69
-rw-r--r--drivers/net/ethernet/sfc/siena.c69
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. */
93struct efx_ptp_data; 93struct efx_ptp_data;
94struct hwtstamp_config;
94 95
95struct efx_self_tests; 96struct 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 */
1064struct efx_nic_type { 1070struct 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);
561int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); 561int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
562void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); 562void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
563bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); 563bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
564int efx_ptp_get_mode(struct efx_nic *efx);
565int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
566 unsigned int new_mode);
564int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); 567int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
565void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); 568void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
566void efx_ptp_start_datapath(struct efx_nic *efx); 569void 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
1364static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, 1364int efx_ptp_get_mode(struct efx_nic *efx)
1365 unsigned int new_mode) 1365{
1366 return efx->ptp_data->mode;
1367}
1368
1369int 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
1407static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) 1412static 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
1495int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr) 1446int 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
126static 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
132static 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
847static 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};