xref: /openbsd/sys/arch/octeon/dev/cn30xxpip.c (revision d415bd75)
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