[Midnightbsd-cvs] src [6558] U trunk/sys/dev/oce: update oce(4) based on freebsd 9.2

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Dec 28 09:28:53 EST 2013


Revision: 6558
          http://svnweb.midnightbsd.org/src/?rev=6558
Author:   laffer1
Date:     2013-12-28 09:28:53 -0500 (Sat, 28 Dec 2013)
Log Message:
-----------
update oce(4) based on freebsd 9.2

Modified Paths:
--------------
    trunk/sys/dev/oce/oce_hw.c
    trunk/sys/dev/oce/oce_hw.h
    trunk/sys/dev/oce/oce_if.c
    trunk/sys/dev/oce/oce_if.h
    trunk/sys/dev/oce/oce_mbox.c
    trunk/sys/dev/oce/oce_queue.c
    trunk/sys/dev/oce/oce_sysctl.c
    trunk/sys/dev/oce/oce_util.c

Property Changed:
----------------
    trunk/sys/dev/oce/oce_hw.c
    trunk/sys/dev/oce/oce_hw.h
    trunk/sys/dev/oce/oce_if.c
    trunk/sys/dev/oce/oce_if.h
    trunk/sys/dev/oce/oce_mbox.c
    trunk/sys/dev/oce/oce_queue.c
    trunk/sys/dev/oce/oce_sysctl.c
    trunk/sys/dev/oce/oce_util.c

Modified: trunk/sys/dev/oce/oce_hw.c
===================================================================
--- trunk/sys/dev/oce/oce_hw.c	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_hw.c	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,7 +37,7 @@
  * Costa Mesa, CA 92626
  */
 
-/* $MidnightBSD$ */
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_hw.c 252905 2013-07-06 23:56:58Z delphij $ */
 
 #include "oce_if.h"
 
@@ -53,12 +54,12 @@
 	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 +69,7 @@
 
 		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 +130,7 @@
 	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 +259,7 @@
 		
 	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 +299,7 @@
 		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,
@@ -340,8 +341,10 @@
 	oce_stats_free(sc);
 	/* disable hardware interrupts */
 	oce_hw_intr_disable(sc);
+#if defined(INET6) || defined(INET)
 	/* Free LRO resources */
 	oce_free_lro(sc);
+#endif
 	/* Release queue*/
 	oce_queue_release_all(sc);
 	/*Delete Network Interface*/
@@ -385,7 +388,7 @@
 	}
 
 	/* 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;
@@ -403,11 +406,6 @@
 
 	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)
@@ -450,9 +448,9 @@
 	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);
 
@@ -475,12 +473,9 @@
 		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);
 	}
@@ -494,12 +489,17 @@
 
 	rc = oce_start_mq(sc->mq);
 	
-	/* we need to get MCC aync events.
-	   So enable intrs and also arm first EQ
+	/* we need to get MCC aync events. So enable intrs and arm
+	   first EQ, Other EQs will be armed after interface is UP 
 	*/
 	oce_hw_intr_enable(sc);
 	oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
 
+	/* Send first mcc cmd and after that we get gracious
+	   MCC notifications from FW
+	*/
+	oce_first_mcc_cmd(sc);
+
 	return rc;
 }
 
@@ -537,8 +537,8 @@
 
 
 /**
- * @brief               Function for hardware update multicast filter
- * @param sc            software handle to the device
+ * @brief		Function for hardware update multicast filter
+ * @param sc		software handle to the device
  */
 int
 oce_hw_update_multicast(POCE_SOFTC sc)


Property changes on: trunk/sys/dev/oce/oce_hw.c
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Modified: trunk/sys/dev/oce/oce_hw.h
===================================================================
--- trunk/sys/dev/oce/oce_hw.h	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_hw.h	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,7 +37,7 @@
  * Costa Mesa, CA 92626
  */
 
-/* $MidnightBSD$ */
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_hw.h 252905 2013-07-06 23:56:58Z delphij $ */
 
 #include <sys/types.h>
 
@@ -63,8 +64,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
@@ -154,6 +154,12 @@
 #define	ASYNC_EVENT_CODE_LINK_STATE	0x1
 #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 */
 #define	ASYNC_EVENT_LOGICAL		0x02
@@ -610,7 +616,10 @@
 			uint32_t hpi_buffer_cmpl:1;
 			uint32_t completed:1;
 			uint32_t consumed:1;
-			uint32_t rsvd0:27;
+			uint32_t rsvd0:3;
+			uint32_t async_type:8;
+			uint32_t event_type:8;
+			uint32_t rsvd1:8;
 #else
 			/* dw0 */
 			uint32_t completion_status:16;
@@ -618,7 +627,10 @@
 			/* dw1 dw2 */
 			uint32_t mq_tag[2];
 			/* dw3 */
-			uint32_t rsvd0:27;
+			uint32_t rsvd1:8;
+			uint32_t event_type:8;
+			uint32_t async_type:8;
+			uint32_t rsvd0:3;
 			uint32_t consumed:1;
 			uint32_t completed:1;
 			uint32_t hpi_buffer_cmpl:1;
@@ -687,6 +699,112 @@
 	} u0;
 };
 
+
+/* PVID aync event */
+struct oce_async_event_grp5_pvid_state {
+	uint8_t enabled;
+	uint8_t rsvd0;
+	uint16_t tag;
+	uint32_t event_tag;
+	uint32_t rsvd1;
+	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 {
+		#ifdef _BIG_ENDIAN
+		/* dw0 */
+		uint32_t dw4rsvd1:16;
+		uint32_t num_pages:16;
+		/* dw1 */
+		uint32_t async_evt_bitmap;
+		/* dw2 */
+		uint32_t cq_id:10;
+		uint32_t dw5rsvd2:2;
+		uint32_t ring_size:4;
+		uint32_t dw5rsvd1:16;
+		/* dw3 */
+		uint32_t valid:1;
+		uint32_t dw6rsvd1:31;
+		/* dw4 */
+		uint32_t dw7rsvd1:21;
+		uint32_t async_cq_id:10;
+		uint32_t async_cq_valid:1;
+	#else
+		/* dw0 */
+		uint32_t num_pages:16;
+		uint32_t dw4rsvd1:16;
+		/* dw1 */
+		uint32_t async_evt_bitmap;
+		/* dw2 */
+		uint32_t dw5rsvd1:16;
+		uint32_t ring_size:4;
+		uint32_t dw5rsvd2:2;
+		uint32_t cq_id:10;
+		/* dw3 */
+		uint32_t dw6rsvd1:31;
+		uint32_t valid:1;
+		/* dw4 */
+		uint32_t async_cq_valid:1;
+		uint32_t async_cq_id:10;
+		uint32_t dw7rsvd1:21;
+	#endif
+		/* 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;
+
+
 /* MQ mailbox structure */
 struct oce_bmbx {
 	struct oce_mbx mbx;
@@ -760,6 +878,7 @@
 	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,
@@ -1342,6 +1461,23 @@
 	} params;
 };
 
+struct mbx_create_common_mq_ex {
+	struct mbx_hdr hdr;
+	union {
+		struct {
+			oce_mq_ext_ctx_t context;
+			struct phys_addr pages[8];
+		} req;
+
+		struct {
+			uint32_t mq_id:16;
+			uint32_t rsvd0:16;
+		} rsp;
+	} params;
+};
+
+
+
 /* [53] OPCODE_COMMON_DESTROY_MQ */
 struct mbx_destroy_common_mq {
 	struct mbx_hdr hdr;
@@ -1584,7 +1720,7 @@
 	FNM_BE3_COMPAT_MODE = 0x10000,	/* BE3 features */
 	FNM_VNIC_MODE = 0x20000,	/* Set when IBM vNIC mode is set */
 	FNM_VNTAG_MODE = 0x40000, 	/* Set when VNTAG mode is set */
-	FNM_UMC_MODE = 0x80000,		/* Set when UMC mode is set */
+	FNM_UMC_MODE = 0x1000000,	/* Set when UMC mode is set */
 	FNM_UMC_DEF_EN = 0x100000,	/* Set when UMC Default is set */
 	FNM_ONE_GB_EN = 0x200000,	/* Set when 1GB Default is set */
 	FNM_VNIC_DEF_VALID = 0x400000,	/* Set when VNIC_DEF_EN is valid */
@@ -1641,6 +1777,12 @@
 	} 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;
@@ -1660,6 +1802,76 @@
 	} 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;
