Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[firefly-linux-kernel-4.4.55.git] / net / hsr / hsr_main.h
index 56fe060c0ab1872330adda30daace83c429313ff..5a9c69962ded0284c62f6b0ab7767ceabecc6aa8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright 2011-2013 Autronica Fire and Security AS
+/* Copyright 2011-2014 Autronica Fire and Security AS
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -6,11 +6,11 @@
  * any later version.
  *
  * Author(s):
- *     2011-2013 Arvid Brodin, arvid.brodin@xdin.com
+ *     2011-2014 Arvid Brodin, arvid.brodin@alten.se
  */
 
-#ifndef _HSR_PRIVATE_H
-#define _HSR_PRIVATE_H
+#ifndef __HSR_PRIVATE_H
+#define __HSR_PRIVATE_H
 
 #include <linux/netdevice.h>
 #include <linux/list.h>
@@ -29,6 +29,7 @@
  * each node differ before we notify of communication problem?
  */
 #define MAX_SLAVE_DIFF                  3000 /* ms */
+#define HSR_SEQNR_START                        (USHRT_MAX - 1024)
 
 
 /* How often shall we check for broken ring and remove node entries older than
  * path, LSDU_size, sequence Nr }. But we let eth_header() create { h_dest,
  * h_source, h_proto = 0x88FB }, and add { path, LSDU_size, sequence Nr,
  * encapsulated protocol } instead.
+ *
+ * Field names as defined in the IEC:2010 standard for HSR.
  */
-#define HSR_TAGLEN     6
-
-/* Field names below as defined in the IEC:2010 standard for HSR. */
 struct hsr_tag {
        __be16          path_and_LSDU_size;
        __be16          sequence_nr;
        __be16          encap_proto;
 } __packed;
 
+#define HSR_HLEN       6
 
 /* The helper functions below assumes that 'path' occupies the 4 most
  * significant bits of the 16-bit field shared by 'path' and 'LSDU_size' (or
@@ -136,31 +137,47 @@ struct hsr_ethhdr_sp {
 } __packed;
 
 
-enum hsr_dev_idx {
-       HSR_DEV_NONE = -1,
-       HSR_DEV_SLAVE_A = 0,
-       HSR_DEV_SLAVE_B,
-       HSR_DEV_MASTER,
+enum hsr_port_type {
+       HSR_PT_NONE = 0,        /* Must be 0, used by framereg */
+       HSR_PT_SLAVE_A,
+       HSR_PT_SLAVE_B,
+       HSR_PT_INTERLINK,
+       HSR_PT_MASTER,
+       HSR_PT_PORTS,   /* This must be the last item in the enum */
+};
+
+struct hsr_port {
+       struct list_head        port_list;
+       struct net_device       *dev;
+       struct hsr_priv         *hsr;
+       enum hsr_port_type      type;
 };
-#define HSR_MAX_SLAVE  (HSR_DEV_SLAVE_B + 1)
-#define HSR_MAX_DEV    (HSR_DEV_MASTER + 1)
 
 struct hsr_priv {
-       struct list_head        hsr_list;       /* List of hsr devices */
        struct rcu_head         rcu_head;
-       struct net_device       *dev;
-       struct net_device       *slave[HSR_MAX_SLAVE];
-       struct list_head        node_db;        /* Other HSR nodes */
+       struct list_head        ports;
+       struct list_head        node_db;        /* Known HSR nodes */
        struct list_head        self_node_db;   /* MACs of slaves */
        struct timer_list       announce_timer; /* Supervision frame dispatch */
+       struct timer_list       prune_timer;
        int announce_count;
        u16 sequence_nr;
        spinlock_t seqnr_lock;                  /* locking for sequence_nr */
        unsigned char           sup_multicast_addr[ETH_ALEN];
 };
 
-void register_hsr_master(struct hsr_priv *hsr_priv);
-void unregister_hsr_master(struct hsr_priv *hsr_priv);
-bool is_hsr_slave(struct net_device *dev);
+#define hsr_for_each_port(hsr, port) \
+       list_for_each_entry_rcu((port), &(hsr)->ports, port_list)
+
+struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt);
+
+/* Caller must ensure skb is a valid HSR frame */
+static inline u16 hsr_get_skb_sequence_nr(struct sk_buff *skb)
+{
+       struct hsr_ethhdr *hsr_ethhdr;
+
+       hsr_ethhdr = (struct hsr_ethhdr *) skb_mac_header(skb);
+       return ntohs(hsr_ethhdr->hsr_tag.sequence_nr);
+}
 
-#endif /*  _HSR_PRIVATE_H */
+#endif /*  __HSR_PRIVATE_H */