xref: /openbsd-src/sys/arch/octeon/dev/cn30xxpip.c (revision 52334306b2a9705ff71115f6fb78beb8340dd9a4)
1*52334306Syasuoka /*	$OpenBSD: cn30xxpip.c,v 1.11 2022/12/28 01:39:21 yasuoka Exp $	*/
24a04f2fdSsyuu 
34a04f2fdSsyuu /*
44a04f2fdSsyuu  * Copyright (c) 2007 Internet Initiative Japan, Inc.
54a04f2fdSsyuu  * All rights reserved.
64a04f2fdSsyuu  *
74a04f2fdSsyuu  * Redistribution and use in source and binary forms, with or without
84a04f2fdSsyuu  * modification, are permitted provided that the following conditions
94a04f2fdSsyuu  * are met:
104a04f2fdSsyuu  * 1. Redistributions of source code must retain the above copyright
114a04f2fdSsyuu  *    notice, this list of conditions and the following disclaimer.
124a04f2fdSsyuu  * 2. Redistributions in binary form must reproduce the above copyright
134a04f2fdSsyuu  *    notice, this list of conditions and the following disclaimer in the
144a04f2fdSsyuu  *    documentation and/or other materials provided with the distribution.
154a04f2fdSsyuu  *
16*52334306Syasuoka  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
174a04f2fdSsyuu  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
184a04f2fdSsyuu  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*52334306Syasuoka  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
204a04f2fdSsyuu  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
214a04f2fdSsyuu  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
224a04f2fdSsyuu  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
234a04f2fdSsyuu  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
244a04f2fdSsyuu  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
254a04f2fdSsyuu  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
264a04f2fdSsyuu  * SUCH DAMAGE.
274a04f2fdSsyuu  */
284a04f2fdSsyuu 
294a04f2fdSsyuu #include <sys/param.h>
304a04f2fdSsyuu #include <sys/systm.h>
314a04f2fdSsyuu #include <sys/malloc.h>
324a04f2fdSsyuu #include <sys/socket.h>
334a04f2fdSsyuu #include <sys/syslog.h>
344a04f2fdSsyuu #include <sys/time.h>
354a04f2fdSsyuu #include <net/if.h>
360deb6685Smpi #include <net/if_var.h>
374a04f2fdSsyuu 
384a04f2fdSsyuu #include <machine/octeonvar.h>
394a04f2fdSsyuu 
40e79b2291Svisa #include <octeon/dev/cn30xxgmxreg.h>
414a04f2fdSsyuu #include <octeon/dev/cn30xxpipreg.h>
424a04f2fdSsyuu #include <octeon/dev/cn30xxpipvar.h>
434a04f2fdSsyuu 
444a04f2fdSsyuu /* XXX */
454a04f2fdSsyuu void
cn30xxpip_init(struct cn30xxpip_attach_args * aa,struct cn30xxpip_softc ** rsc)464a04f2fdSsyuu cn30xxpip_init(struct cn30xxpip_attach_args *aa,
474a04f2fdSsyuu     struct cn30xxpip_softc **rsc)
484a04f2fdSsyuu {
494a04f2fdSsyuu 	struct cn30xxpip_softc *sc;
504a04f2fdSsyuu 	int status;
514a04f2fdSsyuu 
524a04f2fdSsyuu 	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
534a04f2fdSsyuu 	if (sc == NULL)
544a04f2fdSsyuu 		panic("can't allocate memory: %s", __func__);
554a04f2fdSsyuu 
564a04f2fdSsyuu 	sc->sc_port = aa->aa_port;
574a04f2fdSsyuu 	sc->sc_regt = aa->aa_regt;
584a04f2fdSsyuu 	sc->sc_tag_type = aa->aa_tag_type;
594a04f2fdSsyuu 	sc->sc_receive_group = aa->aa_receive_group;
604a04f2fdSsyuu 	sc->sc_ip_offset = aa->aa_ip_offset;
614a04f2fdSsyuu 
624a04f2fdSsyuu 	status = bus_space_map(sc->sc_regt, PIP_BASE, PIP_SIZE, 0,
634a04f2fdSsyuu 	    &sc->sc_regh);
644a04f2fdSsyuu 	if (status != 0)
654a04f2fdSsyuu 		panic("can't map %s space", "pip register");
664a04f2fdSsyuu 
676ece48ccSvisa 	status = bus_space_subregion(sc->sc_regt, sc->sc_regh,
686ece48ccSvisa 	    PIP_STAT_BASE(sc->sc_port), PIP_STAT_SIZE, &sc->sc_regh_stat);
696ece48ccSvisa 	if (status != 0)
706ece48ccSvisa 		panic("can't map stat register space");
716ece48ccSvisa 
724a04f2fdSsyuu 	*rsc = sc;
734a04f2fdSsyuu }
744a04f2fdSsyuu 
754a04f2fdSsyuu #define	_PIP_RD8(sc, off) \
764a04f2fdSsyuu 	bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
774a04f2fdSsyuu #define	_PIP_WR8(sc, off, v) \
784a04f2fdSsyuu 	bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
794a04f2fdSsyuu 
806ece48ccSvisa #define	_PIP_STAT_RD8(sc, off) \
816ece48ccSvisa 	bus_space_read_8((sc)->sc_regt, (sc)->sc_regh_stat, (off))
826ece48ccSvisa #define	_PIP_STAT_WR8(sc, off, v) \
836ece48ccSvisa 	bus_space_write_8((sc)->sc_regt, (sc)->sc_regh_stat, (off), (v))
846ece48ccSvisa 
854a04f2fdSsyuu int
cn30xxpip_port_config(struct cn30xxpip_softc * sc)864a04f2fdSsyuu cn30xxpip_port_config(struct cn30xxpip_softc *sc)
874a04f2fdSsyuu {
884a04f2fdSsyuu 	uint64_t prt_cfg;
894a04f2fdSsyuu 	uint64_t prt_tag;
904a04f2fdSsyuu 	uint64_t ip_offset;
914a04f2fdSsyuu 
924a04f2fdSsyuu 	/*
934a04f2fdSsyuu 	 * Process the headers and place the IP header in the work queue
944a04f2fdSsyuu 	 */
954a04f2fdSsyuu 	prt_cfg = 0;
964a04f2fdSsyuu 	/* RAWDRP=0; don't allow raw packet drop */
974a04f2fdSsyuu 	/* TAGINC=0 */
984c5f1196Svisa 	/* DYN_RS=0; disable dynamic short buffering */
994a04f2fdSsyuu 	/* INST_HDR=0 */
1004a04f2fdSsyuu 	/* GRP_WAT=0 */
1014a04f2fdSsyuu 	SET(prt_cfg, (sc->sc_port << 24) & PIP_PRT_CFGN_QOS);
1024a04f2fdSsyuu 	/* QOS_WAT=0 */
1034a04f2fdSsyuu 	/* SPARE=0 */
1044a04f2fdSsyuu 	/* QOS_DIFF=0 */
1054a04f2fdSsyuu 	/* QOS_VLAN=0 */
1064a04f2fdSsyuu 	SET(prt_cfg, PIP_PRT_CFGN_CRC_EN);
1074a04f2fdSsyuu 	SET(prt_cfg, (PIP_PORT_CFG_MODE_L2) & PIP_PRT_CFGN_MODE);
1084a04f2fdSsyuu 	/* SKIP=0 */
1094a04f2fdSsyuu 
1104a04f2fdSsyuu 	prt_tag = 0;
1114a04f2fdSsyuu 	SET(prt_tag, PIP_PRT_TAGN_INC_PRT);
1124a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP6_DPRT);
1134a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP4_DPRT);
1144a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP6_SPRT);
1154a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP4_SPRT);
1164a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP6_NXTH);
1174a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP4_PCTL);
1184a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP6_DST);
1194a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP4_SRC);
1204a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP6_SRC);
1214a04f2fdSsyuu 	CLR(prt_tag, PIP_PRT_TAGN_IP4_DST);
1224a04f2fdSsyuu 	SET(prt_tag, PIP_PRT_TAGN_TCP6_TAG_ORDERED);
1234a04f2fdSsyuu 	SET(prt_tag, PIP_PRT_TAGN_TCP4_TAG_ORDERED);
1244a04f2fdSsyuu 	SET(prt_tag, PIP_PRT_TAGN_IP6_TAG_ORDERED);
1254a04f2fdSsyuu 	SET(prt_tag, PIP_PRT_TAGN_IP4_TAG_ORDERED);
1264a04f2fdSsyuu 	SET(prt_tag, PIP_PRT_TAGN_NON_TAG_ORDERED);
1274a04f2fdSsyuu 	SET(prt_tag, sc->sc_receive_group & PIP_PRT_TAGN_GRP);
1284a04f2fdSsyuu 
1294a04f2fdSsyuu 	ip_offset = 0;
1304a04f2fdSsyuu 	SET(ip_offset, (sc->sc_ip_offset / 8) & PIP_IP_OFFSET_MASK_OFFSET);
1314a04f2fdSsyuu 
1324a04f2fdSsyuu 	_PIP_WR8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port), prt_cfg);
1334a04f2fdSsyuu 	_PIP_WR8(sc, PIP_PRT_TAG0_OFFSET + (8 * sc->sc_port), prt_tag);
1344a04f2fdSsyuu 	_PIP_WR8(sc, PIP_IP_OFFSET_OFFSET, ip_offset);
1354a04f2fdSsyuu 
1364a04f2fdSsyuu 	return 0;
1374a04f2fdSsyuu }
1384a04f2fdSsyuu 
1394a04f2fdSsyuu void
cn30xxpip_prt_cfg_enable(struct cn30xxpip_softc * sc,uint64_t prt_cfg,int enable)1404a04f2fdSsyuu cn30xxpip_prt_cfg_enable(struct cn30xxpip_softc *sc, uint64_t prt_cfg,
1414a04f2fdSsyuu     int enable)
1424a04f2fdSsyuu {
1434a04f2fdSsyuu 	uint64_t tmp;
1444a04f2fdSsyuu 
1454a04f2fdSsyuu 	tmp = _PIP_RD8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port));
1464a04f2fdSsyuu 	if (enable)
1474a04f2fdSsyuu 		tmp |= prt_cfg;
1484a04f2fdSsyuu 	else
1494a04f2fdSsyuu 		tmp &= ~prt_cfg;
1504a04f2fdSsyuu 	_PIP_WR8(sc, PIP_PRT_CFG0_OFFSET + (8 * sc->sc_port), tmp);
1514a04f2fdSsyuu }
1524a04f2fdSsyuu 
1534a04f2fdSsyuu void
cn30xxpip_stats_init(struct cn30xxpip_softc * sc)1546ece48ccSvisa cn30xxpip_stats_init(struct cn30xxpip_softc *sc)
1554a04f2fdSsyuu {
1566ece48ccSvisa 	/* XXX */
1576ece48ccSvisa 	_PIP_WR8(sc, PIP_STAT_CTL_OFFSET, 1);
1584a04f2fdSsyuu 
1596ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT0_PRT, 0);
1606ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT1_PRT, 0);
1616ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT2_PRT, 0);
1626ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT3_PRT, 0);
1636ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT4_PRT, 0);
1646ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT5_PRT, 0);
1656ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT6_PRT, 0);
1666ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT7_PRT, 0);
1676ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT8_PRT, 0);
1686ece48ccSvisa 	_PIP_STAT_WR8(sc, PIP_STAT9_PRT, 0);
1694a04f2fdSsyuu }
1704a04f2fdSsyuu 
1716ece48ccSvisa #if NKSTAT > 0
1726ece48ccSvisa void
cn30xxpip_kstat_read(struct cn30xxpip_softc * sc,struct kstat_kv * kvs)1736ece48ccSvisa cn30xxpip_kstat_read(struct cn30xxpip_softc *sc, struct kstat_kv *kvs)
1746ece48ccSvisa {
1756ece48ccSvisa 	uint64_t val;
1764a04f2fdSsyuu 
1776ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT0_PRT);
1786ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_qdpo]) += (uint32_t)val;
1796ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_qdpp]) += val >> 32;
1806ece48ccSvisa 
1816ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT1_PRT);
1826ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_toto_pip]) += (uint32_t)val;
1836ece48ccSvisa 
1846ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT2_PRT);
1856ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_raw]) += (uint32_t)val;
1866ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_totp_pip]) += val >> 32;
1876ece48ccSvisa 
1886ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT3_PRT);
1896ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_mcast]) += (uint32_t)val;
1906ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_bcast]) += val >> 32;
1916ece48ccSvisa 
1926ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT4_PRT);
1936ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_h64]) += (uint32_t)val;
1946ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_h127]) += val >> 32;
1956ece48ccSvisa 
1966ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT5_PRT);
1976ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_h255]) += (uint32_t)val;
1986ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_h511]) += val >> 32;
1996ece48ccSvisa 
2006ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT6_PRT);
2016ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_h1023]) += (uint32_t)val;
2026ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_h1518]) += val >> 32;
2036ece48ccSvisa 
2046ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT7_PRT);
2056ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_hmax]) += (uint32_t)val;
2066ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_fcs]) += val >> 32;
2076ece48ccSvisa 
2086ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT8_PRT);
2096ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_undersz]) += (uint32_t)val;
2106ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_frag]) += val >> 32;
2116ece48ccSvisa 
2126ece48ccSvisa 	val = _PIP_STAT_RD8(sc, PIP_STAT9_PRT);
2136ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_oversz]) += (uint32_t)val;
2146ece48ccSvisa 	kstat_kv_u64(&kvs[cnmac_stat_rx_jabber]) += val >> 32;
2154a04f2fdSsyuu }
2166ece48ccSvisa #endif
217