From 506be21dcdc735368d83ec602c3a3d039af4a5bd Mon Sep 17 00:00:00 2001 From: brad Date: Fri, 10 Jan 2014 22:01:30 +0000 Subject: [PATCH] Add MSI support. Tested by comete@daknet.org and vigdis+obsd@chown.me. --- sys/dev/pci/if_jme.c | 77 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/sys/dev/pci/if_jme.c b/sys/dev/pci/if_jme.c index 447029e6b1a..2f989a3e21a 100644 --- a/sys/dev/pci/if_jme.c +++ b/sys/dev/pci/if_jme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_jme.c,v 1.33 2013/12/07 07:22:37 brad Exp $ */ +/* $OpenBSD: if_jme.c,v 1.34 2014/01/10 22:01:30 brad Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon * All rights reserved. @@ -79,6 +79,7 @@ #undef JME_SHOW_ERRORS int jme_match(struct device *, void *, void *); +void jme_map_intr_vector(struct jme_softc *); void jme_attach(struct device *, struct device *, void *); int jme_detach(struct device *, int); @@ -468,6 +469,76 @@ jme_reg_macaddr(struct jme_softc *sc, uint8_t eaddr[]) eaddr[5] = (par1 >> 8) & 0xFF; } +void +jme_map_intr_vector(struct jme_softc *sc) +{ + uint32_t map[MSINUM_NUM_INTR_SOURCE / JME_MSI_MESSAGES]; + + bzero(map, sizeof(map)); + + /* Map Tx interrupts source to MSI/MSIX vector 2. */ + map[MSINUM_REG_INDEX(N_INTR_TXQ0_COMP)] = + MSINUM_INTR_SOURCE(2, N_INTR_TXQ0_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ1_COMP)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ1_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ2_COMP)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ2_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ3_COMP)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ3_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ4_COMP)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ4_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ4_COMP)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ5_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ6_COMP)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ6_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ7_COMP)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ7_COMP); + map[MSINUM_REG_INDEX(N_INTR_TXQ_COAL)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ_COAL); + map[MSINUM_REG_INDEX(N_INTR_TXQ_COAL_TO)] |= + MSINUM_INTR_SOURCE(2, N_INTR_TXQ_COAL_TO); + + /* Map Rx interrupts source to MSI/MSIX vector 1. */ + map[MSINUM_REG_INDEX(N_INTR_RXQ0_COMP)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ0_COMP); + map[MSINUM_REG_INDEX(N_INTR_RXQ1_COMP)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ1_COMP); + map[MSINUM_REG_INDEX(N_INTR_RXQ2_COMP)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ2_COMP); + map[MSINUM_REG_INDEX(N_INTR_RXQ3_COMP)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ3_COMP); + map[MSINUM_REG_INDEX(N_INTR_RXQ0_DESC_EMPTY)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ0_DESC_EMPTY); + map[MSINUM_REG_INDEX(N_INTR_RXQ1_DESC_EMPTY)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ1_DESC_EMPTY); + map[MSINUM_REG_INDEX(N_INTR_RXQ2_DESC_EMPTY)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ2_DESC_EMPTY); + map[MSINUM_REG_INDEX(N_INTR_RXQ3_DESC_EMPTY)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ3_DESC_EMPTY); + map[MSINUM_REG_INDEX(N_INTR_RXQ0_COAL)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ0_COAL); + map[MSINUM_REG_INDEX(N_INTR_RXQ1_COAL)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ1_COAL); + map[MSINUM_REG_INDEX(N_INTR_RXQ2_COAL)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ2_COAL); + map[MSINUM_REG_INDEX(N_INTR_RXQ3_COAL)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ3_COAL); + map[MSINUM_REG_INDEX(N_INTR_RXQ0_COAL_TO)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ0_COAL_TO); + map[MSINUM_REG_INDEX(N_INTR_RXQ1_COAL_TO)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ1_COAL_TO); + map[MSINUM_REG_INDEX(N_INTR_RXQ2_COAL_TO)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ2_COAL_TO); + map[MSINUM_REG_INDEX(N_INTR_RXQ3_COAL_TO)] = + MSINUM_INTR_SOURCE(1, N_INTR_RXQ3_COAL_TO); + + /* Map all other interrupts source to MSI/MSIX vector 0. */ + CSR_WRITE_4(sc, JME_MSINUM_BASE + sizeof(uint32_t) * 0, map[0]); + CSR_WRITE_4(sc, JME_MSINUM_BASE + sizeof(uint32_t) * 1, map[1]); + CSR_WRITE_4(sc, JME_MSINUM_BASE + sizeof(uint32_t) * 2, map[2]); + CSR_WRITE_4(sc, JME_MSINUM_BASE + sizeof(uint32_t) * 3, map[3]); +} + void jme_attach(struct device *parent, struct device *self, void *aux) { @@ -499,7 +570,9 @@ jme_attach(struct device *parent, struct device *self, void *aux) return; } - if (pci_intr_map(pa, &ih) != 0) { + if (pci_intr_map_msi(pa, &ih) == 0) + jme_map_intr_vector(sc); + else if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); return; } -- 2.20.1