Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright 2020 NXP
0003  */
0004 #include "sja1105.h"
0005 #include "sja1105_vl.h"
0006 
0007 struct sja1105_rule *sja1105_rule_find(struct sja1105_private *priv,
0008                        unsigned long cookie)
0009 {
0010     struct sja1105_rule *rule;
0011 
0012     list_for_each_entry(rule, &priv->flow_block.rules, list)
0013         if (rule->cookie == cookie)
0014             return rule;
0015 
0016     return NULL;
0017 }
0018 
0019 static int sja1105_find_free_l2_policer(struct sja1105_private *priv)
0020 {
0021     int i;
0022 
0023     for (i = 0; i < SJA1105_NUM_L2_POLICERS; i++)
0024         if (!priv->flow_block.l2_policer_used[i])
0025             return i;
0026 
0027     return -1;
0028 }
0029 
0030 static int sja1105_setup_bcast_policer(struct sja1105_private *priv,
0031                        struct netlink_ext_ack *extack,
0032                        unsigned long cookie, int port,
0033                        u64 rate_bytes_per_sec,
0034                        u32 burst)
0035 {
0036     struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
0037     struct sja1105_l2_policing_entry *policing;
0038     struct dsa_switch *ds = priv->ds;
0039     bool new_rule = false;
0040     unsigned long p;
0041     int rc;
0042 
0043     if (!rule) {
0044         rule = kzalloc(sizeof(*rule), GFP_KERNEL);
0045         if (!rule)
0046             return -ENOMEM;
0047 
0048         rule->cookie = cookie;
0049         rule->type = SJA1105_RULE_BCAST_POLICER;
0050         rule->bcast_pol.sharindx = sja1105_find_free_l2_policer(priv);
0051         rule->key.type = SJA1105_KEY_BCAST;
0052         new_rule = true;
0053     }
0054 
0055     if (rule->bcast_pol.sharindx == -1) {
0056         NL_SET_ERR_MSG_MOD(extack, "No more L2 policers free");
0057         rc = -ENOSPC;
0058         goto out;
0059     }
0060 
0061     policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;
0062 
0063     if (policing[(ds->num_ports * SJA1105_NUM_TC) + port].sharindx != port) {
0064         NL_SET_ERR_MSG_MOD(extack,
0065                    "Port already has a broadcast policer");
0066         rc = -EEXIST;
0067         goto out;
0068     }
0069 
0070     rule->port_mask |= BIT(port);
0071 
0072     /* Make the broadcast policers of all ports attached to this block
0073      * point to the newly allocated policer
0074      */
0075     for_each_set_bit(p, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
0076         int bcast = (ds->num_ports * SJA1105_NUM_TC) + p;
0077 
0078         policing[bcast].sharindx = rule->bcast_pol.sharindx;
0079     }
0080 
0081     policing[rule->bcast_pol.sharindx].rate = div_u64(rate_bytes_per_sec *
0082                               512, 1000000);
0083     policing[rule->bcast_pol.sharindx].smax = burst;
0084 
0085     /* TODO: support per-flow MTU */
0086     policing[rule->bcast_pol.sharindx].maxlen = VLAN_ETH_FRAME_LEN +
0087                             ETH_FCS_LEN;
0088 
0089     rc = sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);
0090 
0091 out:
0092     if (rc == 0 && new_rule) {
0093         priv->flow_block.l2_policer_used[rule->bcast_pol.sharindx] = true;
0094         list_add(&rule->list, &priv->flow_block.rules);
0095     } else if (new_rule) {
0096         kfree(rule);
0097     }
0098 
0099     return rc;
0100 }
0101 
0102 static int sja1105_setup_tc_policer(struct sja1105_private *priv,
0103                     struct netlink_ext_ack *extack,
0104                     unsigned long cookie, int port, int tc,
0105                     u64 rate_bytes_per_sec,
0106                     u32 burst)
0107 {
0108     struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
0109     struct sja1105_l2_policing_entry *policing;
0110     bool new_rule = false;
0111     unsigned long p;
0112     int rc;
0113 
0114     if (!rule) {
0115         rule = kzalloc(sizeof(*rule), GFP_KERNEL);
0116         if (!rule)
0117             return -ENOMEM;
0118 
0119         rule->cookie = cookie;
0120         rule->type = SJA1105_RULE_TC_POLICER;
0121         rule->tc_pol.sharindx = sja1105_find_free_l2_policer(priv);
0122         rule->key.type = SJA1105_KEY_TC;
0123         rule->key.tc.pcp = tc;
0124         new_rule = true;
0125     }
0126 
0127     if (rule->tc_pol.sharindx == -1) {
0128         NL_SET_ERR_MSG_MOD(extack, "No more L2 policers free");
0129         rc = -ENOSPC;
0130         goto out;
0131     }
0132 
0133     policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;
0134 
0135     if (policing[(port * SJA1105_NUM_TC) + tc].sharindx != port) {
0136         NL_SET_ERR_MSG_MOD(extack,
0137                    "Port-TC pair already has an L2 policer");
0138         rc = -EEXIST;
0139         goto out;
0140     }
0141 
0142     rule->port_mask |= BIT(port);
0143 
0144     /* Make the policers for traffic class @tc of all ports attached to
0145      * this block point to the newly allocated policer
0146      */
0147     for_each_set_bit(p, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
0148         int index = (p * SJA1105_NUM_TC) + tc;
0149 
0150         policing[index].sharindx = rule->tc_pol.sharindx;
0151     }
0152 
0153     policing[rule->tc_pol.sharindx].rate = div_u64(rate_bytes_per_sec *
0154                                512, 1000000);
0155     policing[rule->tc_pol.sharindx].smax = burst;
0156 
0157     /* TODO: support per-flow MTU */
0158     policing[rule->tc_pol.sharindx].maxlen = VLAN_ETH_FRAME_LEN +
0159                          ETH_FCS_LEN;
0160 
0161     rc = sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);
0162 
0163 out:
0164     if (rc == 0 && new_rule) {
0165         priv->flow_block.l2_policer_used[rule->tc_pol.sharindx] = true;
0166         list_add(&rule->list, &priv->flow_block.rules);
0167     } else if (new_rule) {
0168         kfree(rule);
0169     }
0170 
0171     return rc;
0172 }
0173 
0174 static int sja1105_flower_policer(struct sja1105_private *priv, int port,
0175                   struct netlink_ext_ack *extack,
0176                   unsigned long cookie,
0177                   struct sja1105_key *key,
0178                   u64 rate_bytes_per_sec,
0179                   u32 burst)
0180 {
0181     switch (key->type) {
0182     case SJA1105_KEY_BCAST:
0183         return sja1105_setup_bcast_policer(priv, extack, cookie, port,
0184                            rate_bytes_per_sec, burst);
0185     case SJA1105_KEY_TC:
0186         return sja1105_setup_tc_policer(priv, extack, cookie, port,
0187                         key->tc.pcp, rate_bytes_per_sec,
0188                         burst);
0189     default:
0190         NL_SET_ERR_MSG_MOD(extack, "Unknown keys for policing");
0191         return -EOPNOTSUPP;
0192     }
0193 }
0194 
0195 static int sja1105_flower_parse_key(struct sja1105_private *priv,
0196                     struct netlink_ext_ack *extack,
0197                     struct flow_cls_offload *cls,
0198                     struct sja1105_key *key)
0199 {
0200     struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
0201     struct flow_dissector *dissector = rule->match.dissector;
0202     bool is_bcast_dmac = false;
0203     u64 dmac = U64_MAX;
0204     u16 vid = U16_MAX;
0205     u16 pcp = U16_MAX;
0206 
0207     if (dissector->used_keys &
0208         ~(BIT(FLOW_DISSECTOR_KEY_BASIC) |
0209           BIT(FLOW_DISSECTOR_KEY_CONTROL) |
0210           BIT(FLOW_DISSECTOR_KEY_VLAN) |
0211           BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS))) {
0212         NL_SET_ERR_MSG_MOD(extack,
0213                    "Unsupported keys used");
0214         return -EOPNOTSUPP;
0215     }
0216 
0217     if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
0218         struct flow_match_basic match;
0219 
0220         flow_rule_match_basic(rule, &match);
0221         if (match.key->n_proto) {
0222             NL_SET_ERR_MSG_MOD(extack,
0223                        "Matching on protocol not supported");
0224             return -EOPNOTSUPP;
0225         }
0226     }
0227 
0228     if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
0229         u8 bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
0230         u8 null[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
0231         struct flow_match_eth_addrs match;
0232 
0233         flow_rule_match_eth_addrs(rule, &match);
0234 
0235         if (!ether_addr_equal_masked(match.key->src, null,
0236                          match.mask->src)) {
0237             NL_SET_ERR_MSG_MOD(extack,
0238                        "Matching on source MAC not supported");
0239             return -EOPNOTSUPP;
0240         }
0241 
0242         if (!ether_addr_equal(match.mask->dst, bcast)) {
0243             NL_SET_ERR_MSG_MOD(extack,
0244                        "Masked matching on MAC not supported");
0245             return -EOPNOTSUPP;
0246         }
0247 
0248         dmac = ether_addr_to_u64(match.key->dst);
0249         is_bcast_dmac = ether_addr_equal(match.key->dst, bcast);
0250     }
0251 
0252     if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
0253         struct flow_match_vlan match;
0254 
0255         flow_rule_match_vlan(rule, &match);
0256 
0257         if (match.mask->vlan_id &&
0258             match.mask->vlan_id != VLAN_VID_MASK) {
0259             NL_SET_ERR_MSG_MOD(extack,
0260                        "Masked matching on VID is not supported");
0261             return -EOPNOTSUPP;
0262         }
0263 
0264         if (match.mask->vlan_priority &&
0265             match.mask->vlan_priority != 0x7) {
0266             NL_SET_ERR_MSG_MOD(extack,
0267                        "Masked matching on PCP is not supported");
0268             return -EOPNOTSUPP;
0269         }
0270 
0271         if (match.mask->vlan_id)
0272             vid = match.key->vlan_id;
0273         if (match.mask->vlan_priority)
0274             pcp = match.key->vlan_priority;
0275     }
0276 
0277     if (is_bcast_dmac && vid == U16_MAX && pcp == U16_MAX) {
0278         key->type = SJA1105_KEY_BCAST;
0279         return 0;
0280     }
0281     if (dmac == U64_MAX && vid == U16_MAX && pcp != U16_MAX) {
0282         key->type = SJA1105_KEY_TC;
0283         key->tc.pcp = pcp;
0284         return 0;
0285     }
0286     if (dmac != U64_MAX && vid != U16_MAX && pcp != U16_MAX) {
0287         key->type = SJA1105_KEY_VLAN_AWARE_VL;
0288         key->vl.dmac = dmac;
0289         key->vl.vid = vid;
0290         key->vl.pcp = pcp;
0291         return 0;
0292     }
0293     if (dmac != U64_MAX) {
0294         key->type = SJA1105_KEY_VLAN_UNAWARE_VL;
0295         key->vl.dmac = dmac;
0296         return 0;
0297     }
0298 
0299     NL_SET_ERR_MSG_MOD(extack, "Not matching on any known key");
0300     return -EOPNOTSUPP;
0301 }
0302 
0303 static int sja1105_policer_validate(const struct flow_action *action,
0304                     const struct flow_action_entry *act,
0305                     struct netlink_ext_ack *extack)
0306 {
0307     if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
0308         NL_SET_ERR_MSG_MOD(extack,
0309                    "Offload not supported when exceed action is not drop");
0310         return -EOPNOTSUPP;
0311     }
0312 
0313     if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
0314         act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
0315         NL_SET_ERR_MSG_MOD(extack,
0316                    "Offload not supported when conform action is not pipe or ok");
0317         return -EOPNOTSUPP;
0318     }
0319 
0320     if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
0321         !flow_action_is_last_entry(action, act)) {
0322         NL_SET_ERR_MSG_MOD(extack,
0323                    "Offload not supported when conform action is ok, but action is not last");
0324         return -EOPNOTSUPP;
0325     }
0326 
0327     if (act->police.peakrate_bytes_ps ||
0328         act->police.avrate || act->police.overhead) {
0329         NL_SET_ERR_MSG_MOD(extack,
0330                    "Offload not supported when peakrate/avrate/overhead is configured");
0331         return -EOPNOTSUPP;
0332     }
0333 
0334     if (act->police.rate_pkt_ps) {
0335         NL_SET_ERR_MSG_MOD(extack,
0336                    "QoS offload not support packets per second");
0337         return -EOPNOTSUPP;
0338     }
0339 
0340     return 0;
0341 }
0342 
0343 int sja1105_cls_flower_add(struct dsa_switch *ds, int port,
0344                struct flow_cls_offload *cls, bool ingress)
0345 {
0346     struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
0347     struct netlink_ext_ack *extack = cls->common.extack;
0348     struct sja1105_private *priv = ds->priv;
0349     const struct flow_action_entry *act;
0350     unsigned long cookie = cls->cookie;
0351     bool routing_rule = false;
0352     struct sja1105_key key;
0353     bool gate_rule = false;
0354     bool vl_rule = false;
0355     int rc, i;
0356 
0357     rc = sja1105_flower_parse_key(priv, extack, cls, &key);
0358     if (rc)
0359         return rc;
0360 
0361     flow_action_for_each(i, act, &rule->action) {
0362         switch (act->id) {
0363         case FLOW_ACTION_POLICE:
0364             rc = sja1105_policer_validate(&rule->action, act, extack);
0365             if (rc)
0366                 goto out;
0367 
0368             rc = sja1105_flower_policer(priv, port, extack, cookie,
0369                             &key,
0370                             act->police.rate_bytes_ps,
0371                             act->police.burst);
0372             if (rc)
0373                 goto out;
0374             break;
0375         case FLOW_ACTION_TRAP: {
0376             int cpu = dsa_upstream_port(ds, port);
0377 
0378             routing_rule = true;
0379             vl_rule = true;
0380 
0381             rc = sja1105_vl_redirect(priv, port, extack, cookie,
0382                          &key, BIT(cpu), true);
0383             if (rc)
0384                 goto out;
0385             break;
0386         }
0387         case FLOW_ACTION_REDIRECT: {
0388             struct dsa_port *to_dp;
0389 
0390             to_dp = dsa_port_from_netdev(act->dev);
0391             if (IS_ERR(to_dp)) {
0392                 NL_SET_ERR_MSG_MOD(extack,
0393                            "Destination not a switch port");
0394                 return -EOPNOTSUPP;
0395             }
0396 
0397             routing_rule = true;
0398             vl_rule = true;
0399 
0400             rc = sja1105_vl_redirect(priv, port, extack, cookie,
0401                          &key, BIT(to_dp->index), true);
0402             if (rc)
0403                 goto out;
0404             break;
0405         }
0406         case FLOW_ACTION_DROP:
0407             vl_rule = true;
0408 
0409             rc = sja1105_vl_redirect(priv, port, extack, cookie,
0410                          &key, 0, false);
0411             if (rc)
0412                 goto out;
0413             break;
0414         case FLOW_ACTION_GATE:
0415             gate_rule = true;
0416             vl_rule = true;
0417 
0418             rc = sja1105_vl_gate(priv, port, extack, cookie,
0419                          &key, act->hw_index,
0420                          act->gate.prio,
0421                          act->gate.basetime,
0422                          act->gate.cycletime,
0423                          act->gate.cycletimeext,
0424                          act->gate.num_entries,
0425                          act->gate.entries);
0426             if (rc)
0427                 goto out;
0428             break;
0429         default:
0430             NL_SET_ERR_MSG_MOD(extack,
0431                        "Action not supported");
0432             rc = -EOPNOTSUPP;
0433             goto out;
0434         }
0435     }
0436 
0437     if (vl_rule && !rc) {
0438         /* Delay scheduling configuration until DESTPORTS has been
0439          * populated by all other actions.
0440          */
0441         if (gate_rule) {
0442             if (!routing_rule) {
0443                 NL_SET_ERR_MSG_MOD(extack,
0444                            "Can only offload gate action together with redirect or trap");
0445                 return -EOPNOTSUPP;
0446             }
0447             rc = sja1105_init_scheduling(priv);
0448             if (rc)
0449                 goto out;
0450         }
0451 
0452         rc = sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS);
0453     }
0454 
0455 out:
0456     return rc;
0457 }
0458 
0459 int sja1105_cls_flower_del(struct dsa_switch *ds, int port,
0460                struct flow_cls_offload *cls, bool ingress)
0461 {
0462     struct sja1105_private *priv = ds->priv;
0463     struct sja1105_rule *rule = sja1105_rule_find(priv, cls->cookie);
0464     struct sja1105_l2_policing_entry *policing;
0465     int old_sharindx;
0466 
0467     if (!rule)
0468         return 0;
0469 
0470     if (rule->type == SJA1105_RULE_VL)
0471         return sja1105_vl_delete(priv, port, rule, cls->common.extack);
0472 
0473     policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;
0474 
0475     if (rule->type == SJA1105_RULE_BCAST_POLICER) {
0476         int bcast = (ds->num_ports * SJA1105_NUM_TC) + port;
0477 
0478         old_sharindx = policing[bcast].sharindx;
0479         policing[bcast].sharindx = port;
0480     } else if (rule->type == SJA1105_RULE_TC_POLICER) {
0481         int index = (port * SJA1105_NUM_TC) + rule->key.tc.pcp;
0482 
0483         old_sharindx = policing[index].sharindx;
0484         policing[index].sharindx = port;
0485     } else {
0486         return -EINVAL;
0487     }
0488 
0489     rule->port_mask &= ~BIT(port);
0490     if (!rule->port_mask) {
0491         priv->flow_block.l2_policer_used[old_sharindx] = false;
0492         list_del(&rule->list);
0493         kfree(rule);
0494     }
0495 
0496     return sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);
0497 }
0498 
0499 int sja1105_cls_flower_stats(struct dsa_switch *ds, int port,
0500                  struct flow_cls_offload *cls, bool ingress)
0501 {
0502     struct sja1105_private *priv = ds->priv;
0503     struct sja1105_rule *rule = sja1105_rule_find(priv, cls->cookie);
0504     int rc;
0505 
0506     if (!rule)
0507         return 0;
0508 
0509     if (rule->type != SJA1105_RULE_VL)
0510         return 0;
0511 
0512     rc = sja1105_vl_stats(priv, port, rule, &cls->stats,
0513                   cls->common.extack);
0514     if (rc)
0515         return rc;
0516 
0517     return 0;
0518 }
0519 
0520 void sja1105_flower_setup(struct dsa_switch *ds)
0521 {
0522     struct sja1105_private *priv = ds->priv;
0523     int port;
0524 
0525     INIT_LIST_HEAD(&priv->flow_block.rules);
0526 
0527     for (port = 0; port < ds->num_ports; port++)
0528         priv->flow_block.l2_policer_used[port] = true;
0529 }
0530 
0531 void sja1105_flower_teardown(struct dsa_switch *ds)
0532 {
0533     struct sja1105_private *priv = ds->priv;
0534     struct sja1105_rule *rule;
0535     struct list_head *pos, *n;
0536 
0537     list_for_each_safe(pos, n, &priv->flow_block.rules) {
0538         rule = list_entry(pos, struct sja1105_rule, list);
0539         list_del(&rule->list);
0540         kfree(rule);
0541     }
0542 }