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