aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2012-04-10 01:15:44 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-11 10:03:52 -0400
commit71472ec12c61dd305ab4d11822af7ecc4f9717f9 (patch)
tree4f0470a410a76eb59530100dd757be6753fda55f
parent14f066bab19946545130a7379f420af860a02ae8 (diff)
team: add user_linkup and user_linkup_enabled per-port option
Allows userspace to setup linkup for ports. Default is to take linkup directly from ethtool state. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/team/team.c72
-rw-r--r--include/linux/if_team.h26
2 files changed, 81 insertions, 17 deletions
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 2645fae26d6f..e639abecd14f 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -76,6 +76,11 @@ int team_port_set_team_mac(struct team_port *port)
76} 76}
77EXPORT_SYMBOL(team_port_set_team_mac); 77EXPORT_SYMBOL(team_port_set_team_mac);
78 78
79static void team_refresh_port_linkup(struct team_port *port)
80{
81 port->linkup = port->user.linkup_enabled ? port->user.linkup :
82 port->state.linkup;
83}
79 84
80/******************* 85/*******************
81 * Options handling 86 * Options handling
@@ -880,6 +885,40 @@ static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx)
880 return team_change_mode(team, ctx->data.str_val); 885 return team_change_mode(team, ctx->data.str_val);
881} 886}
882 887
888static int team_user_linkup_option_get(struct team *team,
889 struct team_gsetter_ctx *ctx)
890{
891 ctx->data.bool_val = ctx->port->user.linkup;
892 return 0;
893}
894
895static int team_user_linkup_option_set(struct team *team,
896 struct team_gsetter_ctx *ctx)
897{
898 ctx->port->user.linkup = ctx->data.bool_val;
899 team_refresh_port_linkup(ctx->port);
900 return 0;
901}
902
903static int team_user_linkup_en_option_get(struct team *team,
904 struct team_gsetter_ctx *ctx)
905{
906 struct team_port *port = ctx->port;
907
908 ctx->data.bool_val = port->user.linkup_enabled;
909 return 0;
910}
911
912static int team_user_linkup_en_option_set(struct team *team,
913 struct team_gsetter_ctx *ctx)
914{
915 struct team_port *port = ctx->port;
916
917 port->user.linkup_enabled = ctx->data.bool_val;
918 team_refresh_port_linkup(ctx->port);
919 return 0;
920}
921
883static const struct team_option team_options[] = { 922static const struct team_option team_options[] = {
884 { 923 {
885 .name = "mode", 924 .name = "mode",
@@ -887,6 +926,20 @@ static const struct team_option team_options[] = {
887 .getter = team_mode_option_get, 926 .getter = team_mode_option_get,
888 .setter = team_mode_option_set, 927 .setter = team_mode_option_set,
889 }, 928 },
929 {
930 .name = "user_linkup",
931 .type = TEAM_OPTION_TYPE_BOOL,
932 .per_port = true,
933 .getter = team_user_linkup_option_get,
934 .setter = team_user_linkup_option_set,
935 },
936 {
937 .name = "user_linkup_enabled",
938 .type = TEAM_OPTION_TYPE_BOOL,
939 .per_port = true,
940 .getter = team_user_linkup_en_option_get,
941 .setter = team_user_linkup_en_option_set,
942 },
890}; 943};
891 944
892static int team_init(struct net_device *dev) 945static int team_init(struct net_device *dev)
@@ -1670,10 +1723,10 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb,
1670 } 1723 }
1671 if ((port->removed && 1724 if ((port->removed &&
1672 nla_put_flag(skb, TEAM_ATTR_PORT_REMOVED)) || 1725 nla_put_flag(skb, TEAM_ATTR_PORT_REMOVED)) ||
1673 (port->linkup && 1726 (port->state.linkup &&
1674 nla_put_flag(skb, TEAM_ATTR_PORT_LINKUP)) || 1727 nla_put_flag(skb, TEAM_ATTR_PORT_LINKUP)) ||
1675 nla_put_u32(skb, TEAM_ATTR_PORT_SPEED, port->speed) || 1728 nla_put_u32(skb, TEAM_ATTR_PORT_SPEED, port->state.speed) ||
1676 nla_put_u8(skb, TEAM_ATTR_PORT_DUPLEX, port->duplex)) 1729 nla_put_u8(skb, TEAM_ATTR_PORT_DUPLEX, port->state.duplex))
1677 goto nla_put_failure; 1730 goto nla_put_failure;
1678 nla_nest_end(skb, port_item); 1731 nla_nest_end(skb, port_item);
1679 } 1732 }
@@ -1833,23 +1886,24 @@ static void __team_port_change_check(struct team_port *port, bool linkup)
1833{ 1886{
1834 int err; 1887 int err;
1835 1888
1836 if (!port->removed && port->linkup == linkup) 1889 if (!port->removed && port->state.linkup == linkup)
1837 return; 1890 return;
1838 1891
1839 port->changed = true; 1892 port->changed = true;
1840 port->linkup = linkup; 1893 port->state.linkup = linkup;
1894 team_refresh_port_linkup(port);
1841 if (linkup) { 1895 if (linkup) {
1842 struct ethtool_cmd ecmd; 1896 struct ethtool_cmd ecmd;
1843 1897
1844 err = __ethtool_get_settings(port->dev, &ecmd); 1898 err = __ethtool_get_settings(port->dev, &ecmd);
1845 if (!err) { 1899 if (!err) {
1846 port->speed = ethtool_cmd_speed(&ecmd); 1900 port->state.speed = ethtool_cmd_speed(&ecmd);
1847 port->duplex = ecmd.duplex; 1901 port->state.duplex = ecmd.duplex;
1848 goto send_event; 1902 goto send_event;
1849 } 1903 }
1850 } 1904 }
1851 port->speed = 0; 1905 port->state.speed = 0;
1852 port->duplex = 0; 1906 port->state.duplex = 0;
1853 1907
1854send_event: 1908send_event:
1855 err = team_nl_send_event_port_list_get(port->team); 1909 err = team_nl_send_event_port_list_get(port->team);
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 78c84fd9a170..5fd5ab171165 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -33,6 +33,24 @@ struct team_port {
33 struct team *team; 33 struct team *team;
34 int index; 34 int index;
35 35
36 bool linkup; /* either state.linkup or user.linkup */
37
38 struct {
39 bool linkup;
40 u32 speed;
41 u8 duplex;
42 } state;
43
44 /* Values set by userspace */
45 struct {
46 bool linkup;
47 bool linkup_enabled;
48 } user;
49
50 /* Custom gennetlink interface related flags */
51 bool changed;
52 bool removed;
53
36 /* 54 /*
37 * A place for storing original values of the device before it 55 * A place for storing original values of the device before it
38 * become a port. 56 * become a port.
@@ -42,14 +60,6 @@ struct team_port {
42 unsigned int mtu; 60 unsigned int mtu;
43 } orig; 61 } orig;
44 62
45 bool linkup;
46 u32 speed;
47 u8 duplex;
48
49 /* Custom gennetlink interface related flags */
50 bool changed;
51 bool removed;
52
53 struct rcu_head rcu; 63 struct rcu_head rcu;
54}; 64};
55 65