@@ -1702,6 +1914,23 @@
 	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;
@@ -1769,7 +1998,80 @@
 		} 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];
 	uint8_t  ufi_version[4];
@@ -2027,7 +2329,9 @@
 	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


Property changes on: trunk/sys/dev/oce/oce_hw.h
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Modified: trunk/sys/dev/oce/oce_if.c
===================================================================
--- trunk/sys/dev/oce/oce_if.c	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_if.c	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,7 +38,7 @@
  */
 
 
-/* $MidnightBSD$ */
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_if.c 252905 2013-07-06 23:56:58Z delphij $ */
 
 #include "opt_inet6.h"
 #include "opt_inet.h"
@@ -71,10 +72,6 @@
 static void oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq);
 static void oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx,
 					uint32_t status);
-#if defined(INET6) || defined(INET)
-static struct mbuf * oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp,
-					uint16_t *mss);
-#endif
 static int  oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m,
 				 struct oce_wq *wq);
 
@@ -82,9 +79,6 @@
 static void oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe);
 static int  oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
 static int  oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
-#if defined(INET6) || defined(INET)
-static void oce_rx_flush_lro(struct oce_rq *rq);
-#endif
 static void oce_rx(struct oce_rq *rq, uint32_t rqe_idx,
 						struct oce_nic_rx_cqe *cqe);
 
@@ -96,14 +90,23 @@
 static void oce_mac_addr_set(POCE_SOFTC sc);
 static int  oce_handle_passthrough(struct ifnet *ifp, caddr_t data);
 static void oce_local_timer(void *arg);
-#if defined(INET6) || defined(INET)
-static int  oce_init_lro(POCE_SOFTC sc);
-#endif
 static void oce_if_deactivate(POCE_SOFTC sc);
 static void oce_if_activate(POCE_SOFTC sc);
 static void setup_max_queues_want(POCE_SOFTC sc);
 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 */
+#if defined(INET6) || defined(INET)
+static int  oce_init_lro(POCE_SOFTC sc);
+static void oce_rx_flush_lro(struct oce_rq *rq);
+static struct mbuf * oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp);
+#endif
+
 static device_method_t oce_dispatch[] = {
 	DEVMETHOD(device_probe, oce_probe),
 	DEVMETHOD(device_attach, oce_attach),
@@ -145,6 +148,7 @@
 	(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
 };
 
 
@@ -157,10 +161,10 @@
 static int
 oce_probe(device_t dev)
 {
-	uint16_t vendor;
-	uint16_t device;
-	int i;
-	char str[80];
+	uint16_t vendor = 0;
+	uint16_t device = 0;
+	int i = 0;
+	char str[256] = {0};
 	POCE_SOFTC sc;
 
 	sc = device_get_softc(dev);
@@ -170,11 +174,10 @@
 	vendor = pci_get_vendor(dev);
 	device = pci_get_device(dev);
 
-	for (i = 0; i < (sizeof(supportedDevices) / sizeof(uint16_t)); i++) {
+	for (i = 0; i < (sizeof(supportedDevices) / sizeof(uint32_t)); i++) {
 		if (vendor == ((supportedDevices[i] >> 16) & 0xffff)) {
 			if (device == (supportedDevices[i] & 0xffff)) {
-				sprintf(str, "%s:%s",
-					"Emulex CNA NIC function",
+				sprintf(str, "%s:%s", "Emulex CNA NIC function",
 					component_revision);
 				device_set_desc_copy(dev, str);
 
@@ -189,6 +192,9 @@
 				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 +219,6 @@
 	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,37 +233,32 @@
 	if (rc)
 		goto pci_res_free;
 
+	oce_get_config(sc);
 
 	setup_max_queues_want(sc);	
 
-
 	rc = oce_setup_intr(sc);
 	if (rc)
 		goto mbox_free;
 
-
 	rc = oce_queue_init_all(sc);
 	if (rc)
 		goto intr_free;
 
-
 	rc = oce_attach_ifp(sc);
 	if (rc)
 		goto queues_free;
 
-
 #if defined(INET6) || defined(INET)
 	rc = oce_init_lro(sc);
 	if (rc)
-		goto ifp_free;	
+		goto ifp_free;
 #endif
 
-
 	rc = oce_hw_start(sc);
 	if (rc)
-		goto lro_free;;
+		goto lro_free;
 
-
 	sc->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
 				oce_add_vlan, sc, EVENTHANDLER_PRI_FIRST);
 	sc->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
@@ -270,7 +270,6 @@
 
 	oce_add_sysctls(sc);
 
-
 	callout_init(&sc->timer, CALLOUT_MPSAFE);
 	rc = callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc);
 	if (rc)
@@ -315,9 +314,7 @@
 	POCE_SOFTC sc = device_get_softc(dev);
 
 	LOCK(&sc->dev_lock);
-	
 	oce_if_deactivate(sc);
-
 	UNLOCK(&sc->dev_lock);
 
 	callout_drain(&sc->timer);
@@ -359,34 +356,11 @@
 	uint32_t u;
 
 	switch (command) {
-	case SIOCGIFPSRCADDR_IN6:
-		rc = ether_ioctl(ifp, command, data);
-		break;
 
-	case SIOCGIFPSRCADDR:
-		rc = ether_ioctl(ifp, command, data);
-		break;
-
-	case SIOCGIFSTATUS:
-		rc = ether_ioctl(ifp, command, data);
-		break;
-
 	case SIOCGIFMEDIA:
 		rc = ifmedia_ioctl(ifp, ifr, &sc->media, command);
 		break;
 
-	case SIOCSIFMEDIA:
-		rc = ether_ioctl(ifp, command, data);
-		break;
-
-	case SIOCGIFGENERIC:
-		rc = ether_ioctl(ifp, command, data);
-		break;
-
-	case SIOCGETMIFCNT_IN6:
-		rc = ether_ioctl(ifp, command, data);
-		break;
-
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu > OCE_MAX_MTU)
 			rc = EINVAL;
@@ -474,7 +448,6 @@
 			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
 			oce_vid_config(sc);
 		}
-
 #if defined(INET6) || defined(INET)
 		if (u & IFCAP_LRO)
 			ifp->if_capenable ^= IFCAP_LRO;
@@ -518,18 +491,19 @@
 	struct oce_wq *wq = NULL;
 	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;
 
 }
@@ -601,6 +575,7 @@
 
 eq_arm:
 	oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
+
 	return;
 }
 
@@ -611,7 +586,7 @@
 	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;
@@ -666,6 +641,8 @@
 
 	taskqueue_enqueue_fast(ii->tq, &ii->task);
 
+ 	ii->eq->intr++;	
+
 	return FILTER_HANDLED;
 }
 
@@ -808,14 +785,11 @@
 	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;
 	uint32_t reg_value;
-#if defined(INET6) || defined(INET)
-	uint16_t mss = 0;
-#endif
+	boolean_t complete = TRUE;
 
 	m = *mpp;
 	if (!m)
@@ -826,10 +800,19 @@
 		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)
-		/* consolidate packet buffers for TSO/LSO segment offload */
-		m = oce_tso_setup(sc, mpp, &mss);
+		m = oce_tso_setup(sc, mpp);
 #else
 		m = NULL;
 #endif
@@ -839,13 +822,7 @@
 		}
 	}
 
-	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,
@@ -852,7 +829,7 @@
 				     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++;
@@ -861,10 +838,11 @@
 			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);
@@ -873,15 +851,15 @@
 		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) {
@@ -893,12 +871,12 @@
 				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 =
@@ -910,7 +888,7 @@
 			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 =
@@ -922,7 +900,7 @@
 			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++;
 		}
 
@@ -931,15 +909,15 @@
 		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;
-		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) {
-			m_temp = m_defrag(m, M_DONTWAIT);
+			m_temp = m_defrag(m, M_NOWAIT);
 			if (m_temp == NULL)
 				goto free_ret;
 			m = m_temp;
@@ -952,7 +930,7 @@
 		return rc;
 	else
 		goto free_ret;
-
+	
 	return 0;
 
 free_ret:
@@ -965,21 +943,14 @@
 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);
 
@@ -987,6 +958,7 @@
 	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);
@@ -1012,9 +984,10 @@
 
 }
 
+
 #if defined(INET6) || defined(INET)
 static struct mbuf *
-oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp, uint16_t *mss)
+oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp)
 {
 	struct mbuf *m;
 #ifdef INET
@@ -1025,15 +998,13 @@
 #endif
 	struct ether_vlan_header *eh;
 	struct tcphdr *th;
-	int total_len = 0;
 	uint16_t etype;
-	int ehdrlen = 0;
+	int total_len = 0, ehdrlen = 0;
 	
 	m = *mpp;
-	*mss = m->m_pkthdr.tso_segsz;
 
 	if (M_WRITABLE(m) == 0) {
-		m = m_dup(*mpp, M_DONTWAIT);
+		m = m_dup(*mpp, M_NOWAIT);
 		if (!m)
 			return NULL;
 		m_freem(*mpp);
@@ -1049,7 +1020,6 @@
 		ehdrlen = ETHER_HDR_LEN;
 	}
 
-	
 	switch (etype) {
 #ifdef INET
 	case ETHERTYPE_IP:
@@ -1084,7 +1054,6 @@
 }
 #endif /* INET6 || INET */
 
-
 void
 oce_tx_task(void *arg, int npending)
 {
@@ -1092,16 +1061,15 @@
 	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
@@ -1115,22 +1083,26 @@
 	POCE_SOFTC sc = ifp->if_softc;
 	struct mbuf *m;
 	int rc = 0;
+	int def_q = 0; /* Defualt tx queue is 0*/
 
 	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);
 		if (m == NULL)
 			break;
-		/* oce_start always uses default TX queue 0 */
-		LOCK(&sc->wq[0]->tx_lock);
-		rc = oce_tx(sc, &m, 0);
-		UNLOCK(&sc->wq[0]->tx_lock);
+
+		LOCK(&sc->wq[def_q]->tx_lock);
+		rc = oce_tx(sc, &m, def_q);
+		UNLOCK(&sc->wq[def_q]->tx_lock);
 		if (rc) {
 			if (m != NULL) {
-				sc->wq[0]->tx_stats.tx_stops ++;
+				sc->wq[def_q]->tx_stats.tx_stops ++;
 				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 				IFQ_DRV_PREPEND(&ifp->if_snd, m);
 				m = NULL;
@@ -1140,7 +1112,7 @@
 		if (m != NULL)
 			ETHER_BPF_MTAP(ifp, m);
 
-	} while (1);
+	} while (TRUE);
 
 	return;
 }
@@ -1156,7 +1128,6 @@
 	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);
@@ -1180,7 +1151,6 @@
 
 	if (num_cqes)
 		oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
-	UNLOCK(&wq->tx_lock);
 
 	return 0;
 }
@@ -1222,7 +1192,9 @@
 			}  
 			break;
 		}
-		drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
+		ifp->if_obytes += next->m_pkthdr.len;
+		if (next->m_flags & M_MCAST)
+			ifp->if_omcasts++;
 		ETHER_BPF_MTAP(ifp, next);
 		next = drbr_dequeue(ifp, br);
 	}
@@ -1248,7 +1220,6 @@
 	uint16_t vtag;
 
 	len = cqe->u0.s.pkt_size;
-	vtag = cqe->u0.s.vlan_tag;
 	if (!len) {
 		/*partial DMA workaround for Lancer*/
 		oce_discard_rx_comp(rq, cqe);
@@ -1255,6 +1226,13 @@
 		goto exit;
 	}
 
+	 /* Get vlan_tag value */
+	if(IS_BE(sc) || IS_SH(sc))
+		vtag = BSWAP_16(cqe->u0.s.vlan_tag);
+	else
+		vtag = cqe->u0.s.vlan_tag;
+
+
 	for (i = 0; i < cqe->u0.s.num_fragments; i++) {
 
 		if (rq->packets_out == rq->packets_in) {
@@ -1290,7 +1268,7 @@
 					pd->mbuf->m_pkthdr.csum_data = 0xffff;
 				}
 				if (cqe->u0.s.ip_cksum_pass) {
-					if (!cqe->u0.s.ip_ver) { //IPV4 
+					if (!cqe->u0.s.ip_ver) { /* IPV4 */
 						pd->mbuf->m_pkthdr.csum_flags |=
 						(CSUM_IP_CHECKED|CSUM_IP_VALID);
 					}
@@ -1310,27 +1288,26 @@
 
 		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 present
+		/* This deternies if vlan tag is Valid */
 		if (oce_cqe_vtp_valid(sc, cqe)) { 
 			if (sc->function_mode & FNM_FLEX10_MODE) {
-				/* FLEX10 */
+				/* FLEX10. If QnQ is not set, neglect VLAN */
 				if (cqe->u0.s.qnq) {
-					/* If QnQ is not set, neglect VLAN */
-					if (IS_BE(sc))	
-						m->m_pkthdr.ether_vtag = 
-								BSWAP_16(vtag);
-					else
-						m->m_pkthdr.ether_vtag = vtag;
+					m->m_pkthdr.ether_vtag = vtag;
 					m->m_flags |= M_VLANTAG;
 				}
-			} else {
-				if (IS_BE(sc))	
-					m->m_pkthdr.ether_vtag = BSWAP_16(vtag);
-				else
-					m->m_pkthdr.ether_vtag = vtag;
+			} else if (sc->pvid != (vtag & VLAN_VID_MASK))  {
+				/* In UMC mode generally pvid will be striped by
+				   hw. But in some cases we have seen it comes
+				   with pvid. So if pvid == vlan, neglect vlan.
+				*/
+				m->m_pkthdr.ether_vtag = vtag;
 				m->m_flags |= M_VLANTAG;
 			}
 		}
@@ -1339,7 +1316,6 @@
 #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)       &&
@@ -1379,13 +1355,6 @@
 	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,
@@ -1415,9 +1384,8 @@
 	if (sc->be3_native) {
 		cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
 		vtp =  cqe_v1->u0.s.vlan_tag_present; 
-	} else {
+	} else
 		vtp = cqe->u0.s.vlan_tag_present;
-	}
 	
 	return vtp;
 
@@ -1430,7 +1398,7 @@
 	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)
@@ -1442,7 +1410,6 @@
 
 }
 
-
 #if defined(INET6) || defined(INET)
 static void
 oce_rx_flush_lro(struct oce_rq *rq)
@@ -1482,12 +1449,11 @@
 
 	return rc;		
 }
-#endif /* INET6 || INET */
 
+
 void
 oce_free_lro(POCE_SOFTC sc)
 {
-#if defined(INET6) || defined(INET)
 	struct lro_ctrl *lro = NULL;
 	int i = 0;
 
@@ -1496,10 +1462,9 @@
 		if (lro)
 			tcp_lro_free(lro);
 	}
+}
 #endif
-}
 
-
 int
 oce_alloc_rx_bufs(struct oce_rq *rq, int count)
 {
@@ -1511,7 +1476,7 @@
 	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)
@@ -1520,7 +1485,7 @@
 			break;	/* no more room */
 
 		pd = &rq->pckts[rq->packets_in];
-		pd->mbuf = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		pd->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
 		if (pd->mbuf == NULL)
 			break;
 
@@ -1552,7 +1517,6 @@
 	}
 	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);
@@ -1559,7 +1523,6 @@
 			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);
@@ -1581,7 +1544,6 @@
 	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,13 +1556,8 @@
 		} 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;
@@ -1620,6 +1577,7 @@
 		if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
 			break;
 	}
+
 #if defined(INET6) || defined(INET)
 	if (IF_LRO_ENABLED(sc))
 		oce_rx_flush_lro(rq);
@@ -1632,8 +1590,6 @@
 			oce_alloc_rx_bufs(rq, (rq_buffers_used - 1));
 	}
 
-	UNLOCK(&rq->rx_lock);
-	
 	return 0;
 
 }
@@ -1682,9 +1638,11 @@
 	sc->ifp->if_capabilities = OCE_IF_CAPABILITIES;
 	sc->ifp->if_capabilities |= IFCAP_HWCSUM;
 	sc->ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
+
 #if defined(INET6) || defined(INET)
 	sc->ifp->if_capabilities |= IFCAP_TSO;
 	sc->ifp->if_capabilities |= IFCAP_LRO;
+	sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
 #endif
 	
 	sc->ifp->if_capenable = sc->ifp->if_capabilities;
@@ -1794,18 +1752,18 @@
 	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;
@@ -1829,6 +1787,16 @@
 	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;
@@ -1835,7 +1803,71 @@
 
 }
 
+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)
 {
@@ -1850,10 +1882,17 @@
 	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) || IS_SH(sc))
+		oce_eqd_set_periodic(sc);
+
 	callout_reset(&sc->timer, hz, oce_local_timer, sc);
 }
 
 
+/* NOTE : This should only be called holding
+ *        DEVICE_LOCK.
+*/
 static void
 oce_if_deactivate(POCE_SOFTC sc)
 {
@@ -1883,11 +1922,17 @@
 	/* Stop intrs and finish any bottom halves pending */
 	oce_hw_intr_disable(sc);
 
+	/* 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);
 
 	/* Delete RX queue in card with flush param */
 	oce_stop_rx(sc);
@@ -1902,7 +1947,7 @@
 
 	/* 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);
 
@@ -1944,6 +1989,26 @@
 
 }
 
+static void
+process_link_state(POCE_SOFTC sc, struct oce_async_cqe_link_state *acqe)
+{
+	/* Update Link status */
+	if ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) ==
+	     ASYNC_EVENT_LINK_UP) {
+		sc->link_status = ASYNC_EVENT_LINK_UP;
+		if_link_state_change(sc->ifp, LINK_STATE_UP);
+	} else {
+		sc->link_status = ASYNC_EVENT_LINK_DOWN;
+		if_link_state_change(sc->ifp, LINK_STATE_DOWN);
+	}
+
+	/* Update speed */
+	sc->link_speed = acqe->u0.s.speed;
+	sc->qos_link_speed = (uint32_t) acqe->u0.s.qos_link_speed * 10;
+
+}
+
+
 /* Handle the Completion Queue for the Mailbox/Async notifications */
 uint16_t
 oce_mq_handler(void *arg)
@@ -1951,36 +2016,48 @@
 	struct oce_mq *mq = (struct oce_mq *)arg;
 	POCE_SOFTC sc = mq->parent;
 	struct oce_cq *cq = mq->cq;
-	int num_cqes = 0;
+	int num_cqes = 0, evt_type = 0, optype = 0;
 	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,
 			cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
 	cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
+
 	while (cqe->u0.dw[3]) {
 		DW_SWAP((uint32_t *) cqe, sizeof(oce_mq_cqe));
 		if (cqe->u0.s.async_event) {
-			acqe = (struct oce_async_cqe_link_state *)cqe;
-			if ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) ==
-			    ASYNC_EVENT_LINK_UP) {
-				sc->link_status = ASYNC_EVENT_LINK_UP;
-				if_link_state_change(sc->ifp, LINK_STATE_UP);
-			} else {
-				sc->link_status = ASYNC_EVENT_LINK_DOWN;
-				if_link_state_change(sc->ifp, LINK_STATE_DOWN);
+			evt_type = cqe->u0.s.event_type;
+			optype = cqe->u0.s.async_type;
+			if (evt_type  == ASYNC_EVENT_CODE_LINK_STATE) {
+				/* Link status evt */
+				acqe = (struct oce_async_cqe_link_state *)cqe;
+				process_link_state(sc, acqe);
+			} else if ((evt_type == ASYNC_EVENT_GRP5) &&
+				   (optype == ASYNC_EVENT_PVID_STATE)) {
+				/* GRP5 PVID */
+				gcqe = 
+				(struct oce_async_event_grp5_pvid_state *)cqe;
+				if (gcqe->enabled)
+					sc->pvid = gcqe->tag & VLAN_VID_MASK;
+				else
+					sc->pvid = 0;
+				
 			}
-
-			if (acqe->u0.s.event_code ==
-				ASYNC_EVENT_CODE_LINK_STATE) {
-				sc->link_speed = acqe->u0.s.speed;
-				sc->qos_link_speed =
-				(uint32_t )acqe->u0.s.qos_link_speed * 10;
+			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);
-		RING_GET(mq->ring, 1);
 		bus_dmamap_sync(cq->ring->dma.tag,
 				cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
 		cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
@@ -1997,34 +2074,15 @@
 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->rss_enable) ||
-		(sc->flags & OCE_FLAGS_BE2)) {
+	    (sc->function_mode & FNM_UMC_MODE)    ||
+	    (sc->function_mode & FNM_VNIC_MODE)	  ||
+	    (!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);
-	
-		/*Hardware issue. Turn off multi TX for be2 */	
-		if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
-			sc->nwqs = 1;
-
 	}
-
 }
 
 
@@ -2031,11 +2089,9 @@
 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;
-		if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
-			sc->nwqs = 1;
 	} else {
 		sc->nrqs = 1;
 		sc->nwqs = 1;
@@ -2042,3 +2098,107 @@
 	}
 }
 
+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;
+}
+
+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;
+	}
+}


Property changes on: trunk/sys/dev/oce/oce_if.c
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Modified: trunk/sys/dev/oce/oce_if.h
===================================================================
--- trunk/sys/dev/oce/oce_if.h	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_if.h	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,7 +38,7 @@
  */
 
 
-/* $MidnightBSD$ */
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_if.h 252905 2013-07-06 23:56:58Z delphij $ */
 
 #include <sys/param.h>
 #include <sys/endian.h>
@@ -88,7 +89,7 @@
 
 #include "oce_hw.h"
 
-#define COMPONENT_REVISION "4.2.116.0"
+#define COMPONENT_REVISION "4.6.95.0"
 
 /* OCE devices supported by this driver */
 #define PCI_VENDOR_EMULEX		0x10df	/* Emulex */
@@ -97,13 +98,23 @@
 #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 */
 #define OCE_MAX_UNITS			2
 #define OCE_MAX_PPORT			OCE_MAX_UNITS
@@ -111,8 +122,11 @@
 
 extern int mp_ncpus;			/* system's total active cpu cores */
 #define OCE_NCPUS			mp_ncpus
-#define OCE_MAX_RSS			8 /* This should be powers of 2. Like 2,4,8 & 16 */ 
+
+/* This should be powers of 2. Like 2,4,8 & 16 */
+#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
@@ -129,7 +143,7 @@
 #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)
@@ -147,6 +161,7 @@
 #define RSS_ENABLE_IPV6			0x4
 #define RSS_ENABLE_TCP_IPV6		0x8
 
+#define INDIRECTION_TABLE_ENTRIES	128
 
 /* flow control definitions */
 #define OCE_FC_NONE			0x00000000
@@ -171,8 +186,7 @@
 #define OCE_IF_HWASSIST			(CSUM_IP | CSUM_TCP | CSUM_UDP)
 #define OCE_IF_CAPABILITIES		(IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
 					IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
-					IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | \
-					IFCAP_VLAN_MTU)
+					IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU)
 #define OCE_IF_HWASSIST_NONE		0
 #define OCE_IF_CAPABILITIES_NONE 	0
 
@@ -193,6 +207,9 @@
 		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) 	\
@@ -479,8 +496,28 @@
 	} 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 {
 	struct mtx mutex;
@@ -491,7 +528,7 @@
 #define LOCK_CREATE(lock, desc) 		{ \
 	strncpy((lock)->name, (desc), MAX_LOCK_DESC_LEN); \
 	(lock)->name[MAX_LOCK_DESC_LEN] = '\0'; \
-	mtx_init(&(lock)->mutex, (lock)->name, MTX_NETWORK_LOCK, MTX_DEF); \
+	mtx_init(&(lock)->mutex, (lock)->name, NULL, MTX_DEF); \
 }
 #define LOCK_DESTROY(lock) 			\
 		if (mtx_initialized(&(lock)->mutex))\
@@ -563,6 +600,7 @@
 	int cq_valid; 
 	struct eq_config eq_cfg;
 	int vector;
+	uint64_t intr;
 };
 
 enum cq_len {
@@ -649,8 +687,8 @@
 	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;
@@ -663,6 +701,7 @@
 	struct oce_tx_queue_stats tx_stats;
 	struct buf_ring *br;
 	struct task txtask;
+	uint32_t db_offset;
 };
 
 struct rq_config {
@@ -743,6 +782,7 @@
 #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
@@ -811,11 +851,11 @@
 	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 */
@@ -825,6 +865,9 @@
 
 	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;
@@ -835,6 +878,9 @@
 	struct oce_drv_stats oce_stats_info;
 	struct callout  timer;
 	int8_t be3_native;
+	uint16_t qnq_debug_event;
+	uint16_t qnqid;
+	uint16_t pvid;
 
 } OCE_SOFTC, *POCE_SOFTC;
 
@@ -845,37 +891,47 @@
  * BE3: accesses three BAR spaces (CFG, CSR, DB)
  * Lancer: accesses one BAR space (CFG)
  **************************************************/
+#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)))
 #define OCE_READ_REG32(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)))
+	((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)))
 
 
 /***********************************************************
@@ -926,10 +982,12 @@
 /***********************************************************
  * cleanup  functions
  ***********************************************************/
-void oce_free_lro(POCE_SOFTC sc);
 void oce_stop_rx(POCE_SOFTC sc);
 void oce_intr_free(POCE_SOFTC sc);
 void oce_free_posted_rxbuf(struct oce_rq *rq);
+#if defined(INET6) || defined(INET)
+void oce_free_lro(POCE_SOFTC sc);
+#endif
 
 
 /************************************************************
@@ -940,6 +998,8 @@
 int oce_mbox_init(POCE_SOFTC sc);
 int oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec);
 int oce_get_fw_version(POCE_SOFTC sc);
+int oce_first_mcc_cmd(POCE_SOFTC sc);
+
 int oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id, uint8_t perm,
 			uint8_t type, struct mac_address_format *mac);
 int oce_get_fw_config(POCE_SOFTC sc);
@@ -989,6 +1049,11 @@
 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);
+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,
@@ -1037,6 +1102,9 @@
 #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))
@@ -1069,3 +1137,22 @@
 	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
+#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)))
+


Property changes on: trunk/sys/dev/oce/oce_if.h
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Modified: trunk/sys/dev/oce/oce_mbox.c
===================================================================
--- trunk/sys/dev/oce/oce_mbox.c	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_mbox.c	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,12 +39,12 @@
 
 
 
-/* $MidnightBSD$ */
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_mbox.c 252905 2013-07-06 23:56:58Z delphij $ */
 
 
 #include "oce_if.h"
+extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
 
-
 /**
  * @brief Reset (firmware) common function
  * @param sc		software handle to the device
@@ -145,7 +146,6 @@
 }
 
 
-
 /**
  * @brief Mailbox dispatch
  * @param sc		software handle to the device
@@ -279,15 +279,56 @@
 	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);
+error:
+	return ret;
+}
+
+
+/**
+ * @brief	Firmware will send gracious notifications during
+ *		attach only after sending first mcc commnad. We  
+ *		use MCC queue only for getting async and mailbox
+ *		for sending cmds. So to get gracious notifications
+ *		atleast send one dummy command on mcc.
+ */
+int 
+oce_first_mcc_cmd(POCE_SOFTC sc)
+{
+	struct oce_mbx *mbx;
+	struct oce_mq *mq = sc->mq;
+	struct mbx_get_common_fw_version *fwcmd;
+	uint32_t reg_value;
+
+	mbx = RING_GET_PRODUCER_ITEM_VA(mq->ring, struct oce_mbx);
+	bzero(mbx, sizeof(struct oce_mbx));
 	
+	fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
+	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+				MBX_SUBSYSTEM_COMMON,
+				OPCODE_COMMON_GET_FW_VERSION,
+				MBX_TIMEOUT_SEC,
+				sizeof(struct mbx_get_common_fw_version),
+				OCE_MBX_VER_V0);
+	mbx->u0.s.embedded = 1;
+	mbx->payload_length = sizeof(struct mbx_get_common_fw_version);
+	bus_dmamap_sync(mq->ring->dma.tag, mq->ring->dma.map,
+				BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	RING_PUT(mq->ring, 1);
+	reg_value = (1 << 16) | mq->mq_id;
+	OCE_WRITE_REG32(sc, db, PD_MQ_DB, reg_value);
+
 	return 0;
 }
 
-
 /**
  * @brief		Function to post a MBX to the mbox
  * @param sc		software handle to the device
@@ -395,15 +436,20 @@
 	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;
 }
 
 /**
@@ -433,8 +479,13 @@
 	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));
 
@@ -452,7 +503,8 @@
 		sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot;
 	}
 	
-	return 0;
+error:
+	return ret;
 
 }
 
@@ -507,15 +559,20 @@
 	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;
 }
 
 /**
@@ -548,6 +605,11 @@
 	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;
 }
 
@@ -595,9 +657,13 @@
 	DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
 
 	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 0;
 
-	return rc;
-
 }
 
 /**
@@ -634,7 +700,11 @@
 	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;
 }
 
@@ -658,12 +728,14 @@
 {
 	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) {
@@ -693,20 +765,28 @@
 	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) || IS_SH(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);
 
@@ -720,9 +800,12 @@
 		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;
 }
 
@@ -801,7 +884,12 @@
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	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;
 }
 
 /**
@@ -815,10 +903,12 @@
 {
 	struct oce_mbx mbx;
 	struct mbx_query_common_link_config *fwcmd;
-	int rc = 0;
+	int rc = 0, version;
 
 	bzero(&mbx, sizeof(struct oce_mbx));
 
+	IS_XE201(sc) ? (version = OCE_MBX_VER_V1) : (version = OCE_MBX_VER_V0);
+
 	fwcmd = (struct mbx_query_common_link_config *)&mbx.payload;
 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 				MBX_SUBSYSTEM_COMMON,
@@ -825,7 +915,7 @@
 				OPCODE_COMMON_QUERY_LINK_CONFIG,
 				MBX_TIMEOUT_SEC,
 				sizeof(struct mbx_query_common_link_config),
-				OCE_MBX_VER_V0);
+				version);
 
 	mbx.u0.s.embedded = 1;
 	mbx.payload_length = sizeof(struct mbx_query_common_link_config);
@@ -833,15 +923,18 @@
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
 
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
 	if (rc) {
-		device_printf(sc->dev, "Could not get link speed: %d\n", rc);
-	} else {
-		/* interpret response */
-		bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status));
-		link->logical_link_status = LE_32(link->logical_link_status);
-		link->qos_link_speed = LE_16(link->qos_link_speed);
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
+		goto error;
 	}
-
+	/* interpret response */
+	bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status));
+	link->logical_link_status = LE_32(link->logical_link_status);
+	link->qos_link_speed = LE_16(link->qos_link_speed);
+error:
 	return rc;
 }
 
@@ -883,11 +976,11 @@
 
 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
 
-	if (rc) {
-		device_printf(sc->dev, 
-			"Could not get nic statistics: %d\n", rc);
-	}
-	
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
+	if (rc)
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
 	return rc; 
 }
 
@@ -933,10 +1026,11 @@
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
-	if (rc) {
-		device_printf(sc->dev, 
-			"Could not get nic statistics: %d\n", rc);
-	}
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
+	if (rc)
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
 	return rc; 
 }
 
@@ -968,7 +1062,7 @@
 				OCE_MBX_VER_V0);
 
 	fwcmd->params.req.reset_stats = reset_stats;
-	fwcmd->params.req.port_number = sc->if_id;
+	fwcmd->params.req.port_number = sc->port_id;
 	
 	mbx.u0.s.embedded = 0;	/* stats too large for embedded mbx rsp */
 	mbx.u0.s.sge_count = 1; /* using scatter gather instead */
@@ -984,11 +1078,11 @@
 	rc = oce_mbox_post(sc, &mbx, NULL);
 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
 
-	if (rc != 0) {
-		device_printf(sc->dev,
-			  "Could not get physical port statistics: %d\n", rc);
-	}
-
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
+	if (rc)
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
 	return rc;
 }
 
@@ -1037,11 +1131,11 @@
 	rc = oce_mbox_post(sc, &mbx, NULL);
 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
 
-	if (rc != 0) {
-		device_printf(sc->dev,
-			  "Could not get physical port statistics: %d\n", rc);
-	}
-
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
+	if (rc)
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
 	return rc;
 }
 
@@ -1082,7 +1176,11 @@
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
-	
+	if (!rc)
+                rc = req->hdr.u0.rsp.status;
+	if (rc)
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
 	return rc;
 }
 
@@ -1143,11 +1241,15 @@
 	mbx.payload_length = sizeof(struct  mbx_add_common_iface_mac);
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + 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;
+	}
 	*pmac_id = fwcmd->params.rsp.pmac_id;
-
+error:
 	return rc;
 }
 
@@ -1177,6 +1279,11 @@
 	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;
 }
 
@@ -1209,12 +1316,17 @@
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
-	//if (rc != 0)		This can fail in legacy mode. So skip
-	//	FN_LEAVE(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;
+	}
 	sc->be3_native = fwcmd->params.rsp.capability_flags
 			& CAP_BE3_NATIVE_ERX_API;
 
+error:
 	return 0;
 }
 
@@ -1249,6 +1361,11 @@
 	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;
 
@@ -1287,10 +1404,13 @@
 	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)
-		return rc;
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
 	
-	return(fwcmd->params.rsp.status);
+	return rc;
 }
 
 int
@@ -1328,11 +1448,12 @@
 	sgl->length = payload_len;
 
 	/* post the command */
-	if (rc) {
-		device_printf(sc->dev, "Write FlashROM mbox post failed\n");
-	} else {
-		rc = fwcmd->hdr.u0.rsp.status;
-	}
+	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;
 
@@ -1374,12 +1495,15 @@
 
 	/* post the command */
 	rc = oce_mbox_post(sc, &mbx, NULL);
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
 	if (rc) {
-		device_printf(sc->dev, "Read FlashROM CRC mbox post failed\n");
-	} else {
-		bcopy(fwcmd->data_buffer, flash_crc, 4);
-		rc = fwcmd->hdr.u0.rsp.status;
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
+		goto error;
 	}
+	bcopy(fwcmd->data_buffer, flash_crc, 4);
+error:
 	return rc;
 }
 
@@ -1406,20 +1530,22 @@
 
 	/* now post the command */
 	rc = oce_mbox_post(sc, &mbx, NULL);
+	if (!rc)
+                rc = fwcmd->hdr.u0.rsp.status;
 	if (rc) {
-		device_printf(sc->dev, "Read PHY info  mbox post failed\n");
-	} else {
-		rc = fwcmd->hdr.u0.rsp.status;
-		phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
-		phy_info->interface_type =
-				fwcmd->params.rsp.phy_info.interface_type;
-		phy_info->auto_speeds_supported =
-			fwcmd->params.rsp.phy_info.auto_speeds_supported;
-		phy_info->fixed_speeds_supported =
-			fwcmd->params.rsp.phy_info.fixed_speeds_supported;
-		phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params;
-
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
+		goto error;
 	}
+	phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
+	phy_info->interface_type =
+			fwcmd->params.rsp.phy_info.interface_type;
+	phy_info->auto_speeds_supported =
+		fwcmd->params.rsp.phy_info.auto_speeds_supported;
+	phy_info->fixed_speeds_supported =
+		fwcmd->params.rsp.phy_info.fixed_speeds_supported;
+	phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params;
+error:
 	return rc;
 
 }
@@ -1465,14 +1591,16 @@
 
 	/* post the command */
 	rc = oce_mbox_post(sc, &mbx, NULL);
+	if (!rc)
+                rc = fwcmd->params.rsp.status;
 	if (rc) {
-		device_printf(sc->dev,
-			"Write Lancer FlashROM mbox post failed\n");
-	} else {
-		*written_data = fwcmd->params.rsp.actual_write_length;
-		*additional_status = fwcmd->params.rsp.additional_status;
-		rc = fwcmd->params.rsp.status;
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
+		goto error;
 	}
+	*written_data = fwcmd->params.rsp.actual_write_length;
+	*additional_status = fwcmd->params.rsp.additional_status;
+error:
 	return rc;
 
 }
@@ -1519,15 +1647,16 @@
 	mbx.payload_length = sizeof(struct mbx_create_nic_rq);
 	
 	rc = oce_mbox_post(sc, &mbx, NULL);
-	if (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;
- 
+	}
 	rq->rq_id = fwcmd->params.rsp.rq_id;
 	rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
-
-	return 0;
 error:
-	device_printf(sc->dev, "Mbox Create RQ failed\n");
 	return rc;
 
 }
@@ -1548,8 +1677,11 @@
 	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,
@@ -1569,14 +1701,19 @@
 	mbx.payload_length = sizeof(struct mbx_create_nic_wq);
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
-	if (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;
-
+	}
 	wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
-
-	return 0;
+	if (version == OCE_MBX_VER_V2)
+		wq->db_offset = LE_32(fwcmd->params.rsp.db_offset);
+	else
+		wq->db_offset = PD_TXULP_DB;
 error:
-	device_printf(sc->dev, "Mbox Create WQ failed\n");
 	return rc;
 
 }
@@ -1615,14 +1752,15 @@
 	mbx.payload_length = sizeof(struct mbx_create_common_eq);
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
-	if (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;
-
+	}
 	eq->eq_id = LE_16(fwcmd->params.rsp.eq_id);
-
-	return 0;
 error:
-	device_printf(sc->dev, "Mbox Create EQ failed\n");
 	return rc;
 }
 
@@ -1692,14 +1830,309 @@
 	mbx.payload_length = sizeof(struct mbx_create_common_cq);
 
 	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;
+	}
+	cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
+error:
+	return rc;
+
+}
+
+int 
+oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
+{
+	int rc = 0;
+	struct oce_mbx mbx;
+	struct mbx_read_common_transrecv_data *fwcmd;
+	struct oce_mq_sge *sgl;
+	OCE_DMA_MEM dma;
+
+	/* Allocate DMA mem*/
+	if (oce_dma_alloc(sc, sizeof(struct mbx_read_common_transrecv_data),
+				&dma, 0))
+		return ENOMEM;
+
+	fwcmd = OCE_DMAPTR(&dma, struct mbx_read_common_transrecv_data);
+	bzero(fwcmd, sizeof(struct mbx_read_common_transrecv_data));
+
+	bzero(&mbx, sizeof(struct oce_mbx));
+	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+			MBX_SUBSYSTEM_COMMON,
+			OPCODE_COMMON_READ_TRANSRECEIVER_DATA,
+			MBX_TIMEOUT_SEC,
+			sizeof(struct mbx_read_common_transrecv_data),
+			OCE_MBX_VER_V0);
+
+	/* fill rest of mbx */
+	mbx.u0.s.embedded = 0;
+	mbx.payload_length = sizeof(struct mbx_read_common_transrecv_data);
+	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.port = LE_32(sc->port_id);
+	fwcmd->params.req.page_num = LE_32(page_num);
+
+	/* 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;
+	}
+	if(fwcmd->params.rsp.page_num == PAGE_NUM_A0)
+	{
+		bcopy((char *)fwcmd->params.rsp.page_data, 
+				(char *)&sfp_vpd_dump_buffer[0], 
+				TRANSCEIVER_A0_SIZE);
+	}
+
+	if(fwcmd->params.rsp.page_num == PAGE_NUM_A2)
+	{
+		bcopy((char *)fwcmd->params.rsp.page_data, 
+				(char *)&sfp_vpd_dump_buffer[32], 
+				TRANSCEIVER_A2_SIZE);
+	}
+error:
+	oce_dma_free(sc, &dma);
+	return rc;
+}
+
+void
+oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
+				int num)
+{
+	struct oce_mbx mbx;
+	struct mbx_modify_common_eq_delay *fwcmd;
+	int rc = 0;
+	int i = 0;
+
+	bzero(&mbx, sizeof(struct oce_mbx));
+
+	/* Initialize MODIFY_EQ_DELAY ioctl header */
+	fwcmd = (struct mbx_modify_common_eq_delay *)&mbx.payload;
+	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+				MBX_SUBSYSTEM_COMMON,
+				OPCODE_COMMON_MODIFY_EQ_DELAY,
+				MBX_TIMEOUT_SEC,
+				sizeof(struct mbx_modify_common_eq_delay),
+				OCE_MBX_VER_V0);
+	/* fill rest of mbx */
+	mbx.u0.s.embedded = 1;
+	mbx.payload_length = sizeof(struct mbx_modify_common_eq_delay);
+	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+	fwcmd->params.req.num_eq = num;
+	for (i = 0; i < num; i++) {
+		fwcmd->params.req.delay[i].eq_id = 
+					htole32(set_eqd[i].eq_id);
+		fwcmd->params.req.delay[i].phase = 0;
+		fwcmd->params.req.delay[i].dm =
+		htole32(set_eqd[i].delay_multiplier);
+	}
+	
+
+	/* 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);
+}
+
+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;
+	}
 
-	cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
+	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;
 
-	return 0;
+	}
 error:
-	device_printf(sc->dev, "Mbox Create CQ failed\n");
+	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;
+
+}


Property changes on: trunk/sys/dev/oce/oce_mbox.c
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Modified: trunk/sys/dev/oce/oce_queue.c
===================================================================
--- trunk/sys/dev/oce/oce_queue.c	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_queue.c	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +39,7 @@
 
 
 
-/* $MidnightBSD$ */
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_queue.c 252905 2013-07-06 23:56:58Z delphij $ */
 
 
 #include "oce_if.h"
@@ -92,6 +93,7 @@
 	int rc = 0, i, vector;
 	struct oce_wq *wq;
 	struct oce_rq *rq;
+	struct oce_aic_obj *aic;
 
 	/* alloc TX/RX queues */
 	for_all_wq_queues(sc, wq, i) {
@@ -105,7 +107,7 @@
 	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;
 	}
@@ -116,6 +118,13 @@
 
 	/* create all of the event queues */
 	for (vector = 0; vector < sc->intr_count; vector++) {
+		/* setup aic defaults for each event queue */
+		aic = &sc->aic_obj[vector];
+		aic->max_eqd = OCE_MAX_EQD;
+		aic->min_eqd = OCE_MIN_EQD;
+		aic->et_eqd = OCE_MIN_EQD;
+		aic->enable = TRUE;
+
 		sc->eq[vector] = oce_eq_create(sc, EQ_LEN_1024, EQE_SIZE_4,
 						 0, vector);
 		if (!sc->eq[vector])
@@ -653,16 +662,15 @@
 oce_mq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len)
 {
 	struct oce_mbx mbx;
-	struct mbx_create_common_mq *fwcmd = NULL;
+	struct mbx_create_common_mq_ex *fwcmd = NULL;
 	struct oce_mq *mq = NULL;
 	int rc = 0;
 	struct oce_cq *cq;
-	oce_mq_ctx_t *ctx;
+	oce_mq_ext_ctx_t *ctx;
 	uint32_t num_pages;
 	uint32_t page_size;
-	uint32_t version;
+	int version;
 
-
 	cq = oce_cq_create(sc, eq, CQ_LEN_256,
 			sizeof(struct oce_mq_cqe), 1, 1, 0, 0);
 	if (!cq)
@@ -683,13 +691,13 @@
 
 	bzero(&mbx, sizeof(struct oce_mbx));
 
-	fwcmd = (struct mbx_create_common_mq *)&mbx.payload;
-	version = OCE_MBX_VER_V0;
+	IS_XE201(sc) ? (version = OCE_MBX_VER_V1) : (version = OCE_MBX_VER_V0);
+	fwcmd = (struct mbx_create_common_mq_ex *)&mbx.payload;
 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 				MBX_SUBSYSTEM_COMMON,
-				OPCODE_COMMON_CREATE_MQ,
+				OPCODE_COMMON_CREATE_MQ_EXT,
 				MBX_TIMEOUT_SEC,
-				sizeof(struct mbx_create_common_mq),
+				sizeof(struct mbx_create_common_mq_ex),
 				version);
 
 	num_pages = oce_page_list(mq->ring, &fwcmd->params.req.pages[0]);
@@ -696,19 +704,41 @@
 	page_size = mq->ring->num_items * mq->ring->item_size;
 
 	ctx = &fwcmd->params.req.context;
-	ctx->v0.num_pages = num_pages;
-	ctx->v0.cq_id = cq->cq_id;
-	ctx->v0.ring_size = OCE_LOG2(q_len) + 1;
-	ctx->v0.valid = 1;
 
+	if (IS_XE201(sc)) {
+		ctx->v1.num_pages = num_pages;
+		ctx->v1.ring_size = OCE_LOG2(q_len) + 1;
+		ctx->v1.cq_id = cq->cq_id;
+		ctx->v1.valid = 1;
+		ctx->v1.async_cq_id = cq->cq_id;
+		ctx->v1.async_cq_valid = 1;
+		/* Subscribe to Link State and Group 5 Events(bits 1 & 5 set) */
+		ctx->v1.async_evt_bitmap |= LE_32(0x00000022);
+		ctx->v1.async_evt_bitmap |= LE_32(1 << ASYNC_EVENT_CODE_DEBUG);
+		ctx->v1.async_evt_bitmap |=
+					LE_32(1 << ASYNC_EVENT_CODE_SLIPORT);
+	}
+	else {
+		ctx->v0.num_pages = num_pages;
+		ctx->v0.cq_id = cq->cq_id;
+		ctx->v0.ring_size = OCE_LOG2(q_len) + 1;
+		ctx->v0.valid = 1;
+		/* Subscribe to Link State and Group5 Events(bits 1 & 5 set) */
+		ctx->v0.async_evt_bitmap = 0xffffffff;
+	}
+
 	mbx.u0.s.embedded = 1;
-	mbx.payload_length = sizeof(struct mbx_create_common_mq);
+	mbx.payload_length = sizeof(struct mbx_create_common_mq_ex);
 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 
 	rc = oce_mbox_post(sc, &mbx, NULL);
-	if (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;
-
+	}
 	mq->mq_id = LE_16(fwcmd->params.rsp.mq_id);
 	mq->cq = cq;
 	eq->cq[eq->cq_valid] = cq;
@@ -825,10 +855,11 @@
 	DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ);
 
 	rc = oce_mbox_post(sc, mbx, NULL);
-
-	if (rc != 0)
-		device_printf(sc->dev, "Failed to del q\n");
-
+	if (!rc)
+                rc = hdr->u0.rsp.status;
+	if (rc)
+		device_printf(sc->dev,"%s failed - cmd status: %d\n",
+			      __FUNCTION__, rc);
 	return rc;
 }
 
@@ -1195,7 +1226,7 @@
 	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;


Property changes on: trunk/sys/dev/oce/oce_queue.c
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Modified: trunk/sys/dev/oce/oce_sysctl.c
===================================================================
--- trunk/sys/dev/oce/oce_sysctl.c	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_sysctl.c	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,10 +37,9 @@
  * Costa Mesa, CA 92626
  */
 
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_sysctl.c 252905 2013-07-06 23:56:58Z delphij $ */
 
-/* $MidnightBSD$ */
 
-
 #include "oce_if.h"
 
 static void copy_stats_to_sc_xe201(POCE_SOFTC sc);
@@ -51,6 +51,7 @@
 static int  oce_be3_flashdata(POCE_SOFTC sc, const struct firmware
 						*fw, int num_imgs);
 static int  oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
+static int oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS);
 static boolean_t oce_phy_flashing_required(POCE_SOFTC sc);
 static boolean_t oce_img_flashing_required(POCE_SOFTC sc, const char *p,
 				int img_optype, uint32_t img_offset,
@@ -63,8 +64,8 @@
 				struct sysctl_oid *stats_node);
 
 extern char component_revision[32];
+uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
 
-
 void
 oce_add_sysctls(POCE_SOFTC sc)
 {
@@ -95,7 +96,8 @@
 			sizeof(oce_max_rsp_handled),
 			"Maximum receive frames handled per interupt");
 
-	if (sc->function_mode & FNM_FLEX10_MODE)
+	if ((sc->function_mode & FNM_FLEX10_MODE) || 
+	    (sc->function_mode & FNM_UMC_MODE))
 		SYSCTL_ADD_UINT(ctx, child,
 				OID_AUTO, "speed",
 				CTLFLAG_RD,
@@ -108,6 +110,13 @@
 				&sc->speed,
 				0,"Link Speed");
 
+	if (sc->function_mode & FNM_UMC_MODE)
+		SYSCTL_ADD_UINT(ctx, child,
+				OID_AUTO, "pvid",
+				CTLFLAG_RD,
+				&sc->pvid,
+				0,"PVID");
+
 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "loop_back",
 		CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
 		oce_sysctl_loopback, "I", "Loop Back Tests");
@@ -116,10 +125,23 @@
 		CTLTYPE_STRING | CTLFLAG_RW, (void *)sc, 0,
 		oce_sys_fwupgrade, "A", "Firmware ufi file");
 
+        /*
+         *  Dumps Transceiver data
+	 *  "sysctl dev.oce.0.sfp_vpd_dump=0"
+         *  "sysctl -x dev.oce.0.sfp_vpd_dump_buffer" for hex dump
+         *  "sysctl -b dev.oce.0.sfp_vpd_dump_buffer > sfp.bin" for binary dump
+         */
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "sfp_vpd_dump",
+			CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, oce_sysctl_sfp_vpd_dump,
+			"I", "Initiate a sfp_vpd_dump operation");
+	SYSCTL_ADD_OPAQUE(ctx, child, OID_AUTO, "sfp_vpd_dump_buffer",
+			CTLFLAG_RD, sfp_vpd_dump_buffer,
+			TRANSCEIVER_DATA_SIZE, "IU", "Access sfp_vpd_dump buffer");
+
 	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);
@@ -128,7 +150,6 @@
 }
 
 
-
 static uint32_t
 oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type)
 {
@@ -142,7 +163,6 @@
 	return status;
 }
 
-
 static int
 oce_sysctl_loopback(SYSCTL_HANDLER_ARGS)
 {
@@ -204,7 +224,7 @@
 		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");
@@ -1251,7 +1271,7 @@
 {
 	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 
@@ -1279,7 +1299,7 @@
 {
 	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)
@@ -1298,3 +1318,31 @@
 	
 	return rc;
 }
+
+static int 
+oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS)
+{
+	int result = 0, error;
+	int rc = 0;
+	POCE_SOFTC sc = (POCE_SOFTC) arg1;
+
+	/* sysctl default handler */
+	error = sysctl_handle_int(oidp, &result, 0, req);
+	if (error || !req->newptr)
+		return (error);
+
+	if(result == -1) {
+		return EINVAL;
+	}
+	bzero((char *)sfp_vpd_dump_buffer, TRANSCEIVER_DATA_SIZE);
+
+	rc = oce_mbox_read_transrecv_data(sc, PAGE_NUM_A0);
+	if(rc)
+		return rc;
+
+	rc = oce_mbox_read_transrecv_data(sc, PAGE_NUM_A2);
+	if(rc)
+		return rc;
+
+	return rc;
+}


Property changes on: trunk/sys/dev/oce/oce_sysctl.c
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Modified: trunk/sys/dev/oce/oce_util.c
===================================================================
--- trunk/sys/dev/oce/oce_util.c	2013-12-28 14:28:08 UTC (rev 6557)
+++ trunk/sys/dev/oce/oce_util.c	2013-12-28 14:28:53 UTC (rev 6558)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012 Emulex
+ * Copyright (C) 2013 Emulex
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,7 +38,7 @@
  */
 
 
-/* $MidnightBSD$ */
+/* $FreeBSD: release/9.2.0/sys/dev/oce/oce_util.c 252905 2013-07-06 23:56:58Z delphij $ */
 
 
 #include "oce_if.h"
@@ -73,7 +74,8 @@
 	if (rc == 0) {
 		rc = bus_dmamem_alloc(dma->tag,
 				      &dma->ptr,
-				      BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
+				      BUS_DMA_NOWAIT | BUS_DMA_COHERENT |
+					BUS_DMA_ZERO,
 				      &dma->map);
 	}
 


Property changes on: trunk/sys/dev/oce/oce_util.c
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list