Commit fa4dc895 authored by Murali Karicheri's avatar Murali Karicheri Committed by David S. Miller

net: hsr: define and use proto_ops ptrs to handle hsr specific frames

As a preparatory patch to introduce PRP, refactor the code specific to
handling HSR frames into separate functions and call them through
proto_ops function pointers.
Signed-off-by: default avatarMurali Karicheri <m-karicheri2@ti.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c643ff03
...@@ -440,9 +440,12 @@ static struct device_type hsr_type = { ...@@ -440,9 +440,12 @@ static struct device_type hsr_type = {
static struct hsr_proto_ops hsr_ops = { static struct hsr_proto_ops hsr_ops = {
.send_sv_frame = send_hsr_supervision_frame, .send_sv_frame = send_hsr_supervision_frame,
.create_tagged_frame = hsr_create_tagged_frame,
.get_untagged_frame = hsr_get_untagged_frame,
.fill_frame_info = hsr_fill_frame_info,
}; };
struct hsr_proto_ops prp_ops = { static struct hsr_proto_ops prp_ops = {
.send_sv_frame = send_prp_supervision_frame, .send_sv_frame = send_prp_supervision_frame,
}; };
......
...@@ -116,8 +116,8 @@ static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in, ...@@ -116,8 +116,8 @@ static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in,
return skb; return skb;
} }
static struct sk_buff *frame_get_stripped_skb(struct hsr_frame_info *frame, struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame,
struct hsr_port *port) struct hsr_port *port)
{ {
if (!frame->skb_std) if (!frame->skb_std)
frame->skb_std = create_stripped_skb(frame->skb_hsr, frame); frame->skb_std = create_stripped_skb(frame->skb_hsr, frame);
...@@ -192,8 +192,8 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, ...@@ -192,8 +192,8 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
/* If the original frame was an HSR tagged frame, just clone it to be sent /* If the original frame was an HSR tagged frame, just clone it to be sent
* unchanged. Otherwise, create a private frame especially tagged for 'port'. * unchanged. Otherwise, create a private frame especially tagged for 'port'.
*/ */
static struct sk_buff *frame_get_tagged_skb(struct hsr_frame_info *frame, struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame,
struct hsr_port *port) struct hsr_port *port)
{ {
if (frame->skb_hsr) if (frame->skb_hsr)
return skb_clone(frame->skb_hsr, GFP_ATOMIC); return skb_clone(frame->skb_hsr, GFP_ATOMIC);
...@@ -257,6 +257,7 @@ static void hsr_forward_do(struct hsr_frame_info *frame) ...@@ -257,6 +257,7 @@ static void hsr_forward_do(struct hsr_frame_info *frame)
struct sk_buff *skb; struct sk_buff *skb;
hsr_for_each_port(frame->port_rcv->hsr, port) { hsr_for_each_port(frame->port_rcv->hsr, port) {
struct hsr_priv *hsr = port->hsr;
/* Don't send frame back the way it came */ /* Don't send frame back the way it came */
if (port == frame->port_rcv) if (port == frame->port_rcv)
continue; continue;
...@@ -282,9 +283,10 @@ static void hsr_forward_do(struct hsr_frame_info *frame) ...@@ -282,9 +283,10 @@ static void hsr_forward_do(struct hsr_frame_info *frame)
} }
if (port->type != HSR_PT_MASTER) if (port->type != HSR_PT_MASTER)
skb = frame_get_tagged_skb(frame, port); skb = hsr->proto_ops->create_tagged_frame(frame, port);
else else
skb = frame_get_stripped_skb(frame, port); skb = hsr->proto_ops->get_untagged_frame(frame, port);
if (!skb) { if (!skb) {
/* FIXME: Record the dropped frame? */ /* FIXME: Record the dropped frame? */
continue; continue;
...@@ -317,12 +319,34 @@ static void check_local_dest(struct hsr_priv *hsr, struct sk_buff *skb, ...@@ -317,12 +319,34 @@ static void check_local_dest(struct hsr_priv *hsr, struct sk_buff *skb,
} }
} }
static int hsr_fill_frame_info(struct hsr_frame_info *frame, void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb,
struct sk_buff *skb, struct hsr_port *port) struct hsr_frame_info *frame)
{ {
struct ethhdr *ethhdr; struct hsr_priv *hsr = frame->port_rcv->hsr;
unsigned long irqflags; unsigned long irqflags;
if (proto == htons(ETH_P_PRP) || proto == htons(ETH_P_HSR)) {
frame->skb_std = NULL;
frame->skb_hsr = skb;
frame->sequence_nr = hsr_get_skb_sequence_nr(skb);
} else {
frame->skb_std = skb;
frame->skb_hsr = NULL;
/* Sequence nr for the master node */
spin_lock_irqsave(&hsr->seqnr_lock, irqflags);
frame->sequence_nr = hsr->sequence_nr;
hsr->sequence_nr++;
spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags);
}
}
static int fill_frame_info(struct hsr_frame_info *frame,
struct sk_buff *skb, struct hsr_port *port)
{
struct hsr_priv *hsr = port->hsr;
struct ethhdr *ethhdr;
__be16 proto;
frame->is_supervision = is_supervision_frame(port->hsr, skb); frame->is_supervision = is_supervision_frame(port->hsr, skb);
frame->node_src = hsr_get_node(port, skb, frame->is_supervision); frame->node_src = hsr_get_node(port, skb, frame->is_supervision);
if (!frame->node_src) if (!frame->node_src)
...@@ -335,23 +359,10 @@ static int hsr_fill_frame_info(struct hsr_frame_info *frame, ...@@ -335,23 +359,10 @@ static int hsr_fill_frame_info(struct hsr_frame_info *frame,
/* FIXME: */ /* FIXME: */
netdev_warn_once(skb->dev, "VLAN not yet supported"); netdev_warn_once(skb->dev, "VLAN not yet supported");
} }
if (ethhdr->h_proto == htons(ETH_P_PRP) || proto = ethhdr->h_proto;
ethhdr->h_proto == htons(ETH_P_HSR)) {
frame->skb_std = NULL;
frame->skb_hsr = skb;
frame->sequence_nr = hsr_get_skb_sequence_nr(skb);
} else {
frame->skb_std = skb;
frame->skb_hsr = NULL;
/* Sequence nr for the master node */
spin_lock_irqsave(&port->hsr->seqnr_lock, irqflags);
frame->sequence_nr = port->hsr->sequence_nr;
port->hsr->sequence_nr++;
spin_unlock_irqrestore(&port->hsr->seqnr_lock, irqflags);
}
frame->port_rcv = port; frame->port_rcv = port;
check_local_dest(port->hsr, skb, frame); hsr->proto_ops->fill_frame_info(proto, skb, frame);
check_local_dest(hsr, skb, frame);
return 0; return 0;
} }
...@@ -367,7 +378,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) ...@@ -367,7 +378,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
goto out_drop; goto out_drop;
} }
if (hsr_fill_frame_info(&frame, skb, port) < 0) if (fill_frame_info(&frame, skb, port) < 0)
goto out_drop; goto out_drop;
hsr_register_frame_in(frame.node_src, port, frame.sequence_nr); hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
hsr_forward_do(&frame); hsr_forward_do(&frame);
......
...@@ -14,5 +14,10 @@ ...@@ -14,5 +14,10 @@
#include "hsr_main.h" #include "hsr_main.h"
void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port); void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port);
struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame,
struct hsr_port *port);
struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame,
struct hsr_port *port);
void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb,
struct hsr_frame_info *frame);
#endif /* __HSR_FORWARD_H */ #endif /* __HSR_FORWARD_H */
...@@ -162,9 +162,17 @@ enum hsr_version { ...@@ -162,9 +162,17 @@ enum hsr_version {
PRP_V1, PRP_V1,
}; };
struct hsr_frame_info;
struct hsr_proto_ops { struct hsr_proto_ops {
/* format and send supervision frame */ /* format and send supervision frame */
void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval); void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval);
struct sk_buff * (*get_untagged_frame)(struct hsr_frame_info *frame,
struct hsr_port *port);
struct sk_buff * (*create_tagged_frame)(struct hsr_frame_info *frame,
struct hsr_port *port);
void (*fill_frame_info)(__be16 proto, struct sk_buff *skb,
struct hsr_frame_info *frame);
}; };
struct hsr_priv { struct hsr_priv {
......
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