summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_oce.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/if_oce.c')
-rw-r--r--sys/dev/pci/if_oce.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/sys/dev/pci/if_oce.c b/sys/dev/pci/if_oce.c
index 9bdd575b515..2a2d747de91 100644
--- a/sys/dev/pci/if_oce.c
+++ b/sys/dev/pci/if_oce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_oce.c,v 1.60 2012/11/13 19:17:39 mikeb Exp $ */
+/* $OpenBSD: if_oce.c,v 1.61 2012/11/14 17:25:46 mikeb Exp $ */
/*
* Copyright (c) 2012 Mike Belopuhov
@@ -111,6 +111,8 @@
#define OCE_MBX_TIMEOUT 5
+#define OCE_MAX_PAYLOAD 65536
+
#define OCE_TX_RING_SIZE 512
#define OCE_RX_RING_SIZE 1024
@@ -137,6 +139,7 @@
#define OCE_MAX_TX_SIZE 65535
#define OCE_MEM_KVA(_m) ((void *)((_m)->vaddr))
+#define OCE_MEM_DVA(_m) ((_m)->paddr)
#define OCE_WQ_FOREACH(sc, wq, i) \
for (i = 0, wq = sc->sc_wq[0]; i < sc->sc_nwq; i++, wq = sc->sc_wq[i])
@@ -331,6 +334,7 @@ struct oce_softc {
uint sc_fc;
struct oce_dma_mem sc_mbx;
+ struct oce_dma_mem sc_pld;
uint sc_port;
uint sc_fmode;
@@ -564,28 +568,32 @@ oce_attach(struct device *parent, struct device *self, void *aux)
printf(": failed to allocate mailbox memory\n");
return;
}
+ if (oce_dma_alloc(sc, OCE_MAX_PAYLOAD, &sc->sc_pld)) {
+ printf(": failed to allocate payload memory\n");
+ goto fail_1;
+ }
if (oce_init_fw(sc))
- goto fail_1;
+ goto fail_2;
if (oce_mbox_init(sc)) {
printf(": failed to initialize mailbox\n");
- goto fail_1;
+ goto fail_2;
}
if (oce_get_fw_config(sc)) {
printf(": failed to get firmware configuration\n");
- goto fail_1;
+ goto fail_2;
}
if (ISSET(sc->sc_flags, OCE_F_BE3)) {
if (oce_check_native_mode(sc))
- goto fail_1;
+ goto fail_2;
}
if (oce_macaddr_get(sc, sc->sc_macaddr)) {
printf(": failed to fetch MAC address\n");
- goto fail_1;
+ goto fail_2;
}
bcopy(sc->sc_macaddr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
@@ -593,7 +601,7 @@ oce_attach(struct device *parent, struct device *self, void *aux)
oce_pkt_pool = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
if (oce_pkt_pool == NULL) {
printf(": unable to allocate descriptor pool\n");
- goto fail_1;
+ goto fail_2;
}
pool_init(oce_pkt_pool, sizeof(struct oce_pkt), 0, 0, 0,
"ocepkts", NULL);
@@ -605,7 +613,7 @@ oce_attach(struct device *parent, struct device *self, void *aux)
if (pci_intr_map_msi(pa, &ih) != 0 &&
pci_intr_map(pa, &ih) != 0) {
printf(": couldn't map interrupt\n");
- goto fail_1;
+ goto fail_2;
}
intrstr = pci_intr_string(pa->pa_pc, ih);
@@ -616,18 +624,18 @@ oce_attach(struct device *parent, struct device *self, void *aux)
if (intrstr != NULL)
printf(" at %s", intrstr);
printf("\n");
- goto fail_1;
+ goto fail_2;
}
printf(": %s", intrstr);
if (oce_init_queues(sc))
- goto fail_2;
+ goto fail_3;
oce_attach_ifp(sc);
#ifdef OCE_LRO
if (oce_init_lro(sc))
- goto fail_3;
+ goto fail_4;
#endif
timeout_set(&sc->sc_tick, oce_tick, sc);
@@ -640,14 +648,16 @@ oce_attach(struct device *parent, struct device *self, void *aux)
return;
#ifdef OCE_LRO
-fail_3:
+fail_4:
oce_free_lro(sc);
ether_ifdetach(&sc->sc_ac.ac_if);
if_detach(&sc->sc_ac.ac_if);
oce_release_queues(sc);
#endif
-fail_2:
+fail_3:
pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
+fail_2:
+ oce_dma_free(sc, &sc->sc_pld);
fail_1:
oce_dma_free(sc, &sc->sc_mbx);
}
@@ -2749,7 +2759,7 @@ oce_mbox_dispatch(struct oce_softc *sc)
uint32_t pa, reg;
int err;
- pa = (uint32_t)((uint64_t)sc->sc_mbx.paddr >> 34);
+ pa = (uint32_t)((uint64_t)OCE_MEM_DVA(&sc->sc_mbx) >> 34);
reg = PD_MPU_MBOX_DB_HI | (pa << PD_MPU_MBOX_DB_ADDR_SHIFT);
if ((err = oce_mbox_wait(sc)) != 0)
@@ -2757,7 +2767,7 @@ oce_mbox_dispatch(struct oce_softc *sc)
oce_write_db(sc, PD_MPU_MBOX_DB, reg);
- pa = (uint32_t)((uint64_t)sc->sc_mbx.paddr >> 4) & 0x3fffffff;
+ pa = (uint32_t)((uint64_t)OCE_MEM_DVA(&sc->sc_mbx) >> 4) & 0x3fffffff;
reg = pa << PD_MPU_MBOX_DB_ADDR_SHIFT;
if ((err = oce_mbox_wait(sc)) != 0)
@@ -2808,16 +2818,14 @@ oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version,
{
struct oce_bmbx *bmbx = OCE_MEM_KVA(&sc->sc_mbx);
struct oce_mbx *mbx = &bmbx->mbx;
- struct oce_dma_mem sgl;
struct mbx_hdr *hdr;
caddr_t epayload = NULL;
int err;
- if (length > OCE_MBX_PAYLOAD) {
- if (oce_dma_alloc(sc, length, &sgl))
- return (-1);
- epayload = OCE_MEM_KVA(&sgl);
- }
+ if (length > OCE_MBX_PAYLOAD)
+ epayload = OCE_MEM_KVA(&sc->sc_pld);
+ if (length > OCE_MAX_PAYLOAD)
+ return (EINVAL);
oce_dma_sync(&sc->sc_mbx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -2827,11 +2835,11 @@ oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version,
if (epayload) {
mbx->u0.s.sge_count = 1;
- oce_dma_sync(&sgl, BUS_DMASYNC_PREWRITE);
+ oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_PREREAD);
bcopy(payload, epayload, length);
- mbx->payload.u0.u1.sgl[0].paddr = sgl.paddr;
+ mbx->payload.u0.u1.sgl[0].paddr = OCE_MEM_DVA(&sc->sc_pld);
mbx->payload.u0.u1.sgl[0].length = length;
- hdr = OCE_MEM_KVA(&sgl);
+ hdr = (struct mbx_hdr *)epayload;
} else {
mbx->u0.s.embedded = 1;
bcopy(payload, &mbx->payload, length);
@@ -2847,10 +2855,13 @@ oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version,
else
hdr->u0.req.timeout = OCE_MBX_TIMEOUT;
+ if (epayload)
+ oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_PREWRITE);
+
err = oce_mbox_dispatch(sc);
if (err == 0) {
if (epayload) {
- oce_dma_sync(&sgl, BUS_DMASYNC_POSTWRITE);
+ oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_POSTWRITE);
bcopy(epayload, payload, length);
} else
bcopy(&mbx->payload, payload, length);
@@ -2859,8 +2870,6 @@ oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version,
"%spayload lenght %d\n", sc->sc_dev.dv_xname, subsys,
opcode, version, epayload ? "ext " : "",
length);
- if (epayload)
- oce_dma_free(sc, &sgl);
return (err);
}