svn commit: r366628 - in head/sys: amd64/conf arm64/conf conf dev/axgbe modules modules/axgbe modules/axgbe/if_axa modules/axgbe/if_axp

Emmanuel Vadot manu at FreeBSD.org
Sun Oct 11 16:01:18 UTC 2020


Author: manu
Date: Sun Oct 11 16:01:16 2020
New Revision: 366628
URL: https://svnweb.freebsd.org/changeset/base/366628

Log:
  10Gigabit Ethernet driver for AMD SoC
  
  This patch has the driver for 10Gigabit Ethernet controller in AMD
  SoC. This driver is written compatible to the Iflib framework. The
  existing driver is for the old version of hardware. The submitted
  driver here is for the recent versions of the hardware where the Ethernet
  controller is PCI-E based.
  
  Submitted by:	Rajesh Kumar <rajesh1.kumar at amd.com>
  MFC after:	1 month
  Relnotes:	yes
  Differential Revision:	https://reviews.freebsd.org/D25793

Added:
  head/sys/dev/axgbe/if_axgbe_pci.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe-dcb.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe-i2c.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe-phy-v1.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe-phy-v2.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe-ptp.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe-sysctl.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe-txrx.c   (contents, props changed)
  head/sys/dev/axgbe/xgbe_osdep.c   (contents, props changed)
  head/sys/modules/axgbe/
  head/sys/modules/axgbe/Makefile   (contents, props changed)
  head/sys/modules/axgbe/if_axa/
  head/sys/modules/axgbe/if_axa/Makefile   (contents, props changed)
  head/sys/modules/axgbe/if_axp/
  head/sys/modules/axgbe/if_axp/Makefile   (contents, props changed)
Modified:
  head/sys/amd64/conf/GENERIC
  head/sys/amd64/conf/NOTES
  head/sys/arm64/conf/GENERIC
  head/sys/arm64/conf/NOTES
  head/sys/conf/files.amd64
  head/sys/conf/files.arm64
  head/sys/dev/axgbe/if_axgbe.c
  head/sys/dev/axgbe/xgbe-common.h
  head/sys/dev/axgbe/xgbe-desc.c
  head/sys/dev/axgbe/xgbe-dev.c
  head/sys/dev/axgbe/xgbe-drv.c
  head/sys/dev/axgbe/xgbe-mdio.c
  head/sys/dev/axgbe/xgbe.h
  head/sys/dev/axgbe/xgbe_osdep.h
  head/sys/modules/Makefile

Modified: head/sys/amd64/conf/GENERIC
==============================================================================
--- head/sys/amd64/conf/GENERIC	Sun Oct 11 13:39:04 2020	(r366627)
+++ head/sys/amd64/conf/GENERIC	Sun Oct 11 16:01:16 2020	(r366628)
@@ -248,6 +248,7 @@ device		ixl			# Intel 700 Series Physical Function
 device		iavf			# Intel Adaptive Virtual Function
 device		ice			# Intel 800 Series Physical Function
 device		vmx			# VMware VMXNET3 Ethernet
+device		axp			# AMD EPYC integrated NIC
 
 # PCI Ethernet NICs.
 device		bxe			# Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE

Modified: head/sys/amd64/conf/NOTES
==============================================================================
--- head/sys/amd64/conf/NOTES	Sun Oct 11 13:39:04 2020	(r366627)
+++ head/sys/amd64/conf/NOTES	Sun Oct 11 16:01:16 2020	(r366628)
@@ -328,6 +328,7 @@ device		nfe		# nVidia nForce MCP on-board Ethernet
 device		sfxge		# Solarflare SFC9000 10Gb Ethernet
 device		vmx		# VMware VMXNET3 Ethernet
 device		wpi		# Intel 3945ABG wireless NICs.
+device		axp		# AMD EPYC integrated NIC
 
 # IEEE 802.11 adapter firmware modules
 

Modified: head/sys/arm64/conf/GENERIC
==============================================================================
--- head/sys/arm64/conf/GENERIC	Sun Oct 11 13:39:04 2020	(r366627)
+++ head/sys/arm64/conf/GENERIC	Sun Oct 11 16:01:16 2020	(r366628)
@@ -167,7 +167,7 @@ device		mdio
 device		mii
 device		miibus		# MII bus support
 device		awg		# Allwinner EMAC Gigabit Ethernet
-device		axgbe		# AMD Opteron A1100 integrated NIC
+device		axa		# AMD Opteron A1100 integrated NIC
 device		msk		# Marvell/SysKonnect Yukon II Gigabit Ethernet
 device		neta		# Marvell Armada 370/38x/XP/3700 NIC
 device  	smc		# SMSC LAN91C111

Modified: head/sys/arm64/conf/NOTES
==============================================================================
--- head/sys/arm64/conf/NOTES	Sun Oct 11 13:39:04 2020	(r366627)
+++ head/sys/arm64/conf/NOTES	Sun Oct 11 16:01:16 2020	(r366628)
@@ -76,7 +76,7 @@ options 	PCI_IOV		# PCI SR-IOV support
 # Ethernet NICs
 device		mdio
 device		awg		# Allwinner EMAC Gigabit Ethernet
-device		axgbe		# AMD Opteron A1100 integrated NIC
+device		axa		# AMD Opteron A1100 integrated NIC
 device		neta		# Marvell Armada 370/38x/XP/3700 NIC
 device  	smc		# SMSC LAN91C111
 device		vnic		# Cavium ThunderX NIC

Modified: head/sys/conf/files.amd64
==============================================================================
--- head/sys/conf/files.amd64	Sun Oct 11 13:39:04 2020	(r366627)
+++ head/sys/conf/files.amd64	Sun Oct 11 16:01:16 2020	(r366628)
@@ -142,6 +142,16 @@ dev/agp/agp_amd64.c		optional	agp
 dev/agp/agp_i810.c		optional	agp
 dev/agp/agp_via.c		optional	agp
 dev/amdgpio/amdgpio.c		optional	amdgpio
