xref: /openbmc/linux/drivers/net/team/team_mode_roundrobin.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1*2874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
23d249d4cSJiri Pirko /*
30d572e45SJiri Pirko  * drivers/net/team/team_mode_roundrobin.c - Round-robin mode for team
43d249d4cSJiri Pirko  * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com>
53d249d4cSJiri Pirko  */
63d249d4cSJiri Pirko 
73d249d4cSJiri Pirko #include <linux/kernel.h>
83d249d4cSJiri Pirko #include <linux/types.h>
93d249d4cSJiri Pirko #include <linux/module.h>
103d249d4cSJiri Pirko #include <linux/init.h>
113d249d4cSJiri Pirko #include <linux/netdevice.h>
123d249d4cSJiri Pirko #include <linux/if_team.h>
133d249d4cSJiri Pirko 
143d249d4cSJiri Pirko struct rr_priv {
153d249d4cSJiri Pirko 	unsigned int sent_packets;
163d249d4cSJiri Pirko };
173d249d4cSJiri Pirko 
rr_priv(struct team * team)183d249d4cSJiri Pirko static struct rr_priv *rr_priv(struct team *team)
193d249d4cSJiri Pirko {
203d249d4cSJiri Pirko 	return (struct rr_priv *) &team->mode_priv;
213d249d4cSJiri Pirko }
223d249d4cSJiri Pirko 
rr_transmit(struct team * team,struct sk_buff * skb)233d249d4cSJiri Pirko static bool rr_transmit(struct team *team, struct sk_buff *skb)
243d249d4cSJiri Pirko {
253d249d4cSJiri Pirko 	struct team_port *port;
263d249d4cSJiri Pirko 	int port_index;
273d249d4cSJiri Pirko 
28735d381fSJiri Pirko 	port_index = team_num_to_port_index(team,
29735d381fSJiri Pirko 					    rr_priv(team)->sent_packets++);
303d249d4cSJiri Pirko 	port = team_get_port_by_index_rcu(team, port_index);
3176c455deSJiri Pirko 	if (unlikely(!port))
3276c455deSJiri Pirko 		goto drop;
33753f9939SJiri Pirko 	port = team_get_first_port_txable_rcu(team, port);
343d249d4cSJiri Pirko 	if (unlikely(!port))
353d249d4cSJiri Pirko 		goto drop;
36bd2d0837SJiri Pirko 	if (team_dev_queue_xmit(team, port, skb))
373d249d4cSJiri Pirko 		return false;
383d249d4cSJiri Pirko 	return true;
393d249d4cSJiri Pirko 
403d249d4cSJiri Pirko drop:
413d249d4cSJiri Pirko 	dev_kfree_skb_any(skb);
423d249d4cSJiri Pirko 	return false;
433d249d4cSJiri Pirko }
443d249d4cSJiri Pirko 
453d249d4cSJiri Pirko static const struct team_mode_ops rr_mode_ops = {
463d249d4cSJiri Pirko 	.transmit		= rr_transmit,
47acbba0d0SJiri Pirko 	.port_enter		= team_modeop_port_enter,
48acbba0d0SJiri Pirko 	.port_change_dev_addr	= team_modeop_port_change_dev_addr,
493d249d4cSJiri Pirko };
503d249d4cSJiri Pirko 
510402788aSJiri Pirko static const struct team_mode rr_mode = {
523d249d4cSJiri Pirko 	.kind		= "roundrobin",
533d249d4cSJiri Pirko 	.owner		= THIS_MODULE,
543d249d4cSJiri Pirko 	.priv_size	= sizeof(struct rr_priv),
553d249d4cSJiri Pirko 	.ops		= &rr_mode_ops,
568fd72856SJiri Pirko 	.lag_tx_type	= NETDEV_LAG_TX_TYPE_ROUNDROBIN,
573d249d4cSJiri Pirko };
583d249d4cSJiri Pirko 
rr_init_module(void)593d249d4cSJiri Pirko static int __init rr_init_module(void)
603d249d4cSJiri Pirko {
613d249d4cSJiri Pirko 	return team_mode_register(&rr_mode);
623d249d4cSJiri Pirko }
633d249d4cSJiri Pirko 
rr_cleanup_module(void)643d249d4cSJiri Pirko static void __exit rr_cleanup_module(void)
653d249d4cSJiri Pirko {
663d249d4cSJiri Pirko 	team_mode_unregister(&rr_mode);
673d249d4cSJiri Pirko }
683d249d4cSJiri Pirko 
693d249d4cSJiri Pirko module_init(rr_init_module);
703d249d4cSJiri Pirko module_exit(rr_cleanup_module);
713d249d4cSJiri Pirko 
723d249d4cSJiri Pirko MODULE_LICENSE("GPL v2");
733d249d4cSJiri Pirko MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>");
743d249d4cSJiri Pirko MODULE_DESCRIPTION("Round-robin mode for team");
753a5f8997SZhang Shengju MODULE_ALIAS_TEAM_MODE("roundrobin");
76