Author: delphij
Date: Sat Jul  6 23:56:58 2013
New Revision: 252905
URL: http://svnweb.freebsd.org/changeset/base/252905

Log:
  MFC r252869:
  
  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>

Modified:
  stable/9/share/man/man4/oce.4
  stable/9/sys/dev/oce/oce_hw.c
  stable/9/sys/dev/oce/oce_hw.h
  stable/9/sys/dev/oce/oce_if.c
  stable/9/sys/dev/oce/oce_if.h
  stable/9/sys/dev/oce/oce_mbox.c
  stable/9/sys/dev/oce/oce_queue.c
  stable/9/sys/dev/oce/oce_sysctl.c
  stable/9/sys/dev/oce/oce_util.c
Directory Properties:
  stable/9/share/man/man4/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/share/man/man4/oce.4
==============================================================================
--- stable/9/share/man/man4/oce.4       Sat Jul  6 23:46:23 2013        
(r252904)
+++ stable/9/share/man/man4/oce.4       Sat Jul  6 23:56:58 2013        
(r252905)
@@ -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

Modified: stable/9/sys/dev/oce/oce_hw.c
==============================================================================
--- stable/9/sys/dev/oce/oce_hw.c       Sat Jul  6 23:46:23 2013        
(r252904)
+++ stable/9/sys/dev/oce/oce_hw.c       Sat Jul  6 23:56:58 2013        
(r252905)
@@ -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);
 

Modified: stable/9/sys/dev/oce/oce_hw.h
==============================================================================
--- stable/9/sys/dev/oce/oce_hw.h       Sat Jul  6 23:46:23 2013        
(r252904)
+++ stable/9/sys/dev/oce/oce_hw.h       Sat Jul  6 23:56:58 2013        
(r252905)
@@ -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];

Modified: stable/9/sys/dev/oce/oce_if.c
==============================================================================
--- stable/9/sys/dev/oce/oce_if.c       Sat Jul  6 23:46:23 2013        
(r252904)
+++ stable/9/sys/dev/oce/oce_if.c       Sat Jul  6 23:56:58 2013        
(r252905)
@@ -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
 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 */
@@ -146,6 +147,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
 };
 
 
@@ -189,6 +191,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;
                                }
@@ -213,7 +218,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;
@@ -228,6 +232,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);
@@ -485,17 +491,18 @@ oce_multiq_start(struct ifnet *ifp, stru
        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;
 
 }
@@ -578,7 +585,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;
@@ -777,7 +784,6 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp,
        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;
@@ -815,20 +821,14 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp,
                }
        }
 
-       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++;
@@ -837,10 +837,11 @@ retry:
                        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);
@@ -869,12 +870,12 @@ retry:
                                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 =
@@ -886,7 +887,7 @@ retry:
                        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 =
@@ -898,7 +899,7 @@ retry:
                        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++;
                }
 
@@ -911,7 +912,7 @@ retry:
                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) {
@@ -928,7 +929,7 @@ retry:
                return rc;
        else
                goto free_ret;
-
+       
        return 0;
 
 free_ret:
@@ -941,21 +942,14 @@ free_ret:
 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);
 
@@ -963,6 +957,7 @@ oce_tx_complete(struct oce_wq *wq, uint3
        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);
@@ -1065,16 +1060,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
@@ -1133,7 +1127,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);
@@ -1157,7 +1150,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;
 }
@@ -1234,7 +1226,7 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_i
        }
 
         /* 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;
@@ -1295,7 +1287,10 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_i
 
                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 */
@@ -1402,7 +1397,7 @@ oce_cqe_portid_valid(POCE_SOFTC sc, stru
        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)
@@ -1548,7 +1543,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);
@@ -1595,8 +1589,6 @@ oce_rq_handler(void *arg)
                        oce_alloc_rx_bufs(rq, (rq_buffers_used - 1));
        }
 
-       UNLOCK(&rq->rx_lock);
-       
        return 0;
 
 }
@@ -1890,7 +1882,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);
@@ -2081,38 +2073,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 {
@@ -2197,3 +2173,31 @@ oce_tx_asic_stall_verify(POCE_SOFTC sc, 
        }
        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;
+       }
+}

Modified: stable/9/sys/dev/oce/oce_if.h
==============================================================================
--- stable/9/sys/dev/oce/oce_if.h       Sat Jul  6 23:46:23 2013        
(r252904)
+++ stable/9/sys/dev/oce/oce_if.h       Sat Jul  6 23:56:58 2013        
(r252905)
@@ -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
 #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
 #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
                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
 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;      /* 
 #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(uint3
        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

Modified: stable/9/sys/dev/oce/oce_mbox.c
==============================================================================
--- stable/9/sys/dev/oce/oce_mbox.c     Sat Jul  6 23:46:23 2013        
(r252904)
+++ stable/9/sys/dev/oce/oce_mbox.c     Sat Jul  6 23:56:58 2013        
(r252905)
@@ -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 
 {
        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
 
        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 
        /* 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 
                                TRANSCEIVER_A2_SIZE);
        }
 error:
+       oce_dma_free(sc, &dma);
        return rc;
 }
 
@@ -1935,10 +1945,193 @@ oce_mbox_eqd_modify_periodic(POCE_SOFTC 
        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 */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to