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

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
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -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,
};
};


+37 −26
Original line number Original line Diff line number Diff line
@@ -116,7 +116,7 @@ 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)
@@ -192,7 +192,7 @@ 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)
@@ -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)
		}
		}


		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,11 +319,33 @@ 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 hsr_frame_info *frame)
{
	struct hsr_priv *hsr = frame->port_rcv->hsr;
	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 sk_buff *skb, struct hsr_port *port)
{
{
	struct hsr_priv *hsr = port->hsr;
	struct ethhdr *ethhdr;
	struct ethhdr *ethhdr;
	unsigned long irqflags;
	__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);
@@ -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)
		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);
+6 −1
Original line number Original line Diff line number Diff line
@@ -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 */
+8 −0
Original line number Original line Diff line number Diff line
@@ -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 {