ocelot.c (9fde506e0c53b8309f69b18b4b8144c544b4b3b1) ocelot.c (fba01283d85a09e0e2ef552c6e764b903111d90a)
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/dsa/ocelot.h>
8#include <linux/if_bridge.h>

--- 604 unchanged lines hidden (view full) ---

613 } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
614 rew_op = ptp_cmd;
615 }
616
617 return rew_op;
618}
619EXPORT_SYMBOL(ocelot_ptp_rew_op);
620
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/dsa/ocelot.h>
8#include <linux/if_bridge.h>

--- 604 unchanged lines hidden (view full) ---

613 } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
614 rew_op = ptp_cmd;
615 }
616
617 return rew_op;
618}
619EXPORT_SYMBOL(ocelot_ptp_rew_op);
620
621static bool ocelot_ptp_is_onestep_sync(struct sk_buff *skb)
621static bool ocelot_ptp_is_onestep_sync(struct sk_buff *skb,
622 unsigned int ptp_class)
622{
623 struct ptp_header *hdr;
623{
624 struct ptp_header *hdr;
624 unsigned int ptp_class;
625 u8 msgtype, twostep;
626
625 u8 msgtype, twostep;
626
627 ptp_class = ptp_classify_raw(skb);
628 if (ptp_class == PTP_CLASS_NONE)
629 return false;
630
631 hdr = ptp_parse_header(skb, ptp_class);
632 if (!hdr)
633 return false;
634
635 msgtype = ptp_get_msgtype(hdr, ptp_class);
636 twostep = hdr->flag_field[0] & 0x2;
637
638 if (msgtype == PTP_MSGTYPE_SYNC && twostep == 0)
639 return true;
640
641 return false;
642}
643
644int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port,
645 struct sk_buff *skb,
646 struct sk_buff **clone)
647{
648 struct ocelot_port *ocelot_port = ocelot->ports[port];
649 u8 ptp_cmd = ocelot_port->ptp_cmd;
627 hdr = ptp_parse_header(skb, ptp_class);
628 if (!hdr)
629 return false;
630
631 msgtype = ptp_get_msgtype(hdr, ptp_class);
632 twostep = hdr->flag_field[0] & 0x2;
633
634 if (msgtype == PTP_MSGTYPE_SYNC && twostep == 0)
635 return true;
636
637 return false;
638}
639
640int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port,
641 struct sk_buff *skb,
642 struct sk_buff **clone)
643{
644 struct ocelot_port *ocelot_port = ocelot->ports[port];
645 u8 ptp_cmd = ocelot_port->ptp_cmd;
646 unsigned int ptp_class;
650 int err;
651
647 int err;
648
649 /* Don't do anything if PTP timestamping not enabled */
650 if (!ptp_cmd)
651 return 0;
652
653 ptp_class = ptp_classify_raw(skb);
654 if (ptp_class == PTP_CLASS_NONE)
655 return -EINVAL;
656
652 /* Store ptp_cmd in OCELOT_SKB_CB(skb)->ptp_cmd */
653 if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
657 /* Store ptp_cmd in OCELOT_SKB_CB(skb)->ptp_cmd */
658 if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
654 if (ocelot_ptp_is_onestep_sync(skb)) {
659 if (ocelot_ptp_is_onestep_sync(skb, ptp_class)) {
655 OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd;
656 return 0;
657 }
658
659 /* Fall back to two-step timestamping */
660 ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
661 }
662

--- 1588 unchanged lines hidden ---
660 OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd;
661 return 0;
662 }
663
664 /* Fall back to two-step timestamping */
665 ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
666 }
667

--- 1588 unchanged lines hidden ---