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>
MFC after:	3 day
This commit is contained in:
Xin LI 2013-10-23 18:58:38 +00:00
parent 86b2e94a3d
commit 5fbb683079
8 changed files with 685 additions and 287 deletions

View File

@ -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;

View File

@ -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
};

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -36,11 +36,8 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
#include "oce_if.h"
/*****************************************************

View File

@ -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,6 +255,277 @@ done:
return status;
}
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)
{
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);
}
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;
}
}
static int
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, 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)));
p += bin_offset;
while (p < ((const char *)fw->data + fw->datasize)) {
fsec = (const struct flash_sec_info *)p;
if (!memcmp(cookie, fsec->cookie, sizeof(cookie)))
break;
fsec = NULL;
p += 32;
}
if (!fsec) {
device_printf(sc->dev,
"Invalid Cookie. Firmware image corrupted ?\n");
return EINVAL;
}
rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom)
+ 32*1024, &dma_mem, 0);
if (rc) {
device_printf(sc->dev,
"Memory allocation failure while flashing\n");
return ENOMEM;
}
req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom);
if (IS_SH(sc))
num_imgs = HOST_32(fsec->fsec_hdr.num_images);
else if (IS_BE3(sc))
num_imgs = MAX_FLASH_COMP;
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 + imgatt.img_offset;
if ((p + imgatt.img_size) > ((const char *)fw->data + fw->datasize)) {
rc = 1;
goto ret;
}
while (imgatt.img_size) {
if (imgatt.img_size > 32*1024)
num_bytes = 32*1024;
else
num_bytes = imgatt.img_size;
imgatt.img_size -= num_bytes;
if (!imgatt.img_size)
opcode = FLASHROM_OPER_FLASH;
else
opcode = FLASHROM_OPER_SAVE;
memcpy(req->data_buffer, p, num_bytes);
p += 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");
rc = EIO;
goto ret;
}
/* Leave the CPU for others for some time */
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)
@ -268,7 +548,8 @@ oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
sizeof(struct flash_file_hdr) +
(i * sizeof(struct image_hdr)));
if (img_ptr->imageid == 1) {
rc = oce_be3_flashdata(sc, fw, num_imgs);
rc = oce_sh_be3_flashdata(sc, fw, num_imgs);
break;
}
}
@ -277,156 +558,6 @@ oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
}
static int
oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int 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;
OCE_DMA_MEM dma_mem;
/* Validate Cookie */
bin_offset = (sizeof(struct flash_file_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;
if (!memcmp(cookie, fsec->cookie, sizeof(cookie)))
break;
fsec = NULL;
p += 32;
}
if (!fsec) {
device_printf(sc->dev,
"Invalid Cookie. Firmware image corrupted ?\n");
return EINVAL;
}
rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom)
+ 32*1024, &dma_mem, 0);
if (rc) {
device_printf(sc->dev,
"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++) {
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)
continue;
p = fw->data;
p = p + bin_offset + start;
if ((p + size) > ((const char *)fw->data + fw->datasize)) {
rc = 1;
goto ret;
}
while (size) {
if (size > 32*1024)
num_bytes = 32*1024;
else
num_bytes = size;
size -= num_bytes;
if (!size)
opcode = FLASHROM_OPER_FLASH;
else
opcode = FLASHROM_OPER_SAVE;
memcpy(req->data_buffer, p, num_bytes);
p += num_bytes;
rc = oce_mbox_write_flashrom(sc, optype, opcode,
&dma_mem, num_bytes);
if (rc) {
device_printf(sc->dev,
"cmd to write to flash rom failed.\n");
rc = EIO;
goto ret;
}
/* Leave the CPU for others for some time */
pause("yield", 10);
}
}
ret:
oce_dma_free(sc, &dma_mem);
return rc;
}
static boolean_t
oce_phy_flashing_required(POCE_SOFTC sc)
{

View File

@ -36,10 +36,8 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
#include "oce_if.h"
static void oce_dma_map_ring(void *arg,