xref: /openbmc/linux/net/hsr/hsr_main.h (revision f421436a)
1f421436aSArvid Brodin /* Copyright 2011-2013 Autronica Fire and Security AS
2f421436aSArvid Brodin  *
3f421436aSArvid Brodin  * This program is free software; you can redistribute it and/or modify it
4f421436aSArvid Brodin  * under the terms of the GNU General Public License as published by the Free
5f421436aSArvid Brodin  * Software Foundation; either version 2 of the License, or (at your option)
6f421436aSArvid Brodin  * any later version.
7f421436aSArvid Brodin  *
8f421436aSArvid Brodin  * Author(s):
9f421436aSArvid Brodin  *	2011-2013 Arvid Brodin, arvid.brodin@xdin.com
10f421436aSArvid Brodin  */
11f421436aSArvid Brodin 
12f421436aSArvid Brodin #ifndef _HSR_PRIVATE_H
13f421436aSArvid Brodin #define _HSR_PRIVATE_H
14f421436aSArvid Brodin 
15f421436aSArvid Brodin #include <linux/netdevice.h>
16f421436aSArvid Brodin #include <linux/list.h>
17f421436aSArvid Brodin 
18f421436aSArvid Brodin 
19f421436aSArvid Brodin /* Time constants as specified in the HSR specification (IEC-62439-3 2010)
20f421436aSArvid Brodin  * Table 8.
21f421436aSArvid Brodin  * All values in milliseconds.
22f421436aSArvid Brodin  */
23f421436aSArvid Brodin #define HSR_LIFE_CHECK_INTERVAL		 2000 /* ms */
24f421436aSArvid Brodin #define HSR_NODE_FORGET_TIME		60000 /* ms */
25f421436aSArvid Brodin #define HSR_ANNOUNCE_INTERVAL		  100 /* ms */
26f421436aSArvid Brodin 
27f421436aSArvid Brodin 
28f421436aSArvid Brodin /* By how much may slave1 and slave2 timestamps of latest received frame from
29f421436aSArvid Brodin  * each node differ before we notify of communication problem?
30f421436aSArvid Brodin  */
31f421436aSArvid Brodin #define MAX_SLAVE_DIFF			 3000 /* ms */
32f421436aSArvid Brodin 
33f421436aSArvid Brodin 
34f421436aSArvid Brodin /* How often shall we check for broken ring and remove node entries older than
35f421436aSArvid Brodin  * HSR_NODE_FORGET_TIME?
36f421436aSArvid Brodin  */
37f421436aSArvid Brodin #define PRUNE_PERIOD			 3000 /* ms */
38f421436aSArvid Brodin 
39f421436aSArvid Brodin 
40f421436aSArvid Brodin #define HSR_TLV_ANNOUNCE		   22
41f421436aSArvid Brodin #define HSR_TLV_LIFE_CHECK		   23
42f421436aSArvid Brodin 
43f421436aSArvid Brodin 
44f421436aSArvid Brodin /* HSR Tag.
45f421436aSArvid Brodin  * As defined in IEC-62439-3:2010, the HSR tag is really { ethertype = 0x88FB,
46f421436aSArvid Brodin  * path, LSDU_size, sequence Nr }. But we let eth_header() create { h_dest,
47f421436aSArvid Brodin  * h_source, h_proto = 0x88FB }, and add { path, LSDU_size, sequence Nr,
48f421436aSArvid Brodin  * encapsulated protocol } instead.
49f421436aSArvid Brodin  */
50f421436aSArvid Brodin #define HSR_TAGLEN	6
51f421436aSArvid Brodin 
52f421436aSArvid Brodin /* Field names below as defined in the IEC:2010 standard for HSR. */
53f421436aSArvid Brodin struct hsr_tag {
54f421436aSArvid Brodin 	__be16		path_and_LSDU_size;
55f421436aSArvid Brodin 	__be16		sequence_nr;
56f421436aSArvid Brodin 	__be16		encap_proto;
57f421436aSArvid Brodin } __packed;
58f421436aSArvid Brodin 
59f421436aSArvid Brodin 
60f421436aSArvid Brodin /* The helper functions below assumes that 'path' occupies the 4 most
61f421436aSArvid Brodin  * significant bits of the 16-bit field shared by 'path' and 'LSDU_size' (or
62f421436aSArvid Brodin  * equivalently, the 4 most significant bits of HSR tag byte 14).
63f421436aSArvid Brodin  *
64f421436aSArvid Brodin  * This is unclear in the IEC specification; its definition of MAC addresses
65f421436aSArvid Brodin  * indicates the spec is written with the least significant bit first (to the
66f421436aSArvid Brodin  * left). This, however, would mean that the LSDU field would be split in two
67f421436aSArvid Brodin  * with the path field in-between, which seems strange. I'm guessing the MAC
68f421436aSArvid Brodin  * address definition is in error.
69f421436aSArvid Brodin  */
70f421436aSArvid Brodin static inline u16 get_hsr_tag_path(struct hsr_tag *ht)
71f421436aSArvid Brodin {
72f421436aSArvid Brodin 	return ntohs(ht->path_and_LSDU_size) >> 12;
73f421436aSArvid Brodin }
74f421436aSArvid Brodin 
75f421436aSArvid Brodin static inline u16 get_hsr_tag_LSDU_size(struct hsr_tag *ht)
76f421436aSArvid Brodin {
77f421436aSArvid Brodin 	return ntohs(ht->path_and_LSDU_size) & 0x0FFF;
78f421436aSArvid Brodin }
79f421436aSArvid Brodin 
80f421436aSArvid Brodin static inline void set_hsr_tag_path(struct hsr_tag *ht, u16 path)
81f421436aSArvid Brodin {
82f421436aSArvid Brodin 	ht->path_and_LSDU_size = htons(
83f421436aSArvid Brodin 			(ntohs(ht->path_and_LSDU_size) & 0x0FFF) | (path << 12));
84f421436aSArvid Brodin }
85f421436aSArvid Brodin 
86f421436aSArvid Brodin static inline void set_hsr_tag_LSDU_size(struct hsr_tag *ht, u16 LSDU_size)
87f421436aSArvid Brodin {
88f421436aSArvid Brodin 	ht->path_and_LSDU_size = htons(
89f421436aSArvid Brodin 			(ntohs(ht->path_and_LSDU_size) & 0xF000) |
90f421436aSArvid Brodin 			(LSDU_size & 0x0FFF));
91f421436aSArvid Brodin }
92f421436aSArvid Brodin 
93f421436aSArvid Brodin struct hsr_ethhdr {
94f421436aSArvid Brodin 	struct ethhdr	ethhdr;
95f421436aSArvid Brodin 	struct hsr_tag	hsr_tag;
96f421436aSArvid Brodin } __packed;
97f421436aSArvid Brodin 
98f421436aSArvid Brodin 
99f421436aSArvid Brodin /* HSR Supervision Frame data types.
100f421436aSArvid Brodin  * Field names as defined in the IEC:2010 standard for HSR.
101f421436aSArvid Brodin  */
102f421436aSArvid Brodin struct hsr_sup_tag {
103f421436aSArvid Brodin 	__be16		path_and_HSR_Ver;
104f421436aSArvid Brodin 	__be16		sequence_nr;
105f421436aSArvid Brodin 	__u8		HSR_TLV_Type;
106f421436aSArvid Brodin 	__u8		HSR_TLV_Length;
107f421436aSArvid Brodin } __packed;
108f421436aSArvid Brodin 
109f421436aSArvid Brodin struct hsr_sup_payload {
110f421436aSArvid Brodin 	unsigned char	MacAddressA[ETH_ALEN];
111f421436aSArvid Brodin } __packed;
112f421436aSArvid Brodin 
113f421436aSArvid Brodin static inline u16 get_hsr_stag_path(struct hsr_sup_tag *hst)
114f421436aSArvid Brodin {
115f421436aSArvid Brodin 	return get_hsr_tag_path((struct hsr_tag *) hst);
116f421436aSArvid Brodin }
117f421436aSArvid Brodin 
118f421436aSArvid Brodin static inline u16 get_hsr_stag_HSR_ver(struct hsr_sup_tag *hst)
119f421436aSArvid Brodin {
120f421436aSArvid Brodin 	return get_hsr_tag_LSDU_size((struct hsr_tag *) hst);
121f421436aSArvid Brodin }
122f421436aSArvid Brodin 
123f421436aSArvid Brodin static inline void set_hsr_stag_path(struct hsr_sup_tag *hst, u16 path)
124f421436aSArvid Brodin {
125f421436aSArvid Brodin 	set_hsr_tag_path((struct hsr_tag *) hst, path);
126f421436aSArvid Brodin }
127f421436aSArvid Brodin 
128f421436aSArvid Brodin static inline void set_hsr_stag_HSR_Ver(struct hsr_sup_tag *hst, u16 HSR_Ver)
129f421436aSArvid Brodin {
130f421436aSArvid Brodin 	set_hsr_tag_LSDU_size((struct hsr_tag *) hst, HSR_Ver);
131f421436aSArvid Brodin }
132f421436aSArvid Brodin 
133f421436aSArvid Brodin struct hsr_ethhdr_sp {
134f421436aSArvid Brodin 	struct ethhdr		ethhdr;
135f421436aSArvid Brodin 	struct hsr_sup_tag	hsr_sup;
136f421436aSArvid Brodin } __packed;
137f421436aSArvid Brodin 
138f421436aSArvid Brodin 
139f421436aSArvid Brodin enum hsr_dev_idx {
140f421436aSArvid Brodin 	HSR_DEV_NONE = -1,
141f421436aSArvid Brodin 	HSR_DEV_SLAVE_A = 0,
142f421436aSArvid Brodin 	HSR_DEV_SLAVE_B,
143f421436aSArvid Brodin 	HSR_DEV_MASTER,
144f421436aSArvid Brodin };
145f421436aSArvid Brodin #define HSR_MAX_SLAVE	(HSR_DEV_SLAVE_B + 1)
146f421436aSArvid Brodin #define HSR_MAX_DEV	(HSR_DEV_MASTER + 1)
147f421436aSArvid Brodin 
148f421436aSArvid Brodin struct hsr_priv {
149f421436aSArvid Brodin 	struct list_head	hsr_list;	/* List of hsr devices */
150f421436aSArvid Brodin 	struct rcu_head		rcu_head;
151f421436aSArvid Brodin 	struct net_device	*dev;
152f421436aSArvid Brodin 	struct net_device	*slave[HSR_MAX_SLAVE];
153f421436aSArvid Brodin 	struct list_head	node_db;	/* Other HSR nodes */
154f421436aSArvid Brodin 	struct list_head	self_node_db;	/* MACs of slaves */
155f421436aSArvid Brodin 	struct timer_list	announce_timer;	/* Supervision frame dispatch */
156f421436aSArvid Brodin 	int announce_count;
157f421436aSArvid Brodin 	u16 sequence_nr;
158f421436aSArvid Brodin 	spinlock_t seqnr_lock;			/* locking for sequence_nr */
159f421436aSArvid Brodin 	unsigned char		sup_multicast_addr[ETH_ALEN];
160f421436aSArvid Brodin };
161f421436aSArvid Brodin 
162f421436aSArvid Brodin void register_hsr_master(struct hsr_priv *hsr_priv);
163f421436aSArvid Brodin void unregister_hsr_master(struct hsr_priv *hsr_priv);
164f421436aSArvid Brodin bool is_hsr_slave(struct net_device *dev);
165f421436aSArvid Brodin 
166f421436aSArvid Brodin #endif /*  _HSR_PRIVATE_H */
167