diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2020-09-08 13:54:49 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2020-09-08 13:54:49 +0000 |
commit | 071416ea9253d28cdc56b5a258cf0e9a7dd24924 (patch) | |
tree | bf81be538d8eea03fe8c7e2999cb1b435377c045 /sys/arch/octeon | |
parent | a085c5058af6a0a272eacef9e9a45380c90ce4df (diff) |
Handle AGL interface
This makes certain machines' management network port usable.
Diffstat (limited to 'sys/arch/octeon')
-rw-r--r-- | sys/arch/octeon/dev/cn30xxgmx.c | 285 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxgmxreg.h | 51 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxgmxvar.h | 3 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxpko.c | 21 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxpkoreg.h | 12 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octpip.c | 13 |
6 files changed, 366 insertions, 19 deletions
diff --git a/sys/arch/octeon/dev/cn30xxgmx.c b/sys/arch/octeon/dev/cn30xxgmx.c index 3ff9d6b848b..7f99ff48e8a 100644 --- a/sys/arch/octeon/dev/cn30xxgmx.c +++ b/sys/arch/octeon/dev/cn30xxgmx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxgmx.c,v 1.45 2020/09/04 15:18:05 visa Exp $ */ +/* $OpenBSD: cn30xxgmx.c,v 1.46 2020/09/08 13:54:48 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -73,6 +73,19 @@ #define _GMX_PORT_WR8(sc, off, v) \ bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_regh, (off), (v)) +#define AGL_GMX_RD8(sc, reg) \ + bus_space_read_8((sc)->sc_port_gmx->sc_regt, \ + (sc)->sc_port_gmx->sc_regh, (reg)) +#define AGL_GMX_WR8(sc, reg, val) \ + bus_space_write_8((sc)->sc_port_gmx->sc_regt, \ + (sc)->sc_port_gmx->sc_regh, (reg), (val)) +#define AGL_GMX_PORT_RD8(sc, reg) \ + bus_space_read_8((sc)->sc_port_gmx->sc_regt, \ + (sc)->sc_port_regh, (reg)) +#define AGL_GMX_PORT_WR8(sc, reg, val) \ + bus_space_write_8((sc)->sc_port_gmx->sc_regt, \ + (sc)->sc_port_regh, (reg), (val)) + #define PCS_READ_8(sc, reg) \ bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_pcs_regh, \ (reg)) @@ -93,6 +106,10 @@ int cn30xxgmx_port_phy_addr(int); int cn30xxgmx_init(struct cn30xxgmx_softc *); int cn30xxgmx_rx_frm_ctl_xable(struct cn30xxgmx_port_softc *, uint64_t, int); +void cn30xxgmx_agl_init(struct cn30xxgmx_port_softc *); +int cn30xxgmx_agl_enable(struct cn30xxgmx_port_softc *, int); +int cn30xxgmx_agl_speed(struct cn30xxgmx_port_softc *); +int cn30xxgmx_agl_timing(struct cn30xxgmx_port_softc *); int cn30xxgmx_rgmii_enable(struct cn30xxgmx_port_softc *, int); int cn30xxgmx_rgmii_speed(struct cn30xxgmx_port_softc *); int cn30xxgmx_rgmii_speed_newlink(struct cn30xxgmx_port_softc *, @@ -115,6 +132,12 @@ static const int cn30xxgmx_rx_adr_cam_regs[] = { GMX0_RX0_ADR_CAM3, GMX0_RX0_ADR_CAM4, GMX0_RX0_ADR_CAM5 }; +struct cn30xxgmx_port_ops cn30xxgmx_port_ops_agl = { + .port_ops_enable = cn30xxgmx_agl_enable, + .port_ops_speed = cn30xxgmx_agl_speed, + .port_ops_timing = cn30xxgmx_agl_timing, +}; + struct cn30xxgmx_port_ops cn30xxgmx_port_ops_mii = { /* XXX not implemented */ }; @@ -146,7 +169,8 @@ struct cn30xxgmx_port_ops *cn30xxgmx_port_ops[] = { [GMX_GMII_PORT] = &cn30xxgmx_port_ops_gmii, [GMX_RGMII_PORT] = &cn30xxgmx_port_ops_rgmii, [GMX_SGMII_PORT] = &cn30xxgmx_port_ops_sgmii, - [GMX_SPI42_PORT] = &cn30xxgmx_port_ops_spi42 + [GMX_SPI42_PORT] = &cn30xxgmx_port_ops_spi42, + [GMX_AGL_PORT] = &cn30xxgmx_port_ops_agl, }; struct cfattach octgmx_ca = {sizeof(struct cn30xxgmx_softc), @@ -214,7 +238,10 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux) } for (i = 0; i < sc->sc_nports; i++) { - port = GMX_PORT_NUM(sc->sc_unitno, i); + if (sc->sc_port_types[i] == GMX_AGL_PORT) + port = 24; + else + port = GMX_PORT_NUM(sc->sc_unitno, i); if (cn30xxsmi_get_phy(cn30xxgmx_get_phy_phandle(sc->sc_unitno, i), port, &smi, &phy_addr)) continue; @@ -231,6 +258,10 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux) panic(": can't map port register"); switch (port_sc->sc_port_type) { + case GMX_AGL_PORT: + cn30xxgmx_agl_init(port_sc); + break; + case GMX_MII_PORT: case GMX_GMII_PORT: case GMX_RGMII_PORT: { @@ -273,6 +304,7 @@ cn30xxgmx_print(void *aux, const char *pnp) { struct cn30xxgmx_attach_args *ga = aux; static const char *types[] = { + [GMX_AGL_PORT] = "AGL", [GMX_MII_PORT] = "MII", [GMX_GMII_PORT] = "GMII", [GMX_RGMII_PORT] = "RGMII", @@ -284,7 +316,7 @@ cn30xxgmx_print(void *aux, const char *pnp) printf("%s at %s", ga->ga_name, pnp); #endif - printf(": %s", types[ga->ga_port_type]); + printf(": port %d %s", ga->ga_portno, types[ga->ga_port_type]); return UNCONF; } @@ -296,17 +328,19 @@ cn30xxgmx_init(struct cn30xxgmx_softc *sc) uint64_t inf_mode; int i, id; - inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, GMX0_INF_MODE); - if ((inf_mode & INF_MODE_EN) == 0) { - printf("ports are disabled\n"); - sc->sc_nports = 0; - return 1; - } - id = octeon_get_chipid(); switch (octeon_model_family(id)) { case OCTEON_MODEL_FAMILY_CN31XX: + inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, + GMX0_INF_MODE); + if ((inf_mode & INF_MODE_EN) == 0) { + printf("ports are disabled\n"); + sc->sc_nports = 0; + result = 1; + break; + } + /* * CN31XX-HM-1.01 * 14.1 Packet Interface Introduction @@ -329,6 +363,15 @@ cn30xxgmx_init(struct cn30xxgmx_softc *sc) break; case OCTEON_MODEL_FAMILY_CN30XX: case OCTEON_MODEL_FAMILY_CN50XX: + inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, + GMX0_INF_MODE); + if ((inf_mode & INF_MODE_EN) == 0) { + printf("ports are disabled\n"); + sc->sc_nports = 0; + result = 1; + break; + } + /* * CN30XX-HM-1.0 * 13.1 Packet Interface Introduction @@ -359,6 +402,15 @@ cn30xxgmx_init(struct cn30xxgmx_softc *sc) case OCTEON_MODEL_FAMILY_CN61XX: { uint64_t qlm_cfg; + inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, + GMX0_INF_MODE); + if ((inf_mode & INF_MODE_EN) == 0) { + printf("ports are disabled\n"); + sc->sc_nports = 0; + result = 1; + break; + } + if (sc->sc_unitno == 0) qlm_cfg = octeon_xkphys_read_8(MIO_QLM_CFG(2)); else @@ -379,6 +431,32 @@ cn30xxgmx_init(struct cn30xxgmx_softc *sc) break; } case OCTEON_MODEL_FAMILY_CN71XX: + if (sc->sc_unitno == 4) { + uint64_t val; + + sc->sc_nports = 0; + + val = bus_space_read_8(sc->sc_regt, sc->sc_regh, + AGL_PRT_CTL(0)); + if ((val & AGL_PRT_CTL_MODE_M) == + AGL_PRT_CTL_MODE_RGMII) { + sc->sc_nports = 1; + sc->sc_port_types[0] = GMX_AGL_PORT; + } + if (sc->sc_nports == 0) + result = 1; + break; + } + + inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, + GMX0_INF_MODE); + if ((inf_mode & INF_MODE_EN) == 0) { + printf("ports are disabled\n"); + sc->sc_nports = 0; + result = 1; + break; + } + switch (inf_mode & INF_MODE_MODE) { case INF_MODE_MODE_SGMII: sc->sc_nports = 4; @@ -755,6 +833,191 @@ cn30xxgmx_reset_flowctl(struct cn30xxgmx_port_softc *sc) return 0; } +void +cn30xxgmx_agl_init(struct cn30xxgmx_port_softc *sc) +{ + uint64_t val; + int port = 0; + + /* Disable link for initialization. */ + val = AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + CLR(val, AGL_GMX_PRT_CFG_EN); + AGL_GMX_PORT_WR8(sc, AGL_GMX_PRT_CFG, val); + (void)AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + + val = AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + CLR(val, AGL_PRT_CTL_CLKRST); + CLR(val, AGL_PRT_CTL_DLLRST); + CLR(val, AGL_PRT_CTL_CLKTX_BYP); + CLR(val, AGL_PRT_CTL_CLKTX_SET_M); + CLR(val, AGL_PRT_CTL_CLKRX_BYP); + CLR(val, AGL_PRT_CTL_CLKRX_SET_M); + CLR(val, AGL_PRT_CTL_REFCLK_SEL_M); + AGL_GMX_WR8(sc, AGL_PRT_CTL(port), val); + (void)AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + + /* Let the DLL settle. */ + delay(5); + + val = AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + CLR(val, AGL_PRT_CTL_DRV_BYP); + AGL_GMX_WR8(sc, AGL_PRT_CTL(port), val); + (void)AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + + val = AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + SET(val, AGL_PRT_CTL_COMP); + AGL_GMX_WR8(sc, AGL_PRT_CTL(port), val); + (void)AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + + /* Let the compensation controller settle. */ + delay(20); + + val = AGL_GMX_RX_FRM_CTL_PRE_ALIGN + | AGL_GMX_RX_FRM_CTL_PAD_LEN + | AGL_GMX_RX_FRM_CTL_VLAN_LEN + | AGL_GMX_RX_FRM_CTL_PRE_FREE + | AGL_GMX_RX_FRM_CTL_MCST + | AGL_GMX_RX_FRM_CTL_BCK + | AGL_GMX_RX_FRM_CTL_DRP + | AGL_GMX_RX_FRM_CTL_PRE_STRP + | AGL_GMX_RX_FRM_CTL_PRE_CHK; + AGL_GMX_PORT_WR8(sc, AGL_GMX_RX_FRM_CTL, val); + (void)AGL_GMX_PORT_RD8(sc, AGL_GMX_RX_FRM_CTL); +} + +void +cn30xxgmx_agl_up(struct cn30xxgmx_port_softc *sc) +{ + uint64_t val; + + val = AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + SET(val, AGL_GMX_PRT_CFG_RX_EN); + SET(val, AGL_GMX_PRT_CFG_TX_EN); + AGL_GMX_PORT_WR8(sc, AGL_GMX_PRT_CFG, val); + + val = AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + SET(val, AGL_GMX_PRT_CFG_EN); + AGL_GMX_PORT_WR8(sc, AGL_GMX_PRT_CFG, val); + (void)AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); +} + +void +cn30xxgmx_agl_down(struct cn30xxgmx_port_softc *sc) +{ + uint64_t val; + int timeout; + + val = AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + CLR(val, AGL_GMX_PRT_CFG_EN); + AGL_GMX_PORT_WR8(sc, AGL_GMX_PRT_CFG, val); + + val = AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + CLR(val, AGL_GMX_PRT_CFG_RX_EN); + CLR(val, AGL_GMX_PRT_CFG_TX_EN); + AGL_GMX_PORT_WR8(sc, AGL_GMX_PRT_CFG, val); + (void)AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + + /* Wait until the port is idle. */ + for (timeout = 1000; timeout > 0; timeout--) { + const uint64_t idlemask = AGL_GMX_PRT_CFG_RX_IDLE | + AGL_GMX_PRT_CFG_TX_IDLE; + val = AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + if ((val & idlemask) == idlemask) + break; + delay(1000); + } +} + +int +cn30xxgmx_agl_enable(struct cn30xxgmx_port_softc *sc, int enable) +{ + if (enable) + cn30xxgmx_agl_up(sc); + else + cn30xxgmx_agl_down(sc); + return 0; +} + +int +cn30xxgmx_agl_speed(struct cn30xxgmx_port_softc *sc) +{ + struct ifnet *ifp = &sc->sc_port_ac->ac_if; + uint64_t clk_cnt, prt_cfg, val; + unsigned int maxlen; + int port = 0; + + cn30xxgmx_agl_down(sc); + + prt_cfg = AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + + if (ISSET(sc->sc_port_mii->mii_media_active, IFM_FDX)) + SET(prt_cfg, AGL_GMX_PRT_CFG_DUPLEX); + else + CLR(prt_cfg, AGL_GMX_PRT_CFG_DUPLEX); + + switch (ifp->if_baudrate) { + case IF_Mbps(10): + CLR(prt_cfg, AGL_GMX_PRT_CFG_SPEED); + SET(prt_cfg, AGL_GMX_PRT_CFG_SPEED_MSB); + CLR(prt_cfg, AGL_GMX_PRT_CFG_SLOTTIME); + SET(prt_cfg, AGL_GMX_PRT_CFG_BURST); + clk_cnt = 50; + break; + case IF_Mbps(100): + CLR(prt_cfg, AGL_GMX_PRT_CFG_SPEED); + CLR(prt_cfg, AGL_GMX_PRT_CFG_SPEED_MSB); + CLR(prt_cfg, AGL_GMX_PRT_CFG_SLOTTIME); + SET(prt_cfg, AGL_GMX_PRT_CFG_BURST); + clk_cnt = 5; + break; + case IF_Gbps(1): + default: + SET(prt_cfg, AGL_GMX_PRT_CFG_SPEED); + CLR(prt_cfg, AGL_GMX_PRT_CFG_SPEED_MSB); + SET(prt_cfg, AGL_GMX_PRT_CFG_SLOTTIME); + if (ISSET(sc->sc_port_mii->mii_media_active, IFM_FDX)) + SET(prt_cfg, AGL_GMX_PRT_CFG_BURST); + else + CLR(prt_cfg, AGL_GMX_PRT_CFG_BURST); + clk_cnt = 1; + break; + } + + AGL_GMX_PORT_WR8(sc, AGL_GMX_PRT_CFG, prt_cfg); + (void)AGL_GMX_PORT_RD8(sc, AGL_GMX_PRT_CFG); + + val = AGL_GMX_PORT_RD8(sc, AGL_GMX_TX_CLK); + CLR(val, AGL_GMX_TX_CLK_CLK_CNT_M); + SET(val, clk_cnt << AGL_GMX_TX_CLK_CLK_CNT_S); + AGL_GMX_PORT_WR8(sc, AGL_GMX_TX_CLK, val); + (void)AGL_GMX_PORT_RD8(sc, AGL_GMX_TX_CLK); + + maxlen = roundup(ifp->if_hardmtu + ETHER_HDR_LEN + ETHER_CRC_LEN + + ETHER_VLAN_ENCAP_LEN, 8); + AGL_GMX_PORT_WR8(sc, AGL_GMX_RX_JABBER, maxlen); + AGL_GMX_PORT_WR8(sc, AGL_GMX_RX_FRM_MAX, maxlen); + (void)AGL_GMX_PORT_RD8(sc, AGL_GMX_RX_FRM_MAX); + + cn30xxgmx_agl_up(sc); + + val = AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + SET(val, AGL_PRT_CTL_CLKRST); + AGL_GMX_WR8(sc, AGL_PRT_CTL(port), val); + + val = AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + SET(val, AGL_PRT_CTL_ENABLE); + AGL_GMX_WR8(sc, AGL_PRT_CTL(port), val); + (void)AGL_GMX_RD8(sc, AGL_PRT_CTL(port)); + + return 0; +} + +int +cn30xxgmx_agl_timing(struct cn30xxgmx_port_softc *sc) +{ + return 0; +} + int cn30xxgmx_rgmii_enable(struct cn30xxgmx_port_softc *sc, int enable) { diff --git a/sys/arch/octeon/dev/cn30xxgmxreg.h b/sys/arch/octeon/dev/cn30xxgmxreg.h index 037c6ab4ba4..c601a40aba9 100644 --- a/sys/arch/octeon/dev/cn30xxgmxreg.h +++ b/sys/arch/octeon/dev/cn30xxgmxreg.h @@ -3,7 +3,7 @@ * DONT EDIT THIS FILE */ -/* $OpenBSD: cn30xxgmxreg.h,v 1.6 2017/04/08 10:53:48 visa Exp $ */ +/* $OpenBSD: cn30xxgmxreg.h,v 1.7 2020/09/08 13:54:48 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -655,6 +655,55 @@ #define GMX0_BASE_IF0 0x0001180008000000ULL #define GMX0_BASE_IF_SIZE(n) (GMX0_BASE_PORT_SIZE * (n)) +#define AGL_BASE 0x00011800e0000000ULL +#define AGL_SIZE 0x4000 + +#define AGL_GMX_PRT_CFG 0x0010 +#define AGL_GMX_PRT_CFG_TX_IDLE 0x0000000000002000ULL +#define AGL_GMX_PRT_CFG_RX_IDLE 0x0000000000001000ULL +#define AGL_GMX_PRT_CFG_SPEED_MSB 0x0000000000000100ULL +#define AGL_GMX_PRT_CFG_BURST 0x0000000000000040ULL +#define AGL_GMX_PRT_CFG_TX_EN 0x0000000000000020ULL +#define AGL_GMX_PRT_CFG_RX_EN 0x0000000000000010ULL +#define AGL_GMX_PRT_CFG_SLOTTIME 0x0000000000000008ULL +#define AGL_GMX_PRT_CFG_DUPLEX 0x0000000000000004ULL +#define AGL_GMX_PRT_CFG_SPEED 0x0000000000000002ULL +#define AGL_GMX_PRT_CFG_EN 0x0000000000000001ULL + +#define AGL_GMX_RX_FRM_CTL 0x0018 +#define AGL_GMX_RX_FRM_CTL_PRE_ALIGN 0x0000000000000200ULL +#define AGL_GMX_RX_FRM_CTL_PAD_LEN 0x0000000000000100ULL +#define AGL_GMX_RX_FRM_CTL_VLAN_LEN 0x0000000000000080ULL +#define AGL_GMX_RX_FRM_CTL_PRE_FREE 0x0000000000000040ULL +#define AGL_GMX_RX_FRM_CTL_SMAC 0x0000000000000020ULL +#define AGL_GMX_RX_FRM_CTL_MCST 0x0000000000000010ULL +#define AGL_GMX_RX_FRM_CTL_BCK 0x0000000000000008ULL +#define AGL_GMX_RX_FRM_CTL_DRP 0x0000000000000004ULL +#define AGL_GMX_RX_FRM_CTL_PRE_STRP 0x0000000000000002ULL +#define AGL_GMX_RX_FRM_CTL_PRE_CHK 0x0000000000000001ULL + +#define AGL_GMX_RX_FRM_MAX 0x0030 +#define AGL_GMX_RX_JABBER 0x0038 + +#define AGL_GMX_TX_CLK 0x0208 +#define AGL_GMX_TX_CLK_CLK_CNT_M 0x000000000000003fULL +#define AGL_GMX_TX_CLK_CLK_CNT_S 0 + +#define AGL_PRT_CTL(i) (0x2000 + (i) * 8) +#define AGL_PRT_CTL_DRV_BYP 0x8000000000000000ULL +#define AGL_PRT_CTL_CLK_SET_M 0x000000007f000000ULL +#define AGL_PRT_CTL_CLKRX_BYP 0x0000000000800000ULL +#define AGL_PRT_CTL_CLKRX_SET_M 0x00000000007f0000ULL +#define AGL_PRT_CTL_CLKTX_BYP 0x0000000000008000ULL +#define AGL_PRT_CTL_CLKTX_SET_M 0x0000000000007f00ULL +#define AGL_PRT_CTL_REFCLK_SEL_M 0x00000000000000c0ULL +#define AGL_PRT_CTL_DLLRST 0x0000000000000010ULL +#define AGL_PRT_CTL_COMP 0x0000000000000008ULL +#define AGL_PRT_CTL_ENABLE 0x0000000000000004ULL +#define AGL_PRT_CTL_CLKRST 0x0000000000000002ULL +#define AGL_PRT_CTL_MODE_M 0x0000000000000001ULL +#define AGL_PRT_CTL_MODE_RGMII 0x0000000000000000ULL + /* -------------------------------------------------------------------------- */ /* Low-level SGMII link control */ diff --git a/sys/arch/octeon/dev/cn30xxgmxvar.h b/sys/arch/octeon/dev/cn30xxgmxvar.h index a0e0cabab7e..066ba8b2347 100644 --- a/sys/arch/octeon/dev/cn30xxgmxvar.h +++ b/sys/arch/octeon/dev/cn30xxgmxvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxgmxvar.h,v 1.10 2020/09/04 15:18:05 visa Exp $ */ +/* $OpenBSD: cn30xxgmxvar.h,v 1.11 2020/09/08 13:54:48 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -45,6 +45,7 @@ #define GMX_RGMII_PORT 3 #define GMX_SGMII_PORT 4 #define GMX_SPI42_PORT 5 +#define GMX_AGL_PORT 6 #define GMX_FRM_MAX_SIZ 0x600 diff --git a/sys/arch/octeon/dev/cn30xxpko.c b/sys/arch/octeon/dev/cn30xxpko.c index 569eb056466..2ea636b5711 100644 --- a/sys/arch/octeon/dev/cn30xxpko.c +++ b/sys/arch/octeon/dev/cn30xxpko.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxpko.c,v 1.6 2017/11/05 04:57:28 visa Exp $ */ +/* $OpenBSD: cn30xxpko.c,v 1.7 2020/09/08 13:54:48 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -140,7 +140,8 @@ int cn30xxpko_port_config(struct cn30xxpko_softc *sc) { paddr_t buf_ptr = 0; - uint64_t mem_queue_ptrs; + uint64_t mem_queue_ptrs, val; + int i; KASSERT(sc->sc_port < 32); @@ -150,6 +151,22 @@ cn30xxpko_port_config(struct cn30xxpko_softc *sc) KASSERT(buf_ptr != 0); + if (sc->sc_port == 24) { + /* Set up PKO for AGL port. */ + _PKO_WR8(sc, PKO_REG_READ_IDX_OFFSET, 1ULL << 8); + for (i = 0; i < 40; i++) { + val = _PKO_RD8(sc, PKO_MEM_PORT_PTRS_OFFSET); + if ((val & PKO_MEM_PORT_PTRS_PID_M) == 24) { + CLR(val, PKO_MEM_PORT_PTRS_EID_M); + SET(val, 10ULL << PKO_MEM_PORT_PTRS_EID_S); + CLR(val, PKO_MEM_PORT_PTRS_BP_PORT_M); + SET(val, 40ULL << PKO_MEM_PORT_PTRS_BP_PORT_S); + _PKO_WR8(sc, PKO_MEM_PORT_PTRS_OFFSET, val); + break; + } + } + } + /* assume one queue maped one port */ mem_queue_ptrs = 0; SET(mem_queue_ptrs, PKO_MEM_QUEUE_PTRS_TAIL); diff --git a/sys/arch/octeon/dev/cn30xxpkoreg.h b/sys/arch/octeon/dev/cn30xxpkoreg.h index 9f8436364cc..4eae27924b0 100644 --- a/sys/arch/octeon/dev/cn30xxpkoreg.h +++ b/sys/arch/octeon/dev/cn30xxpkoreg.h @@ -3,7 +3,7 @@ * DONT EDIT THIS FILE */ -/* $OpenBSD: cn30xxpkoreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $ */ +/* $OpenBSD: cn30xxpkoreg.h,v 1.2 2020/09/08 13:54:48 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -83,6 +83,7 @@ #define PKO_REG_DEBUG0_OFFSET 0x00098ULL #define PKO_MEM_QUEUE_PTRS_OFFSET 0x01000ULL #define PKO_MEM_QUEUE_QOS_OFFSET 0x01008ULL +#define PKO_MEM_PORT_PTRS_OFFSET 0x01010ULL #define PKO_MEM_COUNT0_OFFSET 0x01080ULL #define PKO_MEM_COUNT1_OFFSET 0x01088ULL #define PKO_MEM_DEBUG0_OFFSET 0x01100ULL @@ -198,6 +199,15 @@ #define PKO_MEM_QUEUE_QOS_QID 0x000000000000007fULL /* + * PKO_MEM_PORT_PTRS + */ +#define PKO_MEM_PORT_PTRS_BP_PORT_M 0x000000000000fc00ULL +#define PKO_MEM_PORT_PTRS_BP_PORT_S 10 +#define PKO_MEM_PORT_PTRS_EID_M 0x00000000000003c0ULL +#define PKO_MEM_PORT_PTRS_EID_S 6 +#define PKO_MEM_PORT_PTRS_PID_M 0x000000000000003fULL + +/* * PKO_MEM_COUNT0 */ #define PKO_MEM_COUNT0_63_32 0xffffffff00000000ULL diff --git a/sys/arch/octeon/dev/octpip.c b/sys/arch/octeon/dev/octpip.c index e078eba506a..dd476df412d 100644 --- a/sys/arch/octeon/dev/octpip.c +++ b/sys/arch/octeon/dev/octpip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: octpip.c,v 1.2 2019/09/28 22:20:25 deraadt Exp $ */ +/* $OpenBSD: octpip.c,v 1.3 2020/09/08 13:54:48 visa Exp $ */ /* * Copyright (c) 2019 Visa Hankala @@ -57,6 +57,7 @@ octpip_attach(struct device *parent, struct device *self, void *aux) { struct iobus_attach_args iaa; struct fdt_attach_args *faa = aux; + paddr_t addr; uint32_t ifindex; int node; @@ -65,14 +66,20 @@ octpip_attach(struct device *parent, struct device *self, void *aux) for (node = OF_child(faa->fa_node); node != 0; node = OF_peer(node)) { if (!OF_is_compatible(node, "cavium,octeon-3860-pip-interface")) continue; + ifindex = OF_getpropint(node, "reg", (uint32_t)-1); - if (ifindex >= 16) + if (ifindex < 2) + addr = GMX0_BASE_PORT0 + GMX_BLOCK_SIZE * ifindex; + else if (ifindex == 4) + addr = AGL_BASE; + else continue; + memset(&iaa, 0, sizeof(iaa)); iaa.aa_name = "octgmx"; iaa.aa_bust = faa->fa_iot; iaa.aa_dmat = faa->fa_dmat; - iaa.aa_addr = GMX0_BASE_PORT0 + GMX_BLOCK_SIZE * ifindex; + iaa.aa_addr = addr; iaa.aa_irq = -1; iaa.aa_unitno = ifindex; config_found(self, &iaa, octpip_print); |