Date: Wed, 16 Oct 2013 10:26:35 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r256616 - in projects/camlock: cddl/contrib/opensolaris/lib/libdtrace/common cddl/lib/libdtrace sbin/gvinum sys/amd64/vmm sys/cddl/contrib/opensolaris/uts/common/dtrace sys/cddl/contrib... Message-ID: <201310161026.r9GAQZ5k037416@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Wed Oct 16 10:26:34 2013 New Revision: 256616 URL: http://svnweb.freebsd.org/changeset/base/256616 Log: MFC @ r256615 Added: projects/camlock/sys/dev/etherswitch/arswitch/arswitch_9340.c - copied unchanged from r256615, head/sys/dev/etherswitch/arswitch/arswitch_9340.c projects/camlock/sys/dev/etherswitch/arswitch/arswitch_9340.h - copied unchanged from r256615, head/sys/dev/etherswitch/arswitch/arswitch_9340.h Modified: projects/camlock/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c projects/camlock/cddl/lib/libdtrace/psinfo.d projects/camlock/sbin/gvinum/gvinum.c projects/camlock/sys/amd64/vmm/vmm_dev.c projects/camlock/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c projects/camlock/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h projects/camlock/sys/cddl/dev/dtrace/dtrace_sysctl.c projects/camlock/sys/conf/files projects/camlock/sys/dev/etherswitch/arswitch/arswitch.c projects/camlock/sys/dev/etherswitch/arswitch/arswitch_vlans.c projects/camlock/sys/dev/etherswitch/arswitch/arswitchvar.h projects/camlock/sys/kern/subr_taskqueue.c projects/camlock/sys/mips/atheros/ar71xx_spi.c projects/camlock/sys/mips/atheros/if_arge.c projects/camlock/sys/mips/atheros/if_argevar.h projects/camlock/sys/mips/conf/DB120 projects/camlock/sys/mips/conf/DB120.hints projects/camlock/sys/net/flowtable.c projects/camlock/sys/net/radix.h projects/camlock/sys/netinet/sctp_constants.h projects/camlock/sys/netinet/sctp_usrreq.c projects/camlock/sys/powerpc/aim/interrupt.c projects/camlock/sys/powerpc/powermac/ata_kauai.c projects/camlock/sys/powerpc/powermac/ata_macio.c projects/camlock/sys/sys/_task.h projects/camlock/sys/sys/taskqueue.h projects/camlock/usr.bin/uname/uname.1 projects/camlock/usr.bin/uname/uname.c projects/camlock/usr.sbin/bsdinstall/scripts/zfsboot projects/camlock/usr.sbin/freebsd-update/freebsd-update.sh projects/camlock/usr.sbin/ppp/mppe.c Directory Properties: projects/camlock/ (props changed) projects/camlock/cddl/ (props changed) projects/camlock/cddl/contrib/opensolaris/ (props changed) projects/camlock/sbin/ (props changed) projects/camlock/sys/ (props changed) projects/camlock/sys/amd64/vmm/ (props changed) projects/camlock/sys/cddl/contrib/opensolaris/ (props changed) projects/camlock/sys/conf/ (props changed) Modified: projects/camlock/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c ============================================================================== --- projects/camlock/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c Wed Oct 16 10:26:34 2013 (r256616) @@ -311,6 +311,10 @@ static const dt_ident_t _dtrace_globals[ &dt_idops_func, "void(@)" }, { "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "uintptr_t *(void *, size_t)" }, +#if !defined(sun) +{ "memstr", DT_IDENT_FUNC, 0, DIF_SUBR_MEMSTR, DT_ATTR_STABCMN, DT_VERS_1_0, + &dt_idops_func, "string(void *, char, size_t)" }, +#endif { "min", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MIN, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "void(@)" }, { "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN, Modified: projects/camlock/cddl/lib/libdtrace/psinfo.d ============================================================================== --- projects/camlock/cddl/lib/libdtrace/psinfo.d Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/cddl/lib/libdtrace/psinfo.d Wed Oct 16 10:26:34 2013 (r256616) @@ -57,7 +57,8 @@ translator psinfo_t < struct proc *T > { pr_gid = T->p_ucred->cr_rgid; pr_egid = T->p_ucred->cr_groups[0]; pr_addr = 0; - pr_psargs = stringof(T->p_args->ar_args); + pr_psargs = (T->p_args->ar_args == 0) ? "" : + memstr(T->p_args->ar_args, ' ', T->p_args->ar_length); pr_arglen = T->p_args->ar_length; pr_jailid = T->p_ucred->cr_prison->pr_id; }; Modified: projects/camlock/sbin/gvinum/gvinum.c ============================================================================== --- projects/camlock/sbin/gvinum/gvinum.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sbin/gvinum/gvinum.c Wed Oct 16 10:26:34 2013 (r256616) @@ -421,6 +421,7 @@ create_drive(char *device) const char *errstr; char *drivename, *dname; int drives, i, flags, volumes, subdisks, plexes; + int found = 0; flags = plexes = subdisks = volumes = 0; drives = 1; @@ -448,10 +449,8 @@ create_drive(char *device) errstr = gctl_issue(req); if (errstr != NULL) { warnx("error creating drive: %s", errstr); - gctl_free(req); - return (NULL); + drivename = NULL; } else { - gctl_free(req); /* XXX: This is needed because we have to make sure the drives * are created before we return. */ /* Loop until it's in the config. */ @@ -461,14 +460,18 @@ create_drive(char *device) /* If we got a different name, quit. */ if (dname == NULL) continue; - if (strcmp(dname, drivename)) { - free(dname); - return (drivename); - } + if (strcmp(dname, drivename)) + found = 1; free(dname); dname = NULL; + if (found) + break; usleep(100000); /* Sleep for 0.1s */ } + if (found == 0) { + warnx("error creating drive"); + drivename = NULL; + } } gctl_free(req); return (drivename); Modified: projects/camlock/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/camlock/sys/amd64/vmm/vmm_dev.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/amd64/vmm/vmm_dev.c Wed Oct 16 10:26:34 2013 (r256616) @@ -60,7 +60,10 @@ struct vmmdev_softc { struct vm *vm; /* vm instance cookie */ struct cdev *cdev; SLIST_ENTRY(vmmdev_softc) link; + int flags; }; +#define VSC_LINKED 0x01 + static SLIST_HEAD(, vmmdev_softc) head; static struct mtx vmmdev_mtx; @@ -104,7 +107,6 @@ vmmdev_rw(struct cdev *cdev, struct uio static char zerobuf[PAGE_SIZE]; error = 0; - mtx_lock(&vmmdev_mtx); sc = vmmdev_lookup2(cdev); if (sc == NULL) error = ENXIO; @@ -134,8 +136,6 @@ vmmdev_rw(struct cdev *cdev, struct uio vm_gpa_release(cookie); } } - - mtx_unlock(&vmmdev_mtx); return (error); } @@ -379,34 +379,28 @@ vmmdev_mmap_single(struct cdev *cdev, vm int error; struct vmmdev_softc *sc; - mtx_lock(&vmmdev_mtx); - sc = vmmdev_lookup2(cdev); if (sc != NULL && (nprot & PROT_EXEC) == 0) error = vm_get_memobj(sc->vm, *offset, size, offset, object); else error = EINVAL; - mtx_unlock(&vmmdev_mtx); - return (error); } static void -vmmdev_destroy(struct vmmdev_softc *sc, boolean_t unlink) +vmmdev_destroy(void *arg) { - /* - * XXX must stop virtual machine instances that may be still - * running and cleanup their state. - */ - if (sc->cdev) + struct vmmdev_softc *sc = arg; + + if (sc->cdev != NULL) destroy_dev(sc->cdev); - if (sc->vm) + if (sc->vm != NULL) vm_destroy(sc->vm); - if (unlink) { + if ((sc->flags & VSC_LINKED) != 0) { mtx_lock(&vmmdev_mtx); SLIST_REMOVE(&head, sc, vmmdev_softc, link); mtx_unlock(&vmmdev_mtx); @@ -421,27 +415,38 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS) int error; char buf[VM_MAX_NAMELEN]; struct vmmdev_softc *sc; + struct cdev *cdev; strlcpy(buf, "beavis", sizeof(buf)); error = sysctl_handle_string(oidp, buf, sizeof(buf), req); if (error != 0 || req->newptr == NULL) return (error); - /* - * XXX TODO if any process has this device open then fail - */ - mtx_lock(&vmmdev_mtx); sc = vmmdev_lookup(buf); - if (sc == NULL) { + if (sc == NULL || sc->cdev == NULL) { mtx_unlock(&vmmdev_mtx); return (EINVAL); } - sc->cdev->si_drv1 = NULL; + /* + * The 'cdev' will be destroyed asynchronously when 'si_threadcount' + * goes down to 0 so we should not do it again in the callback. + */ + cdev = sc->cdev; + sc->cdev = NULL; mtx_unlock(&vmmdev_mtx); - vmmdev_destroy(sc, TRUE); + /* + * Schedule the 'cdev' to be destroyed: + * + * - any new operations on this 'cdev' will return an error (ENXIO). + * + * - when the 'si_threadcount' dwindles down to zero the 'cdev' will + * be destroyed and the callback will be invoked in a taskqueue + * context. + */ + destroy_dev_sched_cb(cdev, vmmdev_destroy, sc); return (0); } @@ -462,6 +467,7 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS) { int error; struct vm *vm; + struct cdev *cdev; struct vmmdev_softc *sc, *sc2; char buf[VM_MAX_NAMELEN]; @@ -489,22 +495,28 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS) */ mtx_lock(&vmmdev_mtx); sc2 = vmmdev_lookup(buf); - if (sc2 == NULL) + if (sc2 == NULL) { SLIST_INSERT_HEAD(&head, sc, link); + sc->flags |= VSC_LINKED; + } mtx_unlock(&vmmdev_mtx); if (sc2 != NULL) { - vmmdev_destroy(sc, FALSE); + vmmdev_destroy(sc); return (EEXIST); } - error = make_dev_p(MAKEDEV_CHECKNAME, &sc->cdev, &vmmdevsw, NULL, + error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmdevsw, NULL, UID_ROOT, GID_WHEEL, 0600, "vmm/%s", buf); if (error != 0) { - vmmdev_destroy(sc, TRUE); + vmmdev_destroy(sc); return (error); } + + mtx_lock(&vmmdev_mtx); + sc->cdev = cdev; sc->cdev->si_drv1 = sc; + mtx_unlock(&vmmdev_mtx); return (0); } Modified: projects/camlock/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c ============================================================================== --- projects/camlock/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Wed Oct 16 10:26:34 2013 (r256616) @@ -185,6 +185,9 @@ hrtime_t dtrace_deadman_interval = NANOS hrtime_t dtrace_deadman_timeout = (hrtime_t)10 * NANOSEC; hrtime_t dtrace_deadman_user = (hrtime_t)30 * NANOSEC; hrtime_t dtrace_unregister_defunct_reap = (hrtime_t)60 * NANOSEC; +#if !defined(sun) +int dtrace_memstr_max = 4096; +#endif /* * DTrace External Variables @@ -4920,6 +4923,45 @@ inetout: regs[rd] = (uintptr_t)end + 1; break; } +#if !defined(sun) + case DIF_SUBR_MEMSTR: { + char *str = (char *)mstate->dtms_scratch_ptr; + uintptr_t mem = tupregs[0].dttk_value; + char c = tupregs[1].dttk_value; + size_t size = tupregs[2].dttk_value; + uint8_t n; + int i; + + regs[rd] = 0; + + if (size == 0) + break; + + if (!dtrace_canload(mem, size - 1, mstate, vstate)) + break; + + if (!DTRACE_INSCRATCH(mstate, size)) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); + break; + } + + if (dtrace_memstr_max != 0 && size > dtrace_memstr_max) { + *flags |= CPU_DTRACE_ILLOP; + break; + } + + for (i = 0; i < size - 1; i++) { + n = dtrace_load8(mem++); + str[i] = (n == 0) ? c : n; + } + str[size - 1] = 0; + + regs[rd] = (uintptr_t)str; + mstate->dtms_scratch_ptr += size; + break; + } +#endif + case DIF_SUBR_TYPEREF: { uintptr_t size = 4 * sizeof(uintptr_t); uintptr_t *typeref = (uintptr_t *) P2ROUNDUP(mstate->dtms_scratch_ptr, sizeof(uintptr_t)); @@ -9102,6 +9144,9 @@ dtrace_difo_validate_helper(dtrace_difo_ subr == DIF_SUBR_NTOHL || subr == DIF_SUBR_NTOHLL || subr == DIF_SUBR_MEMREF || +#if !defined(sun) + subr == DIF_SUBR_MEMSTR || +#endif subr == DIF_SUBR_TYPEREF) break; Modified: projects/camlock/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h ============================================================================== --- projects/camlock/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Wed Oct 16 10:26:34 2013 (r256616) @@ -311,8 +311,9 @@ typedef enum dtrace_probespec { #define DIF_SUBR_SX_SHARED_HELD 48 #define DIF_SUBR_SX_EXCLUSIVE_HELD 49 #define DIF_SUBR_SX_ISEXCLUSIVE 50 +#define DIF_SUBR_MEMSTR 51 -#define DIF_SUBR_MAX 50 /* max subroutine value */ +#define DIF_SUBR_MAX 51 /* max subroutine value */ typedef uint32_t dif_instr_t; Modified: projects/camlock/sys/cddl/dev/dtrace/dtrace_sysctl.c ============================================================================== --- projects/camlock/sys/cddl/dev/dtrace/dtrace_sysctl.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/cddl/dev/dtrace/dtrace_sysctl.c Wed Oct 16 10:26:34 2013 (r256616) @@ -80,3 +80,5 @@ sysctl_dtrace_providers(SYSCTL_HANDLER_A SYSCTL_PROC(_debug_dtrace, OID_AUTO, providers, CTLTYPE_STRING | CTLFLAG_RD, 0, 0, sysctl_dtrace_providers, "A", ""); +SYSCTL_INT(_debug_dtrace, OID_AUTO, memstr_max, CTLFLAG_RW, &dtrace_memstr_max, + 0, "largest allowed argument to memstr(), 0 indicates no limit"); Modified: projects/camlock/sys/conf/files ============================================================================== --- projects/camlock/sys/conf/files Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/conf/files Wed Oct 16 10:26:34 2013 (r256616) @@ -1380,6 +1380,7 @@ dev/etherswitch/arswitch/arswitch_8216.c dev/etherswitch/arswitch/arswitch_8226.c optional arswitch dev/etherswitch/arswitch/arswitch_8316.c optional arswitch dev/etherswitch/arswitch/arswitch_7240.c optional arswitch +dev/etherswitch/arswitch/arswitch_9340.c optional arswitch dev/etherswitch/arswitch/arswitch_vlans.c optional arswitch dev/etherswitch/etherswitch.c optional etherswitch dev/etherswitch/etherswitch_if.m optional etherswitch Modified: projects/camlock/sys/dev/etherswitch/arswitch/arswitch.c ============================================================================== --- projects/camlock/sys/dev/etherswitch/arswitch/arswitch.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/dev/etherswitch/arswitch/arswitch.c Wed Oct 16 10:26:34 2013 (r256616) @@ -64,6 +64,7 @@ #include <dev/etherswitch/arswitch/arswitch_8216.h> #include <dev/etherswitch/arswitch/arswitch_8226.h> #include <dev/etherswitch/arswitch/arswitch_8316.h> +#include <dev/etherswitch/arswitch/arswitch_9340.h> #include "mdio_if.h" #include "miibus_if.h" @@ -93,23 +94,34 @@ arswitch_probe(device_t dev) if (ar7240_probe(dev) == 0) { chipname = "AR7240"; sc->sc_switchtype = AR8X16_SWITCH_AR7240; + sc->is_internal_switch = 1; + id = 0; + goto done; + } + + /* AR9340 probe */ + if (ar9340_probe(dev) == 0) { + chipname = "AR9340"; + sc->sc_switchtype = AR8X16_SWITCH_AR9340; + sc->is_internal_switch = 1; id = 0; goto done; } /* AR8xxx probe */ id = arswitch_readreg(dev, AR8X16_REG_MASK_CTRL); - switch ((id & AR8X16_MASK_CTRL_VER_MASK) >> - AR8X16_MASK_CTRL_VER_SHIFT) { - case 1: + switch (id & (AR8X16_MASK_CTRL_VER_MASK | AR8X16_MASK_CTRL_REV_MASK)) { + case 0x0101: chipname = "AR8216"; sc->sc_switchtype = AR8X16_SWITCH_AR8216; break; - case 2: + case 0x0201: chipname = "AR8226"; sc->sc_switchtype = AR8X16_SWITCH_AR8226; break; - case 16: + /* 0x0301 - AR8236 */ + case 0x1000: + case 0x1001: chipname = "AR8316"; sc->sc_switchtype = AR8X16_SWITCH_AR8316; break; @@ -118,8 +130,8 @@ arswitch_probe(device_t dev) } done: - DPRINTF(dev, "chipname=%s, rev=%02x\n", chipname, - id & AR8X16_MASK_CTRL_REV_MASK); + + DPRINTF(dev, "chipname=%s, id=%08x\n", chipname, id); if (chipname != NULL) { snprintf(desc, sizeof(desc), "Atheros %s Ethernet Switch", @@ -250,6 +262,8 @@ arswitch_attach(device_t dev) */ if (AR8X16_IS_SWITCH(sc, AR7240)) ar7240_attach(sc); + else if (AR8X16_IS_SWITCH(sc, AR9340)) + ar9340_attach(sc); else if (AR8X16_IS_SWITCH(sc, AR8216)) ar8216_attach(sc); else if (AR8X16_IS_SWITCH(sc, AR8226)) @@ -267,6 +281,7 @@ arswitch_attach(device_t dev) sc->phy4cpu = 1; sc->is_rgmii = 1; sc->is_gmii = 0; + sc->is_mii = 0; (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "numphys", &sc->numphys); @@ -276,6 +291,8 @@ arswitch_attach(device_t dev) "is_rgmii", &sc->is_rgmii); (void) resource_int_value(device_get_name(dev), device_get_unit(dev), "is_gmii", &sc->is_gmii); + (void) resource_int_value(device_get_name(dev), device_get_unit(dev), + "is_mii", &sc->is_mii); if (sc->numphys > AR8X16_NUM_PHYS) sc->numphys = AR8X16_NUM_PHYS; @@ -284,6 +301,10 @@ arswitch_attach(device_t dev) if (arswitch_reset(dev)) return (ENXIO); + err = sc->hal.arswitch_hw_setup(sc); + if (err != 0) + return (err); + err = sc->hal.arswitch_hw_global_setup(sc); if (err != 0) return (err); @@ -303,10 +324,6 @@ arswitch_attach(device_t dev) if (err != 0) return (err); - err = sc->hal.arswitch_hw_setup(sc); - if (err != 0) - return (err); - bus_generic_probe(dev); bus_enumerate_hinted_children(dev); err = bus_generic_attach(dev); @@ -435,7 +452,7 @@ arswitch_miipollstat(struct arswitch_sof AR8X16_REG_PORT_STS(arswitch_portforphy(i))); #if 0 DPRINTF(sc->sc_dev, "p[%d]=%b\n", - arge_portforphy(i), + i, portstatus, "\20\3TXMAC\4RXMAC\5TXFLOW\6RXFLOW\7" "DUPLEX\11LINK_UP\12LINK_AUTO\13LINK_PAUSE"); Copied: projects/camlock/sys/dev/etherswitch/arswitch/arswitch_9340.c (from r256615, head/sys/dev/etherswitch/arswitch/arswitch_9340.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/camlock/sys/dev/etherswitch/arswitch/arswitch_9340.c Wed Oct 16 10:26:34 2013 (r256616, copy of r256615, head/sys/dev/etherswitch/arswitch/arswitch_9340.c) @@ -0,0 +1,203 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org> + * 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. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/errno.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/socket.h> +#include <sys/sockio.h> +#include <sys/sysctl.h> +#include <sys/systm.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 <machine/bus.h> +#include <dev/iicbus/iic.h> +#include <dev/iicbus/iiconf.h> +#include <dev/iicbus/iicbus.h> +#include <dev/mii/mii.h> +#include <dev/mii/miivar.h> +#include <dev/etherswitch/mdio.h> + +#include <dev/etherswitch/etherswitch.h> + +#include <dev/etherswitch/arswitch/arswitchreg.h> +#include <dev/etherswitch/arswitch/arswitchvar.h> +#include <dev/etherswitch/arswitch/arswitch_reg.h> +#include <dev/etherswitch/arswitch/arswitch_phy.h> /* XXX for probe */ +#include <dev/etherswitch/arswitch/arswitch_9340.h> + +#include "mdio_if.h" +#include "miibus_if.h" +#include "etherswitch_if.h" + +/* + * AR9340 specific functions + */ +static int +ar9340_hw_setup(struct arswitch_softc *sc) +{ + + return (0); +} + +/* + * Initialise other global values for the AR9340. + */ +static int +ar9340_hw_global_setup(struct arswitch_softc *sc) +{ + + /* Enable CPU port; disable mirror port */ + arswitch_writereg(sc->sc_dev, AR8X16_REG_CPU_PORT, + AR8X16_CPU_PORT_EN | AR8X16_CPU_MIRROR_DIS); + + /* Setup TAG priority mapping */ + arswitch_writereg(sc->sc_dev, AR8X16_REG_TAG_PRIO, 0xfa50); + + /* Enable aging, MAC replacing */ + arswitch_writereg(sc->sc_dev, AR934X_REG_AT_CTRL, + 0x2b /* 5 min age time */ | + AR934X_AT_CTRL_AGE_EN | + AR934X_AT_CTRL_LEARN_CHANGE); + + /* Enable ARP frame acknowledge */ + arswitch_modifyreg(sc->sc_dev, AR934X_REG_QM_CTRL, + AR934X_QM_CTRL_ARP_EN, AR934X_QM_CTRL_ARP_EN); + + /* Enable Broadcast frames transmitted to the CPU */ + arswitch_modifyreg(sc->sc_dev, AR934X_REG_FLOOD_MASK, + AR934X_FLOOD_MASK_BC_DP(0), + AR934X_FLOOD_MASK_BC_DP(0)); + arswitch_modifyreg(sc->sc_dev, AR934X_REG_FLOOD_MASK, + AR934X_FLOOD_MASK_MC_DP(0), + AR934X_FLOOD_MASK_MC_DP(0)); + + /* Enable MIB counters */ + arswitch_modifyreg(sc->sc_dev, AR8X16_REG_MIB_FUNC0, + AR934X_MIB_ENABLE, AR934X_MIB_ENABLE); + + /* Setup MTU */ + arswitch_modifyreg(sc->sc_dev, AR8X16_REG_GLOBAL_CTRL, + AR7240_GLOBAL_CTRL_MTU_MASK, + SM(1536, AR7240_GLOBAL_CTRL_MTU_MASK)); + + /* Service Tag */ + arswitch_modifyreg(sc->sc_dev, AR8X16_REG_SERVICE_TAG, + AR8X16_SERVICE_TAG_MASK, 0); + + /* Settle time */ + DELAY(1000); + + /* + * Check PHY mode bits. + * + * This dictates whether the connected port is to be wired + * up via GMII or MII. I'm not sure why - this is an internal + * wiring issue. + */ + if (sc->is_gmii) { + device_printf(sc->sc_dev, "%s: GMII\n", __func__); + arswitch_modifyreg(sc->sc_dev, AR934X_REG_OPER_MODE0, + AR934X_OPER_MODE0_MAC_GMII_EN, + AR934X_OPER_MODE0_MAC_GMII_EN); + } else if (sc->is_mii) { + device_printf(sc->sc_dev, "%s: MII\n", __func__); + arswitch_modifyreg(sc->sc_dev, AR934X_REG_OPER_MODE0, + AR934X_OPER_MODE0_PHY_MII_EN, + AR934X_OPER_MODE0_PHY_MII_EN); + } else { + device_printf(sc->sc_dev, "%s: need is_gmii or is_mii set\n", + __func__); + return (ENXIO); + } + + /* + * Whether to connect PHY 4 via MII (ie a switch port) or + * treat it as a CPU port. + */ + if (sc->phy4cpu) { + device_printf(sc->sc_dev, "%s: PHY4 - CPU\n", __func__); + arswitch_modifyreg(sc->sc_dev, AR934X_REG_OPER_MODE1, + AR934X_REG_OPER_MODE1_PHY4_MII_EN, + AR934X_REG_OPER_MODE1_PHY4_MII_EN); + sc->info.es_nports = 4; + } else { + device_printf(sc->sc_dev, "%s: PHY4 - Local\n", __func__); + sc->info.es_nports = 5; + } + + /* Settle time */ + DELAY(1000); + + return (0); +} + +/* + * The AR9340 switch probes (almost) the same as the AR7240 on-chip switch. + * + * However, the support is slightly different. + * + * So instead of checking the PHY revision or mask register contents, + * we simply fall back to a hint check. + */ +int +ar9340_probe(device_t dev) +{ + int is_9340 = 0; + + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + "is_9340", &is_9340) != 0) + return (ENXIO); + + if (is_9340 == 0) + return (ENXIO); + + return (0); +} + +void +ar9340_attach(struct arswitch_softc *sc) +{ + + sc->hal.arswitch_hw_setup = ar9340_hw_setup; + sc->hal.arswitch_hw_global_setup = ar9340_hw_global_setup; + + /* Set the switch vlan capabilities. */ + sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q | + ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG; + sc->info.es_nvlangroups = AR8X16_MAX_VLANS; +} Copied: projects/camlock/sys/dev/etherswitch/arswitch/arswitch_9340.h (from r256615, head/sys/dev/etherswitch/arswitch/arswitch_9340.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/camlock/sys/dev/etherswitch/arswitch/arswitch_9340.h Wed Oct 16 10:26:34 2013 (r256616, copy of r256615, head/sys/dev/etherswitch/arswitch/arswitch_9340.h) @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * Copyright (c) 2031 Adrian Chadd <adrian@FreeBSD.org> + * 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. + * + * $FreeBSD$ + */ +#ifndef __ARSWITCH_9340_H__ +#define __ARSWITCH_9340_H__ + +extern int ar9340_probe(device_t dev); +extern void ar9340_attach(struct arswitch_softc *sc); + +#endif /* __ARSWITCH_9340_H__ */ Modified: projects/camlock/sys/dev/etherswitch/arswitch/arswitch_vlans.c ============================================================================== --- projects/camlock/sys/dev/etherswitch/arswitch/arswitch_vlans.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/dev/etherswitch/arswitch/arswitch_vlans.c Wed Oct 16 10:26:34 2013 (r256616) @@ -49,6 +49,12 @@ #include "miibus_if.h" #include "etherswitch_if.h" +/* + * XXX TODO: teach about the AR933x SoC switch + * XXX TODO: teach about the AR934x SoC switch + * XXX TODO: teach about the AR8327 external switch + */ + static int arswitch_vlan_op(struct arswitch_softc *sc, uint32_t op, uint32_t vid, uint32_t data) Modified: projects/camlock/sys/dev/etherswitch/arswitch/arswitchvar.h ============================================================================== --- projects/camlock/sys/dev/etherswitch/arswitch/arswitchvar.h Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/dev/etherswitch/arswitch/arswitchvar.h Wed Oct 16 10:26:34 2013 (r256616) @@ -34,6 +34,7 @@ typedef enum { AR8X16_SWITCH_AR8216, AR8X16_SWITCH_AR8226, AR8X16_SWITCH_AR8316, + AR8X16_SWITCH_AR9340, } ar8x16_switch_type; /* @@ -49,7 +50,9 @@ struct arswitch_softc { int numphys; /* PHYs we manage */ int is_rgmii; /* PHY mode is RGMII (XXX which PHY?) */ int is_gmii; /* PHY mode is GMII (XXX which PHY?) */ + int is_mii; /* PHY mode is MII (XXX which PHY?) */ int page; + int is_internal_switch; ar8x16_switch_type sc_switchtype; char *ifname[AR8X16_NUM_PHYS]; device_t miibus[AR8X16_NUM_PHYS]; Modified: projects/camlock/sys/kern/subr_taskqueue.c ============================================================================== --- projects/camlock/sys/kern/subr_taskqueue.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/kern/subr_taskqueue.c Wed Oct 16 10:26:34 2013 (r256616) @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include <sys/taskqueue.h> #include <sys/unistd.h> #include <machine/stdarg.h> +#include <net/vnet.h> static MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues"); static void *taskqueue_giant_ih; @@ -339,7 +340,9 @@ taskqueue_run_locked(struct taskqueue *q tb.tb_running = task; TQ_UNLOCK(queue); + CURVNET_SET(task->ta_vnet); task->ta_func(task->ta_context, pending); + CURVNET_RESTORE(); TQ_LOCK(queue); tb.tb_running = NULL; Modified: projects/camlock/sys/mips/atheros/ar71xx_spi.c ============================================================================== --- projects/camlock/sys/mips/atheros/ar71xx_spi.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/mips/atheros/ar71xx_spi.c Wed Oct 16 10:26:34 2013 (r256616) @@ -62,8 +62,16 @@ __FBSDID("$FreeBSD$"); /* * register space access macros */ -#define SPI_WRITE(sc, reg, val) do { \ - bus_write_4(sc->sc_mem_res, (reg), (val)); \ + +#define SPI_BARRIER_WRITE(sc) bus_barrier((sc)->sc_mem_res, 0, 0, \ + BUS_SPACE_BARRIER_WRITE) +#define SPI_BARRIER_READ(sc) bus_barrier((sc)->sc_mem_res, 0, 0, \ + BUS_SPACE_BARRIER_READ) +#define SPI_BARRIER_RW(sc) bus_barrier((sc)->sc_mem_res, 0, 0, \ + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) + +#define SPI_WRITE(sc, reg, val) do { \ + bus_write_4(sc->sc_mem_res, (reg), (val)); \ } while (0) #define SPI_READ(sc, reg) bus_read_4(sc->sc_mem_res, (reg)) @@ -102,12 +110,30 @@ ar71xx_spi_attach(device_t dev) return (ENXIO); } - SPI_WRITE(sc, AR71XX_SPI_FS, 1); + + /* Flush out read before reading the control register */ + SPI_BARRIER_WRITE(sc); + sc->sc_reg_ctrl = SPI_READ(sc, AR71XX_SPI_CTRL); + + /* + * XXX TODO: document what the SPI control register does. + */ SPI_WRITE(sc, AR71XX_SPI_CTRL, 0x43); + + /* + * Ensure the config register write has gone out before configuring + * the chip select mask. + */ + SPI_BARRIER_WRITE(sc); SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CSMASK); + /* + * .. and ensure the write has gone out before continuing. + */ + SPI_BARRIER_WRITE(sc); + device_add_child(dev, "spibus", -1); return (bus_generic_attach(dev)); } @@ -121,7 +147,15 @@ ar71xx_spi_chip_activate(struct ar71xx_s */ ioctrl &= ~(SPI_IO_CTRL_CS0 << cs); + /* + * Make sure any other writes have gone out to the + * device before changing the chip select line; + * then ensure that it has made it out to the device + * before continuing. + */ + SPI_BARRIER_WRITE(sc); SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, ioctrl); + SPI_BARRIER_WRITE(sc); } static void @@ -150,14 +184,18 @@ ar71xx_spi_txrx(struct ar71xx_spi_softc iod = ioctrl | SPI_IO_CTRL_DO; else iod = ioctrl & ~SPI_IO_CTRL_DO; + SPI_BARRIER_WRITE(sc); SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, iod); + SPI_BARRIER_WRITE(sc); SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, iod | SPI_IO_CTRL_CLK); } /* * Provide falling edge for connected device by clear clock bit. */ + SPI_BARRIER_WRITE(sc); SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, iod); + SPI_BARRIER_WRITE(sc); rds = SPI_READ(sc, AR71XX_SPI_RDS); return (rds & 0xff); @@ -206,8 +244,25 @@ ar71xx_spi_detach(device_t dev) { struct ar71xx_spi_softc *sc = device_get_softc(dev); + /* + * Ensure any other writes to the device are finished + * before we tear down the SPI device. + */ + SPI_BARRIER_WRITE(sc); + + /* + * Restore the control register; ensure it has hit the + * hardware before continuing. + */ SPI_WRITE(sc, AR71XX_SPI_CTRL, sc->sc_reg_ctrl); + SPI_BARRIER_WRITE(sc); + + /* + * And now, put the flash back into mapped IO mode and + * ensure _that_ has completed before we finish up. + */ SPI_WRITE(sc, AR71XX_SPI_FS, 0); + SPI_BARRIER_WRITE(sc); if (sc->sc_mem_res) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); Modified: projects/camlock/sys/mips/atheros/if_arge.c ============================================================================== --- projects/camlock/sys/mips/atheros/if_arge.c Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/mips/atheros/if_arge.c Wed Oct 16 10:26:34 2013 (r256616) @@ -90,6 +90,7 @@ MODULE_VERSION(arge, 1); #include "miibus_if.h" #include <mips/atheros/ar71xxreg.h> +#include <mips/atheros/ar934xreg.h> /* XXX tsk! */ #include <mips/atheros/if_argevar.h> #include <mips/atheros/ar71xx_setup.h> #include <mips/atheros/ar71xx_cpudef.h> @@ -298,17 +299,38 @@ static void arge_reset_mac(struct arge_softc *sc) { uint32_t reg; + uint32_t reset_reg; /* Step 1. Soft-reset MAC */ ARGE_SET_BITS(sc, AR71XX_MAC_CFG1, MAC_CFG1_SOFT_RESET); DELAY(20); /* Step 2. Punt the MAC core from the central reset register */ - ar71xx_device_stop(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC : - RST_RESET_GE1_MAC); + /* + * XXX TODO: migrate this (and other) chip specific stuff into + * a chipdef method. + */ + if (sc->arge_mac_unit == 0) { + reset_reg = RST_RESET_GE0_MAC; + } else { + reset_reg = RST_RESET_GE1_MAC; + } + + /* + * AR934x (and later) also needs the MDIO block reset. + */ + if (ar71xx_soc == AR71XX_SOC_AR9341 || + ar71xx_soc == AR71XX_SOC_AR9342 || + ar71xx_soc == AR71XX_SOC_AR9344) { + if (sc->arge_mac_unit == 0) { + reset_reg |= AR934X_RESET_GE0_MDIO; + } else { + reset_reg |= AR934X_RESET_GE1_MDIO; + } + } + ar71xx_device_stop(reset_reg); DELAY(100); - ar71xx_device_start(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC : - RST_RESET_GE1_MAC); + ar71xx_device_start(reset_reg); /* Step 3. Reconfigure MAC block */ ARGE_WRITE(sc, AR71XX_MAC_CFG1, @@ -322,14 +344,46 @@ arge_reset_mac(struct arge_softc *sc) ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536); } +/* + * Fetch the MDIO bus clock rate. + * + * For now, the default is DIV_28 for everything + * bar AR934x, which will be DIV_42. + * + * It will definitely need updating to take into account + * the MDIO bus core clock rate and the target clock + * rate for the chip. + */ +static uint32_t +arge_fetch_mdiobus_clock_rate(struct arge_softc *sc) +{ + + switch (ar71xx_soc) { + case AR71XX_SOC_AR9341: + case AR71XX_SOC_AR9342: + case AR71XX_SOC_AR9344: + return (MAC_MII_CFG_CLOCK_DIV_42); + default: + return (MAC_MII_CFG_CLOCK_DIV_28); + } +} + static void arge_reset_miibus(struct arge_softc *sc) { + uint32_t mdio_div; - /* Reset MII bus */ - ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET); + mdio_div = arge_fetch_mdiobus_clock_rate(sc); + + /* + * XXX AR934x and later; should we be also resetting the + * MDIO block(s) using the reset register block? + */ + + /* Reset MII bus; program in the default divisor */ + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET | mdio_div); DELAY(100); - ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28); + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, mdio_div); DELAY(100); } @@ -588,9 +642,13 @@ arge_attach(device_t dev) case AR71XX_SOC_AR7242: case AR71XX_SOC_AR9330: case AR71XX_SOC_AR9331: + case AR71XX_SOC_AR9341: + case AR71XX_SOC_AR9342: + case AR71XX_SOC_AR9344: ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0010ffff); ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x015500aa); break; + /* AR71xx, AR913x */ default: ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0fff0000); ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x00001fff); @@ -917,12 +975,16 @@ arge_set_pll(struct arge_softc *sc, int case AR71XX_SOC_AR7242: case AR71XX_SOC_AR9330: case AR71XX_SOC_AR9331: + case AR71XX_SOC_AR9341: + case AR71XX_SOC_AR9342: + case AR71XX_SOC_AR9344: fifo_tx = 0x01f00140; break; case AR71XX_SOC_AR9130: case AR71XX_SOC_AR9132: fifo_tx = 0x00780fff; break; + /* AR71xx */ default: fifo_tx = 0x008001ff; } Modified: projects/camlock/sys/mips/atheros/if_argevar.h ============================================================================== --- projects/camlock/sys/mips/atheros/if_argevar.h Wed Oct 16 10:11:30 2013 (r256615) +++ projects/camlock/sys/mips/atheros/if_argevar.h Wed Oct 16 10:26:34 2013 (r256616) @@ -55,10 +55,17 @@ /* * register space access macros */ +#define ARGE_BARRIER_READ(sc) bus_barrier(sc->arge_res, 0, 0, \ + BUS_SPACE_BARRIER_READ) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310161026.r9GAQZ5k037416>