+dev/axgbe/if_axgbe_pci.c	optional	axp
+dev/axgbe/xgbe-desc.c		optional	axp
+dev/axgbe/xgbe-dev.c		optional	axp
+dev/axgbe/xgbe-drv.c		optional	axp
+dev/axgbe/xgbe-mdio.c		optional	axp
+dev/axgbe/xgbe-sysctl.c		optional	axp
+dev/axgbe/xgbe-txrx.c		optional	axp
+dev/axgbe/xgbe_osdep.c		optional	axp
+dev/axgbe/xgbe-i2c.c		optional	axp
+dev/axgbe/xgbe-phy-v2.c		optional	axp
 dev/hyperv/vmbus/amd64/hyperv_machdep.c			optional	hyperv
 dev/hyperv/vmbus/amd64/vmbus_vector.S			optional	hyperv
 dev/ice/if_ice_iflib.c		optional	ice pci \

Modified: head/sys/conf/files.arm64
==============================================================================
--- head/sys/conf/files.arm64	Sun Oct 11 13:39:04 2020	(r366627)
+++ head/sys/conf/files.arm64	Sun Oct 11 16:01:16 2020	(r366628)
@@ -249,11 +249,15 @@ dev/acpica/acpi_pxm.c		optional	acpi
 dev/ahci/ahci_fsl_fdt.c		optional	SOC_NXP_LS ahci fdt
 dev/ahci/ahci_generic.c		optional	ahci
 dev/altera/dwc/if_dwc_socfpga.c	optional	fdt dwc_socfpga
-dev/axgbe/if_axgbe.c		optional	axgbe
-dev/axgbe/xgbe-desc.c		optional	axgbe
-dev/axgbe/xgbe-dev.c		optional	axgbe
-dev/axgbe/xgbe-drv.c		optional	axgbe
-dev/axgbe/xgbe-mdio.c		optional	axgbe
+dev/axgbe/if_axgbe.c		optional	axa
+dev/axgbe/xgbe-desc.c		optional	axa
+dev/axgbe/xgbe-dev.c		optional	axa
+dev/axgbe/xgbe-drv.c		optional	axa
+dev/axgbe/xgbe-mdio.c		optional	axa
+dev/axgbe/xgbe-sysctl.c		optional	axa
+dev/axgbe/xgbe-txrx.c		optional	axa
+dev/axgbe/xgbe_osdep.c		optional	axa
+dev/axgbe/xgbe-phy-v1.c		optional	axa
 dev/cpufreq/cpufreq_dt.c	optional	cpufreq fdt
 dev/gpio/pl061.c		optional	pl061 gpio
 dev/gpio/pl061_acpi.c		optional	pl061 gpio acpi

Modified: head/sys/dev/axgbe/if_axgbe.c
==============================================================================
--- head/sys/dev/axgbe/if_axgbe.c	Sun Oct 11 13:39:04 2020	(r366627)
+++ head/sys/dev/axgbe/if_axgbe.c	Sun Oct 11 16:01:16 2020	(r366628)
@@ -1,6 +1,8 @@
 /*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
  * Copyright (c) 2016,2017 SoftIron Inc.
- * All rights reserved.
+ * Copyright (c) 2020 Advanced Micro Devices, Inc.
  *
  * This software was developed by Andrew Turner under
  * the sponsorship of SoftIron Inc.
@@ -114,6 +116,14 @@ static struct resource_spec mac_spec[] = {
 	{ -1, 0 }
 };
 
+static struct xgbe_version_data xgbe_v1 = {
+	.init_function_ptrs_phy_impl    = xgbe_init_function_ptrs_phy_v1,
+	.xpcs_access                    = XGBE_XPCS_ACCESS_V1,
+	.tx_max_fifo_size               = 81920,
+	.rx_max_fifo_size               = 81920,
+	.tx_tstamp_workaround           = 1,
+};
+
 MALLOC_DEFINE(M_AXGBE, "axgbe", "axgbe data");
 
 static void
@@ -135,14 +145,13 @@ axgbe_ioctl(struct ifnet *ifp, unsigned long command, 
 {
 	struct axgbe_softc *sc = ifp->if_softc;
 	struct ifreq *ifr = (struct ifreq *)data;
-	int error;
+	int error = 0;
 
 	switch(command) {
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU_JUMBO)
 			error = EINVAL;
-		else
-			error = xgbe_change_mtu(ifp, ifr->ifr_mtu);
+		/* TODO - change it to iflib way */ 
 		break;
 	case SIOCSIFFLAGS:
 		error = 0;
@@ -307,6 +316,7 @@ axgbe_attach(device_t dev)
 
 	sc = device_get_softc(dev);
 
