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