Skip to content

Commit

Permalink
Merge pull request torvalds#159 in PROCESSOR-SDK/processor-sdk-linux …
Browse files Browse the repository at this point in the history
…from PLSDK-2497 to processor-sdk-linux-4.19.y

* commit 'd7a1049951aaf67074ddace44a693500569efacb':
  net: hsr-prp: Add support for PTP over VLAN
  net: ethernet: prueth: Add functionality to run PTP over VLAN
  • Loading branch information
Aaron Kramer committed Jun 6, 2019
2 parents e7197a1 + d7a1049 commit e11f61e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 18 deletions.
33 changes: 27 additions & 6 deletions drivers/net/ethernet/ti/prueth.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@ static inline int is_hsr_skb(struct sk_buff *skb)
return (*(p + 12) == 0x89 && *(p + 13) == 0x2f);
}

static inline int is_vlan_skb(struct sk_buff *skb)
{
__be16 ethertype;

if (!skb->data)
return 0;

ethertype = *(skb->data + 12);

/* FIXME: should use macros to access header fields */
return eth_type_vlan(ethertype);
}

static inline u32 prueth_read_reg(struct prueth *prueth,
enum prueth_mem region,
unsigned int reg)
Expand Down Expand Up @@ -581,7 +594,7 @@ static int pruptp_hsr_cut_thru_ts_work_init(struct prueth_emac *emac)
static int pruptp_rx_timestamp(struct prueth_emac *emac, struct sk_buff *skb)
{
struct prueth *prueth = emac->prueth;
bool changed = false;
int changed = 0;
u32 ts_ofs;
u8 ts_msgtype;
int ret;
Expand All @@ -591,20 +604,24 @@ static int pruptp_rx_timestamp(struct prueth_emac *emac, struct sk_buff *skb)
if (!emac_is_ptp_rx_enabled(emac))
return -EPERM;

if (is_vlan_skb(skb)) {
skb->data += 4;
changed += 4;
}
if (PRUETH_HAS_HSR(prueth) && is_hsr_skb(skb)) {
/* This 6-byte shift is just a trick to skip
* the size of a hsr tag so that the same
* pruptp_ts_msgtype can be re-used to parse
* hsr tagged skbs
*/
skb->data += 6;
changed = true;
changed += 6;
}

ts_msgtype = pruptp_ts_msgtype(skb);

if (changed)
skb->data -= 6;
skb->data -= changed;

if ((ts_msgtype != PTP_SYNC_MSG_ID) &&
(ts_msgtype != PTP_PDLY_REQ_MSG_ID) &&
Expand Down Expand Up @@ -1675,24 +1692,28 @@ static inline int emac_tx_ts_enqueue(struct prueth_emac *emac,
{
unsigned long flags;
struct prueth *prueth = emac->prueth;
bool changed = false;
int changed = 0;
u8 msg_t;
struct tx_ev_cb_data *cb;

if (is_vlan_skb(skb)) {
skb->data += 4;
changed += 4;
}
if (PRUETH_HAS_HSR(prueth) && is_hsr_skb(skb)) {
/* This 6-byte shift is just a trick to skip
* the size of a hsr tag so that the same
* pruptp_ts_msgtype can be re-used to parse
* hsr tagged skbs
*/
skb->data += 6;
changed = true;
changed += 6;
}

msg_t = pruptp_ts_msgtype(skb);

if (changed)
skb->data -= 6;
skb->data -= changed;

if (msg_t > PTP_PDLY_RSP_MSG_ID) {
netdev_err(emac->ndev, "invalid msg_t %u\n", msg_t);
Expand Down
39 changes: 27 additions & 12 deletions net/hsr-prp/hsr_prp_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,33 @@ struct hsr_prp_frame_info {
struct skb_redundant_info *sred;
};

static inline int is_hsr_l2ptp(struct sk_buff *skb)
static inline int is_hsr_l2ptp(struct sk_buff *skb,
struct hsr_prp_frame_info *frame)
{
struct hsr_ethhdr *hsr_ethhdr;
unsigned char *pc;

hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb);
pc = skb_mac_header(skb);
if (frame->is_vlan)
hsr_ethhdr = (struct hsr_ethhdr *)(pc + VLAN_HLEN);
else
hsr_ethhdr = (struct hsr_ethhdr *)pc;

return (hsr_ethhdr->ethhdr.h_proto == htons(ETH_P_HSR) &&
hsr_ethhdr->hsr_tag.encap_proto == htons(ETH_P_1588));
}

static inline int is_hsr_l2ptp_evt(struct sk_buff *skb)
static inline int is_hsr_l2ptp_evt(struct sk_buff *skb,
struct hsr_prp_frame_info *frame)
{
unsigned char *p;

if (!skb->data)
return 0;

p = skb->data;
if (frame->is_vlan)
p += VLAN_HLEN;

/* FIXME: should use macros to access header fields */
return (*(p + 12) == 0x89 && *(p + 13) == 0x2f && /* HSR */
Expand Down Expand Up @@ -318,7 +327,7 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
struct hsr_prp_port *port)
{
int movelen;
unsigned char *dst, *src;
unsigned char *dst, *src, *pc;
struct sk_buff *skb;
struct skb_redundant_info *sred;
struct hsr_ethhdr *hsr_ethhdr;
Expand Down Expand Up @@ -362,12 +371,14 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,

skb_shinfo(skb)->tx_flags = skb_shinfo(skb_o)->tx_flags;
skb->sk = skb_o->sk;

/* TODO: should check socket option instead? */
if (is_hsr_l2ptp(skb)) {
if (is_hsr_l2ptp(skb, frame)) {
sred = skb_redinfo(skb);
/* assumes no vlan */
hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb);
pc = skb_mac_header(skb);
if (frame->is_vlan)
hsr_ethhdr = (struct hsr_ethhdr *)(pc + VLAN_HLEN);
else
hsr_ethhdr = (struct hsr_ethhdr *)pc;
sred->io_port = (PTP_EVT_OUT | BIT(port->type - 1));
sred->ethertype = ntohs(hsr_ethhdr->ethhdr.h_proto);
s = ntohs(hsr_ethhdr->hsr_tag.path_and_LSDU_size);
Expand Down Expand Up @@ -480,6 +491,7 @@ static void stripped_skb_get_shared_info(struct sk_buff *skb_stripped,
struct sk_buff *skb_hsr, *skb;
struct skb_redundant_info *sred;
struct hsr_ethhdr *hsr_ethhdr;
unsigned char *pc;
u16 s;

if (port_rcv->priv->prot_version > HSR_V1)
Expand All @@ -491,18 +503,21 @@ static void stripped_skb_get_shared_info(struct sk_buff *skb_stripped,
skb_hsr = frame->skb_hsr;
skb = skb_stripped;

if (is_hsr_l2ptp_evt(skb_hsr)) {
if (is_hsr_l2ptp_evt(skb_hsr, frame)) {
/* Rx timestamp */
skb_hwtstamps(skb)->hwtstamp = skb_hwtstamps(skb_hsr)->hwtstamp;
/* Cut-through tx timestamp */
skb_redinfo_hwtstamps(skb)->hwtstamp =
skb_redinfo_hwtstamps(skb_hsr)->hwtstamp;
}

if (is_hsr_l2ptp(skb_hsr)) {
if (is_hsr_l2ptp(skb_hsr, frame)) {
sred = skb_redinfo(skb);
/* assumes no vlan */
hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb_hsr);
pc = skb_mac_header(skb);
if (frame->is_vlan)
hsr_ethhdr = (struct hsr_ethhdr *)(pc + VLAN_HLEN);
else
hsr_ethhdr = (struct hsr_ethhdr *)pc;
sred->io_port = (PTP_MSG_IN | BIT(port_rcv->type - 1));
sred->ethertype = ntohs(hsr_ethhdr->ethhdr.h_proto);
s = ntohs(hsr_ethhdr->hsr_tag.path_and_LSDU_size);
Expand Down

0 comments on commit e11f61e

Please sign in to comment.