1 /* $OpenBSD: cn30xxpip.c,v 1.11 2022/12/28 01:39:21 yasuoka Exp $ */ 2 3 /* 4 * Copyright (c) 2007 Internet Initiative Japan, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/malloc.h> 32 #include <sys/socket.h> 33 #include <sys/syslog.h> 34 #include <sys/time.h> 35 #include <net/if.h> 36 #include <net/if_var.h> 37 38 #include <machine/octeonvar.h> 39 40 #include <octeon/dev/cn30xxgmxreg.h> 41 #include <octeon/dev/cn30xxpipreg.h> 42 #include <octeon/dev/cn30xxpipvar.h> 43 44 /* XXX */ 45 void 46 cn30xxpip_init(struct cn30xxpip_attach_args *aa, 47 struct cn30xxpip_softc **rsc) 48 { 49 struct cn30xxpip_softc *sc; 50 int status; 51 52 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); 53 if (sc == NULL) 54 panic("can't allocate memory: %s", __func__); 55 56 sc->sc_port = aa->aa_port; 57 sc->sc_regt = aa->aa_regt; 58 sc->sc_tag_type = aa->aa_tag_type; 59 sc->sc_receive_group = aa->aa_receive_group; 60 sc->sc_ip_offset = aa->aa_ip_offset; 61 62 status = bus_space_map(sc->sc_regt, PIP_BASE, PIP_SIZE, 0, 63 &sc->sc_regh); 64 if (status != 0) 65 panic("can't map %s space", "pip register"); 66 67 status = bus_space_subregion(sc->sc_regt, sc->sc_regh, 68 PIP_STAT_BASE(sc->sc_port), PIP_STAT_SIZE, &sc->sc_regh_stat); 69 if (status != 0) 70 panic("can't map stat register space"); 71 72 *rsc = sc; 73 } 74 75 #define _PIP_RD8(sc, off) \ 76 bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off)) 77 #define _PIP_WR8(sc, off, v) \ 78 bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v)) 79 80 #define _PIP_STAT_RD8(sc, off) \ 81 bus_space_read_8((sc)->sc_regt, (sc)->sc_regh_stat, (off)) 82 #define _PIP_STAT_WR8(sc, off, v) \ 83 bus_space_write_8((sc)->sc_regt, (sc)->sc_regh_stat, (off), (v)) 84 85 int 86 cn30xxpip_port_config(struct cn30xxpip_softc *sc) 87 { 88 uint64_t prt_cfg; 89 uint64_t prt_tag; 90 uint64_t ip_offset; 91 92 /* 93 * Process the headers and place the IP header in the work queue 94 */ 95 prt_cfg = 0; 96 /* RAWDRP=0; don't allow raw packet drop */ 97 /* TAGINC=0 */ 98 /* DYN_RS=0; disable dynamic short buffering */ 99 /* INST_HDR=0 */ 100 /* GRP_WAT=0 */ 101 SET(prt_cfg, (sc->sc_port << 24) & PIP_PRT_CFGN_QOS); 102 /* QOS_WAT=0 */ 103 /* SPARE=0 */ 104 /* QOS_DIFF=0 */ 105 /* QOS_VLAN=0 */ 106 SET(prt_cfg, PIP_PRT_CFGN_CRC_EN); 107 SET(prt_cfg, (PIP_PORT_CFG_MODE_L2) & PIP_PRT_CFGN_MODE); 108 /* SKIP=0 */ 109 110 prt_tag = 0; 111 SET(prt_tag, PIP_PRT_TAGN_INC_PRT); 112 CLR(prt_tag, PIP_PRT_TAGN_IP6_DPRT); 113 CLR(prt_tag, PIP_PRT_TAGN_IP4_DPRT); 114 CLR(prt_tag, PIP_PRT_TAGN_IP6_SPRT); 115 CLR(prt_tag, PIP_PRT_TAGN_IP4_SPRT); 116 CLR(prt_tag, PIP_PRT_TAGN_IP6_NXTH); 117 CLR(prt_tag, PIP_PRT_TAGN_IP4_PCTL); 118 CLR(prt_tag, PIP_PRT_TAGN_IP6_DST); 119 CLR(prt_tag, PIP_PRT_TAGN_IP4_SRC); 120 CLR(prt_tag, PIP_PRT_TAGN_IP6_SRC); 121 CLR(prt_tag, PIP_PRT_TAGN_IP4_DST); 122 SET(prt_tag, PIP_PRT_TAGN_TCP6_TAG_ORDERED); 123 SET(prt_tag, PIP_PRT_TAGN_TCP4_TAG_ORDERED); 124 SET(prt_tag, PIP_PRT_TAGN_IP6_TAG_ORDERED); 125 SET(prt_tag, PIP_PRT_TAGN_IP4_TAG_ORDERED); 126 SET(prt_tag, PIP_PRT_TAGN_NON_TAG_ORDERED); 127 SET(prt_tag, sc->sc_receive_group & PIP_PRT_TAGN_GRP); 128 129 ip_offset = 0; 130 SET(ip_offset, (sc->sc_ip_offset / 8) & PIP_IP_OFFSET_MASK_OFFSET); 131 132 _PIP_WR8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port), prt_cfg); 133 _PIP_WR8(sc, PIP_PRT_TAG0_OFFSET + (8 * sc->sc_port), prt_tag); 134 _PIP_WR8(sc, PIP_IP_OFFSET_OFFSET, ip_offset); 135 136 return 0; 137 } 138 139 void 140 cn30xxpip_prt_cfg_enable(struct cn30xxpip_softc *sc, uint64_t prt_cfg, 141 int enable) 142 { 143 uint64_t tmp; 144 145 tmp = _PIP_RD8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port)); 146 if (enable) 147 tmp |= prt_cfg; 148 else 149 tmp &= ~prt_cfg; 150 _PIP_WR8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port), tmp); 151 } 152 153 void 154 cn30xxpip_stats_init(struct cn30xxpip_softc *sc) 155 { 156 /* XXX */ 157 _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, 1); 158 159 _PIP_STAT_WR8(sc, PIP_STAT0_PRT, 0); 160 _PIP_STAT_WR8(sc, PIP_STAT1_PRT, 0); 161 _PIP_STAT_WR8(sc, PIP_STAT2_PRT, 0); 162 _PIP_STAT_WR8(sc, PIP_STAT3_PRT, 0); 163 _PIP_STAT_WR8(sc, PIP_STAT4_PRT, 0); 164 _PIP_STAT_WR8(sc, PIP_STAT5_PRT, 0); 165 _PIP_STAT_WR8(sc, PIP_STAT6_PRT, 0); 166 _PIP_STAT_WR8(sc, PIP_STAT7_PRT, 0); 167 _PIP_STAT_WR8(sc, PIP_STAT8_PRT, 0); 168 _PIP_STAT_WR8(sc, PIP_STAT9_PRT, 0); 169 } 170 171 #if NKSTAT > 0 172 void 173 cn30xxpip_kstat_read(struct cn30xxpip_softc *sc, struct kstat_kv *kvs) 174 { 175 uint64_t val; 176 177 val = _PIP_STAT_RD8(sc, PIP_STAT0_PRT); 178 kstat_kv_u64(&kvs[cnmac_stat_rx_qdpo]) += (uint32_t)val; 179 kstat_kv_u64(&kvs[cnmac_stat_rx_qdpp]) += val >> 32; 180 181 val = _PIP_STAT_RD8(sc, PIP_STAT1_PRT); 182 kstat_kv_u64(&kvs[cnmac_stat_rx_toto_pip]) += (uint32_t)val; 183 184 val = _PIP_STAT_RD8(sc, PIP_STAT2_PRT); 185 kstat_kv_u64(&kvs[cnmac_stat_rx_raw]) += (uint32_t)val; 186 kstat_kv_u64(&kvs[cnmac_stat_rx_totp_pip]) += val >> 32; 187 188 val = _PIP_STAT_RD8(sc, PIP_STAT3_PRT); 189 kstat_kv_u64(&kvs[cnmac_stat_rx_mcast]) += (uint32_t)val; 190 kstat_kv_u64(&kvs[cnmac_stat_rx_bcast]) += val >> 32; 191 192 val = _PIP_STAT_RD8(sc, PIP_STAT4_PRT); 193 kstat_kv_u64(&kvs[cnmac_stat_rx_h64]) += (uint32_t)val; 194 kstat_kv_u64(&kvs[cnmac_stat_rx_h127]) += val >> 32; 195 196 val = _PIP_STAT_RD8(sc, PIP_STAT5_PRT); 197 kstat_kv_u64(&kvs[cnmac_stat_rx_h255]) += (uint32_t)val; 198 kstat_kv_u64(&kvs[cnmac_stat_rx_h511]) += val >> 32; 199 200 val = _PIP_STAT_RD8(sc, PIP_STAT6_PRT); 201 kstat_kv_u64(&kvs[cnmac_stat_rx_h1023]) += (uint32_t)val; 202 kstat_kv_u64(&kvs[cnmac_stat_rx_h1518]) += val >> 32; 203 204 val = _PIP_STAT_RD8(sc, PIP_STAT7_PRT); 205 kstat_kv_u64(&kvs[cnmac_stat_rx_hmax]) += (uint32_t)val; 206 kstat_kv_u64(&kvs[cnmac_stat_rx_fcs]) += val >> 32; 207 208 val = _PIP_STAT_RD8(sc, PIP_STAT8_PRT); 209 kstat_kv_u64(&kvs[cnmac_stat_rx_undersz]) += (uint32_t)val; 210 kstat_kv_u64(&kvs[cnmac_stat_rx_frag]) += val >> 32; 211 212 val = _PIP_STAT_RD8(sc, PIP_STAT9_PRT); 213 kstat_kv_u64(&kvs[cnmac_stat_rx_oversz]) += (uint32_t)val; 214 kstat_kv_u64(&kvs[cnmac_stat_rx_jabber]) += val >> 32; 215 } 216 #endif 217