summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2012-10-12 17:41:41 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2012-10-12 17:41:41 +0000
commit1d974704b9b6a82fa327aac41fb4bfdb28fc7082 (patch)
treee3586c656d75db3bc76097bd824822ad5748a082 /sys/dev
parentf902b818adf04bf6c31412950480fcdefa5bb366 (diff)
major cleanup
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_oce.c456
-rw-r--r--sys/dev/pci/oce.c562
-rw-r--r--sys/dev/pci/ocevar.h523
3 files changed, 683 insertions, 858 deletions
diff --git a/sys/dev/pci/if_oce.c b/sys/dev/pci/if_oce.c
index 83a71abb075..f5fe4887579 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.17 2012/10/12 15:16:45 mikeb Exp $ */
+/* $OpenBSD: if_oce.c,v 1.18 2012/10/12 17:41:40 mikeb Exp $ */
/*
* Copyright (c) 2012 Mike Belopuhov
@@ -99,13 +99,17 @@
int oce_probe(struct device *parent, void *match, void *aux);
void oce_attach(struct device *parent, struct device *self, void *aux);
void oce_attachhook(void *arg);
+int oce_attach_ifp(struct oce_softc *sc);
int oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data);
void oce_init(void *xsc);
void oce_stop(struct oce_softc *sc);
void oce_iff(struct oce_softc *sc);
+int oce_pci_alloc(struct oce_softc *sc);
int oce_intr(void *arg);
int oce_alloc_intr(struct oce_softc *sc);
+void oce_intr_enable(struct oce_softc *sc);
+void oce_intr_disable(struct oce_softc *sc);
void oce_media_status(struct ifnet *ifp, struct ifmediareq *ifmr);
int oce_media_change(struct ifnet *ifp);
@@ -130,9 +134,8 @@ int oce_start_rq(struct oce_rq *rq);
void oce_stop_rq(struct oce_rq *rq);
void oce_free_posted_rxbuf(struct oce_rq *rq);
-int oce_attach_ifp(struct oce_softc *sc);
int oce_vid_config(struct oce_softc *sc);
-void oce_mac_addr_set(struct oce_softc *sc);
+void oce_set_macaddr(struct oce_softc *sc);
void oce_local_timer(void *arg);
#if defined(INET6) || defined(INET)
@@ -206,11 +209,8 @@ oce_attach(struct device *parent, struct device *self, void *aux)
{
struct pci_attach_args *pa = (struct pci_attach_args *)aux;
struct oce_softc *sc = (struct oce_softc *)self;
- int rc = 0;
- uint16_t devid;
- devid = PCI_PRODUCT(pa->pa_id);
- switch (devid) {
+ switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_SERVERENGINES_BE2:
case PCI_PRODUCT_SERVERENGINES_OCBE2:
sc->flags |= OCE_FLAGS_BE2;
@@ -225,7 +225,7 @@ oce_attach(struct device *parent, struct device *self, void *aux)
}
sc->pa = *pa;
- if (oce_hw_pci_alloc(sc))
+ if (oce_pci_alloc(sc))
return;
sc->rss_enable = 0;
@@ -234,33 +234,53 @@ oce_attach(struct device *parent, struct device *self, void *aux)
sc->rq_frag_size = OCE_RQ_BUF_SIZE;
sc->flow_control = OCE_DEFAULT_FLOW_CONTROL;
- /* initialise the hardware */
- rc = oce_hw_init(sc);
- if (rc)
+ /* create the bootstrap mailbox */
+ if (oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->bsmbx)) {
+ printf(": failed to allocate mailbox memory\n");
return;
+ }
+
+ if (oce_init_fw(sc))
+ goto fail_1;
+
+ if (oce_mbox_init(sc)) {
+ printf(": failed to initialize mailbox\n");
+ goto fail_1;
+ }
+
+ if (oce_get_fw_version(sc) || oce_get_fw_config(sc)) {
+ printf(": failed to fetch fw configuration\n");
+ goto fail_1;
+ }
+
+ if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) {
+ if (oce_check_native_mode(sc))
+ goto fail_1;
+ } else
+ sc->be3_native = 0;
+
+ if (oce_read_macaddr(sc, sc->macaddr)) {
+ printf(": failed to fetch MAC address\n");
+ goto fail_1;
+ }
+ bcopy(sc->macaddr, sc->arpcom.ac_enaddr, ETH_ADDR_LEN);
sc->nrqs = 1;
sc->nwqs = 1;
sc->intr_count = 1;
- rc = oce_alloc_intr(sc);
- if (rc)
- goto dma_free;
-
- rc = oce_init_queues(sc);
- if (rc)
- goto dma_free;
+ if (oce_alloc_intr(sc))
+ goto fail_1;
- bcopy(sc->macaddr.mac_addr, sc->arpcom.ac_enaddr, ETH_ADDR_LEN);
+ if (oce_init_queues(sc))
+ goto fail_1;
- rc = oce_attach_ifp(sc);
- if (rc)
- goto queues_free;
+ if (oce_attach_ifp(sc))
+ goto fail_2;
#ifdef OCE_LRO
- rc = oce_init_lro(sc);
- if (rc)
- goto ifp_free;
+ if (oce_init_lro(sc))
+ goto fail_3;
#endif
timeout_set(&sc->timer, oce_local_timer, sc);
@@ -268,20 +288,21 @@ oce_attach(struct device *parent, struct device *self, void *aux)
mountroothook_establish(oce_attachhook, sc);
- printf(", address %s\n", ether_sprintf(sc->macaddr.mac_addr));
+ printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
+ printf("%s: %s ASIC %d\n", sc->dev.dv_xname, sc->fw_version, sc->asic_revision);
return;
#ifdef OCE_LRO
-lro_free:
+fail_4:
oce_free_lro(sc);
-ifp_free:
+fail_3:
#endif
ether_ifdetach(&sc->arpcom.ac_if);
if_detach(&sc->arpcom.ac_if);
-queues_free:
+fail_2:
oce_release_queues(sc);
-dma_free:
+fail_1:
oce_dma_free(sc, &sc->bsmbx);
}
@@ -292,14 +313,14 @@ oce_attachhook(void *arg)
oce_get_link_status(sc);
- oce_arm_cq(sc->mq->parent, sc->mq->cq->cq_id, 0, TRUE);
+ oce_arm_cq(sc->mq->sc, sc->mq->cq->id, 0, TRUE);
/*
* We need to get MCC async events. So enable intrs and arm
* first EQ, Other EQs will be armed after interface is UP
*/
- oce_hw_intr_enable(sc);
- oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
+ oce_intr_enable(sc);
+ oce_arm_eq(sc, sc->eq[0]->id, 0, TRUE, FALSE);
/*
* Send first mcc cmd and after that we get gracious
@@ -309,6 +330,50 @@ oce_attachhook(void *arg)
}
int
+oce_attach_ifp(struct oce_softc *sc)
+{
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ ifmedia_init(&sc->media, IFM_IMASK, oce_media_change, oce_media_status);
+ ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
+
+ strlcpy(ifp->if_xname, sc->dev.dv_xname, IFNAMSIZ);
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = oce_ioctl;
+ ifp->if_start = oce_start;
+ ifp->if_watchdog = oce_watchdog;
+ ifp->if_hardmtu = OCE_MAX_MTU;
+ ifp->if_softc = sc;
+ IFQ_SET_MAXLEN(&ifp->if_snd, sc->tx_ring_size - 1);
+ IFQ_SET_READY(&ifp->if_snd);
+
+ /* oce splits jumbos into 2k chunks... */
+ m_clsetwms(ifp, MCLBYTES, 8, sc->rx_ring_size);
+
+ ifp->if_capabilities = IFCAP_VLAN_MTU;
+
+#if NVLAN > 0
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+#endif
+
+#if defined(INET6) || defined(INET)
+#ifdef OCE_TSO
+ ifp->if_capabilities |= IFCAP_TSO;
+ ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
+#endif
+#ifdef OCE_LRO
+ ifp->if_capabilities |= IFCAP_LRO;
+#endif
+#endif
+
+ if_attach(ifp);
+ ether_ifattach(ifp);
+
+ return 0;
+}
+
+int
oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
struct oce_softc *sc = ifp->if_softc;
@@ -429,7 +494,7 @@ oce_intr(void *arg)
claimed = 1;
/* Clear EQ entries, but dont arm */
- oce_arm_eq(sc, eq->eq_id, num_eqes, FALSE, TRUE);
+ oce_arm_eq(sc, eq->id, num_eqes, FALSE, TRUE);
/* Process TX, RX and MCC. But dont arm CQ */
for (i = 0; i < eq->cq_valid; i++) {
@@ -440,14 +505,91 @@ oce_intr(void *arg)
/* Arm all cqs connected to this EQ */
for (i = 0; i < eq->cq_valid; i++) {
cq = eq->cq[i];
- oce_arm_cq(sc, cq->cq_id, 0, TRUE);
+ oce_arm_cq(sc, cq->id, 0, TRUE);
}
eq_arm:
- oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
+ oce_arm_eq(sc, eq->id, 0, TRUE, FALSE);
return (claimed);
}
+
+int
+oce_pci_alloc(struct oce_softc *sc)
+{
+ struct pci_attach_args *pa = &sc->pa;
+ pci_sli_intf_t intf;
+ pcireg_t memtype, reg;
+
+ /* setup the device config region */
+ if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
+ reg = OCE_BAR_CFG_BE2;
+ else
+ reg = OCE_BAR_CFG;
+
+ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
+ if (pci_mapreg_map(pa, reg, memtype, 0, &sc->cfg_iot,
+ &sc->cfg_ioh, NULL, &sc->cfg_size,
+ IS_BE(sc) ? 0 : 32768)) {
+ printf(": can't find cfg mem space\n");
+ return (ENXIO);
+ }
+
+ /* Read the SLI_INTF register and determine whether we
+ * can use this port and its features
+ */
+ intf.dw0 = pci_conf_read(pa->pa_pc, pa->pa_tag, OCE_INTF_REG_OFFSET);
+
+ if (intf.bits.sli_valid != OCE_INTF_VALID_SIG) {
+ printf(": invalid signature\n");
+ goto fail_1;
+ }
+
+ if (intf.bits.sli_rev != OCE_INTF_SLI_REV4) {
+ printf(": adapter doesnt support SLI revision %d\n",
+ intf.bits.sli_rev);
+ goto fail_1;
+ }
+
+ if (intf.bits.sli_if_type == OCE_INTF_IF_TYPE_1)
+ sc->flags |= OCE_FLAGS_MBOX_ENDIAN_RQD;
+
+ if (intf.bits.sli_hint1 == OCE_INTF_FUNC_RESET_REQD)
+ sc->flags |= OCE_FLAGS_FUNCRESET_RQD;
+
+ if (intf.bits.sli_func_type == OCE_INTF_VIRT_FUNC)
+ sc->flags |= OCE_FLAGS_VIRTUAL_PORT;
+
+ /* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */
+ if (IS_BE(sc)) {
+ /* set up CSR region */
+ reg = OCE_BAR_CSR;
+ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
+ if (pci_mapreg_map(pa, reg, memtype, 0, &sc->csr_iot,
+ &sc->csr_ioh, NULL, &sc->csr_size, 0)) {
+ printf(": can't find csr mem space\n");
+ goto fail_1;
+ }
+
+ /* set up DB doorbell region */
+ reg = OCE_BAR_DB;
+ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
+ if (pci_mapreg_map(pa, reg, memtype, 0, &sc->db_iot,
+ &sc->db_ioh, NULL, &sc->db_size, 0)) {
+ printf(": can't find csr mem space\n");
+ goto fail_2;
+ }
+ }
+
+ return (0);
+
+fail_2:
+ bus_space_unmap(sc->csr_iot, sc->csr_ioh, sc->csr_size);
+fail_1:
+ bus_space_unmap(sc->cfg_iot, sc->cfg_ioh, sc->cfg_size);
+ return (ENXIO);
+}
+
int
oce_alloc_intr(struct oce_softc *sc)
{
@@ -477,6 +619,26 @@ oce_alloc_intr(struct oce_softc *sc)
}
void
+oce_intr_enable(struct oce_softc *sc)
+{
+ uint32_t reg;
+
+ reg = OCE_READ_REG32(sc, cfg, PCICFG_INTR_CTRL);
+ reg |= HOSTINTR_MASK;
+ OCE_WRITE_REG32(sc, cfg, PCICFG_INTR_CTRL, reg);
+}
+
+void
+oce_intr_disable(struct oce_softc *sc)
+{
+ uint32_t reg;
+
+ reg = OCE_READ_REG32(sc, cfg, PCICFG_INTR_CTRL);
+ reg &= ~HOSTINTR_MASK;
+ OCE_WRITE_REG32(sc, cfg, PCICFG_INTR_CTRL, reg);
+}
+
+void
oce_update_link_status(struct oce_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ac_if;
@@ -712,7 +874,7 @@ retry:
oce_dma_sync(&wq->ring->dma, BUS_DMASYNC_PREREAD |
BUS_DMASYNC_PREWRITE);
- reg_value = (num_wqes << 16) | wq->wq_id;
+ reg_value = (num_wqes << 16) | wq->id;
OCE_WRITE_REG32(sc, db, PD_TXULP_DB, reg_value);
return 0;
@@ -726,7 +888,7 @@ free_ret:
void
oce_txeof(struct oce_wq *wq, uint32_t wqe_idx, uint32_t status)
{
- struct oce_softc *sc = (struct oce_softc *) wq->parent;
+ struct oce_softc *sc = (struct oce_softc *) wq->sc;
struct oce_packet_desc *pd;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m;
@@ -881,7 +1043,7 @@ void
oce_wq_handler(void *arg)
{
struct oce_wq *wq = (struct oce_wq *)arg;
- struct oce_softc *sc = wq->parent;
+ struct oce_softc *sc = wq->sc;
struct oce_cq *cq = wq->cq;
struct oce_nic_tx_cqe *cqe;
int num_cqes = 0;
@@ -906,13 +1068,13 @@ oce_wq_handler(void *arg)
}
if (num_cqes)
- oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
+ oce_arm_cq(sc, cq->id, num_cqes, FALSE);
}
void
oce_rxeof(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
{
- struct oce_softc *sc = (struct oce_softc *)rq->parent;
+ struct oce_softc *sc = (struct oce_softc *)rq->sc;
struct oce_packet_desc *pd;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m = NULL, *tail = NULL;
@@ -1047,7 +1209,7 @@ oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
{
uint32_t out, i = 0;
struct oce_packet_desc *pd;
- struct oce_softc *sc = (struct oce_softc *) rq->parent;
+ struct oce_softc *sc = (struct oce_softc *) rq->sc;
int num_frags = cqe->u0.s.num_fragments;
if (IS_XE201(sc) && cqe->u0.s.error) {
@@ -1115,7 +1277,7 @@ oce_rx_flush_lro(struct oce_rq *rq)
{
struct lro_ctrl *lro = &rq->lro;
struct lro_entry *queued;
- struct oce_softc *sc = (struct oce_softc *) rq->parent;
+ struct oce_softc *sc = (struct oce_softc *) rq->sc;
if (!IF_LRO_ENABLED(sc))
return;
@@ -1166,7 +1328,7 @@ oce_free_lro(struct oce_softc *sc)
int
oce_get_buf(struct oce_rq *rq)
{
- struct oce_softc *sc = (struct oce_softc *)rq->parent;
+ struct oce_softc *sc = (struct oce_softc *)rq->sc;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct oce_packet_desc *pd;
struct oce_nic_rqe *rqe;
@@ -1218,7 +1380,7 @@ oce_get_buf(struct oce_rq *rq)
int
oce_alloc_rx_bufs(struct oce_rq *rq)
{
- struct oce_softc *sc = (struct oce_softc *)rq->parent;
+ struct oce_softc *sc = (struct oce_softc *)rq->sc;
pd_rxulp_db_t rxdb_reg;
int i, nbufs = 0;
@@ -1230,14 +1392,14 @@ oce_alloc_rx_bufs(struct oce_rq *rq)
DELAY(1);
bzero(&rxdb_reg, sizeof(rxdb_reg));
rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS;
- rxdb_reg.bits.qid = rq->rq_id;
+ rxdb_reg.bits.qid = rq->id;
OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
nbufs -= OCE_MAX_RQ_POSTS;
}
if (nbufs > 0) {
DELAY(1);
bzero(&rxdb_reg, sizeof(rxdb_reg));
- rxdb_reg.bits.qid = rq->rq_id;
+ rxdb_reg.bits.qid = rq->id;
rxdb_reg.bits.num_posted = nbufs;
OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
}
@@ -1266,7 +1428,7 @@ oce_rq_handler(void *arg)
{
struct oce_rq *rq = (struct oce_rq *)arg;
struct oce_cq *cq = rq->cq;
- struct oce_softc *sc = rq->parent;
+ struct oce_softc *sc = rq->sc;
struct oce_nic_rx_cqe *cqe;
struct ifnet *ifp = &sc->arpcom.ac_if;
int num_cqes = 0, rq_buffers_used = 0;
@@ -1314,74 +1476,28 @@ oce_rq_handler(void *arg)
#endif
if (num_cqes) {
- oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
+ oce_arm_cq(sc, cq->id, num_cqes, FALSE);
rq_buffers_used = OCE_RQ_PACKET_ARRAY_SIZE - rq->pending;
if (rq_buffers_used > 1 && !oce_alloc_rx_bufs(rq))
timeout_add(&sc->rxrefill, 1);
}
}
-int
-oce_attach_ifp(struct oce_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifmedia_init(&sc->media, IFM_IMASK, oce_media_change, oce_media_status);
- ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
- ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
-
- strlcpy(ifp->if_xname, sc->dev.dv_xname, IFNAMSIZ);
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = oce_ioctl;
- ifp->if_start = oce_start;
- ifp->if_watchdog = oce_watchdog;
- ifp->if_hardmtu = OCE_MAX_MTU;
- ifp->if_softc = sc;
- IFQ_SET_MAXLEN(&ifp->if_snd, sc->tx_ring_size - 1);
- IFQ_SET_READY(&ifp->if_snd);
-
- /* oce splits jumbos into 2k chunks... */
- m_clsetwms(ifp, MCLBYTES, 8, sc->rx_ring_size);
-
- ifp->if_capabilities = IFCAP_VLAN_MTU;
-
-#if NVLAN > 0
- ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
-#endif
-
-#if defined(INET6) || defined(INET)
-#ifdef OCE_TSO
- ifp->if_capabilities |= IFCAP_TSO;
- ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
-#endif
-#ifdef OCE_LRO
- ifp->if_capabilities |= IFCAP_LRO;
-#endif
-#endif
-
- if_attach(ifp);
- ether_ifattach(ifp);
-
- return 0;
-}
-
void
-oce_mac_addr_set(struct oce_softc *sc)
+oce_set_macaddr(struct oce_softc *sc)
{
uint32_t old_pmac_id = sc->pmac_id;
int status = 0;
- if (!bcmp(sc->arpcom.ac_enaddr, sc->macaddr.mac_addr, ETH_ADDR_LEN))
+ if (!bcmp(sc->macaddr, sc->arpcom.ac_enaddr, ETH_ADDR_LEN))
return;
- status = oce_mbox_macaddr_add(sc, sc->arpcom.ac_enaddr, sc->if_id,
+ status = oce_macaddr_add(sc, sc->arpcom.ac_enaddr, sc->if_id,
&sc->pmac_id);
- if (!status) {
- status = oce_mbox_macaddr_del(sc, sc->if_id, old_pmac_id);
- bcopy(sc->arpcom.ac_enaddr, sc->macaddr.mac_addr,
- sc->macaddr.size_of_struct);
- } else
- printf("%s: Failed to update MAC address\n", sc->dev.dv_xname);
+ if (!status)
+ status = oce_macaddr_del(sc, sc->if_id, old_pmac_id);
+ else
+ printf("%s: failed to set MAC address\n", sc->dev.dv_xname);
}
void
@@ -1422,7 +1538,7 @@ oce_stop(struct oce_softc *sc)
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
/* Stop intrs and finish any bottom halves pending */
- oce_hw_intr_disable(sc);
+ oce_intr_disable(sc);
/* Invalidate any pending cq and eq entries */
for_all_eq_queues(sc, eq, i)
@@ -1452,7 +1568,7 @@ oce_init(void *arg)
DELAY(10);
- oce_mac_addr_set(sc);
+ oce_set_macaddr(sc);
oce_iff(sc);
@@ -1484,15 +1600,15 @@ oce_init(void *arg)
#endif
for_all_rq_queues(sc, rq, i)
- oce_arm_cq(rq->parent, rq->cq->cq_id, 0, TRUE);
+ oce_arm_cq(rq->sc, rq->cq->id, 0, TRUE);
for_all_wq_queues(sc, wq, i)
- oce_arm_cq(wq->parent, wq->cq->cq_id, 0, TRUE);
+ oce_arm_cq(wq->sc, wq->cq->id, 0, TRUE);
- oce_arm_cq(sc->mq->parent, sc->mq->cq->cq_id, 0, TRUE);
+ oce_arm_cq(sc->mq->sc, sc->mq->cq->id, 0, TRUE);
for_all_eq_queues(sc, eq, i)
- oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
+ oce_arm_eq(sc, eq->id, 0, TRUE, FALSE);
if (oce_get_link_status(sc) == 0)
oce_update_link_status(sc);
@@ -1502,7 +1618,7 @@ oce_init(void *arg)
timeout_add_sec(&sc->timer, 1);
- oce_hw_intr_enable(sc);
+ oce_intr_enable(sc);
return;
error:
@@ -1531,7 +1647,7 @@ void
oce_mq_handler(void *arg)
{
struct oce_mq *mq = (struct oce_mq *)arg;
- struct oce_softc *sc = mq->parent;
+ struct oce_softc *sc = mq->sc;
struct oce_cq *cq = mq->cq;
struct oce_mq_cqe *cqe;
struct oce_async_cqe_link_state *acqe;
@@ -1568,7 +1684,7 @@ oce_mq_handler(void *arg)
}
if (num_cqes)
- oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE /* TRUE */);
+ oce_arm_cq(sc, cq->id, num_cqes, FALSE /* TRUE */);
}
int
@@ -1594,7 +1710,7 @@ oce_init_queues(struct oce_softc *sc)
}
/* Create network interface on card */
- if (oce_create_iface(sc))
+ if (oce_create_iface(sc, sc->macaddr))
goto error;
/* create all of the event queues */
@@ -1685,9 +1801,8 @@ oce_wq_init(struct oce_softc *sc, uint32_t q_len, uint32_t wq_type)
wq->cfg.wq_type = (uint8_t) wq_type;
wq->cfg.eqd = OCE_DEFAULT_WQ_EQD;
wq->cfg.nbufs = 2 * wq->cfg.q_len;
- wq->cfg.nhdl = 2 * wq->cfg.q_len;
- wq->parent = sc;
+ wq->sc = sc;
wq->tag = sc->pa.pa_dmat;
for (i = 0; i < OCE_WQ_PACKET_ARRAY_SIZE; i++) {
@@ -1712,11 +1827,11 @@ free_wq:
void
oce_wq_destroy(struct oce_wq *wq)
{
- struct oce_softc *sc = wq->parent;
+ struct oce_softc *sc = wq->sc;
int i;
- if (wq->qstate == QCREATED)
- oce_mbox_destroy_q(sc, QTYPE_WQ, wq->wq_id);
+ if (wq->state == QCREATED)
+ oce_destroy_queue(sc, QTYPE_WQ, wq->id);
if (wq->cq != NULL)
oce_cq_destroy(wq->cq);
@@ -1742,7 +1857,7 @@ oce_wq_destroy(struct oce_wq *wq)
int
oce_wq_create(struct oce_wq *wq, struct oce_eq *eq)
{
- struct oce_softc *sc = wq->parent;
+ struct oce_softc *sc = wq->sc;
struct oce_cq *cq;
int rc = 0;
@@ -1753,12 +1868,11 @@ oce_wq_create(struct oce_wq *wq, struct oce_eq *eq)
wq->cq = cq;
- rc = oce_mbox_create_wq(wq);
+ rc = oce_create_wq(sc, wq);
if (rc)
goto error;
- wq->qstate = QCREATED;
- wq->wq_free = wq->cfg.q_len;
+ wq->state = QCREATED;
wq->ring->cidx = 0;
wq->ring->pidx = 0;
@@ -1804,7 +1918,7 @@ oce_rq_init(struct oce_softc *sc, uint32_t q_len, uint32_t frag_size,
rq->cfg.frag_size = frag_size;
rq->cfg.is_rss_queue = rss;
- rq->parent = sc;
+ rq->sc = sc;
rq->tag = sc->pa.pa_dmat;
for (i = 0; i < OCE_RQ_PACKET_ARRAY_SIZE; i++) {
@@ -1827,11 +1941,11 @@ free_rq:
void
oce_rq_destroy(struct oce_rq *rq)
{
- struct oce_softc *sc = rq->parent;
+ struct oce_softc *sc = rq->sc;
int i;
- if (rq->qstate == QCREATED)
- oce_mbox_destroy_q(sc, QTYPE_RQ, rq->rq_id);
+ if (rq->state == QCREATED)
+ oce_destroy_queue(sc, QTYPE_RQ, rq->id);
if (rq->cq != NULL)
oce_cq_destroy(rq->cq);
@@ -1860,7 +1974,7 @@ oce_rq_destroy(struct oce_rq *rq)
int
oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq)
{
- struct oce_softc *sc = rq->parent;
+ struct oce_softc *sc = rq->sc;
struct oce_cq *cq;
cq = oce_cq_create(sc, eq, CQ_LEN_1024, sizeof(struct oce_nic_rx_cqe),
@@ -1883,10 +1997,12 @@ oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq)
int
oce_start_rq(struct oce_rq *rq)
{
- if (rq->qstate != QCREATED) {
- if (oce_mbox_create_rq(rq))
+ struct oce_softc *sc = rq->sc;
+
+ if (rq->state != QCREATED) {
+ if (oce_create_rq(sc, rq))
return 1;
- rq->qstate = QCREATED;
+ rq->state = QCREATED;
rq->pending = 0;
rq->ring->cidx = 0;
rq->ring->pidx = 0;
@@ -1900,11 +2016,11 @@ oce_start_rq(struct oce_rq *rq)
void
oce_stop_rq(struct oce_rq *rq)
{
- struct oce_softc *sc = rq->parent;
+ struct oce_softc *sc = rq->sc;
- if (rq->qstate == QCREATED) {
- oce_mbox_destroy_q(sc, QTYPE_RQ, rq->rq_id);
- rq->qstate = QDELETED;
+ if (rq->state == QCREATED) {
+ oce_destroy_queue(sc, QTYPE_RQ, rq->id);
+ rq->state = QDELETED;
DELAY(10);
}
}
@@ -1936,13 +2052,13 @@ oce_eq_create(struct oce_softc *sc, uint32_t q_len, uint32_t item_size,
return NULL;
}
- eq->parent = sc;
- eq->eq_id = 0xffff;
- eq->eq_cfg.q_len = q_len;
- eq->eq_cfg.item_size = item_size;
- eq->eq_cfg.cur_eqd = (uint8_t)eq_delay;
+ eq->sc = sc;
+ eq->id = 0xffff;
+ eq->cfg.q_len = q_len;
+ eq->cfg.item_size = item_size;
+ eq->cfg.cur_eqd = (uint8_t)eq_delay;
- rc = oce_mbox_create_eq(eq);
+ rc = oce_create_eq(sc, eq);
if (rc)
goto free_eq;
@@ -1955,10 +2071,10 @@ free_eq:
void
oce_eq_destroy(struct oce_eq *eq)
{
- struct oce_softc *sc = eq->parent;
+ struct oce_softc *sc = eq->sc;
- if (eq->eq_id != 0xffff)
- oce_mbox_destroy_q(sc, QTYPE_EQ, eq->eq_id);
+ if (eq->id != 0xffff)
+ oce_destroy_queue(sc, QTYPE_EQ, eq->id);
if (eq->ring != NULL)
oce_destroy_ring(sc, eq->ring);
@@ -1992,7 +2108,7 @@ oce_mq_create(struct oce_softc *sc, struct oce_eq *eq, uint32_t q_len)
return NULL;
}
- mq->parent = sc;
+ mq->sc = sc;
mq->cq = cq;
mq->ring = oce_create_ring(sc, q_len, sizeof(struct oce_mbx), 8);
@@ -2001,14 +2117,14 @@ oce_mq_create(struct oce_softc *sc, struct oce_eq *eq, uint32_t q_len)
mq->cfg.q_len = (uint8_t)q_len;
- rc = oce_mbox_create_mq(mq);
+ rc = oce_create_mq(sc, mq);
if (rc)
goto free_mq;
eq->cq[eq->cq_valid] = cq;
eq->cq_valid++;
mq->cq->eq = eq;
- mq->qstate = QCREATED;
+ mq->state = QCREATED;
mq->cq->cb_arg = mq;
mq->cq->cq_handler = oce_mq_handler;
@@ -2021,10 +2137,10 @@ free_mq:
void
oce_mq_destroy(struct oce_mq *mq)
{
- struct oce_softc *sc = mq->parent;
+ struct oce_softc *sc = mq->sc;
- if (mq->qstate == QCREATED)
- oce_mbox_destroy_q(sc, QTYPE_MQ, mq->mq_id);
+ if (mq->state == QCREATED)
+ oce_destroy_queue(sc, QTYPE_MQ, mq->id);
if (mq->ring != NULL)
oce_destroy_ring(sc, mq->ring);
@@ -2048,7 +2164,7 @@ oce_mq_destroy(struct oce_mq *mq)
*/
struct oce_cq *
oce_cq_create(struct oce_softc *sc, struct oce_eq *eq, uint32_t q_len,
- uint32_t item_size, uint32_t is_eventable, uint32_t nodelay,
+ uint32_t item_size, uint32_t eventable, uint32_t nodelay,
uint32_t ncoalesce)
{
struct oce_cq *cq = NULL;
@@ -2064,13 +2180,15 @@ oce_cq_create(struct oce_softc *sc, struct oce_eq *eq, uint32_t q_len,
return NULL;
}
- cq->parent = sc;
+ cq->sc = sc;
cq->eq = eq;
- cq->cq_cfg.q_len = q_len;
- cq->cq_cfg.item_size = item_size;
- cq->cq_cfg.nodelay = (uint8_t) nodelay;
+ cq->cfg.q_len = q_len;
+ cq->cfg.item_size = item_size;
+ cq->cfg.nodelay = (uint8_t) nodelay;
+ cq->cfg.ncoalesce = ncoalesce;
+ cq->cfg.eventable = eventable;
- rc = oce_mbox_create_cq(cq, ncoalesce, is_eventable);
+ rc = oce_create_cq(sc, cq);
if (rc)
goto free_cq;
@@ -2085,10 +2203,10 @@ free_cq:
void
oce_cq_destroy(struct oce_cq *cq)
{
- struct oce_softc *sc = cq->parent;
+ struct oce_softc *sc = cq->sc;
if (cq->ring != NULL) {
- oce_mbox_destroy_q(sc, QTYPE_CQ, cq->cq_id);
+ oce_destroy_queue(sc, QTYPE_CQ, cq->id);
oce_destroy_ring(sc, cq->ring);
}
@@ -2147,7 +2265,7 @@ oce_drain_eq(struct oce_eq *eq)
{
struct oce_eqe *eqe;
uint16_t num_eqe = 0;
- struct oce_softc *sc = eq->parent;
+ struct oce_softc *sc = eq->sc;
for (;;) {
eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
@@ -2159,13 +2277,13 @@ oce_drain_eq(struct oce_eq *eq)
RING_GET(eq->ring, 1);
}
- oce_arm_eq(sc, eq->eq_id, num_eqe, FALSE, TRUE);
+ oce_arm_eq(sc, eq->id, num_eqe, FALSE, TRUE);
}
void
oce_drain_wq(struct oce_wq *wq)
{
- struct oce_softc *sc = wq->parent;
+ struct oce_softc *sc = wq->sc;
struct oce_cq *cq = wq->cq;
struct oce_nic_tx_cqe *cqe;
int num_cqes = 0;
@@ -2182,7 +2300,7 @@ oce_drain_wq(struct oce_wq *wq)
num_cqes++;
}
- oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
+ oce_arm_cq(sc, cq->id, num_cqes, FALSE);
}
/*
@@ -2210,7 +2328,7 @@ oce_drain_rq(struct oce_rq *rq)
struct oce_cq *cq;
struct oce_softc *sc;
- sc = rq->parent;
+ sc = rq->sc;
cq = rq->cq;
cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
/* dequeue till you reach an invalid cqe */
@@ -2222,7 +2340,7 @@ oce_drain_rq(struct oce_rq *rq)
num_cqe++;
}
- oce_arm_cq(sc, cq->cq_id, num_cqe, FALSE);
+ oce_arm_cq(sc, cq->id, num_cqe, FALSE);
}
void
@@ -2324,13 +2442,6 @@ oce_dma_free(struct oce_softc *sc, struct oce_dma_mem *dma)
}
}
-void
-oce_destroy_ring(struct oce_softc *sc, struct oce_ring *ring)
-{
- oce_dma_free(sc, &ring->dma);
- free(ring, M_DEVBUF);
-}
-
struct oce_ring *
oce_create_ring(struct oce_softc *sc, int q_len, int item_size,
int max_segs)
@@ -2389,6 +2500,13 @@ fail_0:
return NULL;
}
+void
+oce_destroy_ring(struct oce_softc *sc, struct oce_ring *ring)
+{
+ oce_dma_free(sc, &ring->dma);
+ free(ring, M_DEVBUF);
+}
+
int
oce_load_ring(struct oce_softc *sc, struct oce_ring *ring,
struct phys_addr *pa_list, int max_segs)
diff --git a/sys/dev/pci/oce.c b/sys/dev/pci/oce.c
index 389fa3b8ee0..73e7253757c 100644
--- a/sys/dev/pci/oce.c
+++ b/sys/dev/pci/oce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: oce.c,v 1.10 2012/10/12 15:16:45 mikeb Exp $ */
+/* $OpenBSD: oce.c,v 1.11 2012/10/12 17:41:40 mikeb Exp $ */
/*
* Copyright (c) 2012 Mike Belopuhov
@@ -96,20 +96,12 @@
#include <dev/pci/ocereg.h>
#include <dev/pci/ocevar.h>
-int oce_reset_fw(struct oce_softc *sc);
-int oce_post(struct oce_softc *sc);
int oce_mbox_wait(struct oce_softc *sc);
int oce_mbox_dispatch(struct oce_softc *sc);
-int oce_mbox_init(struct oce_softc *sc);
int oce_fw(struct oce_softc *sc, int subsys, int opcode, int version,
void *payload, int length);
-int oce_get_fw_version(struct oce_softc *sc);
-int oce_get_fw_config(struct oce_softc *sc);
-int oce_if_create(struct oce_softc *sc, uint32_t cap_flags, uint32_t en_flags,
- uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id);
-int oce_if_del(struct oce_softc *sc, uint32_t if_id);
int oce_config_vlan(struct oce_softc *sc, uint32_t if_id,
struct normal_vlan *vtag_arr, uint8_t vtag_cnt, uint32_t untagged,
uint32_t enable_promisc);
@@ -119,22 +111,22 @@ int oce_rss_itbl_init(struct oce_softc *sc, struct mbx_config_nic_rss *fwcmd);
int oce_set_common_iface_rx_filter(struct oce_softc *sc,
struct oce_dma_mem *sgl);
-int oce_mbox_check_native_mode(struct oce_softc *sc);
-
int oce_mbox_get_nic_stats_v0(struct oce_softc *sc, void *buf);
int oce_mbox_get_nic_stats(struct oce_softc *sc, void *buf);
int oce_mbox_get_pport_stats(struct oce_softc *sc, void *buf,
uint32_t reset_stats);
/**
- * @brief Function to post status
+ * @brief Wait for FW to become ready and reset it
* @param sc software handle to the device
*/
int
-oce_post(struct oce_softc *sc)
+oce_init_fw(struct oce_softc *sc)
{
+ struct ioctl_common_function_reset fwcmd;
mpu_ep_semaphore_t post_status;
int tmo = 60000;
+ int err = 0;
/* read semaphore CSR */
post_status.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_SEMAPHORE(sc));
@@ -145,7 +137,7 @@ oce_post(struct oce_softc *sc)
OCE_WRITE_REG32(sc, csr, MPU_EP_SEMAPHORE(sc), post_status.dw0);
}
- /* wait for FW ready */
+ /* wait for FW to become ready */
for (;;) {
if (--tmo == 0)
break;
@@ -154,169 +146,42 @@ oce_post(struct oce_softc *sc)
post_status.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_SEMAPHORE(sc));
if (post_status.bits.error) {
- printf("%s: POST failed: %x\n", sc->dev.dv_xname,
- post_status.dw0);
+ printf(": POST failed: %x\n", post_status.dw0);
return ENXIO;
}
- if (post_status.bits.stage == POST_STAGE_ARMFW_READY)
- return 0;
+ if (post_status.bits.stage == POST_STAGE_ARMFW_READY) {
+ /* reset FW */
+ bzero(&fwcmd, sizeof(fwcmd));
+ if (sc->flags & OCE_FLAGS_FUNCRESET_RQD)
+ err = oce_fw(sc, MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_FUNCTION_RESET, OCE_MBX_VER_V0,
+ &fwcmd, sizeof(fwcmd));
+ return (err);
+ }
}
- printf("%s: POST timed out: %x\n", sc->dev.dv_xname, post_status.dw0);
+ printf(": POST timed out: %x\n", post_status.dw0);
return ENXIO;
}
/**
- * @brief Function for hardware initialization
- * @param sc software handle to the device
- */
-int
-oce_hw_init(struct oce_softc *sc)
-{
- int rc = 0;
-
- rc = oce_post(sc);
- if (rc)
- return rc;
-
- /* create the bootstrap mailbox */
- rc = oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->bsmbx);
- if (rc) {
- printf("%s: Mailbox alloc failed\n", sc->dev.dv_xname);
- return rc;
- }
-
- rc = oce_reset_fw(sc);
- if (rc)
- goto error;
-
- rc = oce_mbox_init(sc);
- if (rc)
- goto error;
-
- rc = oce_get_fw_version(sc);
- if (rc)
- goto error;
-
- rc = oce_get_fw_config(sc);
- if (rc)
- goto error;
-
- sc->macaddr.size_of_struct = 6;
- rc = oce_read_mac_addr(sc, 0, 1, MAC_ADDRESS_TYPE_NETWORK,
- &sc->macaddr);
- if (rc)
- goto error;
-
- if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) {
- rc = oce_mbox_check_native_mode(sc);
- if (rc)
- goto error;
- } else
- sc->be3_native = 0;
-
- return rc;
-
-error:
- oce_dma_free(sc, &sc->bsmbx);
- printf("%s: Hardware initialisation failed\n", sc->dev.dv_xname);
- return rc;
-}
-
-/**
* @brief Allocate PCI resources.
*
* @param sc software handle to the device
* @returns 0 if successful, or error
*/
-int
-oce_hw_pci_alloc(struct oce_softc *sc)
-{
- struct pci_attach_args *pa = &sc->pa;
- pci_sli_intf_t intf;
- pcireg_t memtype, reg;
-
- /* setup the device config region */
- if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
- reg = OCE_BAR_CFG_BE2;
- else
- reg = OCE_BAR_CFG;
-
- memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
- if (pci_mapreg_map(pa, reg, memtype, 0, &sc->cfg_btag,
- &sc->cfg_bhandle, NULL, &sc->cfg_size,
- IS_BE(sc) ? 0 : 32768)) {
- printf(": can't find cfg mem space\n");
- return ENXIO;
- }
-
- /* Read the SLI_INTF register and determine whether we
- * can use this port and its features
- */
- intf.dw0 = pci_conf_read(pa->pa_pc, pa->pa_tag, OCE_INTF_REG_OFFSET);
-
- if (intf.bits.sli_valid != OCE_INTF_VALID_SIG) {
- printf(": invalid signature\n");
- goto fail_1;
- }
-
- if (intf.bits.sli_rev != OCE_INTF_SLI_REV4) {
- printf(": adapter doesnt support SLI revision %d\n",
- intf.bits.sli_rev);
- goto fail_1;
- }
-
- if (intf.bits.sli_if_type == OCE_INTF_IF_TYPE_1)
- sc->flags |= OCE_FLAGS_MBOX_ENDIAN_RQD;
-
- if (intf.bits.sli_hint1 == OCE_INTF_FUNC_RESET_REQD)
- sc->flags |= OCE_FLAGS_FUNCRESET_RQD;
-
- if (intf.bits.sli_func_type == OCE_INTF_VIRT_FUNC)
- sc->flags |= OCE_FLAGS_VIRTUAL_PORT;
-
- /* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */
- if (IS_BE(sc)) {
- /* set up CSR region */
- reg = OCE_BAR_CSR;
- memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
- if (pci_mapreg_map(pa, reg, memtype, 0, &sc->csr_btag,
- &sc->csr_bhandle, NULL, &sc->csr_size, 0)) {
- printf(": can't find csr mem space\n");
- goto fail_1;
- }
-
- /* set up DB doorbell region */
- reg = OCE_BAR_DB;
- memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
- if (pci_mapreg_map(pa, reg, memtype, 0, &sc->db_btag,
- &sc->db_bhandle, NULL, &sc->db_size, 0)) {
- printf(": can't find csr mem space\n");
- goto fail_2;
- }
- }
-
- return 0;
-
-fail_2:
- bus_space_unmap(sc->csr_btag, sc->csr_bhandle, sc->csr_size);
-fail_1:
- bus_space_unmap(sc->cfg_btag, sc->cfg_bhandle, sc->cfg_size);
- return ENXIO;
-}
-
/**
* @brief Function for creating nw interface.
* @param sc software handle to the device
* @returns 0 on success, error otherwise
*/
int
-oce_create_iface(struct oce_softc *sc)
+oce_create_iface(struct oce_softc *sc, uint8_t *macaddr)
{
- int rc;
- uint32_t capab_flags;
- uint32_t capab_en_flags;
+ struct mbx_create_common_iface fwcmd;
+ uint32_t capab_flags, capab_en_flags;
+ int err = 0;
/* interface capabilities to give device when creating interface */
capab_flags = OCE_CAPAB_FLAGS;
@@ -338,104 +203,42 @@ oce_create_iface(struct oce_softc *sc)
capab_flags &= ~MBX_RX_IFACE_FLAGS_RSS;
}
- rc = oce_if_create(sc, capab_flags, capab_en_flags, 0,
- &sc->macaddr.mac_addr[0], &sc->if_id);
- if (rc)
- return rc;
-
- sc->nifs++;
-
- sc->if_cap_flags = capab_en_flags;
-
- /* Enable VLAN Promisc on HW */
- rc = oce_config_vlan(sc, (uint8_t)sc->if_id, NULL, 0, 1, 1);
- if (rc)
- goto error;
-
- /* set default flow control */
- rc = oce_set_flow_control(sc, sc->flow_control);
- if (rc)
- goto error;
-
- return rc;
-
-error:
- oce_if_del(sc, sc->if_id);
- sc->nifs--;
- return rc;
-}
-
-/**
- * @brief Function for hardware enable interupts.
- * @param sc software handle to the device
- */
-void
-oce_hw_intr_enable(struct oce_softc *sc)
-{
- uint32_t reg;
-
- reg = OCE_READ_REG32(sc, cfg, PCICFG_INTR_CTRL);
- reg |= HOSTINTR_MASK;
- OCE_WRITE_REG32(sc, cfg, PCICFG_INTR_CTRL, reg);
-}
+ bzero(&fwcmd, sizeof(fwcmd));
-/**
- * @brief Function for hardware disable interupts
- * @param sc software handle to the device
- */
-void
-oce_hw_intr_disable(struct oce_softc *sc)
-{
- uint32_t reg;
+ fwcmd.params.req.version = 0;
+ fwcmd.params.req.cap_flags = htole32(capab_flags);
+ fwcmd.params.req.enable_flags = htole32(capab_en_flags);
+ if (macaddr != NULL) {
+ bcopy(macaddr, &fwcmd.params.req.mac_addr[0], ETH_ADDR_LEN);
+ fwcmd.params.req.mac_invalid = 0;
+ } else
+ fwcmd.params.req.mac_invalid = 1;
- reg = OCE_READ_REG32(sc, cfg, PCICFG_INTR_CTRL);
- reg &= ~HOSTINTR_MASK;
- OCE_WRITE_REG32(sc, cfg, PCICFG_INTR_CTRL, reg);
-}
+ err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_IFACE,
+ OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
+ if (err)
+ return (err);
-/**
- * @brief Function for hardware update multicast filter
- * @param sc software handle to the device
- * @param multi table of multicast addresses
- * @param naddr number of multicast addresses in the table
- */
-int
-oce_update_mcast(struct oce_softc *sc,
- uint8_t multi[][ETH_ADDR_LEN], int naddr)
-{
- struct mbx_set_common_iface_multicast fwcmd;
- int err;
+ sc->if_id = letoh32(fwcmd.params.rsp.if_id);
- bzero(&fwcmd, sizeof(fwcmd));
+ if (macaddr != NULL)
+ sc->pmac_id = letoh32(fwcmd.params.rsp.pmac_id);
- bcopy(&multi[0], &fwcmd.params.req.mac[0], naddr * ETH_ADDR_LEN);
- fwcmd.params.req.num_mac = htole16(naddr);
- fwcmd.params.req.if_id = sc->if_id;
+ sc->nifs++;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON,
- OPCODE_COMMON_SET_IFACE_MULTICAST, OCE_MBX_VER_V0,
- &fwcmd, sizeof(fwcmd));
- return (err);
-}
+ sc->if_cap_flags = capab_en_flags;
-/**
- * @brief Reset (firmware) common function
- * @param sc software handle to the device
- * @returns 0 on success, ETIMEDOUT on failure
- */
-int
-oce_reset_fw(struct oce_softc *sc)
-{
- struct ioctl_common_function_reset fwcmd;
- int err = 0;
+ /* Enable VLAN Promisc on HW */
+ err = oce_config_vlan(sc, (uint8_t)sc->if_id, NULL, 0, 1, 1);
+ if (err)
+ return (err);
- bzero(&fwcmd, sizeof(fwcmd));
+ /* set default flow control */
+ err = oce_set_flow_control(sc, sc->flow_control);
+ if (err)
+ return (err);
- if (sc->flags & OCE_FLAGS_FUNCRESET_RQD)
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON,
- OPCODE_COMMON_FUNCTION_RESET, OCE_MBX_VER_V0,
- &fwcmd, sizeof(fwcmd));
- return (err);
+ return 0;
}
/**
@@ -619,80 +422,6 @@ oce_get_fw_version(struct oce_softc *sc)
}
/**
- * @brief Firmware will send gracious notifications during
- * attach only after sending first mcc commnad. We
- * use MCC queue only for getting async and mailbox
- * for sending cmds. So to get gracious notifications
- * atleast send one dummy command on mcc.
- */
-int
-oce_first_mcc_cmd(struct oce_softc *sc)
-{
- struct oce_mbx *mbx;
- struct oce_mq *mq = sc->mq;
- struct mbx_hdr *hdr;
- struct mbx_get_common_fw_version *fwcmd;
- uint32_t reg_value;
-
- mbx = RING_GET_PRODUCER_ITEM_VA(mq->ring, struct oce_mbx);
- bzero(mbx, sizeof(struct oce_mbx));
-
- fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
-
- hdr = &fwcmd->hdr;
- hdr->u0.req.subsystem = MBX_SUBSYSTEM_COMMON;
- hdr->u0.req.opcode = OPCODE_COMMON_GET_FW_VERSION;
- hdr->u0.req.version = OCE_MBX_VER_V0;
- hdr->u0.req.timeout = MBX_TIMEOUT_SEC;
- hdr->u0.req.request_length = sizeof(*fwcmd) - sizeof(*hdr);
-
- mbx->u0.s.embedded = 1;
- mbx->payload_length = sizeof(*fwcmd);
- oce_dma_sync(&mq->ring->dma, BUS_DMASYNC_PREREAD |
- BUS_DMASYNC_PREWRITE);
- RING_PUT(mq->ring, 1);
- reg_value = (1 << 16) | mq->mq_id;
- OCE_WRITE_REG32(sc, db, PD_MQ_DB, reg_value);
-
- return 0;
-}
-
-/**
- * @brief Function to read the mac address associated with an interface
- * @param sc software handle to the device
- * @param if_id interface id to read the address from
- * @param perm set to 1 if reading the factory mac address.
- * In this case if_id is ignored
- * @param type type of the mac address, whether network or storage
- * @param[out] mac [OUTPUT] pointer to a buffer containing the
- * mac address when the command succeeds.
- * @returns 0 on success, EIO on failure
- */
-int
-oce_read_mac_addr(struct oce_softc *sc, uint32_t if_id, uint8_t perm,
- uint8_t type, struct mac_address_format *mac)
-{
- struct mbx_query_common_iface_mac fwcmd;
- int err;
-
- bzero(&fwcmd, sizeof(fwcmd));
-
- fwcmd.params.req.type = type;
- fwcmd.params.req.permanent = perm;
- if (!perm)
- fwcmd.params.req.if_id = (uint16_t)if_id;
-
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_QUERY_IFACE_MAC,
- OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
- if (err == 0) {
- mac->size_of_struct = fwcmd.params.rsp.mac.size_of_struct;
- bcopy(&fwcmd.params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
- mac->size_of_struct);
- }
- return (err);
-}
-
-/**
* @brief Function to query the fw attributes from the hw
* @param sc software handle to the device
* @returns 0 on success, EIO on failure
@@ -711,7 +440,6 @@ oce_get_fw_config(struct oce_softc *sc)
if (err)
return (err);
- sc->config_number = fwcmd.params.rsp.config_number;
sc->asic_revision = fwcmd.params.rsp.asic_revision;
sc->port_id = fwcmd.params.rsp.port_id;
sc->function_mode = fwcmd.params.rsp.function_mode;
@@ -729,67 +457,59 @@ oce_get_fw_config(struct oce_softc *sc)
}
/**
- *
- * @brief function to create a device interface
- * @param sc software handle to the device
- * @param cap_flags capability flags
- * @param en_flags enable capability flags
- * @param vlan_tag optional vlan tag to associate with the if
- * @param mac_addr pointer to a buffer containing the mac address
- * @param[out] if_id [OUTPUT] pointer to an integer to hold the ID of the
- interface created
- * @returns 0 on success, EIO on failure
+ * @brief Firmware will send gracious notifications during
+ * attach only after sending first mcc commnad. We
+ * use MCC queue only for getting async and mailbox
+ * for sending cmds. So to get gracious notifications
+ * atleast send one dummy command on mcc.
*/
int
-oce_if_create(struct oce_softc *sc, uint32_t cap_flags, uint32_t en_flags,
- uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id)
+oce_first_mcc_cmd(struct oce_softc *sc)
{
- struct mbx_create_common_iface fwcmd;
- int err = 0;
-
- bzero(&fwcmd, sizeof(fwcmd));
+ struct oce_mbx *mbx;
+ struct oce_mq *mq = sc->mq;
+ struct mbx_hdr *hdr;
+ struct mbx_get_common_fw_version *fwcmd;
+ uint32_t reg_value;
- fwcmd.params.req.version = 0;
- fwcmd.params.req.cap_flags = htole32(cap_flags);
- fwcmd.params.req.enable_flags = htole32(en_flags);
- if (mac_addr != NULL) {
- bcopy(mac_addr, &fwcmd.params.req.mac_addr[0], 6);
- fwcmd.params.req.vlan_tag.u0.normal.vtag = htole16(vlan_tag);
- fwcmd.params.req.mac_invalid = 0;
- } else
- fwcmd.params.req.mac_invalid = 1;
+ mbx = RING_GET_PRODUCER_ITEM_VA(mq->ring, struct oce_mbx);
+ bzero(mbx, sizeof(struct oce_mbx));
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_IFACE,
- OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
- if (err)
- return (err);
+ fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
- *if_id = letoh32(fwcmd.params.rsp.if_id);
+ hdr = &fwcmd->hdr;
+ hdr->u0.req.subsystem = MBX_SUBSYSTEM_COMMON;
+ hdr->u0.req.opcode = OPCODE_COMMON_GET_FW_VERSION;
+ hdr->u0.req.version = OCE_MBX_VER_V0;
+ hdr->u0.req.timeout = MBX_TIMEOUT_SEC;
+ hdr->u0.req.request_length = sizeof(*fwcmd) - sizeof(*hdr);
- if (mac_addr != NULL)
- sc->pmac_id = letoh32(fwcmd.params.rsp.pmac_id);
+ mbx->u0.s.embedded = 1;
+ mbx->payload_length = sizeof(*fwcmd);
+ oce_dma_sync(&mq->ring->dma, BUS_DMASYNC_PREREAD |
+ BUS_DMASYNC_PREWRITE);
+ RING_PUT(mq->ring, 1);
+ reg_value = (1 << 16) | mq->id;
+ OCE_WRITE_REG32(sc, db, PD_MQ_DB, reg_value);
- return (0);
+ return 0;
}
-/**
- * @brief Function to delete an interface
- * @param sc software handle to the device
- * @param if_id ID of the interface to delete
- * @returns 0 on success, EIO on failure
- */
int
-oce_if_del(struct oce_softc *sc, uint32_t if_id)
+oce_read_macaddr(struct oce_softc *sc, uint8_t *macaddr)
{
- struct mbx_destroy_common_iface fwcmd;
+ struct mbx_query_common_iface_mac fwcmd;
int err;
bzero(&fwcmd, sizeof(fwcmd));
- fwcmd.params.req.if_id = if_id;
+ fwcmd.params.req.type = MAC_ADDRESS_TYPE_NETWORK;
+ fwcmd.params.req.permanent = 1;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_DESTROY_IFACE,
+ err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_QUERY_IFACE_MAC,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
+ if (err == 0)
+ bcopy(&fwcmd.params.rsp.mac.mac_addr[0], macaddr, ETH_ADDR_LEN);
return (err);
}
@@ -929,6 +649,31 @@ oce_config_nic_rss(struct oce_softc *sc, uint32_t if_id, uint16_t enable_rss)
#endif /* OCE_RSS */
/**
+ * @brief Function for hardware update multicast filter
+ * @param sc software handle to the device
+ * @param multi table of multicast addresses
+ * @param naddr number of multicast addresses in the table
+ */
+int
+oce_update_mcast(struct oce_softc *sc,
+ uint8_t multi[][ETH_ADDR_LEN], int naddr)
+{
+ struct mbx_set_common_iface_multicast fwcmd;
+ int err;
+
+ bzero(&fwcmd, sizeof(fwcmd));
+
+ bcopy(&multi[0], &fwcmd.params.req.mac[0], naddr * ETH_ADDR_LEN);
+ fwcmd.params.req.num_mac = htole16(naddr);
+ fwcmd.params.req.if_id = sc->if_id;
+
+ err = oce_fw(sc, MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_IFACE_MULTICAST, OCE_MBX_VER_V0,
+ &fwcmd, sizeof(fwcmd));
+ return (err);
+}
+
+/**
* @brief RXF function to enable/disable device promiscuous mode
* @param sc software handle to the device
* @param enable enable/disable flag
@@ -999,7 +744,7 @@ oce_get_link_status(struct oce_softc *sc)
}
int
-oce_mbox_macaddr_add(struct oce_softc *sc, uint8_t *mac_addr, uint32_t if_id,
+oce_macaddr_add(struct oce_softc *sc, uint8_t *enaddr, uint32_t if_id,
uint32_t *pmac_id)
{
struct mbx_add_common_iface_mac fwcmd;
@@ -1008,7 +753,7 @@ oce_mbox_macaddr_add(struct oce_softc *sc, uint8_t *mac_addr, uint32_t if_id,
bzero(&fwcmd, sizeof(fwcmd));
fwcmd.params.req.if_id = htole16(if_id);
- bcopy(mac_addr, fwcmd.params.req.mac_address, ETH_ADDR_LEN);
+ bcopy(enaddr, fwcmd.params.req.mac_address, ETH_ADDR_LEN);
err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_ADD_IFACE_MAC,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
@@ -1018,7 +763,7 @@ oce_mbox_macaddr_add(struct oce_softc *sc, uint8_t *mac_addr, uint32_t if_id,
}
int
-oce_mbox_macaddr_del(struct oce_softc *sc, uint32_t if_id, uint32_t pmac_id)
+oce_macaddr_del(struct oce_softc *sc, uint32_t if_id, uint32_t pmac_id)
{
struct mbx_del_common_iface_mac fwcmd;
int err;
@@ -1034,7 +779,7 @@ oce_mbox_macaddr_del(struct oce_softc *sc, uint32_t if_id, uint32_t pmac_id)
}
int
-oce_mbox_check_native_mode(struct oce_softc *sc)
+oce_check_native_mode(struct oce_softc *sc)
{
struct mbx_common_set_function_cap fwcmd;
int err;
@@ -1058,15 +803,11 @@ oce_mbox_check_native_mode(struct oce_softc *sc)
}
int
-oce_mbox_create_rq(struct oce_rq *rq)
+oce_create_rq(struct oce_softc *sc, struct oce_rq *rq)
{
struct mbx_create_nic_rq fwcmd;
- struct oce_softc *sc = rq->parent;
int err, npages;
- if (rq->qstate == QCREATED)
- return 0;
-
bzero(&fwcmd, sizeof(fwcmd));
npages = oce_load_ring(sc, rq->ring, &fwcmd.params.req.pages[0],
@@ -1082,7 +823,7 @@ oce_mbox_create_rq(struct oce_rq *rq)
} else
fwcmd.params.req.frag_size = ilog2(rq->cfg.frag_size);
fwcmd.params.req.num_pages = npages;
- fwcmd.params.req.cq_id = rq->cq->cq_id;
+ fwcmd.params.req.cq_id = rq->cq->id;
fwcmd.params.req.if_id = htole32(sc->if_id);
fwcmd.params.req.max_frame_size = htole16(rq->cfg.mtu);
fwcmd.params.req.is_rss_queue = htole32(rq->cfg.is_rss_queue);
@@ -1093,17 +834,16 @@ oce_mbox_create_rq(struct oce_rq *rq)
if (err)
return (err);
- rq->rq_id = letoh16(fwcmd.params.rsp.rq_id);
+ rq->id = letoh16(fwcmd.params.rsp.rq_id);
rq->rss_cpuid = fwcmd.params.rsp.rss_cpuid;
return (0);
}
int
-oce_mbox_create_wq(struct oce_wq *wq)
+oce_create_wq(struct oce_softc *sc, struct oce_wq *wq)
{
struct mbx_create_nic_wq fwcmd;
- struct oce_softc *sc = wq->parent;
int err, npages;
bzero(&fwcmd, sizeof(fwcmd));
@@ -1120,7 +860,7 @@ oce_mbox_create_wq(struct oce_wq *wq)
fwcmd.params.req.nic_wq_type = wq->cfg.wq_type;
fwcmd.params.req.num_pages = npages;
fwcmd.params.req.wq_size = ilog2(wq->cfg.q_len) + 1;
- fwcmd.params.req.cq_id = htole16(wq->cq->cq_id);
+ fwcmd.params.req.cq_id = htole16(wq->cq->id);
fwcmd.params.req.ulp_num = 1;
err = oce_fw(sc, MBX_SUBSYSTEM_NIC, OPCODE_NIC_CREATE_WQ,
@@ -1129,16 +869,15 @@ oce_mbox_create_wq(struct oce_wq *wq)
if (err)
return (err);
- wq->wq_id = letoh16(fwcmd.params.rsp.wq_id);
+ wq->id = letoh16(fwcmd.params.rsp.wq_id);
return (0);
}
int
-oce_mbox_create_mq(struct oce_mq *mq)
+oce_create_mq(struct oce_softc *sc, struct oce_mq *mq)
{
struct mbx_create_common_mq_ex fwcmd;
- struct oce_softc *sc = mq->parent;
union oce_mq_ext_ctx *ctx;
int err, npages;
@@ -1153,7 +892,7 @@ oce_mbox_create_mq(struct oce_mq *mq)
ctx = &fwcmd.params.req.context;
ctx->v0.num_pages = npages;
- ctx->v0.cq_id = mq->cq->cq_id;
+ ctx->v0.cq_id = mq->cq->id;
ctx->v0.ring_size = ilog2(mq->cfg.q_len) + 1;
ctx->v0.valid = 1;
/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
@@ -1164,16 +903,15 @@ oce_mbox_create_mq(struct oce_mq *mq)
if (err)
return (err);
- mq->mq_id = letoh16(fwcmd.params.rsp.mq_id);
+ mq->id = letoh16(fwcmd.params.rsp.mq_id);
return (0);
}
int
-oce_mbox_create_eq(struct oce_eq *eq)
+oce_create_eq(struct oce_softc *sc, struct oce_eq *eq)
{
struct mbx_create_common_eq fwcmd;
- struct oce_softc *sc = eq->parent;
int err, npages;
bzero(&fwcmd, sizeof(fwcmd));
@@ -1187,27 +925,25 @@ oce_mbox_create_eq(struct oce_eq *eq)
fwcmd.params.req.ctx.num_pages = htole16(npages);
fwcmd.params.req.ctx.valid = 1;
- fwcmd.params.req.ctx.size = (eq->eq_cfg.item_size == 4) ? 0 : 1;
- fwcmd.params.req.ctx.count = ilog2(eq->eq_cfg.q_len / 256);
+ fwcmd.params.req.ctx.size = (eq->cfg.item_size == 4) ? 0 : 1;
+ fwcmd.params.req.ctx.count = ilog2(eq->cfg.q_len / 256);
fwcmd.params.req.ctx.armed = 0;
- fwcmd.params.req.ctx.delay_mult = htole32(eq->eq_cfg.cur_eqd);
+ fwcmd.params.req.ctx.delay_mult = htole32(eq->cfg.cur_eqd);
err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_EQ,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err)
return (err);
- eq->eq_id = letoh16(fwcmd.params.rsp.eq_id);
+ eq->id = letoh16(fwcmd.params.rsp.eq_id);
return (0);
}
int
-oce_mbox_create_cq(struct oce_cq *cq, uint32_t ncoalesce,
- uint32_t is_eventable)
+oce_create_cq(struct oce_softc *sc, struct oce_cq *cq)
{
struct mbx_create_common_cq fwcmd;
- struct oce_softc *sc = cq->parent;
union oce_cq_ctx *ctx;
int err, npages;
@@ -1225,28 +961,28 @@ oce_mbox_create_cq(struct oce_cq *cq, uint32_t ncoalesce,
if (IS_XE201(sc)) {
ctx->v2.num_pages = htole16(npages);
ctx->v2.page_size = 1; /* for 4K */
- ctx->v2.eventable = is_eventable;
+ ctx->v2.eventable = cq->cfg.eventable;
ctx->v2.valid = 1;
- ctx->v2.count = ilog2(cq->cq_cfg.q_len / 256);
- ctx->v2.nodelay = cq->cq_cfg.nodelay;
- ctx->v2.coalesce_wm = ncoalesce;
+ ctx->v2.count = ilog2(cq->cfg.q_len / 256);
+ ctx->v2.nodelay = cq->cfg.nodelay;
+ ctx->v2.coalesce_wm = cq->cfg.ncoalesce;
ctx->v2.armed = 0;
- ctx->v2.eq_id = cq->eq->eq_id;
+ ctx->v2.eq_id = cq->eq->id;
if (ctx->v2.count == 3) {
- if (cq->cq_cfg.q_len > (4*1024)-1)
+ if (cq->cfg.q_len > (4*1024)-1)
ctx->v2.cqe_count = (4*1024)-1;
else
- ctx->v2.cqe_count = cq->cq_cfg.q_len;
+ ctx->v2.cqe_count = cq->cfg.q_len;
}
} else {
ctx->v0.num_pages = htole16(npages);
- ctx->v0.eventable = is_eventable;
+ ctx->v0.eventable = cq->cfg.eventable;
ctx->v0.valid = 1;
- ctx->v0.count = ilog2(cq->cq_cfg.q_len / 256);
- ctx->v0.nodelay = cq->cq_cfg.nodelay;
- ctx->v0.coalesce_wm = ncoalesce;
+ ctx->v0.count = ilog2(cq->cfg.q_len / 256);
+ ctx->v0.nodelay = cq->cfg.nodelay;
+ ctx->v0.coalesce_wm = cq->cfg.ncoalesce;
ctx->v0.armed = 0;
- ctx->v0.eq_id = cq->eq->eq_id;
+ ctx->v0.eq_id = cq->eq->id;
}
err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_CQ,
@@ -1255,38 +991,38 @@ oce_mbox_create_cq(struct oce_cq *cq, uint32_t ncoalesce,
if (err)
return (err);
- cq->cq_id = letoh16(fwcmd.params.rsp.cq_id);
+ cq->id = letoh16(fwcmd.params.rsp.cq_id);
return (0);
}
int
-oce_mbox_destroy_q(struct oce_softc *sc, enum qtype qtype, uint32_t qid)
+oce_destroy_queue(struct oce_softc *sc, enum qtype qtype, uint32_t qid)
{
struct mbx_destroy_common_mq fwcmd;
int opcode, subsys, err;
switch (qtype) {
- case QTYPE_EQ:
- opcode = OPCODE_COMMON_DESTROY_EQ;
- subsys = MBX_SUBSYSTEM_COMMON;
- break;
case QTYPE_CQ:
opcode = OPCODE_COMMON_DESTROY_CQ;
subsys = MBX_SUBSYSTEM_COMMON;
break;
+ case QTYPE_EQ:
+ opcode = OPCODE_COMMON_DESTROY_EQ;
+ subsys = MBX_SUBSYSTEM_COMMON;
+ break;
case QTYPE_MQ:
opcode = OPCODE_COMMON_DESTROY_MQ;
subsys = MBX_SUBSYSTEM_COMMON;
break;
- case QTYPE_WQ:
- opcode = OPCODE_NIC_DELETE_WQ;
- subsys = MBX_SUBSYSTEM_NIC;
- break;
case QTYPE_RQ:
opcode = OPCODE_NIC_DELETE_RQ;
subsys = MBX_SUBSYSTEM_NIC;
break;
+ case QTYPE_WQ:
+ opcode = OPCODE_NIC_DELETE_WQ;
+ subsys = MBX_SUBSYSTEM_NIC;
+ break;
default:
return (EINVAL);
}
diff --git a/sys/dev/pci/ocevar.h b/sys/dev/pci/ocevar.h
index cd211bcd282..c740d7492e3 100644
--- a/sys/dev/pci/ocevar.h
+++ b/sys/dev/pci/ocevar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ocevar.h,v 1.13 2012/10/12 15:16:45 mikeb Exp $ */
+/* $OpenBSD: ocevar.h,v 1.14 2012/10/12 17:41:40 mikeb Exp $ */
/*-
* Copyright (C) 2012 Emulex
@@ -185,29 +185,29 @@ enum {
struct oce_packet_desc {
- struct mbuf *mbuf;
- bus_dmamap_t map;
- int nsegs;
- uint32_t wqe_idx;
+ struct mbuf * mbuf;
+ bus_dmamap_t map;
+ int nsegs;
+ uint32_t wqe_idx;
};
struct oce_dma_mem {
- bus_dma_tag_t tag;
- bus_dmamap_t map;
- bus_dma_segment_t segs;
- int nsegs;
- bus_size_t size;
- caddr_t vaddr;
- bus_addr_t paddr;
+ bus_dma_tag_t tag;
+ bus_dmamap_t map;
+ bus_dma_segment_t segs;
+ int nsegs;
+ bus_size_t size;
+ caddr_t vaddr;
+ bus_addr_t paddr;
};
struct oce_ring {
- uint16_t cidx; /* Get ptr */
- uint16_t pidx; /* Put Ptr */
- size_t item_size;
- size_t num_items;
- uint32_t num_used;
- struct oce_dma_mem dma;
+ uint16_t cidx; /* Get ptr */
+ uint16_t pidx; /* Put Ptr */
+ size_t item_size;
+ size_t num_items;
+ uint32_t num_used;
+ struct oce_dma_mem dma;
};
/* Stats */
@@ -351,7 +351,6 @@ struct oce_xe_stats {
uint64_t rx_pkts_8192_to_9216_bytes;
};
-typedef int boolean_t;
#define TRUE 1
#define FALSE 0
@@ -367,7 +366,13 @@ typedef int boolean_t;
#define OCE_WQ_PACKET_ARRAY_SIZE (OCE_TX_RING_SIZE/2)
#define OCE_RQ_PACKET_ARRAY_SIZE (OCE_RX_RING_SIZE)
-struct oce_dev;
+struct oce_softc;
+
+enum cq_len {
+ CQ_LEN_256 = 256,
+ CQ_LEN_512 = 512,
+ CQ_LEN_1024 = 1024
+};
enum eq_len {
EQ_LEN_256 = 256,
@@ -391,180 +396,157 @@ enum qtype {
QTYPE_RSS
};
-typedef enum qstate_e {
+enum qstate {
QDELETED = 0x0,
QCREATED = 0x1
-} qstate_t;
+};
+
+struct oce_queue {
+ struct oce_softc * sc;
+ struct oce_ring * ring;
+ uint32_t id;
+ enum qtype type;
+ enum qstate state;
+};
struct eq_config {
- enum eq_len q_len;
- enum eqe_size item_size;
- uint32_t q_vector_num;
- uint8_t min_eqd;
- uint8_t max_eqd;
- uint8_t cur_eqd;
+ enum eq_len q_len;
+ enum eqe_size item_size;
+ int q_vector_num;
+ int min_eqd;
+ int max_eqd;
+ int cur_eqd;
};
struct oce_eq {
- uint32_t eq_id;
- void *parent;
- void *cb_context;
- struct oce_ring *ring;
- qstate_t qstate;
- struct oce_cq *cq[OCE_MAX_CQ_EQ];
- int cq_valid;
- struct eq_config eq_cfg;
- int vector;
-};
+ struct oce_softc * sc;
+ struct oce_ring * ring;
+ uint32_t id;
+ enum qtype type;
+ enum qstate state;
-enum cq_len {
- CQ_LEN_256 = 256,
- CQ_LEN_512 = 512,
- CQ_LEN_1024 = 1024
+ struct oce_cq * cq[OCE_MAX_CQ_EQ];
+ int cq_valid;
+
+ struct eq_config cfg;
};
struct cq_config {
- enum cq_len q_len;
- uint32_t item_size;
- boolean_t is_eventable;
- boolean_t sol_eventable;
- boolean_t nodelay;
- uint16_t dma_coalescing;
+ enum cq_len q_len;
+ int item_size;
+ int nodelay;
+ int dma_coalescing;
+ int ncoalesce;
+ int eventable;
};
struct oce_cq {
- uint32_t cq_id;
- void *parent;
- struct oce_eq *eq;
- void (*cq_handler)(void *);
- void *cb_arg;
- struct oce_ring *ring;
- qstate_t qstate;
- struct cq_config cq_cfg;
+ struct oce_softc * sc;
+ struct oce_ring * ring;
+ uint32_t id;
+ enum qtype type;
+ enum qstate state;
+
+ struct oce_eq * eq;
+
+ struct cq_config cfg;
+
+ void (*cq_handler)(void *);
+ void * cb_arg;
};
struct mq_config {
- uint32_t eqd;
- uint8_t q_len;
+ int eqd;
+ int q_len;
};
struct oce_mq {
- void *parent;
- struct oce_ring *ring;
- uint32_t mq_id;
- struct oce_cq *cq;
- struct oce_cq *async_cq;
- uint32_t mq_free;
- qstate_t qstate;
- struct mq_config cfg;
-};
+ struct oce_softc * sc;
+ struct oce_ring * ring;
+ uint32_t id;
+ enum qtype type;
+ enum qstate state;
-struct oce_mbx_ctx {
- struct oce_mbx *mbx;
- void (*cb) (void *ctx);
- void *cb_ctx;
-};
+ struct oce_cq * cq;
-struct wq_config {
- uint8_t wq_type;
- uint16_t buf_size;
- uint32_t q_len;
- uint16_t pd_id;
- uint16_t pci_fn_num;
- uint32_t eqd; /* interrupt delay */
- uint32_t nbufs;
- uint32_t nhdl;
+ struct mq_config cfg;
};
-struct oce_tx_queue_stats {
- uint64_t tx_pkts;
- uint64_t tx_bytes;
- uint32_t tx_reqs;
- uint32_t tx_stops; /* number of times TX Q was stopped */
- uint32_t tx_wrbs;
- uint32_t tx_compl;
- uint32_t tx_rate;
- uint32_t ipv6_ext_hdr_tx_drop;
+struct wq_config {
+ int wq_type;
+ int buf_size;
+ int q_len;
+ int eqd; /* interrupt delay */
+ int nbufs;
};
struct oce_wq {
- void *parent;
- struct oce_ring *ring;
- struct oce_cq *cq;
- bus_dma_tag_t tag;
- struct oce_packet_desc pckts[OCE_WQ_PACKET_ARRAY_SIZE];
- uint32_t packets_in;
- uint32_t packets_out;
- uint32_t wqm_used;
- boolean_t resched;
- uint32_t wq_free;
- uint32_t tx_deferd;
- uint32_t pkt_drops;
- qstate_t qstate;
- uint16_t wq_id;
- struct wq_config cfg;
- int queue_index;
-};
+ struct oce_softc * sc;
+ struct oce_ring * ring;
+ uint32_t id;
+ enum qtype type;
+ enum qstate state;
-struct rq_config {
- uint32_t q_len;
- uint32_t frag_size;
- uint32_t mtu;
- uint32_t if_id;
- uint32_t is_rss_queue;
- uint32_t eqd;
- uint32_t nbufs;
+ bus_dma_tag_t tag;
+
+ struct oce_cq *cq;
+ struct oce_packet_desc pckts[OCE_WQ_PACKET_ARRAY_SIZE];
+
+ uint32_t packets_in;
+ uint32_t packets_out;
+
+ struct wq_config cfg;
+
+ int queue_index;
};
-struct oce_rx_queue_stats {
- uint32_t rx_post_fail;
- uint32_t rx_ucast_pkts;
- uint32_t rx_compl;
- uint64_t rx_bytes;
- uint64_t rx_bytes_prev;
- uint64_t rx_pkts;
- uint32_t rx_rate;
- uint32_t rx_mcast_pkts;
- uint32_t rxcp_err;
- uint32_t rx_frags;
- uint32_t prev_rx_frags;
- uint32_t rx_fps;
+struct rq_config {
+ int q_len;
+ int frag_size;
+ int mtu;
+ int if_id;
+ int is_rss_queue;
+ int eqd;
+ int nbufs;
};
struct oce_rq {
- struct rq_config cfg;
- uint32_t rq_id;
- int queue_index;
- uint32_t rss_cpuid;
- void *parent;
- struct oce_ring *ring;
- struct oce_cq *cq;
- bus_dma_tag_t tag;
- struct oce_packet_desc pckts[OCE_RQ_PACKET_ARRAY_SIZE];
- uint32_t packets_in;
- uint32_t packets_out;
- uint32_t pending;
-#ifdef notdef
- struct mbuf *head;
- struct mbuf *tail;
- int fragsleft;
-#endif
- qstate_t qstate;
+ struct oce_softc * sc;
+ struct oce_ring * ring;
+ uint32_t id;
+ enum qtype type;
+ enum qstate state;
+
+ bus_dma_tag_t tag;
+
+ struct oce_cq * cq;
+ struct oce_packet_desc pckts[OCE_RQ_PACKET_ARRAY_SIZE];
+
+ uint32_t packets_in;
+ uint32_t packets_out;
+ uint32_t pending;
+
+ uint32_t rss_cpuid;
+
#ifdef OCE_LRO
- struct lro_ctrl lro;
- int lro_pkts_queued;
+ struct lro_ctrl lro;
+ int lro_pkts_queued;
#endif
+
+ struct rq_config cfg;
+
+ int queue_index;
};
struct link_status {
- uint8_t physical_port;
- uint8_t mac_duplex;
- uint8_t mac_speed;
- uint8_t mac_fault;
- uint8_t mgmt_mac_duplex;
- uint8_t mgmt_mac_speed;
- uint16_t qos_link_speed;
- uint32_t logical_link_status;
+ uint8_t physical_port;
+ uint8_t mac_duplex;
+ uint8_t mac_speed;
+ uint8_t mac_fault;
+ uint8_t mgmt_mac_duplex;
+ uint8_t mgmt_mac_speed;
+ uint16_t qos_link_speed;
+ uint32_t logical_link_status;
} __packed;
#define OCE_FLAGS_PCIX 0x00000001
@@ -581,71 +563,71 @@ struct link_status {
#define OCE_FLAGS_BE2 0x00000800
struct oce_softc {
- struct device dev;
+ struct device dev;
+
+ uint32_t flags;
- uint32_t flags;
+ struct pci_attach_args pa;
- struct pci_attach_args pa;
+ bus_space_tag_t cfg_iot;
+ bus_space_handle_t cfg_ioh;
+ bus_size_t cfg_size;
- bus_space_tag_t cfg_btag;
- bus_space_handle_t cfg_bhandle;
- bus_size_t cfg_size;
+ bus_space_tag_t csr_iot;
+ bus_space_handle_t csr_ioh;
+ bus_size_t csr_size;
- bus_space_tag_t csr_btag;
- bus_space_handle_t csr_bhandle;
- bus_size_t csr_size;
+ bus_space_tag_t db_iot;
+ bus_space_handle_t db_ioh;
+ bus_size_t db_size;
- bus_space_tag_t db_btag;
- bus_space_handle_t db_bhandle;
- bus_size_t db_size;
+ struct arpcom arpcom;
+ struct ifmedia media;
+ int link_active;
+ uint8_t link_status;
+ uint8_t link_speed;
+ uint8_t duplex;
+ uint32_t qos_link_speed;
- struct arpcom arpcom;
- struct ifmedia media;
- int link_active;
- uint8_t link_status;
- uint8_t link_speed;
- uint8_t duplex;
- uint32_t qos_link_speed;
+ char fw_version[32];
- char fw_version[32];
- struct mac_address_format macaddr;
+ struct oce_dma_mem bsmbx;
- struct oce_dma_mem bsmbx;
+ uint32_t asic_revision;
+ uint32_t port_id;
+ uint32_t function_mode;
+ uint32_t function_caps;
+ uint32_t max_tx_rings;
+ uint32_t max_rx_rings;
- uint32_t config_number;
- uint32_t asic_revision;
- uint32_t port_id;
- uint32_t function_mode;
- uint32_t function_caps;
- uint32_t max_tx_rings;
- uint32_t max_rx_rings;
+ struct oce_wq *wq[OCE_MAX_WQ]; /* TX work queues */
+ struct oce_rq *rq[OCE_MAX_RQ]; /* RX work queues */
+ struct oce_cq *cq[OCE_MAX_CQ]; /* Completion queues */
+ struct oce_eq *eq[OCE_MAX_EQ]; /* Event queues */
+ struct oce_mq *mq; /* Mailbox queue */
- struct oce_wq *wq[OCE_MAX_WQ]; /* TX work queues */
- struct oce_rq *rq[OCE_MAX_RQ]; /* RX work queues */
- struct oce_cq *cq[OCE_MAX_CQ]; /* Completion queues */
- struct oce_eq *eq[OCE_MAX_EQ]; /* Event queues */
- struct oce_mq *mq; /* Mailbox queue */
+ ushort neqs;
+ ushort ncqs;
+ ushort nrqs;
+ ushort nwqs;
+ ushort intr_count;
+ ushort tx_ring_size;
+ ushort rx_ring_size;
+ ushort rq_frag_size;
+ ushort rss_enable;
- ushort neqs;
- ushort ncqs;
- ushort nrqs;
- ushort nwqs;
- ushort intr_count;
- ushort tx_ring_size;
- ushort rx_ring_size;
- ushort rq_frag_size;
- ushort rss_enable;
+ uint32_t if_id; /* interface ID */
+ uint32_t nifs; /* number of adapter interfaces, 0 or 1 */
+ uint32_t pmac_id; /* PMAC id */
- uint32_t if_id; /* interface ID */
- uint32_t nifs; /* number of adapter interfaces, 0 or 1 */
- uint32_t pmac_id; /* PMAC id */
+ char macaddr[ETH_ADDR_LEN];
- uint32_t if_cap_flags;
+ uint32_t if_cap_flags;
- uint32_t flow_control;
+ uint32_t flow_control;
- char be3_native;
- uint32_t pvid;
+ int be3_native;
+ uint32_t pvid;
union {
struct mbx_get_pport_stats xe;
@@ -653,11 +635,11 @@ struct oce_softc {
struct mbx_get_nic_stats be3;
} stats;
- uint64_t rx_errors;
- uint64_t tx_errors;
+ uint64_t rx_errors;
+ uint64_t tx_errors;
- struct timeout timer;
- struct timeout rxrefill;
+ struct timeout timer;
+ struct timeout rxrefill;
};
/**************************************************
@@ -667,36 +649,30 @@ struct oce_softc {
**************************************************/
#if 1
#define OCE_READ_REG32(sc, space, o) \
- ((IS_BE(sc)) ? (bus_space_read_4((sc)->space##_btag, \
- (sc)->space##_bhandle,o)) \
- : (bus_space_read_4((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o)))
+ ((IS_BE(sc)) ? (bus_space_read_4((sc)->space##_iot, \
+ (sc)->space##_ioh,o)) \
+ : (bus_space_read_4((sc)->cfg_iot, (sc)->cfg_ioh,o)))
#define OCE_READ_REG16(sc, space, o) \
- ((IS_BE(sc)) ? (bus_space_read_2((sc)->space##_btag, \
- (sc)->space##_bhandle,o)) \
- : (bus_space_read_2((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o)))
+ ((IS_BE(sc)) ? (bus_space_read_2((sc)->space##_iot, \
+ (sc)->space##_ioh,o)) \
+ : (bus_space_read_2((sc)->cfg_iot, (sc)->cfg_ioh,o)))
#define OCE_READ_REG8(sc, space, o) \
- ((IS_BE(sc)) ? (bus_space_read_1((sc)->space##_btag, \
- (sc)->space##_bhandle,o)) \
- : (bus_space_read_1((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o)))
+ ((IS_BE(sc)) ? (bus_space_read_1((sc)->space##_iot, \
+ (sc)->space##_ioh,o)) \
+ : (bus_space_read_1((sc)->cfg_iot, (sc)->cfg_ioh,o)))
#define OCE_WRITE_REG32(sc, space, o, v) \
- ((IS_BE(sc)) ? (bus_space_write_4((sc)->space##_btag, \
- (sc)->space##_bhandle,o,v)) \
- : (bus_space_write_4((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o,v)))
+ ((IS_BE(sc)) ? (bus_space_write_4((sc)->space##_iot, \
+ (sc)->space##_ioh,o,v)) \
+ : (bus_space_write_4((sc)->cfg_iot, (sc)->cfg_ioh,o,v)))
#define OCE_WRITE_REG16(sc, space, o, v) \
- ((IS_BE(sc)) ? (bus_space_write_2((sc)->space##_btag, \
- (sc)->space##_bhandle,o,v)) \
- : (bus_space_write_2((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o,v)))
+ ((IS_BE(sc)) ? (bus_space_write_2((sc)->space##_iot, \
+ (sc)->space##_ioh,o,v)) \
+ : (bus_space_write_2((sc)->cfg_iot, (sc)->cfg_ioh,o,v)))
#define OCE_WRITE_REG8(sc, space, o, v) \
- ((IS_BE(sc)) ? (bus_space_write_1((sc)->space##_btag, \
- (sc)->space##_bhandle,o,v)) \
- : (bus_space_write_1((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o,v)))
+ ((IS_BE(sc)) ? (bus_space_write_1((sc)->space##_iot, \
+ (sc)->space##_ioh,o,v)) \
+ : (bus_space_write_1((sc)->cfg_iot, (sc)->cfg_ioh,o,v)))
#else
static __inline u_int32_t
oce_bus_read_4(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t reg)
@@ -744,36 +720,30 @@ oce_bus_write_1(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t reg,
}
#define OCE_READ_REG32(sc, space, o) \
- ((IS_BE(sc)) ? (oce_bus_read_4((sc)->space##_btag, \
- (sc)->space##_bhandle,o)) \
- : (oce_bus_read_4((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o)))
+ ((IS_BE(sc)) ? (oce_bus_read_4((sc)->space##_iot, \
+ (sc)->space##_ioh,o)) \
+ : (oce_bus_read_4((sc)->cfg_iot, (sc)->cfg_ioh,o)))
#define OCE_READ_REG16(sc, space, o) \
- ((IS_BE(sc)) ? (oce_bus_read_2((sc)->space##_btag, \
- (sc)->space##_bhandle,o)) \
- : (oce_bus_read_2((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o)))
+ ((IS_BE(sc)) ? (oce_bus_read_2((sc)->space##_iot, \
+ (sc)->space##_ioh,o)) \
+ : (oce_bus_read_2((sc)->cfg_iot, (sc)->cfg_ioh,o)))
#define OCE_READ_REG8(sc, space, o) \
- ((IS_BE(sc)) ? (oce_bus_read_1((sc)->space##_btag, \
- (sc)->space##_bhandle,o)) \
- : (oce_bus_read_1((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o)))
+ ((IS_BE(sc)) ? (oce_bus_read_1((sc)->space##_iot, \
+ (sc)->space##_ioh,o)) \
+ : (oce_bus_read_1((sc)->cfg_iot, (sc)->cfg_ioh,o)))
#define OCE_WRITE_REG32(sc, space, o, v) \
- ((IS_BE(sc)) ? (oce_bus_write_4((sc)->space##_btag, \
- (sc)->space##_bhandle,o,v)) \
- : (oce_bus_write_4((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o,v)))
+ ((IS_BE(sc)) ? (oce_bus_write_4((sc)->space##_iot, \
+ (sc)->space##_ioh,o,v)) \
+ : (oce_bus_write_4((sc)->cfg_iot, (sc)->cfg_ioh,o,v)))
#define OCE_WRITE_REG16(sc, space, o, v) \
- ((IS_BE(sc)) ? (oce_bus_write_2((sc)->space##_btag, \
- (sc)->space##_bhandle,o,v)) \
- : (oce_bus_write_2((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o,v)))
+ ((IS_BE(sc)) ? (oce_bus_write_2((sc)->space##_iot, \
+ (sc)->space##_ioh,o,v)) \
+ : (oce_bus_write_2((sc)->cfg_iot, (sc)->cfg_ioh,o,v)))
#define OCE_WRITE_REG8(sc, space, o, v) \
- ((IS_BE(sc)) ? (oce_bus_write_1((sc)->space##_btag, \
- (sc)->space##_bhandle,o,v)) \
- : (oce_bus_write_1((sc)->cfg_btag, \
- (sc)->cfg_bhandle,o,v)))
+ ((IS_BE(sc)) ? (oce_bus_write_1((sc)->space##_iot, \
+ (sc)->space##_ioh,o,v)) \
+ : (oce_bus_write_1((sc)->cfg_iot, (sc)->cfg_ioh,o,v)))
#endif
/***********************************************************
@@ -793,19 +763,20 @@ int oce_load_ring(struct oce_softc *sc, struct oce_ring *ring,
struct phys_addr *pa_list, int max_segs);
/************************************************************
- * Some functions
+ * Firmware functions
************************************************************/
-int oce_hw_pci_alloc(struct oce_softc *sc);
-int oce_hw_init(struct oce_softc *sc);
-void oce_hw_intr_enable(struct oce_softc *sc);
-void oce_hw_intr_disable(struct oce_softc *sc);
-int oce_create_iface(struct oce_softc *sc);
+int oce_init_fw(struct oce_softc *sc);
+int oce_get_fw_version(struct oce_softc *sc);
+int oce_get_fw_config(struct oce_softc *sc);
+int oce_check_native_mode(struct oce_softc *sc);
+int oce_create_iface(struct oce_softc *sc, uint8_t *);
int oce_update_mcast(struct oce_softc *sc,
uint8_t multi[][ETH_ADDR_LEN], int naddr);
/************************************************************
* Mailbox functions
************************************************************/
+int oce_mbox_init(struct oce_softc *sc);
int oce_first_mcc_cmd(struct oce_softc *sc);
int oce_get_link_status(struct oce_softc *sc);
@@ -813,20 +784,20 @@ int oce_set_promisc(struct oce_softc *sc, uint32_t enable);
int oce_config_nic_rss(struct oce_softc *sc, uint32_t if_id,
uint16_t enable_rss);
-int oce_mbox_macaddr_del(struct oce_softc *sc, uint32_t if_id,
+int oce_macaddr_del(struct oce_softc *sc, uint32_t if_id,
uint32_t pmac_id);
-int oce_mbox_macaddr_add(struct oce_softc *sc, uint8_t *mac_addr,
+int oce_macaddr_add(struct oce_softc *sc, uint8_t *macaddr,
uint32_t if_id, uint32_t *pmac_id);
-int oce_read_mac_addr(struct oce_softc *sc, uint32_t if_id, uint8_t perm,
- uint8_t type, struct mac_address_format *mac);
-
-int oce_mbox_create_rq(struct oce_rq *rq);
-int oce_mbox_create_wq(struct oce_wq *wq);
-int oce_mbox_create_mq(struct oce_mq *mq);
-int oce_mbox_create_eq(struct oce_eq *eq);
-int oce_mbox_create_cq(struct oce_cq *cq, uint32_t ncoalesce,
- uint32_t is_eventable);
-int oce_mbox_destroy_q(struct oce_softc *sc, enum qtype qtype, uint32_t qid);
+int oce_read_macaddr(struct oce_softc *sc, uint8_t *macaddr);
+
+int oce_create_qeueu(struct oce_softc *sc, struct oce_queue *q,
+ enum qtype qtype);
+int oce_create_rq(struct oce_softc *sc, struct oce_rq *rq);
+int oce_create_wq(struct oce_softc *sc, struct oce_wq *wq);
+int oce_create_mq(struct oce_softc *sc, struct oce_mq *mq);
+int oce_create_eq(struct oce_softc *sc, struct oce_eq *eq);
+int oce_create_cq(struct oce_softc *sc, struct oce_cq *cq);
+int oce_destroy_queue(struct oce_softc *sc, enum qtype qtype, uint32_t qid);
/************************************************************
* Statistics functions