170ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin/* Copyright 2011-2014 Autronica Fire and Security AS
2f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin *
3f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * This program is free software; you can redistribute it and/or modify it
4f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * under the terms of the GNU General Public License as published by the Free
5f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * Software Foundation; either version 2 of the License, or (at your option)
6f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * any later version.
7f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin *
8f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * Author(s):
970ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin *	2011-2014 Arvid Brodin, arvid.brodin@alten.se
10f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin */
11f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
1270ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin#ifndef __HSR_PRIVATE_H
1370ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin#define __HSR_PRIVATE_H
14f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
15f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#include <linux/netdevice.h>
16f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#include <linux/list.h>
17f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
18f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
19f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin/* Time constants as specified in the HSR specification (IEC-62439-3 2010)
20f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * Table 8.
21f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * All values in milliseconds.
22f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin */
23f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#define HSR_LIFE_CHECK_INTERVAL		 2000 /* ms */
24f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#define HSR_NODE_FORGET_TIME		60000 /* ms */
25f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#define HSR_ANNOUNCE_INTERVAL		  100 /* ms */
26f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
27f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
28f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin/* By how much may slave1 and slave2 timestamps of latest received frame from
29f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * each node differ before we notify of communication problem?
30f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin */
31f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#define MAX_SLAVE_DIFF			 3000 /* ms */
32f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin#define HSR_SEQNR_START			(USHRT_MAX - 1024)
33f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
34f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
35f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin/* How often shall we check for broken ring and remove node entries older than
36f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * HSR_NODE_FORGET_TIME?
37f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin */
38f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#define PRUNE_PERIOD			 3000 /* ms */
39f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
40f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
41f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#define HSR_TLV_ANNOUNCE		   22
42f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin#define HSR_TLV_LIFE_CHECK		   23
43f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
44f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
45f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin/* HSR Tag.
46f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * As defined in IEC-62439-3:2010, the HSR tag is really { ethertype = 0x88FB,
47f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * path, LSDU_size, sequence Nr }. But we let eth_header() create { h_dest,
48f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * h_source, h_proto = 0x88FB }, and add { path, LSDU_size, sequence Nr,
49f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * encapsulated protocol } instead.
5070ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin *
5170ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin * Field names as defined in the IEC:2010 standard for HSR.
52f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin */
53f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstruct hsr_tag {
54f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	__be16		path_and_LSDU_size;
55f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	__be16		sequence_nr;
56f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	__be16		encap_proto;
57f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin} __packed;
58f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
5970ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin#define HSR_HLEN	6
60f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
61f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin/* The helper functions below assumes that 'path' occupies the 4 most
62f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * significant bits of the 16-bit field shared by 'path' and 'LSDU_size' (or
63f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * equivalently, the 4 most significant bits of HSR tag byte 14).
64f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin *
65f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * This is unclear in the IEC specification; its definition of MAC addresses
66f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * indicates the spec is written with the least significant bit first (to the
67f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * left). This, however, would mean that the LSDU field would be split in two
68f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * with the path field in-between, which seems strange. I'm guessing the MAC
69f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * address definition is in error.
70f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin */
71f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline u16 get_hsr_tag_path(struct hsr_tag *ht)
72f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
73f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	return ntohs(ht->path_and_LSDU_size) >> 12;
74f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
75f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
76f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline u16 get_hsr_tag_LSDU_size(struct hsr_tag *ht)
77f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
78f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	return ntohs(ht->path_and_LSDU_size) & 0x0FFF;
79f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
80f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
81f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline void set_hsr_tag_path(struct hsr_tag *ht, u16 path)
82f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
83f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	ht->path_and_LSDU_size = htons(
84f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin			(ntohs(ht->path_and_LSDU_size) & 0x0FFF) | (path << 12));
85f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
86f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
87f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline void set_hsr_tag_LSDU_size(struct hsr_tag *ht, u16 LSDU_size)
88f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
89f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	ht->path_and_LSDU_size = htons(
90f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin			(ntohs(ht->path_and_LSDU_size) & 0xF000) |
91f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin			(LSDU_size & 0x0FFF));
92f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
93f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
94f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstruct hsr_ethhdr {
95f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	struct ethhdr	ethhdr;
96f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	struct hsr_tag	hsr_tag;
97f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin} __packed;
98f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
99f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
100f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin/* HSR Supervision Frame data types.
101f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin * Field names as defined in the IEC:2010 standard for HSR.
102f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin */
103f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstruct hsr_sup_tag {
104f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	__be16		path_and_HSR_Ver;
105f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	__be16		sequence_nr;
106f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	__u8		HSR_TLV_Type;
107f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	__u8		HSR_TLV_Length;
108f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin} __packed;
109f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
110f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstruct hsr_sup_payload {
111f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	unsigned char	MacAddressA[ETH_ALEN];
112f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin} __packed;
113f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
114f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline u16 get_hsr_stag_path(struct hsr_sup_tag *hst)
115f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
116f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	return get_hsr_tag_path((struct hsr_tag *) hst);
117f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
118f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
119f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline u16 get_hsr_stag_HSR_ver(struct hsr_sup_tag *hst)
120f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
121f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	return get_hsr_tag_LSDU_size((struct hsr_tag *) hst);
122f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
123f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
124f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline void set_hsr_stag_path(struct hsr_sup_tag *hst, u16 path)
125f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
126f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	set_hsr_tag_path((struct hsr_tag *) hst, path);
127f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
128f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
129f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstatic inline void set_hsr_stag_HSR_Ver(struct hsr_sup_tag *hst, u16 HSR_Ver)
130f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin{
131f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	set_hsr_tag_LSDU_size((struct hsr_tag *) hst, HSR_Ver);
132f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin}
133f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
134f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstruct hsr_ethhdr_sp {
135f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	struct ethhdr		ethhdr;
136f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	struct hsr_sup_tag	hsr_sup;
137f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin} __packed;
138f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
139f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
140c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodinenum hsr_port_type {
141c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	HSR_PT_NONE = 0,	/* Must be 0, used by framereg */
142c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	HSR_PT_SLAVE_A,
143c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	HSR_PT_SLAVE_B,
144c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	HSR_PT_INTERLINK,
145c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	HSR_PT_MASTER,
146c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	HSR_PT_PORTS,	/* This must be the last item in the enum */
147c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin};
148c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin
149c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodinstruct hsr_port {
150c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	struct list_head	port_list;
151c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	struct net_device	*dev;
152c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	struct hsr_priv		*hsr;
153c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	enum hsr_port_type	type;
154f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin};
155f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
156f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodinstruct hsr_priv {
157f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	struct rcu_head		rcu_head;
158c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodin	struct list_head	ports;
159f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin	struct list_head	node_db;	/* Known HSR nodes */
160f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	struct list_head	self_node_db;	/* MACs of slaves */
161f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	struct timer_list	announce_timer;	/* Supervision frame dispatch */
162abff7162765cd66ab109c97fd433ef1f39299120Arvid Brodin	struct timer_list	prune_timer;
163f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	int announce_count;
164f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	u16 sequence_nr;
165f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	spinlock_t seqnr_lock;			/* locking for sequence_nr */
166f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin	unsigned char		sup_multicast_addr[ETH_ALEN];
167f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin};
168f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
169f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin#define hsr_for_each_port(hsr, port) \
170f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin	list_for_each_entry_rcu((port), &(hsr)->ports, port_list)
171f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin
172c5a7591172100269e426cf630da0f2dc8138a206Arvid Brodinstruct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt);
173f421436a591d34fa5279b54a96ac07d70250cc8dArvid Brodin
174f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin/* Caller must ensure skb is a valid HSR frame */
175f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodinstatic inline u16 hsr_get_skb_sequence_nr(struct sk_buff *skb)
176f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin{
177f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin	struct hsr_ethhdr *hsr_ethhdr;
178f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin
179f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin	hsr_ethhdr = (struct hsr_ethhdr *) skb_mac_header(skb);
180f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin	return ntohs(hsr_ethhdr->hsr_tag.sequence_nr);
181f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin}
182f266a683a4804dc499efc6c2206ef68efed029d0Arvid Brodin
18370ebe4a47185db15f3c55be9611a1a971237870bArvid Brodin#endif /*  __HSR_PRIVATE_H */
184