aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/team/team.c
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2012-06-19 01:54:10 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-19 18:00:23 -0400
commit85d59a87248de90e3266e10dce99477b60f524c0 (patch)
tree1642b59a05a69acdf8e9f754bce19864f3f66cbe /drivers/net/team/team.c
parent0d572e45f7f8ae3a27c82c5f0e352abf1dcb67f4 (diff)
team: push array_index and port into separate structure
Introduce struct team_option_inst_info and push option instance info there. It can be then easily passed to gsetter context and used for feature async option changes. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/team/team.c')
-rw-r--r--drivers/net/team/team.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 7ec53f81c1c4..cff8e253df72 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -89,8 +89,7 @@ static void team_refresh_port_linkup(struct team_port *port)
89struct team_option_inst { /* One for each option instance */ 89struct team_option_inst { /* One for each option instance */
90 struct list_head list; 90 struct list_head list;
91 struct team_option *option; 91 struct team_option *option;
92 struct team_port *port; /* != NULL if per-port */ 92 struct team_option_inst_info info;
93 u32 array_index;
94 bool changed; 93 bool changed;
95 bool removed; 94 bool removed;
96}; 95};
@@ -130,6 +129,7 @@ static int __team_option_inst_add(struct team *team, struct team_option *option,
130 struct team_option_inst *opt_inst; 129 struct team_option_inst *opt_inst;
131 unsigned int array_size; 130 unsigned int array_size;
132 unsigned int i; 131 unsigned int i;
132 int err;
133 133
134 array_size = option->array_size; 134 array_size = option->array_size;
135 if (!array_size) 135 if (!array_size)
@@ -140,11 +140,17 @@ static int __team_option_inst_add(struct team *team, struct team_option *option,
140 if (!opt_inst) 140 if (!opt_inst)
141 return -ENOMEM; 141 return -ENOMEM;
142 opt_inst->option = option; 142 opt_inst->option = option;
143 opt_inst->port = port; 143 opt_inst->info.port = port;
144 opt_inst->array_index = i; 144 opt_inst->info.array_index = i;
145 opt_inst->changed = true; 145 opt_inst->changed = true;
146 opt_inst->removed = false; 146 opt_inst->removed = false;
147 list_add_tail(&opt_inst->list, &team->option_inst_list); 147 list_add_tail(&opt_inst->list, &team->option_inst_list);
148 if (option->init) {
149 err = option->init(team, &opt_inst->info);
150 if (err)
151 return err;
152 }
153
148 } 154 }
149 return 0; 155 return 0;
150} 156}
@@ -193,7 +199,7 @@ static void __team_option_inst_del_port(struct team *team,
193 199
194 list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) { 200 list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) {
195 if (opt_inst->option->per_port && 201 if (opt_inst->option->per_port &&
196 opt_inst->port == port) 202 opt_inst->info.port == port)
197 __team_option_inst_del(opt_inst); 203 __team_option_inst_del(opt_inst);
198 } 204 }
199} 205}
@@ -224,7 +230,7 @@ static void __team_option_inst_mark_removed_port(struct team *team,
224 struct team_option_inst *opt_inst; 230 struct team_option_inst *opt_inst;
225 231
226 list_for_each_entry(opt_inst, &team->option_inst_list, list) { 232 list_for_each_entry(opt_inst, &team->option_inst_list, list) {
227 if (opt_inst->port == port) { 233 if (opt_inst->info.port == port) {
228 opt_inst->changed = true; 234 opt_inst->changed = true;
229 opt_inst->removed = true; 235 opt_inst->removed = true;
230 } 236 }
@@ -958,39 +964,47 @@ static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx)
958static int team_port_en_option_get(struct team *team, 964static int team_port_en_option_get(struct team *team,
959 struct team_gsetter_ctx *ctx) 965 struct team_gsetter_ctx *ctx)
960{ 966{
961 ctx->data.bool_val = team_port_enabled(ctx->port); 967 struct team_port *port = ctx->info->port;
968
969 ctx->data.bool_val = team_port_enabled(port);
962 return 0; 970 return 0;
963} 971}
964 972
965static int team_port_en_option_set(struct team *team, 973static int team_port_en_option_set(struct team *team,
966 struct team_gsetter_ctx *ctx) 974 struct team_gsetter_ctx *ctx)
967{ 975{
976 struct team_port *port = ctx->info->port;
977
968 if (ctx->data.bool_val) 978 if (ctx->data.bool_val)
969 team_port_enable(team, ctx->port); 979 team_port_enable(team, port);
970 else 980 else
971 team_port_disable(team, ctx->port); 981 team_port_disable(team, port);
972 return 0; 982 return 0;
973} 983}
974 984
975static int team_user_linkup_option_get(struct team *team, 985static int team_user_linkup_option_get(struct team *team,
976 struct team_gsetter_ctx *ctx) 986 struct team_gsetter_ctx *ctx)
977{ 987{
978 ctx->data.bool_val = ctx->port->user.linkup; 988 struct team_port *port = ctx->info->port;
989
990 ctx->data.bool_val = port->user.linkup;
979 return 0; 991 return 0;
980} 992}
981 993
982static int team_user_linkup_option_set(struct team *team, 994static int team_user_linkup_option_set(struct team *team,
983 struct team_gsetter_ctx *ctx) 995 struct team_gsetter_ctx *ctx)
984{ 996{
985 ctx->port->user.linkup = ctx->data.bool_val; 997 struct team_port *port = ctx->info->port;
986 team_refresh_port_linkup(ctx->port); 998
999 port->user.linkup = ctx->data.bool_val;
1000 team_refresh_port_linkup(port);
987 return 0; 1001 return 0;
988} 1002}
989 1003
990static int team_user_linkup_en_option_get(struct team *team, 1004static int team_user_linkup_en_option_get(struct team *team,
991 struct team_gsetter_ctx *ctx) 1005 struct team_gsetter_ctx *ctx)
992{ 1006{
993 struct team_port *port = ctx->port; 1007 struct team_port *port = ctx->info->port;
994 1008
995 ctx->data.bool_val = port->user.linkup_enabled; 1009 ctx->data.bool_val = port->user.linkup_enabled;
996 return 0; 1010 return 0;
@@ -999,10 +1013,10 @@ static int team_user_linkup_en_option_get(struct team *team,
999static int team_user_linkup_en_option_set(struct team *team, 1013static int team_user_linkup_en_option_set(struct team *team,
1000 struct team_gsetter_ctx *ctx) 1014 struct team_gsetter_ctx *ctx)
1001{ 1015{
1002 struct team_port *port = ctx->port; 1016 struct team_port *port = ctx->info->port;
1003 1017
1004 port->user.linkup_enabled = ctx->data.bool_val; 1018 port->user.linkup_enabled = ctx->data.bool_val;
1005 team_refresh_port_linkup(ctx->port); 1019 team_refresh_port_linkup(port);
1006 return 0; 1020 return 0;
1007} 1021}
1008 1022
@@ -1557,6 +1571,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
1557 list_for_each_entry(opt_inst, &team->option_inst_list, list) { 1571 list_for_each_entry(opt_inst, &team->option_inst_list, list) {
1558 struct nlattr *option_item; 1572 struct nlattr *option_item;
1559 struct team_option *option = opt_inst->option; 1573 struct team_option *option = opt_inst->option;
1574 struct team_option_inst_info *opt_inst_info;
1560 struct team_gsetter_ctx ctx; 1575 struct team_gsetter_ctx ctx;
1561 1576
1562 /* Include only changed options if fill all mode is not on */ 1577 /* Include only changed options if fill all mode is not on */
@@ -1575,16 +1590,18 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
1575 if (opt_inst->removed && 1590 if (opt_inst->removed &&
1576 nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED)) 1591 nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED))
1577 goto nla_put_failure; 1592 goto nla_put_failure;
1578 if (opt_inst->port && 1593
1594 opt_inst_info = &opt_inst->info;
1595 if (opt_inst_info->port &&
1579 nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX, 1596 nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX,
1580 opt_inst->port->dev->ifindex)) 1597 opt_inst_info->port->dev->ifindex))
1581 goto nla_put_failure; 1598 goto nla_put_failure;
1582 ctx.port = opt_inst->port;
1583 if (opt_inst->option->array_size && 1599 if (opt_inst->option->array_size &&
1584 nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX, 1600 nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX,
1585 opt_inst->array_index)) 1601 opt_inst_info->array_index))
1586 goto nla_put_failure; 1602 goto nla_put_failure;
1587 ctx.array_index = opt_inst->array_index; 1603 ctx.info = opt_inst_info;
1604
1588 switch (option->type) { 1605 switch (option->type) {
1589 case TEAM_OPTION_TYPE_U32: 1606 case TEAM_OPTION_TYPE_U32:
1590 if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32)) 1607 if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32))
@@ -1746,19 +1763,20 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
1746 list_for_each_entry(opt_inst, &team->option_inst_list, list) { 1763 list_for_each_entry(opt_inst, &team->option_inst_list, list) {
1747 struct team_option *option = opt_inst->option; 1764 struct team_option *option = opt_inst->option;
1748 struct team_gsetter_ctx ctx; 1765 struct team_gsetter_ctx ctx;
1766 struct team_option_inst_info *opt_inst_info;
1749 int tmp_ifindex; 1767 int tmp_ifindex;
1750 1768
1751 tmp_ifindex = opt_inst->port ? 1769 opt_inst_info = &opt_inst->info;
1752 opt_inst->port->dev->ifindex : 0; 1770 tmp_ifindex = opt_inst_info->port ?
1771 opt_inst_info->port->dev->ifindex : 0;
1753 if (option->type != opt_type || 1772 if (option->type != opt_type ||
1754 strcmp(option->name, opt_name) || 1773 strcmp(option->name, opt_name) ||
1755 tmp_ifindex != opt_port_ifindex || 1774 tmp_ifindex != opt_port_ifindex ||
1756 (option->array_size && !opt_is_array) || 1775 (option->array_size && !opt_is_array) ||
1757 opt_inst->array_index != opt_array_index) 1776 opt_inst_info->array_index != opt_array_index)
1758 continue; 1777 continue;
1759 opt_found = true; 1778 opt_found = true;
1760 ctx.port = opt_inst->port; 1779 ctx.info = opt_inst_info;
1761 ctx.array_index = opt_inst->array_index;
1762 switch (opt_type) { 1780 switch (opt_type) {
1763 case TEAM_OPTION_TYPE_U32: 1781 case TEAM_OPTION_TYPE_U32:
1764 ctx.data.u32_val = nla_get_u32(attr_data); 1782 ctx.data.u32_val = nla_get_u32(attr_data);