1 /* $OpenBSD: cn30xxipd.c,v 1.14 2020/08/15 11:12:28 visa 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 REGENTS 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 REGENTS 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 33 #include <machine/octeonvar.h> 34 35 #include <octeon/dev/cn30xxipdreg.h> 36 #include <octeon/dev/cn30xxipdvar.h> 37 38 void 39 cn30xxipd_init(struct cn30xxipd_attach_args *aa, 40 struct cn30xxipd_softc **rsc) 41 { 42 struct cn30xxipd_softc *sc; 43 int status; 44 45 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); 46 if (sc == NULL) 47 panic("can't allocate memory: %s", __func__); 48 49 sc->sc_port = aa->aa_port; 50 sc->sc_regt = aa->aa_regt; 51 sc->sc_first_mbuff_skip = aa->aa_first_mbuff_skip; 52 sc->sc_not_first_mbuff_skip = aa->aa_not_first_mbuff_skip; 53 54 status = bus_space_map(sc->sc_regt, IPD_BASE, IPD_SIZE, 0, 55 &sc->sc_regh); 56 if (status != 0) 57 panic("can't map %s space", "ipd register"); 58 59 *rsc = sc; 60 } 61 62 #define _IPD_RD8(sc, off) \ 63 bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off)) 64 #define _IPD_WR8(sc, off, v) \ 65 bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v)) 66 67 int 68 cn30xxipd_enable(struct cn30xxipd_softc *sc) 69 { 70 uint64_t ctl_status; 71 72 ctl_status = _IPD_RD8(sc, IPD_CTL_STATUS_OFFSET); 73 SET(ctl_status, IPD_CTL_STATUS_IPD_EN); 74 _IPD_WR8(sc, IPD_CTL_STATUS_OFFSET, ctl_status); 75 76 return 0; 77 } 78 79 int 80 cn30xxipd_config(struct cn30xxipd_softc *sc) 81 { 82 uint64_t first_mbuff_skip; 83 uint64_t not_first_mbuff_skip; 84 uint64_t packet_mbuff_size; 85 uint64_t first_next_ptr_back; 86 uint64_t second_next_ptr_back; 87 uint64_t sqe_fpa_queue; 88 uint64_t ctl_status; 89 90 /* XXX */ 91 first_mbuff_skip = 0; 92 SET(first_mbuff_skip, (sc->sc_first_mbuff_skip / 8) & IPD_1ST_MBUFF_SKIP_SZ); 93 _IPD_WR8(sc, IPD_1ST_MBUFF_SKIP_OFFSET, first_mbuff_skip); 94 /* XXX */ 95 96 /* XXX */ 97 not_first_mbuff_skip = 0; 98 SET(not_first_mbuff_skip, (sc->sc_not_first_mbuff_skip / 8) & 99 IPD_NOT_1ST_MBUFF_SKIP_SZ); 100 _IPD_WR8(sc, IPD_NOT_1ST_MBUFF_SKIP_OFFSET, not_first_mbuff_skip); 101 /* XXX */ 102 103 packet_mbuff_size = 0; 104 SET(packet_mbuff_size, (OCTEON_POOL_SIZE_PKT / 8) & 105 IPD_PACKET_MBUFF_SIZE_MB_SIZE); 106 _IPD_WR8(sc, IPD_PACKET_MBUFF_SIZE_OFFSET, packet_mbuff_size); 107 108 first_next_ptr_back = 0; 109 SET(first_next_ptr_back, (sc->sc_first_mbuff_skip / CACHELINESIZE) 110 & IPD_1ST_NEXT_PTR_BACK_BACK); 111 _IPD_WR8(sc, IPD_1ST_NEXT_PTR_BACK_OFFSET, first_next_ptr_back); 112 113 second_next_ptr_back = 0; 114 SET(second_next_ptr_back, (sc->sc_not_first_mbuff_skip / CACHELINESIZE) 115 & IPD_2ND_NEXT_PTR_BACK_BACK); 116 _IPD_WR8(sc, IPD_2ND_NEXT_PTR_BACK_OFFSET, second_next_ptr_back); 117 118 sqe_fpa_queue = 0; 119 SET(sqe_fpa_queue, OCTEON_POOL_NO_WQE & IPD_WQE_FPA_QUEUE_WQE_QUE); 120 _IPD_WR8(sc, IPD_WQE_FPA_QUEUE_OFFSET, sqe_fpa_queue); 121 122 ctl_status = _IPD_RD8(sc, IPD_CTL_STATUS_OFFSET); 123 CLR(ctl_status, IPD_CTL_STATUS_OPC_MODE); 124 SET(ctl_status, IPD_CTL_STATUS_OPC_MODE_ALL); 125 SET(ctl_status, IPD_CTL_STATUS_PBP_EN); 126 127 _IPD_WR8(sc, IPD_CTL_STATUS_OFFSET, ctl_status); 128 129 return 0; 130 } 131