diff options
author | delphij <delphij@FreeBSD.org> | 2013-10-26 19:02:39 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2013-10-26 19:02:39 +0000 |
commit | b1f939cc2d16430b422067cdf9781196178aa824 (patch) | |
tree | fd7ae2896e90876c01d89b9db789e411c0899dac | |
parent | b5d80767c99d74fd32aff6250bb13733452d09fa (diff) | |
download | FreeBSD-src-b1f939cc2d16430b422067cdf9781196178aa824.zip FreeBSD-src-b1f939cc2d16430b422067cdf9781196178aa824.tar.gz |
MFC r257007:
Update driver to version 10.0.664.0.
Many thanks to Emulex for their continued support of FreeBSD.
Submitted by: Venkata Duvvuru <VenkatKumar.Duvvuru Emulex Com>
Approved by: re (glebius)
-rw-r--r-- | sys/dev/oce/oce_hw.c | 16 | ||||
-rw-r--r-- | sys/dev/oce/oce_hw.h | 28 | ||||
-rw-r--r-- | sys/dev/oce/oce_if.c | 173 | ||||
-rw-r--r-- | sys/dev/oce/oce_if.h | 12 | ||||
-rw-r--r-- | sys/dev/oce/oce_mbox.c | 291 | ||||
-rw-r--r-- | sys/dev/oce/oce_queue.c | 3 | ||||
-rw-r--r-- | sys/dev/oce/oce_sysctl.c | 355 | ||||
-rw-r--r-- | sys/dev/oce/oce_util.c | 2 |
8 files changed, 639 insertions, 241 deletions
diff --git a/sys/dev/oce/oce_hw.c b/sys/dev/oce/oce_hw.c index 1cacb8c..7fc16b8 100644 --- a/sys/dev/oce/oce_hw.c +++ b/sys/dev/oce/oce_hw.c @@ -38,6 +38,7 @@ /* $FreeBSD$ */ + #include "oce_if.h" static int oce_POST(POCE_SOFTC sc); @@ -203,12 +204,16 @@ void oce_get_pci_capabilities(POCE_SOFTC sc) { uint32_t val; - if (pci_find_cap(sc->dev, PCIY_PCIX, &val) == 0) { +#if __FreeBSD_version >= 1000000 + #define pci_find_extcap pci_find_cap +#endif + + if (pci_find_extcap(sc->dev, PCIY_PCIX, &val) == 0) { if (val != 0) sc->flags |= OCE_FLAGS_PCIX; } - if (pci_find_cap(sc->dev, PCIY_EXPRESS, &val) == 0) { + if (pci_find_extcap(sc->dev, PCIY_EXPRESS, &val) == 0) { if (val != 0) { uint16_t link_status = pci_read_config(sc->dev, val + 0x12, 2); @@ -219,12 +224,12 @@ void oce_get_pci_capabilities(POCE_SOFTC sc) } } - if (pci_find_cap(sc->dev, PCIY_MSI, &val) == 0) { + if (pci_find_extcap(sc->dev, PCIY_MSI, &val) == 0) { if (val != 0) sc->flags |= OCE_FLAGS_MSI_CAPABLE; } - if (pci_find_cap(sc->dev, PCIY_MSIX, &val) == 0) { + if (pci_find_extcap(sc->dev, PCIY_MSIX, &val) == 0) { if (val != 0) { val = pci_msix_count(sc->dev); sc->flags |= OCE_FLAGS_MSIX_CAPABLE; @@ -386,6 +391,9 @@ oce_create_nw_interface(POCE_SOFTC sc) capab_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR; } + if (IS_SH(sc) || IS_XE201(sc)) + capab_flags |= MBX_RX_IFACE_FLAGS_MULTICAST; + /* enable capabilities controlled via driver startup parameters */ if (is_rss_enabled(sc)) capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS; diff --git a/sys/dev/oce/oce_hw.h b/sys/dev/oce/oce_hw.h index 66250c8..4cdbea3 100644 --- a/sys/dev/oce/oce_hw.h +++ b/sys/dev/oce/oce_hw.h @@ -59,6 +59,30 @@ #define INTR_EN 0x20000000 #define IMAGE_TRANSFER_SIZE (32 * 1024) /* 32K at a time */ + +/********* UE Status and Mask Registers ***/ +#define PCICFG_UE_STATUS_LOW 0xA0 +#define PCICFG_UE_STATUS_HIGH 0xA4 +#define PCICFG_UE_STATUS_LOW_MASK 0xA8 + +/* Lancer SLIPORT registers */ +#define SLIPORT_STATUS_OFFSET 0x404 +#define SLIPORT_CONTROL_OFFSET 0x408 +#define SLIPORT_ERROR1_OFFSET 0x40C +#define SLIPORT_ERROR2_OFFSET 0x410 +#define PHYSDEV_CONTROL_OFFSET 0x414 + +#define SLIPORT_STATUS_ERR_MASK 0x80000000 +#define SLIPORT_STATUS_DIP_MASK 0x02000000 +#define SLIPORT_STATUS_RN_MASK 0x01000000 +#define SLIPORT_STATUS_RDY_MASK 0x00800000 +#define SLI_PORT_CONTROL_IP_MASK 0x08000000 +#define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002 +#define PHYSDEV_CONTROL_DD_MASK 0x00000004 +#define PHYSDEV_CONTROL_INP_MASK 0x40000000 + +#define SLIPORT_ERROR_NO_RESOURCE1 0x2 +#define SLIPORT_ERROR_NO_RESOURCE2 0x9 /* CSR register offsets */ #define MPU_EP_CONTROL 0 #define MPU_EP_SEMAPHORE_BE3 0xac @@ -2079,7 +2103,8 @@ struct flash_file_hdr { uint32_t antidote; uint32_t num_imgs; uint8_t build[24]; - uint8_t rsvd[32]; + uint8_t asic_type_rev; + uint8_t rsvd[31]; }; struct image_hdr { @@ -3681,4 +3706,3 @@ enum OCE_QUEUE_RX_STATS { QUEUE_RX_BUFFER_ERRORS = 8, QUEUE_RX_N_WORDS = 10 }; - diff --git a/sys/dev/oce/oce_if.c b/sys/dev/oce/oce_if.c index 166828b..bb1e18e 100644 --- a/sys/dev/oce/oce_if.c +++ b/sys/dev/oce/oce_if.c @@ -36,7 +36,6 @@ * Costa Mesa, CA 92626 */ - /* $FreeBSD$ */ #include "opt_inet6.h" @@ -44,6 +43,78 @@ #include "oce_if.h" +/* UE Status Low CSR */ +static char *ue_status_low_desc[] = { + "CEV", + "CTX", + "DBUF", + "ERX", + "Host", + "MPU", + "NDMA", + "PTC ", + "RDMA ", + "RXF ", + "RXIPS ", + "RXULP0 ", + "RXULP1 ", + "RXULP2 ", + "TIM ", + "TPOST ", + "TPRE ", + "TXIPS ", + "TXULP0 ", + "TXULP1 ", + "UC ", + "WDMA ", + "TXULP2 ", + "HOST1 ", + "P0_OB_LINK ", + "P1_OB_LINK ", + "HOST_GPIO ", + "MBOX ", + "AXGMAC0", + "AXGMAC1", + "JTAG", + "MPU_INTPEND" +}; + +/* UE Status High CSR */ +static char *ue_status_hi_desc[] = { + "LPCMEMHOST", + "MGMT_MAC", + "PCS0ONLINE", + "MPU_IRAM", + "PCS1ONLINE", + "PCTL0", + "PCTL1", + "PMEM", + "RR", + "TXPB", + "RXPP", + "XAUI", + "TXP", + "ARM", + "IPC", + "HOST2", + "HOST3", + "HOST4", + "HOST5", + "HOST6", + "HOST7", + "HOST8", + "HOST9", + "NETC", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown" +}; + /* Driver entry points prototypes */ static int oce_probe(device_t dev); @@ -388,11 +459,11 @@ oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) { - sc->promisc = TRUE; - oce_rxf_set_promiscuous(sc, sc->promisc); + if (!oce_rxf_set_promiscuous(sc, (1 | (1 << 1)))) + sc->promisc = TRUE; } else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) { - sc->promisc = FALSE; - oce_rxf_set_promiscuous(sc, sc->promisc); + if (!oce_rxf_set_promiscuous(sc, 0)) + sc->promisc = FALSE; } break; @@ -862,10 +933,12 @@ retry: (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0; nichdr->u0.s.num_wqe = num_wqes; nichdr->u0.s.total_length = m->m_pkthdr.len; + if (m->m_flags & M_VLANTAG) { nichdr->u0.s.vlan = 1; /*Vlan present*/ nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag; } + if (m->m_pkthdr.csum_flags & CSUM_TSO) { if (m->m_pkthdr.tso_segsz) { nichdr->u0.s.lso = 1; @@ -1156,6 +1229,18 @@ oce_wq_handler(void *arg) } +#if __FreeBSD_version >= 1000000 +static __inline void +drbr_stats_update(struct ifnet *ifp, int len, int mflags) +{ +#ifndef NO_SLOW_STATS + ifp->if_obytes += len; + if (mflags & M_MCAST) + ifp->if_omcasts++; +#endif +} +#endif + static int oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq) { @@ -1174,7 +1259,7 @@ oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq) return status; } - if (m != NULL) { + if (m != NULL) { if ((status = drbr_enqueue(ifp, br, m)) != 0) return status; } @@ -1646,6 +1731,10 @@ oce_attach_ifp(POCE_SOFTC sc) sc->ifp->if_capenable = sc->ifp->if_capabilities; if_initbaudrate(sc->ifp, IF_Gbps(10)); +#if __FreeBSD_version >= 1000000 + sc->ifp->if_hw_tsomax = OCE_MAX_TSO_SIZE; +#endif + ether_ifattach(sc->ifp, sc->macaddr.mac_addr); return 0; @@ -1664,7 +1753,8 @@ oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag) sc->vlan_tag[vtag] = 1; sc->vlans_added++; - oce_vid_config(sc); + if (sc->vlans_added <= (sc->max_vlans + 1)) + oce_vid_config(sc); } @@ -1866,12 +1956,76 @@ done: } +static void oce_detect_hw_error(POCE_SOFTC sc) +{ + + uint32_t ue_low = 0, ue_high = 0, ue_low_mask = 0, ue_high_mask = 0; + uint32_t sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; + uint32_t i; + + if (sc->hw_error) + return; + + if (IS_XE201(sc)) { + sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET); + if (sliport_status & SLIPORT_STATUS_ERR_MASK) { + sliport_err1 = OCE_READ_REG32(sc, db, SLIPORT_ERROR1_OFFSET); + sliport_err2 = OCE_READ_REG32(sc, db, SLIPORT_ERROR2_OFFSET); + } + } else { + ue_low = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW); + ue_high = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HIGH); + ue_low_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW_MASK); + ue_high_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HI_MASK); + + ue_low = (ue_low & ~ue_low_mask); + ue_high = (ue_high & ~ue_high_mask); + } + + /* On certain platforms BE hardware can indicate spurious UEs. + * Allow the h/w to stop working completely in case of a real UE. + * Hence not setting the hw_error for UE detection. + */ + if (sliport_status & SLIPORT_STATUS_ERR_MASK) { + sc->hw_error = TRUE; + device_printf(sc->dev, "Error detected in the card\n"); + } + + if (sliport_status & SLIPORT_STATUS_ERR_MASK) { + device_printf(sc->dev, + "ERR: sliport status 0x%x\n", sliport_status); + device_printf(sc->dev, + "ERR: sliport error1 0x%x\n", sliport_err1); + device_printf(sc->dev, + "ERR: sliport error2 0x%x\n", sliport_err2); + } + + if (ue_low) { + for (i = 0; ue_low; ue_low >>= 1, i++) { + if (ue_low & 1) + device_printf(sc->dev, "UE: %s bit set\n", + ue_status_low_desc[i]); + } + } + + if (ue_high) { + for (i = 0; ue_high; ue_high >>= 1, i++) { + if (ue_high & 1) + device_printf(sc->dev, "UE: %s bit set\n", + ue_status_hi_desc[i]); + } + } + +} + + static void oce_local_timer(void *arg) { POCE_SOFTC sc = arg; int i = 0; + oce_detect_hw_error(sc); oce_refresh_nic_stats(sc); oce_refresh_queue_stats(sc); oce_mac_addr_set(sc); @@ -1890,7 +2044,7 @@ oce_local_timer(void *arg) /* NOTE : This should only be called holding * DEVICE_LOCK. -*/ + */ static void oce_if_deactivate(POCE_SOFTC sc) { @@ -2080,6 +2234,9 @@ setup_max_queues_want(POCE_SOFTC sc) (sc->flags & OCE_FLAGS_BE2)) { sc->nrqs = 1; sc->nwqs = 1; + } else { + sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1; + sc->nwqs = MIN(OCE_NCPUS, sc->nrssqs); } } diff --git a/sys/dev/oce/oce_if.h b/sys/dev/oce/oce_if.h index 83de17b..87d57b4 100644 --- a/sys/dev/oce/oce_if.h +++ b/sys/dev/oce/oce_if.h @@ -36,7 +36,6 @@ * Costa Mesa, CA 92626 */ - /* $FreeBSD$ */ #include <sys/param.h> @@ -88,7 +87,8 @@ #include "oce_hw.h" -#define COMPONENT_REVISION "4.6.95.0" +/* OCE device driver module component revision informaiton */ +#define COMPONENT_REVISION "10.0.664.0" /* OCE devices supported by this driver */ #define PCI_VENDOR_EMULEX 0x10df /* Emulex */ @@ -150,6 +150,7 @@ extern int mp_ncpus; /* system's total active cpu cores */ #define OCE_MAX_TX_ELEMENTS 29 #define OCE_MAX_TX_DESC 1024 #define OCE_MAX_TX_SIZE 65535 +#define OCE_MAX_TSO_SIZE (65535 - ETHER_HDR_LEN) #define OCE_MAX_RX_SIZE 4096 #define OCE_MAX_RQ_POSTS 255 #define OCE_DEFAULT_PROMISCUOUS 0 @@ -173,6 +174,7 @@ extern int mp_ncpus; /* system's total active cpu cores */ #define OCE_CAPAB_FLAGS (MBX_RX_IFACE_FLAGS_BROADCAST | \ MBX_RX_IFACE_FLAGS_UNTAGGED | \ MBX_RX_IFACE_FLAGS_PROMISCUOUS | \ + MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS | \ MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS | \ MBX_RX_IFACE_FLAGS_RSS | \ MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR) @@ -863,7 +865,7 @@ typedef struct oce_softc { uint32_t if_cap_flags; uint32_t flow_control; - uint32_t promisc; + uint8_t promisc; struct oce_aic_obj aic_obj[OCE_MAX_EQ]; @@ -877,9 +879,11 @@ typedef struct oce_softc { struct oce_drv_stats oce_stats_info; struct callout timer; int8_t be3_native; + uint8_t hw_error; uint16_t qnq_debug_event; uint16_t qnqid; uint16_t pvid; + uint16_t max_vlans; } OCE_SOFTC, *POCE_SOFTC; @@ -1010,7 +1014,7 @@ int oce_config_vlan(POCE_SOFTC sc, uint32_t if_id, uint32_t untagged, uint32_t enable_promisc); int oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control); int oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss); -int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable); +int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable); int oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl); int oce_get_link_status(POCE_SOFTC sc, struct link_status *link); int oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem); diff --git a/sys/dev/oce/oce_mbox.c b/sys/dev/oce/oce_mbox.c index 9aab595..fbb24be 100644 --- a/sys/dev/oce/oce_mbox.c +++ b/sys/dev/oce/oce_mbox.c @@ -36,11 +36,8 @@ * Costa Mesa, CA 92626 */ - - /* $FreeBSD$ */ - #include "oce_if.h" extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE]; @@ -281,8 +278,10 @@ oce_get_fw_version(POCE_SOFTC sc) if (!ret) ret = fwcmd->hdr.u0.rsp.status; if (ret) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, ret); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, ret, + fwcmd->hdr.u0.rsp.additional_status); goto error; } @@ -438,8 +437,10 @@ oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id, if (!ret) ret = fwcmd->hdr.u0.rsp.status; if (ret) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, ret); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, ret, + fwcmd->hdr.u0.rsp.additional_status); goto error; } @@ -481,25 +482,27 @@ oce_get_fw_config(POCE_SOFTC sc) if (!ret) ret = fwcmd->hdr.u0.rsp.status; if (ret) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, ret); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, ret, + fwcmd->hdr.u0.rsp.additional_status); goto error; } DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config)); - 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; - sc->function_caps = fwcmd->params.rsp.function_caps; + sc->config_number = HOST_32(fwcmd->params.rsp.config_number); + sc->asic_revision = HOST_32(fwcmd->params.rsp.asic_revision); + sc->port_id = HOST_32(fwcmd->params.rsp.port_id); + sc->function_mode = HOST_32(fwcmd->params.rsp.function_mode); + sc->function_caps = HOST_32(fwcmd->params.rsp.function_caps); if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) { - sc->max_tx_rings = fwcmd->params.rsp.ulp[0].nic_wq_tot; - sc->max_rx_rings = fwcmd->params.rsp.ulp[0].lro_rqid_tot; + sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[0].nic_wq_tot); + sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[0].lro_rqid_tot); } else { - sc->max_tx_rings = fwcmd->params.rsp.ulp[1].nic_wq_tot; - sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot; + sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[1].nic_wq_tot); + sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[1].lro_rqid_tot); } error: @@ -561,15 +564,17 @@ oce_if_create(POCE_SOFTC sc, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } - *if_id = LE_32(fwcmd->params.rsp.if_id); + *if_id = HOST_32(fwcmd->params.rsp.if_id); if (mac_addr != NULL) - sc->pmac_id = LE_32(fwcmd->params.rsp.pmac_id); + sc->pmac_id = HOST_32(fwcmd->params.rsp.pmac_id); error: return rc; } @@ -607,8 +612,10 @@ oce_if_del(POCE_SOFTC sc, uint32_t if_id) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -630,7 +637,10 @@ oce_config_vlan(POCE_SOFTC sc, { struct oce_mbx mbx; struct mbx_common_config_vlan *fwcmd; - int rc; + int rc = 0; + + if (sc->vlans_added > sc->max_vlans) + goto vlan_promisc; bzero(&mbx, sizeof(struct oce_mbx)); fwcmd = (struct mbx_common_config_vlan *)&mbx.payload; @@ -659,9 +669,19 @@ oce_config_vlan(POCE_SOFTC sc, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); - return 0; + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); + + goto done; + +vlan_promisc: + /* Enable Vlan Promis */ + oce_rxf_set_promiscuous(sc, (1 << 1)); + device_printf(sc->dev,"Enabling Vlan Promisc Mode\n"); +done: + return rc; } @@ -702,8 +722,10 @@ oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -802,8 +824,10 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); } return rc; } @@ -818,7 +842,7 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss) * This function uses the COMMON_SET_IFACE_RX_FILTER command instead. */ int -oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable) +oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable) { struct mbx_set_common_iface_rx_filter *fwcmd; int sz = sizeof(struct mbx_set_common_iface_rx_filter); @@ -836,10 +860,13 @@ oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable) req = &fwcmd->params.req; req->iface_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS | MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS; - if (enable) { - req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS | - MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS; - } + /* Bit 0 Mac promisc, Bit 1 Vlan promisc */ + if (enable & 0x01) + req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS; + + if (enable & 0x02) + req->iface_flags = MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS; + req->if_id = sc->if_id; rc = oce_set_common_iface_rx_filter(sc, &sgl); @@ -886,9 +913,11 @@ oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); - return 0; + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); + return rc; } /** @@ -925,14 +954,16 @@ oce_get_link_status(POCE_SOFTC sc, struct link_status *link) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } /* interpret response */ bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status)); - link->logical_link_status = LE_32(link->logical_link_status); - link->qos_link_speed = LE_16(link->qos_link_speed); + link->logical_link_status = HOST_32(link->logical_link_status); + link->qos_link_speed = HOST_16(link->qos_link_speed); error: return rc; } @@ -978,8 +1009,10 @@ oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -1028,8 +1061,10 @@ oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -1080,8 +1115,10 @@ oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -1133,8 +1170,10 @@ oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -1178,8 +1217,10 @@ oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem) if (!rc) rc = req->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + req->hdr.u0.rsp.additional_status); return rc; } @@ -1243,8 +1284,10 @@ oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } *pmac_id = fwcmd->params.rsp.pmac_id; @@ -1281,8 +1324,10 @@ oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -1318,11 +1363,13 @@ oce_mbox_check_native_mode(POCE_SOFTC sc) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } - sc->be3_native = fwcmd->params.rsp.capability_flags + sc->be3_native = HOST_32(fwcmd->params.rsp.capability_flags) & CAP_BE3_NATIVE_ERX_API; error: @@ -1363,8 +1410,10 @@ oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; @@ -1406,8 +1455,10 @@ oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; } @@ -1433,9 +1484,9 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode, payload_len, OCE_MBX_VER_V0); - fwcmd->flash_op_type = optype; - fwcmd->flash_op_code = opcode; - fwcmd->data_buffer_size = num_bytes; + fwcmd->flash_op_type = LE_32(optype); + fwcmd->flash_op_code = LE_32(opcode); + fwcmd->data_buffer_size = LE_32(num_bytes); mbx.u0.s.embedded = 0; /*Non embeded*/ mbx.payload_length = payload_len; @@ -1451,8 +1502,10 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); return rc; @@ -1497,8 +1550,10 @@ oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } bcopy(fwcmd->data_buffer, flash_crc, 4); @@ -1532,18 +1587,20 @@ oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } - phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type; + phy_info->phy_type = HOST_16(fwcmd->params.rsp.phy_info.phy_type); phy_info->interface_type = - fwcmd->params.rsp.phy_info.interface_type; + HOST_16(fwcmd->params.rsp.phy_info.interface_type); phy_info->auto_speeds_supported = - fwcmd->params.rsp.phy_info.auto_speeds_supported; + HOST_16(fwcmd->params.rsp.phy_info.auto_speeds_supported); phy_info->fixed_speeds_supported = - fwcmd->params.rsp.phy_info.fixed_speeds_supported; - phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params; + HOST_16(fwcmd->params.rsp.phy_info.fixed_speeds_supported); + phy_info->misc_params = HOST_32(fwcmd->params.rsp.phy_info.misc_params); error: return rc; @@ -1593,11 +1650,13 @@ oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size, if (!rc) rc = fwcmd->params.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->params.rsp.additional_status); goto error; } - *written_data = fwcmd->params.rsp.actual_write_length; + *written_data = HOST_32(fwcmd->params.rsp.actual_write_length); *additional_status = fwcmd->params.rsp.additional_status; error: return rc; @@ -1649,11 +1708,13 @@ oce_mbox_create_rq(struct oce_rq *rq) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } - rq->rq_id = fwcmd->params.rsp.rq_id; + rq->rq_id = HOST_16(fwcmd->params.rsp.rq_id); rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid; error: return rc; @@ -1673,15 +1734,17 @@ oce_mbox_create_wq(struct oce_wq *wq) bzero(&mbx, sizeof(struct oce_mbx)); fwcmd = (struct mbx_create_nic_wq *)&mbx.payload; - if (IS_XE201(sc)) { + if (IS_XE201(sc)) version = OCE_MBX_VER_V1; - fwcmd->params.req.if_id = sc->if_id; - } else if(IS_BE(sc)) + else if(IS_BE(sc)) IS_PROFILE_SUPER_NIC(sc) ? (version = OCE_MBX_VER_V2) : (version = OCE_MBX_VER_V0); else version = OCE_MBX_VER_V2; + if (version > OCE_MBX_VER_V0) + fwcmd->params.req.if_id = sc->if_id; + mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, MBX_SUBSYSTEM_NIC, NIC_CREATE_WQ, MBX_TIMEOUT_SEC, @@ -1703,13 +1766,15 @@ oce_mbox_create_wq(struct oce_wq *wq) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } - wq->wq_id = LE_16(fwcmd->params.rsp.wq_id); + wq->wq_id = HOST_16(fwcmd->params.rsp.wq_id); if (version == OCE_MBX_VER_V2) - wq->db_offset = LE_32(fwcmd->params.rsp.db_offset); + wq->db_offset = HOST_32(fwcmd->params.rsp.db_offset); else wq->db_offset = PD_TXULP_DB; error: @@ -1754,11 +1819,13 @@ oce_mbox_create_eq(struct oce_eq *eq) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } - eq->eq_id = LE_16(fwcmd->params.rsp.eq_id); + eq->eq_id = HOST_16(fwcmd->params.rsp.eq_id); error: return rc; } @@ -1832,11 +1899,13 @@ oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } - cq->cq_id = LE_16(fwcmd->params.rsp.cq_id); + cq->cq_id = HOST_16(fwcmd->params.rsp.cq_id); error: return rc; @@ -1885,8 +1954,10 @@ oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } if(fwcmd->params.rsp.page_num == PAGE_NUM_A0) @@ -1947,8 +2018,10 @@ oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd, if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); } int @@ -2006,8 +2079,10 @@ oce_get_profile_config(POCE_SOFTC sc) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } @@ -2027,6 +2102,7 @@ oce_get_profile_config(POCE_SOFTC sc) goto error; } else { + sc->max_vlans = nic_desc->vlan_count; sc->nwqs = HOST_32(nic_desc->txq_count); if (sc->nwqs) sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ); @@ -2096,8 +2172,10 @@ oce_get_func_config(POCE_SOFTC sc) if (!rc) rc = fwcmd->hdr.u0.rsp.status; if (rc) { - device_printf(sc->dev,"%s failed - cmd status: %d\n", - __FUNCTION__, rc); + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); goto error; } @@ -2117,6 +2195,7 @@ oce_get_func_config(POCE_SOFTC sc) goto error; } else { + sc->max_vlans = nic_desc->vlan_count; sc->nwqs = HOST_32(nic_desc->txq_count); if (sc->nwqs) sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ); diff --git a/sys/dev/oce/oce_queue.c b/sys/dev/oce/oce_queue.c index fbf68fd..308c16d 100644 --- a/sys/dev/oce/oce_queue.c +++ b/sys/dev/oce/oce_queue.c @@ -36,11 +36,8 @@ * Costa Mesa, CA 92626 */ - - /* $FreeBSD$ */ - #include "oce_if.h" /***************************************************** diff --git a/sys/dev/oce/oce_sysctl.c b/sys/dev/oce/oce_sysctl.c index 7dad619..1155c69 100644 --- a/sys/dev/oce/oce_sysctl.c +++ b/sys/dev/oce/oce_sysctl.c @@ -38,7 +38,6 @@ /* $FreeBSD$ */ - #include "oce_if.h" static void copy_stats_to_sc_xe201(POCE_SOFTC sc); @@ -46,9 +45,8 @@ static void copy_stats_to_sc_be3(POCE_SOFTC sc); static void copy_stats_to_sc_be2(POCE_SOFTC sc); static int oce_sysctl_loopback(SYSCTL_HANDLER_ARGS); static int oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw); +static int oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw); static int oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS); -static int oce_be3_flashdata(POCE_SOFTC sc, const struct firmware - *fw, int num_imgs); static int oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw); static int oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS); static boolean_t oce_phy_flashing_required(POCE_SOFTC sc); @@ -62,9 +60,18 @@ static void oce_add_stats_sysctls_xe201(POCE_SOFTC sc, struct sysctl_ctx_list *ctx, struct sysctl_oid *stats_node); + extern char component_revision[32]; uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE]; +struct flash_img_attri { + int img_offset; + int img_size; + int img_type; + bool skip_image; + int optype; +}; + void oce_add_sysctls(POCE_SOFTC sc) { @@ -154,10 +161,10 @@ oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type) { uint32_t status = 0; - oce_mbox_cmd_set_loopback(sc, sc->if_id, loopback_type, 1); - status = oce_mbox_cmd_test_loopback(sc, sc->if_id, loopback_type, + oce_mbox_cmd_set_loopback(sc, sc->port_id, loopback_type, 1); + status = oce_mbox_cmd_test_loopback(sc, sc->port_id, loopback_type, 1500, 2, 0xabc); - oce_mbox_cmd_set_loopback(sc, sc->if_id, OCE_NO_LOOPBACK, 1); + oce_mbox_cmd_set_loopback(sc, sc->port_id, OCE_NO_LOOPBACK, 1); return status; } @@ -223,7 +230,7 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS) return ENOENT; } - if (IS_BE(sc) || IS_SH(sc)) { + if (IS_BE(sc)) { if ((sc->flags & OCE_FLAGS_BE2)) { device_printf(sc->dev, "Flashing not supported for BE2 yet.\n"); @@ -231,6 +238,8 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS) goto done; } status = oce_be3_fwupgrade(sc, fw); + } else if (IS_SH(sc)) { + status = oce_skyhawk_fwupgrade(sc,fw); } else status = oce_lancer_fwupgrade(sc, fw); done: @@ -246,53 +255,117 @@ done: return status; } - -static int -oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw) +static void oce_fill_flash_img_data(POCE_SOFTC sc, const struct flash_sec_info * fsec, + struct flash_img_attri *pimg, int i, + const struct firmware *fw, int bin_offset) { - int rc = 0, num_imgs = 0, i = 0; - const struct flash_file_hdr *fhdr; - const struct image_hdr *img_ptr; - - fhdr = (const struct flash_file_hdr *)fw->data; - if (fhdr->build[0] != '3') { - device_printf(sc->dev, "Invalid BE3 firmware image\n"); - return EINVAL; + if (IS_SH(sc)) { + pimg->img_offset = HOST_32(fsec->fsec_entry[i].offset); + pimg->img_size = HOST_32(fsec->fsec_entry[i].pad_size); } - /* Display flash version */ - device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]); - num_imgs = fhdr->num_imgs; - for (i = 0; i < num_imgs; i++) { - img_ptr = (const struct image_hdr *)((const char *)fw->data + - sizeof(struct flash_file_hdr) + - (i * sizeof(struct image_hdr))); - if (img_ptr->imageid == 1) { - rc = oce_be3_flashdata(sc, fw, num_imgs); + pimg->img_type = HOST_32(fsec->fsec_entry[i].type); + pimg->skip_image = FALSE; + switch (pimg->img_type) { + case IMG_ISCSI: + pimg->optype = 0; + if (IS_BE3(sc)) { + pimg->img_offset = 2097152; + pimg->img_size = 2097152; + } + break; + case IMG_REDBOOT: + pimg->optype = 1; + if (IS_BE3(sc)) { + pimg->img_offset = 262144; + pimg->img_size = 1048576; + } + if (!oce_img_flashing_required(sc, fw->data, + pimg->optype, + pimg->img_offset, + pimg->img_size, + bin_offset)) + pimg->skip_image = TRUE; + break; + case IMG_BIOS: + pimg->optype = 2; + if (IS_BE3(sc)) { + pimg->img_offset = 12582912; + pimg->img_size = 524288; + } + break; + case IMG_PXEBIOS: + pimg->optype = 3; + if (IS_BE3(sc)) { + pimg->img_offset = 13107200;; + pimg->img_size = 524288; + } + break; + case IMG_FCOEBIOS: + pimg->optype = 8; + if (IS_BE3(sc)) { + pimg->img_offset = 13631488; + pimg->img_size = 524288; + } + break; + case IMG_ISCSI_BAK: + pimg->optype = 9; + if (IS_BE3(sc)) { + pimg->img_offset = 4194304; + pimg->img_size = 2097152; + } + break; + case IMG_FCOE: + pimg->optype = 10; + if (IS_BE3(sc)) { + pimg->img_offset = 6291456; + pimg->img_size = 2097152; + } + break; + case IMG_FCOE_BAK: + pimg->optype = 11; + if (IS_BE3(sc)) { + pimg->img_offset = 8388608; + pimg->img_size = 2097152; + } + break; + case IMG_NCSI: + pimg->optype = 13; + if (IS_BE3(sc)) { + pimg->img_offset = 15990784; + pimg->img_size = 262144; + } + break; + case IMG_PHY: + pimg->optype = 99; + if (IS_BE3(sc)) { + pimg->img_offset = 1310720; + pimg->img_size = 262144; + } + if (!oce_phy_flashing_required(sc)) + pimg->skip_image = TRUE; + break; + default: + pimg->skip_image = TRUE; break; - } } - return rc; } - static int -oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs) +oce_sh_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int32_t num_imgs) { char cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "}; const char *p = (const char *)fw->data; const struct flash_sec_info *fsec = NULL; struct mbx_common_read_write_flashrom *req; - int rc = 0, i, img_type, bin_offset = 0; - boolean_t skip_image; - uint32_t optype = 0, size = 0, start = 0, num_bytes = 0; - uint32_t opcode = 0; + int rc = 0, i, bin_offset = 0, opcode, num_bytes; OCE_DMA_MEM dma_mem; + struct flash_img_attri imgatt; /* Validate Cookie */ bin_offset = (sizeof(struct flash_file_hdr) + - (num_imgs * sizeof(struct image_hdr))); + (num_imgs * sizeof(struct image_hdr))); p += bin_offset; while (p < ((const char *)fw->data + fw->datasize)) { fsec = (const struct flash_sec_info *)p; @@ -304,7 +377,7 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs) if (!fsec) { device_printf(sc->dev, - "Invalid Cookie. Firmware image corrupted ?\n"); + "Invalid Cookie. Firmware image corrupted ?\n"); return EINVAL; } @@ -312,94 +385,42 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs) + 32*1024, &dma_mem, 0); if (rc) { device_printf(sc->dev, - "Memory allocation failure while flashing\n"); + "Memory allocation failure while flashing\n"); return ENOMEM; } req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom); - for (i = 0; i < MAX_FLASH_COMP; i++) { + if (IS_SH(sc)) + num_imgs = HOST_32(fsec->fsec_hdr.num_images); + else if (IS_BE3(sc)) + num_imgs = MAX_FLASH_COMP; - img_type = fsec->fsec_entry[i].type; - skip_image = FALSE; - switch (img_type) { - case IMG_ISCSI: - optype = 0; - size = 2097152; - start = 2097152; - break; - case IMG_REDBOOT: - optype = 1; - size = 1048576; - start = 262144; - if (!oce_img_flashing_required(sc, fw->data, - optype, start, size, bin_offset)) - skip_image = TRUE; - break; - case IMG_BIOS: - optype = 2; - size = 524288; - start = 12582912; - break; - case IMG_PXEBIOS: - optype = 3; - size = 524288; - start = 13107200; - break; - case IMG_FCOEBIOS: - optype = 8; - size = 524288; - start = 13631488; - break; - case IMG_ISCSI_BAK: - optype = 9; - size = 2097152; - start = 4194304; - break; - case IMG_FCOE: - optype = 10; - size = 2097152; - start = 6291456; - break; - case IMG_FCOE_BAK: - optype = 11; - size = 2097152; - start = 8388608; - break; - case IMG_NCSI: - optype = 13; - size = 262144; - start = 15990784; - break; - case IMG_PHY: - optype = 99; - size = 262144; - start = 1310720; - if (!oce_phy_flashing_required(sc)) - skip_image = TRUE; - break; - default: - skip_image = TRUE; - break; - } - if (skip_image) + for (i = 0; i < num_imgs; i++) { + + bzero(&imgatt, sizeof(struct flash_img_attri)); + + oce_fill_flash_img_data(sc, fsec, &imgatt, i, fw, bin_offset); + + if (imgatt.skip_image) continue; p = fw->data; - p = p + bin_offset + start; - if ((p + size) > ((const char *)fw->data + fw->datasize)) { + p = p + bin_offset + imgatt.img_offset; + + if ((p + imgatt.img_size) > ((const char *)fw->data + fw->datasize)) { rc = 1; goto ret; } - while (size) { + while (imgatt.img_size) { - if (size > 32*1024) + if (imgatt.img_size > 32*1024) num_bytes = 32*1024; else - num_bytes = size; - size -= num_bytes; + num_bytes = imgatt.img_size; + imgatt.img_size -= num_bytes; - if (!size) + if (!imgatt.img_size) opcode = FLASHROM_OPER_FLASH; else opcode = FLASHROM_OPER_SAVE; @@ -407,11 +428,11 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs) memcpy(req->data_buffer, p, num_bytes); p += num_bytes; - rc = oce_mbox_write_flashrom(sc, optype, opcode, - &dma_mem, num_bytes); + rc = oce_mbox_write_flashrom(sc, imgatt.optype, opcode, + &dma_mem, num_bytes); if (rc) { device_printf(sc->dev, - "cmd to write to flash rom failed.\n"); + "cmd to write to flash rom failed.\n"); rc = EIO; goto ret; } @@ -419,11 +440,121 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs) pause("yield", 10); } + } + ret: oce_dma_free(sc, &dma_mem); return rc; +} + +#define UFI_TYPE2 2 +#define UFI_TYPE3 3 +#define UFI_TYPE3R 10 +#define UFI_TYPE4 4 +#define UFI_TYPE4R 11 +static int oce_get_ufi_type(POCE_SOFTC sc, + const struct flash_file_hdr *fhdr) +{ + if (fhdr == NULL) + goto be_get_ufi_exit; + + if (IS_SH(sc) && fhdr->build[0] == '4') { + if (fhdr->asic_type_rev >= 0x10) + return UFI_TYPE4R; + else + return UFI_TYPE4; + } else if (IS_BE3(sc) && fhdr->build[0] == '3') { + if (fhdr->asic_type_rev == 0x10) + return UFI_TYPE3R; + else + return UFI_TYPE3; + } else if (IS_BE2(sc) && fhdr->build[0] == '2') + return UFI_TYPE2; + +be_get_ufi_exit: + device_printf(sc->dev, + "UFI and Interface are not compatible for flashing\n"); + return -1; +} + + +static int +oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw) +{ + int rc = 0, num_imgs = 0, i = 0, ufi_type; + const struct flash_file_hdr *fhdr; + const struct image_hdr *img_ptr; + + fhdr = (const struct flash_file_hdr *)fw->data; + + ufi_type = oce_get_ufi_type(sc, fhdr); + + /* Display flash version */ + device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]); + + num_imgs = fhdr->num_imgs; + for (i = 0; i < num_imgs; i++) { + img_ptr = (const struct image_hdr *)((const char *)fw->data + + sizeof(struct flash_file_hdr) + + (i * sizeof(struct image_hdr))); + + if (img_ptr->imageid != 1) + continue; + + switch (ufi_type) { + case UFI_TYPE4R: + rc = oce_sh_be3_flashdata(sc, fw, + num_imgs); + break; + case UFI_TYPE4: + if (sc->asic_revision < 0x10) + rc = oce_sh_be3_flashdata(sc, fw, + num_imgs); + else { + rc = -1; + device_printf(sc->dev, + "Cant load SH A0 UFI on B0\n"); + } + break; + default: + rc = -1; + break; + + } + } + + return rc; +} +static int +oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw) +{ + int rc = 0, num_imgs = 0, i = 0; + const struct flash_file_hdr *fhdr; + const struct image_hdr *img_ptr; + + fhdr = (const struct flash_file_hdr *)fw->data; + if (fhdr->build[0] != '3') { + device_printf(sc->dev, "Invalid BE3 firmware image\n"); + return EINVAL; + } + /* Display flash version */ + device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]); + + num_imgs = fhdr->num_imgs; + for (i = 0; i < num_imgs; i++) { + img_ptr = (const struct image_hdr *)((const char *)fw->data + + sizeof(struct flash_file_hdr) + + (i * sizeof(struct image_hdr))); + if (img_ptr->imageid == 1) { + rc = oce_sh_be3_flashdata(sc, fw, num_imgs); + + break; + } + } + + return rc; } diff --git a/sys/dev/oce/oce_util.c b/sys/dev/oce/oce_util.c index eeca2f2..669da03 100644 --- a/sys/dev/oce/oce_util.c +++ b/sys/dev/oce/oce_util.c @@ -36,10 +36,8 @@ * Costa Mesa, CA 92626 */ - /* $FreeBSD$ */ - #include "oce_if.h" static void oce_dma_map_ring(void *arg, |