Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 368186
b: refs/heads/master
c: c939a31
h: refs/heads/master
v: v3
  • Loading branch information
Laurence Evans authored and Ben Hutchings committed Mar 7, 2013
1 parent f48f669 commit 0433fde
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4a74dc65e3ad825a66dfbcb256f98c550f96445b
refs/heads/master: c939a316459783e5cd6c6bd9dc90ea11b18ecd7f
1 change: 1 addition & 0 deletions trunk/drivers/net/ethernet/sfc/mcdi_pcol.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@
#define MC_CMD_PTP_MODE_V1_VLAN 0x1 /* enum */
#define MC_CMD_PTP_MODE_V2 0x2 /* enum */
#define MC_CMD_PTP_MODE_V2_VLAN 0x3 /* enum */
#define MC_CMD_PTP_MODE_V2_ENHANCED 0x4 /* enum */

/* MC_CMD_PTP_IN_DISABLE msgrequest */
#define MC_CMD_PTP_IN_DISABLE_LEN 8
Expand Down
61 changes: 45 additions & 16 deletions trunk/drivers/net/ethernet/sfc/ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@
#define PTP_V2_VERSION_LENGTH 1
#define PTP_V2_VERSION_OFFSET 29

#define PTP_V2_UUID_LENGTH 8
#define PTP_V2_UUID_OFFSET 48

/* Although PTP V2 UUIDs are comprised a ClockIdentity (8) and PortNumber (2),
* the MC only captures the last six bytes of the clock identity. These values
* reflect those, not the ones used in the standard. The standard permits
Expand Down Expand Up @@ -1011,7 +1014,7 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb)
struct efx_nic *efx = channel->efx;
struct efx_ptp_data *ptp = efx->ptp_data;
struct efx_ptp_match *match = (struct efx_ptp_match *)skb->cb;
u8 *data;
u8 *match_data_012, *match_data_345;
unsigned int version;

match->expiry = jiffies + msecs_to_jiffies(PKT_EVENT_LIFETIME_MS);
Expand All @@ -1025,21 +1028,35 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb)
if (version != PTP_VERSION_V1) {
return false;
}

/* PTP V1 uses all six bytes of the UUID to match the packet
* to the timestamp
*/
match_data_012 = skb->data + PTP_V1_UUID_OFFSET;
match_data_345 = skb->data + PTP_V1_UUID_OFFSET + 3;
} else {
if (skb->len < PTP_V2_MIN_LENGTH) {
return false;
}
version = skb->data[PTP_V2_VERSION_OFFSET];

BUG_ON(ptp->mode != MC_CMD_PTP_MODE_V2);
BUILD_BUG_ON(PTP_V1_UUID_OFFSET != PTP_V2_MC_UUID_OFFSET);
BUILD_BUG_ON(PTP_V1_UUID_LENGTH != PTP_V2_MC_UUID_LENGTH);
BUILD_BUG_ON(PTP_V1_SEQUENCE_OFFSET != PTP_V2_SEQUENCE_OFFSET);
BUILD_BUG_ON(PTP_V1_SEQUENCE_LENGTH != PTP_V2_SEQUENCE_LENGTH);

if ((version & PTP_VERSION_V2_MASK) != PTP_VERSION_V2) {
return false;
}

/* The original V2 implementation uses bytes 2-7 of
* the UUID to match the packet to the timestamp. This
* discards two of the bytes of the MAC address used
* to create the UUID (SF bug 33070). The PTP V2
* enhanced mode fixes this issue and uses bytes 0-2
* and byte 5-7 of the UUID.
*/
match_data_345 = skb->data + PTP_V2_UUID_OFFSET + 5;
if (ptp->mode == MC_CMD_PTP_MODE_V2) {
match_data_012 = skb->data + PTP_V2_UUID_OFFSET + 2;
} else {
match_data_012 = skb->data + PTP_V2_UUID_OFFSET + 0;
BUG_ON(ptp->mode != MC_CMD_PTP_MODE_V2_ENHANCED);
}
}

/* Does this packet require timestamping? */
Expand All @@ -1052,14 +1069,19 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb)
timestamps = skb_hwtstamps(skb);
memset(timestamps, 0, sizeof(*timestamps));

/* We expect the sequence number to be in the same position in
* the packet for PTP V1 and V2
*/
BUILD_BUG_ON(PTP_V1_SEQUENCE_OFFSET != PTP_V2_SEQUENCE_OFFSET);
BUILD_BUG_ON(PTP_V1_SEQUENCE_LENGTH != PTP_V2_SEQUENCE_LENGTH);

/* Extract UUID/Sequence information */
data = skb->data + PTP_V1_UUID_OFFSET;
match->words[0] = (data[0] |
(data[1] << 8) |
(data[2] << 16) |
(data[3] << 24));
match->words[1] = (data[4] |
(data[5] << 8) |
match->words[0] = (match_data_012[0] |
(match_data_012[1] << 8) |
(match_data_012[2] << 16) |
(match_data_345[0] << 24));
match->words[1] = (match_data_345[1] |
(match_data_345[2] << 8) |
(skb->data[PTP_V1_SEQUENCE_OFFSET +
PTP_V1_SEQUENCE_LENGTH - 1] <<
16));
Expand Down Expand Up @@ -1165,7 +1187,7 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init)
* timestamped
*/
init->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
new_mode = MC_CMD_PTP_MODE_V2;
new_mode = MC_CMD_PTP_MODE_V2_ENHANCED;
enable_wanted = true;
break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
Expand All @@ -1184,7 +1206,14 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init)
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;

Expand Down

0 comments on commit 0433fde

Please sign in to comment.