Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Mar 2013 09:53:38 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r247880 - head/sys/dev/oce
Message-ID:  <201303060953.r269rcsF063284@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Wed Mar  6 09:53:38 2013
New Revision: 247880
URL: http://svnweb.freebsd.org/changeset/base/247880

Log:
  Update driver to version 4.6.95.0.
  
  Submitted by:	"Duvvuru,Venkat Kumar" <VenkatKumar.Duvvuru Emulex.Com>
  MFC after:	3 days

Modified:
  head/sys/dev/oce/oce_hw.c
  head/sys/dev/oce/oce_hw.h
  head/sys/dev/oce/oce_if.c
  head/sys/dev/oce/oce_if.h
  head/sys/dev/oce/oce_mbox.c
  head/sys/dev/oce/oce_queue.c
  head/sys/dev/oce/oce_sysctl.c
  head/sys/dev/oce/oce_util.c

Modified: head/sys/dev/oce/oce_hw.c
==============================================================================
--- head/sys/dev/oce/oce_hw.c	Wed Mar  6 09:33:16 2013	(r247879)
+++ head/sys/dev/oce/oce_hw.c	Wed Mar  6 09:53:38 2013	(r247880)
@@ -405,11 +405,6 @@ oce_create_nw_interface(POCE_SOFTC sc)
 
 	sc->if_cap_flags = capab_en_flags;
 
-	/* Enable VLAN Promisc on HW */
-	rc = oce_config_vlan(sc, (uint8_t) sc->if_id, NULL, 0, 1, 1);
-	if (rc)
-		goto error;
-
 	/* set default flow control */
 	rc = oce_set_flow_control(sc, sc->flow_control);
 	if (rc)
@@ -477,12 +472,9 @@ oce_hw_start(POCE_SOFTC sc)
 		return 1;
 	
 	if (link.logical_link_status == NTWK_LOGICAL_LINK_UP) {
-		sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
 		sc->link_status = NTWK_LOGICAL_LINK_UP;
 		if_link_state_change(sc->ifp, LINK_STATE_UP);
 	} else {
-		sc->ifp->if_drv_flags &=
-			~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 		sc->link_status = NTWK_LOGICAL_LINK_DOWN;
 		if_link_state_change(sc->ifp, LINK_STATE_DOWN);
 	}

Modified: head/sys/dev/oce/oce_hw.h
==============================================================================
--- head/sys/dev/oce/oce_hw.h	Wed Mar  6 09:33:16 2013	(r247879)
+++ head/sys/dev/oce/oce_hw.h	Wed Mar  6 09:53:38 2013	(r247880)
@@ -38,6 +38,8 @@
 
 /* $FreeBSD$ */
 
+/* $FreeBSD$ */
+
 #include <sys/types.h>
 
 #undef _BIG_ENDIAN /* TODO */
@@ -155,7 +157,10 @@
 #define	ASYNC_EVENT_LINK_UP		0x1
 #define	ASYNC_EVENT_LINK_DOWN		0x0
 #define ASYNC_EVENT_GRP5		0x5
+#define ASYNC_EVENT_CODE_DEBUG		0x6
 #define ASYNC_EVENT_PVID_STATE		0x3
+#define ASYNC_EVENT_DEBUG_QNQ		0x1
+#define ASYNC_EVENT_CODE_SLIPORT	0x11
 #define VLAN_VID_MASK			0x0FFF
 
 /* port link_status */
@@ -707,6 +712,17 @@ struct oce_async_event_grp5_pvid_state {
 	uint32_t code;
 };
 
