diff options
author | 2020-08-22 12:34:14 +0000 | |
---|---|---|
committer | 2020-08-22 12:34:14 +0000 | |
commit | 41cd246c3176c05d48567a93311d8e632b140b49 (patch) | |
tree | 3d7bb0ff6f5135f779cd7265718fd8765e4b6f2c | |
parent | Correct oversize rxq initialization in the classifier. (diff) | |
download | wireguard-openbsd-41cd246c3176c05d48567a93311d8e632b140b49.tar.xz wireguard-openbsd-41cd246c3176c05d48567a93311d8e632b140b49.zip |
Rework unicast/multicast configuration. Keep note that this only changes
the code configuring the parser, we do not yet add the proper multicast
filters.
-rw-r--r-- | sys/dev/fdt/if_mvpp.c | 167 | ||||
-rw-r--r-- | sys/dev/fdt/if_mvppreg.h | 48 |
2 files changed, 93 insertions, 122 deletions
diff --git a/sys/dev/fdt/if_mvpp.c b/sys/dev/fdt/if_mvpp.c index fadd5f32a51..3b84c1feeac 100644 --- a/sys/dev/fdt/if_mvpp.c +++ b/sys/dev/fdt/if_mvpp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mvpp.c,v 1.26 2020/08/22 12:31:48 patrick Exp $ */ +/* $OpenBSD: if_mvpp.c,v 1.27 2020/08/22 12:34:14 patrick Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org> * Copyright (c) 2017, 2020 Patrick Wildt <patrick@blueri.se> @@ -390,8 +390,7 @@ int mvpp2_prs_hw_read(struct mvpp2_softc *, struct mvpp2_prs_entry *, int); int mvpp2_prs_flow_find(struct mvpp2_softc *, int); int mvpp2_prs_tcam_first_free(struct mvpp2_softc *, uint8_t, uint8_t); void mvpp2_prs_mac_drop_all_set(struct mvpp2_softc *, uint32_t, int); -void mvpp2_prs_mac_promisc_set(struct mvpp2_softc *, uint32_t, int); -void mvpp2_prs_mac_multi_set(struct mvpp2_softc *, uint32_t, uint32_t, int); +void mvpp2_prs_mac_promisc_set(struct mvpp2_softc *, uint32_t, int, int); void mvpp2_prs_dsa_tag_set(struct mvpp2_softc *, uint32_t, int, int, int); void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2_softc *, uint32_t, int, int, int); @@ -407,11 +406,11 @@ int mvpp2_prs_ip4_proto(struct mvpp2_softc *, uint16_t, uint32_t, uint32_t); int mvpp2_prs_ip4_cast(struct mvpp2_softc *, uint16_t); int mvpp2_prs_ip6_proto(struct mvpp2_softc *, uint16_t, uint32_t, uint32_t); int mvpp2_prs_ip6_cast(struct mvpp2_softc *, uint16_t); -struct mvpp2_prs_entry *mvpp2_prs_mac_da_range_find(struct mvpp2_softc *, int, - const uint8_t *, uint8_t *, int); +int mvpp2_prs_mac_da_range_find(struct mvpp2_softc *, int, const uint8_t *, + uint8_t *, int); int mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *, const uint8_t *, uint8_t *); -int mvpp2_prs_mac_da_accept(struct mvpp2_softc *, int, const uint8_t *, int); +int mvpp2_prs_mac_da_accept(struct mvpp2_port *, const uint8_t *, int); int mvpp2_prs_tag_mode_set(struct mvpp2_softc *, int, int); int mvpp2_prs_def_flow(struct mvpp2_port *); void mvpp2_cls_flow_write(struct mvpp2_softc *, struct mvpp2_cls_flow_entry *); @@ -809,9 +808,8 @@ mvpp2_prs_mac_init(struct mvpp2_softc *sc) mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); mvpp2_prs_hw_write(sc, &pe); mvpp2_prs_mac_drop_all_set(sc, 0, 0); - mvpp2_prs_mac_promisc_set(sc, 0, 0); - mvpp2_prs_mac_multi_set(sc, MVPP2_PE_MAC_MC_ALL, 0, 0); - mvpp2_prs_mac_multi_set(sc, MVPP2_PE_MAC_MC_IP6, 0, 0); + mvpp2_prs_mac_promisc_set(sc, 0, MVPP2_PRS_L2_UNI_CAST, 0); + mvpp2_prs_mac_promisc_set(sc, 0, MVPP2_PRS_L2_MULTI_CAST, 0); } void @@ -2186,10 +2184,8 @@ mvpp2_up(struct mvpp2_port *sc) int i; memcpy(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN); - mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, etherbroadcastaddr, 1); - mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 1); - /* FIXME: not promisc!!! */ - mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, 1); + mvpp2_prs_mac_da_accept(sc, etherbroadcastaddr, 1); + mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 1); mvpp2_prs_tag_mode_set(sc->sc, sc->sc_id, MVPP2_TAG_TYPE_MH); mvpp2_prs_def_flow(sc); @@ -2708,7 +2704,7 @@ mvpp2_down(struct mvpp2_port *sc) for (i = 0; i < sc->sc_nrxq; i++) mvpp2_rxq_hw_deinit(sc, &sc->sc_rxqs[i]); - mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 0); + mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 0); } void @@ -2819,9 +2815,11 @@ mvpp2_iff(struct mvpp2_port *sc) { /* FIXME: multicast handling */ - mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 0); - memcpy(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN); - mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 1); + if (memcmp(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN) != 0) { + mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 0); + memcpy(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN); + mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 1); + } } struct mvpp2_dmamem * @@ -3567,47 +3565,34 @@ mvpp2_prs_mac_drop_all_set(struct mvpp2_softc *sc, uint32_t port, int add) } void -mvpp2_prs_mac_promisc_set(struct mvpp2_softc *sc, uint32_t port, int add) +mvpp2_prs_mac_promisc_set(struct mvpp2_softc *sc, uint32_t port, int l2_cast, + int add) { struct mvpp2_prs_entry pe; + uint8_t cast_match; + uint32_t ri; + int tid; - if (sc->sc_prs_shadow[MVPP2_PE_MAC_PROMISCUOUS].valid) { - mvpp2_prs_hw_read(sc, &pe, MVPP2_PE_MAC_PROMISCUOUS); + if (l2_cast == MVPP2_PRS_L2_UNI_CAST) { + cast_match = MVPP2_PRS_UCAST_VAL; + tid = MVPP2_PE_MAC_UC_PROMISCUOUS; + ri = MVPP2_PRS_RI_L2_UCAST; } else { - memset(&pe, 0, sizeof(pe)); - mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); - pe.index = MVPP2_PE_MAC_PROMISCUOUS; - mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA); - mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_UCAST, - MVPP2_PRS_RI_L2_CAST_MASK); - mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN, - MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); - mvpp2_prs_tcam_port_map_set(&pe, 0); - mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); + cast_match = MVPP2_PRS_MCAST_VAL; + tid = MVPP2_PE_MAC_MC_PROMISCUOUS; + ri = MVPP2_PRS_RI_L2_MCAST; } - mvpp2_prs_tcam_port_set(&pe, port, add); - mvpp2_prs_hw_write(sc, &pe); -} - -void -mvpp2_prs_mac_multi_set(struct mvpp2_softc *sc, uint32_t port, uint32_t index, int add) -{ - struct mvpp2_prs_entry pe; - uint8_t da_mc; - - da_mc = (index == MVPP2_PE_MAC_MC_ALL) ? 0x01 : 0x33; - - if (sc->sc_prs_shadow[index].valid) { - mvpp2_prs_hw_read(sc, &pe, index); + if (sc->sc_prs_shadow[tid].valid) { + mvpp2_prs_hw_read(sc, &pe, tid); } else { memset(&pe, 0, sizeof(pe)); mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); - pe.index = index; + pe.index = tid; mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA); - mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_MCAST, - MVPP2_PRS_RI_L2_CAST_MASK); - mvpp2_prs_tcam_data_byte_set(&pe, 0, da_mc, 0xff); + mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK); + mvpp2_prs_tcam_data_byte_set(&pe, 0, cast_match, + MVPP2_PRS_CAST_MASK); mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); mvpp2_prs_tcam_port_map_set(&pe, 0); @@ -4106,18 +4091,13 @@ mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *pe, const uint8_t *da, return 1; } -struct mvpp2_prs_entry * +int mvpp2_prs_mac_da_range_find(struct mvpp2_softc *sc, int pmap, const uint8_t *da, uint8_t *mask, int udf_type) { - struct mvpp2_prs_entry *pe; + struct mvpp2_prs_entry pe; int tid; - pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); - if (pe == NULL) - return NULL; - - mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= MVPP2_PE_LAST_FREE_TID; tid++) { uint32_t entry_pmap; @@ -4127,73 +4107,63 @@ mvpp2_prs_mac_da_range_find(struct mvpp2_softc *sc, int pmap, const uint8_t *da, (sc->sc_prs_shadow[tid].udf != udf_type)) continue; - mvpp2_prs_hw_read(sc, pe, tid); - entry_pmap = mvpp2_prs_tcam_port_map_get(pe); - if (mvpp2_prs_mac_range_equals(pe, da, mask) && + mvpp2_prs_hw_read(sc, &pe, tid); + entry_pmap = mvpp2_prs_tcam_port_map_get(&pe); + if (mvpp2_prs_mac_range_equals(&pe, da, mask) && entry_pmap == pmap) - return pe; + return tid; } - free(pe, M_TEMP, sizeof(*pe)); - return NULL; + return -1; } int -mvpp2_prs_mac_da_accept(struct mvpp2_softc *sc, int port_id, const uint8_t *da, - int add) +mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const uint8_t *da, int add) { - struct mvpp2_prs_entry *pe; + struct mvpp2_softc *sc = port->sc; + struct mvpp2_prs_entry pe; uint32_t pmap, len, ri; uint8_t mask[ETHER_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; int tid; - pe = mvpp2_prs_mac_da_range_find(sc, (1 << port_id), da, mask, + memset(&pe, 0, sizeof(pe)); + + tid = mvpp2_prs_mac_da_range_find(sc, BIT(port->sc_id), da, mask, MVPP2_PRS_UDF_MAC_DEF); - if (pe == NULL) { + if (tid < 0) { if (!add) return 0; - for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= - MVPP2_PE_LAST_FREE_TID; tid++) { - if (sc->sc_prs_shadow[tid].valid && - (sc->sc_prs_shadow[tid].lu == MVPP2_PRS_LU_MAC) && - (sc->sc_prs_shadow[tid].udf == MVPP2_PRS_UDF_MAC_RANGE)) - break; - } - - tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, tid - 1); + tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, + MVPP2_PE_LAST_FREE_TID); if (tid < 0) return tid; - pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); - if (pe == NULL) - return ENOMEM; - - mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); - pe->index = tid; - mvpp2_prs_tcam_port_map_set(pe, 0); + pe.index = tid; + mvpp2_prs_tcam_port_map_set(&pe, 0); + } else { + mvpp2_prs_hw_read(sc, &pe, tid); } - mvpp2_prs_tcam_port_set(pe, port_id, add); + mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); + + mvpp2_prs_tcam_port_set(&pe, port->sc_id, add); /* invalidate the entry if no ports are left enabled */ - pmap = mvpp2_prs_tcam_port_map_get(pe); + pmap = mvpp2_prs_tcam_port_map_get(&pe); if (pmap == 0) { - if (add) { - free(pe, M_TEMP, sizeof(*pe)); + if (add) return -1; - } - mvpp2_prs_hw_inv(sc, pe->index); - sc->sc_prs_shadow[pe->index].valid = 0; - free(pe, M_TEMP, sizeof(*pe)); + mvpp2_prs_hw_inv(sc, pe.index); + sc->sc_prs_shadow[pe.index].valid = 0; return 0; } - mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_DSA); + mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA); len = ETHER_ADDR_LEN; while (len--) - mvpp2_prs_tcam_data_byte_set(pe, len, da[len], 0xff); + mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff); if (ETHER_IS_BROADCAST(da)) ri = MVPP2_PRS_RI_L2_BCAST; @@ -4202,17 +4172,16 @@ mvpp2_prs_mac_da_accept(struct mvpp2_softc *sc, int port_id, const uint8_t *da, else ri = MVPP2_PRS_RI_L2_UCAST | MVPP2_PRS_RI_MAC_ME_MASK; - mvpp2_prs_sram_ri_update(pe, ri, MVPP2_PRS_RI_L2_CAST_MASK | + mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK | MVPP2_PRS_RI_MAC_ME_MASK); - mvpp2_prs_shadow_ri_set(sc, pe->index, ri, MVPP2_PRS_RI_L2_CAST_MASK | + mvpp2_prs_shadow_ri_set(sc, pe.index, ri, MVPP2_PRS_RI_L2_CAST_MASK | MVPP2_PRS_RI_MAC_ME_MASK); - mvpp2_prs_sram_shift_set(pe, 2 * ETHER_ADDR_LEN, + mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); - sc->sc_prs_shadow[pe->index].udf = MVPP2_PRS_UDF_MAC_DEF; - mvpp2_prs_shadow_set(sc, pe->index, MVPP2_PRS_LU_MAC); - mvpp2_prs_hw_write(sc, pe); + sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_MAC_DEF; + mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); + mvpp2_prs_hw_write(sc, &pe); - free(pe, M_TEMP, sizeof(*pe)); return 0; } diff --git a/sys/dev/fdt/if_mvppreg.h b/sys/dev/fdt/if_mvppreg.h index 9da14685ef6..134e898d014 100644 --- a/sys/dev/fdt/if_mvppreg.h +++ b/sys/dev/fdt/if_mvppreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mvppreg.h,v 1.12 2020/08/17 22:14:51 patrick Exp $ */ +/* $OpenBSD: if_mvppreg.h,v 1.13 2020/08/22 12:34:14 patrick Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org> * Copyright (c) 2017, 2020 Patrick Wildt <patrick@blueri.se> @@ -985,6 +985,9 @@ enum mvpp2_prs_l3_cast { #define MVPP2_PRS_TCAM_PROTO_MASK 0xff #define MVPP2_PRS_TCAM_PROTO_MASK_L 0x3f #define MVPP2_PRS_DBL_VLANS_MAX 100 +#define MVPP2_PRS_CAST_MASK BIT(0) +#define MVPP2_PRS_MCAST_VAL BIT(0) +#define MVPP2_PRS_UCAST_VAL 0x0 /* * Tcam structure: @@ -1009,28 +1012,27 @@ enum mvpp2_prs_l3_cast { #define MVPP2_PE_FIRST_FREE_TID 1 #define MVPP2_PE_LAST_FREE_TID (MVPP2_PRS_TCAM_SRAM_SIZE - 31) #define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30) -#define MVPP2_PE_MAC_MC_IP6 (MVPP2_PRS_TCAM_SRAM_SIZE - 29) -#define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28) -#define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 27) -#define MVPP2_PE_LAST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 26) -#define MVPP2_PE_FIRST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 19) -#define MVPP2_PE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 18) -#define MVPP2_PE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 17) -#define MVPP2_PE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 16) -#define MVPP2_PE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 15) -#define MVPP2_PE_ETYPE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 14) -#define MVPP2_PE_ETYPE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 13) -#define MVPP2_PE_ETYPE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 12) -#define MVPP2_PE_ETYPE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 11) -#define MVPP2_PE_MH_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 10) -#define MVPP2_PE_DSA_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 9) -#define MVPP2_PE_IP6_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 8) -#define MVPP2_PE_IP4_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 7) -#define MVPP2_PE_ETH_TYPE_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 6) -#define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 5) -#define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 4) -#define MVPP2_PE_MAC_MC_ALL (MVPP2_PRS_TCAM_SRAM_SIZE - 3) -#define MVPP2_PE_MAC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) +#define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 29) +#define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28) +#define MVPP2_PE_LAST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 27) +#define MVPP2_PE_FIRST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 22) +#define MVPP2_PE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 21) +#define MVPP2_PE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 20) +#define MVPP2_PE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 19) +#define MVPP2_PE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 18) +#define MVPP2_PE_ETYPE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 17) +#define MVPP2_PE_ETYPE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 16) +#define MVPP2_PE_ETYPE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 15) +#define MVPP2_PE_ETYPE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 14) +#define MVPP2_PE_MH_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 13) +#define MVPP2_PE_DSA_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 12) +#define MVPP2_PE_IP6_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 11) +#define MVPP2_PE_IP4_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 10) +#define MVPP2_PE_ETH_TYPE_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 9) +#define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 6) +#define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 5) +#define MVPP2_PE_MAC_MC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 3) +#define MVPP2_PE_MAC_UC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) #define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1) /* |