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