+	sc->prv.vdata = &xgbe_v1;
 	node = ofw_bus_get_node(dev);
 	if (OF_getencprop(node, "phy-handle", &phy_handle,
 	    sizeof(phy_handle)) <= 0) {
@@ -391,6 +401,7 @@ axgbe_attach(device_t dev)
 	sc->prv.phy.advertising = ADVERTISED_10000baseKR_Full |
 	    ADVERTISED_1000baseKX_Full;
 
+
 	/*
 	 * Read the needed properties from the phy node.
 	 */
@@ -466,13 +477,11 @@ axgbe_attach(device_t dev)
 	/* Check if the NIC is DMA coherent */
 	sc->prv.coherent = OF_hasprop(node, "dma-coherent");
 	if (sc->prv.coherent) {
-		sc->prv.axdomain = XGBE_DMA_OS_AXDOMAIN;
-		sc->prv.arcache = XGBE_DMA_OS_ARCACHE;
-		sc->prv.awcache = XGBE_DMA_OS_AWCACHE;
+		sc->prv.arcr = XGBE_DMA_OS_ARCR;
+		sc->prv.awcr = XGBE_DMA_OS_AWCR;
 	} else {
-		sc->prv.axdomain = XGBE_DMA_SYS_AXDOMAIN;
-		sc->prv.arcache = XGBE_DMA_SYS_ARCACHE;
-		sc->prv.awcache = XGBE_DMA_SYS_AWCACHE;
+		sc->prv.arcr = XGBE_DMA_SYS_ARCR;
+		sc->prv.awcr = XGBE_DMA_SYS_AWCR;
 	}
 
 	/* Create the lock & workqueues */
@@ -486,6 +495,7 @@ axgbe_attach(device_t dev)
 	xgbe_init_function_ptrs_phy(&sc->prv.phy_if);
 	xgbe_init_function_ptrs_dev(&sc->prv.hw_if);
 	xgbe_init_function_ptrs_desc(&sc->prv.desc_if);
+	sc->prv.vdata->init_function_ptrs_phy_impl(&sc->prv.phy_if);
 
 	/* Reset the hardware */
 	sc->prv.hw_if.exit(&sc->prv);
@@ -494,16 +504,14 @@ axgbe_attach(device_t dev)
 	xgbe_get_all_hw_features(&sc->prv);
 
 	/* Set default values */
-	sc->prv.pblx8 = DMA_PBL_X8_ENABLE;
 	sc->prv.tx_desc_count = XGBE_TX_DESC_CNT;
 	sc->prv.tx_sf_mode = MTL_TSF_ENABLE;
 	sc->prv.tx_threshold = MTL_TX_THRESHOLD_64;
-	sc->prv.tx_pbl = DMA_PBL_16;
 	sc->prv.tx_osp_mode = DMA_OSP_ENABLE;
 	sc->prv.rx_desc_count = XGBE_RX_DESC_CNT;
 	sc->prv.rx_sf_mode = MTL_RSF_DISABLE;
 	sc->prv.rx_threshold = MTL_RX_THRESHOLD_64;
-	sc->prv.rx_pbl = DMA_PBL_16;
+	sc->prv.pbl = DMA_PBL_128;
 	sc->prv.pause_autoneg = 1;
 	sc->prv.tx_pause = 1;
 	sc->prv.rx_pause = 1;
@@ -528,7 +536,7 @@ axgbe_attach(device_t dev)
         ifp->if_softc = sc;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = axgbe_ioctl;
-	ifp->if_transmit = xgbe_xmit;
+	/* TODO - change it to iflib way */ 
 	ifp->if_qflush = axgbe_qflush;
 	ifp->if_get_counter = axgbe_get_counter;
 
@@ -550,11 +558,7 @@ axgbe_attach(device_t dev)
 
 	set_bit(XGBE_DOWN, &sc->prv.dev_state);
 
-	if (xgbe_open(ifp) < 0) {
-		device_printf(dev, "ndo_open failed\n");
-		return (ENXIO);
-	}
-
+	/* TODO - change it to iflib way */
 	return (0);
 }
 
@@ -562,6 +566,7 @@ static device_method_t axgbe_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		axgbe_probe),
 	DEVMETHOD(device_attach,	axgbe_attach),
+
 	{ 0, 0 }
 };
 
@@ -569,8 +574,9 @@ static devclass_t axgbe_devclass;
 
 DEFINE_CLASS_0(axgbe, axgbe_driver, axgbe_methods,
     sizeof(struct axgbe_softc));
-DRIVER_MODULE(axgbe, simplebus, axgbe_driver, axgbe_devclass, 0, 0);
+DRIVER_MODULE(axa, simplebus, axgbe_driver, axgbe_devclass, 0, 0);
 
+
 static struct ofw_compat_data phy_compat_data[] = {
 	{ "amd,xgbe-phy-seattle-v1a",	true },
 	{ NULL,				false }
@@ -605,6 +611,7 @@ static device_method_t axgbephy_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		axgbephy_probe),
 	DEVMETHOD(device_attach,	axgbephy_attach),
+
 	{ 0, 0 }
 };
 

