xref: /openbmc/linux/drivers/net/team/team_mode_broadcast.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1*2874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
25fc88991SJiri Pirko /*
35fc88991SJiri Pirko  * drivers/net/team/team_mode_broadcast.c - Broadcast mode for team
45fc88991SJiri Pirko  * Copyright (c) 2012 Jiri Pirko <jpirko@redhat.com>
55fc88991SJiri Pirko  */
65fc88991SJiri Pirko 
75fc88991SJiri Pirko #include <linux/kernel.h>
85fc88991SJiri Pirko #include <linux/types.h>
95fc88991SJiri Pirko #include <linux/module.h>
105fc88991SJiri Pirko #include <linux/init.h>
115fc88991SJiri Pirko #include <linux/netdevice.h>
125fc88991SJiri Pirko #include <linux/if_team.h>
135fc88991SJiri Pirko 
bc_transmit(struct team * team,struct sk_buff * skb)145fc88991SJiri Pirko static bool bc_transmit(struct team *team, struct sk_buff *skb)
155fc88991SJiri Pirko {
165fc88991SJiri Pirko 	struct team_port *cur;
175fc88991SJiri Pirko 	struct team_port *last = NULL;
185fc88991SJiri Pirko 	struct sk_buff *skb2;
195fc88991SJiri Pirko 	bool ret;
205fc88991SJiri Pirko 	bool sum_ret = false;
215fc88991SJiri Pirko 
225fc88991SJiri Pirko 	list_for_each_entry_rcu(cur, &team->port_list, list) {
235fc88991SJiri Pirko 		if (team_port_txable(cur)) {
245fc88991SJiri Pirko 			if (last) {
255fc88991SJiri Pirko 				skb2 = skb_clone(skb, GFP_ATOMIC);
265fc88991SJiri Pirko 				if (skb2) {
27403f43c9SJiri Pirko 					ret = !team_dev_queue_xmit(team, last,
28bd2d0837SJiri Pirko 								   skb2);
295fc88991SJiri Pirko 					if (!sum_ret)
305fc88991SJiri Pirko 						sum_ret = ret;
315fc88991SJiri Pirko 				}
325fc88991SJiri Pirko 			}
335fc88991SJiri Pirko 			last = cur;
345fc88991SJiri Pirko 		}
355fc88991SJiri Pirko 	}
365fc88991SJiri Pirko 	if (last) {
37403f43c9SJiri Pirko 		ret = !team_dev_queue_xmit(team, last, skb);
385fc88991SJiri Pirko 		if (!sum_ret)
395fc88991SJiri Pirko 			sum_ret = ret;
405fc88991SJiri Pirko 	}
415fc88991SJiri Pirko 	return sum_ret;
425fc88991SJiri Pirko }
435fc88991SJiri Pirko 
445fc88991SJiri Pirko static const struct team_mode_ops bc_mode_ops = {
455fc88991SJiri Pirko 	.transmit		= bc_transmit,
46acbba0d0SJiri Pirko 	.port_enter		= team_modeop_port_enter,
47acbba0d0SJiri Pirko 	.port_change_dev_addr	= team_modeop_port_change_dev_addr,
485fc88991SJiri Pirko };
495fc88991SJiri Pirko 
505fc88991SJiri Pirko static const struct team_mode bc_mode = {
515fc88991SJiri Pirko 	.kind		= "broadcast",
525fc88991SJiri Pirko 	.owner		= THIS_MODULE,
535fc88991SJiri Pirko 	.ops		= &bc_mode_ops,
548fd72856SJiri Pirko 	.lag_tx_type	= NETDEV_LAG_TX_TYPE_BROADCAST,
555fc88991SJiri Pirko };
565fc88991SJiri Pirko 
bc_init_module(void)575fc88991SJiri Pirko static int __init bc_init_module(void)
585fc88991SJiri Pirko {
595fc88991SJiri Pirko 	return team_mode_register(&bc_mode);
605fc88991SJiri Pirko }
615fc88991SJiri Pirko 
bc_cleanup_module(void)625fc88991SJiri Pirko static void __exit bc_cleanup_module(void)
635fc88991SJiri Pirko {
645fc88991SJiri Pirko 	team_mode_unregister(&bc_mode);
655fc88991SJiri Pirko }
665fc88991SJiri Pirko 
675fc88991SJiri Pirko module_init(bc_init_module);
685fc88991SJiri Pirko module_exit(bc_cleanup_module);
695fc88991SJiri Pirko 
705fc88991SJiri Pirko MODULE_LICENSE("GPL v2");
715fc88991SJiri Pirko MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>");
725fc88991SJiri Pirko MODULE_DESCRIPTION("Broadcast mode for team");
733a5f8997SZhang Shengju MODULE_ALIAS_TEAM_MODE("broadcast");
74