Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Feb 2012 14:19:53 +0000 (UTC)
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r231681 - in stable/8/sys: conf dev/oce modules modules/oce
Message-ID:  <201202141419.q1EEJr0N002288@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luigi
Date: Tue Feb 14 14:19:53 2012
New Revision: 231681
URL: http://svn.freebsd.org/changeset/base/231681

Log:
  MFC: bring in the "oce" driver for Emulex OneConnect 10 Gbit adapters.
  Same code as in HEAD and stable/9

Added:
  stable/8/sys/dev/oce/
  stable/8/sys/dev/oce/oce_hw.c   (contents, props changed)
  stable/8/sys/dev/oce/oce_hw.h   (contents, props changed)
  stable/8/sys/dev/oce/oce_if.c   (contents, props changed)
  stable/8/sys/dev/oce/oce_if.h   (contents, props changed)
  stable/8/sys/dev/oce/oce_mbox.c   (contents, props changed)
  stable/8/sys/dev/oce/oce_queue.c   (contents, props changed)
  stable/8/sys/dev/oce/oce_sysctl.c   (contents, props changed)
  stable/8/sys/dev/oce/oce_util.c   (contents, props changed)
  stable/8/sys/modules/oce/
  stable/8/sys/modules/oce/Makefile   (contents, props changed)
Modified:
  stable/8/sys/conf/NOTES
  stable/8/sys/conf/files
  stable/8/sys/modules/Makefile

Modified: stable/8/sys/conf/NOTES
==============================================================================
--- stable/8/sys/conf/NOTES	Tue Feb 14 14:18:28 2012	(r231680)
+++ stable/8/sys/conf/NOTES	Tue Feb 14 14:19:53 2012	(r231681)
@@ -1924,6 +1924,7 @@ device		xmphy		# XaQti XMAC II
 #	SMC EZ Card 1000 (SMC9462TX), D-Link DGE-500T, Asante FriendlyNet
 #	GigaNIX 1000TA and 1000TPC, the Addtron AEG320T, the Surecom
 #	EP-320G-TX and the Netgear GA622T.
+# oce:	Emulex 10 Gbit adapters (OneConnect Ethernet)
 # pcn:	Support for PCI fast ethernet adapters based on the AMD Am79c97x
 #	PCnet-FAST, PCnet-FAST+, PCnet-FAST III, PCnet-PRO and PCnet-Home
 #	chipsets. These can also be handled by the le(4) driver if the
@@ -2062,6 +2063,7 @@ device		ixgbe		# Intel Pro/10Gbe PCIE Et
 device		le		# AMD Am7900 LANCE and Am79C9xx PCnet
 device		mxge		# Myricom Myri-10G 10GbE NIC
 device		nxge		# Neterion Xframe 10GbE Server/Storage Adapter
+device		oce		# Emulex 10 GbE (OneConnect Ethernet)
 device		ti		# Alteon Networks Tigon I/II gigabit Ethernet
 device		txp		# 3Com 3cR990 (``Typhoon'')
 device		vx		# 3Com 3c590, 3c595 (``Vortex'')

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files	Tue Feb 14 14:18:28 2012	(r231680)
+++ stable/8/sys/conf/files	Tue Feb 14 14:19:53 2012	(r231681)
@@ -1401,6 +1401,12 @@ dev/nmdm/nmdm.c			optional nmdm
 dev/nsp/nsp.c			optional nsp
 dev/nsp/nsp_pccard.c		optional nsp pccard
 dev/null/null.c			standard
+dev/oce/oce_hw.c		optional oce pci
+dev/oce/oce_if.c		optional oce pci
+dev/oce/oce_mbox.c		optional oce pci
+dev/oce/oce_queue.c		optional oce pci
+dev/oce/oce_sysctl.c		optional oce pci
+dev/oce/oce_util.c		optional oce pci
 dev/patm/if_patm.c		optional patm pci
 dev/patm/if_patm_attach.c	optional patm pci
 dev/patm/if_patm_intr.c		optional patm pci

Added: stable/8/sys/dev/oce/oce_hw.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/8/sys/dev/oce/oce_hw.c	Tue Feb 14 14:19:53 2012	(r231681)
@@ -0,0 +1,588 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Contact Information:
+ * freebsd-drivers@emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD$ */
+
+#include "oce_if.h"
+
+static int oce_POST(POCE_SOFTC sc);
+
+/**
+ * @brief		Function to post status
+ * @param sc		software handle to the device
+ */
+static int
+oce_POST(POCE_SOFTC sc)
+{
+	mpu_ep_semaphore_t post_status;
+	int tmo = 60000;
+
+	/* read semaphore CSR */
+	post_status.dw0 = OCE_READ_REG32(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);
+	}
+
+	/* wait for FW ready */
+	for (;;) {
+		if (--tmo == 0)
+			break;
+
+		DELAY(1000);
+
+		post_status.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_SEMAPHORE(sc));
+		if (post_status.bits.error) {
+			device_printf(sc->dev,
+				  "POST failed: %x\n", post_status.dw0);
+			return ENXIO;
+		}
+		if (post_status.bits.stage == POST_STAGE_ARMFW_READY)
+			return 0;
+	}
+
+	device_printf(sc->dev, "POST timed out: %x\n", post_status.dw0);
+
+	return ENXIO;
+}
+
+/**
+ * @brief		Function for hardware initialization
+ * @param sc		software handle to the device
+ */
+int
+oce_hw_init(POCE_SOFTC sc)
+{
+	int rc = 0;
+
+	rc = oce_POST(sc);
+	if (rc)
+		return rc;
+	
+	/* create the bootstrap mailbox */
+	rc = oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->bsmbx, 0);
+	if (rc) {
+		device_printf(sc->dev, "Mailbox alloc failed\n");
+		return rc;
+	}
+
+	rc = oce_reset_fun(sc);
+	if (rc)
+		goto error;
+		
+
+	rc = oce_mbox_init(sc);
+	if (rc)
+		goto error;
+
+
+	rc = oce_get_fw_version(sc);
+	if (rc)
+		goto error;
+
+
+	rc = oce_get_fw_config(sc);
+	if (rc)
+		goto error;
+
+
+	sc->macaddr.size_of_struct = 6;
+	rc = oce_read_mac_addr(sc, 0, 1, MAC_ADDRESS_TYPE_NETWORK,
+					&sc->macaddr);
+	if (rc)
+		goto error;
+	
+	if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) {
+		rc = oce_mbox_check_native_mode(sc);
+		if (rc)
+			goto error;
+	} else
+		sc->be3_native = 0;
+	
+	return rc;
+
+error:
+	oce_dma_free(sc, &sc->bsmbx);
+	device_printf(sc->dev, "Hardware initialisation failed\n");
+	return rc;
+}
+
+
+
+/**
+ * @brief		Releases the obtained pci resources
+ * @param sc		software handle to the device
+ */
+void
+oce_hw_pci_free(POCE_SOFTC sc)
+{
+	int pci_cfg_barnum = 0;
+
+	if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
+		pci_cfg_barnum = OCE_DEV_BE2_CFG_BAR;
+	else
+		pci_cfg_barnum = OCE_DEV_CFG_BAR;
+
+	if (sc->devcfg_res != NULL) {
+		bus_release_resource(sc->dev,
+				     SYS_RES_MEMORY,
+				     PCIR_BAR(pci_cfg_barnum), sc->devcfg_res);
+		sc->devcfg_res = (struct resource *)NULL;
+		sc->devcfg_btag = (bus_space_tag_t) 0;
+		sc->devcfg_bhandle = (bus_space_handle_t)0;
+		sc->devcfg_vhandle = (void *)NULL;
+	}
+
+	if (sc->csr_res != NULL) {
+		bus_release_resource(sc->dev,
+				     SYS_RES_MEMORY,
+				     PCIR_BAR(OCE_PCI_CSR_BAR), sc->csr_res);
+		sc->csr_res = (struct resource *)NULL;
+		sc->csr_btag = (bus_space_tag_t)0;
+		sc->csr_bhandle = (bus_space_handle_t)0;
+		sc->csr_vhandle = (void *)NULL;
+	}
+
+	if (sc->db_res != NULL) {
+		bus_release_resource(sc->dev,
+				     SYS_RES_MEMORY,
+				     PCIR_BAR(OCE_PCI_DB_BAR), sc->db_res);
+		sc->db_res = (struct resource *)NULL;
+		sc->db_btag = (bus_space_tag_t)0;
+		sc->db_bhandle = (bus_space_handle_t)0;
+		sc->db_vhandle = (void *)NULL;
+	}
+}
+
+
+
+
+/**
+ * @brief 		Function to get the PCI capabilities
+ * @param sc		software handle to the device
+ */
+static
+void oce_get_pci_capabilities(POCE_SOFTC sc)
+{
+	uint32_t val;
+
+	if (pci_find_extcap(sc->dev, PCIY_PCIX, &val) == 0) {
+		if (val != 0) 
+			sc->flags |= OCE_FLAGS_PCIX;
+	}
+
+	if (pci_find_extcap(sc->dev, PCIY_EXPRESS, &val) == 0) {
+		if (val != 0) {
+			uint16_t link_status =
+			    pci_read_config(sc->dev, val + 0x12, 2);
+
+			sc->flags |= OCE_FLAGS_PCIE;
+			sc->pcie_link_speed = link_status & 0xf;
+			sc->pcie_link_width = (link_status >> 4) & 0x3f;
+		}
+	}
+
+	if (pci_find_extcap(sc->dev, PCIY_MSI, &val) == 0) {
+		if (val != 0)
+			sc->flags |= OCE_FLAGS_MSI_CAPABLE;
+	}
+
+	if (pci_find_extcap(sc->dev, PCIY_MSIX, &val) == 0) {
+		if (val != 0) {
+			val = pci_msix_count(sc->dev);
+			sc->flags |= OCE_FLAGS_MSIX_CAPABLE;
+		}
+	}
+}
+
+/**
+ * @brief	Allocate PCI resources.
+ *
+ * @param sc		software handle to the device
+ * @returns		0 if successful, or error
+ */
+int
+oce_hw_pci_alloc(POCE_SOFTC sc)
+{
+	int rr, pci_cfg_barnum = 0;
+	pci_sli_intf_t intf;
+
+	pci_enable_busmaster(sc->dev);
+
+	oce_get_pci_capabilities(sc);
+
+	sc->fn = pci_get_function(sc->dev);
+
+	/* setup the device config region */
+	if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
+		pci_cfg_barnum = OCE_DEV_BE2_CFG_BAR;
+	else
+		pci_cfg_barnum = OCE_DEV_CFG_BAR;
+		
+	rr = PCIR_BAR(pci_cfg_barnum);
+
+	if (IS_BE(sc))
+		sc->devcfg_res = bus_alloc_resource_any(sc->dev,
+				SYS_RES_MEMORY, &rr,
+				RF_ACTIVE|RF_SHAREABLE);
+	else
+		sc->devcfg_res = bus_alloc_resource(sc->dev,
+				SYS_RES_MEMORY, &rr,
+				0ul, ~0ul, 32768,
+				RF_ACTIVE|RF_SHAREABLE);
+
+	if (!sc->devcfg_res)
+		goto error;
+
+	sc->devcfg_btag = rman_get_bustag(sc->devcfg_res);
+	sc->devcfg_bhandle = rman_get_bushandle(sc->devcfg_res);
+	sc->devcfg_vhandle = rman_get_virtual(sc->devcfg_res);
+
+	/* Read the SLI_INTF register and determine whether we
+	 * can use this port and its features
+	 */
+	intf.dw0 = pci_read_config((sc)->dev,OCE_INTF_REG_OFFSET,4);
+
+	if (intf.bits.sli_valid != OCE_INTF_VALID_SIG)
+		goto error;
+	
+	if (intf.bits.sli_rev != OCE_INTF_SLI_REV4) {
+		device_printf(sc->dev, "Adapter doesnt support SLI4\n");
+		goto error;
+	}
+
+	if (intf.bits.sli_if_type == OCE_INTF_IF_TYPE_1)
+		sc->flags |= OCE_FLAGS_MBOX_ENDIAN_RQD;
+
+	if (intf.bits.sli_hint1 == OCE_INTF_FUNC_RESET_REQD)
+		sc->flags |= OCE_FLAGS_FUNCRESET_RQD;
+
+	if (intf.bits.sli_func_type == OCE_INTF_VIRT_FUNC)
+		sc->flags |= OCE_FLAGS_VIRTUAL_PORT;
+
+	/* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */
+	if (IS_BE(sc)) {
+		/* set up CSR region */
+		rr = PCIR_BAR(OCE_PCI_CSR_BAR);
+		sc->csr_res = bus_alloc_resource_any(sc->dev,
+				SYS_RES_MEMORY, &rr, RF_ACTIVE|RF_SHAREABLE);
+		if (!sc->csr_res)
+			goto error;
+		sc->csr_btag = rman_get_bustag(sc->csr_res);
+		sc->csr_bhandle = rman_get_bushandle(sc->csr_res);
+		sc->csr_vhandle = rman_get_virtual(sc->csr_res);
+		
+		/* set up DB doorbell region */
+		rr = PCIR_BAR(OCE_PCI_DB_BAR);
+		sc->db_res = bus_alloc_resource_any(sc->dev,
+				SYS_RES_MEMORY, &rr, RF_ACTIVE|RF_SHAREABLE);
+		if (!sc->db_res)
+			goto error;
+		sc->db_btag = rman_get_bustag(sc->db_res);
+		sc->db_bhandle = rman_get_bushandle(sc->db_res);
+		sc->db_vhandle = rman_get_virtual(sc->db_res);
+	}
+
+	return 0;
+
+error:	
+	oce_hw_pci_free(sc);
+	return ENXIO;
+}
+
+
+/**
+ * @brief		Function for device shutdown
+ * @param sc		software handle to the device
+ * @returns		0 on success, error otherwise
+ */
+void
+oce_hw_shutdown(POCE_SOFTC sc)
+{
+
+	oce_stats_free(sc);
+	/* disable hardware interrupts */
+	oce_hw_intr_disable(sc);
+	/* Free LRO resources */
+	oce_free_lro(sc);
+	/* Release queue*/
+	oce_queue_release_all(sc);
+	/*Delete Network Interface*/
+	oce_delete_nw_interface(sc);
+	/* After fw clean we dont send any cmds to fw.*/
+	oce_fw_clean(sc);
+	/* release intr resources */
+	oce_intr_free(sc);
+	/* release PCI resources */
+	oce_hw_pci_free(sc);
+	/* free mbox specific resources */
+	LOCK_DESTROY(&sc->bmbx_lock);
+	LOCK_DESTROY(&sc->dev_lock);
+
+	oce_dma_free(sc, &sc->bsmbx);
+}
+
+
+/**
+ * @brief		Function for creating nw interface.
+ * @param sc		software handle to the device
+ * @returns		0 on success, error otherwise
+ */
+int
+oce_create_nw_interface(POCE_SOFTC sc)
+{
+	int rc;
+	uint32_t capab_flags;
+	uint32_t capab_en_flags;
+
+	/* interface capabilities to give device when creating interface */
+	capab_flags = OCE_CAPAB_FLAGS;
+
+	/* capabilities to enable by default (others set dynamically) */
+	capab_en_flags = OCE_CAPAB_ENABLE;
+
+	if (IS_XE201(sc)) {
+		/* LANCER A0 workaround */
+		capab_en_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR;
+		capab_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR;
+	}
+
+	/* enable capabilities controlled via driver startup parameters */
+	if (sc->rss_enable)
+		capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;
+	else {
+		capab_en_flags &= ~MBX_RX_IFACE_FLAGS_RSS;
+		capab_flags &= ~MBX_RX_IFACE_FLAGS_RSS;
+	}
+
+	rc = oce_if_create(sc,
+			   capab_flags,
+			   capab_en_flags,
+			   0, &sc->macaddr.mac_addr[0], &sc->if_id);
+	if (rc)
+		return rc;
+
+	atomic_inc_32(&sc->nifs);
+
+	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)
+		goto error;
+
+	rc = oce_rxf_set_promiscuous(sc, sc->promisc);
+	if (rc)
+		goto error;
+
+	return rc;
+
+error:
+	oce_delete_nw_interface(sc);
+	return rc;
+
+}
+
+/**
+ * @brief		Function to delete a nw interface.
+ * @param sc		software handle to the device
+ */
+void
+oce_delete_nw_interface(POCE_SOFTC sc)
+{
+	/* currently only single interface is implmeneted */
+	if (sc->nifs > 0) {
+		oce_if_del(sc, sc->if_id);
+		atomic_dec_32(&sc->nifs);
+	}
+}
+
+/**
+ * @brief Soft reset.
+ * @param sc		software handle to the device
+ * @returns		0 on success, error otherwise
+ */
+int
+oce_pci_soft_reset(POCE_SOFTC sc)
+{
+	int rc;
+	mpu_ep_control_t ctrl;
+
+	ctrl.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_CONTROL);
+	ctrl.bits.cpu_reset = 1;
+	OCE_WRITE_REG32(sc, csr, MPU_EP_CONTROL, ctrl.dw0);
+	DELAY(50);
+	rc=oce_POST(sc);
+
+	return rc;
+}
+
+/**
+ * @brief		Function for hardware start
+ * @param sc		software handle to the device
+ * @returns		0 on success, error otherwise
+ */
+int
+oce_hw_start(POCE_SOFTC sc)
+{
+	struct link_status link = { 0 };
+	int rc = 0;
+
+	rc = oce_get_link_status(sc, &link);
+	if (rc) 
+		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);
+	}
+
+	if (link.mac_speed > 0 && link.mac_speed < 5)
+		sc->link_speed = link.mac_speed;
+	else
+		sc->link_speed = 0;
+
+	sc->qos_link_speed = (uint32_t )link.qos_link_speed * 10;
+
+	rc = oce_start_mq(sc->mq);
+	
+	/* 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);
+
+	return rc;
+}
+
+
+/**
+ * @brief 		Function for hardware enable interupts.
+ * @param sc		software handle to the device
+ */
+void
+oce_hw_intr_enable(POCE_SOFTC sc)
+{
+	uint32_t reg;
+
+	reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL);
+	reg |= HOSTINTR_MASK;
+	OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg);
+
+}
+
+
+/**
+ * @brief 		Function for hardware disable interupts
+ * @param sc		software handle to the device
+ */
+void
+oce_hw_intr_disable(POCE_SOFTC sc)
+{
+	uint32_t reg;
+	
+	reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL);
+	reg &= ~HOSTINTR_MASK;
+	OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg);
+}
+
+
+
+/**
+ * @brief               Function for hardware update multicast filter
+ * @param sc            software handle to the device
+ */
+int
+oce_hw_update_multicast(POCE_SOFTC sc)
+{
+	struct ifnet    *ifp = sc->ifp;
+	struct ifmultiaddr *ifma;
+	struct mbx_set_common_iface_multicast *req = NULL;
+	OCE_DMA_MEM dma;
+	int rc = 0;
+
+	/* Allocate DMA mem*/
+	if (oce_dma_alloc(sc, sizeof(struct mbx_set_common_iface_multicast),
+							&dma, 0))
+		return ENOMEM;
+
+	req = OCE_DMAPTR(&dma, struct mbx_set_common_iface_multicast);
+	bzero(req, sizeof(struct mbx_set_common_iface_multicast));
+
+#if __FreeBSD_version > 800000
+	if_maddr_rlock(ifp);
+#endif
+	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+		if (ifma->ifma_addr->sa_family != AF_LINK)
+			continue;
+
+		if (req->params.req.num_mac == OCE_MAX_MC_FILTER_SIZE) {
+			/*More multicast addresses than our hardware table
+			  So Enable multicast promiscus in our hardware to
+			  accept all multicat packets
+			*/
+			req->params.req.promiscuous = 1;
+			break;
+		}
+		bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
+			&req->params.req.mac[req->params.req.num_mac],
+			ETH_ADDR_LEN);
+		req->params.req.num_mac = req->params.req.num_mac + 1;
+	}
+#if __FreeBSD_version > 800000
+	if_maddr_runlock(ifp);
+#endif
+	req->params.req.if_id = sc->if_id;
+	rc = oce_update_multicast(sc, &dma);
+	oce_dma_free(sc, &dma);
+	return rc;
+}
+

Added: stable/8/sys/dev/oce/oce_hw.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/8/sys/dev/oce/oce_hw.h	Tue Feb 14 14:19:53 2012	(r231681)
@@ -0,0 +1,3381 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Contact Information:
+ * freebsd-drivers@emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD$ */
+
+#include <sys/types.h>
+
+#undef _BIG_ENDIAN /* TODO */
+#pragma pack(1)
+
+#define	OC_CNA_GEN2			0x2
+#define	OC_CNA_GEN3			0x3
+#define	DEVID_TIGERSHARK		0x700
+#define	DEVID_TOMCAT			0x710
+
+/* PCI CSR offsets */
+#define	PCICFG_F1_CSR			0x0	/* F1 for NIC */
+#define	PCICFG_SEMAPHORE		0xbc
+#define	PCICFG_SOFT_RESET		0x5c
+#define	PCICFG_UE_STATUS_HI_MASK	0xac
+#define	PCICFG_UE_STATUS_LO_MASK	0xa8
+#define	PCICFG_ONLINE0			0xb0
+#define	PCICFG_ONLINE1			0xb4
+#define	INTR_EN				0x20000000
+#define	IMAGE_TRANSFER_SIZE		(32 * 1024)	/* 32K at a time */
+
+/* CSR register offsets */
+#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	PCICFG_INTR_CTRL		0xfc
+#define	HOSTINTR_MASK			(1 << 29)
+#define	HOSTINTR_PFUNC_SHIFT		26
+#define	HOSTINTR_PFUNC_MASK		7
+
+/* POST status reg struct */
+#define	POST_STAGE_POWER_ON_RESET	0x00
+#define	POST_STAGE_AWAITING_HOST_RDY	0x01
+#define	POST_STAGE_HOST_RDY		0x02
+#define	POST_STAGE_CHIP_RESET		0x03
+#define	POST_STAGE_ARMFW_READY		0xc000
+#define	POST_STAGE_ARMFW_UE		0xf000
+
+/* DOORBELL registers */
+#define	PD_RXULP_DB			0x0100
+#define	PD_TXULP_DB			0x0060
+#define	DB_RQ_ID_MASK			0x3FF
+
+#define	PD_CQ_DB			0x0120
+#define	PD_EQ_DB			PD_CQ_DB
+#define	PD_MPU_MBOX_DB			0x0160
+#define	PD_MQ_DB			0x0140
+
+/* EQE completion types */
+#define	EQ_MINOR_CODE_COMPLETION 	0x00
+#define	EQ_MINOR_CODE_OTHER		0x01
+#define	EQ_MAJOR_CODE_COMPLETION 	0x00
+
+/* Link Status field values */
+#define	PHY_LINK_FAULT_NONE		0x0
+#define	PHY_LINK_FAULT_LOCAL		0x01
+#define	PHY_LINK_FAULT_REMOTE		0x02
+
+#define	PHY_LINK_SPEED_ZERO		0x0	/* No link */
+#define	PHY_LINK_SPEED_10MBPS		0x1	/* (10 Mbps) */
+#define	PHY_LINK_SPEED_100MBPS		0x2	/* (100 Mbps) */
+#define	PHY_LINK_SPEED_1GBPS		0x3	/* (1 Gbps) */
+#define	PHY_LINK_SPEED_10GBPS		0x4	/* (10 Gbps) */
+
+#define	PHY_LINK_DUPLEX_NONE		0x0
+#define	PHY_LINK_DUPLEX_HALF		0x1
+#define	PHY_LINK_DUPLEX_FULL		0x2
+
+#define	NTWK_PORT_A			0x0	/* (Port A) */
+#define	NTWK_PORT_B			0x1	/* (Port B) */
+
+#define	PHY_LINK_SPEED_ZERO			0x0	/* (No link.) */
+#define	PHY_LINK_SPEED_10MBPS		0x1	/* (10 Mbps) */
+#define	PHY_LINK_SPEED_100MBPS		0x2	/* (100 Mbps) */
+#define	PHY_LINK_SPEED_1GBPS		0x3	/* (1 Gbps) */
+#define	PHY_LINK_SPEED_10GBPS		0x4	/* (10 Gbps) */
+
+/* Hardware Address types */
+#define	MAC_ADDRESS_TYPE_STORAGE	0x0	/* (Storage MAC Address) */
+#define	MAC_ADDRESS_TYPE_NETWORK	0x1	/* (Network MAC Address) */
+#define	MAC_ADDRESS_TYPE_PD		0x2	/* (Protection Domain MAC Addr) */
+#define	MAC_ADDRESS_TYPE_MANAGEMENT	0x3	/* (Management MAC Address) */
+#define	MAC_ADDRESS_TYPE_FCOE		0x4	/* (FCoE MAC Address) */
+
+/* CREATE_IFACE capability and cap_en flags */
+#define MBX_RX_IFACE_FLAGS_RSS		0x4
+#define MBX_RX_IFACE_FLAGS_PROMISCUOUS	0x8
+#define MBX_RX_IFACE_FLAGS_BROADCAST	0x10
+#define MBX_RX_IFACE_FLAGS_UNTAGGED	0x20
+#define MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS	0x80
+#define MBX_RX_IFACE_FLAGS_VLAN		0x100
+#define MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS	0x200
+#define MBX_RX_IFACE_FLAGS_PASS_L2_ERR	0x400
+#define MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR	0x800
+#define MBX_RX_IFACE_FLAGS_MULTICAST	0x1000
+#define MBX_RX_IFACE_RX_FILTER_IF_MULTICAST_HASH 0x2000
+#define MBX_RX_IFACE_FLAGS_HDS		0x4000
+#define MBX_RX_IFACE_FLAGS_DIRECTED	0x8000
+#define MBX_RX_IFACE_FLAGS_VMQ		0x10000
+#define MBX_RX_IFACE_FLAGS_NETQ		0x20000
+#define MBX_RX_IFACE_FLAGS_QGROUPS	0x40000
+#define MBX_RX_IFACE_FLAGS_LSO		0x80000
+#define MBX_RX_IFACE_FLAGS_LRO		0x100000
+
+#define	MQ_RING_CONTEXT_SIZE_16		0x5	/* (16 entries) */
+#define	MQ_RING_CONTEXT_SIZE_32		0x6	/* (32 entries) */
+#define	MQ_RING_CONTEXT_SIZE_64		0x7	/* (64 entries) */
+#define	MQ_RING_CONTEXT_SIZE_128	0x8	/* (128 entries) */
+
+#define	MBX_DB_READY_BIT		0x1
+#define	MBX_DB_HI_BIT			0x2
+#define	ASYNC_EVENT_CODE_LINK_STATE	0x1
+#define	ASYNC_EVENT_LINK_UP		0x1
+#define	ASYNC_EVENT_LINK_DOWN		0x0
+
+/* port link_status */
+#define	ASYNC_EVENT_LOGICAL		0x02
+
+/* Logical Link Status */
+#define	NTWK_LOGICAL_LINK_DOWN		0
+#define	NTWK_LOGICAL_LINK_UP		1
+
+/* Rx filter bits */
+#define	NTWK_RX_FILTER_IP_CKSUM 	0x1
+#define	NTWK_RX_FILTER_TCP_CKSUM	0x2
+#define	NTWK_RX_FILTER_UDP_CKSUM	0x4
+#define	NTWK_RX_FILTER_STRIP_CRC	0x8
+
+/* max SGE per mbx */
+#define	MAX_MBX_SGE			19
+
+/* Max multicast filter size*/
+#define OCE_MAX_MC_FILTER_SIZE		64
+
+/* PCI SLI (Service Level Interface) capabilities register */ 
+#define OCE_INTF_REG_OFFSET		0x58
+#define OCE_INTF_VALID_SIG		6	/* register's signature */
+#define OCE_INTF_FUNC_RESET_REQD	1
+#define OCE_INTF_HINT1_NOHINT		0
+#define OCE_INTF_HINT1_SEMAINIT		1
+#define OCE_INTF_HINT1_STATCTRL		2
+#define OCE_INTF_IF_TYPE_0		0
+#define OCE_INTF_IF_TYPE_1		1
+#define OCE_INTF_IF_TYPE_2		2
+#define OCE_INTF_IF_TYPE_3		3
+#define OCE_INTF_SLI_REV3		3	/* not supported by driver */
+#define OCE_INTF_SLI_REV4		4	/* driver supports SLI-4 */
+#define OCE_INTF_PHYS_FUNC		0
+#define OCE_INTF_VIRT_FUNC		1
+#define OCE_INTF_FAMILY_BE2		0	/* not supported by driver */
+#define OCE_INTF_FAMILY_BE3		1	/* driver supports BE3 */
+#define OCE_INTF_FAMILY_A0_CHIP		0xA	/* Lancer A0 chip (supported) */
+#define OCE_INTF_FAMILY_B0_CHIP		0xB	/* Lancer B0 chip (future) */
+
+#define	NIC_WQE_SIZE	16
+#define	NIC_UNICAST	0x00
+#define	NIC_MULTICAST	0x01
+#define	NIC_BROADCAST	0x02
+
+#define	NIC_HDS_NO_SPLIT	0x00
+#define	NIC_HDS_SPLIT_L3PL	0x01
+#define	NIC_HDS_SPLIT_L4PL	0x02
+
+#define	NIC_WQ_TYPE_FORWARDING		0x01
+#define	NIC_WQ_TYPE_STANDARD		0x02
+#define	NIC_WQ_TYPE_LOW_LATENCY		0x04
+
+#define OCE_RESET_STATS		1
+#define OCE_RETAIN_STATS	0
+#define OCE_TXP_SW_SZ		48
+
+typedef union pci_sli_intf_u {
+	uint32_t dw0;
+	struct {
+#ifdef _BIG_ENDIAN
+		uint32_t sli_valid:3;
+		uint32_t sli_hint2:5;
+		uint32_t sli_hint1:8;
+		uint32_t sli_if_type:4;
+		uint32_t sli_family:4;
+		uint32_t sli_rev:4;
+		uint32_t rsv0:3;
+		uint32_t sli_func_type:1;
+#else
+		uint32_t sli_func_type:1;
+		uint32_t rsv0:3;
+		uint32_t sli_rev:4;
+		uint32_t sli_family:4;
+		uint32_t sli_if_type:4;
+		uint32_t sli_hint1:8;
+		uint32_t sli_hint2:5;
+		uint32_t sli_valid:3;
+#endif
+	} bits;
+} pci_sli_intf_t;
+
+
+
+/* physical address structure to be used in MBX */
+struct phys_addr {
+	/* dw0 */
+	uint32_t lo;
+	/* dw1 */
+	uint32_t hi;
+};
+
+
+
+typedef union pcicfg_intr_ctl_u {
+	uint32_t dw0;
+	struct {
+#ifdef _BIG_ENDIAN
+		uint32_t winselect:2;
+		uint32_t hostintr:1;
+		uint32_t pfnum:3;
+		uint32_t vf_cev_int_line_en:1;
+		uint32_t winaddr:23;
+		uint32_t membarwinen:1;
+#else
+		uint32_t membarwinen:1;
+		uint32_t winaddr:23;
+		uint32_t vf_cev_int_line_en:1;
+		uint32_t pfnum:3;
+		uint32_t hostintr:1;
+		uint32_t winselect:2;
+#endif
+	} bits;
+} pcicfg_intr_ctl_t;
+
+
+
+
+typedef union pcicfg_semaphore_u {
+	uint32_t dw0;
+	struct {
+#ifdef _BIG_ENDIAN
+		uint32_t rsvd:31;
+		uint32_t lock:1;
+#else
+		uint32_t lock:1;
+		uint32_t rsvd:31;
+#endif
+	} bits;
+} pcicfg_semaphore_t;
+
+
+
+
+typedef union pcicfg_soft_reset_u {
+	uint32_t dw0;
+	struct {
+#ifdef _BIG_ENDIAN
+		uint32_t nec_ll_rcvdetect:8;
+		uint32_t dbg_all_reqs_62_49:14;
+		uint32_t scratchpad0:1;
+		uint32_t exception_oe:1;
+		uint32_t soft_reset:1;
+		uint32_t rsvd0:7;
+#else
+		uint32_t rsvd0:7;
+		uint32_t soft_reset:1;
+		uint32_t exception_oe:1;
+		uint32_t scratchpad0:1;
+		uint32_t dbg_all_reqs_62_49:14;
+		uint32_t nec_ll_rcvdetect:8;
+#endif
+	} bits;
+} pcicfg_soft_reset_t;
+
+
+
+
+typedef union pcicfg_online1_u {
+	uint32_t dw0;
+	struct {
+#ifdef _BIG_ENDIAN
+		uint32_t host8_online:1;
+		uint32_t host7_online:1;
+		uint32_t host6_online:1;
+		uint32_t host5_online:1;
+		uint32_t host4_online:1;
+		uint32_t host3_online:1;
+		uint32_t host2_online:1;
+		uint32_t ipc_online:1;
+		uint32_t arm_online:1;
+		uint32_t txp_online:1;
+		uint32_t xaui_online:1;
+		uint32_t rxpp_online:1;
+		uint32_t txpb_online:1;
+		uint32_t rr_online:1;
+		uint32_t pmem_online:1;
+		uint32_t pctl1_online:1;
+		uint32_t pctl0_online:1;
+		uint32_t pcs1online_online:1;
+		uint32_t mpu_iram_online:1;
+		uint32_t pcs0online_online:1;
+		uint32_t mgmt_mac_online:1;
+		uint32_t lpcmemhost_online:1;
+#else
+		uint32_t lpcmemhost_online:1;
+		uint32_t mgmt_mac_online:1;
+		uint32_t pcs0online_online:1;
+		uint32_t mpu_iram_online:1;
+		uint32_t pcs1online_online:1;
+		uint32_t pctl0_online:1;
+		uint32_t pctl1_online:1;
+		uint32_t pmem_online:1;
+		uint32_t rr_online:1;
+		uint32_t txpb_online:1;
+		uint32_t rxpp_online:1;
+		uint32_t xaui_online:1;
+		uint32_t txp_online:1;
+		uint32_t arm_online:1;
+		uint32_t ipc_online:1;
+		uint32_t host2_online:1;
+		uint32_t host3_online:1;
+		uint32_t host4_online:1;
+		uint32_t host5_online:1;
+		uint32_t host6_online:1;
+		uint32_t host7_online:1;
+		uint32_t host8_online:1;
+#endif
+	} bits;
+} pcicfg_online1_t;
+
+
+
+typedef union mpu_ep_semaphore_u {
+	uint32_t dw0;
+	struct {
+#ifdef _BIG_ENDIAN

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



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