Added: head/sys/dev/axgbe/if_axgbe_pci.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/axgbe/if_axgbe_pci.c	Sun Oct 11 16:01:16 2020	(r366628)
@@ -0,0 +1,2339 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 :
+ * Rajesh Kumar <rajesh1.kumar at amd.com>
+ * Shreyank Amartya <Shreyank.Amartya at amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+#include "miibus_if.h"
+#include "ifdi_if.h"
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+MALLOC_DEFINE(M_AXGBE, "axgbe", "axgbe data");
+
+extern struct if_txrx axgbe_txrx;
+
+/* Function prototypes */
+static void *axgbe_register(device_t);
+static int axgbe_if_attach_pre(if_ctx_t);
+static int axgbe_if_attach_post(if_ctx_t);
+static int axgbe_if_detach(if_ctx_t);
+static void axgbe_if_stop(if_ctx_t);
+static void axgbe_if_init(if_ctx_t);
+
+/* Queue related routines */
+static int axgbe_if_tx_queues_alloc(if_ctx_t, caddr_t *, uint64_t *, int, int);
+static int axgbe_if_rx_queues_alloc(if_ctx_t, caddr_t *, uint64_t *, int, int);
+static int axgbe_alloc_channels(if_ctx_t);
+static void axgbe_if_queues_free(if_ctx_t);
+static int axgbe_if_tx_queue_intr_enable(if_ctx_t, uint16_t);
+static int axgbe_if_rx_queue_intr_enable(if_ctx_t, uint16_t);
+
+/* Interrupt related routines */
+static void axgbe_if_disable_intr(if_ctx_t);
+static void axgbe_if_enable_intr(if_ctx_t);
+static int axgbe_if_msix_intr_assign(if_ctx_t, int);
+static void xgbe_free_intr(struct xgbe_prv_data *, struct resource *, void *, int);
+
+/* Init and Iflib routines */
+static void axgbe_pci_init(struct xgbe_prv_data *);
+static void axgbe_pci_stop(if_ctx_t);
+static void xgbe_disable_rx_tx_int(struct xgbe_prv_data *, struct xgbe_channel *);
+static void xgbe_disable_rx_tx_ints(struct xgbe_prv_data *);
+static int axgbe_if_mtu_set(if_ctx_t, uint32_t);
+static void axgbe_if_update_admin_status(if_ctx_t);
+static void axgbe_if_media_status(if_ctx_t, struct ifmediareq *);
+static int axgbe_if_media_change(if_ctx_t);
+static int axgbe_if_promisc_set(if_ctx_t, int);
+static uint64_t axgbe_if_get_counter(if_ctx_t, ift_counter);
+static void axgbe_if_vlan_register(if_ctx_t, uint16_t);
+static void axgbe_if_vlan_unregister(if_ctx_t, uint16_t);
+#if __FreeBSD_version >= 1300000
+static bool axgbe_if_needs_restart(if_ctx_t, enum iflib_restart_event);
+#endif
+static void axgbe_set_counts(if_ctx_t);
+static void axgbe_init_iflib_softc_ctx(struct axgbe_if_softc *);
+
+/* MII interface registered functions */
+static int axgbe_miibus_readreg(device_t, int, int);
+static int axgbe_miibus_writereg(device_t, int, int, int);
+static void axgbe_miibus_statchg(device_t);
+
+/* ISR routines */
+static int axgbe_dev_isr(void *);
+static void axgbe_ecc_isr(void *);
+static void axgbe_i2c_isr(void *);
+static void axgbe_an_isr(void *);
+static int axgbe_msix_que(void *);
+
+/* Timer routines */
+static void xgbe_service(void *, int);
+static void xgbe_service_timer(void *);
+static void xgbe_init_timers(struct xgbe_prv_data *);
+static void xgbe_stop_timers(struct xgbe_prv_data *);
+
+/* Dump routines */
+static void xgbe_dump_prop_registers(struct xgbe_prv_data *);
+
+/*
+ * Allocate only for MAC (BAR0) and PCS (BAR1) registers, and just point the
+ * MSI-X table bar  (BAR5) to iflib. iflib will do the allocation for MSI-X
+ * table.
+ */
+static struct resource_spec axgbe_pci_mac_spec[] = {
+	{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE }, /* MAC regs */
+	{ SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE }, /* PCS regs */
+	{ -1, 0 }
+};
+
+static pci_vendor_info_t axgbe_vendor_info_array[] =
+{
+	PVID(0x1022, 0x1458,  "AMD 10 Gigabit Ethernet Driver"),
+	PVID(0x1022, 0x1459,  "AMD 10 Gigabit Ethernet Driver"),
+	PVID_END
+};
+
+static struct xgbe_version_data xgbe_v2a = {
+	.init_function_ptrs_phy_impl    = xgbe_init_function_ptrs_phy_v2,
+	.xpcs_access                    = XGBE_XPCS_ACCESS_V2,
+	.mmc_64bit                      = 1,
+	.tx_max_fifo_size               = 229376,
+	.rx_max_fifo_size               = 229376,
+	.tx_tstamp_workaround           = 1,
+	.ecc_support                    = 1,
+	.i2c_support                    = 1,
+	.irq_reissue_support            = 1,
+	.tx_desc_prefetch               = 5,
+	.rx_desc_prefetch               = 5,
+	.an_cdr_workaround              = 1,
+};
+
+static struct xgbe_version_data xgbe_v2b = {
+	.init_function_ptrs_phy_impl    = xgbe_init_function_ptrs_phy_v2,
+	.xpcs_access                    = XGBE_XPCS_ACCESS_V2,
+	.mmc_64bit                      = 1,
+	.tx_max_fifo_size               = 65536,
+	.rx_max_fifo_size               = 65536,
+	.tx_tstamp_workaround           = 1,
+	.ecc_support                    = 1,
+	.i2c_support                    = 1,
+	.irq_reissue_support            = 1,
+	.tx_desc_prefetch               = 5,
+	.rx_desc_prefetch               = 5,
+	.an_cdr_workaround              = 1,
+};
+
+/* Device Interface */
+static device_method_t ax_methods[] = {
+	DEVMETHOD(device_register, axgbe_register),
+	DEVMETHOD(device_probe, iflib_device_probe),
+	DEVMETHOD(device_attach, iflib_device_attach),
+	DEVMETHOD(device_detach, iflib_device_detach),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg, axgbe_miibus_readreg),
+	DEVMETHOD(miibus_writereg, axgbe_miibus_writereg),
+	DEVMETHOD(miibus_statchg, axgbe_miibus_statchg),
+
+	DEVMETHOD_END
+};
+
+static driver_t ax_driver = {
+	"ax", ax_methods, sizeof(struct axgbe_if_softc),
+};
+
+devclass_t ax_devclass;
+DRIVER_MODULE(axp, pci, ax_driver, ax_devclass, 0, 0);
+DRIVER_MODULE(miibus, ax, miibus_driver, miibus_devclass, 0, 0);
+IFLIB_PNP_INFO(pci, ax_driver, axgbe_vendor_info_array);
+
+MODULE_DEPEND(ax, pci, 1, 1, 1);
+MODULE_DEPEND(ax, ether, 1, 1, 1);
+MODULE_DEPEND(ax, iflib, 1, 1, 1);
+MODULE_DEPEND(ax, miibus, 1, 1, 1);
+
+/* Iflib Interface */
+static device_method_t axgbe_if_methods[] = {
+	DEVMETHOD(ifdi_attach_pre, axgbe_if_attach_pre),
+	DEVMETHOD(ifdi_attach_post, axgbe_if_attach_post),
+	DEVMETHOD(ifdi_detach, axgbe_if_detach),
+	DEVMETHOD(ifdi_init, axgbe_if_init),
+	DEVMETHOD(ifdi_stop, axgbe_if_stop),
+	DEVMETHOD(ifdi_msix_intr_assign, axgbe_if_msix_intr_assign),
+	DEVMETHOD(ifdi_intr_enable, axgbe_if_enable_intr),
+	DEVMETHOD(ifdi_intr_disable, axgbe_if_disable_intr),
+	DEVMETHOD(ifdi_tx_queue_intr_enable, axgbe_if_tx_queue_intr_enable),
+	DEVMETHOD(ifdi_rx_queue_intr_enable, axgbe_if_rx_queue_intr_enable),
+	DEVMETHOD(ifdi_tx_queues_alloc, axgbe_if_tx_queues_alloc),
+	DEVMETHOD(ifdi_rx_queues_alloc, axgbe_if_rx_queues_alloc),
+	DEVMETHOD(ifdi_queues_free, axgbe_if_queues_free),
+	DEVMETHOD(ifdi_update_admin_status, axgbe_if_update_admin_status),
+	DEVMETHOD(ifdi_mtu_set, axgbe_if_mtu_set),
+	DEVMETHOD(ifdi_media_status, axgbe_if_media_status),
+	DEVMETHOD(ifdi_media_change, axgbe_if_media_change),
+	DEVMETHOD(ifdi_promisc_set, axgbe_if_promisc_set),
+	DEVMETHOD(ifdi_get_counter, axgbe_if_get_counter),
+	DEVMETHOD(ifdi_vlan_register, axgbe_if_vlan_register),
+	DEVMETHOD(ifdi_vlan_unregister, axgbe_if_vlan_unregister),
+#if __FreeBSD_version >= 1300000
+	DEVMETHOD(ifdi_needs_restart, axgbe_if_needs_restart),
+#endif
+	DEVMETHOD_END
+};
+
+static driver_t axgbe_if_driver = {
+	"axgbe_if", axgbe_if_methods, sizeof(struct axgbe_if_softc)
+};
+
+/* Iflib Shared Context */
+static struct if_shared_ctx axgbe_sctx_init = {
+	.isc_magic = IFLIB_MAGIC,
+	.isc_driver = &axgbe_if_driver,
+	.isc_q_align = PAGE_SIZE,
+	.isc_tx_maxsize = XGBE_TSO_MAX_SIZE + sizeof(struct ether_vlan_header),
+	.isc_tx_maxsegsize = PAGE_SIZE,
+	.isc_tso_maxsize = XGBE_TSO_MAX_SIZE + sizeof(struct ether_vlan_header),
+	.isc_tso_maxsegsize = PAGE_SIZE,
+	.isc_rx_maxsize = MJUM9BYTES,
+	.isc_rx_maxsegsize = MJUM9BYTES,
+	.isc_rx_nsegments = 1,
+	.isc_admin_intrcnt = 4,
+
+	.isc_vendor_info = axgbe_vendor_info_array,
+	.isc_driver_version = XGBE_DRV_VERSION,
+
+	.isc_nrxd_min = {XGBE_RX_DESC_CNT_MIN, XGBE_RX_DESC_CNT_MIN},
+	.isc_nrxd_default = {XGBE_RX_DESC_CNT_DEFAULT, XGBE_RX_DESC_CNT_DEFAULT},
+	.isc_nrxd_max = {XGBE_RX_DESC_CNT_MAX, XGBE_RX_DESC_CNT_MAX},
+	.isc_ntxd_min = {XGBE_TX_DESC_CNT_MIN},
+	.isc_ntxd_default = {XGBE_TX_DESC_CNT_DEFAULT}, 
+	.isc_ntxd_max = {XGBE_TX_DESC_CNT_MAX},
+
+	.isc_nfl = 2,
+	.isc_ntxqs = 1,
+	.isc_nrxqs = 2,
+	.isc_flags = IFLIB_TSO_INIT_IP | IFLIB_NEED_SCRATCH |
+	    IFLIB_NEED_ZERO_CSUM | IFLIB_NEED_ETHER_PAD,
+};
+
+static void *
+axgbe_register(device_t dev)
+{
+	return (&axgbe_sctx_init);
+}
+
+/* MII Interface Functions */
+static int
+axgbe_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct axgbe_if_softc   *sc = iflib_get_softc(device_get_softc(dev));
+	struct xgbe_prv_data    *pdata = &sc->pdata;
+	int val;
+
+	axgbe_printf(3, "%s: phy %d reg %d\n", __func__, phy, reg);
+
+	val = xgbe_phy_mii_read(pdata, phy, reg);
+
+	axgbe_printf(2, "%s: val 0x%x\n", __func__, val);
+	return (val & 0xFFFF);
+}
+
+static int
+axgbe_miibus_writereg(device_t dev, int phy, int reg, int val)
+{
+	struct axgbe_if_softc   *sc = iflib_get_softc(device_get_softc(dev));
+	struct xgbe_prv_data    *pdata = &sc->pdata;
+
+	axgbe_printf(3, "%s: phy %d reg %d val 0x%x\n", __func__, phy, reg, val);
+
+	xgbe_phy_mii_write(pdata, phy, reg, val);
+
+	return(0);
+}
+
+static void
+axgbe_miibus_statchg(device_t dev)
+{
+        struct axgbe_if_softc   *sc = iflib_get_softc(device_get_softc(dev));
+        struct xgbe_prv_data    *pdata = &sc->pdata;
+	struct mii_data		*mii = device_get_softc(pdata->axgbe_miibus);
+	struct ifnet		*ifp = pdata->netdev;
+	int bmsr;
+
+	axgbe_printf(2, "%s: Link %d/%d\n", __func__, pdata->phy.link,
+	    pdata->phy_link);
+
+	if (mii == NULL || ifp == NULL ||
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+
+	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+	    (IFM_ACTIVE | IFM_AVALID)) {
+
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_10_T:
+		case IFM_100_TX:
+			pdata->phy.link = 1;
+			break;
+		case IFM_1000_T:
+		case IFM_1000_SX:
+		case IFM_2500_SX:
+			pdata->phy.link = 1;
+			break;
+		default:
+			pdata->phy.link = 0;
+			break;
+		}
+	} else
+		pdata->phy_link = 0;
+
+	bmsr = axgbe_miibus_readreg(pdata->dev, pdata->mdio_addr, MII_BMSR);
+	if (bmsr & BMSR_ANEG) {
+
+		axgbe_printf(2, "%s: Autoneg Done\n", __func__);
+
+		/* Raise AN Interrupt */
+		XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK,
+		    XGBE_AN_CL73_INT_MASK);
+	}
+}
+
+static int
+axgbe_if_attach_pre(if_ctx_t ctx)
+{
+	struct axgbe_if_softc	*sc;
+	struct xgbe_prv_data	*pdata;
+	struct resource		*mac_res[2];
+	if_softc_ctx_t		scctx;
+	if_shared_ctx_t		sctx;
+	device_t		dev;
+	unsigned int		ma_lo, ma_hi;
+	unsigned int		reg;
+
+	sc = iflib_get_softc(ctx);
+	sc->pdata.dev = dev = iflib_get_dev(ctx);
+	sc->sctx = sctx = iflib_get_sctx(ctx);
+	sc->scctx = scctx = iflib_get_softc_ctx(ctx);
+	sc->media = iflib_get_media(ctx);
+	sc->ctx = ctx;
+	sc->link_status = LINK_STATE_DOWN;
+	pdata = &sc->pdata;
+	pdata->netdev = iflib_get_ifp(ctx);
+
+	spin_lock_init(&pdata->xpcs_lock);
+
+	/* Initialize locks */
+        mtx_init(&pdata->rss_mutex, "xgbe rss mutex lock", NULL, MTX_DEF);
+	mtx_init(&pdata->mdio_mutex, "xgbe MDIO mutex lock", NULL, MTX_SPIN);
+
+	/* Allocate VLAN bitmap */
+	pdata->active_vlans = bit_alloc(VLAN_NVID, M_AXGBE, M_WAITOK|M_ZERO);
+	pdata->num_active_vlans = 0;
+
+	/* Get the version data */
+	DBGPR("%s: Device ID: 0x%x\n", __func__, pci_get_device(dev));
+	if (pci_get_device(dev) == 0x1458)
+		sc->pdata.vdata = &xgbe_v2a;
+	else if (pci_get_device(dev) == 0x1459)
+		sc->pdata.vdata = &xgbe_v2b;
+
+	/* PCI setup */
+        if (bus_alloc_resources(dev, axgbe_pci_mac_spec, mac_res))
+                return (ENXIO);
+
+        sc->pdata.xgmac_res = mac_res[0];
+        sc->pdata.xpcs_res = mac_res[1];
+
+        /* Set the PCS indirect addressing definition registers*/
+	pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
+	pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
+
+        /* Configure the PCS indirect addressing support */
+	reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
+	pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
+	pdata->xpcs_window <<= 6;
+	pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
+	pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7);
+	pdata->xpcs_window_mask = pdata->xpcs_window_size - 1;
+	DBGPR("xpcs window def : %#010x\n",
+	    pdata->xpcs_window_def_reg);
+	DBGPR("xpcs window sel : %#010x\n",
+	    pdata->xpcs_window_sel_reg);
+        DBGPR("xpcs window : %#010x\n",
+	    pdata->xpcs_window);
+	DBGPR("xpcs window size : %#010x\n",
+	    pdata->xpcs_window_size);
+	DBGPR("xpcs window mask : %#010x\n",
+	    pdata->xpcs_window_mask);
+
+	/* Enable all interrupts in the hardware */
+        XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
+	
+	/* Retrieve the MAC address */
+	ma_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO);
+	ma_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI);
+	pdata->mac_addr[0] = ma_lo & 0xff;
+	pdata->mac_addr[1] = (ma_lo >> 8) & 0xff;
+	pdata->mac_addr[2] = (ma_lo >>16) & 0xff;
+	pdata->mac_addr[3] = (ma_lo >> 24) & 0xff;
+	pdata->mac_addr[4] = ma_hi & 0xff;
+	pdata->mac_addr[5] = (ma_hi >> 8) & 0xff;
+	if (!XP_GET_BITS(ma_hi, XP_MAC_ADDR_HI, VALID)) {
+		axgbe_error("Invalid mac address\n");
+		return (EINVAL);
+	}
+	iflib_set_mac(ctx, pdata->mac_addr);
+
+	/* Clock settings */
+	pdata->sysclk_rate = XGBE_V2_DMA_CLOCK_FREQ;
+	pdata->ptpclk_rate = XGBE_V2_PTP_CLOCK_FREQ;
+
+	/* Set the DMA coherency values */
+	pdata->coherent = 1;
+	pdata->arcr = XGBE_DMA_PCI_ARCR;
+	pdata->awcr = XGBE_DMA_PCI_AWCR;
+	pdata->awarcr = XGBE_DMA_PCI_AWARCR;
+
+	/* Read the port property registers */
+	pdata->pp0 = XP_IOREAD(pdata, XP_PROP_0);
+	pdata->pp1 = XP_IOREAD(pdata, XP_PROP_1);
+	pdata->pp2 = XP_IOREAD(pdata, XP_PROP_2);
+	pdata->pp3 = XP_IOREAD(pdata, XP_PROP_3);
+	pdata->pp4 = XP_IOREAD(pdata, XP_PROP_4);
+	DBGPR("port property 0 = %#010x\n", pdata->pp0);
+	DBGPR("port property 1 = %#010x\n", pdata->pp1);
+	DBGPR("port property 2 = %#010x\n", pdata->pp2);
+	DBGPR("port property 3 = %#010x\n", pdata->pp3);
+	DBGPR("port property 4 = %#010x\n", pdata->pp4);
+
+	/* Set the maximum channels and queues */
+	pdata->tx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
+	    MAX_TX_DMA);
+	pdata->rx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
+	    MAX_RX_DMA);
+	pdata->tx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
+	    MAX_TX_QUEUES);
+	pdata->rx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
+	    MAX_RX_QUEUES);
+	DBGPR("max tx/rx channel count = %u/%u\n",
+	    pdata->tx_max_channel_count, pdata->rx_max_channel_count);
+	DBGPR("max tx/rx hw queue count = %u/%u\n",
+	    pdata->tx_max_q_count, pdata->rx_max_q_count);
+
+	axgbe_set_counts(ctx);
+
+	/* Set the maximum fifo amounts */
+        pdata->tx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2,
+                                              TX_FIFO_SIZE);
+        pdata->tx_max_fifo_size *= 16384;
+        pdata->tx_max_fifo_size = min(pdata->tx_max_fifo_size,
+                                      pdata->vdata->tx_max_fifo_size);
+        pdata->rx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2,
+                                              RX_FIFO_SIZE);
+        pdata->rx_max_fifo_size *= 16384;
+        pdata->rx_max_fifo_size = min(pdata->rx_max_fifo_size,
+                                      pdata->vdata->rx_max_fifo_size);
+	DBGPR("max tx/rx max fifo size = %u/%u\n",
+	    pdata->tx_max_fifo_size, pdata->rx_max_fifo_size);
+
+	/* Initialize IFLIB if_softc_ctx_t */
+	axgbe_init_iflib_softc_ctx(sc);
+
+	/* Alloc channels */
+	if (axgbe_alloc_channels(ctx)) {
+		axgbe_error("Unable to allocate channel memory\n");
+                return (ENOMEM);
+        }
+
+	TASK_INIT(&pdata->service_work, 0, xgbe_service, pdata);
+
+	/* create the workqueue */
+	pdata->dev_workqueue = taskqueue_create("axgbe", M_WAITOK,
+	    taskqueue_thread_enqueue, &pdata->dev_workqueue);
+	taskqueue_start_threads(&pdata->dev_workqueue, 1, PI_NET,
+	    "axgbe dev taskq");
+
+	/* Init timers */
+	xgbe_init_timers(pdata);
+
+        return (0);
+} /* axgbe_if_attach_pre */
+
+static void
+xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
+{
+	xgbe_init_function_ptrs_dev(&pdata->hw_if);
+	xgbe_init_function_ptrs_phy(&pdata->phy_if);
+        xgbe_init_function_ptrs_i2c(&pdata->i2c_if);
+	xgbe_init_function_ptrs_desc(&pdata->desc_if);
+
+        pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if);
+}
+
+static void
+axgbe_set_counts(if_ctx_t ctx)
+{
+	struct axgbe_if_softc *sc = iflib_get_softc(ctx);;
+	struct xgbe_prv_data *pdata = &sc->pdata;
+	cpuset_t lcpus;
+	int cpu_count, err;
+	size_t len;
+
+	/* Set all function pointers */
+	xgbe_init_all_fptrs(pdata);
+
+	/* Populate the hardware features */
+	xgbe_get_all_hw_features(pdata);
+
+	if (!pdata->tx_max_channel_count)
+		pdata->tx_max_channel_count = pdata->hw_feat.tx_ch_cnt;
+	if (!pdata->rx_max_channel_count)
+		pdata->rx_max_channel_count = pdata->hw_feat.rx_ch_cnt;
+
+	if (!pdata->tx_max_q_count)
+		pdata->tx_max_q_count = pdata->hw_feat.tx_q_cnt;
+	if (!pdata->rx_max_q_count)
+		pdata->rx_max_q_count = pdata->hw_feat.rx_q_cnt;
+
+	/*
+	 * Calculate the number of Tx and Rx rings to be created
+	 *  -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
+	 *   the number of Tx queues to the number of Tx channels
+	 *   enabled
+	 *  -Rx (DMA) Channels do not map 1-to-1 so use the actual
+	 *   number of Rx queues or maximum allowed
+	 */
+
+	/* Get cpu count from sysctl */
+	len = sizeof(cpu_count);
+	err = kernel_sysctlbyname(curthread, "hw.ncpu", &cpu_count, &len, NULL,
+	    0, NULL, 0);
+	if (err) {
+		axgbe_error("Unable to fetch number of cpus\n");
+		cpu_count = 1;
+	}
+
+	if (bus_get_cpus(pdata->dev, INTR_CPUS, sizeof(lcpus), &lcpus) != 0) {
+                axgbe_error("Unable to fetch CPU list\n");
+                /* TODO - handle CPU_COPY(&all_cpus, &lcpus); */
+        }
+
+	DBGPR("ncpu %d intrcpu %d\n", cpu_count, CPU_COUNT(&lcpus));
+
+	pdata->tx_ring_count = min(CPU_COUNT(&lcpus), pdata->hw_feat.tx_ch_cnt);
+	pdata->tx_ring_count = min(pdata->tx_ring_count,
+	    pdata->tx_max_channel_count);
+	pdata->tx_ring_count = min(pdata->tx_ring_count, pdata->tx_max_q_count);
+
+	pdata->tx_q_count = pdata->tx_ring_count;
+
+	pdata->rx_ring_count = min(CPU_COUNT(&lcpus), pdata->hw_feat.rx_ch_cnt);
+	pdata->rx_ring_count = min(pdata->rx_ring_count,
+	    pdata->rx_max_channel_count);
+
+	pdata->rx_q_count = min(pdata->hw_feat.rx_q_cnt, pdata->rx_max_q_count);
+
+	DBGPR("TX/RX max channel count = %u/%u\n",
+	    pdata->tx_max_channel_count, pdata->rx_max_channel_count);
+	DBGPR("TX/RX max queue count = %u/%u\n",
+	    pdata->tx_max_q_count, pdata->rx_max_q_count);
+	DBGPR("TX/RX DMA ring count = %u/%u\n",
+	    pdata->tx_ring_count, pdata->rx_ring_count);
+	DBGPR("TX/RX hardware queue count = %u/%u\n",
+	    pdata->tx_q_count, pdata->rx_q_count);
+} /* axgbe_set_counts */
+
+static void
+axgbe_init_iflib_softc_ctx(struct axgbe_if_softc *sc)
+{
+	struct xgbe_prv_data *pdata = &sc->pdata;
+	if_softc_ctx_t scctx = sc->scctx;
+	if_shared_ctx_t sctx = sc->sctx;
+	int i;
+
+	scctx->isc_nrxqsets = pdata->rx_q_count;
+	scctx->isc_ntxqsets = pdata->tx_q_count;
+	scctx->isc_msix_bar = pci_msix_table_bar(pdata->dev);
+	scctx->isc_tx_nsegments = 32;
+
+	for (i = 0; i < sctx->isc_ntxqs; i++) {
+		scctx->isc_txqsizes[i] = 
+		    roundup2(scctx->isc_ntxd[i] * sizeof(struct xgbe_ring_desc),
+		    128);
+		scctx->isc_txd_size[i] = sizeof(struct xgbe_ring_desc);
+	}
+
+	for (i = 0; i < sctx->isc_nrxqs; i++) {
+		scctx->isc_rxqsizes[i] =
+		    roundup2(scctx->isc_nrxd[i] * sizeof(struct xgbe_ring_desc),
+		    128);
+		scctx->isc_rxd_size[i] = sizeof(struct xgbe_ring_desc);
+	}
+
+	scctx->isc_tx_tso_segments_max = 32;
+	scctx->isc_tx_tso_size_max = XGBE_TSO_MAX_SIZE;
+	scctx->isc_tx_tso_segsize_max = PAGE_SIZE;
+
+	/*
+	 * Set capabilities
+	 * 1) IFLIB automatically adds IFCAP_HWSTATS, so need to set explicitly
+	 * 2) isc_tx_csum_flags is mandatory if IFCAP_TXCSUM (included in
+	 *    IFCAP_HWCSUM) is set
+	 */
+	scctx->isc_tx_csum_flags = (CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_SCTP |
+	    CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | CSUM_SCTP_IPV6 |
+	    CSUM_TSO);
+	scctx->isc_capenable = (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 |
+	    IFCAP_JUMBO_MTU |
+	    IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWFILTER | 
+	    IFCAP_VLAN_HWCSUM |
+	    IFCAP_TSO | IFCAP_VLAN_HWTSO);
+	scctx->isc_capabilities = scctx->isc_capenable;
+
+	/*
+	 * Set rss_table_size alone when adding RSS support. rss_table_mask
+	 * will be set by IFLIB based on rss_table_size
+	 */
+	scctx->isc_rss_table_size = XGBE_RSS_MAX_TABLE_SIZE;
+
+	scctx->isc_ntxqsets_max = XGBE_MAX_QUEUES;
+	scctx->isc_nrxqsets_max = XGBE_MAX_QUEUES;
+
+	scctx->isc_txrx = &axgbe_txrx;
+}
+
+static int
+axgbe_alloc_channels(if_ctx_t ctx)
+{
+	struct axgbe_if_softc 	*sc = iflib_get_softc(ctx);
+	struct xgbe_prv_data	*pdata = &sc->pdata;
+	struct xgbe_channel	*channel;
+	int i, j, count;
+
+	DBGPR("%s: txqs %d rxqs %d\n", __func__, pdata->tx_ring_count,
+	    pdata->rx_ring_count);
+
+	/* Iflibe sets based on isc_ntxqsets/nrxqsets */
+	count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
+
+	/* Allocate channel memory */
+	for (i = 0; i < count ; i++) {
+		channel = (struct xgbe_channel*)malloc(sizeof(struct xgbe_channel),
+		    M_AXGBE, M_NOWAIT | M_ZERO);
+
+		if (channel == NULL) {	
+			for (j = 0; j < i; j++) {
+				free(pdata->channel[j], M_AXGBE);
+				pdata->channel[j] = NULL;
+			}
+			return (ENOMEM);
+		}
+
+		pdata->channel[i] = channel;
+	}
+
+	pdata->total_channel_count = count;
+	DBGPR("Channel count set to: %u\n", pdata->total_channel_count);
+
+	for (i = 0; i < count; i++) {
+
+		channel = pdata->channel[i];
+		snprintf(channel->name, sizeof(channel->name), "channel-%d",i);
+
+		channel->pdata = pdata;
+		channel->queue_index = i;
+		channel->dma_tag = rman_get_bustag(pdata->xgmac_res);
+		bus_space_subregion(channel->dma_tag,
+		    rman_get_bushandle(pdata->xgmac_res),
+		    DMA_CH_BASE + (DMA_CH_INC * i), DMA_CH_INC,
+		    &channel->dma_handle);
+		channel->tx_ring = NULL;
+		channel->rx_ring = NULL;
+	}
+
+	return (0);
+} /* axgbe_alloc_channels */
+
+static void
+xgbe_service(void *ctx, int pending)
+{
+        struct xgbe_prv_data *pdata = ctx;
+	struct axgbe_if_softc *sc = (struct axgbe_if_softc *)pdata;
+	bool prev_state = false;
+
+	/* Get previous link status */
+	prev_state = pdata->phy.link;
+
+        pdata->phy_if.phy_status(pdata);
+
+	if (prev_state != pdata->phy.link) {
+		pdata->phy_link = pdata->phy.link;
+		axgbe_if_update_admin_status(sc->ctx);
+	}
+
+        callout_reset(&pdata->service_timer, 1*hz, xgbe_service_timer, pdata);
+}
+
+static void
+xgbe_service_timer(void *data)
+{
+        struct xgbe_prv_data *pdata = data;
+
+        taskqueue_enqueue(pdata->dev_workqueue, &pdata->service_work);
+}
+
+static void
+xgbe_init_timers(struct xgbe_prv_data *pdata)
+{
+        callout_init(&pdata->service_timer, 1*hz);
+}
+
+static void
+xgbe_start_timers(struct xgbe_prv_data *pdata)
+{
+	callout_reset(&pdata->service_timer, 1*hz, xgbe_service_timer, pdata);
+}
+
+static void
+xgbe_stop_timers(struct xgbe_prv_data *pdata)
+{
+        callout_drain(&pdata->service_timer);
+        callout_stop(&pdata->service_timer);
+}
+
+static void
+xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)
+{
+        axgbe_printf(1, "\n************* PHY Reg dump *********************\n");
+
+        axgbe_printf(1, "PCS Control Reg (%#06x) = %#06x\n", MDIO_CTRL1,
+            XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1));

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


More information about the svn-src-all mailing list