diff options
author | Jiri Pirko <jpirko@redhat.com> | 2012-06-19 01:54:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-19 18:00:23 -0400 |
commit | 85d59a87248de90e3266e10dce99477b60f524c0 (patch) | |
tree | 1642b59a05a69acdf8e9f754bce19864f3f66cbe /drivers/net/team/team.c | |
parent | 0d572e45f7f8ae3a27c82c5f0e352abf1dcb67f4 (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.c | 68 |
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) | |||
89 | struct team_option_inst { /* One for each option instance */ | 89 | struct 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) | |||
958 | static int team_port_en_option_get(struct team *team, | 964 | static 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 | ||
965 | static int team_port_en_option_set(struct team *team, | 973 | static 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 | ||
975 | static int team_user_linkup_option_get(struct team *team, | 985 | static 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 | ||
982 | static int team_user_linkup_option_set(struct team *team, | 994 | static 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 | ||
990 | static int team_user_linkup_en_option_get(struct team *team, | 1004 | static 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, | |||
999 | static int team_user_linkup_en_option_set(struct team *team, | 1013 | static 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); |