Update driver with recent vendor improvements, most notably support
of Skyhawk adapters. Many thanks to Emulex for their continued support of FreeBSD. Submitted by: "Duvvuru,Venkat Kumar" <VenkatKumar.Duvvuru Emulex.Com> MFC after: 1 day
This commit is contained in:
parent
1fdeb1651c
commit
291a1934fa
@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 2012 Emulex
|
||||
.\" Copyright (C) 2013 Emulex
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -53,12 +53,12 @@ oce_POST(POCE_SOFTC sc)
|
||||
int tmo = 60000;
|
||||
|
||||
/* read semaphore CSR */
|
||||
post_status.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_SEMAPHORE(sc));
|
||||
post_status.dw0 = OCE_READ_CSR_MPU(sc, csr, MPU_EP_SEMAPHORE(sc));
|
||||
|
||||
/* if host is ready then wait for fw ready else send POST */
|
||||
if (post_status.bits.stage <= POST_STAGE_AWAITING_HOST_RDY) {
|
||||
post_status.bits.stage = POST_STAGE_CHIP_RESET;
|
||||
OCE_WRITE_REG32(sc, csr, MPU_EP_SEMAPHORE(sc), post_status.dw0);
|
||||
OCE_WRITE_CSR_MPU(sc, csr, MPU_EP_SEMAPHORE(sc), post_status.dw0);
|
||||
}
|
||||
|
||||
/* wait for FW ready */
|
||||
@ -68,7 +68,7 @@ oce_POST(POCE_SOFTC sc)
|
||||
|
||||
DELAY(1000);
|
||||
|
||||
post_status.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_SEMAPHORE(sc));
|
||||
post_status.dw0 = OCE_READ_CSR_MPU(sc, csr, MPU_EP_SEMAPHORE(sc));
|
||||
if (post_status.bits.error) {
|
||||
device_printf(sc->dev,
|
||||
"POST failed: %x\n", post_status.dw0);
|
||||
@ -129,7 +129,7 @@ oce_hw_init(POCE_SOFTC sc)
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) {
|
||||
if ((IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) || IS_SH(sc)) {
|
||||
rc = oce_mbox_check_native_mode(sc);
|
||||
if (rc)
|
||||
goto error;
|
||||
@ -258,7 +258,7 @@ oce_hw_pci_alloc(POCE_SOFTC sc)
|
||||
|
||||
rr = PCIR_BAR(pci_cfg_barnum);
|
||||
|
||||
if (IS_BE(sc))
|
||||
if (IS_BE(sc) || IS_SH(sc))
|
||||
sc->devcfg_res = bus_alloc_resource_any(sc->dev,
|
||||
SYS_RES_MEMORY, &rr,
|
||||
RF_ACTIVE|RF_SHAREABLE);
|
||||
@ -298,7 +298,7 @@ oce_hw_pci_alloc(POCE_SOFTC sc)
|
||||
sc->flags |= OCE_FLAGS_VIRTUAL_PORT;
|
||||
|
||||
/* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */
|
||||
if (IS_BE(sc)) {
|
||||
if (IS_BE(sc) || IS_SH(sc)) {
|
||||
/* set up CSR region */
|
||||
rr = PCIR_BAR(OCE_PCI_CSR_BAR);
|
||||
sc->csr_res = bus_alloc_resource_any(sc->dev,
|
||||
@ -387,7 +387,7 @@ oce_create_nw_interface(POCE_SOFTC sc)
|
||||
}
|
||||
|
||||
/* enable capabilities controlled via driver startup parameters */
|
||||
if (sc->rss_enable)
|
||||
if (is_rss_enabled(sc))
|
||||
capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;
|
||||
else {
|
||||
capab_en_flags &= ~MBX_RX_IFACE_FLAGS_RSS;
|
||||
@ -447,9 +447,9 @@ oce_pci_soft_reset(POCE_SOFTC sc)
|
||||
int rc;
|
||||
mpu_ep_control_t ctrl;
|
||||
|
||||
ctrl.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_CONTROL);
|
||||
ctrl.dw0 = OCE_READ_CSR_MPU(sc, csr, MPU_EP_CONTROL);
|
||||
ctrl.bits.cpu_reset = 1;
|
||||
OCE_WRITE_REG32(sc, csr, MPU_EP_CONTROL, ctrl.dw0);
|
||||
OCE_WRITE_CSR_MPU(sc, csr, MPU_EP_CONTROL, ctrl.dw0);
|
||||
DELAY(50);
|
||||
rc=oce_POST(sc);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -63,8 +63,7 @@
|
||||
#define MPU_EP_CONTROL 0
|
||||
#define MPU_EP_SEMAPHORE_BE3 0xac
|
||||
#define MPU_EP_SEMAPHORE_XE201 0x400
|
||||
#define MPU_EP_SEMAPHORE(sc) \
|
||||
((IS_BE(sc)) ? MPU_EP_SEMAPHORE_BE3 : MPU_EP_SEMAPHORE_XE201)
|
||||
#define MPU_EP_SEMAPHORE_SH 0x94
|
||||
#define PCICFG_INTR_CTRL 0xfc
|
||||
#define HOSTINTR_MASK (1 << 29)
|
||||
#define HOSTINTR_PFUNC_SHIFT 26
|
||||
@ -1998,6 +1997,79 @@ struct mbx_lowlevel_set_loopback_mode {
|
||||
} rsp;
|
||||
} params;
|
||||
};
|
||||
#define MAX_RESC_DESC 256
|
||||
#define RESC_DESC_SIZE 88
|
||||
#define ACTIVE_PROFILE 2
|
||||
#define NIC_RESC_DESC_TYPE_V0 0x41
|
||||
#define NIC_RESC_DESC_TYPE_V1 0x51
|
||||
/* OPCODE_COMMON_GET_FUNCTION_CONFIG */
|
||||
struct mbx_common_get_func_config {
|
||||
struct mbx_hdr hdr;
|
||||
union {
|
||||
struct {
|
||||
uint8_t rsvd;
|
||||
uint8_t type;
|
||||
uint16_t rsvd1;
|
||||
} req;
|
||||
struct {
|
||||
uint32_t desc_count;
|
||||
uint8_t resources[MAX_RESC_DESC * RESC_DESC_SIZE];
|
||||
} rsp;
|
||||
} params;
|
||||
};
|
||||
|
||||
|
||||
/* OPCODE_COMMON_GET_PROFILE_CONFIG */
|
||||
|
||||
struct mbx_common_get_profile_config {
|
||||
struct mbx_hdr hdr;
|
||||
union {
|
||||
struct {
|
||||
uint8_t rsvd;
|
||||
uint8_t type;
|
||||
uint16_t rsvd1;
|
||||
} req;
|
||||
struct {
|
||||
uint32_t desc_count;
|
||||
uint8_t resources[MAX_RESC_DESC * RESC_DESC_SIZE];
|
||||
} rsp;
|
||||
} params;
|
||||
};
|
||||
|
||||
struct oce_nic_resc_desc {
|
||||
uint8_t desc_type;
|
||||
uint8_t desc_len;
|
||||
uint8_t rsvd1;
|
||||
uint8_t flags;
|
||||
uint8_t vf_num;
|
||||
uint8_t rsvd2;
|
||||
uint8_t pf_num;
|
||||
uint8_t rsvd3;
|
||||
uint16_t unicast_mac_count;
|
||||
uint8_t rsvd4[6];
|
||||
uint16_t mcc_count;
|
||||
uint16_t vlan_count;
|
||||
uint16_t mcast_mac_count;
|
||||
uint16_t txq_count;
|
||||
uint16_t rq_count;
|
||||
uint16_t rssq_count;
|
||||
uint16_t lro_count;
|
||||
uint16_t cq_count;
|
||||
uint16_t toe_conn_count;
|
||||
uint16_t eq_count;
|
||||
uint32_t rsvd5;
|
||||
uint32_t cap_flags;
|
||||
uint8_t link_param;
|
||||
uint8_t rsvd6[3];
|
||||
uint32_t bw_min;
|
||||
uint32_t bw_max;
|
||||
uint8_t acpi_params;
|
||||
uint8_t wol_param;
|
||||
uint16_t rsvd7;
|
||||
uint32_t rsvd8[7];
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct flash_file_hdr {
|
||||
uint8_t sign[52];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -96,6 +96,7 @@ static void update_queues_got(POCE_SOFTC sc);
|
||||
static void process_link_state(POCE_SOFTC sc,
|
||||
struct oce_async_cqe_link_state *acqe);
|
||||
static int oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m);
|
||||
static void oce_get_config(POCE_SOFTC sc);
|
||||
static struct mbuf *oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete);
|
||||
|
||||
/* IP specific */
|
||||
@ -147,6 +148,7 @@ static uint32_t supportedDevices[] = {
|
||||
(PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_BE3,
|
||||
(PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201,
|
||||
(PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201_VF,
|
||||
(PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_SH
|
||||
};
|
||||
|
||||
|
||||
@ -190,6 +192,9 @@ oce_probe(device_t dev)
|
||||
case PCI_PRODUCT_XE201_VF:
|
||||
sc->flags |= OCE_FLAGS_XE201;
|
||||
break;
|
||||
case PCI_PRODUCT_SH:
|
||||
sc->flags |= OCE_FLAGS_SH;
|
||||
break;
|
||||
default:
|
||||
return ENXIO;
|
||||
}
|
||||
@ -214,7 +219,6 @@ oce_attach(device_t dev)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
sc->rss_enable = oce_enable_rss;
|
||||
sc->tx_ring_size = OCE_TX_RING_SIZE;
|
||||
sc->rx_ring_size = OCE_RX_RING_SIZE;
|
||||
sc->rq_frag_size = OCE_RQ_BUF_SIZE;
|
||||
@ -229,6 +233,8 @@ oce_attach(device_t dev)
|
||||
if (rc)
|
||||
goto pci_res_free;
|
||||
|
||||
oce_get_config(sc);
|
||||
|
||||
setup_max_queues_want(sc);
|
||||
|
||||
rc = oce_setup_intr(sc);
|
||||
@ -486,17 +492,18 @@ oce_multiq_start(struct ifnet *ifp, struct mbuf *m)
|
||||
int queue_index = 0;
|
||||
int status = 0;
|
||||
|
||||
if (!sc->link_status)
|
||||
return ENXIO;
|
||||
|
||||
if ((m->m_flags & M_FLOWID) != 0)
|
||||
queue_index = m->m_pkthdr.flowid % sc->nwqs;
|
||||
|
||||
|
||||
wq = sc->wq[queue_index];
|
||||
|
||||
if (TRY_LOCK(&wq->tx_lock)) {
|
||||
status = oce_multiq_transmit(ifp, m, wq);
|
||||
UNLOCK(&wq->tx_lock);
|
||||
} else {
|
||||
status = drbr_enqueue(ifp, wq->br, m);
|
||||
}
|
||||
LOCK(&wq->tx_lock);
|
||||
status = oce_multiq_transmit(ifp, m, wq);
|
||||
UNLOCK(&wq->tx_lock);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
@ -579,7 +586,7 @@ oce_setup_intr(POCE_SOFTC sc)
|
||||
int rc = 0, use_intx = 0;
|
||||
int vector = 0, req_vectors = 0;
|
||||
|
||||
if (sc->rss_enable)
|
||||
if (is_rss_enabled(sc))
|
||||
req_vectors = MAX((sc->nrqs - 1), sc->nwqs);
|
||||
else
|
||||
req_vectors = 1;
|
||||
@ -778,7 +785,6 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
struct mbuf *m, *m_temp;
|
||||
struct oce_wq *wq = sc->wq[wq_index];
|
||||
struct oce_packet_desc *pd;
|
||||
uint32_t out;
|
||||
struct oce_nic_hdr_wqe *nichdr;
|
||||
struct oce_nic_frag_wqe *nicfrag;
|
||||
int num_wqes;
|
||||
@ -816,20 +822,14 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
}
|
||||
}
|
||||
|
||||
out = wq->packets_out + 1;
|
||||
if (out == OCE_WQ_PACKET_ARRAY_SIZE)
|
||||
out = 0;
|
||||
if (out == wq->packets_in)
|
||||
return EBUSY;
|
||||
|
||||
pd = &wq->pckts[wq->packets_out];
|
||||
pd = &wq->pckts[wq->pkt_desc_head];
|
||||
retry:
|
||||
rc = bus_dmamap_load_mbuf_sg(wq->tag,
|
||||
pd->map,
|
||||
m, segs, &pd->nsegs, BUS_DMA_NOWAIT);
|
||||
if (rc == 0) {
|
||||
num_wqes = pd->nsegs + 1;
|
||||
if (IS_BE(sc)) {
|
||||
if (IS_BE(sc) || IS_SH(sc)) {
|
||||
/*Dummy required only for BE3.*/
|
||||
if (num_wqes & 1)
|
||||
num_wqes++;
|
||||
@ -838,10 +838,11 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
bus_dmamap_unload(wq->tag, pd->map);
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
atomic_store_rel_int(&wq->pkt_desc_head,
|
||||
(wq->pkt_desc_head + 1) % \
|
||||
OCE_WQ_PACKET_ARRAY_SIZE);
|
||||
bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_PREWRITE);
|
||||
pd->mbuf = m;
|
||||
wq->packets_out = out;
|
||||
|
||||
nichdr =
|
||||
RING_GET_PRODUCER_ITEM_VA(wq->ring, struct oce_nic_hdr_wqe);
|
||||
@ -870,12 +871,12 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
nichdr->u0.s.lso = 1;
|
||||
nichdr->u0.s.lso_mss = m->m_pkthdr.tso_segsz;
|
||||
}
|
||||
if (!IS_BE(sc))
|
||||
if (!IS_BE(sc) || !IS_SH(sc))
|
||||
nichdr->u0.s.ipcs = 1;
|
||||
}
|
||||
|
||||
RING_PUT(wq->ring, 1);
|
||||
wq->ring->num_used++;
|
||||
atomic_add_int(&wq->ring->num_used, 1);
|
||||
|
||||
for (i = 0; i < pd->nsegs; i++) {
|
||||
nicfrag =
|
||||
@ -887,7 +888,7 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
nicfrag->u0.s.frag_len = segs[i].ds_len;
|
||||
pd->wqe_idx = wq->ring->pidx;
|
||||
RING_PUT(wq->ring, 1);
|
||||
wq->ring->num_used++;
|
||||
atomic_add_int(&wq->ring->num_used, 1);
|
||||
}
|
||||
if (num_wqes > (pd->nsegs + 1)) {
|
||||
nicfrag =
|
||||
@ -899,7 +900,7 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
nicfrag->u0.dw[3] = 0;
|
||||
pd->wqe_idx = wq->ring->pidx;
|
||||
RING_PUT(wq->ring, 1);
|
||||
wq->ring->num_used++;
|
||||
atomic_add_int(&wq->ring->num_used, 1);
|
||||
pd->nsegs++;
|
||||
}
|
||||
|
||||
@ -912,7 +913,7 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
bus_dmamap_sync(wq->ring->dma.tag, wq->ring->dma.map,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
reg_value = (num_wqes << 16) | wq->wq_id;
|
||||
OCE_WRITE_REG32(sc, db, PD_TXULP_DB, reg_value);
|
||||
OCE_WRITE_REG32(sc, db, wq->db_offset, reg_value);
|
||||
|
||||
} else if (rc == EFBIG) {
|
||||
if (retry_cnt == 0) {
|
||||
@ -929,7 +930,7 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
return rc;
|
||||
else
|
||||
goto free_ret;
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
free_ret:
|
||||
@ -942,21 +943,14 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
|
||||
static void
|
||||
oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, uint32_t status)
|
||||
{
|
||||
uint32_t in;
|
||||
struct oce_packet_desc *pd;
|
||||
POCE_SOFTC sc = (POCE_SOFTC) wq->parent;
|
||||
struct mbuf *m;
|
||||
|
||||
if (wq->packets_out == wq->packets_in)
|
||||
device_printf(sc->dev, "WQ transmit descriptor missing\n");
|
||||
|
||||
in = wq->packets_in + 1;
|
||||
if (in == OCE_WQ_PACKET_ARRAY_SIZE)
|
||||
in = 0;
|
||||
|
||||
pd = &wq->pckts[wq->packets_in];
|
||||
wq->packets_in = in;
|
||||
wq->ring->num_used -= (pd->nsegs + 1);
|
||||
pd = &wq->pckts[wq->pkt_desc_tail];
|
||||
atomic_store_rel_int(&wq->pkt_desc_tail,
|
||||
(wq->pkt_desc_tail + 1) % OCE_WQ_PACKET_ARRAY_SIZE);
|
||||
atomic_subtract_int(&wq->ring->num_used, pd->nsegs + 1);
|
||||
bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
|
||||
bus_dmamap_unload(wq->tag, pd->map);
|
||||
|
||||
@ -964,6 +958,7 @@ oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, uint32_t status)
|
||||
m_freem(m);
|
||||
pd->mbuf = NULL;
|
||||
|
||||
|
||||
if (sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) {
|
||||
if (wq->ring->num_used < (wq->ring->num_items / 2)) {
|
||||
sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE);
|
||||
@ -1066,16 +1061,15 @@ oce_tx_task(void *arg, int npending)
|
||||
POCE_SOFTC sc = wq->parent;
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
int rc = 0;
|
||||
|
||||
|
||||
#if __FreeBSD_version >= 800000
|
||||
if (TRY_LOCK(&wq->tx_lock)) {
|
||||
rc = oce_multiq_transmit(ifp, NULL, wq);
|
||||
if (rc) {
|
||||
device_printf(sc->dev,
|
||||
"TX[%d] restart failed\n", wq->queue_index);
|
||||
}
|
||||
UNLOCK(&wq->tx_lock);
|
||||
LOCK(&wq->tx_lock);
|
||||
rc = oce_multiq_transmit(ifp, NULL, wq);
|
||||
if (rc) {
|
||||
device_printf(sc->dev,
|
||||
"TX[%d] restart failed\n", wq->queue_index);
|
||||
}
|
||||
UNLOCK(&wq->tx_lock);
|
||||
#else
|
||||
oce_start(ifp);
|
||||
#endif
|
||||
@ -1134,7 +1128,6 @@ oce_wq_handler(void *arg)
|
||||
struct oce_nic_tx_cqe *cqe;
|
||||
int num_cqes = 0;
|
||||
|
||||
LOCK(&wq->tx_lock);
|
||||
bus_dmamap_sync(cq->ring->dma.tag,
|
||||
cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
|
||||
cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
|
||||
@ -1158,7 +1151,6 @@ oce_wq_handler(void *arg)
|
||||
|
||||
if (num_cqes)
|
||||
oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
|
||||
UNLOCK(&wq->tx_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1233,7 +1225,7 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe)
|
||||
}
|
||||
|
||||
/* Get vlan_tag value */
|
||||
if(IS_BE(sc))
|
||||
if(IS_BE(sc) || IS_SH(sc))
|
||||
vtag = BSWAP_16(cqe->u0.s.vlan_tag);
|
||||
else
|
||||
vtag = cqe->u0.s.vlan_tag;
|
||||
@ -1294,7 +1286,10 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe)
|
||||
|
||||
m->m_pkthdr.rcvif = sc->ifp;
|
||||
#if __FreeBSD_version >= 800000
|
||||
m->m_pkthdr.flowid = rq->queue_index;
|
||||
if (rq->queue_index)
|
||||
m->m_pkthdr.flowid = (rq->queue_index - 1);
|
||||
else
|
||||
m->m_pkthdr.flowid = rq->queue_index;
|
||||
m->m_flags |= M_FLOWID;
|
||||
#endif
|
||||
/* This deternies if vlan tag is Valid */
|
||||
@ -1401,7 +1396,7 @@ oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
|
||||
struct oce_nic_rx_cqe_v1 *cqe_v1;
|
||||
int port_id = 0;
|
||||
|
||||
if (sc->be3_native && IS_BE(sc)) {
|
||||
if (sc->be3_native && (IS_BE(sc) || IS_SH(sc))) {
|
||||
cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
|
||||
port_id = cqe_v1->u0.s.port;
|
||||
if (sc->port_id != port_id)
|
||||
@ -1547,7 +1542,6 @@ oce_rq_handler(void *arg)
|
||||
int num_cqes = 0, rq_buffers_used = 0;
|
||||
|
||||
|
||||
LOCK(&rq->rx_lock);
|
||||
bus_dmamap_sync(cq->ring->dma.tag,
|
||||
cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
|
||||
cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
|
||||
@ -1594,8 +1588,6 @@ oce_rq_handler(void *arg)
|
||||
oce_alloc_rx_bufs(rq, (rq_buffers_used - 1));
|
||||
}
|
||||
|
||||
UNLOCK(&rq->rx_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@ -1889,7 +1881,7 @@ oce_local_timer(void *arg)
|
||||
oce_tx_restart(sc, sc->wq[i]);
|
||||
|
||||
/* calculate and set the eq delay for optimal interrupt rate */
|
||||
if (IS_BE(sc))
|
||||
if (IS_BE(sc) || IS_SH(sc))
|
||||
oce_eqd_set_periodic(sc);
|
||||
|
||||
callout_reset(&sc->timer, hz, oce_local_timer, sc);
|
||||
@ -2080,38 +2072,22 @@ oce_mq_handler(void *arg)
|
||||
static void
|
||||
setup_max_queues_want(POCE_SOFTC sc)
|
||||
{
|
||||
int max_rss = 0;
|
||||
|
||||
/* Check if it is FLEX machine. Is so dont use RSS */
|
||||
if ((sc->function_mode & FNM_FLEX10_MODE) ||
|
||||
(sc->function_mode & FNM_UMC_MODE) ||
|
||||
(sc->function_mode & FNM_VNIC_MODE) ||
|
||||
(!sc->rss_enable) ||
|
||||
(!is_rss_enabled(sc)) ||
|
||||
(sc->flags & OCE_FLAGS_BE2)) {
|
||||
sc->nrqs = 1;
|
||||
sc->nwqs = 1;
|
||||
sc->rss_enable = 0;
|
||||
} else {
|
||||
/* For multiq, our deisgn is to have TX rings equal to
|
||||
RSS rings. So that we can pair up one RSS ring and TX
|
||||
to a single intr, which improves CPU cache efficiency.
|
||||
*/
|
||||
if (IS_BE(sc) && (!sc->be3_native))
|
||||
max_rss = OCE_LEGACY_MODE_RSS;
|
||||
else
|
||||
max_rss = OCE_MAX_RSS;
|
||||
|
||||
sc->nrqs = MIN(OCE_NCPUS, max_rss) + 1; /* 1 for def RX */
|
||||
sc->nwqs = MIN(OCE_NCPUS, max_rss);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_queues_got(POCE_SOFTC sc)
|
||||
{
|
||||
if (sc->rss_enable) {
|
||||
if (is_rss_enabled(sc)) {
|
||||
sc->nrqs = sc->intr_count + 1;
|
||||
sc->nwqs = sc->intr_count;
|
||||
} else {
|
||||
@ -2196,3 +2172,31 @@ oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m)
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
oce_get_config(POCE_SOFTC sc)
|
||||
{
|
||||
int rc = 0;
|
||||
uint32_t max_rss = 0;
|
||||
|
||||
if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
|
||||
max_rss = OCE_LEGACY_MODE_RSS;
|
||||
else
|
||||
max_rss = OCE_MAX_RSS;
|
||||
|
||||
if (!IS_BE(sc)) {
|
||||
rc = oce_get_func_config(sc);
|
||||
if (rc) {
|
||||
sc->nwqs = OCE_MAX_WQ;
|
||||
sc->nrssqs = max_rss;
|
||||
sc->nrqs = sc->nrssqs + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rc = oce_get_profile_config(sc);
|
||||
sc->nrssqs = max_rss;
|
||||
sc->nrqs = sc->nrssqs + 1;
|
||||
if (rc)
|
||||
sc->nwqs = OCE_MAX_WQ;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -97,11 +97,21 @@
|
||||
#define PCI_PRODUCT_BE3 0x0710 /* BE3 network adapter */
|
||||
#define PCI_PRODUCT_XE201 0xe220 /* XE201 network adapter */
|
||||
#define PCI_PRODUCT_XE201_VF 0xe228 /* XE201 with VF in Lancer */
|
||||
#define PCI_PRODUCT_SH 0x0720 /* Skyhawk network adapter */
|
||||
|
||||
#define IS_BE(sc) (((sc->flags & OCE_FLAGS_BE3) | \
|
||||
(sc->flags & OCE_FLAGS_BE2))? 1:0)
|
||||
#define IS_BE3(sc) (sc->flags & OCE_FLAGS_BE3)
|
||||
#define IS_BE2(sc) (sc->flags & OCE_FLAGS_BE2)
|
||||
#define IS_XE201(sc) ((sc->flags & OCE_FLAGS_XE201) ? 1:0)
|
||||
#define HAS_A0_CHIP(sc) ((sc->flags & OCE_FLAGS_HAS_A0_CHIP) ? 1:0)
|
||||
#define IS_SH(sc) ((sc->flags & OCE_FLAGS_SH) ? 1 : 0)
|
||||
|
||||
#define is_be_mode_mc(sc) ((sc->function_mode & FNM_FLEX10_MODE) || \
|
||||
(sc->function_mode & FNM_UMC_MODE) || \
|
||||
(sc->function_mode & FNM_VNIC_MODE))
|
||||
#define OCE_FUNCTION_CAPS_SUPER_NIC 0x40
|
||||
#define IS_PROFILE_SUPER_NIC(sc) (sc->function_caps & OCE_FUNCTION_CAPS_SUPER_NIC)
|
||||
|
||||
|
||||
/* proportion Service Level Interface queues */
|
||||
@ -113,8 +123,9 @@ extern int mp_ncpus; /* system's total active cpu cores */
|
||||
#define OCE_NCPUS mp_ncpus
|
||||
|
||||
/* This should be powers of 2. Like 2,4,8 & 16 */
|
||||
#define OCE_MAX_RSS 4 /* TODO: 8*/
|
||||
#define OCE_MAX_RSS 8
|
||||
#define OCE_LEGACY_MODE_RSS 4 /* For BE3 Legacy mode*/
|
||||
#define is_rss_enabled(sc) ((sc->function_caps & FNC_RSS) && !is_be_mode_mc(sc))
|
||||
|
||||
#define OCE_MIN_RQ 1
|
||||
#define OCE_MIN_WQ 1
|
||||
@ -149,6 +160,7 @@ extern int mp_ncpus; /* system's total active cpu cores */
|
||||
#define RSS_ENABLE_IPV6 0x4
|
||||
#define RSS_ENABLE_TCP_IPV6 0x8
|
||||
|
||||
#define INDIRECTION_TABLE_ENTRIES 128
|
||||
|
||||
/* flow control definitions */
|
||||
#define OCE_FC_NONE 0x00000000
|
||||
@ -194,6 +206,9 @@ extern int mp_ncpus; /* system's total active cpu cores */
|
||||
for (i = 0, wq = sc->wq[0]; i < sc->nwqs; i++, wq = sc->wq[i])
|
||||
#define for_all_rq_queues(sc, rq, i) \
|
||||
for (i = 0, rq = sc->rq[0]; i < sc->nrqs; i++, rq = sc->rq[i])
|
||||
#define for_all_rss_queues(sc, rq, i) \
|
||||
for (i = 0, rq = sc->rq[i + 1]; i < (sc->nrqs - 1); \
|
||||
i++, rq = sc->rq[i + 1])
|
||||
#define for_all_evnt_queues(sc, eq, i) \
|
||||
for (i = 0, eq = sc->eq[0]; i < sc->neqs; i++, eq = sc->eq[i])
|
||||
#define for_all_cq_queues(sc, cq, i) \
|
||||
@ -671,8 +686,8 @@ struct oce_wq {
|
||||
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 pkt_desc_tail;
|
||||
uint32_t pkt_desc_head;
|
||||
uint32_t wqm_used;
|
||||
boolean_t resched;
|
||||
uint32_t wq_free;
|
||||
@ -685,6 +700,7 @@ struct oce_wq {
|
||||
struct oce_tx_queue_stats tx_stats;
|
||||
struct buf_ring *br;
|
||||
struct task txtask;
|
||||
uint32_t db_offset;
|
||||
};
|
||||
|
||||
struct rq_config {
|
||||
@ -765,6 +781,7 @@ struct link_status {
|
||||
#define OCE_FLAGS_BE3 0x00000200
|
||||
#define OCE_FLAGS_XE201 0x00000400
|
||||
#define OCE_FLAGS_BE2 0x00000800
|
||||
#define OCE_FLAGS_SH 0x00001000
|
||||
|
||||
#define OCE_DEV_BE2_CFG_BAR 1
|
||||
#define OCE_DEV_CFG_BAR 0
|
||||
@ -833,11 +850,11 @@ typedef struct oce_softc {
|
||||
uint32_t ncqs;
|
||||
uint32_t nrqs;
|
||||
uint32_t nwqs;
|
||||
uint32_t nrssqs;
|
||||
|
||||
uint32_t tx_ring_size;
|
||||
uint32_t rx_ring_size;
|
||||
uint32_t rq_frag_size;
|
||||
uint32_t rss_enable;
|
||||
|
||||
uint32_t if_id; /* interface ID */
|
||||
uint32_t nifs; /* number of adapter interfaces, 0 or 1 */
|
||||
@ -873,37 +890,47 @@ typedef struct oce_softc {
|
||||
* BE3: accesses three BAR spaces (CFG, CSR, DB)
|
||||
* Lancer: accesses one BAR space (CFG)
|
||||
**************************************************/
|
||||
#define OCE_READ_REG32(sc, space, o) \
|
||||
#define OCE_READ_CSR_MPU(sc, space, o) \
|
||||
((IS_BE(sc)) ? (bus_space_read_4((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o)) \
|
||||
: (bus_space_read_4((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o)))
|
||||
(sc)->space##_bhandle,o)) \
|
||||
: (bus_space_read_4((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o)))
|
||||
#define OCE_READ_REG32(sc, space, o) \
|
||||
((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_4((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o)) \
|
||||
: (bus_space_read_4((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,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)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o)))
|
||||
((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_2((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o)) \
|
||||
: (bus_space_read_2((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,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)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o)))
|
||||
((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_1((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o)) \
|
||||
: (bus_space_read_1((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o)))
|
||||
|
||||
#define OCE_WRITE_REG32(sc, space, o, v) \
|
||||
#define OCE_WRITE_CSR_MPU(sc, space, o, v) \
|
||||
((IS_BE(sc)) ? (bus_space_write_4((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o,v)) \
|
||||
: (bus_space_write_4((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o,v)))
|
||||
: (bus_space_write_4((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o,v)))
|
||||
#define OCE_WRITE_REG32(sc, space, o, v) \
|
||||
((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_4((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o,v)) \
|
||||
: (bus_space_write_4((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o,v)))
|
||||
#define OCE_WRITE_REG16(sc, space, o, v) \
|
||||
((IS_BE(sc)) ? (bus_space_write_2((sc)->space##_btag, \
|
||||
((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_2((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o,v)) \
|
||||
: (bus_space_write_2((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o,v)))
|
||||
: (bus_space_write_2((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o,v)))
|
||||
#define OCE_WRITE_REG8(sc, space, o, v) \
|
||||
((IS_BE(sc)) ? (bus_space_write_1((sc)->space##_btag, \
|
||||
((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_1((sc)->space##_btag, \
|
||||
(sc)->space##_bhandle,o,v)) \
|
||||
: (bus_space_write_1((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o,v)))
|
||||
: (bus_space_write_1((sc)->devcfg_btag, \
|
||||
(sc)->devcfg_bhandle,o,v)))
|
||||
|
||||
|
||||
/***********************************************************
|
||||
@ -1024,6 +1051,8 @@ int oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce,
|
||||
int oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num);
|
||||
void oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
|
||||
int num);
|
||||
int oce_get_profile_config(POCE_SOFTC sc);
|
||||
int oce_get_func_config(POCE_SOFTC sc);
|
||||
void mbx_common_req_hdr_init(struct mbx_hdr *hdr,
|
||||
uint8_t dom,
|
||||
uint8_t port,
|
||||
@ -1072,6 +1101,9 @@ extern uint32_t oce_max_rsp_handled; /* max responses */
|
||||
#define LE_64(x) htole64(x)
|
||||
#define LE_32(x) htole32(x)
|
||||
#define LE_16(x) htole16(x)
|
||||
#define HOST_64(x) le64toh(x)
|
||||
#define HOST_32(x) le32toh(x)
|
||||
#define HOST_16(x) le16toh(x)
|
||||
#define DW_SWAP(x, l)
|
||||
#define IS_ALIGNED(x,a) ((x % a) == 0)
|
||||
#define ADDR_HI(x) ((uint32_t)((uint64_t)(x) >> 32))
|
||||
@ -1104,6 +1136,16 @@ static inline uint32_t oce_highbit(uint32_t x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int MPU_EP_SEMAPHORE(POCE_SOFTC sc)
|
||||
{
|
||||
if (IS_BE(sc))
|
||||
return MPU_EP_SEMAPHORE_BE3;
|
||||
else if (IS_SH(sc))
|
||||
return MPU_EP_SEMAPHORE_SH;
|
||||
else
|
||||
return MPU_EP_SEMAPHORE_XE201;
|
||||
}
|
||||
|
||||
#define TRANSCEIVER_DATA_NUM_ELE 64
|
||||
#define TRANSCEIVER_DATA_SIZE 256
|
||||
#define TRANSCEIVER_A0_SIZE 128
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -727,12 +727,14 @@ oce_rss_itbl_init(POCE_SOFTC sc, struct mbx_config_nic_rss *fwcmd)
|
||||
{
|
||||
int i = 0, j = 0, rc = 0;
|
||||
uint8_t *tbl = fwcmd->params.req.cputable;
|
||||
struct oce_rq *rq = NULL;
|
||||
|
||||
|
||||
for (j = 0; j < sc->nrqs; j++) {
|
||||
if (sc->rq[j]->cfg.is_rss_queue) {
|
||||
tbl[i] = sc->rq[j]->rss_cpuid;
|
||||
i = i + 1;
|
||||
for (j = 0; j < INDIRECTION_TABLE_ENTRIES ; j += (sc->nrqs - 1)) {
|
||||
for_all_rss_queues(sc, rq, i) {
|
||||
if ((j + i) >= INDIRECTION_TABLE_ENTRIES)
|
||||
break;
|
||||
tbl[j + i] = rq->rss_cpuid;
|
||||
}
|
||||
}
|
||||
if (i == 0) {
|
||||
@ -766,7 +768,7 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
|
||||
|
||||
bzero(&mbx, sizeof(struct oce_mbx));
|
||||
|
||||
if (IS_XE201(sc)) {
|
||||
if (IS_XE201(sc) || IS_SH(sc)) {
|
||||
version = OCE_MBX_VER_V1;
|
||||
fwcmd->params.req.enable_rss = RSS_ENABLE_UDP_IPV4 |
|
||||
RSS_ENABLE_UDP_IPV6;
|
||||
@ -1674,8 +1676,11 @@ oce_mbox_create_wq(struct oce_wq *wq)
|
||||
if (IS_XE201(sc)) {
|
||||
version = OCE_MBX_VER_V1;
|
||||
fwcmd->params.req.if_id = sc->if_id;
|
||||
} else
|
||||
version = OCE_MBX_VER_V0;
|
||||
} 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;
|
||||
|
||||
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
|
||||
MBX_SUBSYSTEM_NIC,
|
||||
@ -1703,6 +1708,10 @@ oce_mbox_create_wq(struct oce_wq *wq)
|
||||
goto error;
|
||||
}
|
||||
wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
|
||||
if (version == OCE_MBX_VER_V2)
|
||||
wq->db_offset = LE_32(fwcmd->params.rsp.db_offset);
|
||||
else
|
||||
wq->db_offset = PD_TXULP_DB;
|
||||
error:
|
||||
return rc;
|
||||
|
||||
@ -1874,7 +1883,7 @@ oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
|
||||
/* command post */
|
||||
rc = oce_mbox_post(sc, &mbx, NULL);
|
||||
if (!rc)
|
||||
rc = fwcmd->hdr.u0.rsp.status;
|
||||
rc = fwcmd->hdr.u0.rsp.status;
|
||||
if (rc) {
|
||||
device_printf(sc->dev,"%s failed - cmd status: %d\n",
|
||||
__FUNCTION__, rc);
|
||||
@ -1894,6 +1903,7 @@ oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
|
||||
TRANSCEIVER_A2_SIZE);
|
||||
}
|
||||
error:
|
||||
oce_dma_free(sc, &dma);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1935,10 +1945,193 @@ oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
|
||||
rc = oce_mbox_post(sc, &mbx, NULL);
|
||||
|
||||
if (!rc)
|
||||
rc = fwcmd->hdr.u0.rsp.status;
|
||||
rc = fwcmd->hdr.u0.rsp.status;
|
||||
if (rc)
|
||||
device_printf(sc->dev,"%s failed - cmd status: %d\n",
|
||||
__FUNCTION__, rc);
|
||||
}
|
||||
|
||||
int
|
||||
oce_get_profile_config(POCE_SOFTC sc)
|
||||
{
|
||||
struct oce_mbx mbx;
|
||||
struct mbx_common_get_profile_config *fwcmd;
|
||||
int rc = 0;
|
||||
int version = 0;
|
||||
struct oce_mq_sge *sgl;
|
||||
OCE_DMA_MEM dma;
|
||||
uint32_t desc_count = 0;
|
||||
struct oce_nic_resc_desc *nic_desc = NULL;
|
||||
int i;
|
||||
boolean_t nic_desc_valid = FALSE;
|
||||
|
||||
if (IS_BE2(sc))
|
||||
return -1;
|
||||
|
||||
/* Allocate DMA mem*/
|
||||
if (oce_dma_alloc(sc, sizeof(struct mbx_common_get_profile_config),
|
||||
&dma, 0))
|
||||
return ENOMEM;
|
||||
|
||||
/* Initialize MODIFY_EQ_DELAY ioctl header */
|
||||
fwcmd = OCE_DMAPTR(&dma, struct mbx_common_get_profile_config);
|
||||
bzero(fwcmd, sizeof(struct mbx_common_get_profile_config));
|
||||
|
||||
if (IS_BE3(sc))
|
||||
version = OCE_MBX_VER_V1;
|
||||
else
|
||||
version = OCE_MBX_VER_V0;
|
||||
|
||||
bzero(&mbx, sizeof(struct oce_mbx));
|
||||
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
|
||||
MBX_SUBSYSTEM_COMMON,
|
||||
OPCODE_COMMON_GET_PROFILE_CONFIG,
|
||||
MBX_TIMEOUT_SEC,
|
||||
sizeof(struct mbx_common_get_profile_config),
|
||||
version);
|
||||
/* fill rest of mbx */
|
||||
mbx.u0.s.embedded = 0;
|
||||
mbx.payload_length = sizeof(struct mbx_common_get_profile_config);
|
||||
mbx.u0.s.sge_count = 1;
|
||||
sgl = &mbx.payload.u0.u1.sgl[0];
|
||||
sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
|
||||
sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
|
||||
sgl->length = htole32(mbx.payload_length);
|
||||
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
|
||||
|
||||
fwcmd->params.req.type = ACTIVE_PROFILE;
|
||||
|
||||
/* command post */
|
||||
rc = oce_mbox_post(sc, &mbx, NULL);
|
||||
if (!rc)
|
||||
rc = fwcmd->hdr.u0.rsp.status;
|
||||
if (rc) {
|
||||
device_printf(sc->dev,"%s failed - cmd status: %d\n",
|
||||
__FUNCTION__, rc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
|
||||
desc_count = HOST_32(fwcmd->params.rsp.desc_count);
|
||||
for (i = 0; i < desc_count; i++) {
|
||||
if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
|
||||
(nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
|
||||
nic_desc_valid = TRUE;
|
||||
break;
|
||||
}
|
||||
nic_desc = (struct oce_nic_resc_desc *) \
|
||||
((char *)nic_desc + nic_desc->desc_len);
|
||||
}
|
||||
if (!nic_desc_valid) {
|
||||
rc = -1;
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
sc->nwqs = HOST_32(nic_desc->txq_count);
|
||||
if (sc->nwqs)
|
||||
sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
|
||||
else
|
||||
sc->nwqs = OCE_MAX_WQ;
|
||||
|
||||
}
|
||||
error:
|
||||
oce_dma_free(sc, &dma);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
oce_get_func_config(POCE_SOFTC sc)
|
||||
{
|
||||
struct oce_mbx mbx;
|
||||
struct mbx_common_get_func_config *fwcmd;
|
||||
int rc = 0;
|
||||
int version = 0;
|
||||
struct oce_mq_sge *sgl;
|
||||
OCE_DMA_MEM dma;
|
||||
uint32_t desc_count = 0;
|
||||
struct oce_nic_resc_desc *nic_desc = NULL;
|
||||
int i;
|
||||
boolean_t nic_desc_valid = FALSE;
|
||||
uint32_t max_rss = 0;
|
||||
|
||||
if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
|
||||
max_rss = OCE_LEGACY_MODE_RSS;
|
||||
else
|
||||
max_rss = OCE_MAX_RSS;
|
||||
|
||||
/* Allocate DMA mem*/
|
||||
if (oce_dma_alloc(sc, sizeof(struct mbx_common_get_func_config),
|
||||
&dma, 0))
|
||||
return ENOMEM;
|
||||
|
||||
/* Initialize MODIFY_EQ_DELAY ioctl header */
|
||||
fwcmd = OCE_DMAPTR(&dma, struct mbx_common_get_func_config);
|
||||
bzero(fwcmd, sizeof(struct mbx_common_get_func_config));
|
||||
|
||||
if (IS_SH(sc))
|
||||
version = OCE_MBX_VER_V1;
|
||||
else
|
||||
version = OCE_MBX_VER_V0;
|
||||
|
||||
bzero(&mbx, sizeof(struct oce_mbx));
|
||||
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
|
||||
MBX_SUBSYSTEM_COMMON,
|
||||
OPCODE_COMMON_GET_FUNCTION_CONFIG,
|
||||
MBX_TIMEOUT_SEC,
|
||||
sizeof(struct mbx_common_get_func_config),
|
||||
version);
|
||||
/* fill rest of mbx */
|
||||
mbx.u0.s.embedded = 0;
|
||||
mbx.payload_length = sizeof(struct mbx_common_get_func_config);
|
||||
mbx.u0.s.sge_count = 1;
|
||||
sgl = &mbx.payload.u0.u1.sgl[0];
|
||||
sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
|
||||
sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
|
||||
sgl->length = htole32(mbx.payload_length);
|
||||
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
|
||||
|
||||
/* command post */
|
||||
rc = oce_mbox_post(sc, &mbx, NULL);
|
||||
if (!rc)
|
||||
rc = fwcmd->hdr.u0.rsp.status;
|
||||
if (rc) {
|
||||
device_printf(sc->dev,"%s failed - cmd status: %d\n",
|
||||
__FUNCTION__, rc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
|
||||
desc_count = HOST_32(fwcmd->params.rsp.desc_count);
|
||||
for (i = 0; i < desc_count; i++) {
|
||||
if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
|
||||
(nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
|
||||
nic_desc_valid = TRUE;
|
||||
break;
|
||||
}
|
||||
nic_desc = (struct oce_nic_resc_desc *) \
|
||||
((char *)nic_desc + nic_desc->desc_len);
|
||||
}
|
||||
if (!nic_desc_valid) {
|
||||
rc = -1;
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
sc->nwqs = HOST_32(nic_desc->txq_count);
|
||||
if (sc->nwqs)
|
||||
sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
|
||||
else
|
||||
sc->nwqs = OCE_MAX_WQ;
|
||||
|
||||
sc->nrssqs = HOST_32(nic_desc->rssq_count);
|
||||
if (sc->nrssqs)
|
||||
sc->nrssqs = MIN(sc->nrssqs, max_rss);
|
||||
else
|
||||
sc->nrssqs = max_rss;
|
||||
sc->nrqs = sc->nrssqs + 1; /* 1 for def RX */;
|
||||
}
|
||||
error:
|
||||
oce_dma_free(sc, &dma);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -106,7 +106,7 @@ oce_queue_init_all(POCE_SOFTC sc)
|
||||
for_all_rq_queues(sc, rq, i) {
|
||||
sc->rq[i] = oce_rq_init(sc, sc->rx_ring_size, sc->rq_frag_size,
|
||||
OCE_MAX_JUMBO_FRAME_SIZE,
|
||||
(i == 0) ? 0 : sc->rss_enable);
|
||||
(i == 0) ? 0 : is_rss_enabled(sc));
|
||||
if (!sc->rq[i])
|
||||
goto error;
|
||||
}
|
||||
@ -1225,7 +1225,7 @@ oce_start_rx(POCE_SOFTC sc)
|
||||
DELAY(1);
|
||||
|
||||
/* RSS config */
|
||||
if (sc->rss_enable) {
|
||||
if (is_rss_enabled(sc)) {
|
||||
rc = oce_config_nic_rss(sc, (uint8_t) sc->if_id, RSS_ENABLE);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -140,7 +140,7 @@ oce_add_sysctls(POCE_SOFTC sc)
|
||||
stats_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
|
||||
CTLFLAG_RD, NULL, "Ethernet Statistics");
|
||||
|
||||
if (IS_BE(sc))
|
||||
if (IS_BE(sc) || IS_SH(sc))
|
||||
oce_add_stats_sysctls_be3(sc, ctx, stats_node);
|
||||
else
|
||||
oce_add_stats_sysctls_xe201(sc, ctx, stats_node);
|
||||
@ -223,7 +223,7 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (IS_BE(sc)) {
|
||||
if (IS_BE(sc) || IS_SH(sc)) {
|
||||
if ((sc->flags & OCE_FLAGS_BE2)) {
|
||||
device_printf(sc->dev,
|
||||
"Flashing not supported for BE2 yet.\n");
|
||||
@ -1270,7 +1270,7 @@ oce_stats_init(POCE_SOFTC sc)
|
||||
{
|
||||
int rc = 0, sz;
|
||||
|
||||
if (IS_BE(sc)) {
|
||||
if (IS_BE(sc) || IS_SH(sc)) {
|
||||
if (sc->flags & OCE_FLAGS_BE2)
|
||||
sz = sizeof(struct mbx_get_nic_stats_v0);
|
||||
else
|
||||
@ -1298,7 +1298,7 @@ oce_refresh_nic_stats(POCE_SOFTC sc)
|
||||
{
|
||||
int rc = 0, reset = 0;
|
||||
|
||||
if (IS_BE(sc)) {
|
||||
if (IS_BE(sc) || IS_SH(sc)) {
|
||||
if (sc->flags & OCE_FLAGS_BE2) {
|
||||
rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem);
|
||||
if (!rc)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Emulex
|
||||
* Copyright (C) 2013 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
Loading…
Reference in New Issue
Block a user