+/* async event indicating outer VLAN tag in QnQ */
+struct oce_async_event_qnq {
+        uint8_t valid;       /* Indicates if outer VLAN is valid */
+        uint8_t rsvd0;
+        uint16_t vlan_tag;
+        uint32_t event_tag;
+        uint8_t rsvd1[4];
+	uint32_t code;
+} ;
+
+
 typedef union oce_mq_ext_ctx_u {
 	uint32_t dw[6];
 	struct {
@@ -750,6 +766,44 @@ typedef union oce_mq_ext_ctx_u {
 		/* dw5 */
 		uint32_t dw8rsvd1;
 	} v0;
+	        struct {
+	#ifdef _BIG_ENDIAN
+                /* dw0 */
+                uint32_t cq_id:16;
+                uint32_t num_pages:16;
+                /* dw1 */
+                uint32_t async_evt_bitmap;
+                /* dw2 */
+                uint32_t dw5rsvd2:12;
+                uint32_t ring_size:4;
+                uint32_t async_cq_id:16;
+                /* dw3 */
+                uint32_t valid:1;
+                uint32_t dw6rsvd1:31;
+                /* dw4 */
+		uint32_t dw7rsvd1:31;
+                uint32_t async_cq_valid:1;
+        #else
+                /* dw0 */
+                uint32_t num_pages:16;
+                uint32_t cq_id:16;
+                /* dw1 */
+                uint32_t async_evt_bitmap;
+                /* dw2 */
+                uint32_t async_cq_id:16;
+                uint32_t ring_size:4;
+                uint32_t dw5rsvd2:12;
+                /* dw3 */
+                uint32_t dw6rsvd1:31;
+                uint32_t valid:1;
+                /* dw4 */
+                uint32_t async_cq_valid:1;
+                uint32_t dw7rsvd1:31;
+        #endif
+                /* dw5 */
+                uint32_t dw8rsvd1;
+        } v1;
+
 } oce_mq_ext_ctx_t;
 
 
@@ -826,6 +880,7 @@ enum COMMON_SUBSYSTEM_OPCODES {
 	OPCODE_COMMON_SET_BEACON_CONFIG = 69,
 	OPCODE_COMMON_GET_BEACON_CONFIG = 70,
 	OPCODE_COMMON_GET_PHYSICAL_LINK_CONFIG = 71,
+	OPCODE_COMMON_READ_TRANSRECEIVER_DATA = 73,
 	OPCODE_COMMON_GET_OEM_ATTRIBUTES = 76,
 	OPCODE_COMMON_GET_PORT_NAME = 77,
 	OPCODE_COMMON_GET_CONFIG_SIGNATURE = 78,
@@ -1724,6 +1779,12 @@ struct mbx_set_common_iface_rx_filter {
 	} params;
 };
 
+struct be_set_eqd {
+	uint32_t eq_id;
+	uint32_t phase;
+	uint32_t dm;
+};
+
 /* [41] OPCODE_COMMON_MODIFY_EQ_DELAY */
 struct mbx_modify_common_eq_delay {
 	struct mbx_hdr hdr;
@@ -1743,6 +1804,76 @@ struct mbx_modify_common_eq_delay {
 	} params;
 };
 
+/* [32] OPCODE_COMMON_GET_CNTL_ATTRIBUTES */
+
+struct mgmt_hba_attr {
+	int8_t   flashrom_ver_str[32];
+	int8_t   manufac_name[32];
+	uint32_t supp_modes;
+	int8_t   seeprom_ver_lo;
+	int8_t   seeprom_ver_hi;
+	int8_t   rsvd0[2];
+	uint32_t ioctl_data_struct_ver;
+	uint32_t ep_fw_data_struct_ver;
+	uint8_t  ncsi_ver_str[12];
+	uint32_t def_ext_to;
+	int8_t   cntl_mod_num[32];
+	int8_t   cntl_desc[64];
+	int8_t   cntl_ser_num[32];
+	int8_t   ip_ver_str[32];
+	int8_t   fw_ver_str[32];
+	int8_t   bios_ver_str[32];
+	int8_t   redboot_ver_str[32];
+	int8_t   drv_ver_str[32];
+	int8_t   fw_on_flash_ver_str[32];
+	uint32_t funcs_supp;
+	uint16_t max_cdblen;
+	uint8_t  asic_rev;
+	uint8_t  gen_guid[16];
+	uint8_t  hba_port_count;
+	uint16_t default_link_down_timeout;
+	uint8_t  iscsi_ver_min_max;
+	uint8_t  multifunc_dev;
+	uint8_t  cache_valid;
+	uint8_t  hba_status;
+	uint8_t  max_domains_supp;
+	uint8_t  phy_port;
+	uint32_t fw_post_status;
+	uint32_t hba_mtu[8];
+	uint8_t  iSCSI_feat;
+	uint8_t  asic_gen;
+	uint8_t  future_u8[2];
+	uint32_t future_u32[3];
+};
+
+struct mgmt_cntl_attr {
+	struct    mgmt_hba_attr hba_attr;
+	uint16_t  pci_vendor_id;
+	uint16_t  pci_device_id;
+	uint16_t  pci_sub_vendor_id;
+	uint16_t  pci_sub_system_id;
+	uint8_t   pci_bus_num;
+	uint8_t   pci_dev_num;
+	uint8_t   pci_func_num;
+	uint8_t   interface_type;
+	uint64_t  unique_id;
+	uint8_t   netfilters;
+	uint8_t   rsvd0[3];
+	uint32_t  future_u32[4];
+};
+
+struct mbx_common_get_cntl_attr {
+	struct mbx_hdr hdr;
+	union {
+		struct {
+			uint32_t rsvd0;
+		} req;
+		struct {
+			struct mgmt_cntl_attr cntl_attr_info;
+		} rsp;
+	} params;
+};
+
 /* [59] OPCODE_ADD_COMMON_IFACE_MAC */
 struct mbx_add_common_iface_mac {
 	struct mbx_hdr hdr;
@@ -1785,6 +1916,23 @@ struct ioctl_common_function_reset {
 	struct mbx_hdr hdr;
 };
 
+/* [73] OPCODE_COMMON_READ_TRANSRECEIVER_DATA */
+struct mbx_read_common_transrecv_data {
+	struct mbx_hdr hdr;
+	union {
+		struct {
+			uint32_t    page_num;
+			uint32_t    port;
+		} req;
+		struct {
+			uint32_t    page_num;
+			uint32_t    port;
+			uint32_t    page_data[32];
+		} rsp;
+	} params;
+
+};
+
 /* [80] OPCODE_COMMON_FUNCTION_LINK_CONFIG */
 struct mbx_common_func_link_cfg {
 	struct mbx_hdr hdr;
@@ -2110,7 +2258,9 @@ enum RSS_ENABLE_FLAGS {
 	RSS_ENABLE_IPV4 	= 0x1,	/* (IPV4 HASH enabled ) */
 	RSS_ENABLE_TCP_IPV4 	= 0x2,	/* (TCP IPV4 Hash enabled) */
 	RSS_ENABLE_IPV6 	= 0x4,	/* (IPV6 HASH enabled) */
-	RSS_ENABLE_TCP_IPV6 	= 0x8	/* (TCP IPV6 HASH */
+	RSS_ENABLE_TCP_IPV6 	= 0x8,	/* (TCP IPV6 HASH */
+	RSS_ENABLE_UDP_IPV4	= 0x10, /* UDP IPV4 HASH */
+	RSS_ENABLE_UDP_IPV6	= 0x20  /* UDP IPV6 HASH */
 };
 #define RSS_ENABLE (RSS_ENABLE_IPV4 | RSS_ENABLE_TCP_IPV4)
 #define RSS_DISABLE RSS_ENABLE_NONE

Modified: head/sys/dev/oce/oce_if.c
==============================================================================
--- head/sys/dev/oce/oce_if.c	Wed Mar  6 09:33:16 2013	(r247879)
+++ head/sys/dev/oce/oce_if.c	Wed Mar  6 09:53:38 2013	(r247880)
@@ -36,6 +36,7 @@
  * Costa Mesa, CA 92626
  */
 
+
 /* $FreeBSD$ */
 
 #include "opt_inet6.h"
@@ -94,7 +95,8 @@ static void setup_max_queues_want(POCE_S
 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 struct mbuf *oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete);
 
 /* IP specific */
 #if defined(INET6) || defined(INET)
@@ -266,8 +268,6 @@ oce_attach(device_t dev)
 	rc = callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc);
 	if (rc)
 		goto stats_free;
-#ifdef DEV_NETMAP
-#endif /* DEV_NETMAP */
 
 	return 0;
 
@@ -485,7 +485,7 @@ oce_multiq_start(struct ifnet *ifp, stru
 	struct oce_wq *wq = NULL;
 	int queue_index = 0;
 	int status = 0;
-	
+
 	if ((m->m_flags & M_FLOWID) != 0)
 		queue_index = m->m_pkthdr.flowid % sc->nwqs;
 	
@@ -568,6 +568,7 @@ oce_intr(void *arg, int pending)
 
 eq_arm:
 	oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
+
 	return;
 }
 
@@ -633,6 +634,8 @@ oce_fast_isr(void *arg)
 
 	taskqueue_enqueue_fast(ii->tq, &ii->task);
 
+ 	ii->eq->intr++;	
+
 	return FILTER_HANDLED;
 }
 
@@ -780,6 +783,7 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp,
 	struct oce_nic_frag_wqe *nicfrag;
 	int num_wqes;
 	uint32_t reg_value;
+	boolean_t complete = TRUE;
 
 	m = *mpp;
 	if (!m)
@@ -790,6 +794,15 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp,
 		goto free_ret;
 	}
 
