Commit 85d59a87 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

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: default avatarJiri Pirko <jpirko@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0d572e45
...@@ -89,8 +89,7 @@ static void team_refresh_port_linkup(struct team_port *port) ...@@ -89,8 +89,7 @@ static void team_refresh_port_linkup(struct team_port *port)
struct team_option_inst { /* One for each option instance */ struct team_option_inst { /* One for each option instance */
struct list_head list; struct list_head list;
struct team_option *option; struct team_option *option;
struct team_port *port; /* != NULL if per-port */ struct team_option_inst_info info;
u32 array_index;
bool changed; bool changed;
bool removed; bool removed;
}; };
...@@ -130,6 +129,7 @@ static int __team_option_inst_add(struct team *team, struct team_option *option, ...@@ -130,6 +129,7 @@ static int __team_option_inst_add(struct team *team, struct team_option *option,
struct team_option_inst *opt_inst; struct team_option_inst *opt_inst;
unsigned int array_size; unsigned int array_size;
unsigned int i; unsigned int i;
int err;
array_size = option->array_size; array_size = option->array_size;
if (!array_size) if (!array_size)
...@@ -140,11 +140,17 @@ static int __team_option_inst_add(struct team *team, struct team_option *option, ...@@ -140,11 +140,17 @@ static int __team_option_inst_add(struct team *team, struct team_option *option,
if (!opt_inst) if (!opt_inst)
return -ENOMEM; return -ENOMEM;
opt_inst->option = option; opt_inst->option = option;
opt_inst->port = port; opt_inst->info.port = port;
opt_inst->array_index = i; opt_inst->info.array_index = i;
opt_inst->changed = true; opt_inst->changed = true;
opt_inst->removed = false; opt_inst->removed = false;
list_add_tail(&opt_inst->list, &team->option_inst_list); list_add_tail(&opt_inst->list, &team->option_inst_list);
if (option->init) {
err = option->init(team, &opt_inst->info);
if (err)
return err;
}
} }
return 0; return 0;
} }
...@@ -193,7 +199,7 @@ static void __team_option_inst_del_port(struct team *team, ...@@ -193,7 +199,7 @@ static void __team_option_inst_del_port(struct team *team,
list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) { list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) {
if (opt_inst->option->per_port && if (opt_inst->option->per_port &&
opt_inst->port == port) opt_inst->info.port == port)
__team_option_inst_del(opt_inst); __team_option_inst_del(opt_inst);
} }
} }
...@@ -224,7 +230,7 @@ static void __team_option_inst_mark_removed_port(struct team *team, ...@@ -224,7 +230,7 @@ static void __team_option_inst_mark_removed_port(struct team *team,
struct team_option_inst *opt_inst; struct team_option_inst *opt_inst;
list_for_each_entry(opt_inst, &team->option_inst_list, list) { list_for_each_entry(opt_inst, &team->option_inst_list, list) {
if (opt_inst->port == port) { if (opt_inst->info.port == port) {
opt_inst->changed = true; opt_inst->changed = true;
opt_inst->removed = true; opt_inst->removed = true;
} }
...@@ -958,39 +964,47 @@ static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx) ...@@ -958,39 +964,47 @@ static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx)
static int team_port_en_option_get(struct team *team, static int team_port_en_option_get(struct team *team,
struct team_gsetter_ctx *ctx) struct team_gsetter_ctx *ctx)
{ {
ctx->data.bool_val = team_port_enabled(ctx->port); struct team_port *port = ctx->info->port;
ctx->data.bool_val = team_port_enabled(port);
return 0; return 0;
} }
static int team_port_en_option_set(struct team *team, static int team_port_en_option_set(struct team *team,
struct team_gsetter_ctx *ctx) struct team_gsetter_ctx *ctx)
{ {
struct team_port *port = ctx->info->port;
if (ctx->data.bool_val) if (ctx->data.bool_val)
team_port_enable(team, ctx->port); team_port_enable(team, port);
else else
team_port_disable(team, ctx->port); team_port_disable(team, port);
return 0; return 0;
} }
static int team_user_linkup_option_get(struct team *team, static int team_user_linkup_option_get(struct team *team,
struct team_gsetter_ctx *ctx) struct team_gsetter_ctx *ctx)
{ {
ctx->data.bool_val = ctx->port->user.linkup; struct team_port *port = ctx->info->port;
ctx->data.bool_val = port->user.linkup;
return 0; return 0;
} }
static int team_user_linkup_option_set(struct team *team, static int team_user_linkup_option_set(struct team *team,
struct team_gsetter_ctx *ctx) struct team_gsetter_ctx *ctx)
{ {
ctx->port->user.linkup = ctx->data.bool_val; struct team_port *port = ctx->info->port;
team_refresh_port_linkup(ctx->port);
port->user.linkup = ctx->data.bool_val;
team_refresh_port_linkup(port);
return 0; return 0;
} }
static int team_user_linkup_en_option_get(struct team *team, static int team_user_linkup_en_option_get(struct team *team,
struct team_gsetter_ctx *ctx) struct team_gsetter_ctx *ctx)
{ {
struct team_port *port = ctx->port; struct team_port *port = ctx->info->port;
ctx->data.bool_val = port->user.linkup_enabled; ctx->data.bool_val = port->user.linkup_enabled;
return 0; return 0;
...@@ -999,10 +1013,10 @@ static int team_user_linkup_en_option_get(struct team *team, ...@@ -999,10 +1013,10 @@ static int team_user_linkup_en_option_get(struct team *team,
static int team_user_linkup_en_option_set(struct team *team, static int team_user_linkup_en_option_set(struct team *team,
struct team_gsetter_ctx *ctx) struct team_gsetter_ctx *ctx)
{ {
struct team_port *port = ctx->port; struct team_port *port = ctx->info->port;
port->user.linkup_enabled = ctx->data.bool_val; port->user.linkup_enabled = ctx->data.bool_val;
team_refresh_port_linkup(ctx->port); team_refresh_port_linkup(port);
return 0; return 0;
} }
...@@ -1557,6 +1571,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb, ...@@ -1557,6 +1571,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
list_for_each_entry(opt_inst, &team->option_inst_list, list) { list_for_each_entry(opt_inst, &team->option_inst_list, list) {
struct nlattr *option_item; struct nlattr *option_item;
struct team_option *option = opt_inst->option; struct team_option *option = opt_inst->option;
struct team_option_inst_info *opt_inst_info;
struct team_gsetter_ctx ctx; struct team_gsetter_ctx ctx;
/* Include only changed options if fill all mode is not on */ /* 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,16 +1590,18 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
if (opt_inst->removed && if (opt_inst->removed &&
nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED)) nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED))
goto nla_put_failure; goto nla_put_failure;
if (opt_inst->port &&
opt_inst_info = &opt_inst->info;
if (opt_inst_info->port &&
nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX, nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX,
opt_inst->port->dev->ifindex)) opt_inst_info->port->dev->ifindex))
goto nla_put_failure; goto nla_put_failure;
ctx.port = opt_inst->port;
if (opt_inst->option->array_size && if (opt_inst->option->array_size &&
nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX, nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX,
opt_inst->array_index)) opt_inst_info->array_index))
goto nla_put_failure; goto nla_put_failure;
ctx.array_index = opt_inst->array_index; ctx.info = opt_inst_info;
switch (option->type) { switch (option->type) {
case TEAM_OPTION_TYPE_U32: case TEAM_OPTION_TYPE_U32:
if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32)) 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,19 +1763,20 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
list_for_each_entry(opt_inst, &team->option_inst_list, list) { list_for_each_entry(opt_inst, &team->option_inst_list, list) {
struct team_option *option = opt_inst->option; struct team_option *option = opt_inst->option;
struct team_gsetter_ctx ctx; struct team_gsetter_ctx ctx;
struct team_option_inst_info *opt_inst_info;
int tmp_ifindex; int tmp_ifindex;
tmp_ifindex = opt_inst->port ? opt_inst_info = &opt_inst->info;
opt_inst->port->dev->ifindex : 0; tmp_ifindex = opt_inst_info->port ?
opt_inst_info->port->dev->ifindex : 0;
if (option->type != opt_type || if (option->type != opt_type ||
strcmp(option->name, opt_name) || strcmp(option->name, opt_name) ||
tmp_ifindex != opt_port_ifindex || tmp_ifindex != opt_port_ifindex ||
(option->array_size && !opt_is_array) || (option->array_size && !opt_is_array) ||
opt_inst->array_index != opt_array_index) opt_inst_info->array_index != opt_array_index)
continue; continue;
opt_found = true; opt_found = true;
ctx.port = opt_inst->port; ctx.info = opt_inst_info;
ctx.array_index = opt_inst->array_index;
switch (opt_type) { switch (opt_type) {
case TEAM_OPTION_TYPE_U32: case TEAM_OPTION_TYPE_U32:
ctx.data.u32_val = nla_get_u32(attr_data); ctx.data.u32_val = nla_get_u32(attr_data);
......
...@@ -83,6 +83,11 @@ enum team_option_type { ...@@ -83,6 +83,11 @@ enum team_option_type {
TEAM_OPTION_TYPE_BOOL, TEAM_OPTION_TYPE_BOOL,
}; };
struct team_option_inst_info {
u32 array_index;
struct team_port *port; /* != NULL if per-port */
};
struct team_gsetter_ctx { struct team_gsetter_ctx {
union { union {
u32 u32_val; u32 u32_val;
...@@ -93,8 +98,7 @@ struct team_gsetter_ctx { ...@@ -93,8 +98,7 @@ struct team_gsetter_ctx {
} bin_val; } bin_val;
bool bool_val; bool bool_val;
} data; } data;
u32 array_index; struct team_option_inst_info *info;
struct team_port *port;
}; };
struct team_option { struct team_option {
...@@ -103,6 +107,7 @@ struct team_option { ...@@ -103,6 +107,7 @@ struct team_option {
bool per_port; bool per_port;
unsigned int array_size; /* != 0 means the option is array */ unsigned int array_size; /* != 0 means the option is array */
enum team_option_type type; enum team_option_type type;
int (*init)(struct team *team, struct team_option_inst_info *info);
int (*getter)(struct team *team, struct team_gsetter_ctx *ctx); int (*getter)(struct team *team, struct team_gsetter_ctx *ctx);
int (*setter)(struct team *team, struct team_gsetter_ctx *ctx); int (*setter)(struct team *team, struct team_gsetter_ctx *ctx);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment