Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[linux-drm-fsl-dcu.git] / net / tipc / bcast.c
index 90a051912c03f1c0e90868f9a07e1800d8b78e96..a008c6689305bd7b037a5226f1107a878c943060 100644 (file)
@@ -119,7 +119,7 @@ static struct bclink *bclink = NULL;
 static struct link *bcl = NULL;
 static DEFINE_SPINLOCK(bc_lock);
 
-const char tipc_bclink_name[] = "multicast-link";
+const char tipc_bclink_name[] = "broadcast-link";
 
 
 static u32 buf_seqno(struct sk_buff *buf)
@@ -275,7 +275,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
        buf = buf_acquire(INT_H_SIZE);
        if (buf) {
                msg = buf_msg(buf);
-               msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
+               tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
                         INT_H_SIZE, n_ptr->addr);
                msg_set_mc_netid(msg, tipc_net_id);
                msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
@@ -822,3 +822,113 @@ void tipc_bclink_stop(void)
        spin_unlock_bh(&bc_lock);
 }
 
+
+/**
+ * tipc_nmap_add - add a node to a node map
+ */
+
+void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
+{
+       int n = tipc_node(node);
+       int w = n / WSIZE;
+       u32 mask = (1 << (n % WSIZE));
+
+       if ((nm_ptr->map[w] & mask) == 0) {
+               nm_ptr->count++;
+               nm_ptr->map[w] |= mask;
+       }
+}
+
+/**
+ * tipc_nmap_remove - remove a node from a node map
+ */
+
+void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
+{
+       int n = tipc_node(node);
+       int w = n / WSIZE;
+       u32 mask = (1 << (n % WSIZE));
+
+       if ((nm_ptr->map[w] & mask) != 0) {
+               nm_ptr->map[w] &= ~mask;
+               nm_ptr->count--;
+       }
+}
+
+/**
+ * tipc_nmap_diff - find differences between node maps
+ * @nm_a: input node map A
+ * @nm_b: input node map B
+ * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
+ */
+
+void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
+                                 struct tipc_node_map *nm_diff)
+{
+       int stop = ARRAY_SIZE(nm_a->map);
+       int w;
+       int b;
+       u32 map;
+
+       memset(nm_diff, 0, sizeof(*nm_diff));
+       for (w = 0; w < stop; w++) {
+               map = nm_a->map[w] ^ (nm_a->map[w] & nm_b->map[w]);
+               nm_diff->map[w] = map;
+               if (map != 0) {
+                       for (b = 0 ; b < WSIZE; b++) {
+                               if (map & (1 << b))
+                                       nm_diff->count++;
+                       }
+               }
+       }
+}
+
+/**
+ * tipc_port_list_add - add a port to a port list, ensuring no duplicates
+ */
+
+void tipc_port_list_add(struct port_list *pl_ptr, u32 port)
+{
+       struct port_list *item = pl_ptr;
+       int i;
+       int item_sz = PLSIZE;
+       int cnt = pl_ptr->count;
+
+       for (; ; cnt -= item_sz, item = item->next) {
+               if (cnt < PLSIZE)
+                       item_sz = cnt;
+               for (i = 0; i < item_sz; i++)
+                       if (item->ports[i] == port)
+                               return;
+               if (i < PLSIZE) {
+                       item->ports[i] = port;
+                       pl_ptr->count++;
+                       return;
+               }
+               if (!item->next) {
+                       item->next = kmalloc(sizeof(*item), GFP_ATOMIC);
+                       if (!item->next) {
+                               warn("Incomplete multicast delivery, no memory\n");
+                               return;
+                       }
+                       item->next->next = NULL;
+               }
+       }
+}
+
+/**
+ * tipc_port_list_free - free dynamically created entries in port_list chain
+ *
+ */
+
+void tipc_port_list_free(struct port_list *pl_ptr)
+{
+       struct port_list *item;
+       struct port_list *next;
+
+       for (item = pl_ptr->next; item; item = next) {
+               next = item->next;
+               kfree(item);
+       }
+}
+