diff options
Diffstat (limited to 'drivers/net/ethernet/mscc')
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_ace.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_flower.c | 70 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_tc.c | 47 |
3 files changed, 73 insertions, 48 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h index d621683643e1..e98944c87259 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.h +++ b/drivers/net/ethernet/mscc/ocelot_ace.h @@ -225,8 +225,8 @@ int ocelot_ace_init(struct ocelot *ocelot); void ocelot_ace_deinit(void); int ocelot_setup_tc_block_flower_bind(struct ocelot_port *port, - struct tc_block_offload *f); + struct flow_block_offload *f); void ocelot_setup_tc_block_flower_unbind(struct ocelot_port *port, - struct tc_block_offload *f); + struct flow_block_offload *f); #endif /* _MSCC_OCELOT_ACE_H_ */ diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c index 8778dee5a471..7aaddc09c185 100644 --- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -19,7 +19,7 @@ static u16 get_prio(u32 prio) return prio >> 16; } -static int ocelot_flower_parse_action(struct tc_cls_flower_offload *f, +static int ocelot_flower_parse_action(struct flow_cls_offload *f, struct ocelot_ace_rule *rule) { const struct flow_action_entry *a; @@ -44,10 +44,10 @@ static int ocelot_flower_parse_action(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_flower_parse(struct tc_cls_flower_offload *f, +static int ocelot_flower_parse(struct flow_cls_offload *f, struct ocelot_ace_rule *ocelot_rule) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; if (dissector->used_keys & @@ -174,7 +174,7 @@ finished_key_parsing: } static -struct ocelot_ace_rule *ocelot_ace_rule_create(struct tc_cls_flower_offload *f, +struct ocelot_ace_rule *ocelot_ace_rule_create(struct flow_cls_offload *f, struct ocelot_port_block *block) { struct ocelot_ace_rule *rule; @@ -188,7 +188,7 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct tc_cls_flower_offload *f, return rule; } -static int ocelot_flower_replace(struct tc_cls_flower_offload *f, +static int ocelot_flower_replace(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { struct ocelot_ace_rule *rule; @@ -212,7 +212,7 @@ static int ocelot_flower_replace(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_flower_destroy(struct tc_cls_flower_offload *f, +static int ocelot_flower_destroy(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { struct ocelot_ace_rule rule; @@ -230,7 +230,7 @@ static int ocelot_flower_destroy(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_flower_stats_update(struct tc_cls_flower_offload *f, +static int ocelot_flower_stats_update(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { struct ocelot_ace_rule rule; @@ -247,15 +247,15 @@ static int ocelot_flower_stats_update(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_setup_tc_cls_flower(struct tc_cls_flower_offload *f, +static int ocelot_setup_tc_cls_flower(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { switch (f->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return ocelot_flower_replace(f, port_block); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return ocelot_flower_destroy(f, port_block); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return ocelot_flower_stats_update(f, port_block); default: return -EOPNOTSUPP; @@ -299,36 +299,45 @@ static void ocelot_port_block_destroy(struct ocelot_port_block *block) kfree(block); } +static void ocelot_tc_block_unbind(void *cb_priv) +{ + struct ocelot_port_block *port_block = cb_priv; + + ocelot_port_block_destroy(port_block); +} + int ocelot_setup_tc_block_flower_bind(struct ocelot_port *port, - struct tc_block_offload *f) + struct flow_block_offload *f) { struct ocelot_port_block *port_block; - struct tcf_block_cb *block_cb; + struct flow_block_cb *block_cb; int ret; - if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) + if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) return -EOPNOTSUPP; - block_cb = tcf_block_cb_lookup(f->block, - ocelot_setup_tc_block_cb_flower, port); + block_cb = flow_block_cb_lookup(f, ocelot_setup_tc_block_cb_flower, + port); if (!block_cb) { port_block = ocelot_port_block_create(port); if (!port_block) return -ENOMEM; - block_cb = - __tcf_block_cb_register(f->block, - ocelot_setup_tc_block_cb_flower, - port, port_block, f->extack); + block_cb = flow_block_cb_alloc(f->net, + ocelot_setup_tc_block_cb_flower, + port, port_block, + ocelot_tc_block_unbind); if (IS_ERR(block_cb)) { ret = PTR_ERR(block_cb); goto err_cb_register; } + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, f->driver_block_list); } else { - port_block = tcf_block_cb_priv(block_cb); + port_block = flow_block_cb_priv(block_cb); } - tcf_block_cb_incref(block_cb); + flow_block_cb_incref(block_cb); return 0; err_cb_register: @@ -338,20 +347,17 @@ err_cb_register: } void ocelot_setup_tc_block_flower_unbind(struct ocelot_port *port, - struct tc_block_offload *f) + struct flow_block_offload *f) { - struct ocelot_port_block *port_block; - struct tcf_block_cb *block_cb; + struct flow_block_cb *block_cb; - block_cb = tcf_block_cb_lookup(f->block, - ocelot_setup_tc_block_cb_flower, port); + block_cb = flow_block_cb_lookup(f, ocelot_setup_tc_block_cb_flower, + port); if (!block_cb) return; - port_block = tcf_block_cb_priv(block_cb); - if (!tcf_block_cb_decref(block_cb)) { - tcf_block_cb_unregister(f->block, - ocelot_setup_tc_block_cb_flower, port); - ocelot_port_block_destroy(port_block); + if (!flow_block_cb_decref(block_cb)) { + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); } } diff --git a/drivers/net/ethernet/mscc/ocelot_tc.c b/drivers/net/ethernet/mscc/ocelot_tc.c index 72084306240d..9e6464ffae5d 100644 --- a/drivers/net/ethernet/mscc/ocelot_tc.c +++ b/drivers/net/ethernet/mscc/ocelot_tc.c @@ -128,35 +128,54 @@ static int ocelot_setup_tc_block_cb_eg(enum tc_setup_type type, cb_priv, false); } +static LIST_HEAD(ocelot_block_cb_list); + static int ocelot_setup_tc_block(struct ocelot_port *port, - struct tc_block_offload *f) + struct flow_block_offload *f) { + struct flow_block_cb *block_cb; tc_setup_cb_t *cb; - int ret; + int err; netdev_dbg(port->dev, "tc_block command %d, binder_type %d\n", f->command, f->binder_type); - if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { + if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { cb = ocelot_setup_tc_block_cb_ig; - port->tc.block_shared = tcf_block_shared(f->block); - } else if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) { + port->tc.block_shared = f->block_shared; + } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) { cb = ocelot_setup_tc_block_cb_eg; } else { return -EOPNOTSUPP; } + f->driver_block_list = &ocelot_block_cb_list; + switch (f->command) { - case TC_BLOCK_BIND: - ret = tcf_block_cb_register(f->block, cb, port, - port, f->extack); - if (ret) - return ret; - - return ocelot_setup_tc_block_flower_bind(port, f); - case TC_BLOCK_UNBIND: + case FLOW_BLOCK_BIND: + if (flow_block_cb_is_busy(cb, port, &ocelot_block_cb_list)) + return -EBUSY; + + block_cb = flow_block_cb_alloc(f->net, cb, port, port, NULL); + if (IS_ERR(block_cb)) + return PTR_ERR(block_cb); + + err = ocelot_setup_tc_block_flower_bind(port, f); + if (err < 0) { + flow_block_cb_free(block_cb); + return err; + } + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, f->driver_block_list); + return 0; + case FLOW_BLOCK_UNBIND: + block_cb = flow_block_cb_lookup(f, cb, port); + if (!block_cb) + return -ENOENT; + ocelot_setup_tc_block_flower_unbind(port, f); - tcf_block_cb_unregister(f->block, cb, port); + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); return 0; default: return -EOPNOTSUPP; |