Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'stable/10' of https://github.com/freebsd/freebsd into s…

…table/10

Conflicts:
	sys/conf/newvers.sh
	usr.sbin/freebsd-update/freebsd-update.sh
  • Loading branch information...
commit 5b0f391c694629ac74a08a3833c97e6ee107e689 2 parents f13d1cf + 60686be
@kmoore134 kmoore134 authored
View
8 Makefile.inc1
@@ -58,6 +58,7 @@
# use that new version. And the new (dynamically-linked) /bin/sh
# will expect to find appropriate libraries in /lib and /libexec.
#
+SRCDIR?= ${.CURDIR}
.if defined(SUBDIR_OVERRIDE)
SUBDIR= ${SUBDIR_OVERRIDE}
.else
@@ -128,8 +129,11 @@ OSRELDATE= 0
.endif
.if !defined(VERSION)
-VERSION!= uname -srp
-VERSION+= ${OSRELDATE}
+REVISION!= make -C ${SRCDIR}/release -V REVISION
+BRANCH!= make -C ${SRCDIR}/release -V BRANCH
+SRCRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \
+ ${SRCDIR}/sys/sys/param.h
+VERSION= FreeBSD ${REVISION}-${BRANCH} ${TARGET_ARCH} ${SRCRELDATE}
.endif
KNOWN_ARCHES?= amd64 arm armeb/arm armv6/arm i386 i386/pc98 ia64 mips mipsel/mips mips64el/mips mips64/mips mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc sparc64
View
4 contrib/subversion/subversion/libsvn_subr/opt.c
@@ -1115,10 +1115,8 @@ svn_opt__print_version_info(const char *pgm_name,
return svn_cmdline_printf(pool, "%s\n", SVN_VER_NUMBER);
SVN_ERR(svn_cmdline_printf(pool, _("%s, version %s\n"
- " compiled %s, %s on %s\n\n"),
+ " compiled on %s\n\n"),
pgm_name, SVN_VERSION,
- svn_version_ext_build_date(info),
- svn_version_ext_build_time(info),
svn_version_ext_build_host(info)));
SVN_ERR(svn_cmdline_printf(pool, "%s\n", svn_version_ext_copyright(info)));
View
4 contrib/subversion/subversion/libsvn_subr/version.c
@@ -125,8 +125,8 @@ svn_version_extended(svn_boolean_t verbose,
{
svn_version_extended_t *info = apr_pcalloc(pool, sizeof(*info));
- info->build_date = __DATE__;
- info->build_time = __TIME__;
+ info->build_date = NULL;
+ info->build_time = NULL;
info->build_host = SVN_BUILD_HOST;
info->copyright = apr_pstrdup
(pool, _("Copyright (C) 2013 The Apache Software Foundation.\n"
View
11 lib/libc/gen/getutxent.c
@@ -122,9 +122,20 @@ getfutxent(struct futx *fu)
if (udb == UTXDB_LOG) {
uint16_t len;
+retry:
if (fread(&len, sizeof(len), 1, uf) != 1)
return (-1);
len = be16toh(len);
+ if (len == 0) {
+ /*
+ * XXX: Though zero-size records are valid in theory,
+ * they can never occur in practice. Zero-size records
+ * indicate file corruption. Seek one byte forward, to
+ * see if we can find a record there.
+ */
+ ungetc('\0', uf);
+ goto retry;
+ }
if (len > sizeof *fu) {
/* Forward compatibility. */
if (fread(fu, sizeof(*fu), 1, uf) != 1)
View
4 sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
-.Dd January 10, 2013
+.Dd October 21, 2013
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -2690,7 +2690,7 @@ as a synonym for the canonical form of the option
.Pp
Configure a single CARP redundant address on igb0, and then switch it
to be master:
-.Dl # ifconfig igb0 vhid 1 10.0.0.1/24 pass foobar
+.Dl # ifconfig igb0 vhid 1 10.0.0.1/24 pass foobar up
.Dl # ifconfig igb0 vhid 1 state master
.Pp
Configure the interface
View
1  sys/conf/files.powerpc
@@ -228,6 +228,7 @@ powerpc/ps3/ps3-hvcall.S optional ps3 sc
powerpc/pseries/phyp-hvcall.S optional pseries powerpc64
powerpc/pseries/mmu_phyp.c optional pseries powerpc64
powerpc/pseries/phyp_console.c optional pseries powerpc64 uart
+powerpc/pseries/phyp_llan.c optional llan
powerpc/pseries/phyp_vscsi.c optional pseries powerpc64 scbus
powerpc/pseries/platform_chrp.c optional pseries
powerpc/pseries/plpar_iommu.c optional pseries powerpc64
View
2  sys/dev/drm2/i915/i915_drv.c
@@ -685,7 +685,7 @@ gen6_do_reset(struct drm_device *dev, u8 flags)
/* Spin waiting for the device to ack the reset request */
ret = _intel_wait_for(dev,
- (I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0,
+ (I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0,
500, 1, "915rst");
/* If reset with a user forcewake, try to restore, otherwise turn it off */
View
16 sys/dev/oce/oce_hw.c
@@ -38,6 +38,7 @@
/* $FreeBSD$ */
+
#include "oce_if.h"
static int oce_POST(POCE_SOFTC sc);
@@ -203,12 +204,16 @@ void oce_get_pci_capabilities(POCE_SOFTC sc)
{
uint32_t val;
- if (pci_find_cap(sc->dev, PCIY_PCIX, &val) == 0) {
+#if __FreeBSD_version >= 1000000
+ #define pci_find_extcap pci_find_cap
+#endif
+
+ if (pci_find_extcap(sc->dev, PCIY_PCIX, &val) == 0) {
if (val != 0)
sc->flags |= OCE_FLAGS_PCIX;
}
- if (pci_find_cap(sc->dev, PCIY_EXPRESS, &val) == 0) {
+ 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);
@@ -219,12 +224,12 @@ void oce_get_pci_capabilities(POCE_SOFTC sc)
}
}
- if (pci_find_cap(sc->dev, PCIY_MSI, &val) == 0) {
+ if (pci_find_extcap(sc->dev, PCIY_MSI, &val) == 0) {
if (val != 0)
sc->flags |= OCE_FLAGS_MSI_CAPABLE;
}
- if (pci_find_cap(sc->dev, PCIY_MSIX, &val) == 0) {
+ 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;
@@ -386,6 +391,9 @@ oce_create_nw_interface(POCE_SOFTC sc)
capab_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR;
}
+ if (IS_SH(sc) || IS_XE201(sc))
+ capab_flags |= MBX_RX_IFACE_FLAGS_MULTICAST;
+
/* enable capabilities controlled via driver startup parameters */
if (is_rss_enabled(sc))
capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;
View
28 sys/dev/oce/oce_hw.h
@@ -59,6 +59,30 @@
#define INTR_EN 0x20000000
#define IMAGE_TRANSFER_SIZE (32 * 1024) /* 32K at a time */
+
+/********* UE Status and Mask Registers ***/
+#define PCICFG_UE_STATUS_LOW 0xA0
+#define PCICFG_UE_STATUS_HIGH 0xA4
+#define PCICFG_UE_STATUS_LOW_MASK 0xA8
+
+/* Lancer SLIPORT registers */
+#define SLIPORT_STATUS_OFFSET 0x404
+#define SLIPORT_CONTROL_OFFSET 0x408
+#define SLIPORT_ERROR1_OFFSET 0x40C
+#define SLIPORT_ERROR2_OFFSET 0x410
+#define PHYSDEV_CONTROL_OFFSET 0x414
+
+#define SLIPORT_STATUS_ERR_MASK 0x80000000
+#define SLIPORT_STATUS_DIP_MASK 0x02000000
+#define SLIPORT_STATUS_RN_MASK 0x01000000
+#define SLIPORT_STATUS_RDY_MASK 0x00800000
+#define SLI_PORT_CONTROL_IP_MASK 0x08000000
+#define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002
+#define PHYSDEV_CONTROL_DD_MASK 0x00000004
+#define PHYSDEV_CONTROL_INP_MASK 0x40000000
+
+#define SLIPORT_ERROR_NO_RESOURCE1 0x2
+#define SLIPORT_ERROR_NO_RESOURCE2 0x9
/* CSR register offsets */
#define MPU_EP_CONTROL 0
#define MPU_EP_SEMAPHORE_BE3 0xac
@@ -2079,7 +2103,8 @@ struct flash_file_hdr {
uint32_t antidote;
uint32_t num_imgs;
uint8_t build[24];
- uint8_t rsvd[32];
+ uint8_t asic_type_rev;
+ uint8_t rsvd[31];
};
struct image_hdr {
@@ -3681,4 +3706,3 @@ enum OCE_QUEUE_RX_STATS {
QUEUE_RX_BUFFER_ERRORS = 8,
QUEUE_RX_N_WORDS = 10
};
-
View
173 sys/dev/oce/oce_if.c
@@ -36,7 +36,6 @@
* Costa Mesa, CA 92626
*/
-
/* $FreeBSD$ */
#include "opt_inet6.h"
@@ -44,6 +43,78 @@
#include "oce_if.h"
+/* UE Status Low CSR */
+static char *ue_status_low_desc[] = {
+ "CEV",
+ "CTX",
+ "DBUF",
+ "ERX",
+ "Host",
+ "MPU",
+ "NDMA",
+ "PTC ",
+ "RDMA ",
+ "RXF ",
+ "RXIPS ",
+ "RXULP0 ",
+ "RXULP1 ",
+ "RXULP2 ",
+ "TIM ",
+ "TPOST ",
+ "TPRE ",
+ "TXIPS ",
+ "TXULP0 ",
+ "TXULP1 ",
+ "UC ",
+ "WDMA ",
+ "TXULP2 ",
+ "HOST1 ",
+ "P0_OB_LINK ",
+ "P1_OB_LINK ",
+ "HOST_GPIO ",
+ "MBOX ",
+ "AXGMAC0",
+ "AXGMAC1",
+ "JTAG",
+ "MPU_INTPEND"
+};
+
+/* UE Status High CSR */
+static char *ue_status_hi_desc[] = {
+ "LPCMEMHOST",
+ "MGMT_MAC",
+ "PCS0ONLINE",
+ "MPU_IRAM",
+ "PCS1ONLINE",
+ "PCTL0",
+ "PCTL1",
+ "PMEM",
+ "RR",
+ "TXPB",
+ "RXPP",
+ "XAUI",
+ "TXP",
+ "ARM",
+ "IPC",
+ "HOST2",
+ "HOST3",
+ "HOST4",
+ "HOST5",
+ "HOST6",
+ "HOST7",
+ "HOST8",
+ "HOST9",
+ "NETC",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown"
+};
+
/* Driver entry points prototypes */
static int oce_probe(device_t dev);
@@ -388,11 +459,11 @@ oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) {
- sc->promisc = TRUE;
- oce_rxf_set_promiscuous(sc, sc->promisc);
+ if (!oce_rxf_set_promiscuous(sc, (1 | (1 << 1))))
+ sc->promisc = TRUE;
} else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) {
- sc->promisc = FALSE;
- oce_rxf_set_promiscuous(sc, sc->promisc);
+ if (!oce_rxf_set_promiscuous(sc, 0))
+ sc->promisc = FALSE;
}
break;
@@ -862,10 +933,12 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
(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) {
nichdr->u0.s.vlan = 1; /*Vlan present*/
nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag;
}
+
if (m->m_pkthdr.csum_flags & CSUM_TSO) {
if (m->m_pkthdr.tso_segsz) {
nichdr->u0.s.lso = 1;
@@ -1156,6 +1229,18 @@ oce_wq_handler(void *arg)
}
+#if __FreeBSD_version >= 1000000
+static __inline void
+drbr_stats_update(struct ifnet *ifp, int len, int mflags)
+{
+#ifndef NO_SLOW_STATS
+ ifp->if_obytes += len;
+ if (mflags & M_MCAST)
+ ifp->if_omcasts++;
+#endif
+}
+#endif
+
static int
oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
{
@@ -1174,7 +1259,7 @@ oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
return status;
}
- if (m != NULL) {
+ if (m != NULL) {
if ((status = drbr_enqueue(ifp, br, m)) != 0)
return status;
}
@@ -1646,6 +1731,10 @@ oce_attach_ifp(POCE_SOFTC sc)
sc->ifp->if_capenable = sc->ifp->if_capabilities;
if_initbaudrate(sc->ifp, IF_Gbps(10));
+#if __FreeBSD_version >= 1000000
+ sc->ifp->if_hw_tsomax = OCE_MAX_TSO_SIZE;
+#endif
+
ether_ifattach(sc->ifp, sc->macaddr.mac_addr);
return 0;
@@ -1664,7 +1753,8 @@ oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
sc->vlan_tag[vtag] = 1;
sc->vlans_added++;
- oce_vid_config(sc);
+ if (sc->vlans_added <= (sc->max_vlans + 1))
+ oce_vid_config(sc);
}
@@ -1866,12 +1956,76 @@ oce_eqd_set_periodic(POCE_SOFTC sc)
}
+static void oce_detect_hw_error(POCE_SOFTC sc)
+{
+
+ uint32_t ue_low = 0, ue_high = 0, ue_low_mask = 0, ue_high_mask = 0;
+ uint32_t sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
+ uint32_t i;
+
+ if (sc->hw_error)
+ return;
+
+ if (IS_XE201(sc)) {
+ sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET);
+ if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
+ sliport_err1 = OCE_READ_REG32(sc, db, SLIPORT_ERROR1_OFFSET);
+ sliport_err2 = OCE_READ_REG32(sc, db, SLIPORT_ERROR2_OFFSET);
+ }
+ } else {
+ ue_low = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW);
+ ue_high = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HIGH);
+ ue_low_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW_MASK);
+ ue_high_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HI_MASK);
+
+ ue_low = (ue_low & ~ue_low_mask);
+ ue_high = (ue_high & ~ue_high_mask);
+ }
+
+ /* On certain platforms BE hardware can indicate spurious UEs.
+ * Allow the h/w to stop working completely in case of a real UE.
+ * Hence not setting the hw_error for UE detection.
+ */
+ if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
+ sc->hw_error = TRUE;
+ device_printf(sc->dev, "Error detected in the card\n");
+ }
+
+ if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
+ device_printf(sc->dev,
+ "ERR: sliport status 0x%x\n", sliport_status);
+ device_printf(sc->dev,
+ "ERR: sliport error1 0x%x\n", sliport_err1);
+ device_printf(sc->dev,
+ "ERR: sliport error2 0x%x\n", sliport_err2);
+ }
+
+ if (ue_low) {
+ for (i = 0; ue_low; ue_low >>= 1, i++) {
+ if (ue_low & 1)
+ device_printf(sc->dev, "UE: %s bit set\n",
+ ue_status_low_desc[i]);
+ }
+ }
+
+ if (ue_high) {
+ for (i = 0; ue_high; ue_high >>= 1, i++) {
+ if (ue_high & 1)
+ device_printf(sc->dev, "UE: %s bit set\n",
+ ue_status_hi_desc[i]);
+ }
+ }
+
+}
+
+
static void
oce_local_timer(void *arg)
{
POCE_SOFTC sc = arg;
int i = 0;
+ oce_detect_hw_error(sc);
oce_refresh_nic_stats(sc);
oce_refresh_queue_stats(sc);
oce_mac_addr_set(sc);
@@ -1890,7 +2044,7 @@ oce_local_timer(void *arg)
/* NOTE : This should only be called holding
* DEVICE_LOCK.
-*/
+ */
static void
oce_if_deactivate(POCE_SOFTC sc)
{
@@ -2080,6 +2234,9 @@ setup_max_queues_want(POCE_SOFTC sc)
(sc->flags & OCE_FLAGS_BE2)) {
sc->nrqs = 1;
sc->nwqs = 1;
+ } else {
+ sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1;
+ sc->nwqs = MIN(OCE_NCPUS, sc->nrssqs);
}
}
View
12 sys/dev/oce/oce_if.h
@@ -36,7 +36,6 @@
* Costa Mesa, CA 92626
*/
-
/* $FreeBSD$ */
#include <sys/param.h>
@@ -88,7 +87,8 @@
#include "oce_hw.h"
-#define COMPONENT_REVISION "4.6.95.0"
+/* OCE device driver module component revision informaiton */
+#define COMPONENT_REVISION "10.0.664.0"
/* OCE devices supported by this driver */
#define PCI_VENDOR_EMULEX 0x10df /* Emulex */
@@ -150,6 +150,7 @@ extern int mp_ncpus; /* system's total active cpu cores */
#define OCE_MAX_TX_ELEMENTS 29
#define OCE_MAX_TX_DESC 1024
#define OCE_MAX_TX_SIZE 65535
+#define OCE_MAX_TSO_SIZE (65535 - ETHER_HDR_LEN)
#define OCE_MAX_RX_SIZE 4096
#define OCE_MAX_RQ_POSTS 255
#define OCE_DEFAULT_PROMISCUOUS 0
@@ -173,6 +174,7 @@ extern int mp_ncpus; /* system's total active cpu cores */
#define OCE_CAPAB_FLAGS (MBX_RX_IFACE_FLAGS_BROADCAST | \
MBX_RX_IFACE_FLAGS_UNTAGGED | \
MBX_RX_IFACE_FLAGS_PROMISCUOUS | \
+ MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS | \
MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS | \
MBX_RX_IFACE_FLAGS_RSS | \
MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR)
@@ -863,7 +865,7 @@ typedef struct oce_softc {
uint32_t if_cap_flags;
uint32_t flow_control;
- uint32_t promisc;
+ uint8_t promisc;
struct oce_aic_obj aic_obj[OCE_MAX_EQ];
@@ -877,9 +879,11 @@ typedef struct oce_softc {
struct oce_drv_stats oce_stats_info;
struct callout timer;
int8_t be3_native;
+ uint8_t hw_error;
uint16_t qnq_debug_event;
uint16_t qnqid;
uint16_t pvid;
+ uint16_t max_vlans;
} OCE_SOFTC, *POCE_SOFTC;
@@ -1010,7 +1014,7 @@ int oce_config_vlan(POCE_SOFTC sc, uint32_t if_id,
uint32_t untagged, uint32_t enable_promisc);
int oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control);
int oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss);
-int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable);
+int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable);
int oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl);
int oce_get_link_status(POCE_SOFTC sc, struct link_status *link);
int oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
View
291 sys/dev/oce/oce_mbox.c
@@ -36,11 +36,8 @@
* Costa Mesa, CA 92626
*/
-
-
/* $FreeBSD$ */
-
#include "oce_if.h"
extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
@@ -281,8 +278,10 @@ oce_get_fw_version(POCE_SOFTC sc)
if (!ret)
ret = fwcmd->hdr.u0.rsp.status;
if (ret) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, ret);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, ret,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@@ -438,8 +437,10 @@ oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id,
if (!ret)
ret = fwcmd->hdr.u0.rsp.status;
if (ret) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, ret);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, ret,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@@ -481,25 +482,27 @@ oce_get_fw_config(POCE_SOFTC sc)
if (!ret)
ret = fwcmd->hdr.u0.rsp.status;
if (ret) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, ret);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, ret,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config));
- sc->config_number = fwcmd->params.rsp.config_number;
- sc->asic_revision = fwcmd->params.rsp.asic_revision;
- sc->port_id = fwcmd->params.rsp.port_id;
- sc->function_mode = fwcmd->params.rsp.function_mode;
- sc->function_caps = fwcmd->params.rsp.function_caps;
+ sc->config_number = HOST_32(fwcmd->params.rsp.config_number);
+ sc->asic_revision = HOST_32(fwcmd->params.rsp.asic_revision);
+ sc->port_id = HOST_32(fwcmd->params.rsp.port_id);
+ sc->function_mode = HOST_32(fwcmd->params.rsp.function_mode);
+ sc->function_caps = HOST_32(fwcmd->params.rsp.function_caps);
if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) {
- sc->max_tx_rings = fwcmd->params.rsp.ulp[0].nic_wq_tot;
- sc->max_rx_rings = fwcmd->params.rsp.ulp[0].lro_rqid_tot;
+ sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[0].nic_wq_tot);
+ sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[0].lro_rqid_tot);
} else {
- sc->max_tx_rings = fwcmd->params.rsp.ulp[1].nic_wq_tot;
- sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot;
+ sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[1].nic_wq_tot);
+ sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[1].lro_rqid_tot);
}
error:
@@ -561,15 +564,17 @@ oce_if_create(POCE_SOFTC sc,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
- *if_id = LE_32(fwcmd->params.rsp.if_id);
+ *if_id = HOST_32(fwcmd->params.rsp.if_id);
if (mac_addr != NULL)
- sc->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
+ sc->pmac_id = HOST_32(fwcmd->params.rsp.pmac_id);
error:
return rc;
}
@@ -607,8 +612,10 @@ oce_if_del(POCE_SOFTC sc, uint32_t if_id)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -630,7 +637,10 @@ oce_config_vlan(POCE_SOFTC sc,
{
struct oce_mbx mbx;
struct mbx_common_config_vlan *fwcmd;
- int rc;
+ int rc = 0;
+
+ if (sc->vlans_added > sc->max_vlans)
+ goto vlan_promisc;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_common_config_vlan *)&mbx.payload;
@@ -659,9 +669,19 @@ oce_config_vlan(POCE_SOFTC sc,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
- return 0;
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
+
+ goto done;
+
+vlan_promisc:
+ /* Enable Vlan Promis */
+ oce_rxf_set_promiscuous(sc, (1 << 1));
+ device_printf(sc->dev,"Enabling Vlan Promisc Mode\n");
+done:
+ return rc;
}
@@ -702,8 +722,10 @@ oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -802,8 +824,10 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
}
return rc;
}
@@ -818,7 +842,7 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
* This function uses the COMMON_SET_IFACE_RX_FILTER command instead.
*/
int
-oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable)
+oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable)
{
struct mbx_set_common_iface_rx_filter *fwcmd;
int sz = sizeof(struct mbx_set_common_iface_rx_filter);
@@ -836,10 +860,13 @@ oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable)
req = &fwcmd->params.req;
req->iface_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
- if (enable) {
- req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
- MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
- }
+ /* Bit 0 Mac promisc, Bit 1 Vlan promisc */
+ if (enable & 0x01)
+ req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
+
+ if (enable & 0x02)
+ req->iface_flags = MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
+
req->if_id = sc->if_id;
rc = oce_set_common_iface_rx_filter(sc, &sgl);
@@ -886,9 +913,11 @@ oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
- return 0;
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
+ return rc;
}
/**
@@ -925,14 +954,16 @@ oce_get_link_status(POCE_SOFTC sc, struct link_status *link)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
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);
+ link->logical_link_status = HOST_32(link->logical_link_status);
+ link->qos_link_speed = HOST_16(link->qos_link_speed);
error:
return rc;
}
@@ -978,8 +1009,10 @@ oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1028,8 +1061,10 @@ oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1080,8 +1115,10 @@ oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1133,8 +1170,10 @@ oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1178,8 +1217,10 @@ oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem)
if (!rc)
rc = req->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ req->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1243,8 +1284,10 @@ oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
*pmac_id = fwcmd->params.rsp.pmac_id;
@@ -1281,8 +1324,10 @@ oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1318,11 +1363,13 @@ oce_mbox_check_native_mode(POCE_SOFTC sc)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
- sc->be3_native = fwcmd->params.rsp.capability_flags
+ sc->be3_native = HOST_32(fwcmd->params.rsp.capability_flags)
& CAP_BE3_NATIVE_ERX_API;
error:
@@ -1363,8 +1410,10 @@ oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
@@ -1406,8 +1455,10 @@ oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1433,9 +1484,9 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
payload_len,
OCE_MBX_VER_V0);
- fwcmd->flash_op_type = optype;
- fwcmd->flash_op_code = opcode;
- fwcmd->data_buffer_size = num_bytes;
+ fwcmd->flash_op_type = LE_32(optype);
+ fwcmd->flash_op_code = LE_32(opcode);
+ fwcmd->data_buffer_size = LE_32(num_bytes);
mbx.u0.s.embedded = 0; /*Non embeded*/
mbx.payload_length = payload_len;
@@ -1451,8 +1502,10 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
return rc;
@@ -1497,8 +1550,10 @@ oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
bcopy(fwcmd->data_buffer, flash_crc, 4);
@@ -1532,18 +1587,20 @@ oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
- phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
+ phy_info->phy_type = HOST_16(fwcmd->params.rsp.phy_info.phy_type);
phy_info->interface_type =
- fwcmd->params.rsp.phy_info.interface_type;
+ HOST_16(fwcmd->params.rsp.phy_info.interface_type);
phy_info->auto_speeds_supported =
- fwcmd->params.rsp.phy_info.auto_speeds_supported;
+ HOST_16(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;
+ HOST_16(fwcmd->params.rsp.phy_info.fixed_speeds_supported);
+ phy_info->misc_params = HOST_32(fwcmd->params.rsp.phy_info.misc_params);
error:
return rc;
@@ -1593,11 +1650,13 @@ oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
if (!rc)
rc = fwcmd->params.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->params.rsp.additional_status);
goto error;
}
- *written_data = fwcmd->params.rsp.actual_write_length;
+ *written_data = HOST_32(fwcmd->params.rsp.actual_write_length);
*additional_status = fwcmd->params.rsp.additional_status;
error:
return rc;
@@ -1649,11 +1708,13 @@ oce_mbox_create_rq(struct oce_rq *rq)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
- rq->rq_id = fwcmd->params.rsp.rq_id;
+ rq->rq_id = HOST_16(fwcmd->params.rsp.rq_id);
rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
error:
return rc;
@@ -1673,15 +1734,17 @@ oce_mbox_create_wq(struct oce_wq *wq)
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_create_nic_wq *)&mbx.payload;
- if (IS_XE201(sc)) {
+ if (IS_XE201(sc))
version = OCE_MBX_VER_V1;
- fwcmd->params.req.if_id = sc->if_id;
- } else if(IS_BE(sc))
+ 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;
+ if (version > OCE_MBX_VER_V0)
+ fwcmd->params.req.if_id = sc->if_id;
+
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
NIC_CREATE_WQ, MBX_TIMEOUT_SEC,
@@ -1703,13 +1766,15 @@ oce_mbox_create_wq(struct oce_wq *wq)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
- wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
+ wq->wq_id = HOST_16(fwcmd->params.rsp.wq_id);
if (version == OCE_MBX_VER_V2)
- wq->db_offset = LE_32(fwcmd->params.rsp.db_offset);
+ wq->db_offset = HOST_32(fwcmd->params.rsp.db_offset);
else
wq->db_offset = PD_TXULP_DB;
error:
@@ -1754,11 +1819,13 @@ oce_mbox_create_eq(struct oce_eq *eq)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
- eq->eq_id = LE_16(fwcmd->params.rsp.eq_id);
+ eq->eq_id = HOST_16(fwcmd->params.rsp.eq_id);
error:
return rc;
}
@@ -1832,11 +1899,13 @@ oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
- cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
+ cq->cq_id = HOST_16(fwcmd->params.rsp.cq_id);
error:
return rc;
@@ -1885,8 +1954,10 @@ oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
if(fwcmd->params.rsp.page_num == PAGE_NUM_A0)
@@ -1947,8 +2018,10 @@ oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
}
int
@@ -2006,8 +2079,10 @@ oce_get_profile_config(POCE_SOFTC sc)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@@ -2027,6 +2102,7 @@ oce_get_profile_config(POCE_SOFTC sc)
goto error;
}
else {
+ sc->max_vlans = nic_desc->vlan_count;
sc->nwqs = HOST_32(nic_desc->txq_count);
if (sc->nwqs)
sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
@@ -2096,8 +2172,10 @@ oce_get_func_config(POCE_SOFTC sc)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
- device_printf(sc->dev,"%s failed - cmd status: %d\n",
- __FUNCTION__, rc);
+ device_printf(sc->dev,
+ "%s failed - cmd status: %d addi status: %d\n",
+ __FUNCTION__, rc,
+ fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@@ -2117,6 +2195,7 @@ oce_get_func_config(POCE_SOFTC sc)
goto error;
}
else {
+ sc->max_vlans = nic_desc->vlan_count;
sc->nwqs = HOST_32(nic_desc->txq_count);
if (sc->nwqs)
sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
View
3  sys/dev/oce/oce_queue.c
@@ -36,11 +36,8 @@
* Costa Mesa, CA 92626
*/
-
-
/* $FreeBSD$ */
-
#include "oce_if.h"
/*****************************************************
View
355 sys/dev/oce/oce_sysctl.c
@@ -38,7 +38,6 @@
/* $FreeBSD$ */
-
#include "oce_if.h"
static void copy_stats_to_sc_xe201(POCE_SOFTC sc);
@@ -46,9 +45,8 @@ static void copy_stats_to_sc_be3(POCE_SOFTC sc);
static void copy_stats_to_sc_be2(POCE_SOFTC sc);
static int oce_sysctl_loopback(SYSCTL_HANDLER_ARGS);
static int oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
+static int oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
static int oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS);
-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);
@@ -62,9 +60,18 @@ static void oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
struct sysctl_ctx_list *ctx,
struct sysctl_oid *stats_node);
+
extern char component_revision[32];
uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
+struct flash_img_attri {
+ int img_offset;
+ int img_size;
+ int img_type;
+ bool skip_image;
+ int optype;
+};
+
void
oce_add_sysctls(POCE_SOFTC sc)
{
@@ -154,10 +161,10 @@ oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type)
{
uint32_t status = 0;
- oce_mbox_cmd_set_loopback(sc, sc->if_id, loopback_type, 1);
- status = oce_mbox_cmd_test_loopback(sc, sc->if_id, loopback_type,
+ oce_mbox_cmd_set_loopback(sc, sc->port_id, loopback_type, 1);
+ status = oce_mbox_cmd_test_loopback(sc, sc->port_id, loopback_type,
1500, 2, 0xabc);
- oce_mbox_cmd_set_loopback(sc, sc->if_id, OCE_NO_LOOPBACK, 1);
+ oce_mbox_cmd_set_loopback(sc, sc->port_id, OCE_NO_LOOPBACK, 1);
return status;
}
@@ -223,7 +230,7 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
return ENOENT;
}
- if (IS_BE(sc) || IS_SH(sc)) {
+ if (IS_BE(sc)) {
if ((sc->flags & OCE_FLAGS_BE2)) {
device_printf(sc->dev,
"Flashing not supported for BE2 yet.\n");
@@ -231,6 +238,8 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
goto done;
}
status = oce_be3_fwupgrade(sc, fw);
+ } else if (IS_SH(sc)) {
+ status = oce_skyhawk_fwupgrade(sc,fw);
} else
status = oce_lancer_fwupgrade(sc, fw);
done:
@@ -246,53 +255,117 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
return status;
}
-
-static int
-oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
+static void oce_fill_flash_img_data(POCE_SOFTC sc, const struct flash_sec_info * fsec,
+ struct flash_img_attri *pimg, int i,
+ const struct firmware *fw, int bin_offset)
{
- int rc = 0, num_imgs = 0, i = 0;
- const struct flash_file_hdr *fhdr;
- const struct image_hdr *img_ptr;
-
- fhdr = (const struct flash_file_hdr *)fw->data;
- if (fhdr->build[0] != '3') {
- device_printf(sc->dev, "Invalid BE3 firmware image\n");
- return EINVAL;
+ if (IS_SH(sc)) {
+ pimg->img_offset = HOST_32(fsec->fsec_entry[i].offset);
+ pimg->img_size = HOST_32(fsec->fsec_entry[i].pad_size);
}
- /* Display flash version */
- device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]);
- num_imgs = fhdr->num_imgs;
- for (i = 0; i < num_imgs; i++) {
- img_ptr = (const struct image_hdr *)((const char *)fw->data +
- sizeof(struct flash_file_hdr) +
- (i * sizeof(struct image_hdr)));
- if (img_ptr->imageid == 1) {
- rc = oce_be3_flashdata(sc, fw, num_imgs);
+ pimg->img_type = HOST_32(fsec->fsec_entry[i].type);
+ pimg->skip_image = FALSE;
+ switch (pimg->img_type) {
+ case IMG_ISCSI:
+ pimg->optype = 0;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 2097152;
+ pimg->img_size = 2097152;
+ }
+ break;
+ case IMG_REDBOOT:
+ pimg->optype = 1;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 262144;
+ pimg->img_size = 1048576;
+ }
+ if (!oce_img_flashing_required(sc, fw->data,
+ pimg->optype,
+ pimg->img_offset,
+ pimg->img_size,
+ bin_offset))
+ pimg->skip_image = TRUE;
+ break;
+ case IMG_BIOS:
+ pimg->optype = 2;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 12582912;
+ pimg->img_size = 524288;
+ }
+ break;
+ case IMG_PXEBIOS:
+ pimg->optype = 3;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 13107200;;
+ pimg->img_size = 524288;
+ }
+ break;
+ case IMG_FCOEBIOS:
+ pimg->optype = 8;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 13631488;
+ pimg->img_size = 524288;
+ }
+ break;
+ case IMG_ISCSI_BAK:
+ pimg->optype = 9;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 4194304;
+ pimg->img_size = 2097152;
+ }
+ break;
+ case IMG_FCOE:
+ pimg->optype = 10;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 6291456;
+ pimg->img_size = 2097152;
+ }
+ break;
+ case IMG_FCOE_BAK:
+ pimg->optype = 11;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 8388608;
+ pimg->img_size = 2097152;
+ }
+ break;
+ case IMG_NCSI:
+ pimg->optype = 13;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 15990784;
+ pimg->img_size = 262144;
+ }
+ break;
+ case IMG_PHY:
+ pimg->optype = 99;
+ if (IS_BE3(sc)) {
+ pimg->img_offset = 1310720;
+ pimg->img_size = 262144;
+ }
+ if (!oce_phy_flashing_required(sc))
+ pimg->skip_image = TRUE;
+ break;
+ default:
+ pimg->skip_image = TRUE;
break;
- }
}
- return rc;
}
-
static int
-oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs)
+oce_sh_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int32_t num_imgs)
{
char cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
const char *p = (const char *)fw->data;
const struct flash_sec_info *fsec = NULL;
struct mbx_common_read_write_flashrom *req;
- int rc = 0, i, img_type, bin_offset = 0;
- boolean_t skip_image;
- uint32_t optype = 0, size = 0, start = 0, num_bytes = 0;
- uint32_t opcode = 0;
+ int rc = 0, i, bin_offset = 0, opcode, num_bytes;
OCE_DMA_MEM dma_mem;
+ struct flash_img_attri imgatt;
/* Validate Cookie */
bin_offset = (sizeof(struct flash_file_hdr) +
- (num_imgs * sizeof(struct image_hdr)));
+ (num_imgs * sizeof(struct image_hdr)));
p += bin_offset;
while (p < ((const char *)fw->data + fw->datasize)) {
fsec = (const struct flash_sec_info *)p;
@@ -304,7 +377,7 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs)
if (!fsec) {
device_printf(sc->dev,
- "Invalid Cookie. Firmware image corrupted ?\n");
+ "Invalid Cookie. Firmware image corrupted ?\n");
return EINVAL;
}
@@ -312,94 +385,42 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs)
+ 32*1024, &dma_mem, 0);
if (rc) {
device_printf(sc->dev,
- "Memory allocation failure while flashing\n");
+ "Memory allocation failure while flashing\n");
return ENOMEM;
}
req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom);
- for (i = 0; i < MAX_FLASH_COMP; i++) {
+ if (IS_SH(sc))
+ num_imgs = HOST_32(fsec->fsec_hdr.num_images);
+ else if (IS_BE3(sc))
+ num_imgs = MAX_FLASH_COMP;
- img_type = fsec->fsec_entry[i].type;
- skip_image = FALSE;
- switch (img_type) {
- case IMG_ISCSI:
- optype = 0;
- size = 2097152;
- start = 2097152;
- break;
- case IMG_REDBOOT:
- optype = 1;
- size = 1048576;
- start = 262144;
- if (!oce_img_flashing_required(sc, fw->data,
- optype, start, size, bin_offset))
- skip_image = TRUE;
- break;
- case IMG_BIOS:
- optype = 2;
- size = 524288;
- start = 12582912;
- break;
- case IMG_PXEBIOS:
- optype = 3;
- size = 524288;
- start = 13107200;
- break;
- case IMG_FCOEBIOS:
- optype = 8;
- size = 524288;
- start = 13631488;
- break;
- case IMG_ISCSI_BAK:
- optype = 9;
- size = 2097152;
- start = 4194304;
- break;
- case IMG_FCOE:
- optype = 10;
- size = 2097152;
- start = 6291456;
- break;
- case IMG_FCOE_BAK:
- optype = 11;
- size = 2097152;
- start = 8388608;
- break;
- case IMG_NCSI:
- optype = 13;
- size = 262144;
- start = 15990784;
- break;
- case IMG_PHY:
- optype = 99;
- size = 262144;
- start = 1310720;
- if (!oce_phy_flashing_required(sc))
- skip_image = TRUE;
- break;
- default:
- skip_image = TRUE;
- break;
- }
- if (skip_image)
+ for (i = 0; i < num_imgs; i++) {
+
+ bzero(&imgatt, sizeof(struct flash_img_attri));
+
+ oce_fill_flash_img_data(sc, fsec, &imgatt, i, fw, bin_offset);
+
+ if (imgatt.skip_image)
continue;
p = fw->data;
- p = p + bin_offset + start;
- if ((p + size) > ((const char *)fw->data + fw->datasize)) {
+ p = p + bin_offset + imgatt.img_offset;
+
+ if ((p + imgatt.img_size) > ((const char *)fw->data + fw->datasize)) {
rc = 1;
goto ret;
}
- while (size) {
+ while (imgatt.img_size) {
- if (size > 32*1024)
+ if (imgatt.img_size > 32*1024)
num_bytes = 32*1024;
else
- num_bytes = size;
- size -= num_bytes;
+ num_bytes = imgatt.img_size;
+ imgatt.img_size -= num_bytes;
- if (!size)
+ if (!imgatt.img_size)
opcode = FLASHROM_OPER_FLASH;
else
opcode = FLASHROM_OPER_SAVE;
@@ -407,11 +428,11 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs)
memcpy(req->data_buffer, p, num_bytes);
p += num_bytes;
- rc = oce_mbox_write_flashrom(sc, optype, opcode,
- &dma_mem, num_bytes);
+ rc = oce_mbox_write_flashrom(sc, imgatt.optype, opcode,
+ &dma_mem, num_bytes);
if (rc) {
device_printf(sc->dev,
- "cmd to write to flash rom failed.\n");
+ "cmd to write to flash rom failed.\n");
rc = EIO;
goto ret;
}
@@ -419,11 +440,121 @@ oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs)
pause("yield", 10);
}
+
}
+
ret:
oce_dma_free(sc, &dma_mem);
return rc;
+}
+
+#define UFI_TYPE2 2
+#define UFI_TYPE3 3
+#define UFI_TYPE3R 10
+#define UFI_TYPE4 4
+#define UFI_TYPE4R 11
+static int oce_get_ufi_type(POCE_SOFTC sc,
+ const struct flash_file_hdr *fhdr)
+{
+ if (fhdr == NULL)
+ goto be_get_ufi_exit;
+
+ if (IS_SH(sc) && fhdr->build[0] == '4') {
+ if (fhdr->asic_type_rev >= 0x10)
+ return UFI_TYPE4R;
+ else
+ return UFI_TYPE4;
+ } else if (IS_BE3(sc) && fhdr->build[0] == '3') {
+ if (fhdr->asic_type_rev == 0x10)
+ return UFI_TYPE3R;
+ else
+ return UFI_TYPE3;
+ } else if (IS_BE2(sc) && fhdr->build[0] == '2')
+ return UFI_TYPE2;
+
+be_get_ufi_exit:
+ device_printf(sc->dev,
+ "UFI and Interface are not compatible for flashing\n");
+ return -1;
+}
+
+
+static int
+oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
+{
+ int rc = 0, num_imgs = 0, i = 0, ufi_type;
+ const struct flash_file_hdr *fhdr;
+ const struct image_hdr *img_ptr;
+
+ fhdr = (const struct flash_file_hdr *)fw->data;
+
+ ufi_type = oce_get_ufi_type(sc, fhdr);
+
+ /* Display flash version */
+ device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]);
+
+ num_imgs = fhdr->num_imgs;
+ for (i = 0; i < num_imgs; i++) {
+ img_ptr = (const struct image_hdr *)((const char *)fw->data +
+ sizeof(struct flash_file_hdr) +
+ (i * sizeof(struct image_hdr)));
+
+ if (img_ptr->imageid != 1)
+ continue;
+
+ switch (ufi_type) {
+ case UFI_TYPE4R:
+ rc = oce_sh_be3_flashdata(sc, fw,
+ num_imgs);
+ break;
+ case UFI_TYPE4:
+ if (sc->asic_revision < 0x10)
+ rc = oce_sh_be3_flashdata(sc, fw,
+ num_imgs);
+ else {
+ rc = -1;
+ device_printf(sc->dev,
+ "Cant load SH A0 UFI on B0\n");
+ }
+ break;
+ default:
+ rc = -1;
+ break;
+
+ }
+ }
+
+ return rc;
+}
+static int
+oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
+{
+ int rc = 0, num_imgs = 0, i = 0;
+ const struct flash_file_hdr *fhdr;
+ const struct image_hdr *img_ptr;
+
+ fhdr = (const struct flash_file_hdr *)fw->data;
+ if (fhdr->build[0] != '3') {
+ device_printf(sc->dev, "Invalid BE3 firmware image\n");
+ return EINVAL;
+ }
+ /* Display flash version */
+ device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]);
+
+ num_imgs = fhdr->num_imgs;
+ for (i = 0; i < num_imgs; i++) {
+ img_ptr = (const struct image_hdr *)((const char *)fw->data +
+ sizeof(struct flash_file_hdr) +
+ (i * sizeof(struct image_hdr)));
+ if (img_ptr->imageid == 1) {
+ rc = oce_sh_be3_flashdata(sc, fw, num_imgs);
+
+ break;
+ }
+ }
+
+ return rc;
}
View
2  sys/dev/oce/oce_util.c
@@ -36,10 +36,8 @@
* Costa Mesa, CA 92626
*/
-
/* $FreeBSD$ */
-
#include "oce_if.h"
static void oce_dma_map_ring(void *arg,
View
3  sys/kern/uipc_syscalls.c
@@ -2070,7 +2070,8 @@ sendfile_readpage(vm_object_t obj, struct vnode *vp, int nd,
}
KASSERT(error != 0 || (m->wire_count > 0 &&
vm_page_is_valid(m, off & PAGE_MASK, xfsize)),
- ("wrong page state m %p", m));
+ ("wrong page state m %p off %#jx xfsize %d", m, (uintmax_t)off,
+ xfsize));
VM_OBJECT_WUNLOCK(obj);
return (error);
}
View
2  sys/net/if_tap.c
@@ -205,7 +205,7 @@ vmnet_clone_create(struct if_clone *ifc, int unit, caddr_t params)
i = clone_create(&tapclones, &tap_cdevsw, &unit, &dev, VMNET_DEV_MASK);
if (i) {
dev = make_dev(&tap_cdevsw, unit | VMNET_DEV_MASK, UID_ROOT,
- GID_WHEEL, 0600, "%s%d", tapname, unit);
+ GID_WHEEL, 0600, "%s%d", vmnetname, unit);
}
tapcreate(dev);
View
1  sys/powerpc/conf/GENERIC64
@@ -128,6 +128,7 @@ device em # Intel PRO/1000 Gigabit Ethernet Family
device igb # Intel PRO/1000 PCIE Server Gigabit Family
device ixgbe # Intel PRO/10GbE PCIE Ethernet Family
device glc # Sony Playstation 3 Ethernet
+device llan # IBM pSeries Virtual Ethernet
# PCI Ethernet NICs that use the common MII bus controller code.
device miibus # MII bus support
View
2  sys/powerpc/pseries/phyp-hvcall.S
@@ -36,6 +36,8 @@
ASENTRY(phyp_hcall)
mflr %r0
std %r0,16(%r1)
+ ld %r11,112(%r1) /* Last couple args into volatile regs*/
+ ld %r12,120(%r1)
hc /* invoke the hypervisor */
ld %r0,16(%r1)
mtlr %r0
View
498 sys/powerpc/pseries/phyp_llan.c
@@ -0,0 +1,498 @@
+/*-
+ * Copyright 2013 Nathan Whitehorn
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sockio.h>
+#include <sys/endian.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <powerpc/pseries/phyp-hvcall.h>
+
+#define LLAN_MAX_RX_PACKETS 100
+#define LLAN_MAX_TX_PACKETS 100
+#define LLAN_RX_BUF_LEN 8*PAGE_SIZE
+
+#define LLAN_BUFDESC_VALID (1ULL << 63)
+#define LLAN_ADD_MULTICAST 0x1
+#define LLAN_DEL_MULTICAST 0x2
+#define LLAN_CLEAR_MULTICAST 0x3
+
+struct llan_xfer {
+ struct mbuf *rx_mbuf;
+ bus_dmamap_t rx_dmamap;
+ uint64_t rx_bufdesc;
+};
+
+struct llan_receive_queue_entry { /* PAPR page 539 */
+ uint8_t control;
+ uint8_t reserved;
+ uint16_t offset;
+ uint32_t length;
+ uint64_t handle;
+} __packed;
+
+struct llan_softc {
+ device_t dev;
+ struct mtx io_lock;
+
+ cell_t unit;
+ uint8_t mac_address[8];
+
+ int irqid;
+ struct resource *irq;
+ void *irq_cookie;
+
+ bus_dma_tag_t rx_dma_tag;
+ bus_dma_tag_t rxbuf_dma_tag;
+ bus_dma_tag_t tx_dma_tag;
+
+ bus_dmamap_t tx_dma_map;
+
+ struct llan_receive_queue_entry *rx_buf;
+ int rx_dma_slot;
+ int rx_valid_val;
+ bus_dmamap_t rx_buf_map;
+ bus_addr_t rx_buf_phys;
+ bus_size_t rx_buf_len;
+ bus_addr_t input_buf_phys;
+ bus_addr_t filter_buf_phys;
+ struct llan_xfer rx_xfer[LLAN_MAX_RX_PACKETS];
+
+ struct ifnet *ifp;
+};
+
+static int llan_probe(device_t);
+static int llan_attach(device_t);
+static void llan_intr(void *xsc);
+static void llan_init(void *xsc);
+static void llan_start(struct ifnet *ifp);
+static int llan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
+static void llan_rx_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs,
+ int err);
+static int llan_add_rxbuf(struct llan_softc *sc, struct llan_xfer *rx);
+static int llan_set_multicast(struct llan_softc *sc);
+
+static devclass_t llan_devclass;
+static device_method_t llan_methods[] = {
+ DEVMETHOD(device_probe, llan_probe),
+ DEVMETHOD(device_attach, llan_attach),
+
+ DEVMETHOD_END
+};
+static driver_t llan_driver = {
+ "llan",
+ llan_methods,
+ sizeof(struct llan_softc)
+};
+DRIVER_MODULE(llan, vdevice, llan_driver, llan_devclass, 0, 0);
+
+static int
+llan_probe(device_t dev)
+{
+ if (!ofw_bus_is_compatible(dev,"IBM,l-lan"))
+ return (ENXIO);
+
+ device_set_desc(dev, "POWER Hypervisor Virtual Ethernet");
+ return (0);
+}
+
+static int
+llan_attach(device_t dev)
+{
+ struct llan_softc *sc;
+ phandle_t node;
+ int error, i;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* Get firmware properties */
+ node = ofw_bus_get_node(dev);
+ OF_getprop(node, "local-mac-address", sc->mac_address,
+ sizeof(sc->mac_address));
+ OF_getprop(node, "reg", &sc->unit, sizeof(sc->unit));
+
+ mtx_init(&sc->io_lock, "llan", NULL, MTX_DEF);
+
+ /* Setup interrupt */
+ sc->irqid = 0;
+ sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
+ RF_ACTIVE);
+
+ if (!sc->irq) {
+ device_printf(dev, "Could not allocate IRQ\n");
+ mtx_destroy(&sc->io_lock);
+ return (ENXIO);
+ }
+
+ bus_setup_intr(dev, sc->irq, INTR_TYPE_MISC | INTR_MPSAFE |
+ INTR_ENTROPY, NULL, llan_intr, sc, &sc->irq_cookie);
+
+ /* Setup DMA */
+ error = bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ LLAN_RX_BUF_LEN, 1, BUS_SPACE_MAXSIZE_32BIT,
+ 0, NULL, NULL, &sc->rx_dma_tag);
+ error = bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ BUS_SPACE_MAXSIZE, 1, BUS_SPACE_MAXSIZE_32BIT,
+ 0, NULL, NULL, &sc->rxbuf_dma_tag);
+ error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ BUS_SPACE_MAXSIZE, 6, BUS_SPACE_MAXSIZE_32BIT, 0,
+ busdma_lock_mutex, &sc->io_lock, &sc->tx_dma_tag);
+
+ error = bus_dmamem_alloc(sc->rx_dma_tag, (void **)&sc->rx_buf,
+ BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx_buf_map);
+ error = bus_dmamap_load(sc->rx_dma_tag, sc->rx_buf_map, sc->rx_buf,
+ LLAN_RX_BUF_LEN, llan_rx_load_cb, sc, 0);
+
+ /* TX DMA maps */
+ bus_dmamap_create(sc->tx_dma_tag, 0, &sc->tx_dma_map);
+
+ /* RX DMA */
+ for (i = 0; i < LLAN_MAX_RX_PACKETS; i++) {
+ error = bus_dmamap_create(sc->rxbuf_dma_tag, 0,
+ &sc->rx_xfer[i].rx_dmamap);
+ sc->rx_xfer[i].rx_mbuf = NULL;
+ }
+
+ /* Attach to network stack */
+ sc->ifp = if_alloc(IFT_ETHER);
+ sc->ifp->if_softc = sc;
+
+ if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev));
+ sc->ifp->if_mtu = ETHERMTU; /* XXX max-frame-size from OF? */
+ sc->ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ sc->ifp->if_hwassist = 0; /* XXX: ibm,illan-options */
+ sc->ifp->if_capabilities = 0;
+ sc->ifp->if_capenable = 0;
+ sc->ifp->if_start = llan_start;
+ sc->ifp->if_ioctl = llan_ioctl;
+ sc->ifp->if_init = llan_init;
+
+ IFQ_SET_MAXLEN(&sc->ifp->if_snd, LLAN_MAX_TX_PACKETS);
+ sc->ifp->if_snd.ifq_drv_maxlen = LLAN_MAX_TX_PACKETS;
+ IFQ_SET_READY(&sc->ifp->if_snd);
+
+ ether_ifattach(sc->ifp, &sc->mac_address[2]);
+
+ return (0);
+}
+
+static void
+llan_rx_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int err)
+{
+ struct llan_softc *sc = xsc;
+
+ sc->rx_buf_phys = segs[0].ds_addr;
+ sc->rx_buf_len = segs[0].ds_len - 2*PAGE_SIZE;
+ sc->input_buf_phys = segs[0].ds_addr + segs[0].ds_len - PAGE_SIZE;
+ sc->filter_buf_phys = segs[0].ds_addr + segs[0].ds_len - 2*PAGE_SIZE;
+}
+
+static void
+llan_init(void *xsc)
+{
+ struct llan_softc *sc = xsc;
+ uint64_t rx_buf_desc;
+ uint64_t macaddr;
+ int err, i;
+
+ mtx_lock(&sc->io_lock);
+
+ phyp_hcall(H_FREE_LOGICAL_LAN, sc->unit);
+
+ /* Create buffers (page 539) */
+ sc->rx_dma_slot = 0;
+ sc->rx_valid_val = 1;
+
+ rx_buf_desc = LLAN_BUFDESC_VALID;
+ rx_buf_desc |= (sc->rx_buf_len << 32);
+ rx_buf_desc |= sc->rx_buf_phys;
+ memcpy(&macaddr, sc->mac_address, 8);
+ err = phyp_hcall(H_REGISTER_LOGICAL_LAN, sc->unit, sc->input_buf_phys,
+ rx_buf_desc, sc->filter_buf_phys, macaddr);
+
+ for (i = 0; i < LLAN_MAX_RX_PACKETS; i++)
+ llan_add_rxbuf(sc, &sc->rx_xfer[i]);
+
+ phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); /* Enable interrupts */
+
+ /* Tell stack we're up */
+ sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+ mtx_unlock(&sc->io_lock);
+}
+
+static int
+llan_add_rxbuf(struct llan_softc *sc, struct llan_xfer *rx)
+{
+ struct mbuf *m;
+ bus_dma_segment_t segs[1];
+ int error, nsegs;
+
+ mtx_assert(&sc->io_lock, MA_OWNED);
+
+ m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+ if (m == NULL)
+ return (ENOBUFS);
+
+ m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
+ if (rx->rx_mbuf != NULL) {
+ bus_dmamap_sync(sc->rxbuf_dma_tag, rx->rx_dmamap,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->rxbuf_dma_tag, rx->rx_dmamap);
+ }
+
+ /* Save pointer to buffer structure */
+ m_copyback(m, 0, 8, (void *)&rx);
+
+ error = bus_dmamap_load_mbuf_sg(sc->rxbuf_dma_tag, rx->rx_dmamap, m,
+ segs, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ device_printf(sc->dev,
+ "cannot load RX DMA map %p, error = %d\n", rx, error);
+ m_freem(m);
+ return (error);
+ }
+
+ /* If nsegs is wrong then the stack is corrupt. */
+ KASSERT(nsegs == 1,
+ ("%s: too many DMA segments (%d)", __func__, nsegs));
+ rx->rx_mbuf = m;
+
+ bus_dmamap_sync(sc->rxbuf_dma_tag, rx->rx_dmamap, BUS_DMASYNC_PREREAD);
+
+ rx->rx_bufdesc = LLAN_BUFDESC_VALID;
+ rx->rx_bufdesc |= (((uint64_t)segs[0].ds_len) << 32);
+ rx->rx_bufdesc |= segs[0].ds_addr;
+ error = phyp_hcall(H_ADD_LOGICAL_LAN_BUFFER, sc->unit, rx->rx_bufdesc);
+ if (error != 0) {
+ m_freem(m);
+ rx->rx_mbuf = NULL;
+ return (ENOBUFS);
+ }
+
+ return (0);
+}
+
+static void
+llan_intr(void *xsc)
+{
+ struct llan_softc *sc = xsc;
+ struct llan_xfer *rx;
+ struct mbuf *m;
+
+ mtx_lock(&sc->io_lock);
+ phyp_hcall(H_VIO_SIGNAL, sc->unit, 0);
+
+ while ((sc->rx_buf[sc->rx_dma_slot].control >> 7) == sc->rx_valid_val) {
+ rx = (struct llan_xfer *)sc->rx_buf[sc->rx_dma_slot].handle;
+ m = rx->rx_mbuf;
+ m_adj(m, sc->rx_buf[sc->rx_dma_slot].offset - 8);
+ m->m_len = sc->rx_buf[sc->rx_dma_slot].length;
+
+ /* llan_add_rxbuf does DMA sync and unload as well as requeue */
+ if (llan_add_rxbuf(sc, rx) != 0) {
+ sc->ifp->if_ierrors++;
+ phyp_hcall(H_ADD_LOGICAL_LAN_BUFFER, sc->unit,
+ rx->rx_bufdesc);
+ continue;
+ }
+
+ sc->ifp->if_ipackets++;
+ m_adj(m, sc->rx_buf[sc->rx_dma_slot].offset);
+ m->m_len = sc->rx_buf[sc->rx_dma_slot].length;
+ m->m_pkthdr.rcvif = sc->ifp;
+ m->m_pkthdr.len = m->m_len;
+ sc->rx_dma_slot++;
+
+ if (sc->rx_dma_slot >= sc->rx_buf_len/sizeof(sc->rx_buf[0])) {
+ sc->rx_dma_slot = 0;
+ sc->rx_valid_val = !sc->rx_valid_val;
+ }
+
+ mtx_unlock(&sc->io_lock);
+ (*sc->ifp->if_input)(sc->ifp, m);
+ mtx_lock(&sc->io_lock);
+ }
+
+ phyp_hcall(H_VIO_SIGNAL, sc->unit, 1);
+ mtx_unlock(&sc->io_lock);
+}
+
+static void
+llan_send_packet(void *xsc, bus_dma_segment_t *segs, int nsegs,
+ bus_size_t mapsize, int error)
+{
+ struct llan_softc *sc = xsc;
+ uint64_t bufdescs[6];
+ int i;
+
+ bzero(bufdescs, sizeof(bufdescs));
+
+ for (i = 0; i < nsegs; i++) {
+ bufdescs[i] = LLAN_BUFDESC_VALID;
+ bufdescs[i] |= (((uint64_t)segs[i].ds_len) << 32);
+ bufdescs[i] |= segs[i].ds_addr;
+ }
+
+ phyp_hcall(H_SEND_LOGICAL_LAN, sc->unit, bufdescs[0],
+ bufdescs[1], bufdescs[2], bufdescs[3], bufdescs[4], bufdescs[5], 0);
+ /*
+ * The hypercall returning implies completion -- or that the call will
+ * not complete. In principle, we should try a few times if we get back
+ * H_BUSY based on the continuation token in R4. For now, just drop
+ * the packet in such cases.
+ */
+}
+
+static void
+llan_start_locked(struct ifnet *ifp)
+{
+ struct llan_softc *sc = ifp->if_softc;
+ bus_addr_t first;
+ int nsegs;
+ struct mbuf *mb_head, *m;
+
+ mtx_assert(&sc->io_lock, MA_OWNED);
+ first = 0;
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return;
+
+ while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, mb_head);
+
+ if (mb_head == NULL)
+ break;
+
+ BPF_MTAP(ifp, mb_head);
+
+ for (m = mb_head, nsegs = 0; m != NULL; m = m->m_next)
+ nsegs++;
+ if (nsegs > 6) {
+ m = m_collapse(mb_head, M_NOWAIT, 6);
+ if (m == NULL) {
+ m_freem(mb_head);
+ continue;
+ }
+ }
+
+ bus_dmamap_load_mbuf(sc->tx_dma_tag, sc->tx_dma_map,
+ mb_head, llan_send_packet, sc, 0);
+ bus_dmamap_unload(sc->tx_dma_tag, sc->tx_dma_map);
+ m_freem(mb_head);
+ }
+}
+
+static void
+llan_start(struct ifnet *ifp)
+{
+ struct llan_softc *sc = ifp->if_softc;
+
+ mtx_lock(&sc->io_lock);
+ llan_start_locked(ifp);
+ mtx_unlock(&sc->io_lock);
+}
+
+static int
+llan_set_multicast(struct llan_softc *sc)
+{
+ struct ifnet *ifp = sc->ifp;
+ struct ifmultiaddr *inm;
+ uint64_t macaddr;
+
+ mtx_assert(&sc->io_lock, MA_OWNED);
+
+ phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_CLEAR_MULTICAST, 0);
+
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(inm, &ifp->if_multiaddrs, ifma_link) {
+ if (inm->ifma_addr->sa_family != AF_LINK)
+ continue;
+
+ memcpy((uint8_t *)&macaddr + 2,
+ LLADDR((struct sockaddr_dl *)inm->ifma_addr), 6);
+ phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_ADD_MULTICAST,
+ macaddr);
+ }
+ if_maddr_runlock(ifp);
+
+ return (0);
+}
+
+static int
+llan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ int err = 0;
+ struct llan_softc *sc = ifp->if_softc;
+
+ switch (cmd) {
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ mtx_lock(&sc->io_lock);
+ if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ llan_set_multicast(sc);
+ mtx_unlock(&sc->io_lock);
+ break;
+ case SIOCSIFFLAGS:
+ default:
+ err = ether_ioctl(ifp, cmd, data);
+ break;
+ }
+
+ return (err);
+}
+
View
33 usr.sbin/freebsd-update/freebsd-update.sh