Skip to content

Commit 57ee958

Browse files
HoratiuVulturPaolo Abeni
authored andcommitted
net: lan966x: Fix 1-step timestamping over ipv4 or ipv6
When enabling 1-step timestamping for ptp frames that are over udpv4 or udpv6 then the inserted timestamp is added at the wrong offset in the frame, meaning that will modify the frame at the wrong place, so the frame will be malformed. To fix this, the HW needs to know which kind of frame it is to know where to insert the timestamp. For that there is a field in the IFH that says the PDU_TYPE, which can be NONE which is the default value, IPV4 or IPV6. Therefore make sure to set the PDU_TYPE so the HW knows where to insert the timestamp. Like I mention before the issue is not seen with L2 frames because by default the PDU_TYPE has a value of 0, which represents the L2 frames. Fixes: 77eecf2 ("net: lan966x: Update extraction/injection for timestamping") Signed-off-by: Horatiu Vultur <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 45ca7e9 commit 57ee958

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

drivers/net/ethernet/microchip/lan966x/lan966x_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,11 @@ static void lan966x_ifh_set_rew_op(void *ifh, u64 rew_op)
353353
lan966x_ifh_set(ifh, rew_op, IFH_POS_REW_CMD, IFH_WID_REW_CMD);
354354
}
355355

356+
static void lan966x_ifh_set_oam_type(void *ifh, u64 oam_type)
357+
{
358+
lan966x_ifh_set(ifh, oam_type, IFH_POS_PDU_TYPE, IFH_WID_PDU_TYPE);
359+
}
360+
356361
static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp)
357362
{
358363
lan966x_ifh_set(ifh, timestamp, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP);
@@ -380,6 +385,7 @@ static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb,
380385
return err;
381386

382387
lan966x_ifh_set_rew_op(ifh, LAN966X_SKB_CB(skb)->rew_op);
388+
lan966x_ifh_set_oam_type(ifh, LAN966X_SKB_CB(skb)->pdu_type);
383389
lan966x_ifh_set_timestamp(ifh, LAN966X_SKB_CB(skb)->ts_id);
384390
}
385391

drivers/net/ethernet/microchip/lan966x/lan966x_main.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@
7575
#define IFH_REW_OP_ONE_STEP_PTP 0x3
7676
#define IFH_REW_OP_TWO_STEP_PTP 0x4
7777

78+
#define IFH_PDU_TYPE_NONE 0
79+
#define IFH_PDU_TYPE_IPV4 7
80+
#define IFH_PDU_TYPE_IPV6 8
81+
7882
#define FDMA_RX_DCB_MAX_DBS 1
7983
#define FDMA_TX_DCB_MAX_DBS 1
8084

@@ -254,6 +258,7 @@ struct lan966x_phc {
254258

255259
struct lan966x_skb_cb {
256260
u8 rew_op;
261+
u8 pdu_type;
257262
u16 ts_id;
258263
unsigned long jiffies;
259264
};

drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -322,34 +322,55 @@ void lan966x_ptp_hwtstamp_get(struct lan966x_port *port,
322322
*cfg = phc->hwtstamp_config;
323323
}
324324

325-
static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb)
325+
static void lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb,
326+
u8 *rew_op, u8 *pdu_type)
326327
{
327328
struct ptp_header *header;
328329
u8 msgtype;
329330
int type;
330331

331-
if (port->ptp_tx_cmd == IFH_REW_OP_NOOP)
332-
return IFH_REW_OP_NOOP;
332+
if (port->ptp_tx_cmd == IFH_REW_OP_NOOP) {
333+
*rew_op = IFH_REW_OP_NOOP;
334+
*pdu_type = IFH_PDU_TYPE_NONE;
335+
return;
336+
}
333337

334338
type = ptp_classify_raw(skb);
335-
if (type == PTP_CLASS_NONE)
336-
return IFH_REW_OP_NOOP;
339+
if (type == PTP_CLASS_NONE) {
340+
*rew_op = IFH_REW_OP_NOOP;
341+
*pdu_type = IFH_PDU_TYPE_NONE;
342+
return;
343+
}
337344

338345
header = ptp_parse_header(skb, type);
339-
if (!header)
340-
return IFH_REW_OP_NOOP;
346+
if (!header) {
347+
*rew_op = IFH_REW_OP_NOOP;
348+
*pdu_type = IFH_PDU_TYPE_NONE;
349+
return;
350+
}
341351

342-
if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP)
343-
return IFH_REW_OP_TWO_STEP_PTP;
352+
if (type & PTP_CLASS_L2)
353+
*pdu_type = IFH_PDU_TYPE_NONE;
354+
if (type & PTP_CLASS_IPV4)
355+
*pdu_type = IFH_PDU_TYPE_IPV4;
356+
if (type & PTP_CLASS_IPV6)
357+
*pdu_type = IFH_PDU_TYPE_IPV6;
358+
359+
if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP) {
360+
*rew_op = IFH_REW_OP_TWO_STEP_PTP;
361+
return;
362+
}
344363

345364
/* If it is sync and run 1 step then set the correct operation,
346365
* otherwise run as 2 step
347366
*/
348367
msgtype = ptp_get_msgtype(header, type);
349-
if ((msgtype & 0xf) == 0)
350-
return IFH_REW_OP_ONE_STEP_PTP;
368+
if ((msgtype & 0xf) == 0) {
369+
*rew_op = IFH_REW_OP_ONE_STEP_PTP;
370+
return;
371+
}
351372

352-
return IFH_REW_OP_TWO_STEP_PTP;
373+
*rew_op = IFH_REW_OP_TWO_STEP_PTP;
353374
}
354375

355376
static void lan966x_ptp_txtstamp_old_release(struct lan966x_port *port)
@@ -374,10 +395,12 @@ int lan966x_ptp_txtstamp_request(struct lan966x_port *port,
374395
{
375396
struct lan966x *lan966x = port->lan966x;
376397
unsigned long flags;
398+
u8 pdu_type;
377399
u8 rew_op;
378400

379-
rew_op = lan966x_ptp_classify(port, skb);
401+
lan966x_ptp_classify(port, skb, &rew_op, &pdu_type);
380402
LAN966X_SKB_CB(skb)->rew_op = rew_op;
403+
LAN966X_SKB_CB(skb)->pdu_type = pdu_type;
381404

382405
if (rew_op != IFH_REW_OP_TWO_STEP_PTP)
383406
return 0;

0 commit comments

Comments
 (0)