diff options
Diffstat (limited to 'drivers/net/ethernet/mscc')
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot.c | 123 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_ace.c | 619 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_ace.h | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_board.c | 163 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_flower.c | 272 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_police.c | 27 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_police.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_tc.c | 24 | ||||
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot_vcap.h | 403 |
10 files changed, 706 insertions, 976 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index d3b7373c5961..b4731df186f4 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -442,8 +442,23 @@ void ocelot_adjust_link(struct ocelot *ocelot, int port, ocelot_port_writel(ocelot_port, DEV_MAC_MODE_CFG_FDX_ENA | mode, DEV_MAC_MODE_CFG); - if (ocelot->ops->pcs_init) - ocelot->ops->pcs_init(ocelot, port); + /* Disable HDX fast control */ + ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS, + DEV_PORT_MISC); + + /* SGMII only for now */ + ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA, + PCS1G_MODE_CFG); + ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG); + + /* Enable PCS */ + ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG); + + /* No aneg on SGMII */ + ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG); + + /* No loopback */ + ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG); /* Enable MAC module */ ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | @@ -1398,7 +1413,7 @@ void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state) * a source for the other ports. */ for (p = 0; p < ocelot->num_phys_ports; p++) { - if (p == ocelot->cpu || (ocelot->bridge_fwd_mask & BIT(p))) { + if (ocelot->bridge_fwd_mask & BIT(p)) { unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p); for (i = 0; i < ocelot->num_phys_ports; i++) { @@ -1413,18 +1428,10 @@ void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state) } } - /* Avoid the NPI port from looping back to itself */ - if (p != ocelot->cpu) - mask |= BIT(ocelot->cpu); - ocelot_write_rix(ocelot, mask, ANA_PGID_PGID, PGID_SRC + p); } else { - /* Only the CPU port, this is compatible with link - * aggregation. - */ - ocelot_write_rix(ocelot, - BIT(ocelot->cpu), + ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_SRC + p); } } @@ -2178,13 +2185,25 @@ static int ocelot_init_timestamp(struct ocelot *ocelot) /* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu. * The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG. + * In the special case that it's the NPI port that we're configuring, the + * length of the tag and optional prefix needs to be accounted for privately, + * in order to be able to sustain communication at the requested @sdu. */ -static void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu) +void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu) { struct ocelot_port *ocelot_port = ocelot->ports[port]; int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN; int atop_wm; + if (port == ocelot->npi) { + maxlen += OCELOT_TAG_LEN; + + if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_SHORT) + maxlen += OCELOT_SHORT_PREFIX_LEN; + else if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_LONG) + maxlen += OCELOT_LONG_PREFIX_LEN; + } + ocelot_port_writel(ocelot_port, maxlen, DEV_MAC_MAXLEN_CFG); /* Set Pause WM hysteresis @@ -2202,6 +2221,24 @@ static void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu) SYS_ATOP, port); ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); } +EXPORT_SYMBOL(ocelot_port_set_maxlen); + +int ocelot_get_max_mtu(struct ocelot *ocelot, int port) +{ + int max_mtu = 65535 - ETH_HLEN - ETH_FCS_LEN; + + if (port == ocelot->npi) { + max_mtu -= OCELOT_TAG_LEN; + + if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_SHORT) + max_mtu -= OCELOT_SHORT_PREFIX_LEN; + else if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_LONG) + max_mtu -= OCELOT_LONG_PREFIX_LEN; + } + + return max_mtu; +} +EXPORT_SYMBOL(ocelot_get_max_mtu); void ocelot_init_port(struct ocelot *ocelot, int port) { @@ -2299,42 +2336,57 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port, } EXPORT_SYMBOL(ocelot_probe_port); -void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu, - enum ocelot_tag_prefix injection, - enum ocelot_tag_prefix extraction) +/* Configure and enable the CPU port module, which is a set of queues. + * If @npi contains a valid port index, the CPU port module is connected + * to the Node Processor Interface (NPI). This is the mode through which + * frames can be injected from and extracted to an external CPU, + * over Ethernet. + */ +void ocelot_configure_cpu(struct ocelot *ocelot, int npi, + enum ocelot_tag_prefix injection, + enum ocelot_tag_prefix extraction) { - /* Configure and enable the CPU port. */ + int cpu = ocelot->num_phys_ports; + + ocelot->npi = npi; + ocelot->inj_prefix = injection; + ocelot->xtr_prefix = extraction; + + /* The unicast destination PGID for the CPU port module is unused */ ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu); + /* Instead set up a multicast destination PGID for traffic copied to + * the CPU. Whitelisted MAC addresses like the port netdevice MAC + * addresses will be copied to the CPU via this PGID. + */ ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU); ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA | ANA_PORT_PORT_CFG_PORTID_VAL(cpu), ANA_PORT_PORT_CFG, cpu); - /* If the CPU port is a physical port, set up the port in Node - * Processor Interface (NPI) mode. This is the mode through which - * frames can be injected from and extracted to an external CPU. - * Only one port can be an NPI at the same time. - */ - if (cpu < ocelot->num_phys_ports) { - int sdu = ETH_DATA_LEN + OCELOT_TAG_LEN; - + if (npi >= 0 && npi < ocelot->num_phys_ports) { ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M | - QSYS_EXT_CPU_CFG_EXT_CPU_PORT(cpu), + QSYS_EXT_CPU_CFG_EXT_CPU_PORT(npi), QSYS_EXT_CPU_CFG); - if (injection == OCELOT_TAG_PREFIX_SHORT) - sdu += OCELOT_SHORT_PREFIX_LEN; - else if (injection == OCELOT_TAG_PREFIX_LONG) - sdu += OCELOT_LONG_PREFIX_LEN; - - ocelot_port_set_maxlen(ocelot, cpu, sdu); + /* Enable NPI port */ + ocelot_write_rix(ocelot, + QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | + QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | + QSYS_SWITCH_PORT_MODE_PORT_ENA, + QSYS_SWITCH_PORT_MODE, npi); + /* NPI port Injection/Extraction configuration */ + ocelot_write_rix(ocelot, + SYS_PORT_MODE_INCL_XTR_HDR(extraction) | + SYS_PORT_MODE_INCL_INJ_HDR(injection), + SYS_PORT_MODE, npi); } - /* CPU port Injection/Extraction configuration */ + /* Enable CPU port module */ ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | QSYS_SWITCH_PORT_MODE_PORT_ENA, QSYS_SWITCH_PORT_MODE, cpu); + /* CPU port Injection/Extraction configuration */ ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(extraction) | SYS_PORT_MODE_INCL_INJ_HDR(injection), SYS_PORT_MODE, cpu); @@ -2344,10 +2396,8 @@ void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu, ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1), ANA_PORT_VLAN_CFG, cpu); - - ocelot->cpu = cpu; } -EXPORT_SYMBOL(ocelot_set_cpu_port); +EXPORT_SYMBOL(ocelot_configure_cpu); int ocelot_init(struct ocelot *ocelot) { @@ -2499,7 +2549,6 @@ void ocelot_deinit(struct ocelot *ocelot) cancel_delayed_work(&ocelot->stats_work); destroy_workqueue(ocelot->stats_queue); mutex_destroy(&ocelot->stats_lock); - ocelot_ace_deinit(); if (ocelot->ptp_clock) ptp_clock_unregister(ocelot->ptp_clock); diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h index 04372ba72fec..e34ef8380eb3 100644 --- a/drivers/net/ethernet/mscc/ocelot.h +++ b/drivers/net/ethernet/mscc/ocelot.h @@ -28,16 +28,6 @@ #include "ocelot_tc.h" #include "ocelot_ptp.h" -#define PGID_AGGR 64 -#define PGID_SRC 80 - -/* Reserved PGIDs */ -#define PGID_CPU (PGID_AGGR - 5) -#define PGID_UC (PGID_AGGR - 4) -#define PGID_MC (PGID_AGGR - 3) -#define PGID_MCIPV4 (PGID_AGGR - 2) -#define PGID_MCIPV6 (PGID_AGGR - 1) - #define OCELOT_BUFFER_CELL_SZ 60 #define OCELOT_STATS_CHECK_DELAY (2 * HZ) diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c index 86fc6e6b46dd..3bd286044480 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.c +++ b/drivers/net/ethernet/mscc/ocelot_ace.c @@ -6,60 +6,13 @@ #include <linux/iopoll.h> #include <linux/proc_fs.h> +#include <soc/mscc/ocelot_vcap.h> +#include "ocelot_police.h" #include "ocelot_ace.h" -#include "ocelot_vcap.h" #include "ocelot_s2.h" #define OCELOT_POLICER_DISCARD 0x17f - -static struct ocelot_acl_block *acl_block; - -struct vcap_props { - const char *name; /* Symbolic name */ - u16 tg_width; /* Type-group width (in bits) */ - u16 sw_count; /* Sub word count */ - u16 entry_count; /* Entry count */ - u16 entry_words; /* Number of entry words */ - u16 entry_width; /* Entry width (in bits) */ - u16 action_count; /* Action count */ - u16 action_words; /* Number of action words */ - u16 action_width; /* Action width (in bits) */ - u16 action_type_width; /* Action type width (in bits) */ - struct { - u16 width; /* Action type width (in bits) */ - u16 count; /* Action type sub word count */ - } action_table[2]; - u16 counter_words; /* Number of counter words */ - u16 counter_width; /* Counter width (in bits) */ -}; - #define ENTRY_WIDTH 32 -#define BITS_TO_32BIT(x) (1 + (((x) - 1) / ENTRY_WIDTH)) - -static const struct vcap_props vcap_is2 = { - .name = "IS2", - .tg_width = 2, - .sw_count = 4, - .entry_count = VCAP_IS2_CNT, - .entry_words = BITS_TO_32BIT(VCAP_IS2_ENTRY_WIDTH), - .entry_width = VCAP_IS2_ENTRY_WIDTH, - .action_count = (VCAP_IS2_CNT + VCAP_PORT_CNT + 2), - .action_words = BITS_TO_32BIT(VCAP_IS2_ACTION_WIDTH), - .action_width = (VCAP_IS2_ACTION_WIDTH), - .action_type_width = 1, - .action_table = { - { - .width = (IS2_AO_ACL_ID + IS2_AL_ACL_ID), - .count = 2 - }, - { - .width = 6, - .count = 4 - }, - }, - .counter_words = BITS_TO_32BIT(4 * ENTRY_WIDTH), - .counter_width = ENTRY_WIDTH, -}; enum vcap_sel { VCAP_SEL_ENTRY = 0x1, @@ -95,18 +48,20 @@ struct vcap_data { u32 tg_mask; /* Current type-group mask */ }; -static u32 vcap_s2_read_update_ctrl(struct ocelot *oc) +static u32 vcap_s2_read_update_ctrl(struct ocelot *ocelot) { - return ocelot_read(oc, S2_CORE_UPDATE_CTRL); + return ocelot_read(ocelot, S2_CORE_UPDATE_CTRL); } -static void vcap_cmd(struct ocelot *oc, u16 ix, int cmd, int sel) +static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel) { + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + u32 value = (S2_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) | S2_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) | S2_CORE_UPDATE_CTRL_UPDATE_SHOT); - if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2.entry_count) + if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2->entry_count) return; if (!(sel & VCAP_SEL_ENTRY)) @@ -118,83 +73,101 @@ static void vcap_cmd(struct ocelot *oc, u16 ix, int cmd, int sel) if (!(sel & VCAP_SEL_COUNTER)) value |= S2_CORE_UPDATE_CTRL_UPDATE_CNT_DIS; - ocelot_write(oc, value, S2_CORE_UPDATE_CTRL); - readx_poll_timeout(vcap_s2_read_update_ctrl, oc, value, + ocelot_write(ocelot, value, S2_CORE_UPDATE_CTRL); + readx_poll_timeout(vcap_s2_read_update_ctrl, ocelot, value, (value & S2_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0, 10, 100000); } /* Convert from 0-based row to VCAP entry row and run command */ -static void vcap_row_cmd(struct ocelot *oc, u32 row, int cmd, int sel) +static void vcap_row_cmd(struct ocelot *ocelot, u32 row, int cmd, int sel) { - vcap_cmd(oc, vcap_is2.entry_count - row - 1, cmd, sel); + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + + vcap_cmd(ocelot, vcap_is2->entry_count - row - 1, cmd, sel); } -static void vcap_entry2cache(struct ocelot *oc, struct vcap_data *data) +static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data) { - u32 i; + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + u32 entry_words, i; - for (i = 0; i < vcap_is2.entry_words; i++) { - ocelot_write_rix(oc, data->entry[i], S2_CACHE_ENTRY_DAT, i); - ocelot_write_rix(oc, ~data->mask[i], S2_CACHE_MASK_DAT, i); + entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH); + + for (i = 0; i < entry_words; i++) { + ocelot_write_rix(ocelot, data->entry[i], S2_CACHE_ENTRY_DAT, i); + ocelot_write_rix(ocelot, ~data->mask[i], S2_CACHE_MASK_DAT, i); } - ocelot_write(oc, data->tg, S2_CACHE_TG_DAT); + ocelot_write(ocelot, data->tg, S2_CACHE_TG_DAT); } -static void vcap_cache2entry(struct ocelot *oc, struct vcap_data *data) +static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data) { - u32 i; + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + u32 entry_words, i; + + entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH); - for (i = 0; i < vcap_is2.entry_words; i++) { - data->entry[i] = ocelot_read_rix(oc, S2_CACHE_ENTRY_DAT, i); + for (i = 0; i < entry_words; i++) { + data->entry[i] = ocelot_read_rix(ocelot, S2_CACHE_ENTRY_DAT, i); // Invert mask - data->mask[i] = ~ocelot_read_rix(oc, S2_CACHE_MASK_DAT, i); + data->mask[i] = ~ocelot_read_rix(ocelot, S2_CACHE_MASK_DAT, i); } - data->tg = ocelot_read(oc, S2_CACHE_TG_DAT); + data->tg = ocelot_read(ocelot, S2_CACHE_TG_DAT); } -static void vcap_action2cache(struct ocelot *oc, struct vcap_data *data) +static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data) { - u32 i, width, mask; + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + u32 action_words, i, width, mask; /* Encode action type */ - width = vcap_is2.action_type_width; + width = vcap_is2->action_type_width; if (width) { mask = GENMASK(width, 0); data->action[0] = ((data->action[0] & ~mask) | data->type); } - for (i = 0; i < vcap_is2.action_words; i++) - ocelot_write_rix(oc, data->action[i], S2_CACHE_ACTION_DAT, i); + action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH); - for (i = 0; i < vcap_is2.counter_words; i++) - ocelot_write_rix(oc, data->counter[i], S2_CACHE_CNT_DAT, i); + for (i = 0; i < action_words; i++) + ocelot_write_rix(ocelot, data->action[i], S2_CACHE_ACTION_DAT, + i); + + for (i = 0; i < vcap_is2->counter_words; i++) + ocelot_write_rix(ocelot, data->counter[i], S2_CACHE_CNT_DAT, i); } -static void vcap_cache2action(struct ocelot *oc, struct vcap_data *data) +static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data) { - u32 i, width; + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + u32 action_words, i, width; + + action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH); - for (i = 0; i < vcap_is2.action_words; i++) - data->action[i] = ocelot_read_rix(oc, S2_CACHE_ACTION_DAT, i); + for (i = 0; i < action_words; i++) + data->action[i] = ocelot_read_rix(ocelot, S2_CACHE_ACTION_DAT, + i); - for (i = 0; i < vcap_is2.counter_words; i++) - data->counter[i] = ocelot_read_rix(oc, S2_CACHE_CNT_DAT, i); + for (i = 0; i < vcap_is2->counter_words; i++) + data->counter[i] = ocelot_read_rix(ocelot, S2_CACHE_CNT_DAT, i); /* Extract action type */ - width = vcap_is2.action_type_width; + width = vcap_is2->action_type_width; data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0); } /* Calculate offsets for entry */ -static void is2_data_get(struct vcap_data *data, int ix) +static void is2_data_get(struct ocelot *ocelot, struct vcap_data *data, int ix) { - u32 i, col, offset, count, cnt, base, width = vcap_is2.tg_width; + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + u32 i, col, offset, count, cnt, base; + u32 width = vcap_is2->tg_width; count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4); col = (ix % 2); - cnt = (vcap_is2.sw_count / count); - base = (vcap_is2.sw_count - col * cnt - cnt); + cnt = (vcap_is2->sw_count / count); + base = (vcap_is2->sw_count - col * cnt - cnt); data->tg_value = 0; data->tg_mask = 0; for (i = 0; i < cnt; i++) { @@ -205,13 +178,13 @@ static void is2_data_get(struct vcap_data *data, int ix) /* Calculate key/action/counter offsets */ col = (count - col - 1); - data->key_offset = (base * vcap_is2.entry_width) / vcap_is2.sw_count; - data->counter_offset = (cnt * col * vcap_is2.counter_width); + data->key_offset = (base * vcap_is2->entry_width) / vcap_is2->sw_count; + data->counter_offset = (cnt * col * vcap_is2->counter_width); i = data->type; - width = vcap_is2.action_table[i].width; - cnt = vcap_is2.action_table[i].count; + width = vcap_is2->action_table[i].width; + cnt = vcap_is2->action_table[i].count; data->action_offset = - (((cnt * col * width) / count) + vcap_is2.action_type_width); + (((cnt * col * width) / count) + vcap_is2->action_type_width); } static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value) @@ -242,22 +215,39 @@ static u32 vcap_data_get(u32 *data, u32 offset, u32 len) return value; } -static void vcap_key_set(struct vcap_data *data, u32 offset, u32 width, - u32 value, u32 mask) +static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width, + u32 value, u32 mask) { vcap_data_set(data->entry, offset + data->key_offset, width, value); vcap_data_set(data->mask, offset + data->key_offset, width, mask); } -static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val, - u8 *msk, u32 count) +static void vcap_key_set(struct ocelot *ocelot, struct vcap_data *data, + enum vcap_is2_half_key_field field, + u32 value, u32 mask) { + u32 offset = ocelot->vcap_is2_keys[field].offset; + u32 length = ocelot->vcap_is2_keys[field].length; + + vcap_key_field_set(data, offset, length, value, mask); +} + +static void vcap_key_bytes_set(struct ocelot *ocelot, struct vcap_data *data, + enum vcap_is2_half_key_field field, + u8 *val, u8 *msk) +{ + u32 offset = ocelot->vcap_is2_keys[field].offset; + u32 count = ocelot->vcap_is2_keys[field].length; u32 i, j, n = 0, value = 0, mask = 0; + WARN_ON(count % 8); + /* Data wider than 32 bits are split up in chunks of maximum 32 bits. * The 32 LSB of the data are written to the 32 MSB of the TCAM. */ - offset += (count * 8); + offset += count; + count /= 8; + for (i = 0; i < count; i++) { j = (count - i - 1); value += (val[j] << n); @@ -265,7 +255,7 @@ static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val, n += 8; if (n == ENTRY_WIDTH || (i + 1) == count) { offset -= n; - vcap_key_set(data, offset, n, value, mask); + vcap_key_field_set(data, offset, n, value, mask); n = 0; value = 0; mask = 0; @@ -273,55 +263,71 @@ static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val, } } -static void vcap_key_l4_port_set(struct vcap_data *data, u32 offset, +static void vcap_key_l4_port_set(struct ocelot *ocelot, struct vcap_data *data, + enum vcap_is2_half_key_field field, struct ocelot_vcap_udp_tcp *port) { - vcap_key_set(data, offset, 16, port->value, port->mask); + u32 offset = ocelot->vcap_is2_keys[field].offset; + u32 length = ocelot->vcap_is2_keys[field].length; + + WARN_ON(length != 16); + + vcap_key_field_set(data, offset, length, port->value, port->mask); } -static void vcap_key_bit_set(struct vcap_data *data, u32 offset, +static void vcap_key_bit_set(struct ocelot *ocelot, struct vcap_data *data, + enum vcap_is2_half_key_field field, enum ocelot_vcap_bit val) { - vcap_key_set(data, offset, 1, val == OCELOT_VCAP_BIT_1 ? 1 : 0, - val == OCELOT_VCAP_BIT_ANY ? 0 : 1); -} + u32 offset = ocelot->vcap_is2_keys[field].offset; + u32 length = ocelot->vcap_is2_keys[field].length; + u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0); + u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1); -#define VCAP_KEY_SET(fld, val, msk) \ - vcap_key_set(&data, IS2_HKO_##fld, IS2_HKL_##fld, val, msk) -#define VCAP_KEY_ANY_SET(fld) \ - vcap_key_set(&data, IS2_HKO_##fld, IS2_HKL_##fld, 0, 0) -#define VCAP_KEY_BIT_SET(fld, val) vcap_key_bit_set(&data, IS2_HKO_##fld, val) -#define VCAP_KEY_BYTES_SET(fld, val, msk) \ - vcap_key_bytes_set(&data, IS2_HKO_##fld, val, msk, IS2_HKL_##fld / 8) + WARN_ON(length != 1); -static void vcap_action_set(struct vcap_data *data, u32 offset, u32 width, - u32 value) -{ - vcap_data_set(data->action, offset + data->action_offset, width, value); + vcap_key_field_set(data, offset, length, value, msk); } -#define VCAP_ACT_SET(fld, val) \ - vcap_action_set(data, IS2_AO_##fld, IS2_AL_##fld, val) +static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data, + enum vcap_is2_action_field field, u32 value) +{ + int offset = ocelot->vcap_is2_actions[field].offset; + int length = ocelot->vcap_is2_actions[field].length; + + vcap_data_set(data->action, offset + data->action_offset, length, + value); +} -static void is2_action_set(struct vcap_data *data, - enum ocelot_ace_action action) +static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data, + struct ocelot_ace_rule *ace) { - switch (action) { + switch (ace->action) { case OCELOT_ACL_ACTION_DROP: - VCAP_ACT_SET(PORT_MASK, 0x0); - VCAP_ACT_SET(MASK_MODE, 0x1); - VCAP_ACT_SET(POLICE_ENA, 0x1); - VCAP_ACT_SET(POLICE_IDX, OCELOT_POLICER_DISCARD); - VCAP_ACT_SET(CPU_QU_NUM, 0x0); - VCAP_ACT_SET(CPU_COPY_ENA, 0x0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, + OCELOT_POLICER_DISCARD); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0); break; case OCELOT_ACL_ACTION_TRAP: - VCAP_ACT_SET(PORT_MASK, 0x0); - VCAP_ACT_SET(MASK_MODE, 0x1); - VCAP_ACT_SET(POLICE_ENA, 0x0); - VCAP_ACT_SET(POLICE_IDX, 0x0); - VCAP_ACT_SET(CPU_QU_NUM, 0x0); - VCAP_ACT_SET(CPU_COPY_ENA, 0x1); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 1); + break; + case OCELOT_ACL_ACTION_POLICE: + vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, + ace->pol_ix); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); + vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0); break; } } @@ -329,6 +335,7 @@ static void is2_action_set(struct vcap_data *data, static void is2_entry_set(struct ocelot *ocelot, int ix, struct ocelot_ace_rule *ace) { + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; u32 val, msk, type, type_mask = 0xf, i, count; struct ocelot_ace_vlan *tag = &ace->vlan; struct ocelot_vcap_u64 payload; @@ -344,60 +351,76 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, vcap_cache2action(ocelot, &data); data.tg_sw = VCAP_TG_HALF; - is2_data_get(&data, ix); + is2_data_get(ocelot, &data, ix); data.tg = (data.tg & ~data.tg_mask); if (ace->prio != 0) data.tg |= data.tg_value; data.type = IS2_ACTION_TYPE_NORMAL; - VCAP_KEY_ANY_SET(PAG); - VCAP_KEY_SET(IGR_PORT_MASK, 0, ~BIT(ace->chip_port)); - VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1); - VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY); - VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc); - VCAP_KEY_BIT_SET(L2_BC, ace->dmac_bc); - VCAP_KEY_BIT_SET(VLAN_TAGGED, tag->tagged); - VCAP_KEY_SET(VID, tag->vid.value, tag->vid.mask); - VCAP_KEY_SET(PCP, tag->pcp.value[0], tag->pcp.mask[0]); - VCAP_KEY_BIT_SET(DEI, tag->dei); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_PAG, 0, 0); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0, + ~ace->ingress_port_mask); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_1); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_HOST_MATCH, + OCELOT_VCAP_BIT_ANY); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_MC, ace->dmac_mc); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_BC, ace->dmac_bc); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_VID, + tag->vid.value, tag->vid.mask); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_PCP, + tag->pcp.value[0], tag->pcp.mask[0]); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DEI, tag->dei); switch (ace->type) { case OCELOT_ACE_TYPE_ETYPE: { struct ocelot_ace_frame_etype *etype = &ace->frame.etype; type = IS2_TYPE_ETYPE; - VCAP_KEY_BYTES_SET(L2_DMAC, etype->dmac.value, - etype->dmac.mask); - VCAP_KEY_BYTES_SET(L2_SMAC, etype->smac.value, - etype->smac.mask); - VCAP_KEY_BYTES_SET(MAC_ETYPE_ETYPE, etype->etype.value, - etype->etype.mask); - VCAP_KEY_ANY_SET(MAC_ETYPE_L2_PAYLOAD); // Clear unused bits - vcap_key_bytes_set(&data, IS2_HKO_MAC_ETYPE_L2_PAYLOAD, - etype->data.value, etype->data.mask, 2); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC, + etype->dmac.value, etype->dmac.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC, + etype->smac.value, etype->smac.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE, + etype->etype.value, etype->etype.mask); + /* Clear unused bits */ + vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0, + 0, 0); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1, + 0, 0); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2, + 0, 0); + vcap_key_bytes_set(ocelot, &data, + VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0, + etype->data.value, etype->data.mask); break; } case OCELOT_ACE_TYPE_LLC: { struct ocelot_ace_frame_llc *llc = &ace->frame.llc; type = IS2_TYPE_LLC; - VCAP_KEY_BYTES_SET(L2_DMAC, llc->dmac.value, llc->dmac.mask); - VCAP_KEY_BYTES_SET(L2_SMAC, llc->smac.value, llc->smac.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC, + llc->dmac.value, llc->dmac.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC, + llc->smac.value, llc->smac.mask); for (i = 0; i < 4; i++) { payload.value[i] = llc->llc.value[i]; payload.mask[i] = llc->llc.mask[i]; } - VCAP_KEY_BYTES_SET(MAC_LLC_L2_LLC, payload.value, payload.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC, + payload.value, payload.mask); break; } case OCELOT_ACE_TYPE_SNAP: { struct ocelot_ace_frame_snap *snap = &ace->frame.snap; type = IS2_TYPE_SNAP; - VCAP_KEY_BYTES_SET(L2_DMAC, snap->dmac.value, snap->dmac.mask); - VCAP_KEY_BYTES_SET(L2_SMAC, snap->smac.value, snap->smac.mask); - VCAP_KEY_BYTES_SET(MAC_SNAP_L2_SNAP, + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC, + snap->dmac.value, snap->dmac.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC, + snap->smac.value, snap->smac.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP, ace->frame.snap.snap.value, ace->frame.snap.snap.mask); break; @@ -406,26 +429,42 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, struct ocelot_ace_frame_arp *arp = &ace->frame.arp; type = IS2_TYPE_ARP; - VCAP_KEY_BYTES_SET(MAC_ARP_L2_SMAC, arp->smac.value, - arp->smac.mask); - VCAP_KEY_BIT_SET(MAC_ARP_ARP_ADDR_SPACE_OK, arp->ethernet); - VCAP_KEY_BIT_SET(MAC_ARP_ARP_PROTO_SPACE_OK, arp->ip); - VCAP_KEY_BIT_SET(MAC_ARP_ARP_LEN_OK, arp->length); - VCAP_KEY_BIT_SET(MAC_ARP_ARP_TGT_MATCH, arp->dmac_match); - VCAP_KEY_BIT_SET(MAC_ARP_ARP_SENDER_MATCH, arp->smac_match); - VCAP_KEY_BIT_SET(MAC_ARP_ARP_OPCODE_UNKNOWN, arp->unknown); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_SMAC, + arp->smac.value, arp->smac.mask); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK, + arp->ethernet); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK, + arp->ip); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_LEN_OK, + arp->length); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_TARGET_MATCH, + arp->dmac_match); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_SENDER_MATCH, + arp->smac_match); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN, + arp->unknown); /* OPCODE is inverse, bit 0 is reply flag, bit 1 is RARP flag */ val = ((arp->req == OCELOT_VCAP_BIT_0 ? 1 : 0) | (arp->arp == OCELOT_VCAP_BIT_0 ? 2 : 0)); msk = ((arp->req == OCELOT_VCAP_BIT_ANY ? 0 : 1) | (arp->arp == OCELOT_VCAP_BIT_ANY ? 0 : 2)); - VCAP_KEY_SET(MAC_ARP_ARP_OPCODE, val, msk); - vcap_key_bytes_set(&data, IS2_HKO_MAC_ARP_L3_IP4_DIP, - arp->dip.value.addr, arp->dip.mask.addr, 4); - vcap_key_bytes_set(&data, IS2_HKO_MAC_ARP_L3_IP4_SIP, - arp->sip.value.addr, arp->sip.mask.addr, 4); - VCAP_KEY_ANY_SET(MAC_ARP_DIP_EQ_SIP); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_OPCODE, + val, msk); + vcap_key_bytes_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP, + arp->dip.value.addr, arp->dip.mask.addr); + vcap_key_bytes_set(ocelot, &data, + VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP, + arp->sip.value.addr, arp->sip.mask.addr); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP, + 0, 0); break; } case OCELOT_ACE_TYPE_IPV4: @@ -493,18 +532,23 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, seq_zero = ipv6->seq_zero; } - VCAP_KEY_BIT_SET(IP4, + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4, ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0); - VCAP_KEY_BIT_SET(L3_FRAGMENT, fragment); - VCAP_KEY_ANY_SET(L3_FRAG_OFS_GT0); - VCAP_KEY_BIT_SET(L3_OPTIONS, options); - VCAP_KEY_BIT_SET(L3_TTL_GT0, ttl); - VCAP_KEY_BYTES_SET(L3_TOS, ds.value, ds.mask); - vcap_key_bytes_set(&data, IS2_HKO_L3_IP4_DIP, dip.value.addr, - dip.mask.addr, 4); - vcap_key_bytes_set(&data, IS2_HKO_L3_IP4_SIP, sip.value.addr, - sip.mask.addr, 4); - VCAP_KEY_BIT_SET(DIP_EQ_SIP, sip_eq_dip); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_FRAGMENT, + fragment); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_OPTIONS, + options); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0, + ttl); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_TOS, + ds.value, ds.mask); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_DIP, + dip.value.addr, dip.mask.addr); + vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_SIP, + sip.value.addr, sip.mask.addr); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DIP_EQ_SIP, + sip_eq_dip); val = proto.value[0]; msk = proto.mask[0]; type = IS2_TYPE_IP_UDP_TCP; @@ -512,25 +556,34 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, /* UDP/TCP protocol match */ tcp = (val == 6 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_TCP, tcp); - vcap_key_l4_port_set(&data, - IS2_HKO_IP4_TCP_UDP_L4_DPORT, - dport); - vcap_key_l4_port_set(&data, - IS2_HKO_IP4_TCP_UDP_L4_SPORT, - sport); - VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_RNG); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_SPORT_EQ_DPORT, + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_TCP, tcp); + vcap_key_l4_port_set(ocelot, &data, + VCAP_IS2_HK_L4_DPORT, dport); + vcap_key_l4_port_set(ocelot, &data, + VCAP_IS2_HK_L4_SPORT, sport); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_RNG, 0, 0); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_L4_SPORT_EQ_DPORT, sport_eq_dport); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_SEQUENCE_EQ0, seq_zero); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_FIN, tcp_fin); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_SYN, tcp_syn); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_RST, tcp_rst); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_PSH, tcp_psh); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_ACK, tcp_ack); - VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_URG, tcp_urg); - VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_1588_DOM); - VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_1588_VER); + vcap_key_bit_set(ocelot, &data, + VCAP_IS2_HK_L4_SEQUENCE_EQ0, + seq_zero); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_FIN, + tcp_fin); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_SYN, + tcp_syn); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_RST, + tcp_rst); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_PSH, + tcp_psh); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_ACK, + tcp_ack); + vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_URG, + tcp_urg); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_DOM, + 0, 0); + vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_VER, + 0, 0); } else { if (msk == 0) { /* Any IP protocol match */ @@ -543,10 +596,12 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, payload.mask[i] = ip_data->mask[i]; } } - VCAP_KEY_BYTES_SET(IP4_OTHER_L3_PROTO, proto.value, - proto.mask); - VCAP_KEY_BYTES_SET(IP4_OTHER_L3_PAYLOAD, payload.value, - payload.mask); + vcap_key_bytes_set(ocelot, &data, + VCAP_IS2_HK_IP4_L3_PROTO, + proto.value, proto.mask); + vcap_key_bytes_set(ocelot, &data, + VCAP_IS2_HK_L3_PAYLOAD, + payload.value, payload.mask); } break; } @@ -554,19 +609,21 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, default: type = 0; type_mask = 0; - count = (vcap_is2.entry_width / 2); - for (i = (IS2_HKO_PCP + IS2_HKL_PCP); i < count; - i += ENTRY_WIDTH) { - /* Clear entry data */ - vcap_key_set(&data, i, min(32u, count - i), 0, 0); + count = vcap_is2->entry_width / 2; + /* Iterate over the non-common part of the key and + * clear entry data + */ + for (i = ocelot->vcap_is2_keys[VCAP_IS2_HK_L2_DMAC].offset; + i < count; i += ENTRY_WIDTH) { + vcap_key_field_set(&data, i, min(32u, count - i), 0, 0); } break; } - VCAP_KEY_SET(TYPE, type, type_mask); - is2_action_set(&data, ace->action); - vcap_data_set(data.counter, data.counter_offset, vcap_is2.counter_width, - ace->stats.pkts); + vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask); + is2_action_set(ocelot, &data, ace); + vcap_data_set(data.counter, data.counter_offset, + vcap_is2->counter_width, ace->stats.pkts); /* Write row */ vcap_entry2cache(ocelot, &data); @@ -574,29 +631,37 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, vcap_row_cmd(ocelot, row, VCAP_CMD_WRITE, VCAP_SEL_ALL); } -static void is2_entry_get(struct ocelot_ace_rule *rule, int ix) +static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule, + int ix) { - struct ocelot *op = rule->port->ocelot; + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; struct vcap_data data; int row = (ix / 2); u32 cnt; - vcap_row_cmd(op, row, VCAP_CMD_READ, VCAP_SEL_COUNTER); - vcap_cache2action(op, &data); + vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_COUNTER); + vcap_cache2action(ocelot, &data); data.tg_sw = VCAP_TG_HALF; - is2_data_get(&data, ix); + is2_data_get(ocelot, &data, ix); cnt = vcap_data_get(data.counter, data.counter_offset, - vcap_is2.counter_width); + vcap_is2->counter_width); rule->stats.pkts = cnt; } -static void ocelot_ace_rule_add(struct ocelot_acl_block *block, +static void ocelot_ace_rule_add(struct ocelot *ocelot, + struct ocelot_acl_block *block, struct ocelot_ace_rule *rule) { struct ocelot_ace_rule *tmp; struct list_head *pos, *n; + if (rule->action == OCELOT_ACL_ACTION_POLICE) { + block->pol_lpr--; + rule->pol_ix = block->pol_lpr; + ocelot_ace_policer_add(ocelot, rule->pol_ix, &rule->pol); + } + block->count++; if (list_empty(&block->rules)) { @@ -641,29 +706,57 @@ ocelot_ace_rule_get_rule_index(struct ocelot_acl_block *block, int index) return NULL; } -int ocelot_ace_rule_offload_add(struct ocelot_ace_rule *rule) +int ocelot_ace_rule_offload_add(struct ocelot *ocelot, + struct ocelot_ace_rule *rule) { + struct ocelot_acl_block *block = &ocelot->acl_block; struct ocelot_ace_rule *ace; int i, index; /* Add rule to the linked list */ - ocelot_ace_rule_add(acl_block, rule); + ocelot_ace_rule_add(ocelot, block, rule); /* Get the index of the inserted rule */ - index = ocelot_ace_rule_get_index_id(acl_block, rule); + index = ocelot_ace_rule_get_index_id(block, rule); /* Move down the rules to make place for the new rule */ - for (i = acl_block->count - 1; i > index; i--) { - ace = ocelot_ace_rule_get_rule_index(acl_block, i); - is2_entry_set(rule->port->ocelot, i, ace); + for (i = block->count - 1; i > index; i--) { + ace = ocelot_ace_rule_get_rule_index(block, i); + is2_entry_set(ocelot, i, ace); } /* Now insert the new rule */ - is2_entry_set(rule->port->ocelot, index, rule); + is2_entry_set(ocelot, index, rule); return 0; } -static void ocelot_ace_rule_del(struct ocelot_acl_block *block, +static void ocelot_ace_police_del(struct ocelot *ocelot, + struct ocelot_acl_block *block, + u32 ix) +{ + struct ocelot_ace_rule *ace; + int index = -1; + + if (ix < block->pol_lpr) + return; + + list_for_each_entry(ace, &block->rules, list) { + index++; + if (ace->action == OCELOT_ACL_ACTION_POLICE && + ace->pol_ix < ix) { + ace->pol_ix += 1; + ocelot_ace_policer_add(ocelot, ace->pol_ix, + &ace->pol); + is2_entry_set(ocelot, index, ace); + } + } + + ocelot_ace_policer_del(ocelot, block->pol_lpr); + block->pol_lpr++; +} + +static void ocelot_ace_rule_del(struct ocelot *ocelot, + struct ocelot_acl_block *block, struct ocelot_ace_rule *rule) { struct ocelot_ace_rule *tmp; @@ -672,6 +765,10 @@ static void ocelot_ace_rule_del(struct ocelot_acl_block *block, list_for_each_safe(pos, q, &block->rules) { tmp = list_entry(pos, struct ocelot_ace_rule, list); if (tmp->id == rule->id) { + if (tmp->action == OCELOT_ACL_ACTION_POLICE) + ocelot_ace_police_del(ocelot, block, + tmp->pol_ix); + list_del(pos); kfree(tmp); } @@ -680,8 +777,10 @@ static void ocelot_ace_rule_del(struct ocelot_acl_block *block, block->count--; } -int ocelot_ace_rule_offload_del(struct ocelot_ace_rule *rule) +int ocelot_ace_rule_offload_del(struct ocelot *ocelot, + struct ocelot_ace_rule *rule) { + struct ocelot_acl_block *block = &ocelot->acl_block; struct ocelot_ace_rule del_ace; struct ocelot_ace_rule *ace; int i, index; @@ -689,70 +788,55 @@ int ocelot_ace_rule_offload_del(struct ocelot_ace_rule *rule) memset(&del_ace, 0, sizeof(del_ace)); /* Gets index of the rule */ - index = ocelot_ace_rule_get_index_id(acl_block, rule); + index = ocelot_ace_rule_get_index_id(block, rule); /* Delete rule */ - ocelot_ace_rule_del(acl_block, rule); + ocelot_ace_rule_del(ocelot, block, rule); /* Move up all the blocks over the deleted rule */ - for (i = index; i < acl_block->count; i++) { - ace = ocelot_ace_rule_get_rule_index(acl_block, i); - is2_entry_set(rule->port->ocelot, i, ace); + for (i = index; i < block->count; i++) { + ace = ocelot_ace_rule_get_rule_index(block, i); + is2_entry_set(ocelot, i, ace); } /* Now delete the last rule, because it is duplicated */ - is2_entry_set(rule->port->ocelot, acl_block->count, &del_ace); + is2_entry_set(ocelot, block->count, &del_ace); return 0; } -int ocelot_ace_rule_stats_update(struct ocelot_ace_rule *rule) +int ocelot_ace_rule_stats_update(struct ocelot *ocelot, + struct ocelot_ace_rule *rule) { + struct ocelot_acl_block *block = &ocelot->acl_block; struct ocelot_ace_rule *tmp; int index; - index = ocelot_ace_rule_get_index_id(acl_block, rule); - is2_entry_get(rule, index); + index = ocelot_ace_rule_get_index_id(block, rule); + is2_entry_get(ocelot, rule, index); /* After we get the result we need to clear the counters */ - tmp = ocelot_ace_rule_get_rule_index(acl_block, index); + tmp = ocelot_ace_rule_get_rule_index(block, index); tmp->stats.pkts = 0; - is2_entry_set(rule->port->ocelot, index, tmp); + is2_entry_set(ocelot, index, tmp); return 0; } -static struct ocelot_acl_block *ocelot_acl_block_create(struct ocelot *ocelot) -{ - struct ocelot_acl_block *block; - - block = kzalloc(sizeof(*block), GFP_KERNEL); - if (!block) - return NULL; - - INIT_LIST_HEAD(&block->rules); - block->count = 0; - block->ocelot = ocelot; - - return block; -} - -static void ocelot_acl_block_destroy(struct ocelot_acl_block *block) -{ - kfree(block); -} - int ocelot_ace_init(struct ocelot *ocelot) { + const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + struct ocelot_acl_block *block = &ocelot->acl_block; struct vcap_data data; memset(&data, 0, sizeof(data)); + vcap_entry2cache(ocelot, &data); - ocelot_write(ocelot, vcap_is2.entry_count, S2_CORE_MV_CFG); + ocelot_write(ocelot, vcap_is2->entry_count, S2_CORE_MV_CFG); vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY); vcap_action2cache(ocelot, &data); - ocelot_write(ocelot, vcap_is2.action_count, S2_CORE_MV_CFG); + ocelot_write(ocelot, vcap_is2->action_count, S2_CORE_MV_CFG); vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ACTION | VCAP_SEL_COUNTER); @@ -771,12 +855,9 @@ int ocelot_ace_init(struct ocelot *ocelot) ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_CIR_STATE, OCELOT_POLICER_DISCARD); - acl_block = ocelot_acl_block_create(ocelot); + block->pol_lpr = OCELOT_POLICER_DISCARD - 1; - return 0; -} + INIT_LIST_HEAD(&ocelot->acl_block.rules); -void ocelot_ace_deinit(void) -{ - ocelot_acl_block_destroy(acl_block); + return 0; } diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h index c08e3e8482e7..29d22c566786 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.h +++ b/drivers/net/ethernet/mscc/ocelot_ace.h @@ -7,6 +7,7 @@ #define _MSCC_OCELOT_ACE_H_ #include "ocelot.h" +#include "ocelot_police.h" #include <net/sch_generic.h> #include <net/pkt_cls.h> @@ -176,6 +177,7 @@ struct ocelot_ace_frame_ipv6 { enum ocelot_ace_action { OCELOT_ACL_ACTION_DROP, OCELOT_ACL_ACTION_TRAP, + OCELOT_ACL_ACTION_POLICE, }; struct ocelot_ace_stats { @@ -186,14 +188,13 @@ struct ocelot_ace_stats { struct ocelot_ace_rule { struct list_head list; - struct ocelot_port *port; u16 prio; u32 id; enum ocelot_ace_action action; struct ocelot_ace_stats stats; - int chip_port; + u16 ingress_port_mask; enum ocelot_vcap_bit dmac_mc; enum ocelot_vcap_bit dmac_bc; @@ -209,24 +210,21 @@ struct ocelot_ace_rule { struct ocelot_ace_frame_ipv4 ipv4; struct ocelot_ace_frame_ipv6 ipv6; } frame; + struct ocelot_policer pol; + u32 pol_ix; }; -struct ocelot_acl_block { - struct list_head rules; - struct ocelot *ocelot; - int count; -}; - -int ocelot_ace_rule_offload_add(struct ocelot_ace_rule *rule); -int ocelot_ace_rule_offload_del(struct ocelot_ace_rule *rule); -int ocelot_ace_rule_stats_update(struct ocelot_ace_rule *rule); +int ocelot_ace_rule_offload_add(struct ocelot *ocelot, + struct ocelot_ace_rule *rule); +int ocelot_ace_rule_offload_del(struct ocelot *ocelot, + struct ocelot_ace_rule *rule); +int ocelot_ace_rule_stats_update(struct ocelot *ocelot, + struct ocelot_ace_rule *rule); int ocelot_ace_init(struct ocelot *ocelot); -void ocelot_ace_deinit(void); -int ocelot_setup_tc_block_flower_bind(struct ocelot_port_private *priv, - struct flow_block_offload *f); -void ocelot_setup_tc_block_flower_unbind(struct ocelot_port_private *priv, - struct flow_block_offload *f); +int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv, + struct flow_cls_offload *f, + bool ingress); #endif /* _MSCC_OCELOT_ACE_H_ */ diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c index 1135a18019c7..0ac9fbf77a01 100644 --- a/drivers/net/ethernet/mscc/ocelot_board.c +++ b/drivers/net/ethernet/mscc/ocelot_board.c @@ -14,9 +14,14 @@ #include <linux/skbuff.h> #include <net/switchdev.h> +#include <soc/mscc/ocelot_vcap.h> #include "ocelot.h" #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0)) +#define VSC7514_VCAP_IS2_CNT 64 +#define VSC7514_VCAP_IS2_ENTRY_WIDTH 376 +#define VSC7514_VCAP_IS2_ACTION_WIDTH 99 +#define VSC7514_VCAP_PORT_CNT 11 static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info) { @@ -211,29 +216,6 @@ static const struct of_device_id mscc_ocelot_match[] = { }; MODULE_DEVICE_TABLE(of, mscc_ocelot_match); -static void ocelot_port_pcs_init(struct ocelot *ocelot, int port) -{ - struct ocelot_port *ocelot_port = ocelot->ports[port]; - - /* Disable HDX fast control */ - ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS, - DEV_PORT_MISC); - - /* SGMII only for now */ - ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA, - PCS1G_MODE_CFG); - ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG); - - /* Enable PCS */ - ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG); - - /* No aneg on SGMII */ - ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG); - - /* No loopback */ - ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG); -} - static int ocelot_reset(struct ocelot *ocelot) { int retries = 100; @@ -258,10 +240,132 @@ static int ocelot_reset(struct ocelot *ocelot) } static const struct ocelot_ops ocelot_ops = { - .pcs_init = ocelot_port_pcs_init, .reset = ocelot_reset, }; +static const struct vcap_field vsc7514_vcap_is2_keys[] = { + /* Common: 46 bits */ + [VCAP_IS2_TYPE] = { 0, 4}, + [VCAP_IS2_HK_FIRST] = { 4, 1}, + [VCAP_IS2_HK_PAG] = { 5, 8}, + [VCAP_IS2_HK_IGR_PORT_MASK] = { 13, 12}, + [VCAP_IS2_HK_RSV2] = { 25, 1}, + [VCAP_IS2_HK_HOST_MATCH] = { 26, 1}, + [VCAP_IS2_HK_L2_MC] = { 27, 1}, + [VCAP_IS2_HK_L2_BC] = { 28, 1}, + [VCAP_IS2_HK_VLAN_TAGGED] = { 29, 1}, + [VCAP_IS2_HK_VID] = { 30, 12}, + [VCAP_IS2_HK_DEI] = { 42, 1}, + [VCAP_IS2_HK_PCP] = { 43, 3}, + /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */ + [VCAP_IS2_HK_L2_DMAC] = { 46, 48}, + [VCAP_IS2_HK_L2_SMAC] = { 94, 48}, + /* MAC_ETYPE (TYPE=000) */ + [VCAP_IS2_HK_MAC_ETYPE_ETYPE] = {142, 16}, + [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0] = {158, 16}, + [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1] = {174, 8}, + [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2] = {182, 3}, + /* MAC_LLC (TYPE=001) */ + [VCAP_IS2_HK_MAC_LLC_L2_LLC] = {142, 40}, + /* MAC_SNAP (TYPE=010) */ + [VCAP_IS2_HK_MAC_SNAP_L2_SNAP] = {142, 40}, + /* MAC_ARP (TYPE=011) */ + [VCAP_IS2_HK_MAC_ARP_SMAC] = { 46, 48}, + [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK] = { 94, 1}, + [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK] = { 95, 1}, + [VCAP_IS2_HK_MAC_ARP_LEN_OK] = { 96, 1}, + [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH] = { 97, 1}, + [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH] = { 98, 1}, + [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN] = { 99, 1}, + [VCAP_IS2_HK_MAC_ARP_OPCODE] = {100, 2}, + [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP] = {102, 32}, + [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP] = {134, 32}, + [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP] = {166, 1}, + /* IP4_TCP_UDP / IP4_OTHER common */ + [VCAP_IS2_HK_IP4] = { 46, 1}, + [VCAP_IS2_HK_L3_FRAGMENT] = { 47, 1}, + [VCAP_IS2_HK_L3_FRAG_OFS_GT0] = { 48, 1}, + [VCAP_IS2_HK_L3_OPTIONS] = { 49, 1}, + [VCAP_IS2_HK_IP4_L3_TTL_GT0] = { 50, 1}, + [VCAP_IS2_HK_L3_TOS] = { 51, 8}, + [VCAP_IS2_HK_L3_IP4_DIP] = { 59, 32}, + [VCAP_IS2_HK_L3_IP4_SIP] = { 91, 32}, + [VCAP_IS2_HK_DIP_EQ_SIP] = {123, 1}, + /* IP4_TCP_UDP (TYPE=100) */ + [VCAP_IS2_HK_TCP] = {124, 1}, + [VCAP_IS2_HK_L4_SPORT] = {125, 16}, + [VCAP_IS2_HK_L4_DPORT] = {141, 16}, + [VCAP_IS2_HK_L4_RNG] = {157, 8}, + [VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {165, 1}, + [VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {166, 1}, + [VCAP_IS2_HK_L4_URG] = {167, 1}, + [VCAP_IS2_HK_L4_ACK] = {168, 1}, + [VCAP_IS2_HK_L4_PSH] = {169, 1}, + [VCAP_IS2_HK_L4_RST] = {170, 1}, + [VCAP_IS2_HK_L4_SYN] = {171, 1}, + [VCAP_IS2_HK_L4_FIN] = {172, 1}, + [VCAP_IS2_HK_L4_1588_DOM] = {173, 8}, + [VCAP_IS2_HK_L4_1588_VER] = {181, 4}, + /* IP4_OTHER (TYPE=101) */ + [VCAP_IS2_HK_IP4_L3_PROTO] = {124, 8}, + [VCAP_IS2_HK_L3_PAYLOAD] = {132, 56}, + /* IP6_STD (TYPE=110) */ + [VCAP_IS2_HK_IP6_L3_TTL_GT0] = { 46, 1}, + [VCAP_IS2_HK_L3_IP6_SIP] = { 47, 128}, + [VCAP_IS2_HK_IP6_L3_PROTO] = {175, 8}, + /* OAM (TYPE=111) */ + [VCAP_IS2_HK_OAM_MEL_FLAGS] = {142, 7}, + [VCAP_IS2_HK_OAM_VER] = {149, 5}, + [VCAP_IS2_HK_OAM_OPCODE] = {154, 8}, + [VCAP_IS2_HK_OAM_FLAGS] = {162, 8}, + [VCAP_IS2_HK_OAM_MEPID] = {170, 16}, + [VCAP_IS2_HK_OAM_CCM_CNTS_EQ0] = {186, 1}, + [VCAP_IS2_HK_OAM_IS_Y1731] = {187, 1}, +}; + +static const struct vcap_field vsc7514_vcap_is2_actions[] = { + [VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1}, + [VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1}, + [VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3}, + [VCAP_IS2_ACT_MASK_MODE] = { 5, 2}, + [VCAP_IS2_ACT_MIRROR_ENA] = { 7, 1}, + [VCAP_IS2_ACT_LRN_DIS] = { 8, 1}, + [VCAP_IS2_ACT_POLICE_ENA] = { 9, 1}, + [VCAP_IS2_ACT_POLICE_IDX] = { 10, 9}, + [VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 19, 1}, + [VCAP_IS2_ACT_PORT_MASK] = { 20, 11}, + [VCAP_IS2_ACT_REW_OP] = { 31, 9}, + [VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 40, 1}, + [VCAP_IS2_ACT_RSV] = { 41, 2}, + [VCAP_IS2_ACT_ACL_ID] = { 43, 6}, + [VCAP_IS2_ACT_HIT_CNT] = { 49, 32}, +}; + +static const struct vcap_props vsc7514_vcap_props[] = { + [VCAP_IS2] = { + .tg_width = 2, + .sw_count = 4, + .entry_count = VSC7514_VCAP_IS2_CNT, + .entry_width = VSC7514_VCAP_IS2_ENTRY_WIDTH, + .action_count = VSC7514_VCAP_IS2_CNT + + VSC7514_VCAP_PORT_CNT + 2, + .action_width = 99, + .action_type_width = 1, + .action_table = { + [IS2_ACTION_TYPE_NORMAL] = { + .width = 49, + .count = 2 + }, + [IS2_ACTION_TYPE_SMAC_SIP] = { + .width = 6, + .count = 4 + }, + }, + .counter_words = 4, + .counter_width = 32, + }, +}; + static int mscc_ocelot_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -349,8 +453,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev) ocelot->ptp = 1; } - ocelot->num_cpu_ports = 1; /* 1 port on the switch, two groups */ - ports = of_get_child_by_name(np, "ethernet-ports"); if (!ports) { dev_err(&pdev->dev, "no ethernet-ports child node found\n"); @@ -362,9 +464,14 @@ static int mscc_ocelot_probe(struct platform_device *pdev) ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports, sizeof(struct ocelot_port *), GFP_KERNEL); + ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys; + ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions; + ocelot->vcap = vsc7514_vcap_props; + ocelot_init(ocelot); - ocelot_set_cpu_port(ocelot, ocelot->num_phys_ports, - OCELOT_TAG_PREFIX_NONE, OCELOT_TAG_PREFIX_NONE); + /* No NPI port */ + ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE, + OCELOT_TAG_PREFIX_NONE); for_each_available_child_of_node(ports, portnp) { struct ocelot_port_private *priv; diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c index 3d65b99b9734..341923311fec 100644 --- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -8,27 +8,35 @@ #include "ocelot_ace.h" -struct ocelot_port_block { - struct ocelot_acl_block *block; - struct ocelot_port_private *priv; -}; - static int ocelot_flower_parse_action(struct flow_cls_offload *f, - struct ocelot_ace_rule *rule) + struct ocelot_ace_rule *ace) { const struct flow_action_entry *a; + s64 burst; + u64 rate; int i; - if (f->rule->action.num_entries != 1) + if (!flow_offload_has_one_action(&f->rule->action)) + return -EOPNOTSUPP; + + if (!flow_action_basic_hw_stats_check(&f->rule->action, + f->common.extack)) return -EOPNOTSUPP; flow_action_for_each(i, a, &f->rule->action) { switch (a->id) { case FLOW_ACTION_DROP: - rule->action = OCELOT_ACL_ACTION_DROP; + ace->action = OCELOT_ACL_ACTION_DROP; break; case FLOW_ACTION_TRAP: - rule->action = OCELOT_ACL_ACTION_TRAP; + ace->action = OCELOT_ACL_ACTION_TRAP; + break; + case FLOW_ACTION_POLICE: + ace->action = OCELOT_ACL_ACTION_POLICE; + rate = a->police.rate_bytes_ps; + ace->pol.rate = div_u64(rate, 1000) * 8; + burst = rate * PSCHED_NS2TICKS(a->police.burst); + ace->pol.burst = div_u64(burst, PSCHED_TICKS_PER_SEC); break; default: return -EOPNOTSUPP; @@ -39,7 +47,7 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f, } static int ocelot_flower_parse(struct flow_cls_offload *f, - struct ocelot_ace_rule *ocelot_rule) + struct ocelot_ace_rule *ace) { struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; @@ -84,14 +92,14 @@ static int ocelot_flower_parse(struct flow_cls_offload *f, return -EOPNOTSUPP; flow_rule_match_eth_addrs(rule, &match); - ocelot_rule->type = OCELOT_ACE_TYPE_ETYPE; - ether_addr_copy(ocelot_rule->frame.etype.dmac.value, + ace->type = OCELOT_ACE_TYPE_ETYPE; + ether_addr_copy(ace->frame.etype.dmac.value, match.key->dst); - ether_addr_copy(ocelot_rule->frame.etype.smac.value, + ether_addr_copy(ace->frame.etype.smac.value, match.key->src); - ether_addr_copy(ocelot_rule->frame.etype.dmac.mask, + ether_addr_copy(ace->frame.etype.dmac.mask, match.mask->dst); - ether_addr_copy(ocelot_rule->frame.etype.smac.mask, + ether_addr_copy(ace->frame.etype.smac.mask, match.mask->src); goto finished_key_parsing; } @@ -101,17 +109,17 @@ static int ocelot_flower_parse(struct flow_cls_offload *f, flow_rule_match_basic(rule, &match); if (ntohs(match.key->n_proto) == ETH_P_IP) { - ocelot_rule->type = OCELOT_ACE_TYPE_IPV4; - ocelot_rule->frame.ipv4.proto.value[0] = + ace->type = OCELOT_ACE_TYPE_IPV4; + ace->frame.ipv4.proto.value[0] = match.key->ip_proto; - ocelot_rule->frame.ipv4.proto.mask[0] = + ace->frame.ipv4.proto.mask[0] = match.mask->ip_proto; } if (ntohs(match.key->n_proto) == ETH_P_IPV6) { - ocelot_rule->type = OCELOT_ACE_TYPE_IPV6; - ocelot_rule->frame.ipv6.proto.value[0] = + ace->type = OCELOT_ACE_TYPE_IPV6; + ace->frame.ipv6.proto.value[0] = match.key->ip_proto; - ocelot_rule->frame.ipv6.proto.mask[0] = + ace->frame.ipv6.proto.mask[0] = match.mask->ip_proto; } } @@ -122,16 +130,16 @@ static int ocelot_flower_parse(struct flow_cls_offload *f, u8 *tmp; flow_rule_match_ipv4_addrs(rule, &match); - tmp = &ocelot_rule->frame.ipv4.sip.value.addr[0]; + tmp = &ace->frame.ipv4.sip.value.addr[0]; memcpy(tmp, &match.key->src, 4); - tmp = &ocelot_rule->frame.ipv4.sip.mask.addr[0]; + tmp = &ace->frame.ipv4.sip.mask.addr[0]; memcpy(tmp, &match.mask->src, 4); - tmp = &ocelot_rule->frame.ipv4.dip.value.addr[0]; + tmp = &ace->frame.ipv4.dip.value.addr[0]; memcpy(tmp, &match.key->dst, 4); - tmp = &ocelot_rule->frame.ipv4.dip.mask.addr[0]; + tmp = &ace->frame.ipv4.dip.mask.addr[0]; memcpy(tmp, &match.mask->dst, 4); } @@ -144,213 +152,111 @@ static int ocelot_flower_parse(struct flow_cls_offload *f, struct flow_match_ports match; flow_rule_match_ports(rule, &match); - ocelot_rule->frame.ipv4.sport.value = ntohs(match.key->src); - ocelot_rule->frame.ipv4.sport.mask = ntohs(match.mask->src); - ocelot_rule->frame.ipv4.dport.value = ntohs(match.key->dst); - ocelot_rule->frame.ipv4.dport.mask = ntohs(match.mask->dst); + ace->frame.ipv4.sport.value = ntohs(match.key->src); + ace->frame.ipv4.sport.mask = ntohs(match.mask->src); + ace->frame.ipv4.dport.value = ntohs(match.key->dst); + ace->frame.ipv4.dport.mask = ntohs(match.mask->dst); } if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) { struct flow_match_vlan match; flow_rule_match_vlan(rule, &match); - ocelot_rule->type = OCELOT_ACE_TYPE_ANY; - ocelot_rule->vlan.vid.value = match.key->vlan_id; - ocelot_rule->vlan.vid.mask = match.mask->vlan_id; - ocelot_rule->vlan.pcp.value[0] = match.key->vlan_priority; - ocelot_rule->vlan.pcp.mask[0] = match.mask->vlan_priority; + ace->type = OCELOT_ACE_TYPE_ANY; + ace->vlan.vid.value = match.key->vlan_id; + ace->vlan.vid.mask = match.mask->vlan_id; + ace->vlan.pcp.value[0] = match.key->vlan_priority; + ace->vlan.pcp.mask[0] = match.mask->vlan_priority; } finished_key_parsing: - ocelot_rule->prio = f->common.prio; - ocelot_rule->id = f->cookie; - return ocelot_flower_parse_action(f, ocelot_rule); + ace->prio = f->common.prio; + ace->id = f->cookie; + return ocelot_flower_parse_action(f, ace); } static -struct ocelot_ace_rule *ocelot_ace_rule_create(struct flow_cls_offload *f, - struct ocelot_port_block *block) +struct ocelot_ace_rule *ocelot_ace_rule_create(struct ocelot *ocelot, int port, + struct flow_cls_offload *f) { - struct ocelot_ace_rule *rule; + struct ocelot_ace_rule *ace; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); - if (!rule) + ace = kzalloc(sizeof(*ace), GFP_KERNEL); + if (!ace) return NULL; - rule->port = &block->priv->port; - rule->chip_port = block->priv->chip_port; - return rule; + ace->ingress_port_mask = BIT(port); + return ace; } -static int ocelot_flower_replace(struct flow_cls_offload *f, - struct ocelot_port_block *port_block) +int ocelot_cls_flower_replace(struct ocelot *ocelot, int port, + struct flow_cls_offload *f, bool ingress) { - struct ocelot_ace_rule *rule; + struct ocelot_ace_rule *ace; int ret; - rule = ocelot_ace_rule_create(f, port_block); - if (!rule) + ace = ocelot_ace_rule_create(ocelot, port, f); + if (!ace) return -ENOMEM; - ret = ocelot_flower_parse(f, rule); + ret = ocelot_flower_parse(f, ace); if (ret) { - kfree(rule); + kfree(ace); return ret; } - ret = ocelot_ace_rule_offload_add(rule); - if (ret) - return ret; - - port_block->priv->tc.offload_cnt++; - return 0; + return ocelot_ace_rule_offload_add(ocelot, ace); } +EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace); -static int ocelot_flower_destroy(struct flow_cls_offload *f, - struct ocelot_port_block *port_block) +int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port, + struct flow_cls_offload *f, bool ingress) { - struct ocelot_ace_rule rule; - int ret; - - rule.prio = f->common.prio; - rule.port = &port_block->priv->port; - rule.id = f->cookie; + struct ocelot_ace_rule ace; - ret = ocelot_ace_rule_offload_del(&rule); - if (ret) - return ret; + ace.prio = f->common.prio; + ace.id = f->cookie; - port_block->priv->tc.offload_cnt--; - return 0; + return ocelot_ace_rule_offload_del(ocelot, &ace); } +EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy); -static int ocelot_flower_stats_update(struct flow_cls_offload *f, - struct ocelot_port_block *port_block) +int ocelot_cls_flower_stats(struct ocelot *ocelot, int port, + struct flow_cls_offload *f, bool ingress) { - struct ocelot_ace_rule rule; + struct ocelot_ace_rule ace; int ret; - rule.prio = f->common.prio; - rule.port = &port_block->priv->port; - rule.id = f->cookie; - ret = ocelot_ace_rule_stats_update(&rule); + ace.prio = f->common.prio; + ace.id = f->cookie; + ret = ocelot_ace_rule_stats_update(ocelot, &ace); if (ret) return ret; - flow_stats_update(&f->stats, 0x0, rule.stats.pkts, 0x0); + flow_stats_update(&f->stats, 0x0, ace.stats.pkts, 0x0, + FLOW_ACTION_HW_STATS_IMMEDIATE); return 0; } +EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats); -static int ocelot_setup_tc_cls_flower(struct flow_cls_offload *f, - struct ocelot_port_block *port_block) +int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv, + struct flow_cls_offload *f, + bool ingress) { + struct ocelot *ocelot = priv->port.ocelot; + int port = priv->chip_port; + + if (!ingress) + return -EOPNOTSUPP; + switch (f->command) { case FLOW_CLS_REPLACE: - return ocelot_flower_replace(f, port_block); + return ocelot_cls_flower_replace(ocelot, port, f, ingress); case FLOW_CLS_DESTROY: - return ocelot_flower_destroy(f, port_block); + return ocelot_cls_flower_destroy(ocelot, port, f, ingress); case FLOW_CLS_STATS: - return ocelot_flower_stats_update(f, port_block); - default: - return -EOPNOTSUPP; - } -} - -static int ocelot_setup_tc_block_cb_flower(enum tc_setup_type type, - void *type_data, void *cb_priv) -{ - struct ocelot_port_block *port_block = cb_priv; - - if (!tc_cls_can_offload_and_chain0(port_block->priv->dev, type_data)) - return -EOPNOTSUPP; - - switch (type) { - case TC_SETUP_CLSFLOWER: - return ocelot_setup_tc_cls_flower(type_data, cb_priv); - case TC_SETUP_CLSMATCHALL: - return 0; + return ocelot_cls_flower_stats(ocelot, port, f, ingress); default: return -EOPNOTSUPP; } } - -static struct ocelot_port_block* -ocelot_port_block_create(struct ocelot_port_private *priv) -{ - struct ocelot_port_block *port_block; - - port_block = kzalloc(sizeof(*port_block), GFP_KERNEL); - if (!port_block) - return NULL; - - port_block->priv = priv; - - return port_block; -} - -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_private *priv, - struct flow_block_offload *f) -{ - struct ocelot_port_block *port_block; - struct flow_block_cb *block_cb; - int ret; - - if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) - return -EOPNOTSUPP; - - block_cb = flow_block_cb_lookup(f->block, - ocelot_setup_tc_block_cb_flower, priv); - if (!block_cb) { - port_block = ocelot_port_block_create(priv); - if (!port_block) - return -ENOMEM; - - block_cb = flow_block_cb_alloc(ocelot_setup_tc_block_cb_flower, - priv, 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 = flow_block_cb_priv(block_cb); - } - - flow_block_cb_incref(block_cb); - return 0; - -err_cb_register: - ocelot_port_block_destroy(port_block); - - return ret; -} - -void ocelot_setup_tc_block_flower_unbind(struct ocelot_port_private *priv, - struct flow_block_offload *f) -{ - struct flow_block_cb *block_cb; - - block_cb = flow_block_cb_lookup(f->block, - ocelot_setup_tc_block_cb_flower, priv); - if (!block_cb) - return; - - 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_police.c b/drivers/net/ethernet/mscc/ocelot_police.c index faddce43f2e3..2e1d8e187332 100644 --- a/drivers/net/ethernet/mscc/ocelot_police.c +++ b/drivers/net/ethernet/mscc/ocelot_police.c @@ -4,6 +4,7 @@ * Copyright (c) 2019 Microsemi Corporation */ +#include <soc/mscc/ocelot.h> #include "ocelot_police.h" enum mscc_qos_rate_mode { @@ -203,6 +204,7 @@ int ocelot_port_policer_add(struct ocelot *ocelot, int port, return 0; } +EXPORT_SYMBOL(ocelot_port_policer_add); int ocelot_port_policer_del(struct ocelot *ocelot, int port) { @@ -225,3 +227,28 @@ int ocelot_port_policer_del(struct ocelot *ocelot, int port) return 0; } +EXPORT_SYMBOL(ocelot_port_policer_del); + +int ocelot_ace_policer_add(struct ocelot *ocelot, u32 pol_ix, + struct ocelot_policer *pol) +{ + struct qos_policer_conf pp = { 0 }; + + if (!pol) + return -EINVAL; + + pp.mode = MSCC_QOS_RATE_MODE_DATA; + pp.pir = pol->rate; + pp.pbs = pol->burst; + + return qos_policer_conf_set(ocelot, 0, pol_ix, &pp); +} + +int ocelot_ace_policer_del(struct ocelot *ocelot, u32 pol_ix) +{ + struct qos_policer_conf pp = { 0 }; + + pp.mode = MSCC_QOS_RATE_MODE_DISABLED; + + return qos_policer_conf_set(ocelot, 0, pol_ix, &pp); +} diff --git a/drivers/net/ethernet/mscc/ocelot_police.h b/drivers/net/ethernet/mscc/ocelot_police.h index ae9509229463..792abd28010a 100644 --- a/drivers/net/ethernet/mscc/ocelot_police.h +++ b/drivers/net/ethernet/mscc/ocelot_police.h @@ -9,14 +9,9 @@ #include "ocelot.h" -struct ocelot_policer { - u32 rate; /* kilobit per second */ - u32 burst; /* bytes */ -}; +int ocelot_ace_policer_add(struct ocelot *ocelot, u32 pol_ix, + struct ocelot_policer *pol); -int ocelot_port_policer_add(struct ocelot *ocelot, int port, - struct ocelot_policer *pol); - -int ocelot_port_policer_del(struct ocelot *ocelot, int port); +int ocelot_ace_policer_del(struct ocelot *ocelot, u32 pol_ix); #endif /* _MSCC_OCELOT_POLICE_H_ */ diff --git a/drivers/net/ethernet/mscc/ocelot_tc.c b/drivers/net/ethernet/mscc/ocelot_tc.c index a4f7fbd76507..d326e231f0ad 100644 --- a/drivers/net/ethernet/mscc/ocelot_tc.c +++ b/drivers/net/ethernet/mscc/ocelot_tc.c @@ -4,8 +4,8 @@ * Copyright (c) 2019 Microsemi Corporation */ +#include <soc/mscc/ocelot.h> #include "ocelot_tc.h" -#include "ocelot_police.h" #include "ocelot_ace.h" #include <net/pkt_cls.h> @@ -20,9 +20,6 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, int port = priv->chip_port; int err; - netdev_dbg(priv->dev, "%s: port %u command %d cookie %lu\n", - __func__, port, f->command, f->cookie); - if (!ingress) { NL_SET_ERR_MSG_MOD(extack, "Only ingress is supported"); return -EOPNOTSUPP; @@ -99,17 +96,10 @@ static int ocelot_setup_tc_block_cb(enum tc_setup_type type, switch (type) { case TC_SETUP_CLSMATCHALL: - netdev_dbg(priv->dev, "tc_block_cb: TC_SETUP_CLSMATCHALL %s\n", - ingress ? "ingress" : "egress"); - return ocelot_setup_tc_cls_matchall(priv, type_data, ingress); case TC_SETUP_CLSFLOWER: - return 0; + return ocelot_setup_tc_cls_flower(priv, type_data, ingress); default: - netdev_dbg(priv->dev, "tc_block_cb: type %d %s\n", - type, - ingress ? "ingress" : "egress"); - return -EOPNOTSUPP; } } @@ -137,10 +127,6 @@ static int ocelot_setup_tc_block(struct ocelot_port_private *priv, { struct flow_block_cb *block_cb; flow_setup_cb_t *cb; - int err; - - netdev_dbg(priv->dev, "tc_block command %d, binder_type %d\n", - f->command, f->binder_type); if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { cb = ocelot_setup_tc_block_cb_ig; @@ -162,11 +148,6 @@ static int ocelot_setup_tc_block(struct ocelot_port_private *priv, if (IS_ERR(block_cb)) return PTR_ERR(block_cb); - err = ocelot_setup_tc_block_flower_bind(priv, 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; @@ -175,7 +156,6 @@ static int ocelot_setup_tc_block(struct ocelot_port_private *priv, if (!block_cb) return -ENOENT; - ocelot_setup_tc_block_flower_unbind(priv, f); flow_block_cb_remove(block_cb, f); list_del(&block_cb->driver_list); return 0; diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.h b/drivers/net/ethernet/mscc/ocelot_vcap.h deleted file mode 100644 index e22eac1da783..000000000000 --- a/drivers/net/ethernet/mscc/ocelot_vcap.h +++ /dev/null @@ -1,403 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MIT) - * Microsemi Ocelot Switch driver - * Copyright (c) 2019 Microsemi Corporation - */ - -#ifndef _OCELOT_VCAP_H_ -#define _OCELOT_VCAP_H_ - -/* ================================================================= - * VCAP Common - * ================================================================= - */ - -/* VCAP Type-Group values */ -#define VCAP_TG_NONE 0 /* Entry is invalid */ -#define VCAP_TG_FULL 1 /* Full entry */ -#define VCAP_TG_HALF 2 /* Half entry */ -#define VCAP_TG_QUARTER 3 /* Quarter entry */ - -/* ================================================================= - * VCAP IS2 - * ================================================================= - */ - -#define VCAP_IS2_CNT 64 -#define VCAP_IS2_ENTRY_WIDTH 376 -#define VCAP_IS2_ACTION_WIDTH 99 -#define VCAP_PORT_CNT 11 - -/* IS2 half key types */ -#define IS2_TYPE_ETYPE 0 -#define IS2_TYPE_LLC 1 -#define IS2_TYPE_SNAP 2 -#define IS2_TYPE_ARP 3 -#define IS2_TYPE_IP_UDP_TCP 4 -#define IS2_TYPE_IP_OTHER 5 -#define IS2_TYPE_IPV6 6 -#define IS2_TYPE_OAM 7 -#define IS2_TYPE_SMAC_SIP6 8 -#define IS2_TYPE_ANY 100 /* Pseudo type */ - -/* IS2 half key type mask for matching any IP */ -#define IS2_TYPE_MASK_IP_ANY 0xe - -/* IS2 action types */ -#define IS2_ACTION_TYPE_NORMAL 0 -#define IS2_ACTION_TYPE_SMAC_SIP 1 - -/* IS2 MASK_MODE values */ -#define IS2_ACT_MASK_MODE_NONE 0 -#define IS2_ACT_MASK_MODE_FILTER 1 -#define IS2_ACT_MASK_MODE_POLICY 2 -#define IS2_ACT_MASK_MODE_REDIR 3 - -/* IS2 REW_OP values */ -#define IS2_ACT_REW_OP_NONE 0 -#define IS2_ACT_REW_OP_PTP_ONE 2 -#define IS2_ACT_REW_OP_PTP_TWO 3 -#define IS2_ACT_REW_OP_SPECIAL 8 -#define IS2_ACT_REW_OP_PTP_ORG 9 -#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_1 (IS2_ACT_REW_OP_PTP_ONE | (1 << 3)) -#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_2 (IS2_ACT_REW_OP_PTP_ONE | (2 << 3)) -#define IS2_ACT_REW_OP_PTP_ONE_ADD_DELAY (IS2_ACT_REW_OP_PTP_ONE | (1 << 5)) -#define IS2_ACT_REW_OP_PTP_ONE_ADD_SUB BIT(7) - -#define VCAP_PORT_WIDTH 4 - -/* IS2 quarter key - SMAC_SIP4 */ -#define IS2_QKO_IGR_PORT 0 -#define IS2_QKL_IGR_PORT VCAP_PORT_WIDTH -#define IS2_QKO_L2_SMAC (IS2_QKO_IGR_PORT + IS2_QKL_IGR_PORT) -#define IS2_QKL_L2_SMAC 48 -#define IS2_QKO_L3_IP4_SIP (IS2_QKO_L2_SMAC + IS2_QKL_L2_SMAC) -#define IS2_QKL_L3_IP4_SIP 32 - -/* IS2 half key - common */ -#define IS2_HKO_TYPE 0 -#define IS2_HKL_TYPE 4 -#define IS2_HKO_FIRST (IS2_HKO_TYPE + IS2_HKL_TYPE) -#define IS2_HKL_FIRST 1 -#define IS2_HKO_PAG (IS2_HKO_FIRST + IS2_HKL_FIRST) -#define IS2_HKL_PAG 8 -#define IS2_HKO_IGR_PORT_MASK (IS2_HKO_PAG + IS2_HKL_PAG) -#define IS2_HKL_IGR_PORT_MASK (VCAP_PORT_CNT + 1) -#define IS2_HKO_SERVICE_FRM (IS2_HKO_IGR_PORT_MASK + IS2_HKL_IGR_PORT_MASK) -#define IS2_HKL_SERVICE_FRM 1 -#define IS2_HKO_HOST_MATCH (IS2_HKO_SERVICE_FRM + IS2_HKL_SERVICE_FRM) -#define IS2_HKL_HOST_MATCH 1 -#define IS2_HKO_L2_MC (IS2_HKO_HOST_MATCH + IS2_HKL_HOST_MATCH) -#define IS2_HKL_L2_MC 1 -#define IS2_HKO_L2_BC (IS2_HKO_L2_MC + IS2_HKL_L2_MC) -#define IS2_HKL_L2_BC 1 -#define IS2_HKO_VLAN_TAGGED (IS2_HKO_L2_BC + IS2_HKL_L2_BC) -#define IS2_HKL_VLAN_TAGGED 1 -#define IS2_HKO_VID (IS2_HKO_VLAN_TAGGED + IS2_HKL_VLAN_TAGGED) -#define IS2_HKL_VID 12 -#define IS2_HKO_DEI (IS2_HKO_VID + IS2_HKL_VID) -#define IS2_HKL_DEI 1 -#define IS2_HKO_PCP (IS2_HKO_DEI + IS2_HKL_DEI) -#define IS2_HKL_PCP 3 - -/* IS2 half key - MAC_ETYPE/MAC_LLC/MAC_SNAP/OAM common */ -#define IS2_HKO_L2_DMAC (IS2_HKO_PCP + IS2_HKL_PCP) -#define IS2_HKL_L2_DMAC 48 -#define IS2_HKO_L2_SMAC (IS2_HKO_L2_DMAC + IS2_HKL_L2_DMAC) -#define IS2_HKL_L2_SMAC 48 - -/* IS2 half key - MAC_ETYPE */ -#define IS2_HKO_MAC_ETYPE_ETYPE (IS2_HKO_L2_SMAC + IS2_HKL_L2_SMAC) -#define IS2_HKL_MAC_ETYPE_ETYPE 16 -#define IS2_HKO_MAC_ETYPE_L2_PAYLOAD \ - (IS2_HKO_MAC_ETYPE_ETYPE + IS2_HKL_MAC_ETYPE_ETYPE) -#define IS2_HKL_MAC_ETYPE_L2_PAYLOAD 27 - -/* IS2 half key - MAC_LLC */ -#define IS2_HKO_MAC_LLC_L2_LLC IS2_HKO_MAC_ETYPE_ETYPE -#define IS2_HKL_MAC_LLC_L2_LLC 40 - -/* IS2 half key - MAC_SNAP */ -#define IS2_HKO_MAC_SNAP_L2_SNAP IS2_HKO_MAC_ETYPE_ETYPE -#define IS2_HKL_MAC_SNAP_L2_SNAP 40 - -/* IS2 half key - ARP */ -#define IS2_HKO_MAC_ARP_L2_SMAC IS2_HKO_L2_DMAC -#define IS2_HKL_MAC_ARP_L2_SMAC 48 -#define IS2_HKO_MAC_ARP_ARP_ADDR_SPACE_OK \ - (IS2_HKO_MAC_ARP_L2_SMAC + IS2_HKL_MAC_ARP_L2_SMAC) -#define IS2_HKL_MAC_ARP_ARP_ADDR_SPACE_OK 1 -#define IS2_HKO_MAC_ARP_ARP_PROTO_SPACE_OK \ - (IS2_HKO_MAC_ARP_ARP_ADDR_SPACE_OK + IS2_HKL_MAC_ARP_ARP_ADDR_SPACE_OK) -#define IS2_HKL_MAC_ARP_ARP_PROTO_SPACE_OK 1 -#define IS2_HKO_MAC_ARP_ARP_LEN_OK \ - (IS2_HKO_MAC_ARP_ARP_PROTO_SPACE_OK + \ - IS2_HKL_MAC_ARP_ARP_PROTO_SPACE_OK) -#define IS2_HKL_MAC_ARP_ARP_LEN_OK 1 -#define IS2_HKO_MAC_ARP_ARP_TGT_MATCH \ - (IS2_HKO_MAC_ARP_ARP_LEN_OK + IS2_HKL_MAC_ARP_ARP_LEN_OK) -#define IS2_HKL_MAC_ARP_ARP_TGT_MATCH 1 -#define IS2_HKO_MAC_ARP_ARP_SENDER_MATCH \ - (IS2_HKO_MAC_ARP_ARP_TGT_MATCH + IS2_HKL_MAC_ARP_ARP_TGT_MATCH) -#define IS2_HKL_MAC_ARP_ARP_SENDER_MATCH 1 -#define IS2_HKO_MAC_ARP_ARP_OPCODE_UNKNOWN \ - (IS2_HKO_MAC_ARP_ARP_SENDER_MATCH + IS2_HKL_MAC_ARP_ARP_SENDER_MATCH) -#define IS2_HKL_MAC_ARP_ARP_OPCODE_UNKNOWN 1 -#define IS2_HKO_MAC_ARP_ARP_OPCODE \ - (IS2_HKO_MAC_ARP_ARP_OPCODE_UNKNOWN + \ - IS2_HKL_MAC_ARP_ARP_OPCODE_UNKNOWN) -#define IS2_HKL_MAC_ARP_ARP_OPCODE 2 -#define IS2_HKO_MAC_ARP_L3_IP4_DIP \ - (IS2_HKO_MAC_ARP_ARP_OPCODE + IS2_HKL_MAC_ARP_ARP_OPCODE) -#define IS2_HKL_MAC_ARP_L3_IP4_DIP 32 -#define IS2_HKO_MAC_ARP_L3_IP4_SIP \ - (IS2_HKO_MAC_ARP_L3_IP4_DIP + IS2_HKL_MAC_ARP_L3_IP4_DIP) -#define IS2_HKL_MAC_ARP_L3_IP4_SIP 32 -#define IS2_HKO_MAC_ARP_DIP_EQ_SIP \ - (IS2_HKO_MAC_ARP_L3_IP4_SIP + IS2_HKL_MAC_ARP_L3_IP4_SIP) -#define IS2_HKL_MAC_ARP_DIP_EQ_SIP 1 - -/* IS2 half key - IP4_TCP_UDP/IP4_OTHER common */ -#define IS2_HKO_IP4 IS2_HKO_L2_DMAC -#define IS2_HKL_IP4 1 -#define IS2_HKO_L3_FRAGMENT (IS2_HKO_IP4 + IS2_HKL_IP4) -#define IS2_HKL_L3_FRAGMENT 1 -#define IS2_HKO_L3_FRAG_OFS_GT0 (IS2_HKO_L3_FRAGMENT + IS2_HKL_L3_FRAGMENT) -#define IS2_HKL_L3_FRAG_OFS_GT0 1 -#define IS2_HKO_L3_OPTIONS (IS2_HKO_L3_FRAG_OFS_GT0 + IS2_HKL_L3_FRAG_OFS_GT0) -#define IS2_HKL_L3_OPTIONS 1 -#define IS2_HKO_L3_TTL_GT0 (IS2_HKO_L3_OPTIONS + IS2_HKL_L3_OPTIONS) -#define IS2_HKL_L3_TTL_GT0 1 -#define IS2_HKO_L3_TOS (IS2_HKO_L3_TTL_GT0 + IS2_HKL_L3_TTL_GT0) -#define IS2_HKL_L3_TOS 8 -#define IS2_HKO_L3_IP4_DIP (IS2_HKO_L3_TOS + IS2_HKL_L3_TOS) -#define IS2_HKL_L3_IP4_DIP 32 -#define IS2_HKO_L3_IP4_SIP (IS2_HKO_L3_IP4_DIP + IS2_HKL_L3_IP4_DIP) -#define IS2_HKL_L3_IP4_SIP 32 -#define IS2_HKO_DIP_EQ_SIP (IS2_HKO_L3_IP4_SIP + IS2_HKL_L3_IP4_SIP) -#define IS2_HKL_DIP_EQ_SIP 1 - -/* IS2 half key - IP4_TCP_UDP */ -#define IS2_HKO_IP4_TCP_UDP_TCP (IS2_HKO_DIP_EQ_SIP + IS2_HKL_DIP_EQ_SIP) -#define IS2_HKL_IP4_TCP_UDP_TCP 1 -#define IS2_HKO_IP4_TCP_UDP_L4_DPORT \ - (IS2_HKO_IP4_TCP_UDP_TCP + IS2_HKL_IP4_TCP_UDP_TCP) -#define IS2_HKL_IP4_TCP_UDP_L4_DPORT 16 -#define IS2_HKO_IP4_TCP_UDP_L4_SPORT \ - (IS2_HKO_IP4_TCP_UDP_L4_DPORT + IS2_HKL_IP4_TCP_UDP_L4_DPORT) -#define IS2_HKL_IP4_TCP_UDP_L4_SPORT 16 -#define IS2_HKO_IP4_TCP_UDP_L4_RNG \ - (IS2_HKO_IP4_TCP_UDP_L4_SPORT + IS2_HKL_IP4_TCP_UDP_L4_SPORT) -#define IS2_HKL_IP4_TCP_UDP_L4_RNG 8 -#define IS2_HKO_IP4_TCP_UDP_SPORT_EQ_DPORT \ - (IS2_HKO_IP4_TCP_UDP_L4_RNG + IS2_HKL_IP4_TCP_UDP_L4_RNG) -#define IS2_HKL_IP4_TCP_UDP_SPORT_EQ_DPORT 1 -#define IS2_HKO_IP4_TCP_UDP_SEQUENCE_EQ0 \ - (IS2_HKO_IP4_TCP_UDP_SPORT_EQ_DPORT + \ - IS2_HKL_IP4_TCP_UDP_SPORT_EQ_DPORT) -#define IS2_HKL_IP4_TCP_UDP_SEQUENCE_EQ0 1 -#define IS2_HKO_IP4_TCP_UDP_L4_FIN \ - (IS2_HKO_IP4_TCP_UDP_SEQUENCE_EQ0 + IS2_HKL_IP4_TCP_UDP_SEQUENCE_EQ0) -#define IS2_HKL_IP4_TCP_UDP_L4_FIN 1 -#define IS2_HKO_IP4_TCP_UDP_L4_SYN \ - (IS2_HKO_IP4_TCP_UDP_L4_FIN + IS2_HKL_IP4_TCP_UDP_L4_FIN) -#define IS2_HKL_IP4_TCP_UDP_L4_SYN 1 -#define IS2_HKO_IP4_TCP_UDP_L4_RST \ - (IS2_HKO_IP4_TCP_UDP_L4_SYN + IS2_HKL_IP4_TCP_UDP_L4_SYN) -#define IS2_HKL_IP4_TCP_UDP_L4_RST 1 -#define IS2_HKO_IP4_TCP_UDP_L4_PSH \ - (IS2_HKO_IP4_TCP_UDP_L4_RST + IS2_HKL_IP4_TCP_UDP_L4_RST) -#define IS2_HKL_IP4_TCP_UDP_L4_PSH 1 -#define IS2_HKO_IP4_TCP_UDP_L4_ACK \ - (IS2_HKO_IP4_TCP_UDP_L4_PSH + IS2_HKL_IP4_TCP_UDP_L4_PSH) -#define IS2_HKL_IP4_TCP_UDP_L4_ACK 1 -#define IS2_HKO_IP4_TCP_UDP_L4_URG \ - (IS2_HKO_IP4_TCP_UDP_L4_ACK + IS2_HKL_IP4_TCP_UDP_L4_ACK) -#define IS2_HKL_IP4_TCP_UDP_L4_URG 1 -#define IS2_HKO_IP4_TCP_UDP_L4_1588_DOM \ - (IS2_HKO_IP4_TCP_UDP_L4_URG + IS2_HKL_IP4_TCP_UDP_L4_URG) -#define IS2_HKL_IP4_TCP_UDP_L4_1588_DOM 8 -#define IS2_HKO_IP4_TCP_UDP_L4_1588_VER \ - (IS2_HKO_IP4_TCP_UDP_L4_1588_DOM + IS2_HKL_IP4_TCP_UDP_L4_1588_DOM) -#define IS2_HKL_IP4_TCP_UDP_L4_1588_VER 4 - -/* IS2 half key - IP4_OTHER */ -#define IS2_HKO_IP4_OTHER_L3_PROTO IS2_HKO_IP4_TCP_UDP_TCP -#define IS2_HKL_IP4_OTHER_L3_PROTO 8 -#define IS2_HKO_IP4_OTHER_L3_PAYLOAD \ - (IS2_HKO_IP4_OTHER_L3_PROTO + IS2_HKL_IP4_OTHER_L3_PROTO) -#define IS2_HKL_IP4_OTHER_L3_PAYLOAD 56 - -/* IS2 half key - IP6_STD */ -#define IS2_HKO_IP6_STD_L3_TTL_GT0 IS2_HKO_L2_DMAC -#define IS2_HKL_IP6_STD_L3_TTL_GT0 1 -#define IS2_HKO_IP6_STD_L3_IP6_SIP \ - (IS2_HKO_IP6_STD_L3_TTL_GT0 + IS2_HKL_IP6_STD_L3_TTL_GT0) -#define IS2_HKL_IP6_STD_L3_IP6_SIP 128 -#define IS2_HKO_IP6_STD_L3_PROTO \ - (IS2_HKO_IP6_STD_L3_IP6_SIP + IS2_HKL_IP6_STD_L3_IP6_SIP) -#define IS2_HKL_IP6_STD_L3_PROTO 8 - -/* IS2 half key - OAM */ -#define IS2_HKO_OAM_OAM_MEL_FLAGS IS2_HKO_MAC_ETYPE_ETYPE -#define IS2_HKL_OAM_OAM_MEL_FLAGS 7 -#define IS2_HKO_OAM_OAM_VER \ - (IS2_HKO_OAM_OAM_MEL_FLAGS + IS2_HKL_OAM_OAM_MEL_FLAGS) -#define IS2_HKL_OAM_OAM_VER 5 -#define IS2_HKO_OAM_OAM_OPCODE (IS2_HKO_OAM_OAM_VER + IS2_HKL_OAM_OAM_VER) -#define IS2_HKL_OAM_OAM_OPCODE 8 -#define IS2_HKO_OAM_OAM_FLAGS (IS2_HKO_OAM_OAM_OPCODE + IS2_HKL_OAM_OAM_OPCODE) -#define IS2_HKL_OAM_OAM_FLAGS 8 -#define IS2_HKO_OAM_OAM_MEPID (IS2_HKO_OAM_OAM_FLAGS + IS2_HKL_OAM_OAM_FLAGS) -#define IS2_HKL_OAM_OAM_MEPID 16 -#define IS2_HKO_OAM_OAM_CCM_CNTS_EQ0 \ - (IS2_HKO_OAM_OAM_MEPID + IS2_HKL_OAM_OAM_MEPID) -#define IS2_HKL_OAM_OAM_CCM_CNTS_EQ0 1 - -/* IS2 half key - SMAC_SIP6 */ -#define IS2_HKO_SMAC_SIP6_IGR_PORT IS2_HKL_TYPE -#define IS2_HKL_SMAC_SIP6_IGR_PORT VCAP_PORT_WIDTH -#define IS2_HKO_SMAC_SIP6_L2_SMAC \ - (IS2_HKO_SMAC_SIP6_IGR_PORT + IS2_HKL_SMAC_SIP6_IGR_PORT) -#define IS2_HKL_SMAC_SIP6_L2_SMAC 48 -#define IS2_HKO_SMAC_SIP6_L3_IP6_SIP \ - (IS2_HKO_SMAC_SIP6_L2_SMAC + IS2_HKL_SMAC_SIP6_L2_SMAC) -#define IS2_HKL_SMAC_SIP6_L3_IP6_SIP 128 - -/* IS2 full key - common */ -#define IS2_FKO_TYPE 0 -#define IS2_FKL_TYPE 2 -#define IS2_FKO_FIRST (IS2_FKO_TYPE + IS2_FKL_TYPE) -#define IS2_FKL_FIRST 1 -#define IS2_FKO_PAG (IS2_FKO_FIRST + IS2_FKL_FIRST) -#define IS2_FKL_PAG 8 -#define IS2_FKO_IGR_PORT_MASK (IS2_FKO_PAG + IS2_FKL_PAG) -#define IS2_FKL_IGR_PORT_MASK (VCAP_PORT_CNT + 1) -#define IS2_FKO_SERVICE_FRM (IS2_FKO_IGR_PORT_MASK + IS2_FKL_IGR_PORT_MASK) -#define IS2_FKL_SERVICE_FRM 1 -#define IS2_FKO_HOST_MATCH (IS2_FKO_SERVICE_FRM + IS2_FKL_SERVICE_FRM) -#define IS2_FKL_HOST_MATCH 1 -#define IS2_FKO_L2_MC (IS2_FKO_HOST_MATCH + IS2_FKL_HOST_MATCH) -#define IS2_FKL_L2_MC 1 -#define IS2_FKO_L2_BC (IS2_FKO_L2_MC + IS2_FKL_L2_MC) -#define IS2_FKL_L2_BC 1 -#define IS2_FKO_VLAN_TAGGED (IS2_FKO_L2_BC + IS2_FKL_L2_BC) -#define IS2_FKL_VLAN_TAGGED 1 -#define IS2_FKO_VID (IS2_FKO_VLAN_TAGGED + IS2_FKL_VLAN_TAGGED) -#define IS2_FKL_VID 12 -#define IS2_FKO_DEI (IS2_FKO_VID + IS2_FKL_VID) -#define IS2_FKL_DEI 1 -#define IS2_FKO_PCP (IS2_FKO_DEI + IS2_FKL_DEI) -#define IS2_FKL_PCP 3 - -/* IS2 full key - IP6_TCP_UDP/IP6_OTHER common */ -#define IS2_FKO_L3_TTL_GT0 (IS2_FKO_PCP + IS2_FKL_PCP) -#define IS2_FKL_L3_TTL_GT0 1 -#define IS2_FKO_L3_TOS (IS2_FKO_L3_TTL_GT0 + IS2_FKL_L3_TTL_GT0) -#define IS2_FKL_L3_TOS 8 -#define IS2_FKO_L3_IP6_DIP (IS2_FKO_L3_TOS + IS2_FKL_L3_TOS) -#define IS2_FKL_L3_IP6_DIP 128 -#define IS2_FKO_L3_IP6_SIP (IS2_FKO_L3_IP6_DIP + IS2_FKL_L3_IP6_DIP) -#define IS2_FKL_L3_IP6_SIP 128 -#define IS2_FKO_DIP_EQ_SIP (IS2_FKO_L3_IP6_SIP + IS2_FKL_L3_IP6_SIP) -#define IS2_FKL_DIP_EQ_SIP 1 - -/* IS2 full key - IP6_TCP_UDP */ -#define IS2_FKO_IP6_TCP_UDP_TCP (IS2_FKO_DIP_EQ_SIP + IS2_FKL_DIP_EQ_SIP) -#define IS2_FKL_IP6_TCP_UDP_TCP 1 -#define IS2_FKO_IP6_TCP_UDP_L4_DPORT \ - (IS2_FKO_IP6_TCP_UDP_TCP + IS2_FKL_IP6_TCP_UDP_TCP) -#define IS2_FKL_IP6_TCP_UDP_L4_DPORT 16 -#define IS2_FKO_IP6_TCP_UDP_L4_SPORT \ - (IS2_FKO_IP6_TCP_UDP_L4_DPORT + IS2_FKL_IP6_TCP_UDP_L4_DPORT) -#define IS2_FKL_IP6_TCP_UDP_L4_SPORT 16 -#define IS2_FKO_IP6_TCP_UDP_L4_RNG \ - (IS2_FKO_IP6_TCP_UDP_L4_SPORT + IS2_FKL_IP6_TCP_UDP_L4_SPORT) -#define IS2_FKL_IP6_TCP_UDP_L4_RNG 8 -#define IS2_FKO_IP6_TCP_UDP_SPORT_EQ_DPORT \ - (IS2_FKO_IP6_TCP_UDP_L4_RNG + IS2_FKL_IP6_TCP_UDP_L4_RNG) -#define IS2_FKL_IP6_TCP_UDP_SPORT_EQ_DPORT 1 -#define IS2_FKO_IP6_TCP_UDP_SEQUENCE_EQ0 \ - (IS2_FKO_IP6_TCP_UDP_SPORT_EQ_DPORT + \ - IS2_FKL_IP6_TCP_UDP_SPORT_EQ_DPORT) -#define IS2_FKL_IP6_TCP_UDP_SEQUENCE_EQ0 1 -#define IS2_FKO_IP6_TCP_UDP_L4_FIN \ - (IS2_FKO_IP6_TCP_UDP_SEQUENCE_EQ0 + IS2_FKL_IP6_TCP_UDP_SEQUENCE_EQ0) -#define IS2_FKL_IP6_TCP_UDP_L4_FIN 1 -#define IS2_FKO_IP6_TCP_UDP_L4_SYN \ - (IS2_FKO_IP6_TCP_UDP_L4_FIN + IS2_FKL_IP6_TCP_UDP_L4_FIN) -#define IS2_FKL_IP6_TCP_UDP_L4_SYN 1 -#define IS2_FKO_IP6_TCP_UDP_L4_RST \ - (IS2_FKO_IP6_TCP_UDP_L4_SYN + IS2_FKL_IP6_TCP_UDP_L4_SYN) -#define IS2_FKL_IP6_TCP_UDP_L4_RST 1 -#define IS2_FKO_IP6_TCP_UDP_L4_PSH \ - (IS2_FKO_IP6_TCP_UDP_L4_RST + IS2_FKL_IP6_TCP_UDP_L4_RST) -#define IS2_FKL_IP6_TCP_UDP_L4_PSH 1 -#define IS2_FKO_IP6_TCP_UDP_L4_ACK \ - (IS2_FKO_IP6_TCP_UDP_L4_PSH + IS2_FKL_IP6_TCP_UDP_L4_PSH) -#define IS2_FKL_IP6_TCP_UDP_L4_ACK 1 -#define IS2_FKO_IP6_TCP_UDP_L4_URG \ - (IS2_FKO_IP6_TCP_UDP_L4_ACK + IS2_FKL_IP6_TCP_UDP_L4_ACK) -#define IS2_FKL_IP6_TCP_UDP_L4_URG 1 -#define IS2_FKO_IP6_TCP_UDP_L4_1588_DOM \ - (IS2_FKO_IP6_TCP_UDP_L4_URG + IS2_FKL_IP6_TCP_UDP_L4_URG) -#define IS2_FKL_IP6_TCP_UDP_L4_1588_DOM 8 -#define IS2_FKO_IP6_TCP_UDP_L4_1588_VER \ - (IS2_FKO_IP6_TCP_UDP_L4_1588_DOM + IS2_FKL_IP6_TCP_UDP_L4_1588_DOM) -#define IS2_FKL_IP6_TCP_UDP_L4_1588_VER 4 - -/* IS2 full key - IP6_OTHER */ -#define IS2_FKO_IP6_OTHER_L3_PROTO IS2_FKO_IP6_TCP_UDP_TCP -#define IS2_FKL_IP6_OTHER_L3_PROTO 8 -#define IS2_FKO_IP6_OTHER_L3_PAYLOAD \ - (IS2_FKO_IP6_OTHER_L3_PROTO + IS2_FKL_IP6_OTHER_L3_PROTO) -#define IS2_FKL_IP6_OTHER_L3_PAYLOAD 56 - -/* IS2 full key - CUSTOM */ -#define IS2_FKO_CUSTOM_CUSTOM_TYPE IS2_FKO_L3_TTL_GT0 -#define IS2_FKL_CUSTOM_CUSTOM_TYPE 1 -#define IS2_FKO_CUSTOM_CUSTOM \ - (IS2_FKO_CUSTOM_CUSTOM_TYPE + IS2_FKL_CUSTOM_CUSTOM_TYPE) -#define IS2_FKL_CUSTOM_CUSTOM 320 - -/* IS2 action - BASE_TYPE */ -#define IS2_AO_HIT_ME_ONCE 0 -#define IS2_AL_HIT_ME_ONCE 1 -#define IS2_AO_CPU_COPY_ENA (IS2_AO_HIT_ME_ONCE + IS2_AL_HIT_ME_ONCE) -#define IS2_AL_CPU_COPY_ENA 1 -#define IS2_AO_CPU_QU_NUM (IS2_AO_CPU_COPY_ENA + IS2_AL_CPU_COPY_ENA) -#define IS2_AL_CPU_QU_NUM 3 -#define IS2_AO_MASK_MODE (IS2_AO_CPU_QU_NUM + IS2_AL_CPU_QU_NUM) -#define IS2_AL_MASK_MODE 2 -#define IS2_AO_MIRROR_ENA (IS2_AO_MASK_MODE + IS2_AL_MASK_MODE) -#define IS2_AL_MIRROR_ENA 1 -#define IS2_AO_LRN_DIS (IS2_AO_MIRROR_ENA + IS2_AL_MIRROR_ENA) -#define IS2_AL_LRN_DIS 1 -#define IS2_AO_POLICE_ENA (IS2_AO_LRN_DIS + IS2_AL_LRN_DIS) -#define IS2_AL_POLICE_ENA 1 -#define IS2_AO_POLICE_IDX (IS2_AO_POLICE_ENA + IS2_AL_POLICE_ENA) -#define IS2_AL_POLICE_IDX 9 -#define IS2_AO_POLICE_VCAP_ONLY (IS2_AO_POLICE_IDX + IS2_AL_POLICE_IDX) -#define IS2_AL_POLICE_VCAP_ONLY 1 -#define IS2_AO_PORT_MASK (IS2_AO_POLICE_VCAP_ONLY + IS2_AL_POLICE_VCAP_ONLY) -#define IS2_AL_PORT_MASK VCAP_PORT_CNT -#define IS2_AO_REW_OP (IS2_AO_PORT_MASK + IS2_AL_PORT_MASK) -#define IS2_AL_REW_OP 9 -#define IS2_AO_LM_CNT_DIS (IS2_AO_REW_OP + IS2_AL_REW_OP) -#define IS2_AL_LM_CNT_DIS 1 -#define IS2_AO_ISDX_ENA \ - (IS2_AO_LM_CNT_DIS + IS2_AL_LM_CNT_DIS + 1) /* Reserved bit */ -#define IS2_AL_ISDX_ENA 1 -#define IS2_AO_ACL_ID (IS2_AO_ISDX_ENA + IS2_AL_ISDX_ENA) -#define IS2_AL_ACL_ID 6 - -/* IS2 action - SMAC_SIP */ -#define IS2_AO_SMAC_SIP_CPU_COPY_ENA 0 -#define IS2_AL_SMAC_SIP_CPU_COPY_ENA 1 -#define IS2_AO_SMAC_SIP_CPU_QU_NUM 1 -#define IS2_AL_SMAC_SIP_CPU_QU_NUM 3 -#define IS2_AO_SMAC_SIP_FWD_KILL_ENA 4 -#define IS2_AL_SMAC_SIP_FWD_KILL_ENA 1 -#define IS2_AO_SMAC_SIP_HOST_MATCH 5 -#define IS2_AL_SMAC_SIP_HOST_MATCH 1 - -#endif /* _OCELOT_VCAP_H_ */ |