+	if(oce_tx_asic_stall_verify(sc, m)) {
+		m = oce_insert_vlan_tag(sc, m, &complete);
+		if(!m) {
+			device_printf(sc->dev, "Insertion unsuccessful\n");
+			return 0;
+		}
+
+	}
+
 	if (m->m_pkthdr.csum_flags & CSUM_TSO) {
 		/* consolidate packet buffers for TSO/LSO segment offload */
 #if defined(INET6) || defined(INET)
@@ -837,15 +850,15 @@ retry:
 		nichdr->u0.dw[2] = 0;
 		nichdr->u0.dw[3] = 0;
 
-		nichdr->u0.s.complete = 1;
+		nichdr->u0.s.complete = complete;
 		nichdr->u0.s.event = 1;
 		nichdr->u0.s.crc = 1;
 		nichdr->u0.s.forward = 0;
 		nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0;
 		nichdr->u0.s.udpcs =
-		    (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
+			(m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
 		nichdr->u0.s.tcpcs =
-		    (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
+			(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) {
@@ -895,7 +908,7 @@ retry:
 		wq->tx_stats.tx_wrbs += num_wqes;
 		wq->tx_stats.tx_bytes += m->m_pkthdr.len;
 		wq->tx_stats.tx_pkts++;
-	
+
 		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;
@@ -1081,6 +1094,9 @@ oce_start(struct ifnet *ifp)
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
 			IFF_DRV_RUNNING)
 		return;
+
+	if (!sc->link_status)
+		return;
 	
 	do {
 		IF_DEQUEUE(&sc->ifp->if_snd, m);
@@ -1303,7 +1319,6 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_i
 #if defined(INET6) || defined(INET)
 		/* Try to queue to LRO */
 		if (IF_LRO_ENABLED(sc) &&
-		    !(m->m_flags & M_VLANTAG) &&
 		    (cqe->u0.s.ip_cksum_pass) &&
 		    (cqe->u0.s.l4_cksum_pass) &&
 		    (!cqe->u0.s.ip_ver)       &&
@@ -1343,13 +1358,6 @@ oce_discard_rx_comp(struct oce_rq *rq, s
 	POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
 	int num_frags = cqe->u0.s.num_fragments;
 
-	if (IS_XE201(sc) && cqe->u0.s.error) {
-		/* Lancer A0 workaround
-		* num_frags will be 1 more than actual in case of error
-		 */
-		if (num_frags)
-			num_frags -= 1;
-	}
 	for (i = 0; i < num_frags; i++) {
 		if (rq->packets_out == rq->packets_in) {
 			device_printf(sc->dev,
@@ -1458,7 +1466,7 @@ oce_free_lro(POCE_SOFTC sc)
 			tcp_lro_free(lro);
 	}
 }
-#endif /* INET6 || INET */
+#endif
 
 int
 oce_alloc_rx_bufs(struct oce_rq *rq, int count)
@@ -1471,7 +1479,7 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int
 	struct oce_nic_rqe *rqe;
 	pd_rxulp_db_t rxdb_reg;
 
-
+	bzero(&rxdb_reg, sizeof(pd_rxulp_db_t));
 	for (i = 0; i < count; i++) {
 		in = rq->packets_in + 1;
 		if (in == OCE_RQ_PACKET_ARRAY_SIZE)
@@ -1512,14 +1520,12 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int
 	}
 	if (added != 0) {
 		for (i = added / OCE_MAX_RQ_POSTS; i > 0; i--) {
-			DELAY(1);
 			rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS;
 			rxdb_reg.bits.qid = rq->rq_id;
 			OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
 			added -= OCE_MAX_RQ_POSTS;
 		}
 		if (added > 0) {
-			DELAY(1);
 			rxdb_reg.bits.qid = rq->rq_id;
 			rxdb_reg.bits.num_posted = added;
 			OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
@@ -1554,13 +1560,8 @@ oce_rq_handler(void *arg)
 		} else {
 			rq->rx_stats.rxcp_err++;
 			sc->ifp->if_ierrors++;
-			if (IS_XE201(sc)) 
-				/* Lancer A0 no buffer workaround */
-				oce_discard_rx_comp(rq, cqe);
-			else	
-				/* Post L3/L4 errors to stack.*/
-				oce_rx(rq, cqe->u0.s.frag_index, cqe);
-			
+			/* Post L3/L4 errors to stack.*/
+			oce_rx(rq, cqe->u0.s.frag_index, cqe);
 		}
 		rq->rx_stats.rx_compl++;
 		cqe->u0.dw[2] = 0;
@@ -1757,18 +1758,18 @@ oce_handle_passthrough(struct ifnet *ifp
 	uint32_t req_size;
 	struct mbx_hdr req;
 	OCE_DMA_MEM dma_mem;
-
+	struct mbx_common_get_cntl_attr *fw_cmd;
 
 	if (copyin(priv_data, cookie, strlen(IOCTL_COOKIE)))
 		return EFAULT;
-	
+
 	if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE)))
 		return EINVAL;
-	
+
 	ioctl_ptr = (char *)priv_data + strlen(IOCTL_COOKIE);
 	if (copyin(ioctl_ptr, &req, sizeof(struct mbx_hdr)))
 		return EFAULT;
-	
+
 	req_size = le32toh(req.u0.req.request_length);
 	if (req_size > 65536)
 		return EINVAL;
@@ -1792,12 +1793,86 @@ oce_handle_passthrough(struct ifnet *ifp
 	if (copyout(OCE_DMAPTR(&dma_mem,char), ioctl_ptr, req_size))
 		rc =  EFAULT;
 
+	/* 
+	   firmware is filling all the attributes for this ioctl except
+	   the driver version..so fill it 
+	 */
+	if(req.u0.rsp.opcode == OPCODE_COMMON_GET_CNTL_ATTRIBUTES) {
+		fw_cmd = (struct mbx_common_get_cntl_attr *) ioctl_ptr;
+		strncpy(fw_cmd->params.rsp.cntl_attr_info.hba_attr.drv_ver_str,
+			COMPONENT_REVISION, strlen(COMPONENT_REVISION));	
+	}
+
 dma_free:
 	oce_dma_free(sc, &dma_mem);
 	return rc;
 
 }
 
+static void
+oce_eqd_set_periodic(POCE_SOFTC sc)
+{
+	struct oce_set_eqd set_eqd[OCE_MAX_EQ];
+	struct oce_aic_obj *aic;
+	struct oce_eq *eqo;
+	uint64_t now = 0, delta;
+	int eqd, i, num = 0;
+	uint32_t ips = 0;
+	int tps;
+
+	for (i = 0 ; i < sc->neqs; i++) {
+		eqo = sc->eq[i];
+		aic = &sc->aic_obj[i];
+		/* When setting the static eq delay from the user space */
+		if (!aic->enable) {
+			eqd = aic->et_eqd;
+			goto modify_eqd;
+		}
+
+		now = ticks;
+
+		/* Over flow check */
+		if ((now < aic->ticks) || (eqo->intr < aic->intr_prev))
+			goto done;
+
+		delta = now - aic->ticks;
+		tps = delta/hz;
+
+		/* Interrupt rate based on elapsed ticks */
+		if(tps)
+			ips = (uint32_t)(eqo->intr - aic->intr_prev) / tps;
+
+		if (ips > INTR_RATE_HWM)
+			eqd = aic->cur_eqd + 20;
+		else if (ips < INTR_RATE_LWM)
+			eqd = aic->cur_eqd / 2;
+		else
+			goto done;
+
+		if (eqd < 10)
+			eqd = 0;
+
+		/* Make sure that the eq delay is in the known range */
+		eqd = min(eqd, aic->max_eqd);
+		eqd = max(eqd, aic->min_eqd);
+
+modify_eqd:
+		if (eqd != aic->cur_eqd) {
+			set_eqd[num].delay_multiplier = (eqd * 65)/100;
+			set_eqd[num].eq_id = eqo->eq_id;
+			aic->cur_eqd = eqd;
+			num++;
+		}
+done:
+		aic->intr_prev = eqo->intr;
+		aic->ticks = now;
+	}
+
+	/* Is there atleast one eq that needs to be modified? */
+	if(num)
+		oce_mbox_eqd_modify_periodic(sc, set_eqd, num);
+
+}
 
 static void
 oce_local_timer(void *arg)
@@ -1813,6 +1888,10 @@ oce_local_timer(void *arg)
 	for (i = 0; i < sc->nwqs; i++)
 		oce_tx_restart(sc, sc->wq[i]);
 	
+	/* calculate and set the eq delay for optimal interrupt rate */
+	if (IS_BE(sc))
+		oce_eqd_set_periodic(sc);
+
 	callout_reset(&sc->timer, hz, oce_local_timer, sc);
 }
 
@@ -1849,17 +1928,17 @@ oce_if_deactivate(POCE_SOFTC sc)
 	/* Stop intrs and finish any bottom halves pending */
 	oce_hw_intr_disable(sc);
 
-    /* Since taskqueue_drain takes a Giant Lock, We should not acquire
-       any other lock. So unlock device lock and require after
-       completing taskqueue_drain.
-    */
-    UNLOCK(&sc->dev_lock);
+	/* Since taskqueue_drain takes a Gaint Lock, We should not acquire
+	   any other lock. So unlock device lock and require after
+	   completing taskqueue_drain.
+	*/
+	UNLOCK(&sc->dev_lock);
 	for (i = 0; i < sc->intr_count; i++) {
 		if (sc->intrs[i].tq != NULL) {
 			taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task);
 		}
 	}
-    LOCK(&sc->dev_lock);
+	LOCK(&sc->dev_lock);
 
 	/* Delete RX queue in card with flush param */
 	oce_stop_rx(sc);
@@ -1874,7 +1953,7 @@ oce_if_deactivate(POCE_SOFTC sc)
 
 	/* But still we need to get MCC aync events.
 	   So enable intrs and also arm first EQ
-        */
+	*/
 	oce_hw_intr_enable(sc);
 	oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
 
@@ -1947,6 +2026,7 @@ oce_mq_handler(void *arg)
 	struct oce_mq_cqe *cqe;
 	struct oce_async_cqe_link_state *acqe;
 	struct oce_async_event_grp5_pvid_state *gcqe;
+	struct oce_async_event_qnq *dbgcqe;
 
 
 	bus_dmamap_sync(cq->ring->dma.tag,
@@ -1973,6 +2053,14 @@ oce_mq_handler(void *arg)
 					sc->pvid = 0;
 				
 			}
+			else if(evt_type == ASYNC_EVENT_CODE_DEBUG &&
+				optype == ASYNC_EVENT_DEBUG_QNQ) {
+				dbgcqe = 
+				(struct oce_async_event_qnq *)cqe;
+				if(dbgcqe->valid)
+					sc->qnqid = dbgcqe->vlan_tag;
+				sc->qnq_debug_event = TRUE;
+			}
 		}
 		cqe->u0.dw[3] = 0;
 		RING_GET(cq->ring, 1);
@@ -2032,3 +2120,79 @@ update_queues_got(POCE_SOFTC sc)
 	}
 }
 
+static int 
+oce_check_ipv6_ext_hdr(struct mbuf *m)
+{
+	struct ether_header *eh = mtod(m, struct ether_header *);
+	caddr_t m_datatemp = m->m_data;
+
+	if (eh->ether_type == htons(ETHERTYPE_IPV6)) {
+		m->m_data += sizeof(struct ether_header);
+		struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+
+		if((ip6->ip6_nxt != IPPROTO_TCP) && \
+				(ip6->ip6_nxt != IPPROTO_UDP)){
+			struct ip6_ext *ip6e = NULL;
+			m->m_data += sizeof(struct ip6_hdr);
+
+			ip6e = (struct ip6_ext *) mtod(m, struct ip6_ext *);
+			if(ip6e->ip6e_len == 0xff) {
+				m->m_data = m_datatemp;
+				return TRUE;
+			}
+		} 
+		m->m_data = m_datatemp;
+	}
+	return FALSE;
+}
+
+static int 
+is_be3_a1(POCE_SOFTC sc)
+{
+	if((sc->flags & OCE_FLAGS_BE3)  && ((sc->asic_revision & 0xFF) < 2)) {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static struct mbuf *
+oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete)
+{
+	uint16_t vlan_tag = 0;
+
+	if(!M_WRITABLE(m))
+		return NULL;
+
+	/* Embed vlan tag in the packet if it is not part of it */
+	if(m->m_flags & M_VLANTAG) {
+		vlan_tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
+		m->m_flags &= ~M_VLANTAG;
+	}
+
+	/* if UMC, ignore vlan tag insertion and instead insert pvid */
+	if(sc->pvid) {
+		if(!vlan_tag)
+			vlan_tag = sc->pvid;
+		*complete = FALSE;
+	}
+
+	if(vlan_tag) {
+		m = ether_vlanencap(m, vlan_tag);
+	}
+
+	if(sc->qnqid) {
+		m = ether_vlanencap(m, sc->qnqid);
+		*complete = FALSE;
+	}
+	return m;
+}
+
+static int 
+oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m)
+{
+	if(is_be3_a1(sc) && IS_QNQ_OR_UMC(sc) && \
+			oce_check_ipv6_ext_hdr(m)) {
+		return TRUE;
+	}
+	return FALSE;
+}

Modified: head/sys/dev/oce/oce_if.h
==============================================================================
--- head/sys/dev/oce/oce_if.h	Wed Mar  6 09:33:16 2013	(r247879)
+++ head/sys/dev/oce/oce_if.h	Wed Mar  6 09:53:38 2013	(r247880)
@@ -36,6 +36,7 @@
  * Costa Mesa, CA 92626
  */
 
+
 /* $FreeBSD$ */
 
 #include <sys/param.h>
@@ -87,9 +88,7 @@
 
 #include "oce_hw.h"
 
-/* OCE device driver module component revision informaiton */
-#define COMPONENT_REVISION "4.2.127.0"
-
+#define COMPONENT_REVISION "4.6.95.0"
 
 /* OCE devices supported by this driver */
 #define PCI_VENDOR_EMULEX		0x10df	/* Emulex */
@@ -132,7 +131,7 @@ extern int mp_ncpus;			/* system's total
 #define OCE_RQ_BUF_SIZE			2048
 #define OCE_LSO_MAX_SIZE		(64 * 1024)
 #define LONG_TIMEOUT			30
-#define OCE_MAX_JUMBO_FRAME_SIZE	16360
+#define OCE_MAX_JUMBO_FRAME_SIZE	9018
 #define OCE_MAX_MTU			(OCE_MAX_JUMBO_FRAME_SIZE - \
 						ETHER_VLAN_ENCAP_LEN - \
 						ETHER_HDR_LEN)
@@ -481,7 +480,27 @@ struct oce_drv_stats {
 	} u0;
 };
 
+#define INTR_RATE_HWM                   15000
+#define INTR_RATE_LWM                   10000
+
+#define OCE_MAX_EQD 128u
+#define OCE_MIN_EQD 50u
+
+struct oce_set_eqd {
+	uint32_t eq_id;
+	uint32_t phase;
+	uint32_t delay_multiplier;
+};
 
+struct oce_aic_obj {             /* Adaptive interrupt coalescing (AIC) info */
+	boolean_t enable;
+	uint32_t  min_eqd;            /* in usecs */
+	uint32_t  max_eqd;            /* in usecs */
+	uint32_t  cur_eqd;            /* in usecs */
+	uint32_t  et_eqd;             /* configured value when aic is off */
+	uint64_t  ticks;
+	uint64_t  intr_prev;
+};
 
 #define MAX_LOCK_DESC_LEN			32
 struct oce_lock {
@@ -565,6 +584,7 @@ struct oce_eq {
 	int cq_valid; 
 	struct eq_config eq_cfg;
 	int vector;
+	uint64_t intr;
 };
 
 enum cq_len {
@@ -827,6 +847,9 @@ typedef struct oce_softc {
 
 	uint32_t flow_control;
 	uint32_t promisc;
+
+	struct oce_aic_obj aic_obj[OCE_MAX_EQ];
+
 	/*Vlan Filtering related */
 	eventhandler_tag vlan_attach;
 	eventhandler_tag vlan_detach;
@@ -837,7 +860,9 @@ typedef struct oce_softc {
 	struct oce_drv_stats oce_stats_info;
 	struct callout  timer;
 	int8_t be3_native;
-	uint32_t pvid;
+	uint16_t qnq_debug_event;
+	uint16_t qnqid;
+	uint16_t pvid;
 
 } OCE_SOFTC, *POCE_SOFTC;
 
@@ -996,6 +1021,9 @@ int oce_mbox_create_wq(struct oce_wq *wq
 int oce_mbox_create_eq(struct oce_eq *eq);
 int oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce,
 			 uint32_t is_eventable);
+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);
 void mbx_common_req_hdr_init(struct mbx_hdr *hdr,
 			     uint8_t dom,
 			     uint8_t port,
@@ -1076,3 +1104,12 @@ static inline uint32_t oce_highbit(uint3
 	return 0;
 }
 
+#define TRANSCEIVER_DATA_NUM_ELE 64
+#define TRANSCEIVER_DATA_SIZE 256
+#define TRANSCEIVER_A0_SIZE 128
+#define TRANSCEIVER_A2_SIZE 128
+#define PAGE_NUM_A0 0xa0
+#define PAGE_NUM_A2 0xa2
+#define IS_QNQ_OR_UMC(sc) ((sc->pvid && (sc->function_mode & FNM_UMC_MODE ))\
+		     || (sc->qnqid && (sc->function_mode & FNM_FLEX10_MODE)))
+

Modified: head/sys/dev/oce/oce_mbox.c
==============================================================================
--- head/sys/dev/oce/oce_mbox.c	Wed Mar  6 09:33:16 2013	(r247879)
+++ head/sys/dev/oce/oce_mbox.c	Wed Mar  6 09:53:38 2013	(r247880)
@@ -37,10 +37,12 @@
  */
 
 
+
 /* $FreeBSD$ */
 
-#include "oce_if.h"
 
+#include "oce_if.h"
+extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
 
 /**
  * @brief Reset (firmware) common function
@@ -276,12 +278,17 @@ oce_get_fw_version(POCE_SOFTC sc)
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	ret = oce_mbox_post(sc, &mbx, NULL);
-	if (ret)
-		return ret;
+	if (!ret)
+                ret = fwcmd->hdr.u0.rsp.status;
+	if (ret) {
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, ret);
+		goto error;
+	}
 
 	bcopy(fwcmd->params.rsp.fw_ver_str, sc->fw_version, 32);
-	
-	return 0;
+error:
+	return ret;
 }
 
 
@@ -428,15 +435,20 @@ oce_read_mac_addr(POCE_SOFTC sc, uint32_
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	ret = oce_mbox_post(sc, &mbx, NULL);
-	if (ret)
-		return ret;
+	if (!ret)
+                ret = fwcmd->hdr.u0.rsp.status;
+	if (ret) {
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, ret);
+		goto error;
+	}
 
 	/* copy the mac addres in the output parameter */
 	mac->size_of_struct = fwcmd->params.rsp.mac.size_of_struct;
 	bcopy(&fwcmd->params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
 		mac->size_of_struct);
-
-	return 0;
+error:
+	return ret;
 }
 
 /**
@@ -466,8 +478,13 @@ oce_get_fw_config(POCE_SOFTC sc)
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	ret = oce_mbox_post(sc, &mbx, NULL);
-	if (ret)
-		return ret;
+	if (!ret)
+                ret = fwcmd->hdr.u0.rsp.status;
+	if (ret) {
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, ret);
+		goto error;
+	}
 
 	DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config));
 
@@ -485,7 +502,8 @@ oce_get_fw_config(POCE_SOFTC sc)
 		sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot;
 	}
 	
-	return 0;
+error:
+	return ret;
 
 }
 
@@ -540,15 +558,20 @@ oce_if_create(POCE_SOFTC sc,
 	DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
-	if (rc)
-		return rc;
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
+	if (rc) {
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
+		goto error;
+	}
 
 	*if_id = LE_32(fwcmd->params.rsp.if_id);
 
 	if (mac_addr != NULL)
 		sc->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
-
-	return 0;
+error:
+	return rc;
 }
 
 /**
@@ -581,6 +604,11 @@ oce_if_del(POCE_SOFTC sc, uint32_t if_id
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	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);
 	return rc;
 }
 
@@ -628,8 +656,12 @@ oce_config_vlan(POCE_SOFTC sc,
 	DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
-
-	return rc;
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
+	if (rc)
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
+	return 0;
 
 }
 
@@ -667,7 +699,11 @@ oce_set_flow_control(POCE_SOFTC sc, uint
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	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);
 	return rc;
 }
 
@@ -726,20 +762,28 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32
 	struct oce_mbx mbx;
 	struct mbx_config_nic_rss *fwcmd =
 				(struct mbx_config_nic_rss *)&mbx.payload;
+	int version;
 
 	bzero(&mbx, sizeof(struct oce_mbx));
 
+	if (IS_XE201(sc)) {
+		version = OCE_MBX_VER_V1;
+		fwcmd->params.req.enable_rss = RSS_ENABLE_UDP_IPV4 |
+					       RSS_ENABLE_UDP_IPV6;
+	} else
+		version = OCE_MBX_VER_V0; 
+
 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 				MBX_SUBSYSTEM_NIC,
 				NIC_CONFIG_RSS,
 				MBX_TIMEOUT_SEC,
 				sizeof(struct mbx_config_nic_rss),
-				OCE_MBX_VER_V0);
+				version);
 	if (enable_rss)
-		fwcmd->params.req.enable_rss = (RSS_ENABLE_IPV4 |
-						RSS_ENABLE_TCP_IPV4 |
-						RSS_ENABLE_IPV6 |
-						RSS_ENABLE_TCP_IPV6);
+		fwcmd->params.req.enable_rss |= (RSS_ENABLE_IPV4 |
+					         RSS_ENABLE_TCP_IPV4 |
+						 RSS_ENABLE_IPV6 |
+						 RSS_ENABLE_TCP_IPV6);
 	fwcmd->params.req.flush = OCE_FLUSH;
 	fwcmd->params.req.if_id = LE_32(if_id);
 
@@ -753,9 +797,12 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32
 		DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 		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);
 	}
-	

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303060953.r269rcsF063284>