Commit 3c44191d authored by Vadim Fedorenko's avatar Vadim Fedorenko Committed by David S. Miller

ixgbe: fix timestamp configuration code

The commit in fixes introduced flags to control the status of hardware
configuration while processing packets. At the same time another structure
is used to provide configuration of timestamper to user-space applications.
The way it was coded makes this structures go out of sync easily. The
repro is easy for 82599 chips:

[root@hostname ~]# hwstamp_ctl -i eth0 -r 12 -t 1
current settings:
tx_type 0
rx_filter 0
new settings:
tx_type 1
rx_filter 12

The eth0 device is properly configured to timestamp any PTPv2 events.

[root@hostname ~]# hwstamp_ctl -i eth0 -r 1 -t 1
current settings:
tx_type 1
rx_filter 12
SIOCSHWTSTAMP failed: Numerical result out of range
The requested time stamping mode is not supported by the hardware.

The error is properly returned because HW doesn't support all packets
timestamping. But the adapter->flags is cleared of timestamp flags
even though no HW configuration was done. From that point no RX timestamps
are received by user-space application. But configuration shows good
values:

[root@hostname ~]# hwstamp_ctl -i eth0
current settings:
tx_type 1
rx_filter 12

Fix the issue by applying new flags only when the HW was actually
configured.

Fixes: a9763f3c ("ixgbe: Update PTP to support X550EM_x devices")
Signed-off-by: default avatarVadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ab6c4ec8
...@@ -979,6 +979,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -979,6 +979,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED;
u32 tsync_rx_mtrl = PTP_EV_PORT << 16; u32 tsync_rx_mtrl = PTP_EV_PORT << 16;
u32 aflags = adapter->flags;
bool is_l2 = false; bool is_l2 = false;
u32 regval; u32 regval;
...@@ -996,19 +997,19 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -996,19 +997,19 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
case HWTSTAMP_FILTER_NONE: case HWTSTAMP_FILTER_NONE:
tsync_rx_ctl = 0; tsync_rx_ctl = 0;
tsync_rx_mtrl = 0; tsync_rx_mtrl = 0;
adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
break; break;
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG;
adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
break; break;
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
break; break;
case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_EVENT:
...@@ -1023,7 +1024,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -1023,7 +1024,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
is_l2 = true; is_l2 = true;
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
break; break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
...@@ -1035,7 +1036,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -1035,7 +1036,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
if (hw->mac.type >= ixgbe_mac_X550) { if (hw->mac.type >= ixgbe_mac_X550) {
tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL; config->rx_filter = HWTSTAMP_FILTER_ALL;
adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
break; break;
} }
fallthrough; fallthrough;
...@@ -1046,8 +1047,6 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -1046,8 +1047,6 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
* Delay_Req messages and hardware does not support * Delay_Req messages and hardware does not support
* timestamping all packets => return error * timestamping all packets => return error
*/ */
adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
config->rx_filter = HWTSTAMP_FILTER_NONE; config->rx_filter = HWTSTAMP_FILTER_NONE;
return -ERANGE; return -ERANGE;
} }
...@@ -1079,8 +1078,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -1079,8 +1078,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
IXGBE_TSYNCRXCTL_TYPE_ALL | IXGBE_TSYNCRXCTL_TYPE_ALL |
IXGBE_TSYNCRXCTL_TSIP_UT_EN; IXGBE_TSYNCRXCTL_TSIP_UT_EN;
config->rx_filter = HWTSTAMP_FILTER_ALL; config->rx_filter = HWTSTAMP_FILTER_ALL;
adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER;
is_l2 = true; is_l2 = true;
break; break;
default: default:
...@@ -1113,6 +1112,9 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -1113,6 +1112,9 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
/* configure adapter flags only when HW is actually configured */
adapter->flags = aflags;
/* clear TX/RX time stamp registers, just to be sure */ /* clear TX/RX time stamp registers, just to be sure */
ixgbe_ptp_clear_tx_timestamp(adapter); ixgbe_ptp_clear_tx_timestamp(adapter);
IXGBE_READ_REG(hw, IXGBE_RXSTMPH); IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
......
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