summaryrefslogtreecommitdiffstats
path: root/freebsd/sys
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-20 15:53:03 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:39 +0200
commit18fa92c2dcc6c52e0bf27d214d80f0c25a89b47d (patch)
treea3020ac5b1f366f2f0920941b589808e435dbcee /freebsd/sys
parentUpdate to FreeBSD head 2017-12-01 (diff)
downloadrtems-libbsd-18fa92c2dcc6c52e0bf27d214d80f0c25a89b47d.tar.bz2
Update to FreeBSD head 2018-02-01
Git mirror commit d079ae0442af8fa3cfd6d7ede190d04e64a2c0d4. Update #3472.
Diffstat (limited to 'freebsd/sys')
-rwxr-xr-xfreebsd/sys/arm/lpc/if_lpe.c1414
-rw-r--r--freebsd/sys/arm/lpc/if_lpereg.h210
-rwxr-xr-xfreebsd/sys/arm/lpc/lpc_pwr.c141
-rw-r--r--freebsd/sys/arm/lpc/lpcreg.h667
-rw-r--r--freebsd/sys/arm/lpc/lpcvar.h71
-rw-r--r--freebsd/sys/cam/cam_ccb.h7
-rw-r--r--freebsd/sys/cam/cam_periph.h10
-rw-r--r--freebsd/sys/cam/cam_xpt.h18
-rw-r--r--freebsd/sys/cam/mmc/mmc.h2
-rw-r--r--freebsd/sys/cam/mmc/mmc_all.h2
-rw-r--r--freebsd/sys/cam/nvme/nvme_all.h2
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c4
-rw-r--r--freebsd/sys/dev/cadence/if_cgem.c2
-rw-r--r--freebsd/sys/dev/e1000/e1000_82543.c2
-rw-r--r--freebsd/sys/dev/e1000/e1000_82575.h4
-rw-r--r--freebsd/sys/dev/e1000/e1000_api.c11
-rw-r--r--freebsd/sys/dev/e1000/e1000_hw.h9
-rw-r--r--freebsd/sys/dev/e1000/e1000_ich8lan.c11
-rw-r--r--freebsd/sys/dev/e1000/e1000_ich8lan.h3
-rw-r--r--freebsd/sys/dev/e1000/e1000_regs.h2
-rw-r--r--freebsd/sys/dev/e1000/em_txrx.c2
-rw-r--r--freebsd/sys/dev/e1000/if_em.c20
-rw-r--r--freebsd/sys/dev/e1000/if_em.h2
-rw-r--r--freebsd/sys/dev/e1000/igb_txrx.c6
-rw-r--r--freebsd/sys/dev/fdt/fdt_common.c14
-rw-r--r--freebsd/sys/dev/mmc/mmc.c9
-rw-r--r--freebsd/sys/dev/mmc/mmcsd.c32
-rw-r--r--freebsd/sys/dev/ofw/ofw_bus_subr.c7
-rw-r--r--freebsd/sys/dev/ofw/ofw_fdt.c23
-rw-r--r--freebsd/sys/dev/pci/pci.c34
-rw-r--r--freebsd/sys/dev/pci/pci_pci.c6
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn.c6
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h1
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.c16
-rw-r--r--freebsd/sys/dev/smc/if_smc.c2
-rw-r--r--freebsd/sys/dev/usb/controller/dwc_otg_fdt.c3
-rw-r--r--freebsd/sys/dev/usb/controller/ehci.c4
-rw-r--r--freebsd/sys/dev/usb/controller/ohci.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_cdce.c3
-rw-r--r--freebsd/sys/dev/usb/net/if_mos.c2
-rw-r--r--freebsd/sys/dev/usb/quirk/usb_quirk.c1
-rw-r--r--freebsd/sys/dev/usb/serial/u3g.c52
-rw-r--r--freebsd/sys/dev/usb/serial/umodem.c12
-rw-r--r--freebsd/sys/dev/usb/storage/umass.c3
-rw-r--r--freebsd/sys/dev/usb/usb_dev.c14
-rw-r--r--freebsd/sys/dev/usb/usb_device.c134
-rw-r--r--freebsd/sys/dev/usb/wlan/if_rum.c7
-rw-r--r--freebsd/sys/dev/usb/wlan/if_run.c7
-rw-r--r--freebsd/sys/dev/usb/wlan/if_uath.c2
-rw-r--r--freebsd/sys/fs/devfs/devfs_vnops.c26
-rw-r--r--freebsd/sys/isa/isavar.h4
-rw-r--r--freebsd/sys/kern/init_main.c13
-rw-r--r--freebsd/sys/kern/kern_mbuf.c7
-rw-r--r--freebsd/sys/kern/kern_synch.c12
-rw-r--r--freebsd/sys/kern/subr_bus.c69
-rw-r--r--freebsd/sys/kern/subr_hash.c6
-rw-r--r--freebsd/sys/kern/subr_prf.c3
-rw-r--r--freebsd/sys/kern/subr_sleepqueue.c3
-rw-r--r--freebsd/sys/kern/sys_generic.c2
-rw-r--r--freebsd/sys/kern/sys_socket.c2
-rw-r--r--freebsd/sys/kern/uipc_usrreq.c4
-rw-r--r--freebsd/sys/net/altq/altq_hfsc.h2
-rw-r--r--freebsd/sys/net/bpf.c11
-rw-r--r--freebsd/sys/net/ieee8023ad_lacp.c4
-rw-r--r--freebsd/sys/net/if_clone.c14
-rw-r--r--freebsd/sys/net/if_ethersubr.c2
-rw-r--r--freebsd/sys/net/if_gif.c2
-rw-r--r--freebsd/sys/net/if_lagg.c2
-rw-r--r--freebsd/sys/net/iflib.h12
-rw-r--r--freebsd/sys/net/pfvar.h1
-rw-r--r--freebsd/sys/net/route.c14
-rw-r--r--freebsd/sys/net/route.h13
-rw-r--r--freebsd/sys/net/rtsock.c22
-rw-r--r--freebsd/sys/net/sff8472.h12
-rw-r--r--freebsd/sys/net80211/ieee80211_ht.c2
-rw-r--r--freebsd/sys/net80211/ieee80211_node.c7
-rw-r--r--freebsd/sys/net80211/ieee80211_output.c143
-rw-r--r--freebsd/sys/net80211/ieee80211_proto.c32
-rw-r--r--freebsd/sys/net80211/ieee80211_proto.h1
-rw-r--r--freebsd/sys/net80211/ieee80211_scan_sta.c2
-rw-r--r--freebsd/sys/netinet/icmp6.h2
-rw-r--r--freebsd/sys/netinet/in_pcb.c8
-rw-r--r--freebsd/sys/netinet/ip_mroute.c4
-rw-r--r--freebsd/sys/netinet/ip_output.c7
-rw-r--r--freebsd/sys/netinet/ip_reass.c1
-rw-r--r--freebsd/sys/netinet/libalias/alias_mod.h2
-rw-r--r--freebsd/sys/netinet/libalias/alias_sctp.c641
-rw-r--r--freebsd/sys/netinet/sctp_constants.h33
-rw-r--r--freebsd/sys/netinet/sctp_crc32.c106
-rw-r--r--freebsd/sys/netinet/sctp_crc32.h4
-rw-r--r--freebsd/sys/netinet/sctp_indata.c28
-rw-r--r--freebsd/sys/netinet/sctp_input.c31
-rw-r--r--freebsd/sys/netinet/sctp_input.h2
-rw-r--r--freebsd/sys/netinet/sctp_output.c41
-rw-r--r--freebsd/sys/netinet/sctp_sysctl.c2
-rw-r--r--freebsd/sys/netinet/sctp_uio.h4
-rw-r--r--freebsd/sys/netinet/sctputil.c20
-rw-r--r--freebsd/sys/netinet/tcp_output.c122
-rw-r--r--freebsd/sys/netinet/tcp_timer.c7
-rw-r--r--freebsd/sys/netinet/tcp_timer.h1
-rw-r--r--freebsd/sys/netinet/tcp_var.h1
-rw-r--r--freebsd/sys/netinet6/frag6.c3
-rw-r--r--freebsd/sys/netinet6/icmp6.c4
-rw-r--r--freebsd/sys/netinet6/in6.c2
-rw-r--r--freebsd/sys/netinet6/in6_ifattach.c33
-rw-r--r--freebsd/sys/netinet6/in6_mcast.c3
-rw-r--r--freebsd/sys/netinet6/in6_src.c5
-rw-r--r--freebsd/sys/netinet6/ip6_id.c22
-rw-r--r--freebsd/sys/netinet6/ip6_input.c21
-rw-r--r--freebsd/sys/netinet6/mld6.c3
-rw-r--r--freebsd/sys/netinet6/nd6.c20
-rw-r--r--freebsd/sys/netinet6/nd6.h2
-rw-r--r--freebsd/sys/netinet6/nd6_nbr.c19
-rw-r--r--freebsd/sys/netinet6/nd6_rtr.c8
-rw-r--r--freebsd/sys/netinet6/raw_ip6.c10
-rw-r--r--freebsd/sys/netinet6/scope6.c2
-rw-r--r--freebsd/sys/netinet6/sctp6_usrreq.c8
-rw-r--r--freebsd/sys/netinet6/udp6_usrreq.c6
-rw-r--r--freebsd/sys/netipsec/key.c24
-rw-r--r--freebsd/sys/netipsec/xform_ah.c77
-rw-r--r--freebsd/sys/netipsec/xform_esp.c2
-rw-r--r--freebsd/sys/netipsec/xform_ipcomp.c3
-rw-r--r--freebsd/sys/netpfil/pf/if_pflog.c2
-rw-r--r--freebsd/sys/netpfil/pf/in4_cksum.c2
-rw-r--r--freebsd/sys/netpfil/pf/pf.c6
-rw-r--r--freebsd/sys/netpfil/pf/pf.h2
-rw-r--r--freebsd/sys/netpfil/pf/pf_ioctl.c132
-rw-r--r--freebsd/sys/netpfil/pf/pf_norm.c11
-rw-r--r--freebsd/sys/netpfil/pf/pf_osfp.c2
-rw-r--r--freebsd/sys/opencrypto/crypto.c6
-rw-r--r--freebsd/sys/opencrypto/cryptodev.c265
-rw-r--r--freebsd/sys/opencrypto/cryptodev.h9
-rw-r--r--freebsd/sys/opencrypto/cryptosoft.c7
-rw-r--r--freebsd/sys/opencrypto/xform_userland.h2
-rw-r--r--freebsd/sys/powerpc/include/machine/spr.h17
-rw-r--r--freebsd/sys/sys/_domainset.h60
-rw-r--r--freebsd/sys/sys/bus_dma.h10
-rw-r--r--freebsd/sys/sys/capsicum.h2
-rw-r--r--freebsd/sys/sys/conf.h4
-rw-r--r--freebsd/sys/sys/domainset.h102
-rw-r--r--freebsd/sys/sys/gtaskqueue.h4
-rw-r--r--freebsd/sys/sys/kernel.h33
-rw-r--r--freebsd/sys/sys/libkern.h7
-rw-r--r--freebsd/sys/sys/malloc.h44
-rw-r--r--freebsd/sys/sys/mount.h3
-rw-r--r--freebsd/sys/sys/mouse.h3
-rw-r--r--freebsd/sys/sys/nv.h2
-rw-r--r--freebsd/sys/sys/proc.h18
-rw-r--r--freebsd/sys/sys/random.h1
-rw-r--r--freebsd/sys/sys/rman.h2
-rw-r--r--freebsd/sys/sys/sf_buf.h16
-rw-r--r--freebsd/sys/sys/smp.h11
-rw-r--r--freebsd/sys/sys/socketvar.h2
-rw-r--r--freebsd/sys/sys/sysproto.h35
-rw-r--r--freebsd/sys/sys/systm.h16
-rw-r--r--freebsd/sys/sys/tslog.h62
-rw-r--r--freebsd/sys/sys/vmmeter.h9
-rw-r--r--freebsd/sys/sys/watchdog.h8
-rw-r--r--freebsd/sys/vm/uma.h50
-rw-r--r--freebsd/sys/vm/uma_core.c592
-rw-r--r--freebsd/sys/vm/uma_int.h71
-rw-r--r--freebsd/sys/vm/vm.h2
-rw-r--r--freebsd/sys/vm/vm_extern.h7
-rw-r--r--freebsd/sys/x86/include/machine/bus.h1
-rw-r--r--freebsd/sys/x86/pci/pci_bus.c4
165 files changed, 2612 insertions, 3843 deletions
diff --git a/freebsd/sys/arm/lpc/if_lpe.c b/freebsd/sys/arm/lpc/if_lpe.c
deleted file mode 100755
index 99016be3..00000000
--- a/freebsd/sys/arm/lpc/if_lpe.c
+++ /dev/null
@@ -1,1414 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2011 Jakub Wojciech Klama <jceel@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.
- *
- */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/endian.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/rman.h>
-#include <sys/bus.h>
-#include <sys/socket.h>
-#include <machine/bus.h>
-#ifndef __rtems__
-#include <machine/intr.h>
-#endif /* __rtems__ */
-
-#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_var.h>
-
-#include <net/bpf.h>
-
-#ifndef __rtems__
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-#endif /* __rtems__ */
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-#include <arm/lpc/lpcreg.h>
-#include <arm/lpc/lpcvar.h>
-#include <arm/lpc/if_lpereg.h>
-
-#include <rtems/bsd/local/miibus_if.h>
-#ifdef __rtems__
-#include <machine/rtems-bsd-cache.h>
-#endif /* __rtems__ */
-
-#ifdef DEBUG
-#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
- printf(fmt,##args); } while (0)
-#else
-#define debugf(fmt, args...)
-#endif
-
-struct lpe_dmamap_arg {
- bus_addr_t lpe_dma_busaddr;
-};
-
-struct lpe_rxdesc {
- struct mbuf * lpe_rxdesc_mbuf;
-#ifndef __rtems__
- bus_dmamap_t lpe_rxdesc_dmamap;
-#endif /* __rtems__ */
-};
-
-struct lpe_txdesc {
- int lpe_txdesc_first;
- struct mbuf * lpe_txdesc_mbuf;
-#ifndef __rtems__
- bus_dmamap_t lpe_txdesc_dmamap;
-#endif /* __rtems__ */
-};
-
-struct lpe_chain_data {
- bus_dma_tag_t lpe_parent_tag;
- bus_dma_tag_t lpe_tx_ring_tag;
- bus_dmamap_t lpe_tx_ring_map;
- bus_dma_tag_t lpe_tx_status_tag;
- bus_dmamap_t lpe_tx_status_map;
- bus_dma_tag_t lpe_tx_buf_tag;
- bus_dma_tag_t lpe_rx_ring_tag;
- bus_dmamap_t lpe_rx_ring_map;
- bus_dma_tag_t lpe_rx_status_tag;
- bus_dmamap_t lpe_rx_status_map;
- bus_dma_tag_t lpe_rx_buf_tag;
- struct lpe_rxdesc lpe_rx_desc[LPE_RXDESC_NUM];
- struct lpe_txdesc lpe_tx_desc[LPE_TXDESC_NUM];
- int lpe_tx_prod;
- int lpe_tx_last;
- int lpe_tx_used;
-};
-
-struct lpe_ring_data {
- struct lpe_hwdesc * lpe_rx_ring;
- struct lpe_hwstatus * lpe_rx_status;
- bus_addr_t lpe_rx_ring_phys;
- bus_addr_t lpe_rx_status_phys;
- struct lpe_hwdesc * lpe_tx_ring;
- struct lpe_hwstatus * lpe_tx_status;
- bus_addr_t lpe_tx_ring_phys;
- bus_addr_t lpe_tx_status_phys;
-};
-
-struct lpe_softc {
- struct ifnet * lpe_ifp;
- struct mtx lpe_mtx;
-#ifndef __rtems__
- phandle_t lpe_ofw;
-#endif /* __rtems__ */
- device_t lpe_dev;
- device_t lpe_miibus;
- uint8_t lpe_enaddr[6];
- struct resource * lpe_mem_res;
- struct resource * lpe_irq_res;
- void * lpe_intrhand;
- bus_space_tag_t lpe_bst;
- bus_space_handle_t lpe_bsh;
-#define LPE_FLAG_LINK (1 << 0)
- uint32_t lpe_flags;
- int lpe_watchdog_timer;
- struct callout lpe_tick;
- struct lpe_chain_data lpe_cdata;
- struct lpe_ring_data lpe_rdata;
-};
-
-static int lpe_probe(device_t);
-static int lpe_attach(device_t);
-static int lpe_detach(device_t);
-static int lpe_miibus_readreg(device_t, int, int);
-static int lpe_miibus_writereg(device_t, int, int, int);
-static void lpe_miibus_statchg(device_t);
-
-static void lpe_reset(struct lpe_softc *);
-static void lpe_init(void *);
-static void lpe_init_locked(struct lpe_softc *);
-static void lpe_start(struct ifnet *);
-static void lpe_start_locked(struct ifnet *);
-static void lpe_stop(struct lpe_softc *);
-static void lpe_stop_locked(struct lpe_softc *);
-static int lpe_ioctl(struct ifnet *, u_long, caddr_t);
-static void lpe_set_rxmode(struct lpe_softc *);
-static void lpe_set_rxfilter(struct lpe_softc *);
-static void lpe_intr(void *);
-static void lpe_rxintr(struct lpe_softc *);
-static void lpe_txintr(struct lpe_softc *);
-static void lpe_tick(void *);
-static void lpe_watchdog(struct lpe_softc *);
-static int lpe_encap(struct lpe_softc *, struct mbuf **);
-static int lpe_dma_alloc(struct lpe_softc *);
-static int lpe_dma_alloc_rx(struct lpe_softc *);
-static int lpe_dma_alloc_tx(struct lpe_softc *);
-static int lpe_init_rx(struct lpe_softc *);
-static int lpe_init_rxbuf(struct lpe_softc *, int);
-static void lpe_discard_rxbuf(struct lpe_softc *, int);
-static void lpe_dmamap_cb(void *, bus_dma_segment_t *, int, int);
-static int lpe_ifmedia_upd(struct ifnet *);
-static void lpe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-#define lpe_lock(_sc) mtx_lock(&(_sc)->lpe_mtx)
-#define lpe_unlock(_sc) mtx_unlock(&(_sc)->lpe_mtx)
-#define lpe_lock_assert(_sc) mtx_assert(&(_sc)->lpe_mtx, MA_OWNED)
-
-#define lpe_read_4(_sc, _reg) \
- bus_space_read_4((_sc)->lpe_bst, (_sc)->lpe_bsh, (_reg))
-#define lpe_write_4(_sc, _reg, _val) \
- bus_space_write_4((_sc)->lpe_bst, (_sc)->lpe_bsh, (_reg), (_val))
-
-#define LPE_HWDESC_RXERRS (LPE_HWDESC_CRCERROR | LPE_HWDESC_SYMBOLERROR | \
- LPE_HWDESC_LENGTHERROR | LPE_HWDESC_ALIGNERROR | LPE_HWDESC_OVERRUN | \
- LPE_HWDESC_RXNODESCR)
-
-#define LPE_HWDESC_TXERRS (LPE_HWDESC_EXCDEFER | LPE_HWDESC_EXCCOLL | \
- LPE_HWDESC_LATECOLL | LPE_HWDESC_UNDERRUN | LPE_HWDESC_TXNODESCR)
-
-static int
-lpe_probe(device_t dev)
-{
-
-#ifndef __rtems__
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (!ofw_bus_is_compatible(dev, "lpc,ethernet"))
- return (ENXIO);
-#endif /* __rtems__ */
-
- device_set_desc(dev, "LPC32x0 10/100 Ethernet");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-lpe_attach(device_t dev)
-{
- struct lpe_softc *sc = device_get_softc(dev);
- struct ifnet *ifp;
- int rid, i;
- uint32_t val;
-
- sc->lpe_dev = dev;
-#ifndef __rtems__
- sc->lpe_ofw = ofw_bus_get_node(dev);
-
- i = OF_getprop(sc->lpe_ofw, "local-mac-address", (void *)&sc->lpe_enaddr, 6);
- if (i != 6) {
- sc->lpe_enaddr[0] = 0x00;
- sc->lpe_enaddr[1] = 0x11;
- sc->lpe_enaddr[2] = 0x22;
- sc->lpe_enaddr[3] = 0x33;
- sc->lpe_enaddr[4] = 0x44;
- sc->lpe_enaddr[5] = 0x55;
- }
-#else /* __rtems__ */
- rtems_bsd_get_mac_address(device_get_name(sc->lpe_dev), device_get_unit(sc->lpe_dev), &sc->lpe_enaddr);
-#endif /* __rtems__ */
-
- mtx_init(&sc->lpe_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
- MTX_DEF);
-
- callout_init_mtx(&sc->lpe_tick, &sc->lpe_mtx, 0);
-
- rid = 0;
- sc->lpe_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->lpe_mem_res) {
- device_printf(dev, "cannot allocate memory window\n");
- goto fail;
- }
-
- sc->lpe_bst = rman_get_bustag(sc->lpe_mem_res);
- sc->lpe_bsh = rman_get_bushandle(sc->lpe_mem_res);
-
- rid = 0;
- sc->lpe_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (!sc->lpe_irq_res) {
- device_printf(dev, "cannot allocate interrupt\n");
- goto fail;
- }
-
- sc->lpe_ifp = if_alloc(IFT_ETHER);
- if (!sc->lpe_ifp) {
- device_printf(dev, "cannot allocated ifnet\n");
- goto fail;
- }
-
- ifp = sc->lpe_ifp;
-
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_start = lpe_start;
- ifp->if_ioctl = lpe_ioctl;
- ifp->if_init = lpe_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- ether_ifattach(ifp, sc->lpe_enaddr);
-
- if (bus_setup_intr(dev, sc->lpe_irq_res, INTR_TYPE_NET, NULL,
- lpe_intr, sc, &sc->lpe_intrhand)) {
- device_printf(dev, "cannot establish interrupt handler\n");
- ether_ifdetach(ifp);
- goto fail;
- }
-
- /* Enable Ethernet clock */
-#ifndef __rtems__
- lpc_pwr_write(dev, LPC_CLKPWR_MACCLK_CTRL,
- LPC_CLKPWR_MACCLK_CTRL_REG |
- LPC_CLKPWR_MACCLK_CTRL_SLAVE |
- LPC_CLKPWR_MACCLK_CTRL_MASTER |
- LPC_CLKPWR_MACCLK_CTRL_HDWINF(3));
-#else /* __rtems__ */
-#ifdef LPC32XX_ETHERNET_RMII
- lpc_pwr_write(dev, LPC_CLKPWR_MACCLK_CTRL,
- LPC_CLKPWR_MACCLK_CTRL_REG |
- LPC_CLKPWR_MACCLK_CTRL_SLAVE |
- LPC_CLKPWR_MACCLK_CTRL_MASTER |
- LPC_CLKPWR_MACCLK_CTRL_HDWINF(3));
-#else
- lpc_pwr_write(dev, LPC_CLKPWR_MACCLK_CTRL,
- LPC_CLKPWR_MACCLK_CTRL_REG |
- LPC_CLKPWR_MACCLK_CTRL_SLAVE |
- LPC_CLKPWR_MACCLK_CTRL_MASTER |
- LPC_CLKPWR_MACCLK_CTRL_HDWINF(1));
-#endif
-#endif /* __rtems__ */
-
- /* Reset chip */
- lpe_reset(sc);
-
- /* Initialize MII */
-#ifndef __rtems__
- val = lpe_read_4(sc, LPE_COMMAND);
- lpe_write_4(sc, LPE_COMMAND, val | LPE_COMMAND_RMII);
-
- if (mii_attach(dev, &sc->lpe_miibus, ifp, lpe_ifmedia_upd,
- lpe_ifmedia_sts, BMSR_DEFCAPMASK, 0x01,
- MII_OFFSET_ANY, 0)) {
- device_printf(dev, "cannot find PHY\n");
- goto fail;
- }
-#else /* __rtems__ */
- if (mii_attach(dev, &sc->lpe_miibus, ifp, lpe_ifmedia_upd,
- lpe_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY,
- MII_OFFSET_ANY, 0)) {
- device_printf(dev, "cannot find PHY\n");
- goto fail;
- }
-#endif /* __rtems__ */
-
- lpe_dma_alloc(sc);
-
- return (0);
-
-fail:
- if (sc->lpe_ifp)
- if_free(sc->lpe_ifp);
- if (sc->lpe_intrhand)
- bus_teardown_intr(dev, sc->lpe_irq_res, sc->lpe_intrhand);
- if (sc->lpe_irq_res)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lpe_irq_res);
- if (sc->lpe_mem_res)
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lpe_mem_res);
- return (ENXIO);
-}
-
-static int
-lpe_detach(device_t dev)
-{
- struct lpe_softc *sc = device_get_softc(dev);
-
- lpe_stop(sc);
-
- if_free(sc->lpe_ifp);
- bus_teardown_intr(dev, sc->lpe_irq_res, sc->lpe_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lpe_irq_res);
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lpe_mem_res);
-
- return (0);
-}
-
-static int
-lpe_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct lpe_softc *sc = device_get_softc(dev);
- uint32_t val;
- int result;
-
- lpe_write_4(sc, LPE_MCMD, LPE_MCMD_READ);
- lpe_write_4(sc, LPE_MADR,
- (reg & LPE_MADR_REGMASK) << LPE_MADR_REGSHIFT |
- (phy & LPE_MADR_PHYMASK) << LPE_MADR_PHYSHIFT);
-
- val = lpe_read_4(sc, LPE_MIND);
-
- /* Wait until request is completed */
- while (val & LPE_MIND_BUSY) {
- val = lpe_read_4(sc, LPE_MIND);
- DELAY(10);
- }
-
- if (val & LPE_MIND_INVALID)
- return (0);
-
- lpe_write_4(sc, LPE_MCMD, 0);
- result = (lpe_read_4(sc, LPE_MRDD) & LPE_MRDD_DATAMASK);
- debugf("phy=%d reg=%d result=0x%04x\n", phy, reg, result);
-
- return (result);
-}
-
-static int
-lpe_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
- struct lpe_softc *sc = device_get_softc(dev);
- uint32_t val;
-
- debugf("phy=%d reg=%d data=0x%04x\n", phy, reg, data);
-
- lpe_write_4(sc, LPE_MCMD, LPE_MCMD_WRITE);
- lpe_write_4(sc, LPE_MADR,
- (reg & LPE_MADR_REGMASK) << LPE_MADR_REGSHIFT |
- (phy & LPE_MADR_PHYMASK) << LPE_MADR_PHYSHIFT);
-
- lpe_write_4(sc, LPE_MWTD, (data & LPE_MWTD_DATAMASK));
-
- val = lpe_read_4(sc, LPE_MIND);
-
- /* Wait until request is completed */
- while (val & LPE_MIND_BUSY) {
- val = lpe_read_4(sc, LPE_MIND);
- DELAY(10);
- }
-
- return (0);
-}
-
-static void
-lpe_miibus_statchg(device_t dev)
-{
- struct lpe_softc *sc = device_get_softc(dev);
- struct mii_data *mii = device_get_softc(sc->lpe_miibus);
-
-#ifndef __rtems__
- lpe_lock(sc);
-#endif /* __rtems__ */
-
- if ((mii->mii_media_status & IFM_ACTIVE) &&
- (mii->mii_media_status & IFM_AVALID))
- sc->lpe_flags |= LPE_FLAG_LINK;
- else
- sc->lpe_flags &= ~LPE_FLAG_LINK;
-
-#ifndef __rtems__
- lpe_unlock(sc);
-#endif /* __rtems__ */
-}
-
-static void
-lpe_reset(struct lpe_softc *sc)
-{
- uint32_t mac1;
-
-#ifndef __rtems__
- /* Enter soft reset mode */
- mac1 = lpe_read_4(sc, LPE_MAC1);
- lpe_write_4(sc, LPE_MAC1, mac1 | LPE_MAC1_SOFTRESET | LPE_MAC1_RESETTX |
- LPE_MAC1_RESETMCSTX | LPE_MAC1_RESETRX | LPE_MAC1_RESETMCSRX);
-
- /* Reset registers, Tx path and Rx path */
- lpe_write_4(sc, LPE_COMMAND, LPE_COMMAND_REGRESET |
- LPE_COMMAND_TXRESET | LPE_COMMAND_RXRESET);
-
- /* Set station address */
- lpe_write_4(sc, LPE_SA2, sc->lpe_enaddr[1] << 8 | sc->lpe_enaddr[0]);
- lpe_write_4(sc, LPE_SA1, sc->lpe_enaddr[3] << 8 | sc->lpe_enaddr[2]);
- lpe_write_4(sc, LPE_SA0, sc->lpe_enaddr[5] << 8 | sc->lpe_enaddr[4]);
-
- /* Leave soft reset mode */
- mac1 = lpe_read_4(sc, LPE_MAC1);
- lpe_write_4(sc, LPE_MAC1, mac1 & ~(LPE_MAC1_SOFTRESET | LPE_MAC1_RESETTX |
- LPE_MAC1_RESETMCSTX | LPE_MAC1_RESETRX | LPE_MAC1_RESETMCSRX));
-#else /* __rtems__ */
- /* Reset registers, Tx path and Rx path */
- lpe_write_4(sc, LPE_COMMAND, LPE_COMMAND_REGRESET | LPE_COMMAND_TXRESET | LPE_COMMAND_RXRESET);
-
- /* Enter soft reset mode */
- mac1 = lpe_read_4(sc, LPE_MAC1);
- lpe_write_4(sc, LPE_MAC1, mac1 | LPE_MAC1_SOFTRESET | LPE_MAC1_RESETTX |
- LPE_MAC1_RESETMCSTX | LPE_MAC1_RESETRX | LPE_MAC1_RESETMCSRX);
-
- /* Leave soft reset mode */
- mac1 = lpe_read_4(sc, LPE_MAC1);
- lpe_write_4(sc, LPE_MAC1, mac1 & ~(LPE_MAC1_SOFTRESET | LPE_MAC1_RESETTX |
- LPE_MAC1_RESETMCSTX | LPE_MAC1_RESETRX | LPE_MAC1_RESETMCSRX));
-
- /* Reinitialize registers */
- lpe_write_4(sc, LPE_MCFG, LPE_MCFG_CLKSEL(0x7));
- lpe_write_4(sc, LPE_MAC2, LPE_MAC2_PADCRCENABLE | LPE_MAC2_CRCENABLE | LPE_MAC2_FULLDUPLEX);
- lpe_write_4(sc, LPE_IPGT, 0x15);
- lpe_write_4(sc, LPE_IPGR, 0x12);
- lpe_write_4(sc, LPE_CLRT, 0x370f);
- lpe_write_4(sc, LPE_MAXF, 0x0600);
- lpe_write_4(sc, LPE_SUPP, LPE_SUPP_SPEED);
- lpe_write_4(sc, LPE_TEST, 0x0);
-#ifdef LPC32XX_ETHERNET_RMII
- lpe_write_4(sc, LPE_COMMAND, LPE_COMMAND_FULLDUPLEX | LPE_COMMAND_RMII);
-#else
- lpe_write_4(sc, LPE_COMMAND, LPE_COMMAND_FULLDUPLEX);
-#endif
- lpe_write_4(sc, LPE_INTENABLE, 0x0);
- lpe_write_4(sc, LPE_INTCLEAR, 0x30ff);
- lpe_write_4(sc, LPE_POWERDOWN, 0x0);
-
- /* Set station address */
- lpe_write_4(sc, LPE_SA2, sc->lpe_enaddr[1] << 8 | sc->lpe_enaddr[0]);
- lpe_write_4(sc, LPE_SA1, sc->lpe_enaddr[3] << 8 | sc->lpe_enaddr[2]);
- lpe_write_4(sc, LPE_SA0, sc->lpe_enaddr[5] << 8 | sc->lpe_enaddr[4]);
-#endif /* __rtems__ */
-}
-
-static void
-lpe_init(void *arg)
-{
- struct lpe_softc *sc = (struct lpe_softc *)arg;
-
- lpe_lock(sc);
- lpe_init_locked(sc);
- lpe_unlock(sc);
-}
-
-static void
-lpe_init_locked(struct lpe_softc *sc)
-{
- struct ifnet *ifp = sc->lpe_ifp;
- uint32_t cmd, mac1;
-
- lpe_lock_assert(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- return;
-
- /* Enable Tx and Rx */
- cmd = lpe_read_4(sc, LPE_COMMAND);
- lpe_write_4(sc, LPE_COMMAND, cmd | LPE_COMMAND_RXENABLE |
- LPE_COMMAND_TXENABLE | LPE_COMMAND_PASSRUNTFRAME);
-
- /* Enable receive */
- mac1 = lpe_read_4(sc, LPE_MAC1);
- lpe_write_4(sc, LPE_MAC1, /*mac1 |*/ LPE_MAC1_RXENABLE | LPE_MAC1_PASSALL);
-
- lpe_write_4(sc, LPE_MAC2, LPE_MAC2_CRCENABLE | LPE_MAC2_PADCRCENABLE |
- LPE_MAC2_FULLDUPLEX);
-
- lpe_write_4(sc, LPE_MCFG, LPE_MCFG_CLKSEL(7));
-
- /* Set up Rx filter */
- lpe_set_rxmode(sc);
-
- /* Enable interrupts */
- lpe_write_4(sc, LPE_INTENABLE, LPE_INT_RXOVERRUN | LPE_INT_RXERROR |
- LPE_INT_RXFINISH | LPE_INT_RXDONE | LPE_INT_TXUNDERRUN |
- LPE_INT_TXERROR | LPE_INT_TXFINISH | LPE_INT_TXDONE);
-
- sc->lpe_cdata.lpe_tx_prod = 0;
- sc->lpe_cdata.lpe_tx_last = 0;
- sc->lpe_cdata.lpe_tx_used = 0;
-
- lpe_init_rx(sc);
-
- /* Initialize Rx packet and status descriptor heads */
- lpe_write_4(sc, LPE_RXDESC, sc->lpe_rdata.lpe_rx_ring_phys);
- lpe_write_4(sc, LPE_RXSTATUS, sc->lpe_rdata.lpe_rx_status_phys);
- lpe_write_4(sc, LPE_RXDESC_NUMBER, LPE_RXDESC_NUM - 1);
- lpe_write_4(sc, LPE_RXDESC_CONS, 0);
-
- /* Initialize Tx packet and status descriptor heads */
- lpe_write_4(sc, LPE_TXDESC, sc->lpe_rdata.lpe_tx_ring_phys);
- lpe_write_4(sc, LPE_TXSTATUS, sc->lpe_rdata.lpe_tx_status_phys);
- lpe_write_4(sc, LPE_TXDESC_NUMBER, LPE_TXDESC_NUM - 1);
- lpe_write_4(sc, LPE_TXDESC_PROD, 0);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- callout_reset(&sc->lpe_tick, hz, lpe_tick, sc);
-}
-
-static void
-lpe_start(struct ifnet *ifp)
-{
- struct lpe_softc *sc = (struct lpe_softc *)ifp->if_softc;
-
- lpe_lock(sc);
- lpe_start_locked(ifp);
- lpe_unlock(sc);
-}
-
-static void
-lpe_start_locked(struct ifnet *ifp)
-{
- struct lpe_softc *sc = (struct lpe_softc *)ifp->if_softc;
- struct mbuf *m_head;
- int encap = 0;
-
- lpe_lock_assert(sc);
-
- while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
- if (lpe_read_4(sc, LPE_TXDESC_PROD) ==
- lpe_read_4(sc, LPE_TXDESC_CONS) - 5)
- break;
-
- /* Dequeue first packet */
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
- if (!m_head)
- break;
-
- lpe_encap(sc, &m_head);
-
- encap++;
- }
-
- /* Submit new descriptor list */
- if (encap) {
- lpe_write_4(sc, LPE_TXDESC_PROD, sc->lpe_cdata.lpe_tx_prod);
- sc->lpe_watchdog_timer = 5;
- }
-
-}
-
-#ifdef __rtems__
-static int
-lpe_get_segs_for_tx(struct mbuf *m, bus_dma_segment_t segs[LPE_MAXFRAGS],
- int *nsegs)
-{
- int i = 0;
-
- do {
- if (m->m_len > 0) {
- segs[i].ds_addr = mtod(m, bus_addr_t);
- segs[i].ds_len = m->m_len;
-#ifdef CPU_DATA_CACHE_ALIGNMENT
- rtems_cache_flush_multiple_data_lines(m->m_data, m->m_len);
-#endif
- ++i;
- }
- m = m->m_next;
- if (m == NULL) {
- *nsegs = i;
- return (0);
- }
- } while (i < LPE_MAXFRAGS);
- return (EFBIG);
-}
-#endif /* __rtems__ */
-static int
-lpe_encap(struct lpe_softc *sc, struct mbuf **m_head)
-{
- struct lpe_txdesc *txd;
- struct lpe_hwdesc *hwd;
- bus_dma_segment_t segs[LPE_MAXFRAGS];
- int i, err, nsegs, prod;
-
- lpe_lock_assert(sc);
- M_ASSERTPKTHDR((*m_head));
-
- prod = sc->lpe_cdata.lpe_tx_prod;
- txd = &sc->lpe_cdata.lpe_tx_desc[prod];
-
- debugf("starting with prod=%d\n", prod);
-
-#ifndef __rtems__
- err = bus_dmamap_load_mbuf_sg(sc->lpe_cdata.lpe_tx_buf_tag,
- txd->lpe_txdesc_dmamap, *m_head, segs, &nsegs, BUS_DMA_NOWAIT);
-#else /* __rtems__ */
- err = lpe_get_segs_for_tx(*m_head, segs, &nsegs);
-#endif /* __rtems__ */
-
- if (err)
- return (err);
-
- if (nsegs == 0) {
- m_freem(*m_head);
- *m_head = NULL;
- return (EIO);
- }
-
-#ifndef __rtems__
- bus_dmamap_sync(sc->lpe_cdata.lpe_tx_buf_tag, txd->lpe_txdesc_dmamap,
- BUS_DMASYNC_PREREAD);
-#endif /* __rtems__ */
- bus_dmamap_sync(sc->lpe_cdata.lpe_tx_ring_tag, sc->lpe_cdata.lpe_tx_ring_map,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-
- txd->lpe_txdesc_first = 1;
- txd->lpe_txdesc_mbuf = *m_head;
-
- for (i = 0; i < nsegs; i++) {
- hwd = &sc->lpe_rdata.lpe_tx_ring[prod];
- hwd->lhr_data = segs[i].ds_addr;
- hwd->lhr_control = segs[i].ds_len - 1;
-
- if (i == nsegs - 1) {
- hwd->lhr_control |= LPE_HWDESC_LASTFLAG;
- hwd->lhr_control |= LPE_HWDESC_INTERRUPT;
- hwd->lhr_control |= LPE_HWDESC_CRC;
- hwd->lhr_control |= LPE_HWDESC_PAD;
- }
-
-#ifdef __rtems__
-#ifdef CPU_DATA_CACHE_ALIGNMENT
- rtems_cache_flush_multiple_data_lines(hwd, sizeof(*hwd));
-#endif
-#endif /* __rtems__ */
- LPE_INC(prod, LPE_TXDESC_NUM);
- }
-
- bus_dmamap_sync(sc->lpe_cdata.lpe_tx_ring_tag, sc->lpe_cdata.lpe_tx_ring_map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-
- sc->lpe_cdata.lpe_tx_used += nsegs;
- sc->lpe_cdata.lpe_tx_prod = prod;
-
- return (0);
-}
-
-static void
-lpe_stop(struct lpe_softc *sc)
-{
- lpe_lock(sc);
- lpe_stop_locked(sc);
- lpe_unlock(sc);
-}
-
-static void
-lpe_stop_locked(struct lpe_softc *sc)
-{
- lpe_lock_assert(sc);
-
- callout_stop(&sc->lpe_tick);
-
- /* Disable interrupts */
- lpe_write_4(sc, LPE_INTCLEAR, 0xffffffff);
-
- /* Stop EMAC */
- lpe_write_4(sc, LPE_MAC1, 0);
- lpe_write_4(sc, LPE_MAC2, 0);
- lpe_write_4(sc, LPE_COMMAND, 0);
-
- sc->lpe_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- sc->lpe_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-}
-
-static int
-lpe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct lpe_softc *sc = ifp->if_softc;
- struct mii_data *mii = device_get_softc(sc->lpe_miibus);
- struct ifreq *ifr = (struct ifreq *)data;
- int err = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- lpe_lock(sc);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- lpe_set_rxmode(sc);
- lpe_set_rxfilter(sc);
- } else
- lpe_init_locked(sc);
- } else
- lpe_stop(sc);
- lpe_unlock(sc);
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- lpe_lock(sc);
- lpe_set_rxfilter(sc);
- lpe_unlock(sc);
- }
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- err = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
- break;
- default:
- err = ether_ioctl(ifp, cmd, data);
- break;
- }
-
- return (err);
-}
-
-static void lpe_set_rxmode(struct lpe_softc *sc)
-{
- struct ifnet *ifp = sc->lpe_ifp;
- uint32_t rxfilt;
-
- rxfilt = LPE_RXFILTER_UNIHASH | LPE_RXFILTER_MULTIHASH | LPE_RXFILTER_PERFECT;
-
- if (ifp->if_flags & IFF_BROADCAST)
- rxfilt |= LPE_RXFILTER_BROADCAST;
-
- if (ifp->if_flags & IFF_PROMISC)
- rxfilt |= LPE_RXFILTER_UNICAST | LPE_RXFILTER_MULTICAST;
-
- if (ifp->if_flags & IFF_ALLMULTI)
- rxfilt |= LPE_RXFILTER_MULTICAST;
-
- lpe_write_4(sc, LPE_RXFILTER_CTRL, rxfilt);
-}
-
-static void lpe_set_rxfilter(struct lpe_softc *sc)
-{
- struct ifnet *ifp = sc->lpe_ifp;
- struct ifmultiaddr *ifma;
- int index;
- uint32_t hashl, hashh;
-
- hashl = 0;
- hashh = 0;
-
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
-
- index = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) >> 23 & 0x3f;
-
- if (index > 31)
- hashh |= (1 << (index - 32));
- else
- hashl |= (1 << index);
- }
- if_maddr_runlock(ifp);
-
- /* Program new hash filter */
- lpe_write_4(sc, LPE_HASHFILTER_L, hashl);
- lpe_write_4(sc, LPE_HASHFILTER_H, hashh);
-}
-
-static void
-lpe_intr(void *arg)
-{
- struct lpe_softc *sc = (struct lpe_softc *)arg;
- uint32_t intstatus;
-
- debugf("status=0x%08x\n", lpe_read_4(sc, LPE_INTSTATUS));
-
- lpe_lock(sc);
-
- while ((intstatus = lpe_read_4(sc, LPE_INTSTATUS))) {
- if (intstatus & LPE_INT_RXDONE)
- lpe_rxintr(sc);
-
-#ifndef __rtems__
- if (intstatus & LPE_INT_TXDONE)
- lpe_txintr(sc);
-
-#else /* __rtems__ */
- if (intstatus & LPE_INT_TXUNDERRUN) {
- if_inc_counter(sc->lpe_ifp, IFCOUNTER_OERRORS, 1);
- lpe_stop_locked(sc);
- lpe_init_locked(sc);
- }
- else if (intstatus & (LPE_INT_TXERROR | LPE_INT_TXFINISH | LPE_INT_TXDONE))
- lpe_txintr(sc);
-#endif /* __rtems__ */
- lpe_write_4(sc, LPE_INTCLEAR, 0xffff);
- }
-
- lpe_unlock(sc);
-}
-
-static void
-lpe_rxintr(struct lpe_softc *sc)
-{
- struct ifnet *ifp = sc->lpe_ifp;
- struct lpe_hwdesc *hwd;
- struct lpe_hwstatus *hws;
- struct lpe_rxdesc *rxd;
- struct mbuf *m;
- int prod, cons;
-
- for (;;) {
- prod = lpe_read_4(sc, LPE_RXDESC_PROD);
- cons = lpe_read_4(sc, LPE_RXDESC_CONS);
-
- if (prod == cons)
- break;
-
- rxd = &sc->lpe_cdata.lpe_rx_desc[cons];
- hwd = &sc->lpe_rdata.lpe_rx_ring[cons];
- hws = &sc->lpe_rdata.lpe_rx_status[cons];
-#ifdef __rtems__
-#ifdef CPU_DATA_CACHE_ALIGNMENT
- rtems_cache_invalidate_multiple_data_lines(rxd, sizeof(*rxd));
- rtems_cache_invalidate_multiple_data_lines(hwd, sizeof(*hwd));
- rtems_cache_invalidate_multiple_data_lines(hws, sizeof(*hws));
-#endif
-#endif /* __rtems__ */
-
- /* Check received frame for errors */
- if (hws->lhs_info & LPE_HWDESC_RXERRS) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- lpe_discard_rxbuf(sc, cons);
- lpe_init_rxbuf(sc, cons);
- goto skip;
- }
-
- m = rxd->lpe_rxdesc_mbuf;
-#ifdef __rtems__
-#ifdef CPU_DATA_CACHE_ALIGNMENT
- rtems_cache_invalidate_multiple_data_lines(m->m_data, m->m_len);
-#endif
-#endif /* __rtems__ */
- m->m_pkthdr.rcvif = ifp;
- m->m_data += 2;
-
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
-
- lpe_unlock(sc);
- (*ifp->if_input)(ifp, m);
- lpe_lock(sc);
-
- lpe_init_rxbuf(sc, cons);
-skip:
- LPE_INC(cons, LPE_RXDESC_NUM);
- lpe_write_4(sc, LPE_RXDESC_CONS, cons);
- }
-}
-
-static void
-lpe_txintr(struct lpe_softc *sc)
-{
- struct ifnet *ifp = sc->lpe_ifp;
- struct lpe_hwdesc *hwd;
- struct lpe_hwstatus *hws;
- struct lpe_txdesc *txd;
- int cons, last;
-
- for (;;) {
- cons = lpe_read_4(sc, LPE_TXDESC_CONS);
- last = sc->lpe_cdata.lpe_tx_last;
-
- if (cons == last)
- break;
-
- txd = &sc->lpe_cdata.lpe_tx_desc[last];
- hwd = &sc->lpe_rdata.lpe_tx_ring[last];
- hws = &sc->lpe_rdata.lpe_tx_status[last];
-
-#ifndef __rtems__
- bus_dmamap_sync(sc->lpe_cdata.lpe_tx_buf_tag,
- txd->lpe_txdesc_dmamap, BUS_DMASYNC_POSTWRITE);
-#else /* __rtems__ */
-#ifdef CPU_DATA_CACHE_ALIGNMENT
- rtems_cache_invalidate_multiple_data_lines(txd, sizeof(*txd));
- rtems_cache_invalidate_multiple_data_lines(hwd, sizeof(*hwd));
- rtems_cache_invalidate_multiple_data_lines(hws, sizeof(*hws));
-#endif
-#endif /* __rtems__ */
-
- if_inc_counter(ifp, IFCOUNTER_COLLISIONS, LPE_HWDESC_COLLISIONS(hws->lhs_info));
-
- if (hws->lhs_info & LPE_HWDESC_TXERRS)
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- else
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
- if (txd->lpe_txdesc_first) {
-#ifndef __rtems__
- bus_dmamap_unload(sc->lpe_cdata.lpe_tx_buf_tag,
- txd->lpe_txdesc_dmamap);
-#endif /* __rtems__ */
-
- m_freem(txd->lpe_txdesc_mbuf);
- txd->lpe_txdesc_mbuf = NULL;
- txd->lpe_txdesc_first = 0;
- }
-
- sc->lpe_cdata.lpe_tx_used--;
- LPE_INC(sc->lpe_cdata.lpe_tx_last, LPE_TXDESC_NUM);
- }
-
- if (!sc->lpe_cdata.lpe_tx_used)
- sc->lpe_watchdog_timer = 0;
-}
-
-static void
-lpe_tick(void *arg)
-{
- struct lpe_softc *sc = (struct lpe_softc *)arg;
- struct mii_data *mii = device_get_softc(sc->lpe_miibus);
-
- lpe_lock_assert(sc);
-
- mii_tick(mii);
- lpe_watchdog(sc);
-
- callout_reset(&sc->lpe_tick, hz, lpe_tick, sc);
-}
-
-static void
-lpe_watchdog(struct lpe_softc *sc)
-{
- struct ifnet *ifp = sc->lpe_ifp;
-
- lpe_lock_assert(sc);
-
- if (sc->lpe_watchdog_timer == 0 || sc->lpe_watchdog_timer--)
- return;
-
- /* Chip has stopped responding */
- device_printf(sc->lpe_dev, "WARNING: chip hangup, restarting...\n");
- lpe_stop_locked(sc);
- lpe_init_locked(sc);
-
- /* Try to resend packets */
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- lpe_start_locked(ifp);
-}
-
-static int
-lpe_dma_alloc(struct lpe_softc *sc)
-{
- int err;
-
- /* Create parent DMA tag */
- err = bus_dma_tag_create(
- bus_get_dma_tag(sc->lpe_dev),
- 1, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- BUS_SPACE_MAXSIZE_32BIT, 0, /* maxsize, nsegments */
- BUS_SPACE_MAXSIZE_32BIT, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->lpe_cdata.lpe_parent_tag);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create parent DMA tag\n");
- return (err);
- }
-
- err = lpe_dma_alloc_rx(sc);
- if (err)
- return (err);
-
- err = lpe_dma_alloc_tx(sc);
- if (err)
- return (err);
-
- return (0);
-}
-
-static int
-lpe_dma_alloc_rx(struct lpe_softc *sc)
-{
- struct lpe_rxdesc *rxd;
- struct lpe_dmamap_arg ctx;
- int err, i;
-
- /* Create tag for Rx ring */
- err = bus_dma_tag_create(
- sc->lpe_cdata.lpe_parent_tag,
- LPE_DESC_ALIGN, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- LPE_RXDESC_SIZE, 1, /* maxsize, nsegments */
- LPE_RXDESC_SIZE, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->lpe_cdata.lpe_rx_ring_tag);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Rx ring DMA tag\n");
- goto fail;
- }
-
- /* Create tag for Rx status ring */
- err = bus_dma_tag_create(
- sc->lpe_cdata.lpe_parent_tag,
- LPE_DESC_ALIGN, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- LPE_RXSTATUS_SIZE, 1, /* maxsize, nsegments */
- LPE_RXSTATUS_SIZE, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->lpe_cdata.lpe_rx_status_tag);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Rx status ring DMA tag\n");
- goto fail;
- }
-
- /* Create tag for Rx buffers */
- err = bus_dma_tag_create(
- sc->lpe_cdata.lpe_parent_tag,
- LPE_DESC_ALIGN, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MCLBYTES * LPE_RXDESC_NUM, /* maxsize */
- LPE_RXDESC_NUM, /* segments */
- MCLBYTES, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->lpe_cdata.lpe_rx_buf_tag);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Rx buffers DMA tag\n");
- goto fail;
- }
-
- /* Allocate Rx DMA ring */
- err = bus_dmamem_alloc(sc->lpe_cdata.lpe_rx_ring_tag,
- (void **)&sc->lpe_rdata.lpe_rx_ring, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
- BUS_DMA_ZERO, &sc->lpe_cdata.lpe_rx_ring_map);
-
- err = bus_dmamap_load(sc->lpe_cdata.lpe_rx_ring_tag,
- sc->lpe_cdata.lpe_rx_ring_map, sc->lpe_rdata.lpe_rx_ring,
- LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
-
- sc->lpe_rdata.lpe_rx_ring_phys = ctx.lpe_dma_busaddr;
-
- /* Allocate Rx status ring */
- err = bus_dmamem_alloc(sc->lpe_cdata.lpe_rx_status_tag,
- (void **)&sc->lpe_rdata.lpe_rx_status, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
- BUS_DMA_ZERO, &sc->lpe_cdata.lpe_rx_status_map);
-
- err = bus_dmamap_load(sc->lpe_cdata.lpe_rx_status_tag,
- sc->lpe_cdata.lpe_rx_status_map, sc->lpe_rdata.lpe_rx_status,
- LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
-
- sc->lpe_rdata.lpe_rx_status_phys = ctx.lpe_dma_busaddr;
-
-
- /* Create Rx buffers DMA map */
- for (i = 0; i < LPE_RXDESC_NUM; i++) {
- rxd = &sc->lpe_cdata.lpe_rx_desc[i];
- rxd->lpe_rxdesc_mbuf = NULL;
-#ifndef __rtems__
- rxd->lpe_rxdesc_dmamap = NULL;
-
- err = bus_dmamap_create(sc->lpe_cdata.lpe_rx_buf_tag, 0,
- &rxd->lpe_rxdesc_dmamap);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Rx DMA map\n");
- return (err);
- }
-#endif /* __rtems__ */
- }
-
- return (0);
-fail:
- return (err);
-}
-
-static int
-lpe_dma_alloc_tx(struct lpe_softc *sc)
-{
- struct lpe_txdesc *txd;
- struct lpe_dmamap_arg ctx;
- int err, i;
-
- /* Create tag for Tx ring */
- err = bus_dma_tag_create(
- sc->lpe_cdata.lpe_parent_tag,
- LPE_DESC_ALIGN, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- LPE_TXDESC_SIZE, 1, /* maxsize, nsegments */
- LPE_TXDESC_SIZE, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->lpe_cdata.lpe_tx_ring_tag);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Tx ring DMA tag\n");
- goto fail;
- }
-
- /* Create tag for Tx status ring */
- err = bus_dma_tag_create(
- sc->lpe_cdata.lpe_parent_tag,
- LPE_DESC_ALIGN, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- LPE_TXSTATUS_SIZE, 1, /* maxsize, nsegments */
- LPE_TXSTATUS_SIZE, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->lpe_cdata.lpe_tx_status_tag);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Tx status ring DMA tag\n");
- goto fail;
- }
-
- /* Create tag for Tx buffers */
- err = bus_dma_tag_create(
- sc->lpe_cdata.lpe_parent_tag,
- LPE_DESC_ALIGN, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MCLBYTES * LPE_TXDESC_NUM, /* maxsize */
- LPE_TXDESC_NUM, /* segments */
- MCLBYTES, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->lpe_cdata.lpe_tx_buf_tag);
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Tx buffers DMA tag\n");
- goto fail;
- }
-
- /* Allocate Tx DMA ring */
- err = bus_dmamem_alloc(sc->lpe_cdata.lpe_tx_ring_tag,
- (void **)&sc->lpe_rdata.lpe_tx_ring, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
- BUS_DMA_ZERO, &sc->lpe_cdata.lpe_tx_ring_map);
-
- err = bus_dmamap_load(sc->lpe_cdata.lpe_tx_ring_tag,
- sc->lpe_cdata.lpe_tx_ring_map, sc->lpe_rdata.lpe_tx_ring,
- LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
-
- sc->lpe_rdata.lpe_tx_ring_phys = ctx.lpe_dma_busaddr;
-
- /* Allocate Tx status ring */
- err = bus_dmamem_alloc(sc->lpe_cdata.lpe_tx_status_tag,
- (void **)&sc->lpe_rdata.lpe_tx_status, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
- BUS_DMA_ZERO, &sc->lpe_cdata.lpe_tx_status_map);
-
- err = bus_dmamap_load(sc->lpe_cdata.lpe_tx_status_tag,
- sc->lpe_cdata.lpe_tx_status_map, sc->lpe_rdata.lpe_tx_status,
- LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
-
- sc->lpe_rdata.lpe_tx_status_phys = ctx.lpe_dma_busaddr;
-
-
- /* Create Tx buffers DMA map */
- for (i = 0; i < LPE_TXDESC_NUM; i++) {
- txd = &sc->lpe_cdata.lpe_tx_desc[i];
- txd->lpe_txdesc_mbuf = NULL;
-#ifndef __rtems__
- txd->lpe_txdesc_dmamap = NULL;
-#endif /* __rtems__ */
- txd->lpe_txdesc_first = 0;
-
-#ifndef __rtems__
- err = bus_dmamap_create(sc->lpe_cdata.lpe_tx_buf_tag, 0,
- &txd->lpe_txdesc_dmamap);
-#endif /* __rtems__ */
-
- if (err) {
- device_printf(sc->lpe_dev, "cannot create Tx DMA map\n");
- return (err);
- }
- }
-
- return (0);
-fail:
- return (err);
-}
-
-static int
-lpe_init_rx(struct lpe_softc *sc)
-{
- int i, err;
-
- for (i = 0; i < LPE_RXDESC_NUM; i++) {
- err = lpe_init_rxbuf(sc, i);
- if (err)
- return (err);
- }
-
- return (0);
-}
-
-static int
-lpe_init_rxbuf(struct lpe_softc *sc, int n)
-{
- struct lpe_rxdesc *rxd;
- struct lpe_hwdesc *hwd;
- struct lpe_hwstatus *hws;
- struct mbuf *m;
- bus_dma_segment_t segs[1];
- int nsegs;
-
- rxd = &sc->lpe_cdata.lpe_rx_desc[n];
- hwd = &sc->lpe_rdata.lpe_rx_ring[n];
- hws = &sc->lpe_rdata.lpe_rx_status[n];
- m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
-
- if (!m) {
- device_printf(sc->lpe_dev, "WARNING: mbufs exhausted!\n");
- return (ENOBUFS);
- }
-
- m->m_len = m->m_pkthdr.len = MCLBYTES;
-
-#ifndef __rtems__
- bus_dmamap_unload(sc->lpe_cdata.lpe_rx_buf_tag, rxd->lpe_rxdesc_dmamap);
-
- if (bus_dmamap_load_mbuf_sg(sc->lpe_cdata.lpe_rx_buf_tag,
- rxd->lpe_rxdesc_dmamap, m, segs, &nsegs, 0)) {
- m_freem(m);
- return (ENOBUFS);
- }
-
- bus_dmamap_sync(sc->lpe_cdata.lpe_rx_buf_tag, rxd->lpe_rxdesc_dmamap,
- BUS_DMASYNC_PREREAD);
-#else /* __rtems__ */
-#ifdef CPU_DATA_CACHE_ALIGNMENT
- rtems_cache_invalidate_multiple_data_lines(m->m_data, m->m_len);
-#endif
- segs[0].ds_addr = mtod(m, bus_addr_t);
-#endif /* __rtems__ */
-
- rxd->lpe_rxdesc_mbuf = m;
- hwd->lhr_data = segs[0].ds_addr + 2;
- hwd->lhr_control = (segs[0].ds_len - 1) | LPE_HWDESC_INTERRUPT;
-#ifdef __rtems__
-#ifdef CPU_DATA_CACHE_ALIGNMENT
- rtems_cache_flush_multiple_data_lines(hwd, sizeof(*hwd));
-#endif
-#endif /* __rtems__ */
-
- return (0);
-}
-
-static void
-lpe_discard_rxbuf(struct lpe_softc *sc, int n)
-{
- struct lpe_rxdesc *rxd;
- struct lpe_hwdesc *hwd;
-
- rxd = &sc->lpe_cdata.lpe_rx_desc[n];
- hwd = &sc->lpe_rdata.lpe_rx_ring[n];
-
-#ifndef __rtems__
- bus_dmamap_unload(sc->lpe_cdata.lpe_rx_buf_tag, rxd->lpe_rxdesc_dmamap);
-#endif /* __rtems__ */
-
- hwd->lhr_data = 0;
- hwd->lhr_control = 0;
-
- if (rxd->lpe_rxdesc_mbuf) {
- m_freem(rxd->lpe_rxdesc_mbuf);
- rxd->lpe_rxdesc_mbuf = NULL;
- }
-}
-
-static void
-lpe_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- struct lpe_dmamap_arg *ctx;
-
- if (error)
- return;
-
- ctx = (struct lpe_dmamap_arg *)arg;
- ctx->lpe_dma_busaddr = segs[0].ds_addr;
-}
-
-static int
-lpe_ifmedia_upd(struct ifnet *ifp)
-{
- return (0);
-}
-
-static void
-lpe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct lpe_softc *sc = ifp->if_softc;
- struct mii_data *mii = device_get_softc(sc->lpe_miibus);
-
- lpe_lock(sc);
- mii_pollstat(mii);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
- lpe_unlock(sc);
-}
-
-static device_method_t lpe_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, lpe_probe),
- DEVMETHOD(device_attach, lpe_attach),
- DEVMETHOD(device_detach, lpe_detach),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, lpe_miibus_readreg),
- DEVMETHOD(miibus_writereg, lpe_miibus_writereg),
- DEVMETHOD(miibus_statchg, lpe_miibus_statchg),
- { 0, 0 }
-};
-
-static driver_t lpe_driver = {
- "lpe",
- lpe_methods,
- sizeof(struct lpe_softc),
-};
-
-static devclass_t lpe_devclass;
-
-#ifndef __rtems__
-DRIVER_MODULE(lpe, simplebus, lpe_driver, lpe_devclass, 0, 0);
-#else /* __rtems__ */
-DRIVER_MODULE(lpe, nexus, lpe_driver, lpe_devclass, 0, 0);
-#endif /* __rtems__ */
-DRIVER_MODULE(miibus, lpe, miibus_driver, miibus_devclass, 0, 0);
-MODULE_DEPEND(lpe, obio, 1, 1, 1);
-MODULE_DEPEND(lpe, miibus, 1, 1, 1);
-MODULE_DEPEND(lpe, ether, 1, 1, 1);
diff --git a/freebsd/sys/arm/lpc/if_lpereg.h b/freebsd/sys/arm/lpc/if_lpereg.h
deleted file mode 100644
index a40bf8b5..00000000
--- a/freebsd/sys/arm/lpc/if_lpereg.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2011 Jakub Wojciech Klama <jceel@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 _ARM_LPC_IF_LPEREG_H
-#define _ARM_LPC_IF_LPEREG_H
-
-#define LPE_MAC1 0x000
-#define LPE_MAC1_RXENABLE (1 << 0)
-#define LPE_MAC1_PASSALL (1 << 1)
-#define LPE_MAC1_RXFLOWCTRL (1 << 2)
-#define LPE_MAC1_TXFLOWCTRL (1 << 3)
-#define LPE_MAC1_LOOPBACK (1 << 4)
-#define LPE_MAC1_RESETTX (1 << 8)
-#define LPE_MAC1_RESETMCSTX (1 << 9)
-#define LPE_MAC1_RESETRX (1 << 10)
-#define LPE_MAC1_RESETMCSRX (1 << 11)
-#define LPE_MAC1_SIMRESET (1 << 14)
-#define LPE_MAC1_SOFTRESET (1 << 15)
-#define LPE_MAC2 0x004
-#define LPE_MAC2_FULLDUPLEX (1 << 0)
-#define LPE_MAC2_FRAMELENCHECK (1 << 1)
-#define LPE_MAC2_HUGEFRAME (1 << 2)
-#define LPE_MAC2_DELAYEDCRC (1 << 3)
-#define LPE_MAC2_CRCENABLE (1 << 4)
-#define LPE_MAC2_PADCRCENABLE (1 << 5)
-#define LPE_MAC2_VLANPADENABLE (1 << 6)
-#define LPE_MAC2_AUTOPADENABLE (1 << 7)
-#define LPE_MAC2_PUREPREAMBLE (1 << 8)
-#define LPE_MAC2_LONGPREAMBLE (1 << 9)
-#define LPE_MAC2_NOBACKOFF (1 << 12)
-#define LPE_MAC2_BACKPRESSURE (1 << 13)
-#define LPE_MAC2_EXCESSDEFER (1 << 14)
-#define LPE_IPGT 0x008
-#define LPE_IPGR 0x00c
-#define LPE_CLRT 0x010
-#define LPE_MAXF 0x014
-#define LPE_SUPP 0x018
-#define LPE_SUPP_SPEED (1 << 8)
-#define LPE_TEST 0x01c
-#define LPE_MCFG 0x020
-#define LPE_MCFG_SCANINCR (1 << 0)
-#define LPE_MCFG_SUPPREAMBLE (1 << 1)
-#define LPE_MCFG_CLKSEL(_n) ((_n & 0x7) << 2)
-#define LPC_MCFG_RESETMII (1 << 15)
-#define LPE_MCMD 0x024
-#define LPE_MCMD_READ (1 << 0)
-#define LPE_MCMD_WRITE (0 << 0)
-#define LPE_MCMD_SCAN (1 << 1)
-#define LPE_MADR 0x028
-#define LPE_MADR_REGMASK 0x1f
-#define LPE_MADR_REGSHIFT 0
-#define LPE_MADR_PHYMASK 0x1f
-#define LPE_MADR_PHYSHIFT 8
-#define LPE_MWTD 0x02c
-#define LPE_MWTD_DATAMASK 0xffff
-#define LPE_MRDD 0x030
-#define LPE_MRDD_DATAMASK 0xffff
-#define LPE_MIND 0x034
-#define LPE_MIND_BUSY (1 << 0)
-#define LPE_MIND_SCANNING (1 << 1)
-#define LPE_MIND_INVALID (1 << 2)
-#define LPE_MIND_MIIFAIL (1 << 3)
-#define LPE_SA0 0x040
-#define LPE_SA1 0x044
-#define LPE_SA2 0x048
-#define LPE_COMMAND 0x100
-#define LPE_COMMAND_RXENABLE (1 << 0)
-#define LPE_COMMAND_TXENABLE (1 << 1)
-#define LPE_COMMAND_REGRESET (1 << 3)
-#define LPE_COMMAND_TXRESET (1 << 4)
-#define LPE_COMMAND_RXRESET (1 << 5)
-#define LPE_COMMAND_PASSRUNTFRAME (1 << 6)
-#define LPE_COMMAND_PASSRXFILTER (1 << 7)
-#define LPE_COMMAND_TXFLOWCTL (1 << 8)
-#define LPE_COMMAND_RMII (1 << 9)
-#define LPE_COMMAND_FULLDUPLEX (1 << 10)
-#define LPE_STATUS 0x104
-#define LPE_STATUS_RXACTIVE (1 << 0)
-#define LPE_STATUS_TXACTIVE (1 << 1)
-#define LPE_RXDESC 0x108
-#define LPE_RXSTATUS 0x10c
-#define LPE_RXDESC_NUMBER 0x110
-#define LPE_RXDESC_PROD 0x114
-#define LPE_RXDESC_CONS 0x118
-#define LPE_TXDESC 0x11c
-#define LPE_TXSTATUS 0x120
-#define LPE_TXDESC_NUMBER 0x124
-#define LPE_TXDESC_PROD 0x128
-#define LPE_TXDESC_CONS 0x12c
-#define LPE_TSV0 0x158
-#define LPE_TSV1 0x15c
-#define LPE_RSV 0x160
-#define LPE_FLOWCONTROL_COUNTER 0x170
-#define LPE_FLOWCONTROL_STATUS 0x174
-#define LPE_RXFILTER_CTRL 0x200
-#define LPE_RXFILTER_UNICAST (1 << 0)
-#define LPE_RXFILTER_BROADCAST (1 << 1)
-#define LPE_RXFILTER_MULTICAST (1 << 2)
-#define LPE_RXFILTER_UNIHASH (1 << 3)
-#define LPE_RXFILTER_MULTIHASH (1 << 4)
-#define LPE_RXFILTER_PERFECT (1 << 5)
-#define LPE_RXFILTER_WOL (1 << 12)
-#define LPE_RXFILTER_FILTWOL (1 << 13)
-#define LPE_RXFILTER_WOL_STATUS 0x204
-#define LPE_RXFILTER_WOL_CLEAR 0x208
-#define LPE_HASHFILTER_L 0x210
-#define LPE_HASHFILTER_H 0x214
-#define LPE_INTSTATUS 0xfe0
-#define LPE_INTENABLE 0xfe4
-#define LPE_INTCLEAR 0xfe8
-#define LPE_INTSET 0xfec
-#define LPE_INT_RXOVERRUN (1 << 0)
-#define LPE_INT_RXERROR (1 << 1)
-#define LPE_INT_RXFINISH (1 << 2)
-#define LPE_INT_RXDONE (1 << 3)
-#define LPE_INT_TXUNDERRUN (1 << 4)
-#define LPE_INT_TXERROR (1 << 5)
-#define LPE_INT_TXFINISH (1 << 6)
-#define LPE_INT_TXDONE (1 << 7)
-#define LPE_INT_SOFTINT (1 << 12)
-#define LPE_INTWAKEUPINT (1 << 13)
-#define LPE_POWERDOWN 0xff4
-
-#define LPE_DESC_ALIGN 8
-#define LPE_TXDESC_NUM 128
-#define LPE_RXDESC_NUM 128
-#define LPE_TXDESC_SIZE (LPE_TXDESC_NUM * sizeof(struct lpe_hwdesc))
-#define LPE_RXDESC_SIZE (LPE_RXDESC_NUM * sizeof(struct lpe_hwdesc))
-#define LPE_TXSTATUS_SIZE (LPE_TXDESC_NUM * sizeof(struct lpe_hwstatus))
-#define LPE_RXSTATUS_SIZE (LPE_RXDESC_NUM * sizeof(struct lpe_hwstatus))
-#define LPE_MAXFRAGS 8
-
-struct lpe_hwdesc {
- uint32_t lhr_data;
- uint32_t lhr_control;
-};
-
-struct lpe_hwstatus {
- uint32_t lhs_info;
- uint32_t lhs_crc;
-};
-
-#define LPE_INC(x, y) (x) = ((x) == ((y)-1)) ? 0 : (x)+1
-
-/* These are valid for both Rx and Tx descriptors */
-#define LPE_HWDESC_SIZE_MASK (1 << 10)
-#define LPE_HWDESC_INTERRUPT (1U << 31)
-
-/* These are valid for Tx descriptors */
-#define LPE_HWDESC_LAST (1 << 30)
-#define LPE_HWDESC_CRC (1 << 29)
-#define LPE_HWDESC_PAD (1 << 28)
-#define LPE_HWDESC_HUGE (1 << 27)
-#define LPE_HWDESC_OVERRIDE (1 << 26)
-
-/* These are valid for Tx status descriptors */
-#define LPE_HWDESC_COLLISIONS(_n) (((_n) >> 21) & 0x7)
-#define LPE_HWDESC_DEFER (1 << 25)
-#define LPE_HWDESC_EXCDEFER (1 << 26)
-#define LPE_HWDESC_EXCCOLL (1 << 27)
-#define LPE_HWDESC_LATECOLL (1 << 28)
-#define LPE_HWDESC_UNDERRUN (1 << 29)
-#define LPE_HWDESC_TXNODESCR (1 << 30)
-#define LPE_HWDESC_ERROR (1U << 31)
-
-/* These are valid for Rx status descriptors */
-#define LPE_HWDESC_CONTROL (1 << 18)
-#define LPE_HWDESC_VLAN (1 << 19)
-#define LPE_HWDESC_FAILFILTER (1 << 20)
-#define LPE_HWDESC_MULTICAST (1 << 21)
-#define LPE_HWDESC_BROADCAST (1 << 22)
-#define LPE_HWDESC_CRCERROR (1 << 23)
-#define LPE_HWDESC_SYMBOLERROR (1 << 24)
-#define LPE_HWDESC_LENGTHERROR (1 << 25)
-#define LPE_HWDESC_RANGEERROR (1 << 26)
-#define LPE_HWDESC_ALIGNERROR (1 << 27)
-#define LPE_HWDESC_OVERRUN (1 << 28)
-#define LPE_HWDESC_RXNODESCR (1 << 29)
-#define LPE_HWDESC_LASTFLAG (1 << 30)
-#define LPE_HWDESC_ERROR (1U << 31)
-
-
-#endif /* _ARM_LPC_IF_LPEREG_H */
diff --git a/freebsd/sys/arm/lpc/lpc_pwr.c b/freebsd/sys/arm/lpc/lpc_pwr.c
deleted file mode 100755
index dd1064c8..00000000
--- a/freebsd/sys/arm/lpc/lpc_pwr.c
+++ /dev/null
@@ -1,141 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2011 Jakub Wojciech Klama <jceel@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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <machine/bus.h>
-#ifndef __rtems__
-#include <machine/intr.h>
-
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-#endif /* __rtems__ */
-
-#include <arm/lpc/lpcreg.h>
-#include <arm/lpc/lpcvar.h>
-
-struct lpc_pwr_softc {
- device_t dp_dev;
- struct resource * dp_mem_res;
- bus_space_tag_t dp_bst;
- bus_space_handle_t dp_bsh;
-};
-
-static struct lpc_pwr_softc *lpc_pwr_sc = NULL;
-
-static int lpc_pwr_probe(device_t);
-static int lpc_pwr_attach(device_t);
-
-#define lpc_pwr_read_4(_sc, _reg) \
- bus_space_read_4((_sc)->dp_bst, (_sc)->dp_bsh, _reg)
-#define lpc_pwr_write_4(_sc, _reg, _val) \
- bus_space_write_4((_sc)->dp_bst, (_sc)->dp_bsh, _reg, _val)
-
-static int
-lpc_pwr_probe(device_t dev)
-{
-
-#ifndef __rtems__
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (!ofw_bus_is_compatible(dev, "lpc,pwr"))
- return (ENXIO);
-#endif /* __rtems__ */
-
- device_set_desc(dev, "LPC32x0 Power Controller");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-lpc_pwr_attach(device_t dev)
-{
- struct lpc_pwr_softc *sc = device_get_softc(dev);
- int rid;
-
- sc->dp_dev = dev;
-
- rid = 0;
- sc->dp_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->dp_mem_res) {
- device_printf(dev, "cannot allocate memory window\n");
- return (ENXIO);
- }
-
- sc->dp_bst = rman_get_bustag(sc->dp_mem_res);
- sc->dp_bsh = rman_get_bushandle(sc->dp_mem_res);
-
- lpc_pwr_sc = sc;
-
- return (0);
-}
-
-uint32_t
-lpc_pwr_read(device_t dev, int reg)
-{
- return (lpc_pwr_read_4(lpc_pwr_sc, reg));
-}
-
-void
-lpc_pwr_write(device_t dev, int reg, uint32_t value)
-{
- lpc_pwr_write_4(lpc_pwr_sc, reg, value);
-}
-
-static device_method_t lpc_pwr_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, lpc_pwr_probe),
- DEVMETHOD(device_attach, lpc_pwr_attach),
- { 0, 0 }
-};
-
-static devclass_t lpc_pwr_devclass;
-
-static driver_t lpc_pwr_driver = {
- "pwr",
- lpc_pwr_methods,
- sizeof(struct lpc_pwr_softc),
-};
-
-#ifndef __rtems__
-DRIVER_MODULE(pwr, simplebus, lpc_pwr_driver, lpc_pwr_devclass, 0, 0);
-#else /* __rtems__ */
-DRIVER_MODULE(pwr, nexus, lpc_pwr_driver, lpc_pwr_devclass, 0, 0);
-#endif /* __rtems__ */
diff --git a/freebsd/sys/arm/lpc/lpcreg.h b/freebsd/sys/arm/lpc/lpcreg.h
deleted file mode 100644
index d094e8f9..00000000
--- a/freebsd/sys/arm/lpc/lpcreg.h
+++ /dev/null
@@ -1,667 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2011 Jakub Wojciech Klama <jceel@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 _ARM_LPC_LPCREG_H
-#define _ARM_LPC_LPCREG_H
-
-#define LPC_DEV_PHYS_BASE 0x40000000
-#define LPC_DEV_P5_PHYS_BASE 0x20000000
-#define LPC_DEV_P6_PHYS_BASE 0x30000000
-#define LPC_DEV_SIZE 0x10000000
-
-/*
- * Interrupt controller (from UM10326: LPC32x0 User manual, page 87)
-
- */
-#define LPC_INTC_MIC_ER 0x0000
-#define LPC_INTC_MIC_RSR 0x0004
-#define LPC_INTC_MIC_SR 0x0008
-#define LPC_INTC_MIC_APR 0x000c
-#define LPC_INTC_MIC_ATR 0x0010
-#define LPC_INTC_MIC_ITR 0x0014
-#define LPC_INTC_SIC1_ER 0x4000
-#define LPC_INTC_SIC1_RSR 0x4004
-#define LPC_INTC_SIC1_SR 0x4008
-#define LPC_INTC_SIC1_APR 0x400c
-#define LPC_INTC_SIC1_ATR 0x4010
-#define LPC_INTC_SIC1_ITR 0x4014
-#define LPC_INTC_SIC2_ER 0x8000
-#define LPC_INTC_SIC2_RSR 0x8004
-#define LPC_INTC_SIC2_SR 0x8008
-#define LPC_INTC_SIC2_APR 0x800c
-#define LPC_INTC_SIC2_ATR 0x8010
-#define LPC_INTC_SIC2_ITR 0x8014
-
-
-/*
- * Timer 0|1|2|3|4|5. (from UM10326: LPC32x0 User manual, page 540)
- */
-#define LPC_TIMER_IR 0x00
-#define LPC_TIMER_TCR 0x04
-#define LPC_TIMER_TCR_ENABLE (1 << 0)
-#define LPC_TIMER_TCR_RESET (1 << 1)
-#define LPC_TIMER_TC 0x08
-#define LPC_TIMER_PR 0x0c
-#define LPC_TIMER_PC 0x10
-#define LPC_TIMER_MCR 0x14
-#define LPC_TIMER_MCR_MR0I (1 << 0)
-#define LPC_TIMER_MCR_MR0R (1 << 1)
-#define LPC_TIMER_MCR_MR0S (1 << 2)
-#define LPC_TIMER_MCR_MR1I (1 << 3)
-#define LPC_TIMER_MCR_MR1R (1 << 4)
-#define LPC_TIMER_MCR_MR1S (1 << 5)
-#define LPC_TIMER_MCR_MR2I (1 << 6)
-#define LPC_TIMER_MCR_MR2R (1 << 7)
-#define LPC_TIMER_MCR_MR2S (1 << 8)
-#define LPC_TIMER_MCR_MR3I (1 << 9)
-#define LPC_TIMER_MCR_MR3R (1 << 10)
-#define LPC_TIMER_MCR_MR3S (1 << 11)
-#define LPC_TIMER_MR0 0x18
-#define LPC_TIMER_CTCR 0x70
-
-/*
- * Watchdog timer. (from UM10326: LPC32x0 User manual, page 572)
- */
-#define LPC_WDTIM_PHYS_BASE (LPC_DEV_PHYS_BASE + 0x3c000)
-#define LPC_WDTIM_INT 0x00
-#define LPC_WDTIM_CTRL 0x04
-#define LPC_WDTIM_COUNTER 0x08
-#define LPC_WDTIM_MCTRL 0x0c
-#define LPC_WDTIM_MATCH0 0x10
-#define LPC_WDTIM_EMR 0x14
-#define LPC_WDTIM_PULSE 0x18
-#define LPC_WDTIM_RES 0x1c
-#define LPC_WDTIM_SIZE 0x20
-
-/*
- * Clocking and power control. (from UM10326: LPC32x0 User manual, page 58)
- */
-#define LPC_CLKPWR_PHYS_BASE (LPC_DEV_PHYS_BASE + 0x4000)
-#define LPC_CLKPWR_PWR_CTRL 0x44
-#define LPC_CLKPWR_OSC_CTRL 0x4c
-#define LPC_CLKPWR_SYSCLK_CTRL 0x50
-#define LPC_CLKPWR_PLL397_CTRL 0x48
-#define LPC_CLKPWR_HCLKPLL_CTRL 0x58
-#define LPC_CLKPWR_HCLKDIV_CTRL 0x40
-#define LPC_CLKPWR_TEST_CTRL 0xa4
-#define LPC_CLKPWR_AUTOCLK_CTRL 0xec
-#define LPC_CLKPWR_START_ER_PIN 0x30
-#define LPC_CLKPWR_START_ER_INT 0x20
-#define LPC_CLKPWR_P0_INTR_ER 0x18
-#define LPC_CLKPWR_START_SR_PIN 0x38
-#define LPC_CLKPWR_START_SR_INT 0x28
-#define LPC_CLKPWR_START_RSR_PIN 0x34
-#define LPC_CLKPWR_START_RSR_INT 0x24
-#define LPC_CLKPWR_START_APR_PIN 0x3c
-#define LPC_CLKPWR_START_APR_INT 0x2c
-#define LPC_CLKPWR_USB_CTRL 0x64
-#define LPC_CLKPWR_USB_CTRL_SLAVE_HCLK (1 << 24)
-#define LPC_CLKPWR_USB_CTRL_I2C_EN (1 << 23)
-#define LPC_CLKPWR_USB_CTRL_DEV_NEED_CLK_EN (1 << 22)
-#define LPC_CLKPWR_USB_CTRL_HOST_NEED_CLK_EN (1 << 21)
-#define LPC_CLKPWR_USB_CTRL_BUSKEEPER (1 << 19)
-#define LPC_CLKPWR_USB_CTRL_CLK_EN2 (1 << 18)
-#define LPC_CLKPWR_USB_CTRL_CLK_EN1 (1 << 17)
-#define LPC_CLKPWR_USB_CTRL_PLL_PDOWN (1 << 16)
-#define LPC_CLKPWR_USB_CTRL_BYPASS (1 << 15)
-#define LPC_CLKPWR_USB_CTRL_DIRECT_OUT (1 << 14)
-#define LPC_CLKPWR_USB_CTRL_FEEDBACK (1 << 13)
-#define LPC_CLKPWR_USB_CTRL_POSTDIV(_x) ((_x & 0x3) << 11)
-#define LPC_CLKPWR_USB_CTRL_PREDIV(_x) ((_x & 0x3) << 9)
-#define LPC_CLKPWR_USB_CTRL_FDBKDIV(_x) (((_x-1) & 0xff) << 1)
-#define LPC_CLKPWR_USB_CTRL_PLL_LOCK (1 << 0)
-#define LPC_CLKPWR_USBDIV_CTRL 0x1c
-#define LPC_CLKPWR_MS_CTRL 0x80
-#define LPC_CLKPWR_MS_CTRL_DISABLE_SD (1 << 10)
-#define LPC_CLKPWR_MS_CTRL_CLOCK_EN (1 << 9)
-#define LPC_CLKPWR_MS_CTRL_MSSDIO23_PAD (1 << 8)
-#define LPC_CLKPWR_MS_CTRL_MSSDIO1_PAD (1 << 7)
-#define LPC_CLKPWR_MS_CTRL_MSSDIO0_PAD (1 << 6)
-#define LPC_CLKPWR_MS_CTRL_SD_CLOCK (1 << 5)
-#define LPC_CLKPWR_MS_CTRL_CLKDIV_MASK 0xf
-#define LPC_CLKPWR_DMACLK_CTRL 0xe8
-#define LPC_CLKPWR_DMACLK_CTRL_EN (1 << 0)
-#define LPC_CLKPWR_FLASHCLK_CTRL 0xc8
-#define LPC_CLKPWR_MACCLK_CTRL 0x90
-#define LPC_CLKPWR_MACCLK_CTRL_REG (1 << 0)
-#define LPC_CLKPWR_MACCLK_CTRL_SLAVE (1 << 1)
-#define LPC_CLKPWR_MACCLK_CTRL_MASTER (1 << 2)
-#define LPC_CLKPWR_MACCLK_CTRL_HDWINF(_n) ((_n & 0x3) << 3)
-#define LPC_CLKPWR_LCDCLK_CTRL 0x54
-#define LPC_CLKPWR_LCDCLK_CTRL_DISPTYPE (1 << 8)
-#define LPC_CLKPWR_LCDCLK_CTRL_MODE(_n) ((_n & 0x3) << 6)
-#define LPC_CLKPWR_LCDCLK_CTRL_MODE_12 0x0
-#define LPC_CLKPWR_LCDCLK_CTRL_MODE_15 0x1
-#define LPC_CLKPWR_LCDCLK_CTRL_MODE_16 0x2
-#define LPC_CLKPWR_LCDCLK_CTRL_MODE_24 0x3
-#define LPC_CLKPWR_LCDCLK_CTRL_HCLKEN (1 << 5)
-#define LPC_CLKPWR_LCDCLK_CTRL_CLKDIV(_n) ((_n) & 0x1f)
-#define LPC_CLKPWR_I2S_CTRL 0x7c
-#define LPC_CLKPWR_SSP_CTRL 0x78
-#define LPC_CLKPWR_SSP_CTRL_SSP1RXDMA (1 << 5)
-#define LPC_CLKPWR_SSP_CTRL_SSP1TXDMA (1 << 4)
-#define LPC_CLKPWR_SSP_CTRL_SSP0RXDMA (1 << 3)
-#define LPC_CLKPWR_SSP_CTRL_SSP0TXDMA (1 << 2)
-#define LPC_CLKPWR_SSP_CTRL_SSP1EN (1 << 1)
-#define LPC_CLKPWR_SSP_CTRL_SSP0EN (1 << 0)
-#define LPC_CLKPWR_SPI_CTRL 0xc4
-#define LPC_CLKPWR_I2CCLK_CTRL 0xac
-#define LPC_CLKPWR_TIMCLK_CTRL1 0xc0
-#define LPC_CLKPWR_TIMCLK_CTRL1_TIMER4 (1 << 0)
-#define LPC_CLKPWR_TIMCLK_CTRL1_TIMER5 (1 << 1)
-#define LPC_CLKPWR_TIMCLK_CTRL1_TIMER0 (1 << 2)
-#define LPC_CLKPWR_TIMCLK_CTRL1_TIMER1 (1 << 3)
-#define LPC_CLKPWR_TIMCLK_CTRL1_TIMER2 (1 << 4)
-#define LPC_CLKPWR_TIMCLK_CTRL1_TIMER3 (1 << 5)
-#define LPC_CLKPWR_TIMCLK_CTRL1_MOTORCTL (1 << 6)
-#define LPC_CLKPWR_TIMCLK_CTRL 0xbc
-#define LPC_CLKPWR_TIMCLK_CTRL_WATCHDOG (1 << 0)
-#define LPC_CLKPWR_TIMCLK_CTRL_HSTIMER (1 << 1)
-#define LPC_CLKPWR_ADCLK_CTRL 0xb4
-#define LPC_CLKPWR_ADCLK_CTRL1 0x60
-#define LPC_CLKPWR_KEYCLK_CTRL 0xb0
-#define LPC_CLKPWR_PWMCLK_CTRL 0xb8
-#define LPC_CLKPWR_UARTCLK_CTRL 0xe4
-#define LPC_CLKPWR_POS0_IRAM_CTRL 0x110
-#define LPC_CLKPWR_POS1_IRAM_CTRL 0x114
-#define LPC_CLKPWR_SIZE 0x118
-
-/* Additional UART registers in CLKPWR address space. */
-#define LPC_CLKPWR_UART_U3CLK 0xd0
-#define LPC_CLKPWR_UART_U4CLK 0xd4
-#define LPC_CLKPWR_UART_U5CLK 0xd8
-#define LPC_CLKPWR_UART_U6CLK 0xdc
-#define LPC_CLKPWR_UART_UCLK_HCLK (1 << 16)
-#define LPC_CLKPWR_UART_UCLK_X(_n) (((_n) & 0xff) << 8)
-#define LPC_CLKPWR_UART_UCLK_Y(_n) ((_n) & 0xff)
-#define LPC_CLKPWR_UART_IRDACLK 0xe0
-
-/* Additional UART registers */
-#define LPC_UART_BASE 0x80000
-#define LPC_UART_CONTROL_BASE 0x54000
-#define LPC_UART5_BASE 0x90000
-#define LPC_UART_CTRL 0x00
-#define LPC_UART_CLKMODE 0x04
-#define LPC_UART_CLKMODE_UART3(_n) (((_n) & 0x3) << 4)
-#define LPC_UART_CLKMODE_UART4(_n) (((_n) & 0x3) << 6)
-#define LPC_UART_CLKMODE_UART5(_n) (((_n) & 0x3) << 8)
-#define LPC_UART_CLKMODE_UART6(_n) (((_n) & 0x3) << 10)
-#define LPC_UART_LOOP 0x08
-#define LPC_UART_CONTROL_SIZE 0x0c
-#define LPC_UART_FIFOSIZE 64
-
-/*
- * Real time clock. (from UM10326: LPC32x0 User manual, page 566)
- */
-#define LPC_RTC_UCOUNT 0x00
-#define LPC_RTC_DCOUNT 0x04
-#define LPC_RTC_MATCH0 0x08
-#define LPC_RTC_MATCH1 0x0c
-#define LPC_RTC_CTRL 0x10
-#define LPC_RTC_CTRL_ONSW (1 << 7)
-#define LPC_RTC_CTRL_DISABLE (1 << 6)
-#define LPC_RTC_CTRL_RTCRESET (1 << 4)
-#define LPC_RTC_CTRL_MATCH0ONSW (1 << 3)
-#define LPC_RTC_CTRL_MATCH1ONSW (1 << 2)
-#define LPC_RTC_CTRL_MATCH1INTR (1 << 1)
-#define LPC_RTC_CTRL_MATCH0INTR (1 << 0)
-#define LPC_RTC_INTSTAT 0x14
-#define LPC_RTC_KEY 0x18
-#define LPC_RTC_SRAM_BEGIN 0x80
-#define LPC_RTC_SRAM_END 0xff
-
-/*
- * MMC/SD controller. (from UM10326: LPC32x0 User manual, page 436)
- */
-#define LPC_SD_PHYS_BASE (LPC_DEV_P5_PHYS_BASE + 0x98000)
-#define LPC_SD_CLK (13 * 1000 * 1000) // 13Mhz
-#define LPC_SD_POWER 0x00
-#define LPC_SD_POWER_OPENDRAIN (1 << 6)
-#define LPC_SD_POWER_CTRL_OFF 0x00
-#define LPC_SD_POWER_CTRL_UP 0x02
-#define LPC_SD_POWER_CTRL_ON 0x03
-#define LPC_SD_CLOCK 0x04
-#define LPC_SD_CLOCK_WIDEBUS (1 << 11)
-#define LPC_SD_CLOCK_BYPASS (1 << 10)
-#define LPC_SD_CLOCK_PWRSAVE (1 << 9)
-#define LPC_SD_CLOCK_ENABLE (1 << 8)
-#define LPC_SD_CLOCK_CLKDIVMASK 0xff
-#define LPC_SD_ARGUMENT 0x08
-#define LPC_SD_COMMAND 0x0c
-#define LPC_SD_COMMAND_ENABLE (1 << 10)
-#define LPC_SD_COMMAND_PENDING (1 << 9)
-#define LPC_SD_COMMAND_INTERRUPT (1 << 8)
-#define LPC_SD_COMMAND_LONGRSP (1 << 7)
-#define LPC_SD_COMMAND_RESPONSE (1 << 6)
-#define LPC_SD_COMMAND_CMDINDEXMASK 0x3f
-#define LPC_SD_RESPCMD 0x10
-#define LPC_SD_RESP0 0x14
-#define LPC_SD_RESP1 0x18
-#define LPC_SD_RESP2 0x1c
-#define LPC_SD_RESP3 0x20
-#define LPC_SD_DATATIMER 0x24
-#define LPC_SD_DATALENGTH 0x28
-#define LPC_SD_DATACTRL 0x2c
-#define LPC_SD_DATACTRL_BLOCKSIZESHIFT 4
-#define LPC_SD_DATACTRL_BLOCKSIZEMASK 0xf
-#define LPC_SD_DATACTRL_DMAENABLE (1 << 3)
-#define LPC_SD_DATACTRL_MODE (1 << 2)
-#define LPC_SD_DATACTRL_WRITE (0 << 1)
-#define LPC_SD_DATACTRL_READ (1 << 1)
-#define LPC_SD_DATACTRL_ENABLE (1 << 0)
-#define LPC_SD_DATACNT 0x30
-#define LPC_SD_STATUS 0x34
-#define LPC_SD_STATUS_RXDATAAVLBL (1 << 21)
-#define LPC_SD_STATUS_TXDATAAVLBL (1 << 20)
-#define LPC_SD_STATUS_RXFIFOEMPTY (1 << 19)
-#define LPC_SD_STATUS_TXFIFOEMPTY (1 << 18)
-#define LPC_SD_STATUS_RXFIFOFULL (1 << 17)
-#define LPC_SD_STATUS_TXFIFOFULL (1 << 16)
-#define LPC_SD_STATUS_RXFIFOHALFFULL (1 << 15)
-#define LPC_SD_STATUS_TXFIFOHALFEMPTY (1 << 14)
-#define LPC_SD_STATUS_RXACTIVE (1 << 13)
-#define LPC_SD_STATUS_TXACTIVE (1 << 12)
-#define LPC_SD_STATUS_CMDACTIVE (1 << 11)
-#define LPC_SD_STATUS_DATABLOCKEND (1 << 10)
-#define LPC_SD_STATUS_STARTBITERR (1 << 9)
-#define LPC_SD_STATUS_DATAEND (1 << 8)
-#define LPC_SD_STATUS_CMDSENT (1 << 7)
-#define LPC_SD_STATUS_CMDRESPEND (1 << 6)
-#define LPC_SD_STATUS_RXOVERRUN (1 << 5)
-#define LPC_SD_STATUS_TXUNDERRUN (1 << 4)
-#define LPC_SD_STATUS_DATATIMEOUT (1 << 3)
-#define LPC_SD_STATUS_CMDTIMEOUT (1 << 2)
-#define LPC_SD_STATUS_DATACRCFAIL (1 << 1)
-#define LPC_SD_STATUS_CMDCRCFAIL (1 << 0)
-#define LPC_SD_CLEAR 0x38
-#define LPC_SD_MASK0 0x03c
-#define LPC_SD_MASK1 0x40
-#define LPC_SD_FIFOCNT 0x48
-#define LPC_SD_FIFO 0x80
-
-/*
- * USB OTG controller (from UM10326: LPC32x0 User manual, page 410)
- */
-#define LPC_OTG_INT_STATUS 0x100
-#define LPC_OTG_INT_ENABLE 0x104
-#define LPC_OTG_INT_SET 0x108
-#define LPC_OTG_INT_CLEAR 0x10c
-#define LPC_OTG_STATUS 0x110
-#define LPC_OTG_STATUS_ATOB_HNP_TRACK (1 << 9)
-#define LPC_OTG_STATUS_BTOA_HNP_TACK (1 << 8)
-#define LPC_OTG_STATUS_TRANSP_I2C_EN (1 << 7)
-#define LPC_OTG_STATUS_TIMER_RESET (1 << 6)
-#define LPC_OTG_STATUS_TIMER_EN (1 << 5)
-#define LPC_OTG_STATUS_TIMER_MODE (1 << 4)
-#define LPC_OTG_STATUS_TIMER_SCALE (1 << 2)
-#define LPC_OTG_STATUS_HOST_EN (1 << 0)
-#define LPC_OTG_TIMER 0x114
-#define LPC_OTG_I2C_TXRX 0x300
-#define LPC_OTG_I2C_STATUS 0x304
-#define LPC_OTG_I2C_STATUS_TFE (1 << 11)
-#define LPC_OTG_I2C_STATUS_TFF (1 << 10)
-#define LPC_OTG_I2C_STATUS_RFE (1 << 9)
-#define LPC_OTG_I2C_STATUS_RFF (1 << 8)
-#define LPC_OTG_I2C_STATUS_SDA (1 << 7)
-#define LPC_OTG_I2C_STATUS_SCL (1 << 6)
-#define LPC_OTG_I2C_STATUS_ACTIVE (1 << 5)
-#define LPC_OTG_I2C_STATUS_DRSI (1 << 4)
-#define LPC_OTG_I2C_STATUS_DRMI (1 << 3)
-#define LPC_OTG_I2C_STATUS_NAI (1 << 2)
-#define LPC_OTG_I2C_STATUS_AFI (1 << 1)
-#define LPC_OTG_I2C_STATUS_TDI (1 << 0)
-#define LPC_OTG_I2C_CTRL 0x308
-#define LPC_OTG_I2C_CTRL_SRST (1 << 8)
-#define LPC_OTG_I2C_CTRL_TFFIE (1 << 7)
-#define LPC_OTG_I2C_CTRL_RFDAIE (1 << 6)
-#define LPC_OTG_I2C_CTRL_RFFIE (1 << 5)
-#define LPC_OTG_I2C_CTRL_DRSIE (1 << 4)
-#define LPC_OTG_I2C_CTRL_DRMIE (1 << 3)
-#define LPC_OTG_I2C_CTRL_NAIE (1 << 2)
-#define LPC_OTG_I2C_CTRL_AFIE (1 << 1)
-#define LPC_OTG_I2C_CTRL_TDIE (1 << 0)
-#define LPC_OTG_I2C_CLKHI 0x30c
-#define LPC_OTG_I2C_CLKLO 0x310
-#define LPC_OTG_CLOCK_CTRL 0xff4
-#define LPC_OTG_CLOCK_CTRL_AHB_EN (1 << 4)
-#define LPC_OTG_CLOCK_CTRL_OTG_EN (1 << 3)
-#define LPC_OTG_CLOCK_CTRL_I2C_EN (1 << 2)
-#define LPC_OTG_CLOCK_CTRL_DEV_EN (1 << 1)
-#define LPC_OTG_CLOCK_CTRL_HOST_EN (1 << 0)
-#define LPC_OTG_CLOCK_STATUS 0xff8
-
-/*
- * ISP3101 USB transceiver registers
- */
-#define LPC_ISP3101_I2C_ADDR 0x2d
-#define LPC_ISP3101_MODE_CONTROL_1 0x04
-#define LPC_ISP3101_MC1_SPEED_REG (1 << 0)
-#define LPC_ISP3101_MC1_SUSPEND_REG (1 << 1)
-#define LPC_ISP3101_MC1_DAT_SE0 (1 << 2)
-#define LPC_ISP3101_MC1_TRANSPARENT (1 << 3)
-#define LPC_ISP3101_MC1_BDIS_ACON_EN (1 << 4)
-#define LPC_ISP3101_MC1_OE_INT_EN (1 << 5)
-#define LPC_ISP3101_MC1_UART_EN (1 << 6)
-#define LPC_ISP3101_MODE_CONTROL_2 0x12
-#define LPC_ISP3101_MC2_GLOBAL_PWR_DN (1 << 0)
-#define LPC_ISP3101_MC2_SPD_SUSP_CTRL (1 << 1)
-#define LPC_ISP3101_MC2_BI_DI (1 << 2)
-#define LPC_ISP3101_MC2_TRANSP_BDIR0 (1 << 3)
-#define LPC_ISP3101_MC2_TRANSP_BDIR1 (1 << 4)
-#define LPC_ISP3101_MC2_AUDIO_EN (1 << 5)
-#define LPC_ISP3101_MC2_PSW_EN (1 << 6)
-#define LPC_ISP3101_MC2_EN2V7 (1 << 7)
-#define LPC_ISP3101_OTG_CONTROL_1 0x06
-#define LPC_ISP3101_OTG1_DP_PULLUP (1 << 0)
-#define LPC_ISP3101_OTG1_DM_PULLUP (1 << 1)
-#define LPC_ISP3101_OTG1_DP_PULLDOWN (1 << 2)
-#define LPC_ISP3101_OTG1_DM_PULLDOWN (1 << 3)
-#define LPC_ISP3101_OTG1_ID_PULLDOWN (1 << 4)
-#define LPC_ISP3101_OTG1_VBUS_DRV (1 << 5)
-#define LPC_ISP3101_OTG1_VBUS_DISCHRG (1 << 6)
-#define LPC_ISP3101_OTG1_VBUS_CHRG (1 << 7)
-#define LPC_ISP3101_OTG_CONTROL_2 0x10
-#define LPC_ISP3101_OTG_INTR_LATCH 0x0a
-#define LPC_ISP3101_OTG_INTR_FALLING 0x0c
-#define LPC_ISP3101_OTG_INTR_RISING 0x0e
-#define LPC_ISP3101_REG_CLEAR_ADDR 0x01
-
-/*
- * LCD Controller (from UM10326: LPC32x0 User manual, page 229)
- */
-#define LPC_LCD_TIMH 0x00
-#define LPC_LCD_TIMH_HBP(_n) (((_n) & 0xff) << 24)
-#define LPC_LCD_TIMH_HFP(_n) (((_n) & 0xff) << 16)
-#define LPC_LCD_TIMH_HSW(_n) (((_n) & 0xff) << 8)
-#define LPC_LCD_TIMH_PPL(_n) (((_n) / 16 - 1) << 2)
-#define LPC_LCD_TIMV 0x04
-#define LPC_LCD_TIMV_VBP(_n) (((_n) & 0xff) << 24)
-#define LPC_LCD_TIMV_VFP(_n) (((_n) & 0xff) << 16)
-#define LPC_LCD_TIMV_VSW(_n) (((_n) & 0x3f) << 10)
-#define LPC_LCD_TIMV_LPP(_n) ((_n) & 0x1ff)
-#define LPC_LCD_POL 0x08
-#define LPC_LCD_POL_PCD_HI (((_n) & 0x1f) << 27)
-#define LPC_LCD_POL_BCD (1 << 26)
-#define LPC_LCD_POL_CPL(_n) (((_n) & 0x3ff) << 16)
-#define LPC_LCD_POL_IOE (1 << 14)
-#define LPC_LCD_POL_IPC (1 << 13)
-#define LPC_LCD_POL_IHS (1 << 12)
-#define LPC_LCD_POL_IVS (1 << 11)
-#define LPC_LCD_POL_ACB(_n) ((_n & 0x1f) << 6)
-#define LPC_LCD_POL_CLKSEL (1 << 5)
-#define LPC_LCD_POL_PCD_LO(_n) ((_n) & 0x1f)
-#define LPC_LCD_LE 0x0c
-#define LPC_LCD_LE_LEE (1 << 16)
-#define LPC_LCD_LE_LED ((_n) & 0x7f)
-#define LPC_LCD_UPBASE 0x10
-#define LPC_LCD_LPBASE 0x14
-#define LPC_LCD_CTRL 0x18
-#define LPC_LCD_CTRL_WATERMARK (1 << 16)
-#define LPC_LCD_CTRL_LCDVCOMP(_n) (((_n) & 0x3) << 12)
-#define LPC_LCD_CTRL_LCDPWR (1 << 11)
-#define LPC_LCD_CTRL_BEPO (1 << 10)
-#define LPC_LCD_CTRL_BEBO (1 << 9)
-#define LPC_LCD_CTRL_BGR (1 << 8)
-#define LPC_LCD_CTRL_LCDDUAL (1 << 7)
-#define LPC_LCD_CTRL_LCDMONO8 (1 << 6)
-#define LPC_LCD_CTRL_LCDTFT (1 << 5)
-#define LPC_LCD_CTRL_LCDBW (1 << 4)
-#define LPC_LCD_CTRL_LCDBPP(_n) (((_n) & 0x7) << 1)
-#define LPC_LCD_CTRL_BPP1 0
-#define LPC_LCD_CTRL_BPP2 1
-#define LPC_LCD_CTRL_BPP4 2
-#define LPC_LCD_CTRL_BPP8 3
-#define LPC_LCD_CTRL_BPP16 4
-#define LPC_LCD_CTRL_BPP24 5
-#define LPC_LCD_CTRL_BPP16_565 6
-#define LPC_LCD_CTRL_BPP12_444 7
-#define LPC_LCD_CTRL_LCDEN (1 << 0)
-#define LPC_LCD_INTMSK 0x1c
-#define LPC_LCD_INTRAW 0x20
-#define LPC_LCD_INTSTAT 0x24
-#define LPC_LCD_INTCLR 0x28
-#define LPC_LCD_UPCURR 0x2c
-#define LPC_LCD_LPCURR 0x30
-#define LPC_LCD_PAL 0x200
-#define LPC_LCD_CRSR_IMG 0x800
-#define LPC_LCD_CRSR_CTRL 0xc00
-#define LPC_LCD_CRSR_CFG 0xc04
-#define LPC_LCD_CRSR_PAL0 0xc08
-#define LPC_LCD_CRSR_PAL1 0xc0c
-#define LPC_LCD_CRSR_XY 0xc10
-#define LPC_LCD_CRSR_CLIP 0xc14
-#define LPC_LCD_CRSR_INTMSK 0xc20
-#define LPC_LCD_CRSR_INTCLR 0xc24
-#define LPC_LCD_CRSR_INTRAW 0xc28
-#define LPC_LCD_CRSR_INTSTAT 0xc2c
-
-/*
- * SPI interface (from UM10326: LPC32x0 User manual, page 483)
- */
-#define LPC_SPI_GLOBAL 0x00
-#define LPC_SPI_GLOBAL_RST (1 << 1)
-#define LPC_SPI_GLOBAL_ENABLE (1 << 0)
-#define LPC_SPI_CON 0x04
-#define LPC_SPI_CON_UNIDIR (1 << 23)
-#define LPC_SPI_CON_BHALT (1 << 22)
-#define LPC_SPI_CON_BPOL (1 << 21)
-#define LPC_SPI_CON_MSB (1 << 19)
-#define LPC_SPI_CON_MODE(_n) ((_n & 0x3) << 16)
-#define LPC_SPI_CON_RXTX (1 << 15)
-#define LPC_SPI_CON_THR (1 << 14)
-#define LPC_SPI_CON_SHIFT_OFF (1 << 13)
-#define LPC_SPI_CON_BITNUM(_n) ((_n & 0xf) << 9)
-#define LPC_SPI_CON_MS (1 << 7)
-#define LPC_SPI_CON_RATE(_n) (_n & 0x7f)
-#define LPC_SPI_FRM 0x08
-#define LPC_SPI_IER 0x0c
-#define LPC_SPI_IER_INTEOT (1 << 1)
-#define LPC_SPI_IER_INTTHR (1 << 0)
-#define LPC_SPI_STAT 0x10
-#define LPC_SPI_STAT_INTCLR (1 << 8)
-#define LPC_SPI_STAT_EOT (1 << 7)
-#define LPC_SPI_STAT_BUSYLEV (1 << 6)
-#define LPC_SPI_STAT_SHIFTACT (1 << 3)
-#define LPC_SPI_STAT_BF (1 << 2)
-#define LPC_SPI_STAT_THR (1 << 1)
-#define LPC_SPI_STAT_BE (1 << 0)
-#define LPC_SPI_DAT 0x14
-#define LPC_SPI_TIM_CTRL 0x400
-#define LPC_SPI_TIM_COUNT 0x404
-#define LPC_SPI_TIM_STAT 0x408
-
-/*
- * SSP interface (from UM10326: LPC32x0 User manual, page 500)
- */
-#define LPC_SSP0_BASE 0x4c00
-#define LPC_SSP1_BASE 0xc000
-#define LPC_SSP_CR0 0x00
-#define LPC_SSP_CR0_DSS(_n) ((_n-1) & 0xf)
-#define LPC_SSP_CR0_TI (1 << 4)
-#define LPC_SSP_CR0_MICROWIRE (1 << 5)
-#define LPC_SSP_CR0_CPOL (1 << 6)
-#define LPC_SSP_CR0_CPHA (1 << 7)
-#define LPC_SSP_CR0_SCR(_n) ((_x & & 0xff) << 8)
-#define LPC_SSP_CR1 0x04
-#define LPC_SSP_CR1_LBM (1 << 0)
-#define LPC_SSP_CR1_SSE (1 << 1)
-#define LPC_SSP_CR1_MS (1 << 2)
-#define LPC_SSP_CR1_SOD (1 << 3)
-#define LPC_SSP_DR 0x08
-#define LPC_SSP_SR 0x0c
-#define LPC_SSP_SR_TFE (1 << 0)
-#define LPC_SSP_SR_TNF (1 << 1)
-#define LPC_SSP_SR_RNE (1 << 2)
-#define LPC_SSP_SR_RFF (1 << 3)
-#define LPC_SSP_SR_BSY (1 << 4)
-#define LPC_SSP_CPSR 0x10
-#define LPC_SSP_IMSC 0x14
-#define LPC_SSP_IMSC_RORIM (1 << 0)
-#define LPC_SSP_IMSC_RTIM (1 << 1)
-#define LPC_SSP_IMSC_RXIM (1 << 2)
-#define LPC_SSP_IMSC_TXIM (1 << 3)
-#define LPC_SSP_RIS 0x18
-#define LPC_SSP_RIS_RORRIS (1 << 0)
-#define LPC_SSP_RIS_RTRIS (1 << 1)
-#define LPC_SSP_RIS_RXRIS (1 << 2)
-#define LPC_SSP_RIS_TXRIS (1 << 3)
-#define LPC_SSP_MIS 0x1c
-#define LPC_SSP_ICR 0x20
-#define LPC_SSP_DMACR 0x24
-
-/*
- * GPIO (from UM10326: LPC32x0 User manual, page 606)
- */
-#define LPC_GPIO_PHYS_BASE (LPC_DEV_PHYS_BASE + 0x28000)
-#define LPC_GPIO_P0_COUNT 8
-#define LPC_GPIO_P1_COUNT 24
-#define LPC_GPIO_P2_COUNT 13
-#define LPC_GPIO_P3_COUNT 52
-#define LPC_GPIO_P0_INP_STATE 0x40
-#define LPC_GPIO_P0_OUTP_SET 0x44
-#define LPC_GPIO_P0_OUTP_CLR 0x48
-#define LPC_GPIO_P0_OUTP_STATE 0x4c
-#define LPC_GPIO_P0_DIR_SET 0x50
-#define LPC_GPIO_P0_DIR_CLR 0x54
-#define LPC_GPIO_P0_DIR_STATE 0x58
-#define LPC_GPIO_P1_INP_STATE 0x60
-#define LPC_GPIO_P1_OUTP_SET 0x64
-#define LPC_GPIO_P1_OUTP_CLR 0x68
-#define LPC_GPIO_P1_OUTP_STATE 0x6c
-#define LPC_GPIO_P1_DIR_SET 0x70
-#define LPC_GPIO_P1_DIR_CLR 0x74
-#define LPC_GPIO_P1_DIR_STATE 0x78
-#define LPC_GPIO_P2_INP_STATE 0x1c
-#define LPC_GPIO_P2_OUTP_SET 0x20
-#define LPC_GPIO_P2_OUTP_CLR 0x24
-#define LPC_GPIO_P2_DIR_SET 0x10
-#define LPC_GPIO_P2_DIR_CLR 0x14
-#define LPC_GPIO_P2_DIR_STATE 0x14
-#define LPC_GPIO_P3_INP_STATE 0x00
-#define LPC_GPIO_P3_OUTP_SET 0x04
-#define LPC_GPIO_P3_OUTP_CLR 0x08
-#define LPC_GPIO_P3_OUTP_STATE 0x0c
-#define LPC_GPIO_SIZE 0x80
-
-/* Aliases for logical pin numbers: */
-#define LPC_GPIO_GPI_00(_n) (0 + _n)
-#define LPC_GPIO_GPI_15(_n) (10 + _n)
-#define LPC_GPIO_GPI_25 (19)
-#define LPC_GPIO_GPI_27(_n) (20 + _n)
-#define LPC_GPIO_GPO_00(_n) (22 + _n)
-#define LPC_GPIO_GPIO_00(_n) (46 + _n)
-/* SPI devices chip selects: */
-#define SSD1289_CS_PIN LPC_GPIO_GPO_00(4)
-#define SSD1289_DC_PIN LPC_GPIO_GPO_00(5)
-#define ADS7846_CS_PIN LPC_GPIO_GPO_00(11)
-#define ADS7846_INTR_PIN LPC_GPIO_GPIO_00(0)
-
-/*
- * GPDMA controller (from UM10326: LPC32x0 User manual, page 106)
- */
-#define LPC_DMAC_INTSTAT 0x00
-#define LPC_DMAC_INTTCSTAT 0x04
-#define LPC_DMAC_INTTCCLEAR 0x08
-#define LPC_DMAC_INTERRSTAT 0x0c
-#define LPC_DMAC_INTERRCLEAR 0x10
-#define LPC_DMAC_RAWINTTCSTAT 0x14
-#define LPC_DMAC_RAWINTERRSTAT 0x18
-#define LPC_DMAC_ENABLED_CHANNELS 0x1c
-#define LPC_DMAC_SOFTBREQ 0x20
-#define LPC_DMAC_SOFTSREQ 0x24
-#define LPC_DMAC_SOFTLBREQ 0x28
-#define LPC_DMAC_SOFTLSREQ 0x2c
-#define LPC_DMAC_CONFIG 0x30
-#define LPC_DMAC_CONFIG_M1 (1 << 2)
-#define LPC_DMAC_CONFIG_M0 (1 << 1)
-#define LPC_DMAC_CONFIG_ENABLE (1 << 0)
-#define LPC_DMAC_CHADDR(_n) (0x100 + (_n * 0x20))
-#define LPC_DMAC_CHNUM 8
-#define LPC_DMAC_CHSIZE 0x20
-#define LPC_DMAC_CH_SRCADDR 0x00
-#define LPC_DMAC_CH_DSTADDR 0x04
-#define LPC_DMAC_CH_LLI 0x08
-#define LPC_DMAC_CH_LLI_AHB1 (1 << 0)
-#define LPC_DMAC_CH_CONTROL 0x0c
-#define LPC_DMAC_CH_CONTROL_I (1U << 31)
-#define LPC_DMAC_CH_CONTROL_DI (1 << 27)
-#define LPC_DMAC_CH_CONTROL_SI (1 << 26)
-#define LPC_DMAC_CH_CONTROL_D (1 << 25)
-#define LPC_DMAC_CH_CONTROL_S (1 << 24)
-#define LPC_DMAC_CH_CONTROL_WIDTH_4 2
-#define LPC_DMAC_CH_CONTROL_DWIDTH(_n) ((_n & 0x7) << 21)
-#define LPC_DMAC_CH_CONTROL_SWIDTH(_n) ((_n & 0x7) << 18)
-#define LPC_DMAC_CH_CONTROL_BURST_8 2
-#define LPC_DMAC_CH_CONTROL_DBSIZE(_n) ((_n & 0x7) << 15)
-#define LPC_DMAC_CH_CONTROL_SBSIZE(_n) ((_n & 0x7) << 12)
-#define LPC_DMAC_CH_CONTROL_XFERLEN(_n) (_n & 0xfff)
-#define LPC_DMAC_CH_CONFIG 0x10
-#define LPC_DMAC_CH_CONFIG_H (1 << 18)
-#define LPC_DMAC_CH_CONFIG_A (1 << 17)
-#define LPC_DMAC_CH_CONFIG_L (1 << 16)
-#define LPC_DMAC_CH_CONFIG_ITC (1 << 15)
-#define LPC_DMAC_CH_CONFIG_IE (1 << 14)
-#define LPC_DMAC_CH_CONFIG_FLOWCNTL(_n) ((_n & 0x7) << 11)
-#define LPC_DMAC_CH_CONFIG_DESTP(_n) ((_n & 0x1f) << 6)
-#define LPC_DMAC_CH_CONFIG_SRCP(_n) ((_n & 0x1f) << 1)
-#define LPC_DMAC_CH_CONFIG_E (1 << 0)
-
-/* DMA flow control values */
-#define LPC_DMAC_FLOW_D_M2M 0
-#define LPC_DMAC_FLOW_D_M2P 1
-#define LPC_DMAC_FLOW_D_P2M 2
-#define LPC_DMAC_FLOW_D_P2P 3
-#define LPC_DMAC_FLOW_DP_P2P 4
-#define LPC_DMAC_FLOW_P_M2P 5
-#define LPC_DMAC_FLOW_P_P2M 6
-#define LPC_DMAC_FLOW_SP_P2P 7
-
-/* DMA peripheral ID's */
-#define LPC_DMAC_I2S0_DMA0_ID 0
-#define LPC_DMAC_NAND_ID 1
-#define LPC_DMAC_IS21_DMA0_ID 2
-#define LPC_DMAC_SSP1_ID 3
-#define LPC_DMAC_SPI2_ID 3
-#define LPC_DMAC_SD_ID 4
-#define LPC_DMAC_UART1_TX_ID 5
-#define LPC_DMAC_UART1_RX_ID 6
-#define LPC_DMAC_UART2_TX_ID 7
-#define LPC_DMAC_UART2_RX_ID 8
-#define LPC_DMAC_UART7_TX_ID 9
-#define LPC_DMAC_UART7_RX_ID 10
-#define LPC_DMAC_I2S1_DMA1_ID 10
-#define LPC_DMAC_SPI1_ID 11
-#define LPC_DMAC_SSP1_TX_ID 11
-#define LPC_DMAC_NAND2_ID 12
-#define LPC_DMAC_I2S0_DMA1_ID 13
-#define LPC_DMAC_SSP0_RX 14
-#define LPC_DMAC_SSP0_TX 15
-
-#endif /* _ARM_LPC_LPCREG_H */
diff --git a/freebsd/sys/arm/lpc/lpcvar.h b/freebsd/sys/arm/lpc/lpcvar.h
deleted file mode 100644
index dafbef08..00000000
--- a/freebsd/sys/arm/lpc/lpcvar.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2011 Jakub Wojciech Klama <jceel@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 _ARM_LPC_LPCVAR_H
-#define _ARM_LPC_LPCVAR_H
-
-#include <sys/types.h>
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-/* Clocking and power control */
-uint32_t lpc_pwr_read(device_t, int);
-void lpc_pwr_write(device_t, int, uint32_t);
-
-/* GPIO */
-void lpc_gpio_init(void);
-int lpc_gpio_set_flags(device_t, int, int);
-int lpc_gpio_set_state(device_t, int, int);
-int lpc_gpio_get_state(device_t, int, int *);
-
-/* DMA */
-struct lpc_dmac_channel_config
-{
- int ldc_fcntl;
- int ldc_src_periph;
- int ldc_src_width;
- int ldc_src_incr;
- int ldc_src_burst;
- int ldc_dst_periph;
- int ldc_dst_width;
- int ldc_dst_incr;
- int ldc_dst_burst;
- void (*ldc_success_handler)(void *);
- void (*ldc_error_handler)(void *);
- void * ldc_handler_arg;
-};
-
-int lpc_dmac_config_channel(device_t, int, struct lpc_dmac_channel_config *);
-int lpc_dmac_setup_transfer(device_t, int, bus_addr_t, bus_addr_t, bus_size_t, int);
-int lpc_dmac_enable_channel(device_t, int);
-int lpc_dmac_disable_channel(device_t, int);
-int lpc_dmac_start_burst(device_t, int);
-
-#endif /* _ARM_LPC_LPCVAR_H */
diff --git a/freebsd/sys/cam/cam_ccb.h b/freebsd/sys/cam/cam_ccb.h
index 8e88b4a3..642e7862 100644
--- a/freebsd/sys/cam/cam_ccb.h
+++ b/freebsd/sys/cam/cam_ccb.h
@@ -519,7 +519,6 @@ struct device_match_result {
struct scsi_inquiry_data inq_data;
struct ata_params ident_data;
dev_result_flags flags;
- struct mmc_params mmc_ident_data;
};
struct bus_match_result {
@@ -646,6 +645,11 @@ struct ccb_pathinq_settings_sas {
struct ccb_pathinq_settings_nvme {
uint32_t nsid; /* Namespace ID for this path */
+ uint32_t domain;
+ uint8_t bus;
+ uint8_t slot;
+ uint8_t function;
+ uint8_t extra;
};
#define PATHINQ_SETTINGS_SIZE 128
@@ -1296,6 +1300,7 @@ struct ccb_dev_advinfo {
#define CDAI_TYPE_EXT_INQ 5
#define CDAI_TYPE_NVME_CNTRL 6 /* NVMe Identify Controller data */
#define CDAI_TYPE_NVME_NS 7 /* NVMe Identify Namespace data */
+#define CDAI_TYPE_MMC_PARAMS 8 /* MMC/SD ident */
off_t bufsiz; /* IN: Size of external buffer */
#define CAM_SCSI_DEVID_MAXLEN 65536 /* length in buffer is an uint16_t */
off_t provsiz; /* OUT: Size required/used */
diff --git a/freebsd/sys/cam/cam_periph.h b/freebsd/sys/cam/cam_periph.h
index b7f0618e..ee9a5fc0 100644
--- a/freebsd/sys/cam/cam_periph.h
+++ b/freebsd/sys/cam/cam_periph.h
@@ -197,12 +197,15 @@ void cam_periph_freeze_after_event(struct cam_periph *periph,
struct timeval* event_time,
u_int duration_ms);
int cam_periph_error(union ccb *ccb, cam_flags camflags,
- u_int32_t sense_flags, union ccb *save_ccb);
+ u_int32_t sense_flags);
static __inline struct mtx *
cam_periph_mtx(struct cam_periph *periph)
{
- return (xpt_path_mtx(periph->path));
+ if (periph != NULL)
+ return (xpt_path_mtx(periph->path));
+ else
+ return (NULL);
}
#define cam_periph_owned(periph) \
@@ -257,5 +260,8 @@ cam_periph_acquire_next(struct cam_periph *pperiph)
(periph) != NULL; \
(periph) = cam_periph_acquire_next(periph))
+#define CAM_PERIPH_PRINT(p, msg, args...) \
+ printf("%s%d:" msg, (periph)->periph_name, (periph)->unit_number, ##args)
+
#endif /* _KERNEL */
#endif /* _CAM_CAM_PERIPH_H */
diff --git a/freebsd/sys/cam/cam_xpt.h b/freebsd/sys/cam/cam_xpt.h
index 8baec294..fb49c893 100644
--- a/freebsd/sys/cam/cam_xpt.h
+++ b/freebsd/sys/cam/cam_xpt.h
@@ -36,8 +36,10 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
+#include <cam/cam_ccb.h>
#endif
+
/* Forward Declarations */
union ccb;
struct cam_periph;
@@ -144,6 +146,22 @@ void xpt_copy_path(struct cam_path *new_path,
void xpt_release_path(struct cam_path *path);
const char * xpt_action_name(uint32_t action);
+void xpt_pollwait(union ccb *start_ccb, uint32_t timeout);
+uint32_t xpt_poll_setup(union ccb *start_ccb);
+
+/*
+ * Perform a path inquiry at the request priority. The bzero may be
+ * unnecessary.
+ */
+static inline void
+xpt_path_inq(struct ccb_pathinq *cpi, struct cam_path *path)
+{
+
+ bzero(cpi, sizeof(*cpi));
+ xpt_setup_ccb(&cpi->ccb_h, path, CAM_PRIORITY_NORMAL);
+ cpi->ccb_h.func_code = XPT_PATH_INQ;
+ xpt_action((union ccb *)cpi);
+}
#endif /* _KERNEL */
diff --git a/freebsd/sys/cam/mmc/mmc.h b/freebsd/sys/cam/mmc/mmc.h
index 2e31f029..9b9659fe 100644
--- a/freebsd/sys/cam/mmc/mmc.h
+++ b/freebsd/sys/cam/mmc/mmc.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2014-2016 Ilya Bakulin. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/freebsd/sys/cam/mmc/mmc_all.h b/freebsd/sys/cam/mmc/mmc_all.h
index c2494894..cbc32c0d 100644
--- a/freebsd/sys/cam/mmc/mmc_all.h
+++ b/freebsd/sys/cam/mmc/mmc_all.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2014-2016 Ilya Bakulin. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/freebsd/sys/cam/nvme/nvme_all.h b/freebsd/sys/cam/nvme/nvme_all.h
index b2db4833..fa229846 100644
--- a/freebsd/sys/cam/nvme/nvme_all.h
+++ b/freebsd/sys/cam/nvme/nvme_all.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2015 Netflix, Inc
* All rights reserved.
*
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index d344cc14..1a469f32 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -1,10 +1,10 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
* Implementation of Utility functions for all SCSI device types.
*
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
* Copyright (c) 1997, 1998, 2003 Kenneth D. Merry.
* All rights reserved.
diff --git a/freebsd/sys/dev/cadence/if_cgem.c b/freebsd/sys/dev/cadence/if_cgem.c
index 42fd4213..191362c4 100644
--- a/freebsd/sys/dev/cadence/if_cgem.c
+++ b/freebsd/sys/dev/cadence/if_cgem.c
@@ -895,7 +895,7 @@ cgem_start_locked(if_t ifp)
WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow |
CGEM_NET_CTRL_START_TX);
- /* If there is a BPF listener, bounce a copy to to him. */
+ /* If there is a BPF listener, bounce a copy to him. */
ETHER_BPF_MTAP(ifp, m);
}
}
diff --git a/freebsd/sys/dev/e1000/e1000_82543.c b/freebsd/sys/dev/e1000/e1000_82543.c
index dbaa4a6e..0bd0c6d5 100644
--- a/freebsd/sys/dev/e1000/e1000_82543.c
+++ b/freebsd/sys/dev/e1000/e1000_82543.c
@@ -1312,7 +1312,7 @@ static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
* turn it on. For compatibility with a TBI link
* partner, we will store bad packets. Some
* frames have an additional byte on the end and
- * will look like CRC errors to to the hardware.
+ * will look like CRC errors to the hardware.
*/
if (!e1000_tbi_sbp_enabled_82543(hw)) {
e1000_set_tbi_sbp_82543(hw, TRUE);
diff --git a/freebsd/sys/dev/e1000/e1000_82575.h b/freebsd/sys/dev/e1000/e1000_82575.h
index 7e127ed7..a96b25f4 100644
--- a/freebsd/sys/dev/e1000/e1000_82575.h
+++ b/freebsd/sys/dev/e1000/e1000_82575.h
@@ -385,7 +385,7 @@ struct e1000_adv_tx_context_desc {
#define E1000_ETQF_FILTER_ENABLE (1 << 26)
#define E1000_ETQF_IMM_INT (1 << 29)
#define E1000_ETQF_1588 (1 << 30)
-#define E1000_ETQF_QUEUE_ENABLE (1 << 31)
+#define E1000_ETQF_QUEUE_ENABLE (1U << 31)
/*
* ETQF filter list: one static filter per filter consumer. This is
* to avoid filter collisions later. Add new filters
@@ -412,7 +412,7 @@ struct e1000_adv_tx_context_desc {
#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
#define E1000_DTXSWC_LLE_SHIFT 16
-#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
+#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1U << 31) /* global VF LB enable */
/* Easy defines for setting default pool, would normally be left a zero */
#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
diff --git a/freebsd/sys/dev/e1000/e1000_api.c b/freebsd/sys/dev/e1000/e1000_api.c
index 393a22e2..c351901c 100644
--- a/freebsd/sys/dev/e1000/e1000_api.c
+++ b/freebsd/sys/dev/e1000/e1000_api.c
@@ -313,6 +313,16 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_PCH_SPT_I219_V5:
mac->type = e1000_pch_spt;
break;
+ case E1000_DEV_ID_PCH_CNP_I219_LM6:
+ case E1000_DEV_ID_PCH_CNP_I219_V6:
+ case E1000_DEV_ID_PCH_CNP_I219_LM7:
+ case E1000_DEV_ID_PCH_CNP_I219_V7:
+ case E1000_DEV_ID_PCH_ICP_I219_LM8:
+ case E1000_DEV_ID_PCH_ICP_I219_V8:
+ case E1000_DEV_ID_PCH_ICP_I219_LM9:
+ case E1000_DEV_ID_PCH_ICP_I219_V9:
+ mac->type = e1000_pch_cnp;
+ break;
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
@@ -464,6 +474,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
e1000_init_function_pointers_ich8lan(hw);
break;
case e1000_82575:
diff --git a/freebsd/sys/dev/e1000/e1000_hw.h b/freebsd/sys/dev/e1000/e1000_hw.h
index 82e783fe..2c17a022 100644
--- a/freebsd/sys/dev/e1000/e1000_hw.h
+++ b/freebsd/sys/dev/e1000/e1000_hw.h
@@ -147,6 +147,14 @@ struct e1000_hw;
#define E1000_DEV_ID_PCH_SPT_I219_V4 0x15D8
#define E1000_DEV_ID_PCH_SPT_I219_LM5 0x15E3
#define E1000_DEV_ID_PCH_SPT_I219_V5 0x15D6
+#define E1000_DEV_ID_PCH_CNP_I219_LM6 0x15BD
+#define E1000_DEV_ID_PCH_CNP_I219_V6 0x15BE
+#define E1000_DEV_ID_PCH_CNP_I219_LM7 0x15BB
+#define E1000_DEV_ID_PCH_CNP_I219_V7 0x15BC
+#define E1000_DEV_ID_PCH_ICP_I219_LM8 0x15DF
+#define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0
+#define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1
+#define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
@@ -233,6 +241,7 @@ enum e1000_mac_type {
e1000_pch2lan,
e1000_pch_lpt,
e1000_pch_spt,
+ e1000_pch_cnp,
e1000_82575,
e1000_82576,
e1000_82580,
diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.c b/freebsd/sys/dev/e1000/e1000_ich8lan.c
index b78b7283..bcd82c47 100644
--- a/freebsd/sys/dev/e1000/e1000_ich8lan.c
+++ b/freebsd/sys/dev/e1000/e1000_ich8lan.c
@@ -347,6 +347,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
if (e1000_phy_is_accessible_pchlan(hw))
break;
@@ -495,6 +496,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
/* In case the PHY needs to be in mdio slow mode,
* set slow mode and try to get the PHY id again.
*/
@@ -796,6 +798,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
/* fall-through */
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
/* multicast address update for pch2 */
mac->ops.update_mc_addr_list =
e1000_update_mc_addr_list_pch2lan;
@@ -1833,6 +1836,7 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
hw->phy.ops.init_params = e1000_init_phy_params_pchlan;
break;
default:
@@ -2297,6 +2301,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
break;
default:
@@ -2657,6 +2662,8 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
e1000_phy_sw_reset_generic(hw);
ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL,
0x3140);
+ if (ret_val)
+ return ret_val;
}
}
@@ -3414,6 +3421,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
switch (hw->mac.type) {
case e1000_pch_spt:
+ case e1000_pch_cnp:
bank1_offset = nvm->flash_bank_size;
act_offset = E1000_ICH_NVM_SIG_WORD;
@@ -4389,6 +4397,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
word = NVM_COMPAT;
valid_csum_mask = NVM_COMPAT_VALID_CSUM;
break;
@@ -5195,7 +5204,7 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
/* Device Status */
if (hw->mac.type == e1000_ich8lan) {
reg = E1000_READ_REG(hw, E1000_STATUS);
- reg &= ~(1 << 31);
+ reg &= ~(1U << 31);
E1000_WRITE_REG(hw, E1000_STATUS, reg);
}
diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.h b/freebsd/sys/dev/e1000/e1000_ich8lan.h
index d61f4df8..db37aab7 100644
--- a/freebsd/sys/dev/e1000/e1000_ich8lan.h
+++ b/freebsd/sys/dev/e1000/e1000_ich8lan.h
@@ -124,7 +124,8 @@
#define NVM_SIZE_MULTIPLIER 4096 /*multiplier for NVMS field*/
#define E1000_FLASH_BASE_ADDR 0xE000 /*offset of NVM access regs*/
#define E1000_CTRL_EXT_NVMVS 0x3 /*NVM valid sector */
-#define E1000_TARC0_CB_MULTIQ_3_REQ (1 << 28 | 1 << 29)
+#define E1000_TARC0_CB_MULTIQ_3_REQ 0x30000000
+#define E1000_TARC0_CB_MULTIQ_2_REQ 0x20000000
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
diff --git a/freebsd/sys/dev/e1000/e1000_regs.h b/freebsd/sys/dev/e1000/e1000_regs.h
index d9949817..246968e9 100644
--- a/freebsd/sys/dev/e1000/e1000_regs.h
+++ b/freebsd/sys/dev/e1000/e1000_regs.h
@@ -215,7 +215,7 @@
/* QAV Tx mode control register bitfields masks */
#define E1000_TQAVCC_IDLE_SLOPE 0xFFFF /* Idle slope */
#define E1000_TQAVCC_KEEP_CREDITS (1 << 30) /* Keep credits opt enable */
-#define E1000_TQAVCC_QUEUE_MODE (1 << 31) /* SP vs. SR Tx mode */
+#define E1000_TQAVCC_QUEUE_MODE (1U << 31) /* SP vs. SR Tx mode */
/* Good transmitted packets counter registers */
#define E1000_PQGPTC(_n) (0x010014 + (0x100 * (_n)))
diff --git a/freebsd/sys/dev/e1000/em_txrx.c b/freebsd/sys/dev/e1000/em_txrx.c
index 2183a8bd..9286f0ea 100644
--- a/freebsd/sys/dev/e1000/em_txrx.c
+++ b/freebsd/sys/dev/e1000/em_txrx.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
- * Copyright (c) 2016-2017 Matt Macy <mmacy@nextbsd.org>
+ * Copyright (c) 2016-2017 Matthew Macy <mmacy@mattmacy.io>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index 07acaad9..94159e31 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -3,7 +3,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2016 Matt Macy <mmacy@nextbsd.org>
+ * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -168,6 +168,14 @@ static pci_vendor_info_t em_vendor_info_array[] =
PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V4, "Intel(R) PRO/1000 Network Connection"),
PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_LM5, "Intel(R) PRO/1000 Network Connection"),
PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V5, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_LM6, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_V6, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_LM7, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_V7, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_LM8, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V8, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_LM9, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V9, "Intel(R) PRO/1000 Network Connection"),
/* required last entry */
PVID_END
};
@@ -864,7 +872,7 @@ em_if_attach_pre(if_ctx_t ctx)
** so use the same tag and an offset handle for the
** FLASH read/write macros in the shared code.
*/
- else if (hw->mac.type == e1000_pch_spt) {
+ else if (hw->mac.type >= e1000_pch_spt) {
adapter->osdep.flash_bus_space_tag =
adapter->osdep.mem_bus_space_tag;
adapter->osdep.flash_bus_space_handle =
@@ -1134,6 +1142,7 @@ em_if_mtu_set(if_ctx_t ctx, uint32_t mtu)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
case e1000_82574:
case e1000_82583:
case e1000_80003es2lan:
@@ -2418,6 +2427,7 @@ em_reset(if_ctx_t ctx)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
pba = E1000_PBA_26K;
break;
case e1000_82575:
@@ -2526,6 +2536,7 @@ em_reset(if_ctx_t ctx)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
hw->fc.high_water = 0x5C20;
hw->fc.low_water = 0x5048;
hw->fc.pause_time = 0x0650;
@@ -3056,13 +3067,16 @@ em_initialize_transmit_unit(if_ctx_t ctx)
/* This write will effectively turn on the transmit unit. */
E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
+ /* SPT and KBL errata workarounds */
if (hw->mac.type == e1000_pch_spt) {
u32 reg;
reg = E1000_READ_REG(hw, E1000_IOSFPC);
reg |= E1000_RCTL_RDMTS_HEX;
E1000_WRITE_REG(hw, E1000_IOSFPC, reg);
+ /* i218-i219 Specification Update 1.5.4.5 */
reg = E1000_READ_REG(hw, E1000_TARC(0));
- reg |= E1000_TARC0_CB_MULTIQ_3_REQ;
+ reg &= ~E1000_TARC0_CB_MULTIQ_3_REQ;
+ reg |= E1000_TARC0_CB_MULTIQ_2_REQ;
E1000_WRITE_REG(hw, E1000_TARC(0), reg);
}
}
diff --git a/freebsd/sys/dev/e1000/if_em.h b/freebsd/sys/dev/e1000/if_em.h
index 4f9d34b8..0a6a09ca 100644
--- a/freebsd/sys/dev/e1000/if_em.h
+++ b/freebsd/sys/dev/e1000/if_em.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2016 Matt Macy <mmacy@nextbsd.org>
+ * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/freebsd/sys/dev/e1000/igb_txrx.c b/freebsd/sys/dev/e1000/igb_txrx.c
index 2ed24e2d..05b2fff2 100644
--- a/freebsd/sys/dev/e1000/igb_txrx.c
+++ b/freebsd/sys/dev/e1000/igb_txrx.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
- * Copyright (c) 2016 Matt Macy <mmacy@nextbsd.org>
+ * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -239,7 +239,7 @@ igb_isc_txd_encap(void *arg, if_pkt_info_t pi)
int nsegs = pi->ipi_nsegs;
bus_dma_segment_t *segs = pi->ipi_segs;
union e1000_adv_tx_desc *txd = NULL;
- int i, j, first, pidx_last;
+ int i, j, pidx_last;
u32 olinfo_status, cmd_type_len, txd_flags;
qidx_t ntxd;
@@ -251,7 +251,7 @@ igb_isc_txd_encap(void *arg, if_pkt_info_t pi)
if (pi->ipi_mflags & M_VLANTAG)
cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
- first = i = pi->ipi_pidx;
+ i = pi->ipi_pidx;
ntxd = scctx->isc_ntxd[0];
txd_flags = pi->ipi_flags & IPI_TX_INTR ? E1000_ADVTXD_DCMD_RS : 0;
/* Consume the first descriptor */
diff --git a/freebsd/sys/dev/fdt/fdt_common.c b/freebsd/sys/dev/fdt/fdt_common.c
index 26f73bc3..daa45832 100644
--- a/freebsd/sys/dev/fdt/fdt_common.c
+++ b/freebsd/sys/dev/fdt/fdt_common.c
@@ -157,7 +157,7 @@ fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size)
pcell_t ranges[FDT_RANGES_SIZE], *rangesptr;
pcell_t addr_cells, size_cells, par_addr_cells;
u_long par_bus_addr, pbase, psize;
- int err, len, tuple_size, tuples;
+ int err, len;
if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
return (ENXIO);
@@ -183,10 +183,6 @@ fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size)
if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
return (EINVAL);
- tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
- size_cells);
- tuples = len / tuple_size;
-
if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2)
return (ERANGE);
@@ -602,11 +598,9 @@ fdt_get_reserved_regions(struct mem_region *mr, int *mrcnt)
pcell_t reserve[FDT_REG_CELLS * FDT_MEM_REGIONS];
pcell_t *reservep;
phandle_t memory, root;
- uint32_t memory_size;
int addr_cells, size_cells;
- int i, max_size, res_len, rv, tuple_size, tuples;
+ int i, res_len, rv, tuple_size, tuples;
- max_size = sizeof(reserve);
root = OF_finddevice("/");
memory = OF_finddevice("/memory");
if (memory == -1) {
@@ -636,7 +630,6 @@ fdt_get_reserved_regions(struct mem_region *mr, int *mrcnt)
goto out;
}
- memory_size = 0;
tuples = res_len / tuple_size;
reservep = (pcell_t *)&reserve;
for (i = 0; i < tuples; i++) {
@@ -664,9 +657,8 @@ fdt_get_mem_regions(struct mem_region *mr, int *mrcnt, uint64_t *memsize)
phandle_t memory;
uint64_t memory_size;
int addr_cells, size_cells;
- int i, max_size, reg_len, rv, tuple_size, tuples;
+ int i, reg_len, rv, tuple_size, tuples;
- max_size = sizeof(reg);
memory = OF_finddevice("/memory");
if (memory == -1) {
rv = ENXIO;
diff --git a/freebsd/sys/dev/mmc/mmc.c b/freebsd/sys/dev/mmc/mmc.c
index 32599383..2c3cba3d 100644
--- a/freebsd/sys/dev/mmc/mmc.c
+++ b/freebsd/sys/dev/mmc/mmc.c
@@ -1573,17 +1573,14 @@ mmc_host_timing(device_t dev, enum mmc_bus_timing timing)
static void
mmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard)
{
- enum mmc_bus_timing max_timing, timing;
+ enum mmc_bus_timing timing;
device_printf(dev, "Card at relative address 0x%04x%s:\n",
ivar->rca, newcard ? " added" : "");
device_printf(dev, " card: %s\n", ivar->card_id_string);
- max_timing = bus_timing_normal;
for (timing = bus_timing_max; timing > bus_timing_normal; timing--) {
- if (isset(&ivar->timings, timing)) {
- max_timing = timing;
+ if (isset(&ivar->timings, timing))
break;
- }
}
device_printf(dev, " quirks: %b\n", ivar->quirks, MMC_QUIRKS_FMT);
device_printf(dev, " bus: %ubit, %uMHz (%s timing)\n",
@@ -1885,7 +1882,7 @@ mmc_discover_cards(struct mmc_softc *sc)
* units of 10 ms), defaulting to 500 ms.
*/
ivar->cmd6_time = 500 * 1000;
- if (ivar->csd.spec_vers >= 6)
+ if (ivar->raw_ext_csd[EXT_CSD_REV] >= 6)
ivar->cmd6_time = 10 *
ivar->raw_ext_csd[EXT_CSD_GEN_CMD6_TIME];
/* Handle HC erase sector size. */
diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c
index df29b544..94e6e73f 100644
--- a/freebsd/sys/dev/mmc/mmcsd.c
+++ b/freebsd/sys/dev/mmc/mmcsd.c
@@ -1005,11 +1005,9 @@ mmcsd_close(struct disk *dp __unused)
static void
mmcsd_strategy(struct bio *bp)
{
- struct mmcsd_softc *sc;
struct mmcsd_part *part;
part = bp->bio_disk->d_drv1;
- sc = part->sc;
MMCSD_DISK_LOCK(part);
if (part->running > 0 || part->suspend > 0) {
bioq_disksort(&part->bio_queue, bp);
@@ -1169,6 +1167,16 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
default:
break;
}
+ /*
+ * No partition switching in userland; it's almost impossible
+ * to recover from that, especially if things go wrong.
+ */
+ if (cmd.opcode == MMC_SWITCH_FUNC && dp != NULL &&
+ (((uint8_t *)dp)[EXT_CSD_PART_CONFIG] &
+ EXT_CSD_PART_CONFIG_ACC_MASK) != part->type) {
+ err = EINVAL;
+ goto out;
+ }
}
dev = sc->dev;
mmcbus = sc->mmcbus;
@@ -1189,7 +1197,7 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
/*
* If the request went to the RPMB partition, try to ensure
- * that the command actually has completed ...
+ * that the command actually has completed.
*/
retries = MMCSD_CMD_RETRIES;
do {
@@ -1201,13 +1209,6 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
break;
DELAY(1000);
} while (retries-- > 0);
-
-switch_back:
- /* ... and always switch back to the default partition. */
- err = mmcsd_switch_part(mmcbus, dev, rca,
- EXT_CSD_PART_CONFIG_ACC_DEFAULT);
- if (err != MMC_ERR_NONE)
- goto release;
}
/*
* If EXT_CSD was changed, our copy is outdated now. Specifically,
@@ -1219,6 +1220,17 @@ switch_back:
if (err != MMC_ERR_NONE)
goto release;
}
+switch_back:
+ if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
+ /*
+ * If the request went to the RPMB partition, always switch
+ * back to the default partition (see mmcsd_switch_part()).
+ */
+ err = mmcsd_switch_part(mmcbus, dev, rca,
+ EXT_CSD_PART_CONFIG_ACC_DEFAULT);
+ if (err != MMC_ERR_NONE)
+ goto release;
+ }
MMCBUS_RELEASE_BUS(mmcbus, dev);
if (cmd.error != MMC_ERR_NONE) {
switch (cmd.error) {
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.c b/freebsd/sys/dev/ofw/ofw_bus_subr.c
index c655e668..8406988f 100644
--- a/freebsd/sys/dev/ofw/ofw_bus_subr.c
+++ b/freebsd/sys/dev/ofw/ofw_bus_subr.c
@@ -92,6 +92,7 @@ ofw_bus_gen_child_pnpinfo_str(device_t cbdev, device_t child, char *buf,
size_t buflen)
{
+ *buf = '\0';
if (ofw_bus_get_name(child) != NULL) {
strlcat(buf, "name=", buflen);
strlcat(buf, ofw_bus_get_name(child), buflen);
@@ -388,9 +389,8 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
uint8_t *mptr;
pcell_t paddrsz;
pcell_t pintrsz;
- int i, rsz, tsz;
+ int i, tsz;
- rsz = -1;
if (imapmsk != NULL) {
for (i = 0; i < physsz; i++)
ref[i] = uiregs[i] & uiimapmsk[i];
@@ -447,7 +447,7 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
{
pcell_t *map, mask, msi_base, rid_base, rid_length;
ssize_t len;
- uint32_t masked_rid, rid;
+ uint32_t masked_rid;
int err, i;
/* TODO: This should be OF_searchprop_alloc if we had it */
@@ -464,7 +464,6 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
}
err = ENOENT;
- rid = 0;
mask = 0xffffffff;
OF_getencprop(node, "msi-map-mask", &mask, sizeof(mask));
diff --git a/freebsd/sys/dev/ofw/ofw_fdt.c b/freebsd/sys/dev/ofw/ofw_fdt.c
index 7bdf447b..b9266eb5 100644
--- a/freebsd/sys/dev/ofw/ofw_fdt.c
+++ b/freebsd/sys/dev/ofw/ofw_fdt.c
@@ -256,7 +256,7 @@ ofw_fdt_instance_to_package(ofw_t ofw, ihandle_t instance)
static ssize_t
ofw_fdt_getproplen(ofw_t ofw, phandle_t package, const char *propname)
{
- const struct fdt_property *prop;
+ const void *prop;
int offset, len;
offset = fdt_phandle_offset(package);
@@ -264,7 +264,7 @@ ofw_fdt_getproplen(ofw_t ofw, phandle_t package, const char *propname)
return (-1);
len = -1;
- prop = fdt_get_property(fdtp, offset, propname, &len);
+ prop = fdt_getprop(fdtp, offset, propname, &len);
if (prop == NULL && strcmp(propname, "name") == 0) {
/* Emulate the 'name' property */
@@ -341,7 +341,7 @@ static int
ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf,
size_t size)
{
- const struct fdt_property *prop;
+ const void *prop;
const char *name;
int offset;
@@ -356,7 +356,7 @@ ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf,
if (previous != NULL) {
while (offset >= 0) {
- prop = fdt_get_property_by_offset(fdtp, offset, NULL);
+ prop = fdt_getprop_by_offset(fdtp, offset, &name, NULL);
if (prop == NULL)
return (-1); /* Internal error */
@@ -365,17 +365,16 @@ ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf,
return (0); /* No more properties */
/* Check if the last one was the one we wanted */
- name = fdt_string(fdtp, fdt32_to_cpu(prop->nameoff));
if (strcmp(name, previous) == 0)
break;
}
}
- prop = fdt_get_property_by_offset(fdtp, offset, &offset);
+ prop = fdt_getprop_by_offset(fdtp, offset, &name, &offset);
if (prop == NULL)
return (-1); /* Internal error */
- strncpy(buf, fdt_string(fdtp, fdt32_to_cpu(prop->nameoff)), size);
+ strncpy(buf, name, size);
return (1);
}
@@ -439,8 +438,7 @@ ofw_fdt_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len)
return (-1);
}
-#ifndef __rtems__
-#if defined(FDT_MARVELL) || defined(__powerpc__)
+#if defined(FDT_MARVELL)
static int
ofw_fdt_fixup(ofw_t ofw)
{
@@ -483,13 +481,11 @@ ofw_fdt_fixup(ofw_t ofw)
return (0);
}
#endif
-#endif /* __rtems__ */
static int
ofw_fdt_interpret(ofw_t ofw, const char *cmd, int nret, cell_t *retvals)
{
-#if defined(FDT_MARVELL) || defined(__powerpc__)
-#ifndef __rtems__
+#if defined(FDT_MARVELL)
int rv;
/*
@@ -508,9 +504,6 @@ ofw_fdt_interpret(ofw_t ofw, const char *cmd, int nret, cell_t *retvals)
retvals[0] = rv;
return (rv);
-#else /* __rtems__ */
- return (0);
-#endif /* __rtems__ */
#else
return (0);
#endif
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index e492846d..7fbdc693 100644
--- a/freebsd/sys/dev/pci/pci.c
+++ b/freebsd/sys/dev/pci/pci.c
@@ -125,6 +125,8 @@ static void pci_resume_msi(device_t dev);
static void pci_resume_msix(device_t dev);
static int pci_remap_intr_method(device_t bus, device_t dev,
u_int irq);
+static void pci_hint_device_unit(device_t acdev, device_t child,
+ const char *name, int *unitp);
static int pci_get_id_method(device_t dev, device_t child,
enum pci_id_type type, uintptr_t *rid);
@@ -164,6 +166,7 @@ static device_method_t pci_methods[] = {
DEVMETHOD(bus_child_detached, pci_child_detached),
DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method),
DEVMETHOD(bus_child_location_str, pci_child_location_str_method),
+ DEVMETHOD(bus_hint_device_unit, pci_hint_device_unit),
DEVMETHOD(bus_remap_intr, pci_remap_intr_method),
DEVMETHOD(bus_suspend_child, pci_suspend_child),
DEVMETHOD(bus_resume_child, pci_resume_child),
@@ -3987,7 +3990,6 @@ pci_rescan_method(device_t dev)
{
#define REG(n, w) PCIB_READ_CONFIG(pcib, busno, s, f, n, w)
device_t pcib = device_get_parent(dev);
- struct pci_softc *sc;
device_t child, *devlist, *unchanged;
int devcount, error, i, j, maxslots, oldcount;
int busno, domain, s, f, pcifunchigh;
@@ -4007,7 +4009,6 @@ pci_rescan_method(device_t dev)
} else
unchanged = NULL;
- sc = device_get_softc(dev);
domain = pcib_get_domain(dev);
busno = pcib_get_bus(dev);
maxslots = PCIB_MAXSLOTS(pcib);
@@ -4084,12 +4085,10 @@ device_t
pci_add_iov_child(device_t bus, device_t pf, uint16_t rid, uint16_t vid,
uint16_t did)
{
- struct pci_devinfo *pf_dinfo, *vf_dinfo;
+ struct pci_devinfo *vf_dinfo;
device_t pcib;
int busno, slot, func;
- pf_dinfo = device_get_ivars(pf);
-
pcib = device_get_parent(bus);
PCIB_DECODE_RID(pcib, rid, &busno, &slot, &func);
@@ -4231,6 +4230,31 @@ pci_detach(device_t dev)
}
static void
+pci_hint_device_unit(device_t dev, device_t child, const char *name, int *unitp)
+{
+ int line, unit;
+ const char *at;
+ char me1[24], me2[32];
+ uint8_t b, s, f;
+ uint32_t d;
+
+ d = pci_get_domain(child);
+ b = pci_get_bus(child);
+ s = pci_get_slot(child);
+ f = pci_get_function(child);
+ snprintf(me1, sizeof(me1), "pci%u:%u:%u", b, s, f);
+ snprintf(me2, sizeof(me2), "pci%u:%u:%u:%u", d, b, s, f);
+ line = 0;
+ while (resource_find_dev(&line, name, &unit, "at", NULL) == 0) {
+ resource_string_value(name, unit, "at", &at);
+ if (strcmp(at, me1) != 0 && strcmp(at, me2) != 0)
+ continue; /* No match, try next candidate */
+ *unitp = unit;
+ return;
+ }
+}
+
+static void
pci_set_power_child(device_t dev, device_t child, int state)
{
device_t pcib;
diff --git a/freebsd/sys/dev/pci/pci_pci.c b/freebsd/sys/dev/pci/pci_pci.c
index 5585bd32..20364cf9 100644
--- a/freebsd/sys/dev/pci/pci_pci.c
+++ b/freebsd/sys/dev/pci/pci_pci.c
@@ -1243,10 +1243,8 @@ static void
pcib_pcie_ab_timeout(void *arg)
{
struct pcib_softc *sc;
- device_t dev;
sc = arg;
- dev = sc->dev;
mtx_assert(&Giant, MA_OWNED);
if (sc->flags & PCIB_DETACH_PENDING) {
sc->flags |= PCIB_DETACHING;
@@ -1486,16 +1484,14 @@ pcib_cfg_save(struct pcib_softc *sc)
static void
pcib_cfg_restore(struct pcib_softc *sc)
{
- device_t dev;
#ifndef NEW_PCIB
uint16_t command;
#endif
- dev = sc->dev;
#ifdef NEW_PCIB
pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM);
#else
- command = pci_read_config(dev, PCIR_COMMAND, 2);
+ command = pci_read_config(sc->dev, PCIR_COMMAND, 2);
if (command & PCIM_CMD_PORTEN)
pcib_set_io_decode(sc);
if (command & PCIM_CMD_MEMEN)
diff --git a/freebsd/sys/dev/rtwn/if_rtwn.c b/freebsd/sys/dev/rtwn/if_rtwn.c
index 1f057dad..79868dc0 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn.c
+++ b/freebsd/sys/dev/rtwn/if_rtwn.c
@@ -1576,17 +1576,19 @@ rtwn_set_channel(struct ieee80211com *ic)
static int
rtwn_wme_update(struct ieee80211com *ic)
{
+ struct chanAccParams chp;
struct ieee80211_channel *c = ic->ic_curchan;
struct rtwn_softc *sc = ic->ic_softc;
struct wmeParams *wmep = sc->cap_wmeParams;
uint8_t aifs, acm, slottime;
int ac;
+ ieee80211_wme_ic_getparams(ic, &chp);
+
/* Prevent possible races. */
IEEE80211_LOCK(ic); /* XXX */
RTWN_LOCK(sc);
- memcpy(wmep, ic->ic_wme.wme_chanParams.cap_wmeParams,
- sizeof(sc->cap_wmeParams));
+ memcpy(wmep, chp.cap_wmeParams, sizeof(sc->cap_wmeParams));
RTWN_UNLOCK(sc);
IEEE80211_UNLOCK(ic);
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
index 6bbdf5bc..e30ae6be 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
@@ -134,6 +134,7 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8812AU_DEV(MELCO, WIU3866D),
RTWN_RTL8812AU_DEV(NEC, WL900U),
RTWN_RTL8812AU_DEV(PLANEX2, GW900D),
+ RTWN_RTL8812AU_DEV(REALTEK, RTL8812AU),
RTWN_RTL8812AU_DEV(SENAO, EUB1200AC),
RTWN_RTL8812AU_DEV(SITECOMEU, WLA7100),
RTWN_RTL8812AU_DEV(TPLINK, T4U),
diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c
index 496e8fac..39b9dc91 100644
--- a/freebsd/sys/dev/sdhci/sdhci.c
+++ b/freebsd/sys/dev/sdhci/sdhci.c
@@ -275,7 +275,7 @@ sdhci_tuning_intmask(struct sdhci_slot *slot)
uint32_t intmask;
intmask = 0;
- if (slot->opt & SDHCI_TUNING_SUPPORTED) {
+ if (slot->opt & SDHCI_TUNING_ENABLED) {
intmask |= SDHCI_INT_TUNEERR;
if (slot->retune_mode == SDHCI_RETUNE_MODE_2 ||
slot->retune_mode == SDHCI_RETUNE_MODE_3)
@@ -303,7 +303,7 @@ sdhci_init(struct sdhci_slot *slot)
slot->intmask |= SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
}
- WR4(slot, SDHCI_INT_ENABLE, slot->intmask | sdhci_tuning_intmask(slot));
+ WR4(slot, SDHCI_INT_ENABLE, slot->intmask);
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
}
@@ -656,6 +656,7 @@ sdhci_card_task(void *arg, int pending __unused)
xpt_rescan(ccb);
#else
slot->intmask &= ~sdhci_tuning_intmask(slot);
+ WR4(slot, SDHCI_INT_ENABLE, slot->intmask);
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
slot->opt &= ~SDHCI_TUNING_ENABLED;
SDHCI_UNLOCK(slot);
@@ -1340,6 +1341,7 @@ sdhci_generic_tune(device_t brdev __unused, device_t reqdev, bool hs400)
if (err == 0) {
slot->opt |= SDHCI_TUNING_ENABLED;
slot->intmask |= sdhci_tuning_intmask(slot);
+ WR4(slot, SDHCI_INT_ENABLE, slot->intmask);
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
if (slot->retune_ticks) {
callout_reset(&slot->retune_callout, slot->retune_ticks,
@@ -1408,6 +1410,7 @@ sdhci_exec_tuning(struct sdhci_slot *slot, bool reset)
*/
intmask = slot->intmask;
slot->intmask = SDHCI_INT_DATA_AVAIL;
+ WR4(slot, SDHCI_INT_ENABLE, SDHCI_INT_DATA_AVAIL);
WR4(slot, SDHCI_SIGNAL_ENABLE, SDHCI_INT_DATA_AVAIL);
hostctrl2 = RD2(slot, SDHCI_HOST_CONTROL2);
@@ -1447,8 +1450,17 @@ sdhci_exec_tuning(struct sdhci_slot *slot, bool reset)
DELAY(1000);
}
+ /*
+ * Restore DMA usage and interrupts.
+ * Note that the interrupt aggregation code might have cleared
+ * SDHCI_INT_DMA_END and/or SDHCI_INT_RESPONSE in slot->intmask
+ * and SDHCI_SIGNAL_ENABLE respectively so ensure SDHCI_INT_ENABLE
+ * doesn't lose these.
+ */
slot->opt = opt;
slot->intmask = intmask;
+ WR4(slot, SDHCI_INT_ENABLE, intmask | SDHCI_INT_DMA_END |
+ SDHCI_INT_RESPONSE);
WR4(slot, SDHCI_SIGNAL_ENABLE, intmask);
if ((hostctrl2 & (SDHCI_CTRL2_EXEC_TUNING |
diff --git a/freebsd/sys/dev/smc/if_smc.c b/freebsd/sys/dev/smc/if_smc.c
index 6b087a85..ac2fdf88 100644
--- a/freebsd/sys/dev/smc/if_smc.c
+++ b/freebsd/sys/dev/smc/if_smc.c
@@ -1224,7 +1224,6 @@ smc_stop(struct smc_softc *sc)
#ifdef DEVICE_POLLING
ether_poll_deregister(sc->smc_ifp);
sc->smc_ifp->if_capenable &= ~IFCAP_POLLING;
- sc->smc_ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT;
#endif
/*
@@ -1284,7 +1283,6 @@ smc_init_locked(struct smc_softc *sc)
ether_poll_register(smc_poll, ifp);
SMC_LOCK(sc);
ifp->if_capenable |= IFCAP_POLLING;
- ifp->if_capenable |= IFCAP_POLLING_NOCOUNT;
#endif
}
diff --git a/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c b/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c
index 1cf96f4c..a7110887 100644
--- a/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c
+++ b/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c
@@ -175,7 +175,6 @@ int
dwc_otg_detach(device_t dev)
{
struct dwc_otg_fdt_softc *sc = device_get_softc(dev);
- int err;
/* during module unload there are lots of children leftover */
device_delete_children(dev);
@@ -186,7 +185,7 @@ dwc_otg_detach(device_t dev)
*/
dwc_otg_uninit(&sc->sc_otg);
- err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res,
+ bus_teardown_intr(dev, sc->sc_otg.sc_irq_res,
sc->sc_otg.sc_intr_hdl);
sc->sc_otg.sc_intr_hdl = NULL;
}
diff --git a/freebsd/sys/dev/usb/controller/ehci.c b/freebsd/sys/dev/usb/controller/ehci.c
index 557698f6..6e7c05f4 100644
--- a/freebsd/sys/dev/usb/controller/ehci.c
+++ b/freebsd/sys/dev/usb/controller/ehci.c
@@ -1204,9 +1204,7 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer)
static void
ehci_non_isoc_done(struct usb_xfer *xfer)
{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
ehci_qh_t *qh;
- uint32_t status;
usb_error_t err = 0;
DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
@@ -1226,8 +1224,6 @@ ehci_non_isoc_done(struct usb_xfer *xfer)
usb_pc_cpu_invalidate(qh->page_cache);
- status = hc32toh(sc, qh->qh_qtd.qtd_status);
-
/* reset scanner */
xfer->td_transfer_cache = xfer->td_transfer_first;
diff --git a/freebsd/sys/dev/usb/controller/ohci.c b/freebsd/sys/dev/usb/controller/ohci.c
index df1981cc..48db76f0 100644
--- a/freebsd/sys/dev/usb/controller/ohci.c
+++ b/freebsd/sys/dev/usb/controller/ohci.c
@@ -2387,7 +2387,6 @@ ohci_xfer_setup(struct usb_setup_params *parm)
{
struct usb_page_search page_info;
struct usb_page_cache *pc;
- ohci_softc_t *sc;
struct usb_xfer *xfer;
void *last_obj;
uint32_t ntd;
@@ -2395,7 +2394,6 @@ ohci_xfer_setup(struct usb_setup_params *parm)
uint32_t nqh;
uint32_t n;
- sc = OHCI_BUS2SC(parm->udev->bus);
xfer = parm->curr_xfer;
parm->hc_max_packet_size = 0x500;
diff --git a/freebsd/sys/dev/usb/net/if_cdce.c b/freebsd/sys/dev/usb/net/if_cdce.c
index ececc5b3..9a15da69 100644
--- a/freebsd/sys/dev/usb/net/if_cdce.c
+++ b/freebsd/sys/dev/usb/net/if_cdce.c
@@ -288,6 +288,9 @@ static const STRUCT_USB_HOST_ID cdce_host_devs[] = {
{USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x76),
USB_DRIVER_INFO(0)},
+ {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(0x03), USB_IFACE_PROTOCOL(0x16),
+ USB_DRIVER_INFO(0)},
};
static const STRUCT_USB_DUAL_ID cdce_dual_devs[] = {
diff --git a/freebsd/sys/dev/usb/net/if_mos.c b/freebsd/sys/dev/usb/net/if_mos.c
index a25e9df6..ad7bfcce 100644
--- a/freebsd/sys/dev/usb/net/if_mos.c
+++ b/freebsd/sys/dev/usb/net/if_mos.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
- * SPDX-License-Identifier: 0BSD AND BSD-4-Clause
+ * SPDX-License-Identifier: (BSD-1-Clause AND BSD-4-Clause)
*
* Copyright (c) 2011 Rick van der Zwet <info@rickvanderzwet.nl>
*
diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c
index 8c9e91cb..3ae4a557 100644
--- a/freebsd/sys/dev/usb/quirk/usb_quirk.c
+++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c
@@ -246,6 +246,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI,
UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */
+ USB_QUIRK(JMICRON, JMS567, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN),
USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI,
UQ_MSC_NO_SYNC_CACHE),
diff --git a/freebsd/sys/dev/usb/serial/u3g.c b/freebsd/sys/dev/usb/serial/u3g.c
index 0f3933e6..6f1cfdb1 100644
--- a/freebsd/sys/dev/usb/serial/u3g.c
+++ b/freebsd/sys/dev/usb/serial/u3g.c
@@ -202,6 +202,7 @@ static driver_t u3g_driver = {
static const STRUCT_USB_HOST_ID u3g_devs[] = {
#define U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+ U3G_DEV(ABIT, AK_020, 0),
U3G_DEV(ACERP, H10, 0),
U3G_DEV(AIRPLUS, MCD650, 0),
U3G_DEV(AIRPRIME, PC5220, 0),
@@ -310,7 +311,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
U3G_DEV(HUAWEI, E173, 0),
U3G_DEV(HUAWEI, E173_INIT, U3GINIT_HUAWEISCSI),
U3G_DEV(HUAWEI, E3131, 0),
- U3G_DEV(HUAWEI, E3131_INIT, U3GINIT_HUAWEISCSI),
+ U3G_DEV(HUAWEI, E3131_INIT, U3GINIT_HUAWEISCSI2),
U3G_DEV(HUAWEI, E180V, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI),
@@ -331,6 +332,8 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
U3G_DEV(HUAWEI, K4505, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, K4505_INIT, U3GINIT_HUAWEISCSI),
U3G_DEV(HUAWEI, ETS2055, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E3272_INIT, U3GINIT_HUAWEISCSI2),
+ U3G_DEV(HUAWEI, E3272, 0),
U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
U3G_DEV(KYOCERA2, KPC680, 0),
U3G_DEV(LONGCHEER, WM66, U3GINIT_HUAWEI),
@@ -493,6 +496,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
U3G_DEV(QUANTA, GLX, 0),
U3G_DEV(QUANTA, Q101, 0),
U3G_DEV(QUANTA, Q111, 0),
+ U3G_DEV(QUECTEL, EC25, 0),
U3G_DEV(SIERRA, AC402, 0),
U3G_DEV(SIERRA, AC595U, 0),
U3G_DEV(SIERRA, AC313U, 0),
@@ -632,6 +636,45 @@ u3g_huawei_init(struct usb_device *udev)
return (0);
}
+static int
+u3g_huawei_is_cdce(uint16_t idVendor, uint8_t bInterfaceSubClass,
+ uint8_t bInterfaceProtocol)
+{
+ /*
+ * This function returns non-zero if the interface being
+ * probed is of type CDC ethernet, which the U3G driver should
+ * not attach to. See sys/dev/usb/net/if_cdce.c for matching
+ * entries.
+ */
+ if (idVendor != USB_VENDOR_HUAWEI)
+ goto done;
+
+ switch (bInterfaceSubClass) {
+ case 0x02:
+ switch (bInterfaceProtocol) {
+ case 0x16:
+ case 0x46:
+ case 0x76:
+ return (1);
+ default:
+ break;
+ }
+ break;
+ case 0x03:
+ switch (bInterfaceProtocol) {
+ case 0x16:
+ return (1);
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+done:
+ return (0);
+}
+
static void
u3g_sael_m460_init(struct usb_device *udev)
{
@@ -845,6 +888,10 @@ u3g_probe(device_t self)
if (uaa->info.bInterfaceClass != UICLASS_VENDOR) {
return (ENXIO);
}
+ if (u3g_huawei_is_cdce(uaa->info.idVendor, uaa->info.bInterfaceSubClass,
+ uaa->info.bInterfaceProtocol)) {
+ return (ENXIO);
+ }
return (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa));
}
@@ -888,6 +935,9 @@ u3g_attach(device_t dev)
id = usbd_get_interface_descriptor(iface);
if (id == NULL || id->bInterfaceClass != UICLASS_VENDOR)
continue;
+ if (u3g_huawei_is_cdce(uaa->info.idVendor,
+ id->bInterfaceSubClass, id->bInterfaceProtocol))
+ continue;
usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
iface_valid |= (1<<i);
}
diff --git a/freebsd/sys/dev/usb/serial/umodem.c b/freebsd/sys/dev/usb/serial/umodem.c
index c64600c8..ac1e35c8 100644
--- a/freebsd/sys/dev/usb/serial/umodem.c
+++ b/freebsd/sys/dev/usb/serial/umodem.c
@@ -133,6 +133,18 @@ static const STRUCT_USB_DUAL_ID umodem_dual_devs[] = {
static const STRUCT_USB_HOST_ID umodem_host_devs[] = {
/* Huawei Modem class match */
+ {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x01)},
+ {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x02)},
+ {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x10)},
+ {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x12)},
+ {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x61)},
+ {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR),
+ USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x62)},
{USB_VENDOR(USB_VENDOR_HUAWEI),USB_IFACE_CLASS(UICLASS_CDC),
USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
USB_IFACE_PROTOCOL(0xFF)},
diff --git a/freebsd/sys/dev/usb/storage/umass.c b/freebsd/sys/dev/usb/storage/umass.c
index 6b488cf7..c74a8403 100644
--- a/freebsd/sys/dev/usb/storage/umass.c
+++ b/freebsd/sys/dev/usb/storage/umass.c
@@ -1097,7 +1097,6 @@ static void
umass_init_shuttle(struct umass_softc *sc)
{
struct usb_device_request req;
- usb_error_t err;
uint8_t status[2] = {0, 0};
/*
@@ -1110,7 +1109,7 @@ umass_init_shuttle(struct umass_softc *sc)
req.wIndex[0] = sc->sc_iface_no;
req.wIndex[1] = 0;
USETW(req.wLength, sizeof(status));
- err = usbd_do_request(sc->sc_udev, NULL, &req, &status);
+ usbd_do_request(sc->sc_udev, NULL, &req, &status);
DPRINTF(sc, UDMASS_GEN, "Shuttle init returned 0x%02x%02x\n",
status[0], status[1]);
diff --git a/freebsd/sys/dev/usb/usb_dev.c b/freebsd/sys/dev/usb/usb_dev.c
index 2b244d80..94f306d4 100644
--- a/freebsd/sys/dev/usb/usb_dev.c
+++ b/freebsd/sys/dev/usb/usb_dev.c
@@ -882,7 +882,7 @@ usb_open(struct cdev *dev, int fflags, int devtype, struct thread *td)
struct usb_fs_privdata* pd = (struct usb_fs_privdata*)dev->si_drv1;
struct usb_cdev_refdata refs;
struct usb_cdev_privdata *cpd;
- int err, ep;
+ int err;
DPRINTFN(2, "%s fflags=0x%08x\n", devtoname(dev), fflags);
@@ -894,7 +894,6 @@ usb_open(struct cdev *dev, int fflags, int devtype, struct thread *td)
}
cpd = malloc(sizeof(*cpd), M_USBDEV, M_WAITOK | M_ZERO);
- ep = cpd->ep_addr = pd->ep_addr;
usb_loc_fill(pd, cpd);
err = usb_ref_device(cpd, &refs, 1);
@@ -1422,8 +1421,6 @@ usb_read(struct cdev *dev, struct uio *uio, int ioflag)
struct usb_cdev_privdata* cpd;
struct usb_fifo *f;
struct usb_mbuf *m;
- int fflags;
- int resid;
int io_len;
int err;
uint8_t tr_data = 0;
@@ -1436,8 +1433,6 @@ usb_read(struct cdev *dev, struct uio *uio, int ioflag)
if (err)
return (ENXIO);
- fflags = cpd->fflags;
-
f = refs.rxfifo;
if (f == NULL) {
/* should not happen */
@@ -1445,8 +1440,6 @@ usb_read(struct cdev *dev, struct uio *uio, int ioflag)
return (EPERM);
}
- resid = uio->uio_resid;
-
mtx_lock(f->priv_mtx);
/* check for permanent read error */
@@ -1546,8 +1539,6 @@ usb_write(struct cdev *dev, struct uio *uio, int ioflag)
struct usb_fifo *f;
struct usb_mbuf *m;
uint8_t *pdata;
- int fflags;
- int resid;
int io_len;
int err;
uint8_t tr_data = 0;
@@ -1562,15 +1553,12 @@ usb_write(struct cdev *dev, struct uio *uio, int ioflag)
if (err)
return (ENXIO);
- fflags = cpd->fflags;
-
f = refs.txfifo;
if (f == NULL) {
/* should not happen */
usb_unref_device(cpd, &refs);
return (EPERM);
}
- resid = uio->uio_resid;
mtx_lock(f->priv_mtx);
diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c
index 861f6029..5f1cf409 100644
--- a/freebsd/sys/dev/usb/usb_device.c
+++ b/freebsd/sys/dev/usb/usb_device.c
@@ -89,6 +89,7 @@
/* function prototypes */
+static int sysctl_hw_usb_template(SYSCTL_HANDLER_ARGS);
static void usb_init_endpoint(struct usb_device *, uint8_t,
struct usb_endpoint_descriptor *,
struct usb_endpoint_ss_comp_descriptor *,
@@ -123,8 +124,137 @@ int usb_template;
#endif
#ifndef __rtems__
-SYSCTL_INT(_hw_usb, OID_AUTO, template, CTLFLAG_RWTUN,
- &usb_template, 0, "Selected USB device side template");
+SYSCTL_PROC(_hw_usb, OID_AUTO, template,
+ CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
+ NULL, 0, sysctl_hw_usb_template,
+ "I", "Selected USB device side template");
+
+/*------------------------------------------------------------------------*
+ * usb_trigger_reprobe_on_off
+ *
+ * This function sets the pull up resistors for all ports currently
+ * operating in device mode either on (when on_not_off is 1), or off
+ * (when it's 0).
+ *------------------------------------------------------------------------*/
+static void
+usb_trigger_reprobe_on_off(int on_not_off)
+{
+ struct usb_port_status ps;
+ struct usb_bus *bus;
+ struct usb_device *udev;
+ usb_error_t err;
+ int do_unlock, max;
+
+ max = devclass_get_maxunit(usb_devclass_ptr);
+ while (max >= 0) {
+ mtx_lock(&usb_ref_lock);
+ bus = devclass_get_softc(usb_devclass_ptr, max);
+ max--;
+
+ if (bus == NULL || bus->devices == NULL ||
+ bus->devices[USB_ROOT_HUB_ADDR] == NULL) {
+ mtx_unlock(&usb_ref_lock);
+ continue;
+ }
+
+ udev = bus->devices[USB_ROOT_HUB_ADDR];
+
+ if (udev->refcount == USB_DEV_REF_MAX) {
+ mtx_unlock(&usb_ref_lock);
+ continue;
+ }
+
+ udev->refcount++;
+ mtx_unlock(&usb_ref_lock);
+
+ do_unlock = usbd_enum_lock(udev);
+ if (do_unlock > 1) {
+ do_unlock = 0;
+ goto next;
+ }
+
+ err = usbd_req_get_port_status(udev, NULL, &ps, 1);
+ if (err != 0) {
+ DPRINTF("usbd_req_get_port_status() "
+ "failed: %s\n", usbd_errstr(err));
+ goto next;
+ }
+
+ if ((UGETW(ps.wPortStatus) & UPS_PORT_MODE_DEVICE) == 0)
+ goto next;
+
+ if (on_not_off) {
+ err = usbd_req_set_port_feature(udev, NULL, 1,
+ UHF_PORT_POWER);
+ if (err != 0) {
+ DPRINTF("usbd_req_set_port_feature() "
+ "failed: %s\n", usbd_errstr(err));
+ }
+ } else {
+ err = usbd_req_clear_port_feature(udev, NULL, 1,
+ UHF_PORT_POWER);
+ if (err != 0) {
+ DPRINTF("usbd_req_clear_port_feature() "
+ "failed: %s\n", usbd_errstr(err));
+ }
+ }
+
+next:
+ mtx_lock(&usb_ref_lock);
+ if (do_unlock)
+ usbd_enum_unlock(udev);
+ if (--(udev->refcount) == 0)
+ cv_broadcast(&udev->ref_cv);
+ mtx_unlock(&usb_ref_lock);
+ }
+}
+
+/*------------------------------------------------------------------------*
+ * usb_trigger_reprobe_all
+ *
+ * This function toggles the pull up resistors for all ports currently
+ * operating in device mode, causing the host machine to reenumerate them.
+ *------------------------------------------------------------------------*/
+static void
+usb_trigger_reprobe_all(void)
+{
+
+ /*
+ * Set the pull up resistors off for all ports in device mode.
+ */
+ usb_trigger_reprobe_on_off(0);
+
+ /*
+ * According to the DWC OTG spec this must be at least 3ms.
+ */
+ usb_pause_mtx(NULL, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
+
+ /*
+ * Set the pull up resistors back on.
+ */
+ usb_trigger_reprobe_on_off(1);
+}
+
+static int
+sysctl_hw_usb_template(SYSCTL_HANDLER_ARGS)
+{
+ int error, val;
+
+ val = usb_template;
+ error = sysctl_handle_int(oidp, &val, 0, req);
+ if (error != 0 || req->newptr == NULL || usb_template == val)
+ return (error);
+
+ usb_template = val;
+
+ if (usb_template < 0) {
+ usb_trigger_reprobe_on_off(0);
+ } else {
+ usb_trigger_reprobe_all();
+ }
+
+ return (0);
+}
#endif /* __rtems__ */
/* English is default language */
diff --git a/freebsd/sys/dev/usb/wlan/if_rum.c b/freebsd/sys/dev/usb/wlan/if_rum.c
index 9996576e..dbb12335 100644
--- a/freebsd/sys/dev/usb/wlan/if_rum.c
+++ b/freebsd/sys/dev/usb/wlan/if_rum.c
@@ -2303,11 +2303,14 @@ rum_update_slot(struct ieee80211com *ic)
static int
rum_wme_update(struct ieee80211com *ic)
{
- const struct wmeParams *chanp =
- ic->ic_wme.wme_chanParams.cap_wmeParams;
+ struct chanAccParams chp;
+ const struct wmeParams *chanp;
struct rum_softc *sc = ic->ic_softc;
int error = 0;
+ ieee80211_wme_ic_getparams(ic, &chp);
+ chanp = chp.cap_wmeParams;
+
RUM_LOCK(sc);
error = rum_write(sc, RT2573_AIFSN_CSR,
chanp[WME_AC_VO].wmep_aifsn << 12 |
diff --git a/freebsd/sys/dev/usb/wlan/if_run.c b/freebsd/sys/dev/usb/wlan/if_run.c
index d9bda8c8..71f53dd3 100644
--- a/freebsd/sys/dev/usb/wlan/if_run.c
+++ b/freebsd/sys/dev/usb/wlan/if_run.c
@@ -2219,11 +2219,14 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
static int
run_wme_update(struct ieee80211com *ic)
{
+ struct chanAccParams chp;
struct run_softc *sc = ic->ic_softc;
- const struct wmeParams *ac =
- ic->ic_wme.wme_chanParams.cap_wmeParams;
+ const struct wmeParams *ac;
int aci, error = 0;
+ ieee80211_wme_ic_getparams(ic, &chp);
+ ac = chp.cap_wmeParams;
+
/* update MAC TX configuration registers */
RUN_LOCK(sc);
for (aci = 0; aci < WME_NUM_AC; aci++) {
diff --git a/freebsd/sys/dev/usb/wlan/if_uath.c b/freebsd/sys/dev/usb/wlan/if_uath.c
index e1aa5ec0..e001d9ed 100644
--- a/freebsd/sys/dev/usb/wlan/if_uath.c
+++ b/freebsd/sys/dev/usb/wlan/if_uath.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND 0BSD
+ * SPDX-License-Identifier: (BSD-2-Clause-FreeBSD AND BSD-1-Clause)
*
* Copyright (c) 2006 Sam Leffler, Errno Consulting
* Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org>
diff --git a/freebsd/sys/fs/devfs/devfs_vnops.c b/freebsd/sys/fs/devfs/devfs_vnops.c
index 4a1c0675..dfa8413b 100644
--- a/freebsd/sys/fs/devfs/devfs_vnops.c
+++ b/freebsd/sys/fs/devfs/devfs_vnops.c
@@ -911,6 +911,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
struct devfs_dirent *de, *dd;
struct devfs_dirent **dde;
struct devfs_mount *dmp;
+ struct mount *mp;
struct cdev *cdev;
int error, flags, nameiop, dvplocked;
char specname[SPECNAMELEN + 1], *pname;
@@ -922,7 +923,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
td = cnp->cn_thread;
flags = cnp->cn_flags;
nameiop = cnp->cn_nameiop;
- dmp = VFSTODEVFS(dvp->v_mount);
+ mp = dvp->v_mount;
+ dmp = VFSTODEVFS(mp);
dd = dvp->v_data;
*vpp = NULLVP;
@@ -955,8 +957,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
return (ENOENT);
dvplocked = VOP_ISLOCKED(dvp);
VOP_UNLOCK(dvp, 0);
- error = devfs_allocv(de, dvp->v_mount,
- cnp->cn_lkflags & LK_TYPE_MASK, vpp);
+ error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK,
+ vpp);
*dm_unlock = 0;
vn_lock(dvp, dvplocked | LK_RETRY);
return (error);
@@ -1041,8 +1043,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
return (0);
}
}
- error = devfs_allocv(de, dvp->v_mount, cnp->cn_lkflags & LK_TYPE_MASK,
- vpp);
+ error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, vpp);
*dm_unlock = 0;
return (error);
}
@@ -1195,6 +1196,18 @@ devfs_pathconf(struct vop_pathconf_args *ap)
{
switch (ap->a_name) {
+ case _PC_FILESIZEBITS:
+ *ap->a_retval = 64;
+ return (0);
+ case _PC_NAME_MAX:
+ *ap->a_retval = NAME_MAX;
+ return (0);
+ case _PC_LINK_MAX:
+ *ap->a_retval = INT_MAX;
+ return (0);
+ case _PC_SYMLINK_MAX:
+ *ap->a_retval = MAXPATHLEN;
+ return (0);
case _PC_MAX_CANON:
if (ap->a_vp->v_vflag & VV_ISTTY) {
*ap->a_retval = MAX_CANON;
@@ -1224,6 +1237,9 @@ devfs_pathconf(struct vop_pathconf_args *ap)
*ap->a_retval = 0;
#endif
return (0);
+ case _PC_CHOWN_RESTRICTED:
+ *ap->a_retval = 1;
+ return (0);
default:
return (vop_stdpathconf(ap));
}
diff --git a/freebsd/sys/isa/isavar.h b/freebsd/sys/isa/isavar.h
index 28d13505..30fd1f8d 100644
--- a/freebsd/sys/isa/isavar.h
+++ b/freebsd/sys/isa/isavar.h
@@ -142,6 +142,10 @@ enum isa_device_ivars {
#define ISACFGATTR_DYNAMIC (1 << 1) /* dynamic configuration */
#define ISACFGATTR_HINTS (1 << 3) /* source of config is hints */
+#define ISA_PNP_DESCR "E:pnpid;D:#"
+#define ISA_PNP_INFO(t) \
+ MODULE_PNP_INFO(ISA_PNP_DESCR, isa, t, t, sizeof(t[0]), nitems(t) - 1); \
+
/*
* Simplified accessors for isa devices
*/
diff --git a/freebsd/sys/kern/init_main.c b/freebsd/sys/kern/init_main.c
index b8961ab6..ea827ebe 100644
--- a/freebsd/sys/kern/init_main.c
+++ b/freebsd/sys/kern/init_main.c
@@ -91,7 +91,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
-#include <vm/vm_domain.h>
#include <sys/copyright.h>
#include <ddb/ddb.h>
@@ -235,6 +234,8 @@ mi_startup(void)
int verbose;
#endif
+ TSENTER();
+
#ifndef __rtems__
if (boothowto & RB_VERBOSE)
bootverbose++;
@@ -334,6 +335,8 @@ restart:
#endif /* __rtems__ */
}
+ TSEXIT(); /* Here so we don't overlap with start_init. */
+
mtx_assert(&Giant, MA_OWNED | MA_NOTRECURSED);
mtx_unlock(&Giant);
@@ -517,10 +520,7 @@ proc0_init(void *dummy __unused)
td->td_flags = TDF_INMEM;
td->td_pflags = TDP_KTHREAD;
td->td_cpuset = cpuset_thread0();
- vm_domain_policy_init(&td->td_vm_dom_policy);
- vm_domain_policy_set(&td->td_vm_dom_policy, VM_POLICY_NONE, -1);
- vm_domain_policy_init(&p->p_vm_dom_policy);
- vm_domain_policy_set(&p->p_vm_dom_policy, VM_POLICY_NONE, -1);
+ td->td_domain.dr_policy = td->td_cpuset->cs_domain;
prison0_init();
p->p_peers = 0;
p->p_leader = p;
@@ -730,6 +730,8 @@ start_init(void *dummy)
GIANT_REQUIRED;
+ TSENTER(); /* Here so we don't overlap with mi_startup. */
+
td = curthread;
p = td->td_proc;
@@ -823,6 +825,7 @@ start_init(void *dummy)
*/
if ((error = sys_execve(td, &args)) == EJUSTRETURN) {
mtx_unlock(&Giant);
+ TSEXIT();
return;
}
if (error != ENOENT)
diff --git a/freebsd/sys/kern/kern_mbuf.c b/freebsd/sys/kern/kern_mbuf.c
index 0f46259a..78e3528f 100644
--- a/freebsd/sys/kern/kern_mbuf.c
+++ b/freebsd/sys/kern/kern_mbuf.c
@@ -295,7 +295,7 @@ static void mb_dtor_pack(void *, int, void *);
static int mb_zinit_pack(void *, int, int);
static void mb_zfini_pack(void *, int);
static void mb_reclaim(uma_zone_t, int);
-static void *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
+static void *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
/* Ensure that MSIZE is a power of 2. */
CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE);
@@ -400,13 +400,14 @@ SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL);
* pages.
*/
static void *
-mbuf_jumbo_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait)
+mbuf_jumbo_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *flags,
+ int wait)
{
/* Inform UMA that this allocator uses kernel_map/object. */
*flags = UMA_SLAB_KERNEL;
#ifndef __rtems__
- return ((void *)kmem_alloc_contig(kernel_arena, bytes, wait,
+ return ((void *)kmem_alloc_contig_domain(domain, bytes, wait,
(vm_paddr_t)0, ~(vm_paddr_t)0, 1, 0, VM_MEMATTR_DEFAULT));
#else /* __rtems__ */
return ((void *)malloc(bytes, M_TEMP, wait));
diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c
index d96954c7..f6485a86 100644
--- a/freebsd/sys/kern/kern_synch.c
+++ b/freebsd/sys/kern/kern_synch.c
@@ -139,18 +139,12 @@ _sleep(void *ident, struct lock_object *lock, int priority,
const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags)
{
struct thread *td;
-#ifndef __rtems__
- struct proc *p;
-#endif /* __rtems__ */
struct lock_class *class;
uintptr_t lock_state;
int catch, pri, rval, sleepq_flags;
WITNESS_SAVE_DECL(lock_witness);
td = curthread;
-#ifndef __rtems__
- p = td->td_proc;
-#endif /* __rtems__ */
#ifdef KTRACE
if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 0, wmesg);
@@ -198,7 +192,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
sleepq_lock(ident);
CTR5(KTR_PROC, "sleep: thread %ld (pid %ld, %s) on %s (%p)",
- td->td_tid, p->p_pid, td->td_name, wmesg, ident);
+ td->td_tid, td->td_proc->p_pid, td->td_name, wmesg, ident);
if (lock == &Giant.lock_object)
mtx_assert(&Giant, MA_OWNED);
@@ -263,12 +257,10 @@ msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg,
sbintime_t sbt, sbintime_t pr, int flags)
{
struct thread *td;
- struct proc *p;
int rval;
WITNESS_SAVE_DECL(mtx);
td = curthread;
- p = td->td_proc;
KASSERT(mtx != NULL, ("sleeping without a mutex"));
KASSERT(ident != NULL, ("msleep_spin_sbt: NULL ident"));
KASSERT(TD_IS_RUNNING(td), ("msleep_spin_sbt: curthread not running"));
@@ -278,7 +270,7 @@ msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg,
sleepq_lock(ident);
CTR5(KTR_PROC, "msleep_spin: thread %ld (pid %ld, %s) on %s (%p)",
- td->td_tid, p->p_pid, td->td_name, wmesg, ident);
+ td->td_tid, td->td_proc->p_pid, td->td_name, wmesg, ident);
DROP_GIANT();
mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED);
diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c
index 09a459aa..8076e7e3 100644
--- a/freebsd/sys/kern/subr_bus.c
+++ b/freebsd/sys/kern/subr_bus.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/conf.h>
+#include <sys/eventhandler.h>
#include <sys/filio.h>
#include <sys/lock.h>
#include <sys/kernel.h>
@@ -149,6 +150,10 @@ static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures");
static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc");
#ifndef __rtems__
+EVENTHANDLER_LIST_DEFINE(device_attach);
+EVENTHANDLER_LIST_DEFINE(device_detach);
+EVENTHANDLER_LIST_DEFINE(dev_lookup);
+
static void devctl2_init(void);
#endif /* __rtems__ */
@@ -2981,6 +2986,7 @@ device_attach(device_t dev)
dev->flags &= ~DF_DONENOMATCH;
#ifndef __rtems__
EVENTHANDLER_INVOKE(device_attach, dev);
+ EVENTHANDLER_DIRECT_INVOKE(device_attach, dev);
#endif /* __rtems__ */
devadded(dev);
return (0);
@@ -3016,16 +3022,18 @@ device_detach(device_t dev)
return (0);
#ifndef __rtems__
- EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN);
+ EVENTHANDLER_DIRECT_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN);
#endif /* __rtems__ */
if ((error = DEVICE_DETACH(dev)) != 0) {
#ifndef __rtems__
- EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_FAILED);
+ EVENTHANDLER_DIRECT_INVOKE(device_detach, dev,
+ EVHDEV_DETACH_FAILED);
#endif /* __rtems__ */
return (error);
} else {
#ifndef __rtems__
- EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_COMPLETE);
+ EVENTHANDLER_DIRECT_INVOKE(device_detach, dev,
+ EVHDEV_DETACH_COMPLETE);
#endif /* __rtems__ */
}
devremoved(dev);
@@ -5099,7 +5107,7 @@ print_device_short(device_t dev, int indent)
if (!dev)
return;
- indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
+ indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
dev->unit, dev->desc,
(dev->parent? "":"no "),
(TAILQ_EMPTY(&dev->children)? "no ":""),
@@ -5108,6 +5116,7 @@ print_device_short(device_t dev, int indent)
(dev->flags&DF_WILDCARD? "wildcard,":""),
(dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
(dev->flags&DF_REBID? "rebiddable,":""),
+ (dev->flags&DF_SUSPENDED? "suspended,":""),
(dev->ivars? "":"no "),
(dev->softc? "":"no "),
dev->busy));
@@ -5388,7 +5397,7 @@ find_device(struct devreq *req, device_t *devp)
/* Finally, give device enumerators a chance. */
dev = NULL;
- EVENTHANDLER_INVOKE(dev_lookup, req->dr_name, &dev);
+ EVENTHANDLER_DIRECT_INVOKE(dev_lookup, req->dr_name, &dev);
if (dev == NULL)
return (ENOENT);
*devp = dev;
@@ -5655,6 +5664,56 @@ devctl2_init(void)
UID_ROOT, GID_WHEEL, 0600, "devctl2");
}
+/*
+ * APIs to manage deprecation and obsolescence.
+ */
+static int obsolete_panic = 0;
+SYSCTL_INT(_debug, OID_AUTO, obsolete_panic, CTLFLAG_RWTUN, &obsolete_panic, 0,
+ "Bus debug level");
+/* 0 - don't panic, 1 - panic if already obsolete, 2 - panic if deprecated */
+static void
+gone_panic(int major, int running, const char *msg)
+{
+
+ switch (obsolete_panic)
+ {
+ case 0:
+ return;
+ case 1:
+ if (running < major)
+ return;
+ /* FALLTHROUGH */
+ default:
+ panic("%s", msg);
+ }
+}
+
+void
+_gone_in(int major, const char *msg)
+{
+
+ gone_panic(major, P_OSREL_MAJOR(__FreeBSD_version), msg);
+ if (P_OSREL_MAJOR(__FreeBSD_version) >= major)
+ printf("Obsolete code will removed soon: %s\n", msg);
+ else if (P_OSREL_MAJOR(__FreeBSD_version) + 1 == major)
+ printf("Deprecated code (to be removed in FreeBSD %d): %s\n",
+ major, msg);
+}
+
+void
+_gone_in_dev(device_t dev, int major, const char *msg)
+{
+
+ gone_panic(major, P_OSREL_MAJOR(__FreeBSD_version), msg);
+ if (P_OSREL_MAJOR(__FreeBSD_version) >= major)
+ device_printf(dev,
+ "Obsolete code will removed soon: %s\n", msg);
+ else if (P_OSREL_MAJOR(__FreeBSD_version) + 1 == major)
+ device_printf(dev,
+ "Deprecated code (to be removed in FreeBSD %d): %s\n",
+ major, msg);
+}
+
#ifdef DDB
DB_SHOW_COMMAND(device, db_show_device)
{
diff --git a/freebsd/sys/kern/subr_hash.c b/freebsd/sys/kern/subr_hash.c
index 488d8bcd..dd442931 100644
--- a/freebsd/sys/kern/subr_hash.c
+++ b/freebsd/sys/kern/subr_hash.c
@@ -59,9 +59,8 @@ void *
hashinit_flags(int elements, struct malloc_type *type, u_long *hashmask,
int flags)
{
- long hashsize;
+ long hashsize, i;
LIST_HEAD(generic, generic) *hashtbl;
- int i;
KASSERT(elements > 0, ("%s: bad elements", __func__));
/* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */
@@ -116,9 +115,8 @@ static const int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531,
void *
phashinit_flags(int elements, struct malloc_type *type, u_long *nentries, int flags)
{
- long hashsize;
+ long hashsize, i;
LIST_HEAD(generic, generic) *hashtbl;
- int i;
KASSERT(elements > 0, ("%s: bad elements", __func__));
/* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */
diff --git a/freebsd/sys/kern/subr_prf.c b/freebsd/sys/kern/subr_prf.c
index 0405b369..12a0825d 100644
--- a/freebsd/sys/kern/subr_prf.c
+++ b/freebsd/sys/kern/subr_prf.c
@@ -137,6 +137,7 @@ static void snprintf_func(int ch, void *arg);
#ifndef __rtems__
static int msgbufmapped; /* Set when safe to use msgbuf */
int msgbuftrigger;
+struct msgbuf *msgbufp;
static int log_console_output = 1;
SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RWTUN,
@@ -290,6 +291,7 @@ _vprintf(int level, int flags, const char *fmt, va_list ap)
char bufr[PRINTF_BUFR_SIZE];
#endif
+ TSENTER();
pca.tty = NULL;
pca.pri = level;
pca.flags = flags;
@@ -317,6 +319,7 @@ _vprintf(int level, int flags, const char *fmt, va_list ap)
}
#endif
+ TSEXIT();
return (retval);
}
#else /* __rtems__ */
diff --git a/freebsd/sys/kern/subr_sleepqueue.c b/freebsd/sys/kern/subr_sleepqueue.c
index fa33af86..6ecefc70 100644
--- a/freebsd/sys/kern/subr_sleepqueue.c
+++ b/freebsd/sys/kern/subr_sleepqueue.c
@@ -1441,11 +1441,10 @@ sleepq_sbuf_print_stacks(struct sbuf *sb, void *wchan, int queue,
struct stack **st;
struct sbuf **td_infos;
int i, stack_idx, error, stacks_to_allocate;
- bool finished, partial_print;
+ bool finished;
error = 0;
finished = false;
- partial_print = false;
KASSERT(wchan != NULL, ("%s: invalid NULL wait channel", __func__));
MPASS((queue >= 0) && (queue < NR_SLEEPQS));
diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c
index 118b4c77..1c46bd29 100644
--- a/freebsd/sys/kern/sys_generic.c
+++ b/freebsd/sys/kern/sys_generic.c
@@ -2004,6 +2004,8 @@ seltdfini(struct thread *td)
if (stp->st_free2)
uma_zfree(selfd_zone, stp->st_free2);
td->td_sel = NULL;
+ cv_destroy(&stp->st_wait);
+ mtx_destroy(&stp->st_mtx);
free(stp, M_SELECT);
}
diff --git a/freebsd/sys/kern/sys_socket.c b/freebsd/sys/kern/sys_socket.c
index 974f7eec..4f4ce99e 100644
--- a/freebsd/sys/kern/sys_socket.c
+++ b/freebsd/sys/kern/sys_socket.c
@@ -585,6 +585,7 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
kif->kf_type = KF_TYPE_SOCKET;
so = fp->f_data;
+ CURVNET_SET(so->so_vnet);
kif->kf_un.kf_sock.kf_sock_domain0 =
so->so_proto->pr_domain->dom_family;
kif->kf_un.kf_sock.kf_sock_type0 = so->so_type;
@@ -637,6 +638,7 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
}
strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
sizeof(kif->kf_path));
+ CURVNET_RESTORE();
return (0);
}
diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c
index 9f7e545f..7849be9d 100644
--- a/freebsd/sys/kern/uipc_usrreq.c
+++ b/freebsd/sys/kern/uipc_usrreq.c
@@ -1724,13 +1724,13 @@ unp_disconnect(struct unpcb *unp, struct unpcb *unp2)
static int
unp_pcblist(SYSCTL_HANDLER_ARGS)
{
- int error, i, n;
- int freeunp;
struct unpcb *unp, **unp_list;
unp_gen_t gencnt;
struct xunpgen *xug;
struct unp_head *head;
struct xunpcb *xu;
+ u_int i;
+ int error, freeunp, n;
switch ((intptr_t)arg1) {
case SOCK_STREAM:
diff --git a/freebsd/sys/net/altq/altq_hfsc.h b/freebsd/sys/net/altq/altq_hfsc.h
index de5e89b8..0a9fcf95 100644
--- a/freebsd/sys/net/altq/altq_hfsc.h
+++ b/freebsd/sys/net/altq/altq_hfsc.h
@@ -192,7 +192,7 @@ struct hfsc_class_stats {
* representation.
* the slope values are scaled to avoid overflow.
* the inverse slope values as well as the y-projection of the 1st
- * segment are kept in order to to avoid 64-bit divide operations
+ * segment are kept in order to avoid 64-bit divide operations
* that are expensive on 32-bit architectures.
*
* note: Intel Pentium TSC never wraps around in several thousands of years.
diff --git a/freebsd/sys/net/bpf.c b/freebsd/sys/net/bpf.c
index 6fc6b435..e6ad9e25 100644
--- a/freebsd/sys/net/bpf.c
+++ b/freebsd/sys/net/bpf.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <sys/ttycom.h>
#include <sys/uio.h>
+#include <sys/sysent.h>
#include <sys/event.h>
#include <sys/file.h>
@@ -728,7 +729,7 @@ bpf_check_upgrade(u_long cmd, struct bpf_d *d, struct bpf_insn *fcode, int flen)
* Check if cmd looks like snaplen setting from
* pcap_bpf.c:pcap_open_live().
* Note we're not checking .k value here:
- * while pcap_open_live() definitely sets to to non-zero value,
+ * while pcap_open_live() definitely sets to non-zero value,
* we'd prefer to treat k=0 (deny ALL) case the same way: e.g.
* do not consider upgrading immediately
*/
@@ -1396,9 +1397,11 @@ bpfioctl(struct bpf_d *d, u_long cmd, caddr_t addr, int flags,
case BIOCGDLTLIST32:
case BIOCGRTIMEOUT32:
case BIOCSRTIMEOUT32:
- BPFD_LOCK(d);
- d->bd_compat32 = 1;
- BPFD_UNLOCK(d);
+ if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+ BPFD_LOCK(d);
+ d->bd_compat32 = 1;
+ BPFD_UNLOCK(d);
+ }
}
#endif
diff --git a/freebsd/sys/net/ieee8023ad_lacp.c b/freebsd/sys/net/ieee8023ad_lacp.c
index 1778193d..2a30f4a3 100644
--- a/freebsd/sys/net/ieee8023ad_lacp.c
+++ b/freebsd/sys/net/ieee8023ad_lacp.c
@@ -203,8 +203,8 @@ SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, debug, CTLFLAG_RWTUN | CTLFLAG_VNET,
&VNET_NAME(lacp_debug), 0, "Enable LACP debug logging (1=debug, 2=trace)");
static VNET_DEFINE(int, lacp_default_strict_mode) = 1;
-SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, default_strict_mode, CTLFLAG_RWTUN,
- &VNET_NAME(lacp_default_strict_mode), 0,
+SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, default_strict_mode,
+ CTLFLAG_RWTUN | CTLFLAG_VNET, &VNET_NAME(lacp_default_strict_mode), 0,
"LACP strict protocol compliance default");
#define LACP_DPRINTF(a) if (V_lacp_debug & 0x01) { lacp_dprintf a ; }
diff --git a/freebsd/sys/net/if_clone.c b/freebsd/sys/net/if_clone.c
index 99faa05f..295bddf4 100644
--- a/freebsd/sys/net/if_clone.c
+++ b/freebsd/sys/net/if_clone.c
@@ -357,7 +357,7 @@ if_clone_alloc(const char *name, int maxunit)
return (ifc);
}
-
+
static int
if_clone_attach(struct if_clone *ifc)
{
@@ -389,10 +389,8 @@ if_clone_advanced(const char *name, u_int maxunit, ifc_match_t match,
ifc->ifc_create = create;
ifc->ifc_destroy = destroy;
- if (if_clone_attach(ifc) != 0) {
- if_clone_free(ifc);
+ if (if_clone_attach(ifc) != 0)
return (NULL);
- }
EVENTHANDLER_INVOKE(if_clone_event, ifc);
@@ -412,10 +410,8 @@ if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy,
ifc->ifcs_destroy = destroy;
ifc->ifcs_minifs = minifs;
- if (if_clone_attach(ifc) != 0) {
- if_clone_free(ifc);
+ if (if_clone_attach(ifc) != 0)
return (NULL);
- }
for (unit = 0; unit < minifs; unit++) {
char name[IFNAMSIZ];
@@ -452,7 +448,7 @@ if_clone_detach(struct if_clone *ifc)
/* destroy all interfaces for this cloner */
while (!LIST_EMPTY(&ifc->ifc_iflist))
if_clone_destroyif(ifc, LIST_FIRST(&ifc->ifc_iflist));
-
+
IF_CLONE_REMREF(ifc);
}
@@ -514,7 +510,7 @@ if_clone_list(struct if_clonereq *ifcr)
done:
IF_CLONERS_UNLOCK();
- if (err == 0)
+ if (err == 0 && dst != NULL)
err = copyout(outbuf, dst, buf_count*IFNAMSIZ);
if (outbuf != NULL)
free(outbuf, M_CLONE);
diff --git a/freebsd/sys/net/if_ethersubr.c b/freebsd/sys/net/if_ethersubr.c
index 9b927511..24f11436 100644
--- a/freebsd/sys/net/if_ethersubr.c
+++ b/freebsd/sys/net/if_ethersubr.c
@@ -292,7 +292,6 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
int hlen; /* link layer header length */
uint32_t pflags;
struct llentry *lle = NULL;
- struct rtentry *rt0 = NULL;
int addref = 0;
phdr = NULL;
@@ -322,7 +321,6 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
pflags = lle->r_flags;
}
}
- rt0 = ro->ro_rt;
}
#ifdef MAC
diff --git a/freebsd/sys/net/if_gif.c b/freebsd/sys/net/if_gif.c
index fdbccbb6..bd33ab75 100644
--- a/freebsd/sys/net/if_gif.c
+++ b/freebsd/sys/net/if_gif.c
@@ -526,7 +526,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn)
struct ip6_hdr *ip6;
uint32_t t;
#endif
- struct gif_softc *sc;
struct ether_header *eh;
struct ifnet *oldifp;
int isr, n, af;
@@ -536,7 +535,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn)
m_freem(m);
return;
}
- sc = ifp->if_softc;
m->m_pkthdr.rcvif = ifp;
m_clrprotoflags(m);
switch (proto) {
diff --git a/freebsd/sys/net/if_lagg.c b/freebsd/sys/net/if_lagg.c
index ce696fb2..36c8095a 100644
--- a/freebsd/sys/net/if_lagg.c
+++ b/freebsd/sys/net/if_lagg.c
@@ -246,7 +246,7 @@ SYSCTL_INT(_net_link_lagg, OID_AUTO, failover_rx_all, CTLFLAG_RW | CTLFLAG_VNET,
"Accept input from any interface in a failover lagg");
/* Default value for using flowid */
-static VNET_DEFINE(int, def_use_flowid) = 1;
+static VNET_DEFINE(int, def_use_flowid) = 0;
#define V_def_use_flowid VNET(def_use_flowid)
SYSCTL_INT(_net_link_lagg, OID_AUTO, default_use_flowid, CTLFLAG_RWTUN,
&VNET_NAME(def_use_flowid), 0,
diff --git a/freebsd/sys/net/iflib.h b/freebsd/sys/net/iflib.h
index 70992fdd..3730f0ea 100644
--- a/freebsd/sys/net/iflib.h
+++ b/freebsd/sys/net/iflib.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014-2017, Matthew Macy (mmacy@nextbsd.org)
+ * Copyright (c) 2014-2017, Matthew Macy (mmacy@mattmacy.io)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -174,9 +174,9 @@ typedef struct pci_vendor_info {
#define PVID_END {0, 0, 0, 0, 0, 0, NULL}
#define IFLIB_PNP_DESCR "U32:vendor;U32:device;U32:subvendor;U32:subdevice;" \
- "U32:revision;U32:class;D:human"
+ "U32:revision;U32:class;D:#"
#define IFLIB_PNP_INFO(b, u, t) \
- MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), nitems(t))
+ MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), nitems(t) - 1)
typedef struct if_txrx {
int (*ift_txd_encap) (void *, if_pkt_info_t);
@@ -217,6 +217,8 @@ typedef struct if_softc_ctx {
iflib_intr_mode_t isc_intr;
uint16_t isc_max_frame_size; /* set at init time by driver */
+ uint16_t isc_min_frame_size; /* set at init time by driver, only used if
+ IFLIB_NEED_ETHER_PAD is set. */
uint32_t isc_pause_frames; /* set by driver for iflib_timer to detect */
pci_vendor_info_t isc_vendor_info; /* set by iflib prior to attach_pre */
int isc_disable_msix;
@@ -314,6 +316,10 @@ typedef enum {
* Driver needs csum zeroed for offloading
*/
#define IFLIB_NEED_ZERO_CSUM 0x80
+/*
+ * Driver needs frames padded to some minimum length
+ */
+#define IFLIB_NEED_ETHER_PAD 0x100
diff --git a/freebsd/sys/net/pfvar.h b/freebsd/sys/net/pfvar.h
index 4bc84d94..c9b1d1db 100644
--- a/freebsd/sys/net/pfvar.h
+++ b/freebsd/sys/net/pfvar.h
@@ -1619,6 +1619,7 @@ int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *,
u_int32_t
pf_state_expires(const struct pf_state *);
void pf_purge_expired_fragments(void);
+void pf_purge_fragments(uint32_t);
int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *,
int);
int pf_socket_lookup(int, struct pf_pdesc *, struct mbuf *);
diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c
index 1be39753..ade738a2 100644
--- a/freebsd/sys/net/route.c
+++ b/freebsd/sys/net/route.c
@@ -1765,6 +1765,8 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
int family, mtu;
struct if_mtuinfo ifmtu;
+ RIB_WLOCK_ASSERT(rnh);
+
rt = (struct rtentry *)rnh->rnh_lookup(info->rti_info[RTAX_DST],
info->rti_info[RTAX_NETMASK], &rnh->head);
@@ -1813,8 +1815,9 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
/* Check if outgoing interface has changed */
if (info->rti_ifa != NULL && info->rti_ifa != rt->rt_ifa &&
- rt->rt_ifa != NULL && rt->rt_ifa->ifa_rtrequest != NULL) {
- rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, info);
+ rt->rt_ifa != NULL) {
+ if (rt->rt_ifa->ifa_rtrequest != NULL)
+ rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, info);
ifa_free(rt->rt_ifa);
}
/* Update gateway address */
@@ -1854,6 +1857,13 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
}
}
+ /*
+ * This route change may have modified the route's gateway. In that
+ * case, any inpcbs that have cached this route need to invalidate their
+ * llentry cache.
+ */
+ rnh->rnh_gen++;
+
if (ret_nrt) {
*ret_nrt = rt;
RT_ADDREF(rt);
diff --git a/freebsd/sys/net/route.h b/freebsd/sys/net/route.h
index 8835433e..28f1db01 100644
--- a/freebsd/sys/net/route.h
+++ b/freebsd/sys/net/route.h
@@ -416,6 +416,14 @@ struct rt_addrinfo {
} \
} while (0)
+#define RO_INVALIDATE_CACHE(ro) do { \
+ RO_RTFREE(ro); \
+ if ((ro)->ro_lle != NULL) { \
+ LLE_FREE((ro)->ro_lle); \
+ (ro)->ro_lle = NULL; \
+ } \
+ } while (0)
+
/*
* Validate a cached route based on a supplied cookie. If there is an
* out-of-date cache, simply free it. Update the generation number
@@ -424,10 +432,7 @@ struct rt_addrinfo {
#define RT_VALIDATE(ro, cookiep, fibnum) do { \
rt_gen_t cookie = RT_GEN(fibnum, (ro)->ro_dst.sa_family); \
if (*(cookiep) != cookie) { \
- if ((ro)->ro_rt != NULL) { \
- RTFREE((ro)->ro_rt); \
- (ro)->ro_rt = NULL; \
- } \
+ RO_INVALIDATE_CACHE(ro); \
*(cookiep) = cookie; \
} \
} while (0)
diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c
index fe608d70..851c30c9 100644
--- a/freebsd/sys/net/rtsock.c
+++ b/freebsd/sys/net/rtsock.c
@@ -114,6 +114,12 @@ struct ifa_msghdrl32 {
int32_t ifam_metric;
struct if_data ifam_data;
};
+
+#define SA_SIZE32(sa) \
+ ( (((struct sockaddr *)(sa))->sa_len == 0) ? \
+ sizeof(int) : \
+ 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(int) - 1) ) )
+
#endif /* COMPAT_FREEBSD32 */
MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
@@ -1128,6 +1134,9 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *
struct sockaddr_storage ss;
struct sockaddr_in6 *sin6;
#endif
+#ifdef COMPAT_FREEBSD32
+ bool compat32 = false;
+#endif
switch (type) {
@@ -1135,9 +1144,10 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *
case RTM_NEWADDR:
if (w != NULL && w->w_op == NET_RT_IFLISTL) {
#ifdef COMPAT_FREEBSD32
- if (w->w_req->flags & SCTL_MASK32)
+ if (w->w_req->flags & SCTL_MASK32) {
len = sizeof(struct ifa_msghdrl32);
- else
+ compat32 = true;
+ } else
#endif
len = sizeof(struct ifa_msghdrl);
} else
@@ -1151,6 +1161,7 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *
len = sizeof(struct if_msghdrl32);
else
len = sizeof(struct if_msghdr32);
+ compat32 = true;
break;
}
#endif
@@ -1181,7 +1192,12 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *
if ((sa = rtinfo->rti_info[i]) == NULL)
continue;
rtinfo->rti_addrs |= (1 << i);
- dlen = SA_SIZE(sa);
+#ifdef COMPAT_FREEBSD32
+ if (compat32)
+ dlen = SA_SIZE32(sa);
+ else
+#endif
+ dlen = SA_SIZE(sa);
if (cp != NULL && buflen >= dlen) {
#ifdef INET6
if (V_deembed_scopeid && sa->sa_family == AF_INET6) {
diff --git a/freebsd/sys/net/sff8472.h b/freebsd/sys/net/sff8472.h
index e67aa7f6..d38fcfc0 100644
--- a/freebsd/sys/net/sff8472.h
+++ b/freebsd/sys/net/sff8472.h
@@ -379,7 +379,7 @@ enum {
/*
* Table 3.2 Identifier values.
- * Identifier constants has taken from SFF-8024 rev 2.9 table 4.1
+ * Identifier constants has taken from SFF-8024 rev 4.2 table 4.1
* (as referenced by table 3.2 footer)
* */
enum {
@@ -400,13 +400,15 @@ enum {
SFF_8024_ID_CXP = 0xE, /* CXP */
SFF_8024_ID_HD4X = 0xF, /* Shielded Mini Multilane HD 4X */
SFF_8024_ID_HD8X = 0x10, /* Shielded Mini Multilane HD 8X */
- SFF_8024_ID_QSFP28 = 0x11, /* QSFP28 */
+ SFF_8024_ID_QSFP28 = 0x11, /* QSFP28 or later */
SFF_8024_ID_CXP2 = 0x12, /* CXP2 (aka CXP28) */
SFF_8024_ID_CDFP = 0x13, /* CDFP (Style 1/Style 2) */
SFF_8024_ID_SMM4 = 0x14, /* Shielded Mini Multilate HD 4X Fanout */
SFF_8024_ID_SMM8 = 0x15, /* Shielded Mini Multilate HD 8X Fanout */
SFF_8024_ID_CDFP3 = 0x16, /* CDFP (Style3) */
- SFF_8024_ID_LAST = SFF_8024_ID_CDFP3
+ SFF_8024_ID_MICROQSFP = 0x17, /* microQSFP */
+ SFF_8024_ID_QSFP_DD = 0x18, /* QSFP-DD 8X Pluggable Transceiver */
+ SFF_8024_ID_LAST = SFF_8024_ID_QSFP_DD
};
static const char *sff_8024_id[SFF_8024_ID_LAST + 1] = {"Unknown",
@@ -431,7 +433,9 @@ static const char *sff_8024_id[SFF_8024_ID_LAST + 1] = {"Unknown",
"CDFP",
"SMM4",
"SMM8",
- "CDFP3"};
+ "CDFP3",
+ "microQSFP",
+ "QSFP-DD"};
/* Keep compatibility with old definitions */
#define SFF_8472_ID_UNKNOWN SFF_8024_ID_UNKNOWN
diff --git a/freebsd/sys/net80211/ieee80211_ht.c b/freebsd/sys/net80211/ieee80211_ht.c
index 21d85fb3..c6a3a200 100644
--- a/freebsd/sys/net80211/ieee80211_ht.c
+++ b/freebsd/sys/net80211/ieee80211_ht.c
@@ -3356,7 +3356,7 @@ ieee80211_add_htinfo_body(uint8_t *frm, struct ieee80211_node *ni)
}
/*
- * Add 802.11n HT information information element.
+ * Add 802.11n HT information element.
*/
uint8_t *
ieee80211_add_htinfo(uint8_t *frm, struct ieee80211_node *ni)
diff --git a/freebsd/sys/net80211/ieee80211_node.c b/freebsd/sys/net80211/ieee80211_node.c
index 023fb128..45d6fa73 100644
--- a/freebsd/sys/net80211/ieee80211_node.c
+++ b/freebsd/sys/net80211/ieee80211_node.c
@@ -245,7 +245,12 @@ ieee80211_node_setuptxparms(struct ieee80211_node *ni)
struct ieee80211vap *vap = ni->ni_vap;
enum ieee80211_phymode mode;
- if (ni->ni_flags & IEEE80211_NODE_HT) {
+ if (ni->ni_flags & IEEE80211_NODE_VHT) {
+ if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan))
+ mode = IEEE80211_MODE_VHT_5GHZ;
+ else
+ mode = IEEE80211_MODE_VHT_2GHZ;
+ } else if (ni->ni_flags & IEEE80211_NODE_HT) {
if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan))
mode = IEEE80211_MODE_11NA;
else
diff --git a/freebsd/sys/net80211/ieee80211_output.c b/freebsd/sys/net80211/ieee80211_output.c
index 51a75af2..a49c8a16 100644
--- a/freebsd/sys/net80211/ieee80211_output.c
+++ b/freebsd/sys/net80211/ieee80211_output.c
@@ -553,6 +553,59 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
return (error);
}
+static int
+ieee80211_validate_frame(struct mbuf *m,
+ const struct ieee80211_bpf_params *params)
+{
+ struct ieee80211_frame *wh;
+ int type;
+
+ if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_ack))
+ return (EINVAL);
+
+ wh = mtod(m, struct ieee80211_frame *);
+ if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
+ IEEE80211_FC0_VERSION_0)
+ return (EINVAL);
+
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ if (type != IEEE80211_FC0_TYPE_DATA) {
+ if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) !=
+ IEEE80211_FC1_DIR_NODS)
+ return (EINVAL);
+
+ if (type != IEEE80211_FC0_TYPE_MGT &&
+ (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) != 0)
+ return (EINVAL);
+
+ /* XXX skip other field checks? */
+ }
+
+ if ((params && (params->ibp_flags & IEEE80211_BPF_CRYPTO) != 0) ||
+ (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0) {
+ int subtype;
+
+ subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ /*
+ * See IEEE Std 802.11-2012,
+ * 8.2.4.1.9 'Protected Frame field'
+ */
+ /* XXX no support for robust management frames yet. */
+ if (!(type == IEEE80211_FC0_TYPE_DATA ||
+ (type == IEEE80211_FC0_TYPE_MGT &&
+ subtype == IEEE80211_FC0_SUBTYPE_AUTH)))
+ return (EINVAL);
+
+ wh->i_fc[1] |= IEEE80211_FC1_PROTECTED;
+ }
+
+ if (m->m_pkthdr.len < ieee80211_anyhdrsize(wh))
+ return (EINVAL);
+
+ return (0);
+}
+
/*
* 802.11 output routine. This is (currently) used only to
* connect bpf write calls to the 802.11 layer for injecting
@@ -563,6 +616,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro)
{
#define senderr(e) do { error = (e); goto bad;} while (0)
+ const struct ieee80211_bpf_params *params = NULL;
struct ieee80211_node *ni = NULL;
struct ieee80211vap *vap;
struct ieee80211_frame *wh;
@@ -608,14 +662,20 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
senderr(EIO);
/* XXX bypass bridge, pfil, carp, etc. */
- if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_ack))
- senderr(EIO); /* XXX */
+ /*
+ * NB: DLT_IEEE802_11_RADIO identifies the parameters are
+ * present by setting the sa_len field of the sockaddr (yes,
+ * this is a hack).
+ * NB: we assume sa_data is suitably aligned to cast.
+ */
+ if (dst->sa_len != 0)
+ params = (const struct ieee80211_bpf_params *)dst->sa_data;
+
+ error = ieee80211_validate_frame(m, params);
+ if (error != 0)
+ senderr(error);
+
wh = mtod(m, struct ieee80211_frame *);
- if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
- IEEE80211_FC0_VERSION_0)
- senderr(EIO); /* XXX */
- if (m->m_pkthdr.len < ieee80211_anyhdrsize(wh))
- senderr(EIO); /* XXX */
/* locate destination node */
switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
@@ -628,7 +688,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
ni = ieee80211_find_txnode(vap, wh->i_addr3);
break;
default:
- senderr(EIO); /* XXX */
+ senderr(EDOOFUS);
}
if (ni == NULL) {
/*
@@ -647,11 +707,18 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
* it marks EAPOL in frames with M_EAPOL.
*/
m->m_flags &= ~M_80211_TX;
+ m->m_flags |= M_ENCAP; /* mark encapsulated */
- /* calculate priority so drivers can find the tx queue */
- /* XXX assumes an 802.3 frame */
- if (ieee80211_classify(ni, m))
- senderr(EIO); /* XXX */
+ if (IEEE80211_IS_DATA(wh)) {
+ /* calculate priority so drivers can find the tx queue */
+ if (ieee80211_classify(ni, m))
+ senderr(EIO); /* XXX */
+
+ /* NB: ieee80211_encap does not include 802.11 header */
+ IEEE80211_NODE_STAT_ADD(ni, tx_bytes,
+ m->m_pkthdr.len - ieee80211_hdrsize(wh));
+ } else
+ M_WME_SETAC(m, WME_AC_BE);
IEEE80211_NODE_STAT(ni, tx_data);
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
@@ -659,20 +726,9 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
m->m_flags |= M_MCAST;
} else
IEEE80211_NODE_STAT(ni, tx_ucast);
- /* NB: ieee80211_encap does not include 802.11 header */
- IEEE80211_NODE_STAT_ADD(ni, tx_bytes, m->m_pkthdr.len);
IEEE80211_TX_LOCK(ic);
-
- /*
- * NB: DLT_IEEE802_11_RADIO identifies the parameters are
- * present by setting the sa_len field of the sockaddr (yes,
- * this is a hack).
- * NB: we assume sa_data is suitably aligned to cast.
- */
- ret = ieee80211_raw_output(vap, ni, m,
- (const struct ieee80211_bpf_params *)(dst->sa_len ?
- dst->sa_data : NULL));
+ ret = ieee80211_raw_output(vap, ni, m, params);
IEEE80211_TX_UNLOCK(ic);
return (ret);
bad:
@@ -1008,13 +1064,44 @@ ieee80211_send_nulldata(struct ieee80211_node *ni)
int
ieee80211_classify(struct ieee80211_node *ni, struct mbuf *m)
{
- const struct ether_header *eh = mtod(m, struct ether_header *);
+ const struct ether_header *eh = NULL;
+ uint16_t ether_type;
int v_wme_ac, d_wme_ac, ac;
+ if (__predict_false(m->m_flags & M_ENCAP)) {
+ struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
+ struct llc *llc;
+ int hdrlen, subtype;
+
+ subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+ if (subtype & IEEE80211_FC0_SUBTYPE_NODATA) {
+ ac = WME_AC_BE;
+ goto done;
+ }
+
+ hdrlen = ieee80211_hdrsize(wh);
+ if (m->m_pkthdr.len < hdrlen + sizeof(*llc))
+ return 1;
+
+ llc = (struct llc *)mtodo(m, hdrlen);
+ if (llc->llc_dsap != LLC_SNAP_LSAP ||
+ llc->llc_ssap != LLC_SNAP_LSAP ||
+ llc->llc_control != LLC_UI ||
+ llc->llc_snap.org_code[0] != 0 ||
+ llc->llc_snap.org_code[1] != 0 ||
+ llc->llc_snap.org_code[2] != 0)
+ return 1;
+
+ ether_type = llc->llc_snap.ether_type;
+ } else {
+ eh = mtod(m, struct ether_header *);
+ ether_type = eh->ether_type;
+ }
+
/*
* Always promote PAE/EAPOL frames to high priority.
*/
- if (eh->ether_type == htons(ETHERTYPE_PAE)) {
+ if (ether_type == htons(ETHERTYPE_PAE)) {
/* NB: mark so others don't need to check header */
m->m_flags |= M_EAPOL;
ac = WME_AC_VO;
@@ -1049,7 +1136,7 @@ ieee80211_classify(struct ieee80211_node *ni, struct mbuf *m)
/* XXX m_copydata may be too slow for fast path */
#ifdef INET
- if (eh->ether_type == htons(ETHERTYPE_IP)) {
+ if (eh && eh->ether_type == htons(ETHERTYPE_IP)) {
uint8_t tos;
/*
* IP frame, map the DSCP bits from the TOS field.
@@ -1062,7 +1149,7 @@ ieee80211_classify(struct ieee80211_node *ni, struct mbuf *m)
} else {
#endif /* INET */
#ifdef INET6
- if (eh->ether_type == htons(ETHERTYPE_IPV6)) {
+ if (eh && eh->ether_type == htons(ETHERTYPE_IPV6)) {
uint32_t flow;
uint8_t tos;
/*
diff --git a/freebsd/sys/net80211/ieee80211_proto.c b/freebsd/sys/net80211/ieee80211_proto.c
index 73410d70..129e11e2 100644
--- a/freebsd/sys/net80211/ieee80211_proto.c
+++ b/freebsd/sys/net80211/ieee80211_proto.c
@@ -1310,6 +1310,12 @@ ieee80211_wme_updateparams(struct ieee80211vap *vap)
}
}
+/*
+ * Fetch the WME parameters for the given VAP.
+ *
+ * When net80211 grows p2p, etc support, this may return different
+ * parameters for each VAP.
+ */
void
ieee80211_wme_vap_getparams(struct ieee80211vap *vap, struct chanAccParams *wp)
{
@@ -1317,6 +1323,12 @@ ieee80211_wme_vap_getparams(struct ieee80211vap *vap, struct chanAccParams *wp)
memcpy(wp, &vap->iv_ic->ic_wme.wme_chanParams, sizeof(*wp));
}
+/*
+ * For NICs which only support one set of WME paramaters (ie, softmac NICs)
+ * there may be different VAP WME parameters but only one is "active".
+ * This returns the "NIC" WME parameters for the currently active
+ * context.
+ */
void
ieee80211_wme_ic_getparams(struct ieee80211com *ic, struct chanAccParams *wp)
{
@@ -1324,6 +1336,26 @@ ieee80211_wme_ic_getparams(struct ieee80211com *ic, struct chanAccParams *wp)
memcpy(wp, &ic->ic_wme.wme_chanParams, sizeof(*wp));
}
+/*
+ * Return whether to use QoS on a given WME queue.
+ *
+ * This is intended to be called from the transmit path of softmac drivers
+ * which are setting NoAck bits in transmit descriptors.
+ *
+ * Ideally this would be set in some transmit field before the packet is
+ * queued to the driver but net80211 isn't quite there yet.
+ */
+int
+ieee80211_wme_vap_ac_is_noack(struct ieee80211vap *vap, int ac)
+{
+ /* Bounds/sanity check */
+ if (ac < 0 || ac >= WME_NUM_AC)
+ return (0);
+
+ /* Again, there's only one global context for now */
+ return (!! vap->iv_ic->ic_wme.wme_chanParams.cap_wmeParams[ac].wmep_noackPolicy);
+}
+
static void
parent_updown(void *arg, int npending)
{
diff --git a/freebsd/sys/net80211/ieee80211_proto.h b/freebsd/sys/net80211/ieee80211_proto.h
index 187f7018..28238ce8 100644
--- a/freebsd/sys/net80211/ieee80211_proto.h
+++ b/freebsd/sys/net80211/ieee80211_proto.h
@@ -298,6 +298,7 @@ void ieee80211_wme_vap_getparams(struct ieee80211vap *vap,
struct chanAccParams *);
void ieee80211_wme_ic_getparams(struct ieee80211com *ic,
struct chanAccParams *);
+int ieee80211_wme_vap_ac_is_noack(struct ieee80211vap *vap, int ac);
/*
* Return the WME TID from a QoS frame. If no TID
diff --git a/freebsd/sys/net80211/ieee80211_scan_sta.c b/freebsd/sys/net80211/ieee80211_scan_sta.c
index ed069ed8..a7a1fc29 100644
--- a/freebsd/sys/net80211/ieee80211_scan_sta.c
+++ b/freebsd/sys/net80211/ieee80211_scan_sta.c
@@ -121,7 +121,7 @@ static void sta_flush_table(struct sta_table *);
/*
* match_bss returns a bitmask describing if an entry is suitable
* for use. If non-zero the entry was deemed not suitable and it's
- * contents explains why. The following flags are or'd to to this
+ * contents explains why. The following flags are or'd to this
* mask and can be used to figure out why the entry was rejected.
*/
#define MATCH_CHANNEL 0x00001 /* channel mismatch */
diff --git a/freebsd/sys/netinet/icmp6.h b/freebsd/sys/netinet/icmp6.h
index b0ae67fe..310684b8 100644
--- a/freebsd/sys/netinet/icmp6.h
+++ b/freebsd/sys/netinet/icmp6.h
@@ -628,7 +628,7 @@ struct icmp6stat {
uint64_t icp6s_nd_badopt; /* bad ND options */
uint64_t icp6s_badns; /* bad neighbor solicitation */
uint64_t icp6s_badna; /* bad neighbor advertisement */
- uint64_t icp6s_badrs; /* bad router advertisement */
+ uint64_t icp6s_badrs; /* bad router solicitation */
uint64_t icp6s_badra; /* bad router advertisement */
uint64_t icp6s_badredirect; /* bad redirect message */
};
diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c
index 2783a276..2803126d 100644
--- a/freebsd/sys/netinet/in_pcb.c
+++ b/freebsd/sys/netinet/in_pcb.c
@@ -1331,9 +1331,7 @@ in_pcbfree(struct inpcb *inp)
if (inp->inp_moptions != NULL)
inp_freemoptions(inp->inp_moptions);
#endif
- RO_RTFREE(&inp->inp_route);
- if (inp->inp_route.ro_lle)
- LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */
+ RO_INVALIDATE_CACHE(&inp->inp_route);
inp->inp_vflag = 0;
inp->inp_flags2 |= INP_FREED;
@@ -2271,9 +2269,7 @@ void
in_losing(struct inpcb *inp)
{
- RO_RTFREE(&inp->inp_route);
- if (inp->inp_route.ro_lle)
- LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */
+ RO_INVALIDATE_CACHE(&inp->inp_route);
return;
}
diff --git a/freebsd/sys/netinet/ip_mroute.c b/freebsd/sys/netinet/ip_mroute.c
index eba4af63..3bf4fa91 100644
--- a/freebsd/sys/netinet/ip_mroute.c
+++ b/freebsd/sys/netinet/ip_mroute.c
@@ -2820,7 +2820,7 @@ static void
vnet_mroute_init(const void *unused __unused)
{
- MALLOC(V_nexpire, u_char *, mfchashsize, M_MRTABLE, M_WAITOK|M_ZERO);
+ V_nexpire = malloc(mfchashsize, M_MRTABLE, M_WAITOK|M_ZERO);
bzero(V_bw_meter_timers, sizeof(V_bw_meter_timers));
callout_init(&V_expire_upcalls_ch, 1);
callout_init(&V_bw_upcalls_ch, 1);
@@ -2834,7 +2834,7 @@ static void
vnet_mroute_uninit(const void *unused __unused)
{
- FREE(V_nexpire, M_MRTABLE);
+ free(V_nexpire, M_MRTABLE);
V_nexpire = NULL;
}
diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c
index 62110ed1..4944c035 100644
--- a/freebsd/sys/netinet/ip_output.c
+++ b/freebsd/sys/netinet/ip_output.c
@@ -304,11 +304,8 @@ again:
!RT_LINK_IS_UP(rte->rt_ifp) ||
dst->sin_family != AF_INET ||
dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
- RTFREE(rte);
- rte = ro->ro_rt = (struct rtentry *)NULL;
- if (ro->ro_lle)
- LLE_FREE(ro->ro_lle); /* zeros ro_lle */
- ro->ro_lle = (struct llentry *)NULL;
+ RO_INVALIDATE_CACHE(ro);
+ rte = NULL;
}
ia = NULL;
have_ia_ref = 0;
diff --git a/freebsd/sys/netinet/ip_reass.c b/freebsd/sys/netinet/ip_reass.c
index 30cf3ba4..64660228 100644
--- a/freebsd/sys/netinet/ip_reass.c
+++ b/freebsd/sys/netinet/ip_reass.c
@@ -379,6 +379,7 @@ ip_reass(struct mbuf *m)
q->m_nextpkt = NULL;
m->m_pkthdr.csum_flags &= q->m_pkthdr.csum_flags;
m->m_pkthdr.csum_data += q->m_pkthdr.csum_data;
+ m_demote_pkthdr(q);
m_cat(m, q);
}
/*
diff --git a/freebsd/sys/netinet/libalias/alias_mod.h b/freebsd/sys/netinet/libalias/alias_mod.h
index d57798f7..c646f794 100644
--- a/freebsd/sys/netinet/libalias/alias_mod.h
+++ b/freebsd/sys/netinet/libalias/alias_mod.h
@@ -43,7 +43,7 @@ MALLOC_DECLARE(M_ALIAS);
#if defined(_SYS_MALLOC_H_)
#ifndef __rtems__
#define malloc(x) malloc(x, M_ALIAS, M_NOWAIT|M_ZERO)
-#define calloc(x, n) malloc(x*n)
+#define calloc(n, x) mallocarray((n), (x), M_ALIAS, M_NOWAIT|M_ZERO)
#define free(x) free(x, M_ALIAS)
#else /* __rtems__ */
#undef malloc
diff --git a/freebsd/sys/netinet/libalias/alias_sctp.c b/freebsd/sys/netinet/libalias/alias_sctp.c
index f7fda7bf..4f7d4940 100644
--- a/freebsd/sys/netinet/libalias/alias_sctp.c
+++ b/freebsd/sys/netinet/libalias/alias_sctp.c
@@ -29,7 +29,7 @@
*/
/*
- * Alias_sctp forms part of the libalias kernel module to handle
+ * Alias_sctp forms part of the libalias kernel module to handle
* Network Address Translation (NAT) for the SCTP protocol.
*
* This software was developed by David A. Hayes and Jason But
@@ -41,13 +41,13 @@
* proposed by Jason But and Grenville Armitage:
* http://caia.swin.edu.au/urp/sonata/
*
- *
+ *
* This project has been made possible in part by a grant from
* the Cisco University Research Program Fund at Community
* Foundation Silicon Valley.
*
*/
-/** @mainpage
+/** @mainpage
* Alias_sctp is part of the SONATA (http://caia.swin.edu.au/urp/sonata) project
* to develop and release a BSD licensed implementation of a Network Address
* Translation (NAT) module that supports the Stream Control Transmission
@@ -178,7 +178,7 @@ static void SctpAliasLog(const char *format, ...);
*
* Calls the higher level ShowAliasStats() in alias_db.c which logs all current
* statistics about the libalias instance - including SCTP statistics
- *
+ *
* @param la Pointer to the libalias instance
*/
void SctpShowAliasStats(struct libalias *la);
@@ -189,7 +189,7 @@ static MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs");
/* Use kernel allocator. */
#ifdef _SYS_MALLOC_H_
#define sn_malloc(x) malloc(x, M_SCTPNAT, M_NOWAIT|M_ZERO)
-#define sn_calloc(n,x) sn_malloc(x * n)
+#define sn_calloc(n,x) mallocarray((n), (x), M_SCTPNAT, M_NOWAIT|M_ZERO)
#define sn_free(x) free(x, M_SCTPNAT)
#endif// #ifdef _SYS_MALLOC_H_
@@ -263,7 +263,7 @@ static MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs");
* Define various log levels and a macro to call specified log functions only if
* the current log level (sysctl_log_level) matches the specified level @{
*/
-#define SN_LOG_LOW 0
+#define SN_LOG_LOW 0
#define SN_LOG_EVENT 1
#define SN_LOG_INFO 2
#define SN_LOG_DETAIL 3
@@ -424,9 +424,9 @@ int sysctl_chg_loglevel(SYSCTL_HANDLER_ARGS)
error = sysctl_handle_int(oidp, &level, 0, req);
if (error) return (error);
- sysctl_log_level = (level > SN_LOG_DEBUG_MAX)?(SN_LOG_DEBUG_MAX):(level);
- sysctl_log_level = (level < SN_LOG_LOW)?(SN_LOG_LOW):(level);
-
+ level = (level > SN_LOG_DEBUG_MAX) ? (SN_LOG_DEBUG_MAX) : (level);
+ level = (level < SN_LOG_LOW) ? (SN_LOG_LOW) : (level);
+ sysctl_log_level = level;
return (0);
}
@@ -445,12 +445,11 @@ int sysctl_chg_timer(SYSCTL_HANDLER_ARGS)
error = sysctl_handle_int(oidp, &timer, 0, req);
if (error) return (error);
- timer = (timer > SN_MAX_TIMER)?(SN_MAX_TIMER):(timer);
+ timer = (timer > SN_MAX_TIMER) ? (SN_MAX_TIMER) : (timer);
- if (((u_int *)arg1) != &sysctl_holddown_timer)
- {
- timer = (timer < SN_MIN_TIMER)?(SN_MIN_TIMER):(timer);
- }
+ if (((u_int *)arg1) != &sysctl_holddown_timer) {
+ timer = (timer < SN_MIN_TIMER) ? (SN_MIN_TIMER) : (timer);
+ }
*(u_int *)arg1 = timer;
@@ -474,11 +473,11 @@ int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS)
error = sysctl_handle_int(oidp, &size, 0, req);
if (error) return (error);
- size = (size < SN_MIN_HASH_SIZE)?(SN_MIN_HASH_SIZE):((size > SN_MAX_HASH_SIZE)?(SN_MAX_HASH_SIZE):(size));
+ size = (size < SN_MIN_HASH_SIZE) ? (SN_MIN_HASH_SIZE) : ((size > SN_MAX_HASH_SIZE) ? (SN_MAX_HASH_SIZE) : (size));
size |= 0x00000001; /* make odd */
- for(;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2);
+ for (;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2);
sysctl_hashtable_size = size;
return (0);
@@ -487,7 +486,7 @@ int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS)
/** @ingroup sysctl
* @brief sysctl callback for changing net.inet.ip.alias.sctp.error_on_ootb
*
- * Updates the error_on_clash sysctl variable.
+ * Updates the error_on_clash sysctl variable.
* If set to 0, no ErrorM will be sent if there is a look up table clash
* If set to 1, an ErrorM is sent only to the local side
* If set to 2, an ErrorM is sent to the local side and global side if there is
@@ -542,16 +541,16 @@ int sysctl_chg_initialising_chunk_proc_limit(SYSCTL_HANDLER_ARGS)
if (error) return (error);
sysctl_initialising_chunk_proc_limit = (proclimit < 1) ? 1: proclimit;
- sysctl_chunk_proc_limit =
+ sysctl_chunk_proc_limit =
(sysctl_chunk_proc_limit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : sysctl_chunk_proc_limit;
-
+
return (0);
}
/** @ingroup sysctl
* @brief sysctl callback for changing net.inet.ip.alias.sctp.chunk_proc_limit
*
- * Updates the chunk_proc_limit sysctl variable.
+ * Updates the chunk_proc_limit sysctl variable.
* Number of chunks that should be processed to find key chunk:
* >= initialising_chunk_proc_limit (A high value is a DoS risk)
*/
@@ -563,7 +562,7 @@ int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS)
error = sysctl_handle_int(oidp, &proclimit, 0, req);
if (error) return (error);
- sysctl_chunk_proc_limit =
+ sysctl_chunk_proc_limit =
(proclimit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : proclimit;
return (0);
@@ -573,7 +572,7 @@ int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS)
/** @ingroup sysctl
* @brief sysctl callback for changing net.inet.ip.alias.sctp.param_proc_limit
*
- * Updates the param_proc_limit sysctl variable.
+ * Updates the param_proc_limit sysctl variable.
* Number of parameters that should be processed to find key parameters:
* > 1 (A high value is a DoS risk)
*/
@@ -585,7 +584,7 @@ int sysctl_chg_param_proc_limit(SYSCTL_HANDLER_ARGS)
error = sysctl_handle_int(oidp, &proclimit, 0, req);
if (error) return (error);
- sysctl_param_proc_limit =
+ sysctl_param_proc_limit =
(proclimit < 2) ? 2 : proclimit;
return (0);
@@ -616,9 +615,9 @@ int sysctl_chg_track_global_addresses(SYSCTL_HANDLER_ARGS)
* CODE BEGINS HERE
* ----------------------------------------------------------------------
*/
-/**
+/**
* @brief Initialises the SCTP NAT Implementation
- *
+ *
* Creates the look-up tables and the timer queue and initialises all state
* variables
*
@@ -652,7 +651,7 @@ void AliasSctpInit(struct libalias *la)
la->sctpLinkCount = 0;
}
-/**
+/**
* @brief Cleans-up the SCTP NAT Implementation prior to unloading
*
* Removes all entries from the timer queue, freeing associations as it goes.
@@ -707,7 +706,7 @@ void AliasSctpTerm(struct libalias *la)
* @param la Pointer to the relevant libalias instance
* @param pip Pointer to IP packet to process
* @param direction SN_TO_LOCAL | SN_TO_GLOBAL
- *
+ *
* @return PKT_ALIAS_OK | PKT_ALIAS_IGNORE | PKT_ALIAS_ERROR
*/
int
@@ -719,10 +718,10 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
if ((direction != SN_TO_LOCAL) && (direction != SN_TO_GLOBAL)) {
SctpAliasLog("ERROR: Invalid direction\n");
- return(PKT_ALIAS_ERROR);
+ return (PKT_ALIAS_ERROR);
}
- sctp_CheckTimers(la); /* Check timers */
+ sctp_CheckTimers(la); /* Check timers */
/* Parse the packet */
rtnval = sctp_PktParser(la, direction, pip, &msg, &assoc); //using *char (change to mbuf when get code from paolo)
@@ -737,24 +736,24 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
}
SN_LOG(SN_LOG_EVENT,
logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
- return(PKT_ALIAS_ERROR);
+ return (PKT_ALIAS_ERROR);
case SN_PARSE_ERROR_PARTIALLOOKUP:
if (sysctl_error_on_ootb > SN_LOCALandPARTIAL_ERROR_ON_OOTB) {
SN_LOG(SN_LOG_EVENT,
logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
- return(PKT_ALIAS_ERROR);
+ return (PKT_ALIAS_ERROR);
}
case SN_PARSE_ERROR_LOOKUP:
if (sysctl_error_on_ootb == SN_ERROR_ON_OOTB ||
(sysctl_error_on_ootb == SN_LOCALandPARTIAL_ERROR_ON_OOTB && direction == SN_TO_LOCAL) ||
(sysctl_error_on_ootb == SN_LOCAL_ERROR_ON_OOTB && direction == SN_TO_GLOBAL)) {
TxAbortErrorM(la, &msg, assoc, SN_REFLECT_ERROR, direction); /*NB assoc=NULL */
- return(PKT_ALIAS_RESPOND);
+ return (PKT_ALIAS_RESPOND);
}
default:
SN_LOG(SN_LOG_EVENT,
logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
- return(PKT_ALIAS_ERROR);
+ return (PKT_ALIAS_ERROR);
}
SN_LOG(SN_LOG_DETAIL,
@@ -772,9 +771,9 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
);
SN_LOG(SN_LOG_DEBUG, logTimerQ(la));
- switch(rtnval){
+ switch (rtnval) {
case SN_NAT_PKT:
- switch(direction) {
+ switch (direction) {
case SN_TO_LOCAL:
DifferentialChecksum(&(msg.ip_hdr->ip_sum),
&(assoc->l_addr), &(msg.ip_hdr->ip_dst), 2);
@@ -796,7 +795,7 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
break;
case SN_REPLY_ABORT:
case SN_REPLY_ERROR:
- case SN_SEND_ABORT:
+ case SN_SEND_ABORT:
TxAbortErrorM(la, &msg, assoc, rtnval, direction);
break;
default:
@@ -816,22 +815,22 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
freeGlobalAddressList(assoc);
sn_free(assoc);
}
- switch(rtnval) {
+ switch (rtnval) {
case SN_NAT_PKT:
- return(PKT_ALIAS_OK);
+ return (PKT_ALIAS_OK);
case SN_SEND_ABORT:
- return(PKT_ALIAS_OK);
+ return (PKT_ALIAS_OK);
case SN_REPLY_ABORT:
case SN_REPLY_ERROR:
case SN_REFLECT_ERROR:
- return(PKT_ALIAS_RESPOND);
+ return (PKT_ALIAS_RESPOND);
case SN_DROP_PKT:
default:
- return(PKT_ALIAS_ERROR);
+ return (PKT_ALIAS_ERROR);
}
}
-/**
+/**
* @brief Send an AbortM or ErrorM
*
* We construct the new SCTP packet to send in place of the existing packet we
@@ -867,7 +866,7 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
static uint32_t
local_sctp_finalize_crc32(uint32_t crc32c)
{
- /* This routine is duplicated from SCTP
+ /* This routine is duplicated from SCTP
* we need to do that since it MAY be that SCTP
* is NOT compiled into the kernel. The CRC32C routines
* however are always available in libkern.
@@ -926,7 +925,7 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
ip->ip_hl = 5; /* 5*32 bit words */
ip->ip_tos = 0;
ip->ip_len = htons(ip_size);
- ip->ip_id = sm->ip_hdr->ip_id;
+ ip->ip_id = sm->ip_hdr->ip_id;
ip->ip_off = 0;
ip->ip_ttl = 255;
ip->ip_p = IPPROTO_SCTP;
@@ -939,7 +938,7 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR;
chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG;
if (include_error_cause) {
- error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION);
+ error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION);
error_cause->length = htons(sizeof(struct sctp_error_cause));
chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause));
} else {
@@ -947,22 +946,22 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
}
/* set specific values */
- switch(sndrply) {
+ switch (sndrply) {
case SN_REFLECT_ERROR:
chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */
- sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
+ sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
break;
case SN_REPLY_ERROR:
- sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ;
+ sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ;
break;
case SN_SEND_ABORT:
- sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
+ sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
break;
case SN_REPLY_ABORT:
sctp_hdr->v_tag = sm->sctpchnk.Init->initiate_tag;
break;
}
-
+
/* Set send/reply values */
if (sndrply == SN_SEND_ABORT) { /*pass through NAT */
ip->ip_src = (direction == SN_TO_LOCAL) ? sm->ip_hdr->ip_src : assoc->a_addr;
@@ -975,10 +974,10 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
sctp_hdr->src_port = sm->sctp_hdr->dest_port;
sctp_hdr->dest_port = sm->sctp_hdr->src_port;
}
-
+
/* Calculate IP header checksum */
ip->ip_sum = in_cksum_hdr(ip);
-
+
/* calculate SCTP header CRC32 */
sctp_hdr->checksum = 0;
sctp_hdr->checksum = local_sctp_finalize_crc32(calculate_crc32c(0xffffffff, (unsigned char *) sctp_hdr, sctp_size));
@@ -1005,18 +1004,18 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
*/
/** @ingroup packet_parser
* @brief Parses SCTP packets for the key SCTP chunk that will be processed
- *
+ *
* This module parses SCTP packets for the key SCTP chunk that will be processed
* The module completes the sctp_nat_msg structure and either retrieves the
* relevant (existing) stored association from the Hash Tables or creates a new
* association entity with state SN_ID
*
* @param la Pointer to the relevant libalias instance
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
- * @param pip
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ * @param pip
* @param sm Pointer to sctp message information
* @param passoc Pointer to the association this SCTP Message belongs to
- *
+ *
* @return SN_PARSE_OK | SN_PARSE_ERROR_*
*/
static int
@@ -1051,26 +1050,26 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
/* Check SCTP header length and move to first chunk */
if (bytes_left < sizeof(struct sctphdr)) {
sm->sctp_hdr = NULL;
- return(SN_PARSE_ERROR_IPSHL); /* packet not long enough*/
+ return (SN_PARSE_ERROR_IPSHL); /* packet not long enough*/
}
sm->sctp_hdr = sctp_hdr = (struct sctphdr *) ip_next(pip);
bytes_left -= sizeof(struct sctphdr);
-
+
/* Check for valid ports (zero valued ports would find partially initialised associations */
if (sctp_hdr->src_port == 0 || sctp_hdr->dest_port == 0)
- return(SN_PARSE_ERROR_PORT);
+ return (SN_PARSE_ERROR_PORT);
/* Check length of first chunk */
if (bytes_left < SN_MIN_CHUNK_SIZE) /* malformed chunk - could cause endless loop*/
- return(SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */
-
+ return (SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */
+
/* First chunk */
chunk_hdr = SN_SCTP_FIRSTCHUNK(sctp_hdr);
-
+
chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length));
if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) /* malformed chunk - could cause endless loop*/
- return(SN_PARSE_ERROR_CHHL);
+ return (SN_PARSE_ERROR_CHHL);
if ((chunk_hdr->chunk_flags & SCTP_HAD_NO_TCB) &&
((chunk_hdr->chunk_type == SCTP_ABORT_ASSOCIATION) ||
@@ -1093,43 +1092,43 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
sm->msg = SN_SCTP_OTHER;/* Initialise to largest value*/
sm->chunk_length = 0; /* only care about length for key chunks */
while (IS_SCTP_CONTROL(chunk_hdr)) {
- switch(chunk_hdr->chunk_type) {
+ switch (chunk_hdr->chunk_type) {
case SCTP_INITIATION:
if (chunk_length < sizeof(struct sctp_init_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
+ return (SN_PARSE_ERROR_CHHL);
sm->msg = SN_SCTP_INIT;
sm->sctpchnk.Init = (struct sctp_init *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr));
sm->chunk_length = chunk_length;
/* if no existing association, create a new one */
if (*passoc == NULL) {
- if (sctp_hdr->v_tag == 0){ //Init requires vtag=0
+ if (sctp_hdr->v_tag == 0) { //Init requires vtag=0
*passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc));
- if (*passoc == NULL) {/* out of resources */
- return(SN_PARSE_ERROR_AS_MALLOC);
+ if (*passoc == NULL) {/* out of resources */
+ return (SN_PARSE_ERROR_AS_MALLOC);
}
- /* Initialise association - malloc initialises memory to zeros */
+ /* Initialize association - sn_malloc initializes memory to zeros */
(*passoc)->state = SN_ID;
LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */
(*passoc)->TableRegister = SN_NULL_TBL;
- return(SN_PARSE_OK);
+ return (SN_PARSE_OK);
}
- return(SN_PARSE_ERROR_VTAG);
+ return (SN_PARSE_ERROR_VTAG);
}
- return(SN_PARSE_ERROR_LOOKUP);
+ return (SN_PARSE_ERROR_LOOKUP);
case SCTP_INITIATION_ACK:
if (chunk_length < sizeof(struct sctp_init_ack_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
+ return (SN_PARSE_ERROR_CHHL);
sm->msg = SN_SCTP_INITACK;
sm->sctpchnk.InitAck = (struct sctp_init_ack *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr));
sm->chunk_length = chunk_length;
- return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK));
+ return ((*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP) : (SN_PARSE_OK));
case SCTP_ABORT_ASSOCIATION: /* access only minimum sized chunk */
sm->msg = SN_SCTP_ABORT;
sm->chunk_length = chunk_length;
- return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP_ABORT):(SN_PARSE_OK));
+ return ((*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP_ABORT) : (SN_PARSE_OK));
case SCTP_SHUTDOWN_ACK:
if (chunk_length < sizeof(struct sctp_shutdown_ack_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
+ return (SN_PARSE_ERROR_CHHL);
if (sm->msg > SN_SCTP_SHUTACK) {
sm->msg = SN_SCTP_SHUTACK;
sm->chunk_length = chunk_length;
@@ -1140,11 +1139,11 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
sm->msg = SN_SCTP_SHUTCOMP;
sm->chunk_length = chunk_length;
}
- return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK));
+ return ((*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP) : (SN_PARSE_OK));
case SCTP_ASCONF:
if (sm->msg > SN_SCTP_ASCONF) {
if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv4addr_param))) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
+ return (SN_PARSE_ERROR_CHHL);
//leave parameter searching to later, if required
param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + sizeof(struct sctp_asconf_chunk)); /*compulsory IP parameter*/
if (ntohs(param_hdr->param_type) == SCTP_IPV4_ADDRESS) {
@@ -1153,38 +1152,38 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
ipv4addr.s_addr = ((struct sctp_ipv4addr_param *) param_hdr)->addr;
*passoc = FindSctpGlobal(la, ipv4addr, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match);
}
- param_hdr = (struct sctp_paramhdr *)
+ param_hdr = (struct sctp_paramhdr *)
((char *) param_hdr + sizeof(struct sctp_ipv4addr_param)); /*asconf's compulsory address parameter */
sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv4addr_param); /* rest of chunk */
} else {
if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv6addr_param))) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
- param_hdr = (struct sctp_paramhdr *)
- ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */
+ return (SN_PARSE_ERROR_CHHL);
+ param_hdr = (struct sctp_paramhdr *)
+ ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */
sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv6addr_param); /* rest of chunk */
}
sm->msg = SN_SCTP_ASCONF;
sm->sctpchnk.Asconf = param_hdr;
-
+
if (*passoc == NULL) { /* AddIP with no association */
*passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc));
- if (*passoc == NULL) {/* out of resources */
- return(SN_PARSE_ERROR_AS_MALLOC);
+ if (*passoc == NULL) {/* out of resources */
+ return (SN_PARSE_ERROR_AS_MALLOC);
}
- /* Initialise association - malloc initialises memory to zeros */
+ /* Initialize association - sn_malloc initializes memory to zeros */
(*passoc)->state = SN_ID;
LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */
(*passoc)->TableRegister = SN_NULL_TBL;
- return(SN_PARSE_OK);
+ return (SN_PARSE_OK);
}
}
break;
case SCTP_ASCONF_ACK:
if (sm->msg > SN_SCTP_ASCONFACK) {
if (chunk_length < sizeof(struct sctp_asconf_ack_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
+ return (SN_PARSE_ERROR_CHHL);
//leave parameter searching to later, if required
- param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr
+ param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr
+ sizeof(struct sctp_asconf_ack_chunk));
sm->msg = SN_SCTP_ASCONFACK;
sm->sctpchnk.Asconf = param_hdr;
@@ -1197,33 +1196,33 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
/* if no association is found exit - we need to find an Init or AddIP within sysctl_initialising_chunk_proc_limit */
if ((*passoc == NULL) && (chunk_count >= sysctl_initialising_chunk_proc_limit))
- return(SN_PARSE_ERROR_LOOKUP);
+ return (SN_PARSE_ERROR_LOOKUP);
/* finished with this chunk, on to the next chunk*/
bytes_left-= chunk_length;
/* Is this the end of the packet ? */
if (bytes_left == 0)
- return (*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK);
+ return (*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP) : (SN_PARSE_OK);
/* Are there enough bytes in packet to at least retrieve length of next chunk ? */
if (bytes_left < SN_MIN_CHUNK_SIZE)
- return(SN_PARSE_ERROR_CHHL);
+ return (SN_PARSE_ERROR_CHHL);
chunk_hdr = SN_SCTP_NEXTCHUNK(chunk_hdr);
/* Is the chunk long enough to not cause endless look and are there enough bytes in packet to read the chunk ? */
chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length));
if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left))
- return(SN_PARSE_ERROR_CHHL);
- if(++chunk_count > sysctl_chunk_proc_limit)
- return(SN_PARSE_OK); /* limit for processing chunks, take what we get */
+ return (SN_PARSE_ERROR_CHHL);
+ if (++chunk_count > sysctl_chunk_proc_limit)
+ return (SN_PARSE_OK); /* limit for processing chunks, take what we get */
}
if (*passoc == NULL)
- return (partial_match)?(SN_PARSE_ERROR_PARTIALLOOKUP):(SN_PARSE_ERROR_LOOKUP);
+ return (partial_match) ? (SN_PARSE_ERROR_PARTIALLOOKUP) : (SN_PARSE_ERROR_LOOKUP);
else
- return(SN_PARSE_OK);
+ return (SN_PARSE_OK);
}
/** @ingroup packet_parser
@@ -1231,7 +1230,7 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
*
* GetAsconfVtags scans an Asconf Chunk for the vtags parameter, and then
* extracts the vtags.
- *
+ *
* GetAsconfVtags is not called from within sctp_PktParser. It is called only
* from within ID_process when an AddIP has been received.
*
@@ -1239,9 +1238,9 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
* @param sm Pointer to sctp message information
* @param l_vtag Pointer to the local vtag in the association this SCTP Message belongs to
* @param g_vtag Pointer to the local vtag in the association this SCTP Message belongs to
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
- *
- * @return 1 - success | 0 - fail
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ *
+ * @return 1 - success | 0 - fail
*/
static int
GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, uint32_t *g_vtag, int direction)
@@ -1253,7 +1252,7 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u
uint32_t local_vtag;
uint32_t remote_vtag;
} __attribute__((packed));
-
+
struct sctp_vtag_param *vtag_param;
struct sctp_paramhdr *param;
int bytes_left;
@@ -1268,7 +1267,7 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u
while((bytes_left >= param_size) && (bytes_left >= SN_VTAG_PARAM_SIZE)) {
if (ntohs(param->param_type) == SCTP_VTAG_PARAM) {
vtag_param = (struct sctp_vtag_param *) param;
- switch(direction) {
+ switch (direction) {
/* The Internet draft is a little ambigious as to order of these vtags.
We think it is this way around. If we are wrong, the order will need
to be changed. */
@@ -1281,11 +1280,11 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u
*l_vtag = vtag_param->local_vtag;
break;
}
- return(1); /* found */
+ return (1); /* found */
}
bytes_left -= param_size;
- if (bytes_left < SN_MIN_PARAM_SIZE) return(0);
+ if (bytes_left < SN_MIN_PARAM_SIZE) return (0);
param = SN_SCTP_NEXTPARAM(param);
param_size = SCTP_SIZE32(ntohs(param->param_length));
@@ -1293,22 +1292,22 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u
SN_LOG(SN_LOG_EVENT,
logsctperror("Parameter parse limit exceeded (GetAsconfVtags)",
sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- return(0); /* not found limit exceeded*/
+ return (0); /* not found limit exceeded*/
}
}
- return(0); /* not found */
+ return (0); /* not found */
}
/** @ingroup packet_parser
* @brief AddGlobalIPAddresses from Init,InitAck,or AddIP packets
- *
+ *
* AddGlobalIPAddresses scans an SCTP chunk (in sm) for Global IP addresses, and
* adds them.
*
* @param sm Pointer to sctp message information
* @param assoc Pointer to the association this SCTP Message belongs to
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
- *
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ *
*/
static void
AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction)
@@ -1321,7 +1320,7 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
int param_size;
int param_count, addr_param_count = 0;
- switch(direction) {
+ switch (direction) {
case SN_TO_GLOBAL: /* does not contain global addresses */
g_addr = sm->ip_hdr->ip_dst;
bytes_left = 0; /* force exit */
@@ -1329,7 +1328,7 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
case SN_TO_LOCAL:
g_addr = sm->ip_hdr->ip_src;
param_count = 1;
- switch(sm->msg) {
+ switch (sm->msg) {
case SN_SCTP_INIT:
bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk);
param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init));
@@ -1344,16 +1343,16 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
break;
}
}
- if (bytes_left >= SN_MIN_PARAM_SIZE)
+ if (bytes_left >= SN_MIN_PARAM_SIZE)
param_size = SCTP_SIZE32(ntohs(param->param_length));
else
param_size = bytes_left+1; /* force skip loop */
-
- if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */
+
+ if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */
G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress));
- if (G_Addr == NULL) {/* out of resources */
+ if (G_Addr == NULL) {/* out of resources */
SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
+ logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
sm->sctp_hdr->v_tag, 0, direction));
assoc->num_Gaddr = 0; /* don't track any more for this assoc*/
sysctl_track_global_addresses=0;
@@ -1362,7 +1361,7 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
G_Addr->g_addr = g_addr;
if (!Add_Global_Address_to_List(assoc, G_Addr))
SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Address already in list",
+ logsctperror("AddGlobalIPAddress: Address already in list",
sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
}
@@ -1370,21 +1369,22 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) {
if (assoc->num_Gaddr >= sysctl_track_global_addresses) {
SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached",
+ logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached",
sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
return;
}
- switch(ntohs(param->param_type)) {
+ switch (ntohs(param->param_type)) {
case SCTP_ADD_IP_ADDRESS:
/* skip to address parameter - leave param_size so bytes left will be calculated properly*/
param = (struct sctp_paramhdr *) &((struct sctp_asconf_addrv4_param *) param)->addrp;
+ /* FALLTHROUGH */
case SCTP_IPV4_ADDRESS:
ipv4_param = (struct sctp_ipv4addr_param *) param;
/* add addresses to association */
G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress));
- if (G_Addr == NULL) {/* out of resources */
+ if (G_Addr == NULL) {/* out of resources */
SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
+ logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
sm->sctp_hdr->v_tag, 0, direction));
assoc->num_Gaddr = 0; /* don't track any more for this assoc*/
sysctl_track_global_addresses=0;
@@ -1396,22 +1396,22 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
G_Addr->g_addr = g_addr;
if (!Add_Global_Address_to_List(assoc, G_Addr))
SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Address already in list",
+ logsctperror("AddGlobalIPAddress: Address already in list",
sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
return; /*shouldn't be any other addresses if the zero address is given*/
} else {
G_Addr->g_addr.s_addr = ipv4_param->addr;
if (!Add_Global_Address_to_List(assoc, G_Addr))
SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Address already in list",
+ logsctperror("AddGlobalIPAddress: Address already in list",
sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
}
- }
-
+ }
+
bytes_left -= param_size;
if (bytes_left < SN_MIN_PARAM_SIZE)
break;
-
+
param = SN_SCTP_NEXTPARAM(param);
param_size = SCTP_SIZE32(ntohs(param->param_length));
if (++param_count > sysctl_param_proc_limit) {
@@ -1423,39 +1423,39 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
}
if (addr_param_count == 0) {
SN_LOG(SN_LOG_DETAIL,
- logsctperror("AddGlobalIPAddress: no address parameters to add",
+ logsctperror("AddGlobalIPAddress: no address parameters to add",
sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
}
}
-/**
+/**
* @brief Add_Global_Address_to_List
*
* Adds a global IP address to an associations address list, if it is not
* already there. The first address added us usually the packet's address, and
* is most likely to be used, so it is added at the beginning. Subsequent
* addresses are added after this one.
- *
+ *
* @param assoc Pointer to the association this SCTP Message belongs to
* @param G_addr Pointer to the global address to add
*
- * @return 1 - success | 0 - fail
+ * @return 1 - success | 0 - fail
*/
static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr)
{
- struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL;
- first_G_Addr = LIST_FIRST(&(assoc->Gaddr));
+ struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL;
+ first_G_Addr = LIST_FIRST(&(assoc->Gaddr));
if (first_G_Addr == NULL) {
LIST_INSERT_HEAD(&(assoc->Gaddr), G_addr, list_Gaddr); /* add new address to beginning of list*/
} else {
LIST_FOREACH(iter_G_Addr, &(assoc->Gaddr), list_Gaddr) {
if (G_addr->g_addr.s_addr == iter_G_Addr->g_addr.s_addr)
- return(0); /* already exists, so don't add */
+ return (0); /* already exists, so don't add */
}
LIST_INSERT_AFTER(first_G_Addr, G_addr, list_Gaddr); /* add address to end of list*/
}
- assoc->num_Gaddr++;
- return(1); /* success */
+ assoc->num_Gaddr++;
+ return (1); /* success */
}
/** @ingroup packet_parser
@@ -1468,8 +1468,8 @@ static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sct
*
* @param sm Pointer to sctp message information
* @param assoc Pointer to the association this SCTP Message belongs to
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
- *
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ *
*/
static void
RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction)
@@ -1482,7 +1482,7 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d
int param_size;
int param_count;
- if(direction == SN_TO_GLOBAL)
+ if (direction == SN_TO_GLOBAL)
g_addr = sm->ip_hdr->ip_dst;
else
g_addr = sm->ip_hdr->ip_src;
@@ -1490,29 +1490,29 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d
bytes_left = sm->chunk_length;
param_count = 1;
param = sm->sctpchnk.Asconf;
- if (bytes_left >= SN_MIN_PARAM_SIZE) {
+ if (bytes_left >= SN_MIN_PARAM_SIZE) {
param_size = SCTP_SIZE32(ntohs(param->param_length));
} else {
SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses",
+ logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses",
sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
return;
}
-
+
/* step through Asconf parameters */
while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) {
if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) {
asconf_ipv4_param = (struct sctp_asconf_addrv4_param *) param;
if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */
LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) {
- if(G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) {
+ if (G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) {
if (assoc->num_Gaddr > 1) { /* only delete if more than one */
LIST_REMOVE(G_Addr, list_Gaddr);
sn_free(G_Addr);
assoc->num_Gaddr--;
} else {
SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
+ logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
}
}
@@ -1520,7 +1520,7 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d
return; /*shouldn't be any other addresses if the zero address is given*/
} else {
LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) {
- if(G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) {
+ if (G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) {
if (assoc->num_Gaddr > 1) { /* only delete if more than one */
LIST_REMOVE(G_Addr, list_Gaddr);
sn_free(G_Addr);
@@ -1528,22 +1528,22 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d
break; /* Since add only adds new addresses, there should be no double entries */
} else {
SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
+ logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
}
}
}
}
- }
+ }
bytes_left -= param_size;
if (bytes_left == 0) return;
else if (bytes_left < SN_MIN_PARAM_SIZE) {
SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses",
+ logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses",
sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
return;
}
-
+
param = SN_SCTP_NEXTPARAM(param);
param_size = SCTP_SIZE32(ntohs(param->param_length));
if (++param_count > sysctl_param_proc_limit) {
@@ -1570,11 +1570,11 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d
* Since there is currently no connection on this path, there should be no other
* ASCONF configuration parameters outstanding, so we presume that if there is
* an ACK that it is responding to the AddIP and activate the new association.
- *
+ *
* @param la Pointer to the relevant libalias instance
* @param sm Pointer to sctp message information
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
- *
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ *
* @return 1 - success | 0 - fail
*/
static int
@@ -1589,45 +1589,45 @@ IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction)
param = sm->sctpchnk.Asconf;
param_size = SCTP_SIZE32(ntohs(param->param_length));
if (param_size == 8)
- return(1); /*success - default acknowledgement of everything */
+ return (1); /*success - default acknowledgement of everything */
bytes_left = sm->chunk_length;
if (bytes_left < param_size)
- return(0); /* not found */
+ return (0); /* not found */
/* step through Asconf parameters */
while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) {
if (ntohs(param->param_type) == SCTP_SUCCESS_REPORT)
- return(1); /* success - but can't match correlation IDs - should only be one */
+ return (1); /* success - but can't match correlation IDs - should only be one */
/* check others just in case */
bytes_left -= param_size;
if (bytes_left >= SN_MIN_PARAM_SIZE) {
param = SN_SCTP_NEXTPARAM(param);
} else {
- return(0);
+ return (0);
}
param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (bytes_left < param_size) return(0);
+ if (bytes_left < param_size) return (0);
if (++param_count > sysctl_param_proc_limit) {
SN_LOG(SN_LOG_EVENT,
- logsctperror("Parameter parse limit exceeded (IsASCONFack)",
+ logsctperror("Parameter parse limit exceeded (IsASCONFack)",
sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- return(0); /* not found limit exceeded*/
+ return (0); /* not found limit exceeded*/
}
}
- return(0); /* not success */
+ return (0); /* not success */
}
/** @ingroup packet_parser
- * @brief Check to see if ASCONF contains an Add IP or Del IP parameter
- *
+ * @brief Check to see if ASCONF contains an Add IP or Del IP parameter
+ *
* IsADDorDEL scans an ASCONF packet to see if it contains an AddIP or DelIP
* parameter
*
* @param la Pointer to the relevant libalias instance
* @param sm Pointer to sctp message information
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
- *
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ *
* @return SCTP_ADD_IP_ADDRESS | SCTP_DEL_IP_ADDRESS | 0 - fail
*/
static int
@@ -1644,31 +1644,31 @@ IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction)
bytes_left = sm->chunk_length;
if (bytes_left < param_size)
- return(0); /* not found */
+ return (0); /* not found */
/* step through Asconf parameters */
while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) {
if (ntohs(param->param_type) == SCTP_ADD_IP_ADDRESS)
- return(SCTP_ADD_IP_ADDRESS);
- else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS)
- return(SCTP_DEL_IP_ADDRESS);
+ return (SCTP_ADD_IP_ADDRESS);
+ else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS)
+ return (SCTP_DEL_IP_ADDRESS);
/* check others just in case */
bytes_left -= param_size;
if (bytes_left >= SN_MIN_PARAM_SIZE) {
param = SN_SCTP_NEXTPARAM(param);
} else {
- return(0); /*Neither found */
+ return (0); /*Neither found */
}
param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (bytes_left < param_size) return(0);
+ if (bytes_left < param_size) return (0);
if (++param_count > sysctl_param_proc_limit) {
SN_LOG(SN_LOG_EVENT,
- logsctperror("Parameter parse limit exceeded IsADDorDEL)",
+ logsctperror("Parameter parse limit exceeded IsADDorDEL)",
sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- return(0); /* not found limit exceeded*/
+ return (0); /* not found limit exceeded*/
}
}
- return(0); /*Neither found */
+ return (0); /*Neither found */
}
/* ----------------------------------------------------------------------
@@ -1691,7 +1691,7 @@ IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction)
* each state.
*
* @param la Pointer to the relevant libalias instance
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
* @param sm Pointer to sctp message information
* @param assoc Pointer to the association this SCTP Message belongs to
*
@@ -1708,17 +1708,17 @@ ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, stru
if (rtnval != SN_NAT_PKT) {
assoc->state = SN_RM;/* Mark for removal*/
}
- return(rtnval);
+ return (rtnval);
case SN_INi: /* Initialising - Init */
- return(INi_process(la, direction, assoc, sm));
+ return (INi_process(la, direction, assoc, sm));
case SN_INa: /* Initialising - AddIP */
- return(INa_process(la, direction, assoc, sm));
+ return (INa_process(la, direction, assoc, sm));
case SN_UP: /* Association UP */
- return(UP_process(la, direction, assoc, sm));
+ return (UP_process(la, direction, assoc, sm));
case SN_CL: /* Association Closing */
- return(CL_process(la, direction, assoc, sm));
+ return (CL_process(la, direction, assoc, sm));
}
- return(SN_PROCESSING_ERROR);
+ return (SN_PROCESSING_ERROR);
}
/** @ingroup state_machine
@@ -1738,56 +1738,57 @@ ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, stru
static int
ID_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
+ switch (sm->msg) {
case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk with ADDIP */
if (!sysctl_accept_global_ootb_addip && (direction == SN_TO_LOCAL))
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
/* if this Asconf packet does not contain the Vtag parameters it is of no use in Idle state */
if (!GetAsconfVtags(la, sm, &(assoc->l_vtag), &(assoc->g_vtag), direction))
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
+ /* FALLTHROUGH */
case SN_SCTP_INIT: /* a packet containing an INIT chunk or an ASCONF AddIP */
if (sysctl_track_global_addresses)
AddGlobalIPAddresses(sm, assoc, direction);
- switch(direction){
+ switch (direction) {
case SN_TO_GLOBAL:
assoc->l_addr = sm->ip_hdr->ip_src;
assoc->a_addr = FindAliasAddress(la, assoc->l_addr);
assoc->l_port = sm->sctp_hdr->src_port;
assoc->g_port = sm->sctp_hdr->dest_port;
- if(sm->msg == SN_SCTP_INIT)
+ if (sm->msg == SN_SCTP_INIT)
assoc->g_vtag = sm->sctpchnk.Init->initiate_tag;
if (AddSctpAssocGlobal(la, assoc)) /* DB clash *///**** need to add dst address
- return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
- if(sm->msg == SN_SCTP_ASCONF) {
+ return ((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
+ if (sm->msg == SN_SCTP_ASCONF) {
if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_dst)) /* DB clash */
- return(SN_REPLY_ERROR);
+ return (SN_REPLY_ERROR);
assoc->TableRegister |= SN_WAIT_TOLOCAL; /* wait for tolocal ack */
}
break;
case SN_TO_LOCAL:
assoc->l_addr = FindSctpRedirectAddress(la, sm);
- assoc->a_addr = sm->ip_hdr->ip_dst;
+ assoc->a_addr = sm->ip_hdr->ip_dst;
assoc->l_port = sm->sctp_hdr->dest_port;
assoc->g_port = sm->sctp_hdr->src_port;
- if(sm->msg == SN_SCTP_INIT)
+ if (sm->msg == SN_SCTP_INIT)
assoc->l_vtag = sm->sctpchnk.Init->initiate_tag;
if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) /* DB clash */
- return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
- if(sm->msg == SN_SCTP_ASCONF) {
+ return ((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
+ if (sm->msg == SN_SCTP_ASCONF) {
if (AddSctpAssocGlobal(la, assoc)) /* DB clash */ //**** need to add src address
- return(SN_REPLY_ERROR);
+ return (SN_REPLY_ERROR);
assoc->TableRegister |= SN_WAIT_TOGLOBAL; /* wait for toglobal ack */
}
break;
}
- assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa;
- assoc->exp = SN_I_T(la);
- sctp_AddTimeOut(la,assoc);
- return(SN_NAT_PKT);
+ assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa;
+ assoc->exp = SN_I_T(la);
+ sctp_AddTimeOut(la,assoc);
+ return (SN_NAT_PKT);
default: /* Any other type of SCTP message is not valid in Idle */
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
}
-return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
@@ -1795,30 +1796,30 @@ return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the b
*
* Only an INIT-ACK, resent INIT, or an ABORT SCTP packet are valid in this
* state, all other packets are dropped.
- *
+ *
* @param la Pointer to the relevant libalias instance
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
* @param sm Pointer to sctp message information
* @param assoc Pointer to the association this SCTP Message belongs to
- *
- * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT
+ *
+ * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT
*/
static int
INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
+ switch (sm->msg) {
case SN_SCTP_INIT: /* a packet containing a retransmitted INIT chunk */
sctp_ResetTimeOut(la, assoc, SN_I_T(la));
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
case SN_SCTP_INITACK: /* a packet containing an INIT-ACK chunk */
- switch(direction){
+ switch (direction) {
case SN_TO_LOCAL:
if (assoc->num_Gaddr) /*If tracking global addresses for this association */
AddGlobalIPAddresses(sm, assoc, direction);
assoc->l_vtag = sm->sctpchnk.Init->initiate_tag;
if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) { /* DB clash */
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_SEND_ABORT);
+ return (SN_SEND_ABORT);
}
break;
case SN_TO_GLOBAL:
@@ -1826,97 +1827,97 @@ INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, st
assoc->g_vtag = sm->sctpchnk.Init->initiate_tag;
if (AddSctpAssocGlobal(la, assoc)) { /* DB clash */
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_SEND_ABORT);
+ return (SN_SEND_ABORT);
}
break;
}
assoc->state = SN_UP;/* association established for NAT */
sctp_ResetTimeOut(la,assoc, SN_U_T(la));
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
default:
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
}
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
* @brief Process SCTP message while waiting for an AddIp-ACK message
- *
+ *
* Only an AddIP-ACK, resent AddIP, or an ABORT message are valid, all other
* SCTP packets are dropped
*
* @param la Pointer to the relevant libalias instance
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
* @param sm Pointer to sctp message information
* @param assoc Pointer to the association this SCTP Message belongs to
- *
- * @return SN_NAT_PKT | SN_DROP_PKT
+ *
+ * @return SN_NAT_PKT | SN_DROP_PKT
*/
static int
INa_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
+ switch (sm->msg) {
case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/
sctp_ResetTimeOut(la,assoc, SN_I_T(la));
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
case SN_SCTP_ASCONFACK: /* a packet containing an ASCONF chunk with a ADDIP-ACK */
- switch(direction){
+ switch (direction) {
case SN_TO_LOCAL:
if (!(assoc->TableRegister & SN_WAIT_TOLOCAL)) /* wrong direction */
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
break;
case SN_TO_GLOBAL:
if (!(assoc->TableRegister & SN_WAIT_TOGLOBAL)) /* wrong direction */
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
}
if (IsASCONFack(la,sm,direction)) {
assoc->TableRegister &= SN_BOTH_TBL; /* remove wait flags */
assoc->state = SN_UP; /* association established for NAT */
sctp_ResetTimeOut(la,assoc, SN_U_T(la));
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
} else {
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
}
case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
default:
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
}
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
* @brief Process SCTP messages while association is UP redirecting packets
- *
+ *
* While in the SN_UP state, all packets for the particular association
* are passed. Only a SHUT-ACK or an ABORT will cause a change of state.
*
* @param la Pointer to the relevant libalias instance
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
* @param sm Pointer to sctp message information
* @param assoc Pointer to the association this SCTP Message belongs to
- *
- * @return SN_NAT_PKT | SN_DROP_PKT
+ *
+ * @return SN_NAT_PKT | SN_DROP_PKT
*/
static int
UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
+ switch (sm->msg) {
case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */
assoc->state = SN_CL;
sctp_ResetTimeOut(la,assoc, SN_C_T(la));
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/
if ((direction == SN_TO_LOCAL) && assoc->num_Gaddr) /*If tracking global addresses for this association & from global side */
- switch(IsADDorDEL(la,sm,direction)) {
+ switch (IsADDorDEL(la,sm,direction)) {
case SCTP_ADD_IP_ADDRESS:
AddGlobalIPAddresses(sm, assoc, direction);
break;
@@ -1926,9 +1927,9 @@ UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, str
} /* fall through to default */
default:
sctp_ResetTimeOut(la,assoc, SN_U_T(la));
- return(SN_NAT_PKT); /* forward packet */
+ return (SN_NAT_PKT); /* forward packet */
}
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
@@ -1940,34 +1941,34 @@ UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, str
* ABORT packets are permitted in this state. All other packets are dropped.
*
* @param la Pointer to the relevant libalias instance
- * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
+ * @param direction SN_TO_LOCAL | SN_TO_GLOBAL
* @param sm Pointer to sctp message information
* @param assoc Pointer to the association this SCTP Message belongs to
- *
- * @return SN_NAT_PKT | SN_DROP_PKT
+ *
+ * @return SN_NAT_PKT | SN_DROP_PKT
*/
static int
CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
+ switch (sm->msg) {
case SN_SCTP_SHUTCOMP: /* a packet containing a SHUTDOWN-COMPLETE chunk */
assoc->state = SN_CL; /* Stay in Close state until timeout */
if (sysctl_holddown_timer > 0)
sctp_ResetTimeOut(la, assoc, SN_X_T(la));/* allow to stay open for Tbit packets*/
else
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */
assoc->state = SN_CL; /* Stay in Close state until timeout */
sctp_ResetTimeOut(la, assoc, SN_C_T(la));
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
+ return (SN_NAT_PKT);
default:
- return(SN_DROP_PKT);
+ return (SN_DROP_PKT);
}
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/* ----------------------------------------------------------------------
@@ -1981,7 +1982,7 @@ CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, stru
*/
/** @ingroup Hash
* @brief Find the SCTP association given the local address, port and vtag
- *
+ *
* Searches the local look-up table for the association entry matching the
* provided local <address:ports:vtag> tuple
*
@@ -1991,7 +1992,7 @@ CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, stru
* @param l_vtag local Vtag
* @param l_port local Port
* @param g_port global Port
- *
+ *
* @return pointer to association or NULL
*/
static struct sctp_nat_assoc*
@@ -2000,7 +2001,7 @@ FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr,
u_int i;
struct sctp_nat_assoc *assoc = NULL;
struct sctp_GlobalAddress *G_Addr = NULL;
-
+
if (l_vtag != 0) { /* an init packet, vtag==0 */
i = SN_TABLE_HASH(l_vtag, l_port, la->sctpNatTableSize);
LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
@@ -2008,27 +2009,27 @@ FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr,
&& (assoc->l_addr.s_addr == l_addr.s_addr)) {
if (assoc->num_Gaddr) {
LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == g_addr.s_addr)
- return(assoc);
+ if (G_Addr->g_addr.s_addr == g_addr.s_addr)
+ return (assoc);
}
} else {
- return(assoc);
+ return (assoc);
}
}
}
}
- return(NULL);
+ return (NULL);
}
/** @ingroup Hash
* @brief Check for Global Clash
- *
+ *
* Searches the global look-up table for the association entry matching the
* provided global <(addresses):ports:vtag> tuple
*
* @param la Pointer to the relevant libalias instance
* @param Cassoc association being checked for a clash
- *
+ *
* @return pointer to association or NULL
*/
static struct sctp_nat_assoc*
@@ -2038,7 +2039,7 @@ FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc)
struct sctp_nat_assoc *assoc = NULL;
struct sctp_GlobalAddress *G_Addr = NULL;
struct sctp_GlobalAddress *G_AddrC = NULL;
-
+
if (Cassoc->g_vtag != 0) { /* an init packet, vtag==0 */
i = SN_TABLE_HASH(Cassoc->g_vtag, Cassoc->g_port, la->sctpNatTableSize);
LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
@@ -2046,22 +2047,22 @@ FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc)
if (assoc->num_Gaddr) {
LIST_FOREACH(G_AddrC, &(Cassoc->Gaddr), list_Gaddr) {
LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr)
- return(assoc);
+ if (G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr)
+ return (assoc);
}
}
} else {
- return(assoc);
+ return (assoc);
}
}
}
}
- return(NULL);
+ return (NULL);
}
/** @ingroup Hash
* @brief Find the SCTP association given the global port and vtag
- *
+ *
* Searches the global look-up table for the association entry matching the
* provided global <address:ports:vtag> tuple
*
@@ -2075,7 +2076,7 @@ FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc)
* @param g_vtag global vtag
* @param g_port global port
* @param l_port local port
- *
+ *
* @return pointer to association or NULL
*/
static struct sctp_nat_assoc*
@@ -2084,7 +2085,7 @@ FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint
u_int i;
struct sctp_nat_assoc *assoc = NULL;
struct sctp_GlobalAddress *G_Addr = NULL;
-
+
*partial_match = 0;
if (g_vtag != 0) { /* an init packet, vtag==0 */
i = SN_TABLE_HASH(g_vtag, g_port, la->sctpNatTableSize);
@@ -2093,21 +2094,21 @@ FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint
*partial_match = 1;
if (assoc->num_Gaddr) {
LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == g_addr.s_addr)
- return(assoc);
+ if (G_Addr->g_addr.s_addr == g_addr.s_addr)
+ return (assoc);
}
} else {
- return(assoc);
+ return (assoc);
}
}
}
}
- return(NULL);
+ return (NULL);
}
/** @ingroup Hash
* @brief Find the SCTP association for a T-Flag message (given the global port and local vtag)
- *
+ *
* Searches the local look-up table for a unique association entry matching the
* provided global port and local vtag information
*
@@ -2116,40 +2117,40 @@ FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint
* @param l_vtag local Vtag
* @param g_port global Port
* @param l_port local Port
- *
+ *
* @return pointer to association or NULL
*/
static struct sctp_nat_assoc*
-FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port)
+FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port)
{
u_int i;
struct sctp_nat_assoc *assoc = NULL, *lastmatch = NULL;
struct sctp_GlobalAddress *G_Addr = NULL;
int cnt = 0;
-
+
if (l_vtag != 0) { /* an init packet, vtag==0 */
i = SN_TABLE_HASH(l_vtag, g_port, la->sctpNatTableSize);
LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
if ((assoc->g_vtag == l_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) {
if (assoc->num_Gaddr) {
LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == G_Addr->g_addr.s_addr)
- return(assoc); /* full match */
+ if (G_Addr->g_addr.s_addr == g_addr.s_addr)
+ return (assoc); /* full match */
}
} else {
- if (++cnt > 1) return(NULL);
+ if (++cnt > 1) return (NULL);
lastmatch = assoc;
}
}
}
}
/* If there is more than one match we do not know which local address to send to */
- return( cnt ? lastmatch : NULL );
+ return (cnt ? lastmatch : NULL);
}
/** @ingroup Hash
* @brief Find the SCTP association for a T-Flag message (given the local port and global vtag)
- *
+ *
* Searches the global look-up table for a unique association entry matching the
* provided local port and global vtag information
*
@@ -2158,7 +2159,7 @@ FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uin
* @param g_vtag global vtag
* @param l_port local port
* @param g_port global port
- *
+ *
* @return pointer to association or NULL
*/
static struct sctp_nat_assoc*
@@ -2167,28 +2168,28 @@ FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uin
u_int i;
struct sctp_nat_assoc *assoc = NULL;
struct sctp_GlobalAddress *G_Addr = NULL;
-
+
if (g_vtag != 0) { /* an init packet, vtag==0 */
i = SN_TABLE_HASH(g_vtag, l_port, la->sctpNatTableSize);
LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
if ((assoc->l_vtag == g_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)) {
if (assoc->num_Gaddr) {
LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == g_addr.s_addr)
- return(assoc);
+ if (G_Addr->g_addr.s_addr == g_addr.s_addr)
+ return (assoc);
}
} else {
- return(assoc);
+ return (assoc);
}
}
}
}
- return(NULL);
+ return (NULL);
}
/** @ingroup Hash
* @brief Add the sctp association information to the local look up table
- *
+ *
* Searches the local look-up table for an existing association with the same
* details. If a match exists and is ONLY in the local look-up table then this
* is a repeated INIT packet, we need to remove this association from the
@@ -2199,7 +2200,7 @@ FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uin
* @param la Pointer to the relevant libalias instance
* @param assoc pointer to sctp association
* @param g_addr global address
- *
+ *
* @return SN_ADD_OK | SN_ADD_CLASH
*/
static int
@@ -2225,9 +2226,9 @@ AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_a
freeGlobalAddressList(found);
sn_free(found);
} else
- return(SN_ADD_CLASH);
+ return (SN_ADD_CLASH);
}
-
+
LIST_INSERT_HEAD(&la->sctpTableLocal[SN_TABLE_HASH(assoc->l_vtag, assoc->l_port, la->sctpNatTableSize)],
assoc, list_L);
assoc->TableRegister |= SN_LOCAL_TBL;
@@ -2241,7 +2242,7 @@ AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_a
SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^"));
}
- return(SN_ADD_OK);
+ return (SN_ADD_OK);
}
/** @ingroup Hash
@@ -2274,9 +2275,9 @@ AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc)
freeGlobalAddressList(found);
sn_free(found);
} else
- return(SN_ADD_CLASH);
+ return (SN_ADD_CLASH);
}
-
+
LIST_INSERT_HEAD(&la->sctpTableGlobal[SN_TABLE_HASH(assoc->g_vtag, assoc->g_port, la->sctpNatTableSize)],
assoc, list_G);
assoc->TableRegister |= SN_GLOBAL_TBL;
@@ -2290,12 +2291,12 @@ AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc)
SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^"));
}
- return(SN_ADD_OK);
+ return (SN_ADD_OK);
}
/** @ingroup Hash
* @brief Remove the sctp association information from the look up table
- *
+ *
* For each of the two (local/global) look-up tables, remove the association
* from that table IF it has been registered in that table.
*
@@ -2327,7 +2328,7 @@ RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc)
la->sctpLinkCount--; //decrement link count
LIST_REMOVE(assoc, list_L);
}
-
+
if (assoc->TableRegister & SN_GLOBAL_TBL) {
assoc->TableRegister ^= SN_GLOBAL_TBL;
la->sctpLinkCount--; //decrement link count
@@ -2339,20 +2340,20 @@ RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc)
SctpShowAliasStats(la);
}
-/**
+/**
* @ingroup Hash
* @brief free the Global Address List memory
- *
+ *
* freeGlobalAddressList deletes all global IP addresses in an associations
* global IP address list.
*
- * @param assoc
+ * @param assoc
*/
static void freeGlobalAddressList(struct sctp_nat_assoc *assoc)
{
struct sctp_GlobalAddress *gaddr1=NULL,*gaddr2=NULL;
/*free global address list*/
- gaddr1 = LIST_FIRST(&(assoc->Gaddr));
+ gaddr1 = LIST_FIRST(&(assoc->Gaddr));
while (gaddr1 != NULL) {
gaddr2 = LIST_NEXT(gaddr1, list_Gaddr);
sn_free(gaddr1);
@@ -2383,8 +2384,8 @@ static void freeGlobalAddressList(struct sctp_nat_assoc *assoc)
* Determine the location in the queue to add the timeout and insert the
* association into the list at that queue position
*
- * @param la
- * @param assoc
+ * @param la
+ * @param assoc
*/
static void
sctp_AddTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc)
@@ -2440,7 +2441,7 @@ sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp)
/** @ingroup Timer
* @brief Check timer Q against current time
- *
+ *
* Loop through each entry in the timer queue since the last time we processed
* the timer queue until now (the current time). For each association in the
* event list, we remove it from that position in the timer queue and check if
@@ -2451,22 +2452,22 @@ sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp)
*
* If the timer hasn't really expired we place the association into its new
* correct position in the timer queue.
- *
+ *
* @param la Pointer to the relevant libalias instance
*/
void
sctp_CheckTimers(struct libalias *la)
{
struct sctp_nat_assoc *assoc;
-
+
LIBALIAS_LOCK_ASSERT(la);
while(la->timeStamp >= la->sctpNatTimer.loc_time) {
- while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) {
+ while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) {
assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]);
//SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q);
LIST_REMOVE(assoc, timer_Q);
if (la->timeStamp >= assoc->exp) { /* state expired */
- SN_LOG(((assoc->state == SN_CL)?(SN_LOG_DEBUG):(SN_LOG_INFO)),
+ SN_LOG(((assoc->state == SN_CL) ? (SN_LOG_DEBUG) : (SN_LOG_INFO)),
logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR));
RmSctpAssoc(la, assoc);
freeGlobalAddressList(assoc);
@@ -2483,7 +2484,7 @@ sctp_CheckTimers(struct libalias *la)
}
/* ----------------------------------------------------------------------
- * LOGGING CODE
+ * LOGGING CODE
* ----------------------------------------------------------------------
*/
/** @addtogroup Logging
@@ -2494,7 +2495,7 @@ sctp_CheckTimers(struct libalias *la)
*/
/** @ingroup Logging
* @brief Log sctp nat errors
- *
+ *
* @param errormsg Error message to be logged
* @param vtag Current Vtag
* @param error Error number
@@ -2504,7 +2505,7 @@ static void
logsctperror(char* errormsg, uint32_t vtag, int error, int direction)
{
char dir;
- switch(direction) {
+ switch (direction) {
case SN_TO_LOCAL:
dir = 'L';
break;
@@ -2520,7 +2521,7 @@ logsctperror(char* errormsg, uint32_t vtag, int error, int direction)
/** @ingroup Logging
* @brief Log what the parser parsed
- *
+ *
* @param direction Direction of packet
* @param sm Pointer to sctp message information
*/
@@ -2528,7 +2529,7 @@ static void
logsctpparse(int direction, struct sctp_nat_msg *sm)
{
char *ploc, *pstate;
- switch(direction) {
+ switch (direction) {
case SN_TO_LOCAL:
ploc = "TO_LOCAL -";
break;
@@ -2538,7 +2539,7 @@ logsctpparse(int direction, struct sctp_nat_msg *sm)
default:
ploc = "";
}
- switch(sm->msg) {
+ switch (sm->msg) {
case SN_SCTP_INIT:
pstate = "Init";
break;
@@ -2572,7 +2573,7 @@ logsctpparse(int direction, struct sctp_nat_msg *sm)
/** @ingroup Logging
* @brief Log an SCTP association's details
- *
+ *
* @param assoc pointer to sctp association
* @param s Character that indicates the state of processing for this packet
*/
@@ -2582,7 +2583,7 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s)
char *sp;
char addrbuf[INET_ADDRSTRLEN];
- switch(assoc->state) {
+ switch (assoc->state) {
case SN_ID:
sp = "ID ";
break;
@@ -2618,15 +2619,15 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s)
}
/** @ingroup Logging
- * @brief Output Global table to log
- *
+ * @brief Output Global table to log
+ *
* @param la Pointer to the relevant libalias instance
*/
static void logSctpGlobal(struct libalias *la)
{
u_int i;
struct sctp_nat_assoc *assoc = NULL;
-
+
SctpAliasLog("G->\n");
for (i=0; i < la->sctpNatTableSize; i++) {
LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
@@ -2636,15 +2637,15 @@ static void logSctpGlobal(struct libalias *la)
}
/** @ingroup Logging
- * @brief Output Local table to log
- *
+ * @brief Output Local table to log
+ *
* @param la Pointer to the relevant libalias instance
*/
static void logSctpLocal(struct libalias *la)
{
u_int i;
struct sctp_nat_assoc *assoc = NULL;
-
+
SctpAliasLog("L->\n");
for (i=0; i < la->sctpNatTableSize; i++) {
LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
@@ -2655,7 +2656,7 @@ static void logSctpLocal(struct libalias *la)
/** @ingroup Logging
* @brief Output timer queue to log
- *
+ *
* @param la Pointer to the relevant libalias instance
*/
static void logTimerQ(struct libalias *la)
@@ -2674,12 +2675,12 @@ static void logTimerQ(struct libalias *la)
}
}
-/** @ingroup Logging
+/** @ingroup Logging
* @brief Sctp NAT logging function
- *
+ *
* This function is based on a similar function in alias_db.c
*
- * @param str/stream logging descriptor
+ * @param str/stream logging descriptor
* @param format printf type string
*/
#ifdef _KERNEL
diff --git a/freebsd/sys/netinet/sctp_constants.h b/freebsd/sys/netinet/sctp_constants.h
index 94378799..018cd282 100644
--- a/freebsd/sys/netinet/sctp_constants.h
+++ b/freebsd/sys/netinet/sctp_constants.h
@@ -400,43 +400,34 @@ __FBSDID("$FreeBSD$");
#define SCTP_HOSTNAME_ADDRESS 0x000b
#define SCTP_SUPPORTED_ADDRTYPE 0x000c
-/* draft-ietf-stewart-tsvwg-strreset-xxx */
+/* RFC 6525 */
#define SCTP_STR_RESET_OUT_REQUEST 0x000d
#define SCTP_STR_RESET_IN_REQUEST 0x000e
#define SCTP_STR_RESET_TSN_REQUEST 0x000f
#define SCTP_STR_RESET_RESPONSE 0x0010
#define SCTP_STR_RESET_ADD_OUT_STREAMS 0x0011
-#define SCTP_STR_RESET_ADD_IN_STREAMS 0x0012
+#define SCTP_STR_RESET_ADD_IN_STREAMS 0x0012
#define SCTP_MAX_RESET_PARAMS 2
-#define SCTP_STREAM_RESET_TSN_DELTA 0x1000
+#define SCTP_STREAM_RESET_TSN_DELTA 0x1000
/*************0x4000 series*************/
/*************0x8000 series*************/
#define SCTP_ECN_CAPABLE 0x8000
-/* draft-ietf-tsvwg-auth-xxx */
+/* RFC 4895 */
#define SCTP_RANDOM 0x8002
#define SCTP_CHUNK_LIST 0x8003
#define SCTP_HMAC_LIST 0x8004
-/*
- * draft-ietf-tsvwg-addip-sctp-xx param=0x8008 len=0xNNNN Byte | Byte | Byte
- * | Byte Byte | Byte ...
- *
- * Where each byte is a chunk type extension supported. For example, to support
- * all chunks one would have (in hex):
- *
- * 80 01 00 09 C0 C1 80 81 82 00 00 00
- *
- * Has the parameter. C0 = PR-SCTP (RFC3758) C1, 80 = ASCONF (addip draft) 81
- * = Packet Drop 82 = Stream Reset 83 = Authentication
- */
-#define SCTP_SUPPORTED_CHUNK_EXT 0x8008
+/* RFC 4820 */
+#define SCTP_PAD 0x8005
+/* RFC 5061 */
+#define SCTP_SUPPORTED_CHUNK_EXT 0x8008
/*************0xC000 series*************/
#define SCTP_PRSCTP_SUPPORTED 0xc000
-/* draft-ietf-tsvwg-addip-sctp */
+/* RFC 5061 */
#define SCTP_ADD_IP_ADDRESS 0xc001
#define SCTP_DEL_IP_ADDRESS 0xc002
#define SCTP_ERROR_CAUSE_IND 0xc003
@@ -444,8 +435,8 @@ __FBSDID("$FreeBSD$");
#define SCTP_SUCCESS_REPORT 0xc005
#define SCTP_ULP_ADAPTATION 0xc006
/* behave-nat-draft */
-#define SCTP_HAS_NAT_SUPPORT 0xc007
-#define SCTP_NAT_VTAGS 0xc008
+#define SCTP_HAS_NAT_SUPPORT 0xc007
+#define SCTP_NAT_VTAGS 0xc008
/* bits for TOS field */
#define SCTP_ECT0_BIT 0x02
@@ -624,7 +615,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_RTO_INITIAL (3000) /* 3 sec in ms */
-#define SCTP_INP_KILL_TIMEOUT 20/* number of ms to retry kill of inpcb */
+#define SCTP_INP_KILL_TIMEOUT 20 /* number of ms to retry kill of inpcb */
#define SCTP_ASOC_KILL_TIMEOUT 10 /* number of ms to retry kill of inpcb */
#define SCTP_DEF_MAX_INIT 8
diff --git a/freebsd/sys/netinet/sctp_crc32.c b/freebsd/sys/netinet/sctp_crc32.c
index 82e361e1..e22abeb6 100644
--- a/freebsd/sys/netinet/sctp_crc32.c
+++ b/freebsd/sys/netinet/sctp_crc32.c
@@ -37,30 +37,36 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <rtems/bsd/local/opt_sctp.h>
+
+#ifdef SCTP
#include <netinet/sctp_os.h>
#include <netinet/sctp.h>
#include <netinet/sctp_crc32.h>
#include <netinet/sctp_pcb.h>
+#else
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
-
-#if !defined(SCTP_WITH_NO_CSUM)
+#include <netinet/sctp_crc32.h>
+#endif
static uint32_t
sctp_finalize_crc32c(uint32_t crc32c)
{
uint32_t result;
-
#if BYTE_ORDER == BIG_ENDIAN
uint8_t byte0, byte1, byte2, byte3;
-
#endif
+
/* Complement the result */
result = ~crc32c;
#if BYTE_ORDER == BIG_ENDIAN
/*
- * For BIG-ENDIAN.. aka Motorola byte order the result is in
- * little-endian form. So we must manually swap the bytes. Then we
- * can call htonl() which does nothing...
+ * For BIG-ENDIAN platforms the result is in little-endian form. So
+ * we must swap the bytes to return the result in network byte
+ * order.
*/
byte0 = result & 0x000000ff;
byte1 = (result >> 8) & 0x000000ff;
@@ -69,65 +75,57 @@ sctp_finalize_crc32c(uint32_t crc32c)
crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
#else
/*
- * For INTEL platforms the result comes out in network order. No
- * htonl is required or the swap above. So we optimize out both the
- * htonl and the manual swap above.
+ * For LITTLE ENDIAN platforms the result is in already in network
+ * byte order.
*/
crc32c = result;
#endif
return (crc32c);
}
+/*
+ * Compute the SCTP checksum in network byte order for a given mbuf chain m
+ * which contains an SCTP packet starting at offset.
+ * Since this function is also called by ipfw, don't assume that
+ * it is compiled on a kernel with SCTP support.
+ */
uint32_t
sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
{
- /*
- * given a mbuf chain with a packetheader offset by 'offset'
- * pointing at a sctphdr (with csum set to 0) go through the chain
- * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
- * has a side bonus as it will calculate the total length of the
- * mbuf chain. Note: if offset is greater than the total mbuf
- * length, checksum=1, pktlen=0 is returned (ie. no real error code)
- */
uint32_t base = 0xffffffff;
- struct mbuf *at;
- at = m;
- /* find the correct mbuf and offset into mbuf */
- while ((at != NULL) && (offset > (uint32_t)SCTP_BUF_LEN(at))) {
- offset -= SCTP_BUF_LEN(at); /* update remaining offset
- * left */
- at = SCTP_BUF_NEXT(at);
- }
- while (at != NULL) {
- if ((SCTP_BUF_LEN(at) - offset) > 0) {
- base = calculate_crc32c(base,
- (unsigned char *)(SCTP_BUF_AT(at, offset)),
- (unsigned int)(SCTP_BUF_LEN(at) - offset));
- }
- if (offset) {
- /* we only offset once into the first mbuf */
- if (offset < (uint32_t)SCTP_BUF_LEN(at))
- offset = 0;
- else
- offset -= SCTP_BUF_LEN(at);
+ while (offset > 0) {
+ KASSERT(m != NULL, ("sctp_calculate_cksum, offset > length of mbuf chain"));
+ if (offset < (uint32_t)m->m_len) {
+ break;
}
- at = SCTP_BUF_NEXT(at);
+ offset -= m->m_len;
+ m = m->m_next;
+ }
+ if (offset > 0) {
+ base = calculate_crc32c(base,
+ (unsigned char *)(m->m_data + offset),
+ (unsigned int)(m->m_len - offset));
+ m = m->m_next;
+ }
+ while (m != NULL) {
+ base = calculate_crc32c(base,
+ (unsigned char *)m->m_data,
+ (unsigned int)m->m_len);
+ m = m->m_next;
}
base = sctp_finalize_crc32c(base);
return (base);
}
-#endif /* !defined(SCTP_WITH_NO_CSUM) */
-
+#ifdef SCTP
+/*
+ * Compute and insert the SCTP checksum in network byte order for a given
+ * mbuf chain m which contains an SCTP packet starting at offset.
+ */
void
sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
{
-#if defined(SCTP_WITH_NO_CSUM)
-#ifdef INVARIANTS
- panic("sctp_delayed_cksum() called when using no SCTP CRC.");
-#endif
-#else
uint32_t checksum;
checksum = sctp_calculate_cksum(m, offset);
@@ -136,15 +134,15 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
offset += offsetof(struct sctphdr, checksum);
if (offset + sizeof(uint32_t) > (uint32_t)(m->m_len)) {
- SCTP_PRINTF("sctp_delayed_cksum(): m->len: %d, off: %d.\n",
- (uint32_t)m->m_len, offset);
- /*
- * XXX this shouldn't happen, but if it does, the correct
- * behavior may be to insert the checksum in the appropriate
- * next mbuf in the chain.
- */
+#ifdef INVARIANTS
+ panic("sctp_delayed_cksum(): m->m_len: %d, offset: %u.",
+ m->m_len, offset);
+#else
+ SCTP_PRINTF("sctp_delayed_cksum(): m->m_len: %d, offset: %u.\n",
+ m->m_len, offset);
+#endif
return;
}
*(uint32_t *)(m->m_data + offset) = checksum;
-#endif
}
+#endif
diff --git a/freebsd/sys/netinet/sctp_crc32.h b/freebsd/sys/netinet/sctp_crc32.h
index adc38afc..4bdf8265 100644
--- a/freebsd/sys/netinet/sctp_crc32.h
+++ b/freebsd/sys/netinet/sctp_crc32.h
@@ -39,9 +39,9 @@ __FBSDID("$FreeBSD$");
#define _NETINET_SCTP_CRC32_H_
#if defined(_KERNEL)
-#if !defined(SCTP_WITH_NO_CSUM)
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
-#endif
+#ifdef SCTP
void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
+#endif
#endif /* _KERNEL */
#endif /* __crc32c_h__ */
diff --git a/freebsd/sys/netinet/sctp_indata.c b/freebsd/sys/netinet/sctp_indata.c
index c4522a39..3325dd03 100644
--- a/freebsd/sys/netinet/sctp_indata.c
+++ b/freebsd/sys/netinet/sctp_indata.c
@@ -3366,7 +3366,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
}
}
- if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap)) {
+ if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap) &&
+ !(accum_moved && asoc->fast_retran_loss_recovery)) {
/* we are beyond the tsn in the sack */
break;
}
@@ -3390,8 +3391,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
* FR using this SACK.
*/
continue;
- } else if (tp1->whoTo && SCTP_TSN_GT(tp1->rec.data.tsn,
- tp1->whoTo->this_sack_highest_newack)) {
+ } else if (tp1->whoTo &&
+ SCTP_TSN_GT(tp1->rec.data.tsn,
+ tp1->whoTo->this_sack_highest_newack) &&
+ !(accum_moved && asoc->fast_retran_loss_recovery)) {
/*
* CMT: New acks were receieved for data sent to
* this dest. But no new acks were seen for data
@@ -3676,7 +3679,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
tp1->whoTo->find_pseudo_cumack = 1;
tp1->whoTo->find_rtx_pseudo_cumack = 1;
}
- } else {/* CMT is OFF */
+ } else { /* CMT is OFF */
#ifdef SCTP_FR_TO_ALTERNATE
/* Can we find an alternate? */
@@ -4605,6 +4608,13 @@ hopeless_peer:
if (stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) {
(*stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) (stcb, net);
}
+ /*
+ * CMT: SFR algo (and HTNA) - this_sack_highest_newack has
+ * to be greater than the cumack. Also reset saw_newack to 0
+ * for all dests.
+ */
+ net->saw_newack = 0;
+ net->this_sack_highest_newack = last_tsn;
}
/* process the new consecutive TSN first */
TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
@@ -4732,16 +4742,6 @@ hopeless_peer:
if ((num_seg > 0) || (num_nr_seg > 0)) {
/*
- * CMT: SFR algo (and HTNA) - this_sack_highest_newack has
- * to be greater than the cumack. Also reset saw_newack to 0
- * for all dests.
- */
- TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
- net->saw_newack = 0;
- net->this_sack_highest_newack = last_tsn;
- }
-
- /*
* thisSackHighestGap will increase while handling NEW
* segments this_sack_highest_newack will increase while
* handling NEWLY ACKED chunks. this_sack_lowest_newack is
diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c
index 9c552ff5..9a74ef4b 100644
--- a/freebsd/sys/netinet/sctp_input.c
+++ b/freebsd/sys/netinet/sctp_input.c
@@ -3209,9 +3209,9 @@ sctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb, struct sct
stcb->asoc.ecn_echo_cnt_onq--;
TAILQ_REMOVE(&stcb->asoc.control_send_queue, chk,
sctp_next);
+ stcb->asoc.ctrl_queue_cnt--;
sctp_m_freem(chk->data);
chk->data = NULL;
- stcb->asoc.ctrl_queue_cnt--;
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
if (override == 0) {
break;
@@ -3643,26 +3643,23 @@ static void
sctp_clean_up_stream_reset(struct sctp_tcb *stcb)
{
struct sctp_association *asoc;
- struct sctp_tmit_chunk *chk = stcb->asoc.str_reset;
+ struct sctp_tmit_chunk *chk;
- if (stcb->asoc.str_reset == NULL) {
+ asoc = &stcb->asoc;
+ chk = asoc->str_reset;
+ if (chk == NULL) {
return;
}
- asoc = &stcb->asoc;
-
+ asoc->str_reset = NULL;
sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb,
chk->whoTo, SCTP_FROM_SCTP_INPUT + SCTP_LOC_28);
- TAILQ_REMOVE(&asoc->control_send_queue,
- chk,
- sctp_next);
+ TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
+ asoc->ctrl_queue_cnt--;
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
}
- asoc->ctrl_queue_cnt--;
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
- /* sa_ignore NO_NULL_CHK */
- stcb->asoc.str_reset = NULL;
}
@@ -5509,9 +5506,7 @@ void
sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_chunkhdr *ch,
-#if !defined(SCTP_WITH_NO_CSUM)
uint8_t compute_crc,
-#endif
uint8_t ecn_bits,
uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
@@ -5531,7 +5526,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
sctp_audit_log(0xE0, 1);
sctp_auditing(0, inp, stcb, net);
#endif
-#if !defined(SCTP_WITH_NO_CSUM)
if (compute_crc != 0) {
uint32_t check, calc_check;
@@ -5576,7 +5570,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
goto out;
}
}
-#endif
/* Destination port of 0 is illegal, based on RFC4960. */
if (sh->dest_port == 0) {
SCTP_STAT_INCR(sctps_hdrops);
@@ -5894,9 +5887,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
struct sctphdr *sh;
struct sctp_chunkhdr *ch;
int length, offset;
-#if !defined(SCTP_WITH_NO_CSUM)
uint8_t compute_crc;
-#endif
uint32_t mflowid;
uint8_t mflowtype;
uint16_t fibnum;
@@ -5966,9 +5957,6 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
goto out;
}
ecn_bits = ip->ip_tos;
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_recvnocrc);
-#else
if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
SCTP_STAT_INCR(sctps_recvhwcrc);
compute_crc = 0;
@@ -5976,14 +5964,11 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
SCTP_STAT_INCR(sctps_recvswcrc);
compute_crc = 1;
}
-#endif
sctp_common_input_processing(&m, iphlen, offset, length,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch,
-#if !defined(SCTP_WITH_NO_CSUM)
compute_crc,
-#endif
ecn_bits,
mflowtype, mflowid, fibnum,
vrf_id, port);
diff --git a/freebsd/sys/netinet/sctp_input.h b/freebsd/sys/netinet/sctp_input.h
index ff0916e7..f393ad89 100644
--- a/freebsd/sys/netinet/sctp_input.h
+++ b/freebsd/sys/netinet/sctp_input.h
@@ -43,9 +43,7 @@ void
sctp_common_input_processing(struct mbuf **, int, int, int,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_chunkhdr *,
-#if !defined(SCTP_WITH_NO_CSUM)
uint8_t,
-#endif
uint8_t,
uint8_t, uint32_t, uint16_t,
uint32_t, uint16_t);
diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c
index bc54ee96..9dd2e0fa 100644
--- a/freebsd/sys/netinet/sctp_output.c
+++ b/freebsd/sys/netinet/sctp_output.c
@@ -4228,23 +4228,15 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
}
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
if (port) {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr));
SCTP_STAT_INCR(sctps_sendswcrc);
-#endif
if (V_udp_cksum) {
SCTP_ENABLE_UDP_CSUM(o_pak);
}
} else {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
m->m_pkthdr.csum_flags = CSUM_SCTP;
m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
SCTP_STAT_INCR(sctps_sendhwcrc);
-#endif
}
#ifdef SCTP_PACKET_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
@@ -4568,23 +4560,15 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
}
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
if (port) {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
SCTP_STAT_INCR(sctps_sendswcrc);
-#endif
if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) {
udp->uh_sum = 0xffff;
}
} else {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
SCTP_STAT_INCR(sctps_sendhwcrc);
-#endif
}
/* send it out. table id is taken from stcb */
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -6916,11 +6900,11 @@ sctp_toss_old_cookies(struct sctp_tcb *stcb, struct sctp_association *asoc)
TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
+ asoc->ctrl_queue_cnt--;
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
}
- asoc->ctrl_queue_cnt--;
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
}
}
@@ -6945,11 +6929,11 @@ sctp_toss_old_asconf(struct sctp_tcb *stcb)
}
}
TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
+ asoc->ctrl_queue_cnt--;
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
}
- asoc->ctrl_queue_cnt--;
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
}
}
@@ -7073,13 +7057,14 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_l
/* Stray chunks must be cleaned up */
clean_up_anyway:
TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
+ asoc->ctrl_queue_cnt--;
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
}
- asoc->ctrl_queue_cnt--;
- if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN)
+ if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) {
asoc->fwd_tsn_cnt--;
+ }
sctp_free_a_chunk(stcb, chk, so_locked);
} else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) {
/* special handling, we must look into the param */
@@ -11229,23 +11214,15 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
}
ip->ip_len = htons(len);
if (port) {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip) + sizeof(struct udphdr));
SCTP_STAT_INCR(sctps_sendswcrc);
-#endif
if (V_udp_cksum) {
SCTP_ENABLE_UDP_CSUM(o_pak);
}
} else {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
mout->m_pkthdr.csum_flags = CSUM_SCTP;
mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
SCTP_STAT_INCR(sctps_sendhwcrc);
-#endif
}
#ifdef SCTP_PACKET_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
@@ -11259,23 +11236,15 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
case AF_INET6:
ip6->ip6_plen = (uint16_t)(len - sizeof(struct ip6_hdr));
if (port) {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
SCTP_STAT_INCR(sctps_sendswcrc);
-#endif
if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
udp->uh_sum = 0xffff;
}
} else {
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
SCTP_STAT_INCR(sctps_sendhwcrc);
-#endif
}
#ifdef SCTP_PACKET_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c
index 8259140f..f1a8d1d5 100644
--- a/freebsd/sys/netinet/sctp_sysctl.c
+++ b/freebsd/sys/netinet/sctp_sysctl.c
@@ -718,7 +718,6 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
sb.sctps_recvauthfailed += sarry->sctps_recvauthfailed;
sb.sctps_recvexpress += sarry->sctps_recvexpress;
sb.sctps_recvexpressm += sarry->sctps_recvexpressm;
- sb.sctps_recvnocrc += sarry->sctps_recvnocrc;
sb.sctps_recvswcrc += sarry->sctps_recvswcrc;
sb.sctps_recvhwcrc += sarry->sctps_recvhwcrc;
sb.sctps_sendpackets += sarry->sctps_sendpackets;
@@ -731,7 +730,6 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
sb.sctps_sendecne += sarry->sctps_sendecne;
sb.sctps_sendauth += sarry->sctps_sendauth;
sb.sctps_senderrors += sarry->sctps_senderrors;
- sb.sctps_sendnocrc += sarry->sctps_sendnocrc;
sb.sctps_sendswcrc += sarry->sctps_sendswcrc;
sb.sctps_sendhwcrc += sarry->sctps_sendhwcrc;
sb.sctps_pdrpfmbox += sarry->sctps_pdrpfmbox;
diff --git a/freebsd/sys/netinet/sctp_uio.h b/freebsd/sys/netinet/sctp_uio.h
index 93274a70..8732219c 100644
--- a/freebsd/sys/netinet/sctp_uio.h
+++ b/freebsd/sys/netinet/sctp_uio.h
@@ -986,7 +986,7 @@ struct sctpstat {
uint32_t sctps_recvexpress; /* total fast path receives all one
* chunk */
uint32_t sctps_recvexpressm; /* total fast path multi-part data */
- uint32_t sctps_recvnocrc;
+ uint32_t sctps_recv_spare; /* formerly sctps_recvnocrc */
uint32_t sctps_recvswcrc;
uint32_t sctps_recvhwcrc;
@@ -1006,7 +1006,7 @@ struct sctpstat {
uint32_t sctps_sendecne;/* total output ECNE chunks */
uint32_t sctps_sendauth;/* total output AUTH chunks FIXME */
uint32_t sctps_senderrors; /* ip_output error counter */
- uint32_t sctps_sendnocrc;
+ uint32_t sctps_send_spare; /* formerly sctps_sendnocrc */
uint32_t sctps_sendswcrc;
uint32_t sctps_sendhwcrc;
/* PCKDROPREP statistics: */
diff --git a/freebsd/sys/netinet/sctputil.c b/freebsd/sys/netinet/sctputil.c
index 98c2a708..5511df64 100644
--- a/freebsd/sys/netinet/sctputil.c
+++ b/freebsd/sys/netinet/sctputil.c
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_output.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_timer.h>
-#include <netinet/sctp_indata.h>/* for sctp_deliver_data() */
+#include <netinet/sctp_indata.h>
#include <netinet/sctp_auth.h>
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_bsd_addr.h>
@@ -6096,7 +6096,7 @@ sctp_m_free(struct mbuf *m)
return (m_free(m));
}
-void
+void
sctp_m_freem(struct mbuf *mb)
{
while (mb != NULL)
@@ -6166,6 +6166,7 @@ sctp_soreceive(struct socket *so,
struct sockaddr *from;
struct sctp_extrcvinfo sinfo;
int filling_sinfo = 1;
+ int flags;
struct sctp_inpcb *inp;
inp = (struct sctp_inpcb *)so->so_pcb;
@@ -6193,15 +6194,24 @@ sctp_soreceive(struct socket *so,
if (filling_sinfo) {
memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo));
}
- error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp,
+ if (flagsp != NULL) {
+ flags = *flagsp;
+ } else {
+ flags = 0;
+ }
+ error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, &flags,
(struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
+ if (flagsp != NULL) {
+ *flagsp = flags;
+ }
if (controlp != NULL) {
/* copy back the sinfo in a CMSG format */
- if (filling_sinfo)
+ if (filling_sinfo && ((flags & MSG_NOTIFICATION) == 0)) {
*controlp = sctp_build_ctl_nchunk(inp,
(struct sctp_sndrcvinfo *)&sinfo);
- else
+ } else {
*controlp = NULL;
+ }
}
if (psa) {
/* copy back the address info */
diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c
index 1cb622ac..d0f08e3a 100644
--- a/freebsd/sys/netinet/tcp_output.c
+++ b/freebsd/sys/netinet/tcp_output.c
@@ -200,7 +200,9 @@ tcp_output(struct tcpcb *tp)
int off, flags, error = 0; /* Keep compiler happy */
struct mbuf *m;
struct ip *ip = NULL;
+#ifdef TCPDEBUG
struct ipovly *ipov = NULL;
+#endif
struct tcphdr *th;
u_char opt[TCP_MAXOLEN];
unsigned ipoptlen, optlen, hdrlen;
@@ -489,59 +491,7 @@ after_sack_rexmit:
/* len will be >= 0 after this point. */
KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__));
- /*
- * Automatic sizing of send socket buffer. Often the send buffer
- * size is not optimally adjusted to the actual network conditions
- * at hand (delay bandwidth product). Setting the buffer size too
- * small limits throughput on links with high bandwidth and high
- * delay (eg. trans-continental/oceanic links). Setting the
- * buffer size too big consumes too much real kernel memory,
- * especially with many connections on busy servers.
- *
- * The criteria to step up the send buffer one notch are:
- * 1. receive window of remote host is larger than send buffer
- * (with a fudge factor of 5/4th);
- * 2. send buffer is filled to 7/8th with data (so we actually
- * have data to make use of it);
- * 3. send buffer fill has not hit maximal automatic size;
- * 4. our send window (slow start and cogestion controlled) is
- * larger than sent but unacknowledged data in send buffer.
- *
- * The remote host receive window scaling factor may limit the
- * growing of the send buffer before it reaches its allowed
- * maximum.
- *
- * It scales directly with slow start or congestion window
- * and does at most one step per received ACK. This fast
- * scaling has the drawback of growing the send buffer beyond
- * what is strictly necessary to make full use of a given
- * delay*bandwidth product. However testing has shown this not
- * to be much of an problem. At worst we are trading wasting
- * of available bandwidth (the non-use of it) for wasting some
- * socket buffer memory.
- *
- * TODO: Shrink send buffer during idle periods together
- * with congestion window. Requires another timer. Has to
- * wait for upcoming tcp timer rewrite.
- *
- * XXXGL: should there be used sbused() or sbavail()?
- */
- if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) {
- int lowat;
-
- lowat = V_tcp_sendbuf_auto_lowat ? so->so_snd.sb_lowat : 0;
- if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat - lowat &&
- sbused(&so->so_snd) >=
- (so->so_snd.sb_hiwat / 8 * 7) - lowat &&
- sbused(&so->so_snd) < V_tcp_autosndbuf_max &&
- sendwin >= (sbused(&so->so_snd) -
- (tp->snd_nxt - tp->snd_una))) {
- if (!sbreserve_locked(&so->so_snd,
- min(so->so_snd.sb_hiwat + V_tcp_autosndbuf_inc,
- V_tcp_autosndbuf_max), so, curthread))
- so->so_snd.sb_flags &= ~SB_AUTOSIZE;
- }
- }
+ tcp_sndbuf_autoscale(tp, so, sendwin);
/*
* Decide if we can use TCP Segmentation Offloading (if supported by
@@ -1145,7 +1095,9 @@ send:
#endif /* INET6 */
{
ip = mtod(m, struct ip *);
+#ifdef TCPDEBUG
ipov = (struct ipovly *)ip;
+#endif
th = (struct tcphdr *)(ip + 1);
tcpip_fillheaders(tp->t_inpcb, ip, th);
}
@@ -1293,12 +1245,13 @@ send:
* NOTE: since TCP options buffer doesn't point into
* mbuf's data, calculate offset and use it.
*/
- if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th,
- (u_char *)(th + 1) + (to.to_signature - opt)) != 0) {
+ if (!TCPMD5_ENABLED() || (error = TCPMD5_OUTPUT(m, th,
+ (u_char *)(th + 1) + (to.to_signature - opt))) != 0) {
/*
* Do not send segment if the calculation of MD5
* digest has failed.
*/
+ m_freem(m);
goto out;
}
}
@@ -1860,3 +1813,62 @@ tcp_addoptions(struct tcpopt *to, u_char *optp)
KASSERT(optlen <= TCP_MAXOLEN, ("%s: TCP options too long", __func__));
return (optlen);
}
+
+void
+tcp_sndbuf_autoscale(struct tcpcb *tp, struct socket *so, uint32_t sendwin)
+{
+
+ /*
+ * Automatic sizing of send socket buffer. Often the send buffer
+ * size is not optimally adjusted to the actual network conditions
+ * at hand (delay bandwidth product). Setting the buffer size too
+ * small limits throughput on links with high bandwidth and high
+ * delay (eg. trans-continental/oceanic links). Setting the
+ * buffer size too big consumes too much real kernel memory,
+ * especially with many connections on busy servers.
+ *
+ * The criteria to step up the send buffer one notch are:
+ * 1. receive window of remote host is larger than send buffer
+ * (with a fudge factor of 5/4th);
+ * 2. send buffer is filled to 7/8th with data (so we actually
+ * have data to make use of it);
+ * 3. send buffer fill has not hit maximal automatic size;
+ * 4. our send window (slow start and cogestion controlled) is
+ * larger than sent but unacknowledged data in send buffer.
+ *
+ * The remote host receive window scaling factor may limit the
+ * growing of the send buffer before it reaches its allowed
+ * maximum.
+ *
+ * It scales directly with slow start or congestion window
+ * and does at most one step per received ACK. This fast
+ * scaling has the drawback of growing the send buffer beyond
+ * what is strictly necessary to make full use of a given
+ * delay*bandwidth product. However testing has shown this not
+ * to be much of an problem. At worst we are trading wasting
+ * of available bandwidth (the non-use of it) for wasting some
+ * socket buffer memory.
+ *
+ * TODO: Shrink send buffer during idle periods together
+ * with congestion window. Requires another timer. Has to
+ * wait for upcoming tcp timer rewrite.
+ *
+ * XXXGL: should there be used sbused() or sbavail()?
+ */
+ if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) {
+ int lowat;
+
+ lowat = V_tcp_sendbuf_auto_lowat ? so->so_snd.sb_lowat : 0;
+ if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat - lowat &&
+ sbused(&so->so_snd) >=
+ (so->so_snd.sb_hiwat / 8 * 7) - lowat &&
+ sbused(&so->so_snd) < V_tcp_autosndbuf_max &&
+ sendwin >= (sbused(&so->so_snd) -
+ (tp->snd_nxt - tp->snd_una))) {
+ if (!sbreserve_locked(&so->so_snd,
+ min(so->so_snd.sb_hiwat + V_tcp_autosndbuf_inc,
+ V_tcp_autosndbuf_max), so, curthread))
+ so->so_snd.sb_flags &= ~SB_AUTOSIZE;
+ }
+ }
+}
diff --git a/freebsd/sys/netinet/tcp_timer.c b/freebsd/sys/netinet/tcp_timer.c
index a2f854d7..539913f4 100644
--- a/freebsd/sys/netinet/tcp_timer.c
+++ b/freebsd/sys/netinet/tcp_timer.c
@@ -120,9 +120,9 @@ SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_slop, CTLTYPE_INT|CTLFLAG_RW,
&tcp_rexmit_slop, 0, sysctl_msec_to_ticks, "I",
"Retransmission Timer Slop");
-static int always_keepalive = 1;
+int tcp_always_keepalive = 1;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_RW,
- &always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections");
+ &tcp_always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections");
int tcp_fast_finwait2_recycle = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, fast_finwait2_recycle, CTLFLAG_RW,
@@ -473,7 +473,8 @@ tcp_timer_keep(void *xtp)
TCPSTAT_INC(tcps_keeptimeo);
if (tp->t_state < TCPS_ESTABLISHED)
goto dropit;
- if ((always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) &&
+ if ((tcp_always_keepalive ||
+ inp->inp_socket->so_options & SO_KEEPALIVE) &&
tp->t_state <= TCPS_CLOSING) {
if (ticks - tp->t_rcvtime >= TP_KEEPIDLE(tp) + TP_MAXIDLE(tp))
goto dropit;
diff --git a/freebsd/sys/netinet/tcp_timer.h b/freebsd/sys/netinet/tcp_timer.h
index 9a26c95d..b0ff3809 100644
--- a/freebsd/sys/netinet/tcp_timer.h
+++ b/freebsd/sys/netinet/tcp_timer.h
@@ -197,6 +197,7 @@ extern int tcp_ttl; /* time to live for TCP segs */
extern int tcp_backoff[];
extern int tcp_syn_backoff[];
+extern int tcp_always_keepalive;
extern int tcp_finwait2_timeout;
extern int tcp_fast_finwait2_recycle;
diff --git a/freebsd/sys/netinet/tcp_var.h b/freebsd/sys/netinet/tcp_var.h
index 0bcb3dc6..35b44410 100644
--- a/freebsd/sys/netinet/tcp_var.h
+++ b/freebsd/sys/netinet/tcp_var.h
@@ -884,6 +884,7 @@ void tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
void tcp_free_sackholes(struct tcpcb *tp);
int tcp_newreno(struct tcpcb *, struct tcphdr *);
int tcp_compute_pipe(struct tcpcb *);
+void tcp_sndbuf_autoscale(struct tcpcb *, struct socket *, uint32_t);
static inline void
tcp_fields_to_host(struct tcphdr *th)
diff --git a/freebsd/sys/netinet6/frag6.c b/freebsd/sys/netinet6/frag6.c
index 1224aeaa..5b405ebb 100644
--- a/freebsd/sys/netinet6/frag6.c
+++ b/freebsd/sys/netinet6/frag6.c
@@ -229,6 +229,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
*offp = offset;
+ m->m_flags |= M_FRAGMENTED;
return (ip6f->ip6f_nxt);
}
@@ -542,6 +543,7 @@ insert:
while (t->m_next)
t = t->m_next;
m_adj(IP6_REASS_MBUF(af6), af6->ip6af_offset);
+ m_demote_pkthdr(IP6_REASS_MBUF(af6));
m_cat(t, IP6_REASS_MBUF(af6));
free(af6, M_FTABLE);
af6 = af6dwn;
@@ -829,5 +831,6 @@ ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
m_cat(m, t);
}
+ m->m_flags |= M_FRAGMENTED;
return (0);
}
diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c
index fb537170..38f14461 100644
--- a/freebsd/sys/netinet6/icmp6.c
+++ b/freebsd/sys/netinet6/icmp6.c
@@ -2266,6 +2266,10 @@ icmp6_redirect_input(struct mbuf *m, int off)
if (!V_icmp6_rediraccept)
goto freeit;
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
#ifndef PULLDOWN_TEST
IP6_EXTHDR_CHECK(m, off, icmp6len,);
nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c
index 2046043d..6fc29892 100644
--- a/freebsd/sys/netinet6/in6.c
+++ b/freebsd/sys/netinet6/in6.c
@@ -1458,7 +1458,7 @@ in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
/*
- * find the internet address corresponding to a given address.
+ * find the interface address corresponding to a given IPv6 address.
* ifaddr is returned referenced.
*/
struct in6_ifaddr *
diff --git a/freebsd/sys/netinet6/in6_ifattach.c b/freebsd/sys/netinet6/in6_ifattach.c
index d89581e4..26a682ad 100644
--- a/freebsd/sys/netinet6/in6_ifattach.c
+++ b/freebsd/sys/netinet6/in6_ifattach.c
@@ -700,7 +700,6 @@ void
in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
{
struct in6_ifaddr *ia;
- struct in6_addr in6;
if (ifp->if_afdata[AF_INET6] == NULL)
return;
@@ -733,18 +732,16 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
/*
* assign loopback address for loopback interface.
- * XXX multiple loopback interface case.
*/
if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
- struct ifaddr *ifa;
-
- in6 = in6addr_loopback;
- ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &in6);
- if (ifa == NULL) {
- if (in6_ifattach_loopback(ifp) != 0)
- return;
- } else
- ifa_free(ifa);
+ /*
+ * check that loopback address doesn't exist yet.
+ */
+ ia = in6ifa_ifwithaddr(&in6addr_loopback, 0);
+ if (ia == NULL)
+ in6_ifattach_loopback(ifp);
+ else
+ ifa_free(&ia->ia_ifa);
}
/*
@@ -752,18 +749,10 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
*/
if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) {
- int error;
-
ia = in6ifa_ifpforlinklocal(ifp, 0);
- if (ia == NULL) {
- error = in6_ifattach_linklocal(ifp, altifp);
-#if 0
- if (error)
- log(LOG_NOTICE, "in6_ifattach_linklocal: "
- "failed to add a link-local addr to %s\n",
- if_name(ifp));
-#endif
- } else
+ if (ia == NULL)
+ in6_ifattach_linklocal(ifp, altifp);
+ else
ifa_free(&ia->ia_ifa);
}
diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c
index 4119d1d9..a634b18b 100644
--- a/freebsd/sys/netinet6/in6_mcast.c
+++ b/freebsd/sys/netinet6/in6_mcast.c
@@ -1240,11 +1240,8 @@ out_in6m_release:
int
in6_mc_leave(struct in6_multi *inm, /*const*/ struct in6_mfilter *imf)
{
- struct ifnet *ifp;
int error;
- ifp = inm->in6m_ifp;
-
IN6_MULTI_LOCK();
error = in6_mc_leave_locked(inm, imf);
IN6_MULTI_UNLOCK();
diff --git a/freebsd/sys/netinet6/in6_src.c b/freebsd/sys/netinet6/in6_src.c
index a13c1a06..5b110274 100644
--- a/freebsd/sys/netinet6/in6_src.c
+++ b/freebsd/sys/netinet6/in6_src.c
@@ -162,7 +162,6 @@ static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *);
*/
#define REPLACE(r) do {\
IP6STAT_INC(ip6s_sources_rule[(r)]); \
- rule = (r); \
/* { \
char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \
printf("in6_selectsrc: replace %s with %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \
@@ -178,7 +177,6 @@ static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *);
} while(0)
#define BREAK(r) do { \
IP6STAT_INC(ip6s_sources_rule[(r)]); \
- rule = (r); \
goto out; /* XXX: we can't use 'break' here */ \
} while(0)
@@ -196,7 +194,7 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock,
struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL;
u_int32_t odstzone;
int prefer_tempaddr;
- int error, rule;
+ int error;
struct ip6_moptions *mopts;
KASSERT(srcp != NULL, ("%s: srcp is NULL", __func__));
@@ -312,7 +310,6 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock,
if (error)
return (error);
- rule = 0;
IN6_IFADDR_RLOCK(&in6_ifa_tracker);
TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
int new_scope = -1, new_matchlen = -1;
diff --git a/freebsd/sys/netinet6/ip6_id.c b/freebsd/sys/netinet6/ip6_id.c
index cf0f3a4c..0905ab3f 100644
--- a/freebsd/sys/netinet6/ip6_id.c
+++ b/freebsd/sys/netinet6/ip6_id.c
@@ -1,6 +1,8 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
+ * SPDX-License-Identifier: (BSD-3-Clause AND BSD-2-Clause)
+ *
* Copyright (C) 2003 WIDE Project.
* All rights reserved.
*
@@ -32,8 +34,6 @@
*/
/*-
- * SPDX-License-Identifier: BSD-4-Clause AND BSD-3-Clause
- *
* Copyright 1998 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
*
@@ -50,11 +50,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Niels Provos.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -67,7 +62,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $OpenBSD: ip_id.c,v 1.6 2002/03/15 18:19:52 millert Exp $
+ * $OpenBSD: ip6_id.c,v 1.3 2003/12/12 06:57:12 itojun Exp $
*/
#include <sys/cdefs.h>
@@ -88,7 +83,7 @@ __FBSDID("$FreeBSD$");
* The transaction id is determined by:
* id[n] = seed xor (g^X[n] mod n)
*
- * Effectivly the id is restricted to the lower (bits - 1) bits, thus
+ * Effectively the id is restricted to the lower (bits - 1) bits, thus
* yielding two different cycles by toggling the msb on and off.
* This avoids reuse issues caused by reseeding.
*/
@@ -179,7 +174,7 @@ pmod(u_int32_t gen, u_int32_t expo, u_int32_t mod)
}
/*
- * Initalizes the seed and chooses a suitable generator. Also toggles
+ * Initializes the seed and chooses a suitable generator. Also toggles
* the msb flag. The msb flag is used to generate two distinct
* cycles of random numbers and thus avoiding reuse of ids.
*
@@ -234,15 +229,12 @@ static u_int32_t
randomid(struct randomtab *p)
{
int i, n;
- u_int32_t tmp;
if (p->ru_counter >= p->ru_max || time_uptime > p->ru_reseed)
initid(p);
- tmp = arc4random();
-
/* Skip a random number of ids */
- n = tmp & 0x3; tmp = tmp >> 2;
+ n = arc4random() & 0x3;
if (p->ru_counter + n >= p->ru_max)
initid(p);
@@ -253,7 +245,7 @@ randomid(struct randomtab *p)
p->ru_counter += i;
- return (p->ru_seed ^ pmod(p->ru_g, p->ru_seed2 ^ p->ru_x, p->ru_n)) |
+ return (p->ru_seed ^ pmod(p->ru_g, p->ru_seed2 + p->ru_x, p->ru_n)) |
p->ru_msb;
}
diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c
index c22f2015..78d941ae 100644
--- a/freebsd/sys/netinet6/ip6_input.c
+++ b/freebsd/sys/netinet6/ip6_input.c
@@ -575,10 +575,8 @@ ip6_input(struct mbuf *m)
/*
* Firewall changed destination to local.
*/
- m->m_flags &= ~M_FASTFWD_OURS;
- ours = 1;
ip6 = mtod(m, struct ip6_hdr *);
- goto hbhcheck;
+ goto passin;
}
/*
@@ -739,10 +737,8 @@ ip6_input(struct mbuf *m)
if ((m = ip6_tryforward(m)) == NULL)
return;
if (m->m_flags & M_FASTFWD_OURS) {
- m->m_flags &= ~M_FASTFWD_OURS;
- ours = 1;
ip6 = mtod(m, struct ip6_hdr *);
- goto hbhcheck;
+ goto passin;
}
}
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
@@ -773,13 +769,7 @@ ip6_input(struct mbuf *m)
return;
ip6 = mtod(m, struct ip6_hdr *);
srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
-
- if (m->m_flags & M_FASTFWD_OURS) {
- m->m_flags &= ~M_FASTFWD_OURS;
- ours = 1;
- goto hbhcheck;
- }
- if ((m->m_flags & M_IP6_NEXTHOP) &&
+ if ((m->m_flags & (M_IP6_NEXTHOP | M_FASTFWD_OURS)) == M_IP6_NEXTHOP &&
m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL) {
/*
* Directly ship the packet on. This allows forwarding
@@ -810,6 +800,11 @@ passin:
IP6STAT_INC(ip6s_badscope);
goto bad;
}
+ if (m->m_flags & M_FASTFWD_OURS) {
+ m->m_flags &= ~M_FASTFWD_OURS;
+ ours = 1;
+ goto hbhcheck;
+ }
/*
* Multicast check. Assume packet is for us to avoid
* prematurely taking locks.
diff --git a/freebsd/sys/netinet6/mld6.c b/freebsd/sys/netinet6/mld6.c
index 26fb21f7..c1dff0c3 100644
--- a/freebsd/sys/netinet6/mld6.c
+++ b/freebsd/sys/netinet6/mld6.c
@@ -2288,7 +2288,7 @@ mld_v2_enqueue_group_record(struct mbufq *mq, struct in6_multi *inm,
struct ifnet *ifp;
struct ip6_msource *ims, *nims;
struct mbuf *m0, *m, *md;
- int error, is_filter_list_change;
+ int is_filter_list_change;
int minrec0len, m0srcs, msrcs, nbytes, off;
int record_has_sources;
int now;
@@ -2300,7 +2300,6 @@ mld_v2_enqueue_group_record(struct mbufq *mq, struct in6_multi *inm,
IN6_MULTI_LOCK_ASSERT();
- error = 0;
ifp = inm->in6m_ifp;
is_filter_list_change = 0;
m = NULL;
diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c
index 30672e23..6235b808 100644
--- a/freebsd/sys/netinet6/nd6.c
+++ b/freebsd/sys/netinet6/nd6.c
@@ -2034,10 +2034,11 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
if (ln_tmp == NULL) {
/* No existing lle, mark as new entry (6,7) */
is_newentry = 1;
- nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
- if (lladdr != NULL) /* (7) */
+ if (lladdr != NULL) { /* (7) */
+ nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
EVENTHANDLER_INVOKE(lle_event, ln,
LLENTRY_RESOLVED);
+ }
} else {
lltable_free_entry(LLTABLE6(ifp), ln);
ln = ln_tmp;
@@ -2115,7 +2116,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
LLE_RUNLOCK(ln);
if (chain != NULL)
- nd6_flush_holdchain(ifp, ifp, chain, &sin6);
+ nd6_flush_holdchain(ifp, chain, &sin6);
/*
* When the link-layer address of a router changes, select the
@@ -2504,23 +2505,18 @@ nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
}
int
-nd6_flush_holdchain(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *chain,
+nd6_flush_holdchain(struct ifnet *ifp, struct mbuf *chain,
struct sockaddr_in6 *dst)
{
struct mbuf *m, *m_head;
- struct ifnet *outifp;
int error = 0;
m_head = chain;
- if ((ifp->if_flags & IFF_LOOPBACK) != 0)
- outifp = origifp;
- else
- outifp = ifp;
-
+
while (m_head) {
m = m_head;
m_head = m_head->m_nextpkt;
- error = nd6_output_ifp(ifp, origifp, m, dst, NULL);
+ error = nd6_output_ifp(ifp, ifp, m, dst, NULL);
}
/*
@@ -2528,7 +2524,7 @@ nd6_flush_holdchain(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *chain
* note that intermediate errors are blindly ignored
*/
return (error);
-}
+}
static int
nd6_need_cache(struct ifnet *ifp)
diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h
index 30990637..cabfeec0 100644
--- a/freebsd/sys/netinet6/nd6.h
+++ b/freebsd/sys/netinet6/nd6.h
@@ -448,7 +448,7 @@ void nd6_cache_lladdr(struct ifnet *, struct in6_addr *,
char *, int, int, int);
void nd6_grab_holdchain(struct llentry *, struct mbuf **,
struct sockaddr_in6 *);
-int nd6_flush_holdchain(struct ifnet *, struct ifnet *, struct mbuf *,
+int nd6_flush_holdchain(struct ifnet *, struct mbuf *,
struct sockaddr_in6 *);
int nd6_add_ifa_lle(struct in6_ifaddr *);
void nd6_rem_ifa_lle(struct in6_ifaddr *, int);
diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c
index 5e55fc2b..0c875324 100644
--- a/freebsd/sys/netinet6/nd6_nbr.c
+++ b/freebsd/sys/netinet6/nd6_nbr.c
@@ -139,6 +139,10 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
struct sockaddr_dl proxydl;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
rflag = 0;
@@ -633,6 +637,10 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
int lladdr_off;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
@@ -888,7 +896,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
LLE_WUNLOCK(ln);
if (chain != NULL)
- nd6_flush_holdchain(ifp, ifp, chain, &sin6);
+ nd6_flush_holdchain(ifp, chain, &sin6);
if (checklink)
pfxlist_onlink_check();
@@ -1301,7 +1309,8 @@ nd6_dad_stop(struct ifaddr *ifa)
* we were waiting for it to stop, so re-do the lookup.
*/
nd6_dad_rele(dp);
- if (nd6_dad_find(ifa, NULL) == NULL)
+ dp = nd6_dad_find(ifa, NULL);
+ if (dp == NULL)
return;
nd6_dad_del(dp);
@@ -1508,17 +1517,11 @@ nd6_dad_ns_output(struct dadq *dp)
static void
nd6_dad_ns_input(struct ifaddr *ifa, struct nd_opt_nonce *ndopt_nonce)
{
- struct in6_ifaddr *ia;
- struct ifnet *ifp;
- const struct in6_addr *taddr6;
struct dadq *dp;
if (ifa == NULL)
panic("ifa == NULL in nd6_dad_ns_input");
- ia = (struct in6_ifaddr *)ifa;
- ifp = ifa->ifa_ifp;
- taddr6 = &ia->ia_addr.sin6_addr;
/* Ignore Nonce option when Enhanced DAD is disabled. */
if (V_dad_enhanced == 0)
ndopt_nonce = NULL;
diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c
index 47fc497e..2affacbf 100644
--- a/freebsd/sys/netinet6/nd6_rtr.c
+++ b/freebsd/sys/netinet6/nd6_rtr.c
@@ -141,6 +141,10 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
if (!V_ip6_forwarding || ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV)
goto freeit;
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
/* Sanity checks */
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
@@ -231,6 +235,10 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV))
goto freeit;
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c
index 743fe787..b68077ef 100644
--- a/freebsd/sys/netinet6/raw_ip6.c
+++ b/freebsd/sys/netinet6/raw_ip6.c
@@ -341,9 +341,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
void
rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
{
- struct ip6_hdr *ip6;
- struct mbuf *m;
- int off = 0;
struct ip6ctlparam *ip6cp = NULL;
const struct sockaddr_in6 *sa6_src = NULL;
void *cmdarg;
@@ -367,14 +364,9 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
*/
if (d != NULL) {
ip6cp = (struct ip6ctlparam *)d;
- m = ip6cp->ip6c_m;
- ip6 = ip6cp->ip6c_ip6;
- off = ip6cp->ip6c_off;
cmdarg = ip6cp->ip6c_cmdarg;
sa6_src = ip6cp->ip6c_src;
} else {
- m = NULL;
- ip6 = NULL;
cmdarg = NULL;
sa6_src = &sa6_any;
}
@@ -393,7 +385,6 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
struct mbuf *control;
struct m_tag *mtag;
struct sockaddr_in6 *dstsock;
- struct in6_addr *dst;
struct ip6_hdr *ip6;
struct inpcb *in6p;
u_int plen = m->m_pkthdr.len;
@@ -415,7 +406,6 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
in6p = sotoinpcb(so);
INP_WLOCK(in6p);
- dst = &dstsock->sin6_addr;
if (control != NULL) {
if ((error = ip6_setpktopts(control, &opt,
in6p->in6p_outputopts, so->so_cred,
diff --git a/freebsd/sys/netinet6/scope6.c b/freebsd/sys/netinet6/scope6.c
index a4c56769..40218287 100644
--- a/freebsd/sys/netinet6/scope6.c
+++ b/freebsd/sys/netinet6/scope6.c
@@ -413,7 +413,7 @@ in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id)
if (scope == IPV6_ADDR_SCOPE_INTFACELOCAL ||
scope == IPV6_ADDR_SCOPE_LINKLOCAL) {
/*
- * Currently we use interface indeces as the
+ * Currently we use interface indices as the
* zone IDs for interface-local and link-local
* scopes.
*/
diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c
index 619a30dc..a79e6f53 100644
--- a/freebsd/sys/netinet6/sctp6_usrreq.c
+++ b/freebsd/sys/netinet6/sctp6_usrreq.c
@@ -73,9 +73,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
struct sctphdr *sh;
struct sctp_chunkhdr *ch;
int length, offset;
-#if !defined(SCTP_WITH_NO_CSUM)
uint8_t compute_crc;
-#endif
uint32_t mflowid;
uint8_t mflowtype;
uint16_t fibnum;
@@ -146,9 +144,6 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
goto out;
}
ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
-#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_recvnocrc);
-#else
if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
SCTP_STAT_INCR(sctps_recvhwcrc);
compute_crc = 0;
@@ -156,14 +151,11 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
SCTP_STAT_INCR(sctps_recvswcrc);
compute_crc = 1;
}
-#endif
sctp_common_input_processing(&m, iphlen, offset, length,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch,
-#if !defined(SCTP_WITH_NO_CSUM)
compute_crc,
-#endif
ecn_bits,
mflowtype, mflowid, fibnum,
vrf_id, port);
diff --git a/freebsd/sys/netinet6/udp6_usrreq.c b/freebsd/sys/netinet6/udp6_usrreq.c
index ae57ac79..98d097f7 100644
--- a/freebsd/sys/netinet6/udp6_usrreq.c
+++ b/freebsd/sys/netinet6/udp6_usrreq.c
@@ -1192,7 +1192,6 @@ udp6_disconnect(struct socket *so)
{
struct inpcb *inp;
struct inpcbinfo *pcbinfo;
- int error;
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
inp = sotoinpcb(so);
@@ -1214,8 +1213,8 @@ udp6_disconnect(struct socket *so)
#endif
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
- error = ENOTCONN;
- goto out;
+ INP_WUNLOCK(inp);
+ return (ENOTCONN);
}
INP_HASH_WLOCK(pcbinfo);
@@ -1225,7 +1224,6 @@ udp6_disconnect(struct socket *so)
SOCK_LOCK(so);
so->so_state &= ~SS_ISCONNECTED; /* XXX */
SOCK_UNLOCK(so);
-out:
INP_WUNLOCK(inp);
return (0);
}
diff --git a/freebsd/sys/netipsec/key.c b/freebsd/sys/netipsec/key.c
index 3652524c..31269058 100644
--- a/freebsd/sys/netipsec/key.c
+++ b/freebsd/sys/netipsec/key.c
@@ -5746,7 +5746,6 @@ static int
key_setident(struct secashead *sah, const struct sadb_msghdr *mhp)
{
const struct sadb_ident *idsrc, *iddst;
- int idsrclen, iddstlen;
IPSEC_ASSERT(sah != NULL, ("null secashead"));
IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
@@ -5768,8 +5767,6 @@ key_setident(struct secashead *sah, const struct sadb_msghdr *mhp)
idsrc = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_SRC];
iddst = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_DST];
- idsrclen = mhp->extlen[SADB_EXT_IDENTITY_SRC];
- iddstlen = mhp->extlen[SADB_EXT_IDENTITY_DST];
/* validity check */
if (idsrc->sadb_ident_type != iddst->sadb_ident_type) {
@@ -7466,7 +7463,6 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
SAHTREE_RLOCK_TRACKER;
struct secashead *sah;
struct secasvar *sav;
- struct sadb_msg *newmsg;
struct mbuf *n;
uint32_t cnt;
uint8_t proto, satype;
@@ -7503,7 +7499,6 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
}
/* send this to the userland, one at a time. */
- newmsg = NULL;
TAILQ_FOREACH(sah, &V_sahtree, chain) {
if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC &&
proto != sah->saidx.proto)
@@ -8149,7 +8144,10 @@ key_destroy(void)
TAILQ_CONCAT(&drainq, &V_sptree[i], chain);
TAILQ_CONCAT(&drainq, &V_sptree_ifnet[i], chain);
}
+ for (i = 0; i < V_sphash_mask + 1; i++)
+ LIST_INIT(&V_sphashtbl[i]);
SPTREE_WUNLOCK();
+
sp = TAILQ_FIRST(&drainq);
while (sp != NULL) {
nextsp = TAILQ_NEXT(sp, chain);
@@ -8200,6 +8198,10 @@ key_destroy(void)
free(acq, M_IPSEC_SAQ);
acq = nextacq;
}
+ for (i = 0; i < V_acqaddrhash_mask + 1; i++)
+ LIST_INIT(&V_acqaddrhashtbl[i]);
+ for (i = 0; i < V_acqseqhash_mask + 1; i++)
+ LIST_INIT(&V_acqseqhashtbl[i]);
ACQ_UNLOCK();
SPACQ_LOCK();
@@ -8215,6 +8217,18 @@ key_destroy(void)
hashdestroy(V_acqaddrhashtbl, M_IPSEC_SAQ, V_acqaddrhash_mask);
hashdestroy(V_acqseqhashtbl, M_IPSEC_SAQ, V_acqseqhash_mask);
uma_zdestroy(V_key_lft_zone);
+
+ if (!IS_DEFAULT_VNET(curvnet))
+ return;
+#ifndef IPSEC_DEBUG2
+ callout_drain(&key_timer);
+#endif
+ XFORMS_LOCK_DESTROY();
+ SPTREE_LOCK_DESTROY();
+ REGTREE_LOCK_DESTROY();
+ SAHTREE_LOCK_DESTROY();
+ ACQ_LOCK_DESTROY();
+ SPACQ_LOCK_DESTROY();
}
#endif
diff --git a/freebsd/sys/netipsec/xform_ah.c b/freebsd/sys/netipsec/xform_ah.c
index 5667f78f..9125ba40 100644
--- a/freebsd/sys/netipsec/xform_ah.c
+++ b/freebsd/sys/netipsec/xform_ah.c
@@ -266,7 +266,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
#ifdef INET6
struct ip6_ext *ip6e;
struct ip6_hdr ip6;
- int alloc, len, ad;
+ int ad, alloc, nxt, noff;
#endif /* INET6 */
switch (proto) {
@@ -295,7 +295,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
else
ip->ip_off = htons(0);
- ptr = mtod(m, unsigned char *) + sizeof(struct ip);
+ ptr = mtod(m, unsigned char *);
/* IPv4 option processing */
for (off = sizeof(struct ip); off < skip;) {
@@ -376,7 +376,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
/* Zeroize all other options. */
count = ptr[off + 1];
- bcopy(ipseczeroes, ptr, count);
+ bcopy(ipseczeroes, ptr + off, count);
off += count;
break;
}
@@ -449,61 +449,44 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
} else
break;
- off = ip6.ip6_nxt & 0xff; /* Next header type. */
+ nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
- for (len = 0; len < skip - sizeof(struct ip6_hdr);)
- switch (off) {
+ for (off = 0; off < skip - sizeof(struct ip6_hdr);)
+ switch (nxt) {
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
- ip6e = (struct ip6_ext *) (ptr + len);
+ ip6e = (struct ip6_ext *)(ptr + off);
+ noff = off + ((ip6e->ip6e_len + 1) << 3);
+
+ /* Sanity check. */
+ if (noff > skip - sizeof(struct ip6_hdr))
+ goto error6;
/*
- * Process the mutable/immutable
- * options -- borrows heavily from the
- * KAME code.
+ * Zero out mutable options.
*/
- for (count = len + sizeof(struct ip6_ext);
- count < len + ((ip6e->ip6e_len + 1) << 3);) {
+ for (count = off + sizeof(struct ip6_ext);
+ count < noff;) {
if (ptr[count] == IP6OPT_PAD1) {
count++;
continue; /* Skip padding. */
}
- /* Sanity check. */
- if (count > len +
- ((ip6e->ip6e_len + 1) << 3)) {
- m_freem(m);
-
- /* Free, if we allocated. */
- if (alloc)
- free(ptr, M_XDATA);
- return EINVAL;
- }
-
- ad = ptr[count + 1];
+ ad = ptr[count + 1] + 2;
+ if (count + ad > noff)
+ goto error6;
- /* If mutable option, zeroize. */
if (ptr[count] & IP6OPT_MUTABLE)
- bcopy(ipseczeroes, ptr + count,
- ptr[count + 1]);
-
+ memset(ptr + count, 0, ad);
count += ad;
-
- /* Sanity check. */
- if (count >
- skip - sizeof(struct ip6_hdr)) {
- m_freem(m);
-
- /* Free, if we allocated. */
- if (alloc)
- free(ptr, M_XDATA);
- return EINVAL;
- }
}
+ if (count != noff)
+ goto error6;
+
/* Advance. */
- len += ((ip6e->ip6e_len + 1) << 3);
- off = ip6e->ip6e_nxt;
+ off += ((ip6e->ip6e_len + 1) << 3);
+ nxt = ip6e->ip6e_nxt;
break;
case IPPROTO_ROUTING:
@@ -511,14 +494,15 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
* Always include routing headers in
* computation.
*/
- ip6e = (struct ip6_ext *) (ptr + len);
- len += ((ip6e->ip6e_len + 1) << 3);
- off = ip6e->ip6e_nxt;
+ ip6e = (struct ip6_ext *) (ptr + off);
+ off += ((ip6e->ip6e_len + 1) << 3);
+ nxt = ip6e->ip6e_nxt;
break;
default:
DPRINTF(("%s: unexpected IPv6 header type %d",
__func__, off));
+error6:
if (alloc)
free(ptr, M_XDATA);
m_freem(m);
@@ -687,9 +671,7 @@ ah_input_cb(struct cryptop *crp)
{
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
unsigned char calc[AH_ALEN_MAX];
- const struct auth_hash *ahx;
struct mbuf *m;
- struct cryptodesc *crd;
struct xform_data *xd;
struct secasvar *sav;
struct secasindex *saidx;
@@ -698,7 +680,6 @@ ah_input_cb(struct cryptop *crp)
int authsize, rplen, error, skip, protoff;
uint8_t nxt;
- crd = crp->crp_desc;
m = (struct mbuf *) crp->crp_buf;
xd = (struct xform_data *) crp->crp_opaque;
sav = xd->sav;
@@ -711,8 +692,6 @@ ah_input_cb(struct cryptop *crp)
saidx->dst.sa.sa_family == AF_INET6,
("unexpected protocol family %u", saidx->dst.sa.sa_family));
- ahx = sav->tdb_authalgxform;
-
/* Check for crypto errors. */
if (crp->crp_etype) {
if (crp->crp_etype == EAGAIN) {
diff --git a/freebsd/sys/netipsec/xform_esp.c b/freebsd/sys/netipsec/xform_esp.c
index 8af95f7d..f26b8ae7 100644
--- a/freebsd/sys/netipsec/xform_esp.c
+++ b/freebsd/sys/netipsec/xform_esp.c
@@ -443,7 +443,6 @@ esp_input_cb(struct cryptop *crp)
IPSEC_DEBUG_DECLARE(char buf[128]);
u_int8_t lastthree[3], aalg[AH_HMAC_MAXHASHLEN];
const struct auth_hash *esph;
- const struct enc_xform *espx;
struct mbuf *m;
struct cryptodesc *crd;
struct xform_data *xd;
@@ -464,7 +463,6 @@ esp_input_cb(struct cryptop *crp)
cryptoid = xd->cryptoid;
saidx = &sav->sah->saidx;
esph = sav->tdb_authalgxform;
- espx = sav->tdb_encalgxform;
/* Check for crypto errors */
if (crp->crp_etype) {
diff --git a/freebsd/sys/netipsec/xform_ipcomp.c b/freebsd/sys/netipsec/xform_ipcomp.c
index 4764e609..956383d5 100644
--- a/freebsd/sys/netipsec/xform_ipcomp.c
+++ b/freebsd/sys/netipsec/xform_ipcomp.c
@@ -276,7 +276,6 @@ static int
ipcomp_input_cb(struct cryptop *crp)
{
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
- struct cryptodesc *crd;
struct xform_data *xd;
struct mbuf *m;
struct secasvar *sav;
@@ -287,8 +286,6 @@ ipcomp_input_cb(struct cryptop *crp)
int skip, protoff;
uint8_t nproto;
- crd = crp->crp_desc;
-
m = (struct mbuf *) crp->crp_buf;
xd = (struct xform_data *) crp->crp_opaque;
sav = xd->sav;
diff --git a/freebsd/sys/netpfil/pf/if_pflog.c b/freebsd/sys/netpfil/pf/if_pflog.c
index 1ad6a774..53cf94c8 100644
--- a/freebsd/sys/netpfil/pf/if_pflog.c
+++ b/freebsd/sys/netpfil/pf/if_pflog.c
@@ -1,6 +1,8 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
+ * SPDX-License-Identifier: ISC
+ *
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
* Niels Provos (provos@physnet.uni-hamburg.de).
diff --git a/freebsd/sys/netpfil/pf/in4_cksum.c b/freebsd/sys/netpfil/pf/in4_cksum.c
index 509c33cd..242909cc 100644
--- a/freebsd/sys/netpfil/pf/in4_cksum.c
+++ b/freebsd/sys/netpfil/pf/in4_cksum.c
@@ -5,7 +5,7 @@
/* $KAME: in4_cksum.c,v 1.10 2001/11/30 10:06:15 itojun Exp $ */
/* $NetBSD: in_cksum.c,v 1.13 1996/10/13 02:03:03 christos Exp $ */
-/*
+/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 1999 WIDE Project.
diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c
index d94966b9..a904a0db 100644
--- a/freebsd/sys/netpfil/pf/pf.c
+++ b/freebsd/sys/netpfil/pf/pf.c
@@ -1500,7 +1500,7 @@ pf_unload_vnet_purge(void)
* Now purge everything.
*/
pf_purge_expired_states(0, pf_hashmask);
- pf_purge_expired_fragments();
+ pf_purge_fragments(UINT_MAX);
pf_purge_expired_src_nodes();
/*
@@ -1615,6 +1615,7 @@ int
pf_unlink_state(struct pf_state *s, u_int flags)
{
struct pf_idhash *ih = &V_pf_idhash[PF_IDHASH(s)];
+ int last;
if ((flags & PF_ENTER_LOCKED) == 0)
PF_HASHROW_LOCK(ih);
@@ -1655,7 +1656,8 @@ pf_unlink_state(struct pf_state *s, u_int flags)
PF_HASHROW_UNLOCK(ih);
pf_detach_state(s);
- refcount_release(&s->refs);
+ last = refcount_release(&s->refs);
+ KASSERT(last == 0, ("Incorrect state reference count"));
return (pf_release_state(s));
}
diff --git a/freebsd/sys/netpfil/pf/pf.h b/freebsd/sys/netpfil/pf/pf.h
index 333faea3..69472782 100644
--- a/freebsd/sys/netpfil/pf/pf.h
+++ b/freebsd/sys/netpfil/pf/pf.h
@@ -1,4 +1,4 @@
-/*
+/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2001 Daniel Hartmeier
diff --git a/freebsd/sys/netpfil/pf/pf_ioctl.c b/freebsd/sys/netpfil/pf/pf_ioctl.c
index 98f190e7..a1b0b5e5 100644
--- a/freebsd/sys/netpfil/pf/pf_ioctl.c
+++ b/freebsd/sys/netpfil/pf/pf_ioctl.c
@@ -2543,7 +2543,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_table);
- pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
+ M_TEMP, M_WAITOK);
+ if (! pfrts) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
@@ -2567,7 +2572,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_table);
- pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
+ M_TEMP, M_WAITOK);
+ if (! pfrts) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
@@ -2591,7 +2601,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_table);
- pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
+ M_TEMP, M_WAITOK);
+ if (! pfrts) {
+ error = ENOMEM;
+ break;
+ }
PF_RULES_RLOCK();
error = pfr_get_tables(&io->pfrio_table, pfrts,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
@@ -2612,7 +2627,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_tstats);
- pfrtstats = malloc(totlen, M_TEMP, M_WAITOK);
+ pfrtstats = mallocarray(io->pfrio_size,
+ sizeof(struct pfr_tstats), M_TEMP, M_WAITOK);
+ if (! pfrtstats) {
+ error = ENOMEM;
+ break;
+ }
PF_RULES_WLOCK();
error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
@@ -2633,7 +2653,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_table);
- pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
+ M_TEMP, M_WAITOK);
+ if (! pfrts) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
@@ -2657,7 +2682,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_table);
- pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
+ M_TEMP, M_WAITOK);
+ if (! pfrts) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
@@ -2696,7 +2726,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_addr);
- pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
+ M_TEMP, M_WAITOK);
+ if (! pfras) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfras, totlen);
if (error) {
free(pfras, M_TEMP);
@@ -2723,7 +2758,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_addr);
- pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
+ M_TEMP, M_WAITOK);
+ if (! pfras) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfras, totlen);
if (error) {
free(pfras, M_TEMP);
@@ -2751,7 +2791,12 @@ DIOCCHANGEADDR_error:
}
count = max(io->pfrio_size, io->pfrio_size2);
totlen = count * sizeof(struct pfr_addr);
- pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
+ M_WAITOK);
+ if (! pfras) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfras, totlen);
if (error) {
free(pfras, M_TEMP);
@@ -2779,7 +2824,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_addr);
- pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
+ M_TEMP, M_WAITOK);
+ if (! pfras) {
+ error = ENOMEM;
+ break;
+ }
PF_RULES_RLOCK();
error = pfr_get_addrs(&io->pfrio_table, pfras,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
@@ -2800,7 +2850,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_astats);
- pfrastats = malloc(totlen, M_TEMP, M_WAITOK);
+ pfrastats = mallocarray(io->pfrio_size,
+ sizeof(struct pfr_astats), M_TEMP, M_WAITOK);
+ if (! pfrastats) {
+ error = ENOMEM;
+ break;
+ }
PF_RULES_RLOCK();
error = pfr_get_astats(&io->pfrio_table, pfrastats,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
@@ -2821,7 +2876,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_addr);
- pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
+ M_TEMP, M_WAITOK);
+ if (! pfras) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfras, totlen);
if (error) {
free(pfras, M_TEMP);
@@ -2848,7 +2908,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_addr);
- pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
+ M_TEMP, M_WAITOK);
+ if (! pfras) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfras, totlen);
if (error) {
free(pfras, M_TEMP);
@@ -2875,7 +2940,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = io->pfrio_size * sizeof(struct pfr_addr);
- pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
+ M_TEMP, M_WAITOK);
+ if (! pfras) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->pfrio_buffer, pfras, totlen);
if (error) {
free(pfras, M_TEMP);
@@ -2917,7 +2987,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = sizeof(struct pfioc_trans_e) * io->size;
- ioes = malloc(totlen, M_TEMP, M_WAITOK);
+ ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
+ M_TEMP, M_WAITOK);
+ if (! ioes) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->array, ioes, totlen);
if (error) {
free(ioes, M_TEMP);
@@ -2983,7 +3058,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = sizeof(struct pfioc_trans_e) * io->size;
- ioes = malloc(totlen, M_TEMP, M_WAITOK);
+ ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
+ M_TEMP, M_WAITOK);
+ if (! ioes) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->array, ioes, totlen);
if (error) {
free(ioes, M_TEMP);
@@ -3049,7 +3129,12 @@ DIOCCHANGEADDR_error:
break;
}
totlen = sizeof(struct pfioc_trans_e) * io->size;
- ioes = malloc(totlen, M_TEMP, M_WAITOK);
+ ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
+ M_TEMP, M_WAITOK);
+ if (! ioes) {
+ error = ENOMEM;
+ break;
+ }
error = copyin(io->array, ioes, totlen);
if (error) {
free(ioes, M_TEMP);
@@ -3250,7 +3335,12 @@ DIOCCHANGEADDR_error:
}
bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
- ifstore = malloc(bufsiz, M_TEMP, M_WAITOK);
+ ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
+ M_TEMP, M_WAITOK);
+ if (! ifstore) {
+ error = ENOMEM;
+ break;
+ }
PF_RULES_RLOCK();
pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
PF_RULES_RUNLOCK();
@@ -3845,12 +3935,6 @@ pf_modevent(module_t mod, int type, void *data)
case MOD_LOAD:
error = pf_load();
break;
- case MOD_QUIESCE:
- /*
- * Module should not be unloaded due to race conditions.
- */
- error = EBUSY;
- break;
case MOD_UNLOAD:
/* Handled in SYSUNINIT(pf_unload) to ensure it's done after
* the vnet_pf_uninit()s */
diff --git a/freebsd/sys/netpfil/pf/pf_norm.c b/freebsd/sys/netpfil/pf/pf_norm.c
index e3a00971..4f0966ed 100644
--- a/freebsd/sys/netpfil/pf/pf_norm.c
+++ b/freebsd/sys/netpfil/pf/pf_norm.c
@@ -221,9 +221,16 @@ pf_frag_compare(struct pf_fragment *a, struct pf_fragment *b)
void
pf_purge_expired_fragments(void)
{
+ u_int32_t expire = time_uptime -
+ V_pf_default_rule.timeout[PFTM_FRAG];
+
+ pf_purge_fragments(expire);
+}
+
+void
+pf_purge_fragments(uint32_t expire)
+{
struct pf_fragment *frag;
- u_int32_t expire = time_uptime -
- V_pf_default_rule.timeout[PFTM_FRAG];
PF_FRAG_LOCK();
while ((frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue)) != NULL) {
diff --git a/freebsd/sys/netpfil/pf/pf_osfp.c b/freebsd/sys/netpfil/pf/pf_osfp.c
index 7b55d20a..1ee16df5 100644
--- a/freebsd/sys/netpfil/pf/pf_osfp.c
+++ b/freebsd/sys/netpfil/pf/pf_osfp.c
@@ -1,6 +1,8 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
+ * SPDX-License-Identifier: ISC
+ *
* Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
*
* Permission to use, copy, modify, and distribute this software for any
diff --git a/freebsd/sys/opencrypto/crypto.c b/freebsd/sys/opencrypto/crypto.c
index 2631ca5b..f6943be2 100644
--- a/freebsd/sys/opencrypto/crypto.c
+++ b/freebsd/sys/opencrypto/crypto.c
@@ -903,11 +903,12 @@ crypto_dispatch(struct cryptop *crp)
binuptime(&crp->crp_tstamp);
#endif
+ crp->crp_retw_id = crp->crp_sid % crypto_workers_num;
+
if (CRYPTOP_ASYNC(crp)) {
if (crp->crp_flags & CRYPTO_F_ASYNC_KEEPORDER) {
struct crypto_ret_worker *ret_worker;
- crp->crp_retw_id = crp->crp_sid % crypto_workers_num;
ret_worker = CRYPTO_RETW(crp->crp_retw_id);
CRYPTO_RETW_LOCK(ret_worker);
@@ -1001,7 +1002,7 @@ kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
static struct cryptocap *
crypto_select_kdriver(const struct cryptkop *krp, int flags)
{
- struct cryptocap *cap, *best, *blocked;
+ struct cryptocap *cap, *best;
int match, hid;
CRYPTO_DRIVER_ASSERT();
@@ -1014,7 +1015,6 @@ crypto_select_kdriver(const struct cryptkop *krp, int flags)
else
match = CRYPTOCAP_F_SOFTWARE;
best = NULL;
- blocked = NULL;
again:
for (hid = 0; hid < crypto_drivers_num; hid++) {
cap = &crypto_drivers[hid];
diff --git a/freebsd/sys/opencrypto/cryptodev.c b/freebsd/sys/opencrypto/cryptodev.c
index 9d8b23dc..c24af195 100644
--- a/freebsd/sys/opencrypto/cryptodev.c
+++ b/freebsd/sys/opencrypto/cryptodev.c
@@ -280,14 +280,17 @@ struct csession {
caddr_t key;
int keylen;
- u_char tmp_iv[EALG_MAX_BLOCK_LEN];
caddr_t mackey;
int mackeylen;
+};
+
+struct cryptop_data {
+ struct csession *cse;
- struct iovec iovec;
+ struct iovec iovec[1];
struct uio uio;
- int error;
+ bool done;
};
struct fcrypt {
@@ -449,6 +452,7 @@ cryptof_ioctl(
default:
CRYPTDEB("invalid cipher");
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
}
@@ -496,6 +500,7 @@ cryptof_ioctl(
break;
default:
CRYPTDEB("invalid mac");
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
}
@@ -509,6 +514,8 @@ cryptof_ioctl(
sop->keylen < txform->minkey) {
CRYPTDEB("invalid cipher parameters");
error = EINVAL;
+ SDT_PROBE1(opencrypto, dev, ioctl, error,
+ __LINE__);
goto bail;
}
@@ -517,6 +524,8 @@ cryptof_ioctl(
if ((error = copyin(sop->key, crie.cri_key,
crie.cri_klen / 8))) {
CRYPTDEB("invalid key");
+ SDT_PROBE1(opencrypto, dev, ioctl, error,
+ __LINE__);
goto bail;
}
if (thash)
@@ -530,6 +539,8 @@ cryptof_ioctl(
sop->mackeylen > thash->keysize) {
CRYPTDEB("invalid mac key length");
error = EINVAL;
+ SDT_PROBE1(opencrypto, dev, ioctl, error,
+ __LINE__);
goto bail;
}
@@ -539,6 +550,8 @@ cryptof_ioctl(
if ((error = copyin(sop->mackey, cria.cri_key,
cria.cri_klen / 8))) {
CRYPTDEB("invalid mac key");
+ SDT_PROBE1(opencrypto, dev, ioctl,
+ error, __LINE__);
goto bail;
}
}
@@ -554,6 +567,8 @@ cryptof_ioctl(
error = checkforsoftware(&crid);
if (error) {
CRYPTDEB("checkforsoftware");
+ SDT_PROBE1(opencrypto, dev, ioctl, error,
+ __LINE__);
goto bail;
}
} else
@@ -561,6 +576,7 @@ cryptof_ioctl(
error = crypto_newsession(&sid, (txform ? &crie : &cria), crid);
if (error) {
CRYPTDEB("crypto_newsession");
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
@@ -571,6 +587,7 @@ cryptof_ioctl(
if (cse == NULL) {
crypto_freesession(sid);
error = EINVAL;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
CRYPTDEB("csecreate");
goto bail;
}
@@ -603,8 +620,10 @@ bail:
case CIOCFSESSION:
ses = *(u_int32_t *)data;
cse = csefind(fcr, ses);
- if (cse == NULL)
+ if (cse == NULL) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
+ }
csedelete(fcr, cse);
error = csefree(cse);
break;
@@ -634,8 +653,10 @@ bail:
case CIOCKEY32:
case CIOCKEY232:
#endif
- if (!crypto_userasymcrypto)
+ if (!crypto_userasymcrypto) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EPERM); /* XXX compat? */
+ }
#ifdef COMPAT_FREEBSD32
if (cmd == CIOCKEY32 || cmd == CIOCKEY232) {
kop = &kopc;
@@ -669,8 +690,12 @@ bail:
* fallback to doing them in software.
*/
*(int *)data = 0;
- } else
+ } else {
error = crypto_getfeat((int *)data);
+ if (error)
+ SDT_PROBE1(opencrypto, dev, ioctl, error,
+ __LINE__);
+ }
break;
case CIOCFINDDEV:
error = cryptodev_find((struct crypt_find_op *)data);
@@ -678,12 +703,15 @@ bail:
case CIOCCRYPTAEAD:
caead = (struct crypt_aead *)data;
cse = csefind(fcr, caead->ses);
- if (cse == NULL)
+ if (cse == NULL) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
+ }
error = cryptodev_aead(cse, caead, active_cred, td);
break;
default:
error = EINVAL;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
break;
}
return (error);
@@ -711,8 +739,36 @@ rtems_bsd_cryptof_ioctl(rtems_libio_t *iop, ioctl_command_t request,
}
#endif /* __rtems__ */
-static int cryptodev_cb(void *);
+static int cryptodev_cb(struct cryptop *);
+
+static struct cryptop_data *
+cod_alloc(struct csession *cse, size_t len, struct thread *td)
+{
+ struct cryptop_data *cod;
+ struct uio *uio;
+
+ cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO);
+
+ cod->cse = cse;
+ uio = &cod->uio;
+ uio->uio_iov = cod->iovec;
+ uio->uio_iovcnt = 1;
+ uio->uio_resid = len;
+ uio->uio_segflg = UIO_SYSSPACE;
+ uio->uio_rw = UIO_WRITE;
+ uio->uio_td = td;
+ uio->uio_iov[0].iov_len = len;
+ uio->uio_iov[0].iov_base = malloc(len, M_XDATA, M_WAITOK);
+ return (cod);
+}
+
+static void
+cod_free(struct cryptop_data *cod)
+{
+ free(cod->uio.uio_iov[0].iov_base, M_XDATA);
+ free(cod, M_XDATA);
+}
static int
cryptodev_op(
@@ -721,6 +777,7 @@ cryptodev_op(
struct ucred *active_cred,
struct thread *td)
{
+ struct cryptop_data *cod = NULL;
struct cryptop *crp = NULL;
struct cryptodesc *crde = NULL, *crda = NULL;
int error;
@@ -737,20 +794,10 @@ cryptodev_op(
}
}
- cse->uio.uio_iov = &cse->iovec;
- cse->uio.uio_iovcnt = 1;
- cse->uio.uio_offset = 0;
- cse->uio.uio_resid = cop->len;
- cse->uio.uio_segflg = UIO_SYSSPACE;
- cse->uio.uio_rw = UIO_WRITE;
- cse->uio.uio_td = td;
- cse->uio.uio_iov[0].iov_len = cop->len;
- if (cse->thash) {
- cse->uio.uio_iov[0].iov_len += cse->thash->hashsize;
- cse->uio.uio_resid += cse->thash->hashsize;
- }
- cse->uio.uio_iov[0].iov_base = malloc(cse->uio.uio_iov[0].iov_len,
- M_XDATA, M_WAITOK);
+ if (cse->thash)
+ cod = cod_alloc(cse, cop->len + cse->thash->hashsize, td);
+ else
+ cod = cod_alloc(cse, cop->len, td);
crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL));
if (crp == NULL) {
@@ -777,7 +824,7 @@ cryptodev_op(
goto bail;
}
- if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base,
+ if ((error = copyin(cop->src, cod->uio.uio_iov[0].iov_base,
cop->len))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
@@ -809,10 +856,10 @@ cryptodev_op(
crp->crp_ilen = cop->len;
crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
| (cop->flags & COP_F_BATCH);
- crp->crp_buf = (caddr_t)&cse->uio;
- crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
+ crp->crp_uio = &cod->uio;
+ crp->crp_callback = cryptodev_cb;
crp->crp_sid = cse->sid;
- crp->crp_opaque = (void *)cse;
+ crp->crp_opaque = cod;
if (cop->iv) {
if (crde == NULL) {
@@ -825,12 +872,11 @@ cryptodev_op(
error = EINVAL;
goto bail;
}
- if ((error = copyin(cop->iv, cse->tmp_iv,
+ if ((error = copyin(cop->iv, crde->crd_iv,
cse->txform->blocksize))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
- bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize);
crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
crde->crd_skip = 0;
} else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
@@ -856,19 +902,20 @@ again:
* entry and the crypto_done callback into us.
*/
error = crypto_dispatch(crp);
- mtx_lock(&cse->lock);
- if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0)
- error = msleep(crp, &cse->lock, PWAIT, "crydev", 0);
- mtx_unlock(&cse->lock);
-
if (error != 0) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
+ mtx_lock(&cse->lock);
+ while (!cod->done)
+ mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
+ mtx_unlock(&cse->lock);
+
if (crp->crp_etype == EAGAIN) {
crp->crp_etype = 0;
crp->crp_flags &= ~CRYPTO_F_DONE;
+ cod->done = false;
goto again;
}
@@ -878,21 +925,15 @@ again:
goto bail;
}
- if (cse->error) {
- SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
- error = cse->error;
- goto bail;
- }
-
if (cop->dst &&
- (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst,
+ (error = copyout(cod->uio.uio_iov[0].iov_base, cop->dst,
cop->len))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
if (cop->mac &&
- (error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
+ (error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base + cop->len,
cop->mac, cse->thash->hashsize))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
@@ -901,8 +942,8 @@ again:
bail:
if (crp)
crypto_freereq(crp);
- if (cse->uio.uio_iov[0].iov_base)
- free(cse->uio.uio_iov[0].iov_base, M_XDATA);
+ if (cod)
+ cod_free(cod);
return (error);
}
@@ -914,34 +955,29 @@ cryptodev_aead(
struct ucred *active_cred,
struct thread *td)
{
- struct uio *uio;
+ struct cryptop_data *cod = NULL;
struct cryptop *crp = NULL;
struct cryptodesc *crde = NULL, *crda = NULL;
int error;
- if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4)
+ if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (E2BIG);
+ }
if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL ||
- (caead->len % cse->txform->blocksize) != 0)
+ (caead->len % cse->txform->blocksize) != 0) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
+ }
- uio = &cse->uio;
- uio->uio_iov = &cse->iovec;
- uio->uio_iovcnt = 1;
- uio->uio_offset = 0;
- uio->uio_resid = caead->aadlen + caead->len + cse->thash->hashsize;
- uio->uio_segflg = UIO_SYSSPACE;
- uio->uio_rw = UIO_WRITE;
- uio->uio_td = td;
- uio->uio_iov[0].iov_len = uio->uio_resid;
-
- uio->uio_iov[0].iov_base = malloc(uio->uio_iov[0].iov_len,
- M_XDATA, M_WAITOK);
+ cod = cod_alloc(cse, caead->aadlen + caead->len + cse->thash->hashsize,
+ td);
crp = crypto_getreq(2);
if (crp == NULL) {
error = ENOMEM;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
@@ -953,13 +989,17 @@ cryptodev_aead(
crde = crda->crd_next;
}
- if ((error = copyin(caead->aad, cse->uio.uio_iov[0].iov_base,
- caead->aadlen)))
+ if ((error = copyin(caead->aad, cod->uio.uio_iov[0].iov_base,
+ caead->aadlen))) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
+ }
- if ((error = copyin(caead->src, (char *)cse->uio.uio_iov[0].iov_base +
- caead->aadlen, caead->len)))
+ if ((error = copyin(caead->src, (char *)cod->uio.uio_iov[0].iov_base +
+ caead->aadlen, caead->len))) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
+ }
/*
* For GCM, crd_len covers only the AAD. For other ciphers
@@ -992,20 +1032,22 @@ cryptodev_aead(
crp->crp_ilen = caead->aadlen + caead->len;
crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
| (caead->flags & COP_F_BATCH);
- crp->crp_buf = (caddr_t)&cse->uio.uio_iov;
- crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
+ crp->crp_uio = &cod->uio;
+ crp->crp_callback = cryptodev_cb;
crp->crp_sid = cse->sid;
- crp->crp_opaque = (void *)cse;
+ crp->crp_opaque = cod;
if (caead->iv) {
- if (caead->ivlen > sizeof cse->tmp_iv) {
+ if (caead->ivlen > sizeof(crde->crd_iv)) {
error = EINVAL;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
- if ((error = copyin(caead->iv, cse->tmp_iv, caead->ivlen)))
+ if ((error = copyin(caead->iv, crde->crd_iv, caead->ivlen))) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
- bcopy(cse->tmp_iv, crde->crd_iv, caead->ivlen);
+ }
crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
} else {
crde->crd_flags |= CRD_F_IV_PRESENT;
@@ -1013,9 +1055,11 @@ cryptodev_aead(
crde->crd_len -= cse->txform->blocksize;
}
- if ((error = copyin(caead->tag, (caddr_t)cse->uio.uio_iov[0].iov_base +
- caead->len + caead->aadlen, cse->thash->hashsize)))
+ if ((error = copyin(caead->tag, (caddr_t)cod->uio.uio_iov[0].iov_base +
+ caead->len + caead->aadlen, cse->thash->hashsize))) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
+ }
again:
/*
* Let the dispatch run unlocked, then, interlock against the
@@ -1025,56 +1069,64 @@ again:
* entry and the crypto_done callback into us.
*/
error = crypto_dispatch(crp);
+ if (error != 0) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+ goto bail;
+ }
+
mtx_lock(&cse->lock);
- if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0)
- error = msleep(crp, &cse->lock, PWAIT, "crydev", 0);
+ while (!cod->done)
+ mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
mtx_unlock(&cse->lock);
- if (error != 0)
- goto bail;
-
if (crp->crp_etype == EAGAIN) {
crp->crp_etype = 0;
crp->crp_flags &= ~CRYPTO_F_DONE;
+ cod->done = false;
goto again;
}
if (crp->crp_etype != 0) {
error = crp->crp_etype;
- goto bail;
- }
-
- if (cse->error) {
- error = cse->error;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
if (caead->dst && (error = copyout(
- (caddr_t)cse->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst,
- caead->len)))
+ (caddr_t)cod->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst,
+ caead->len))) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
+ }
- if ((error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base +
- caead->aadlen + caead->len, caead->tag, cse->thash->hashsize)))
+ if ((error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base +
+ caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
+ }
bail:
crypto_freereq(crp);
- free(cse->uio.uio_iov[0].iov_base, M_XDATA);
+ if (cod)
+ cod_free(cod);
return (error);
}
static int
-cryptodev_cb(void *op)
+cryptodev_cb(struct cryptop *crp)
{
- struct cryptop *crp = (struct cryptop *) op;
- struct csession *cse = (struct csession *)crp->crp_opaque;
+ struct cryptop_data *cod = crp->crp_opaque;
- mtx_lock(&cse->lock);
- cse->error = crp->crp_etype;
- wakeup_one(crp);
- mtx_unlock(&cse->lock);
+ /*
+ * Lock to ensure the wakeup() is not missed by the loops
+ * waiting on cod->done in cryptodev_op() and
+ * cryptodev_aead().
+ */
+ mtx_lock(&cod->cse->lock);
+ cod->done = true;
+ mtx_unlock(&cod->cse->lock);
+ wakeup(cod);
return (0);
}
@@ -1095,6 +1147,7 @@ cryptodev_key(struct crypt_kop *kop)
int in, out, size, i;
if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EFBIG);
}
@@ -1104,30 +1157,38 @@ cryptodev_key(struct crypt_kop *kop)
case CRK_MOD_EXP:
if (in == 3 && out == 1)
break;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
case CRK_MOD_EXP_CRT:
if (in == 6 && out == 1)
break;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
case CRK_DSA_SIGN:
if (in == 5 && out == 2)
break;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
case CRK_DSA_VERIFY:
if (in == 7 && out == 0)
break;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
case CRK_DH_COMPUTE_KEY:
if (in == 3 && out == 1)
break;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
default:
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
}
krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO);
- if (!krp)
+ if (!krp) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (ENOMEM);
+ }
krp->krp_op = kop->crk_op;
krp->krp_status = kop->crk_status;
krp->krp_iparams = kop->crk_iparams;
@@ -1137,9 +1198,11 @@ cryptodev_key(struct crypt_kop *kop)
krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
for (i = 0; i < CRK_MAXPARAM; i++) {
- if (kop->crk_param[i].crp_nbits > 65536)
+ if (kop->crk_param[i].crp_nbits > 65536) {
/* Limit is the same as in OpenBSD */
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail;
+ }
krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
}
for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
@@ -1150,22 +1213,28 @@ cryptodev_key(struct crypt_kop *kop)
if (i >= krp->krp_iparams)
continue;
error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
- if (error)
+ if (error) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail;
+ }
}
error = crypto_kdispatch(krp);
- if (error)
+ if (error) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail;
+ }
error = tsleep(krp, PSOCK, "crydev", 0);
if (error) {
/* XXX can this happen? if so, how do we recover? */
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail;
}
kop->crk_crid = krp->krp_crid; /* device that did the work */
if (krp->krp_status != 0) {
error = krp->krp_status;
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail;
}
@@ -1174,8 +1243,10 @@ cryptodev_key(struct crypt_kop *kop)
if (size == 0)
continue;
error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
- if (error)
+ if (error) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail;
+ }
}
fail:
diff --git a/freebsd/sys/opencrypto/cryptodev.h b/freebsd/sys/opencrypto/cryptodev.h
index cfbda068..f929d10a 100644
--- a/freebsd/sys/opencrypto/cryptodev.h
+++ b/freebsd/sys/opencrypto/cryptodev.h
@@ -425,8 +425,12 @@ struct cryptop {
* if CRYPTO_F_ASYNC flags is set
*/
- caddr_t crp_buf; /* Data to be processed */
- caddr_t crp_opaque; /* Opaque pointer, passed along */
+ union {
+ caddr_t crp_buf; /* Data to be processed */
+ struct mbuf *crp_mbuf;
+ struct uio *crp_uio;
+ };
+ void * crp_opaque; /* Opaque pointer, passed along */
struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
int (*crp_callback)(struct cryptop *); /* Callback function */
@@ -538,5 +542,6 @@ extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
caddr_t out);
extern int crypto_apply(int flags, caddr_t buf, int off, int len,
int (*f)(void *, void *, u_int), void *arg);
+
#endif /* _KERNEL */
#endif /* _CRYPTO_CRYPTO_H_ */
diff --git a/freebsd/sys/opencrypto/cryptosoft.c b/freebsd/sys/opencrypto/cryptosoft.c
index f0858b3c..b2828452 100644
--- a/freebsd/sys/opencrypto/cryptosoft.c
+++ b/freebsd/sys/opencrypto/cryptosoft.c
@@ -609,9 +609,7 @@ swcr_authenc(struct cryptop *crp)
bzero(blk, blksz);
crypto_copydata(crp->crp_flags, buf,
crde->crd_skip + i, len, blk);
- if (!(crde->crd_flags & CRD_F_ENCRYPT)) {
- exf->decrypt(swe->sw_kschedule, blk);
- }
+ exf->decrypt(swe->sw_kschedule, blk);
crypto_copyback(crp->crp_flags, buf,
crde->crd_skip + i, len, blk);
}
@@ -988,7 +986,6 @@ swcr_freesession_locked(device_t dev, u_int64_t tid)
struct swcr_data *swd;
struct enc_xform *txf;
struct auth_hash *axf;
- struct comp_algo *cxf;
u_int32_t sid = CRYPTO_SESID2LID(tid);
if (sid > swcr_sesnum || swcr_sessions == NULL ||
@@ -1063,7 +1060,7 @@ swcr_freesession_locked(device_t dev, u_int64_t tid)
break;
case CRYPTO_DEFLATE_COMP:
- cxf = swd->sw_cxf;
+ /* Nothing to do */
break;
}
diff --git a/freebsd/sys/opencrypto/xform_userland.h b/freebsd/sys/opencrypto/xform_userland.h
index 04266dc8..ef4845aa 100644
--- a/freebsd/sys/opencrypto/xform_userland.h
+++ b/freebsd/sys/opencrypto/xform_userland.h
@@ -34,7 +34,7 @@
#define KMALLOC(size, type, flags) malloc(size, type, flags)
#define KFREE(ptr, type) free(ptr, type)
#else /* not _KERNEL */
-#ifdef _STAND
+#ifdef _STANDALONE
#include <stand.h>
#else /* !_STAND */
#include <stdlib.h>
diff --git a/freebsd/sys/powerpc/include/machine/spr.h b/freebsd/sys/powerpc/include/machine/spr.h
index 3e479415..db94753b 100644
--- a/freebsd/sys/powerpc/include/machine/spr.h
+++ b/freebsd/sys/powerpc/include/machine/spr.h
@@ -199,6 +199,9 @@
#define FSL_E300C3 0x8085
#define FSL_E300C4 0x8086
+#define SPR_LPCR 0x13e /* Logical Partitioning Control */
+#define LPCR_LPES 0x008 /* Bit 60 */
+
#define SPR_EPCR 0x133
#define EPCR_EXTGS 0x80000000
#define EPCR_DTLBGS 0x40000000
@@ -673,19 +676,7 @@
#define PMC970N_CYCLES 0xf /* Processor cycles */
#define PMC970N_ICOMP 0x9 /* Instructions completed */
-#if defined(AIM)
-
-#define SPR_ESR 0x3d4 /* 4.. Exception Syndrome Register */
-#define ESR_MCI 0x80000000 /* Machine check - instruction */
-#define ESR_PIL 0x08000000 /* Program interrupt - illegal */
-#define ESR_PPR 0x04000000 /* Program interrupt - privileged */
-#define ESR_PTR 0x02000000 /* Program interrupt - trap */
-#define ESR_ST 0x01000000 /* Store operation */
-#define ESR_DST 0x00800000 /* Data storage interrupt - store fault */
-#define ESR_DIZ 0x00800000 /* Data/instruction storage interrupt - zone fault */
-#define ESR_U0F 0x00008000 /* Data storage interrupt - U0 fault */
-
-#elif defined(BOOKE)
+#if defined(BOOKE)
#define SPR_MCARU 0x239 /* ..8 Machine Check Address register upper bits */
#define SPR_MCSR 0x23c /* ..8 Machine Check Syndrome register */
diff --git a/freebsd/sys/sys/_domainset.h b/freebsd/sys/sys/_domainset.h
new file mode 100644
index 00000000..30d8501c
--- /dev/null
+++ b/freebsd/sys/sys/_domainset.h
@@ -0,0 +1,60 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2017, Jeffrey Roberson <jeff@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 unmodified, 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 ``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 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 _SYS__DOMAINSET_H_
+#define _SYS__DOMAINSET_H_
+
+#include <sys/_bitset.h>
+
+#ifdef _KERNEL
+#define DOMAINSET_SETSIZE MAXMEMDOM
+#endif
+
+#define DOMAINSET_MAXSIZE 256
+
+#ifndef DOMAINSET_SETSIZE
+#define DOMAINSET_SETSIZE DOMAINSET_MAXSIZE
+#endif
+
+BITSET_DEFINE(_domainset, DOMAINSET_SETSIZE);
+typedef struct _domainset domainset_t;
+
+/*
+ * This structure is intended to be embedded in objects which have policy
+ * attributes. Each object keeps its own iterator so round-robin is
+ * synchronized and accurate.
+ */
+struct domainset;
+struct domainset_ref {
+ struct domainset * volatile dr_policy;
+ int dr_iterator;
+};
+
+#endif /* !_SYS__DOMAINSET_H_ */
diff --git a/freebsd/sys/sys/bus_dma.h b/freebsd/sys/sys/bus_dma.h
index c5799661..2bf46ca8 100644
--- a/freebsd/sys/sys/bus_dma.h
+++ b/freebsd/sys/sys/bus_dma.h
@@ -1,7 +1,7 @@
/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */
/*-
- * SPDX-License-Identifier: BSD-2-Clause-NetBSD
+ * SPDX-License-Identifier: (BSD-2-Clause-NetBSD AND BSD-4-Clause)
*
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -176,6 +176,14 @@ int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
void *lockfuncarg, bus_dma_tag_t *dmat);
+/*
+ * Set the memory domain to be used for allocations.
+ *
+ * Automatic for PCI devices. Must be set prior to creating maps or
+ * allocating memory.
+ */
+int bus_dma_tag_set_domain(bus_dma_tag_t dmat, int domain);
+
int bus_dma_tag_destroy(bus_dma_tag_t dmat);
/*
diff --git a/freebsd/sys/sys/capsicum.h b/freebsd/sys/sys/capsicum.h
index ae466952..847b4478 100644
--- a/freebsd/sys/sys/capsicum.h
+++ b/freebsd/sys/sys/capsicum.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2008-2010, 2015 Robert N. M. Watson
* Copyright (c) 2012 FreeBSD Foundation
* All rights reserved.
diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h
index 7f240f68..3980eba2 100644
--- a/freebsd/sys/sys/conf.h
+++ b/freebsd/sys/sys/conf.h
@@ -367,8 +367,8 @@ struct dumperinfo {
off_t mediasize; /* Space available in bytes. */
void *blockbuf; /* Buffer for padding shorter dump blocks */
off_t dumpoff; /* Offset of ongoing kernel dump. */
- struct kerneldumpcrypto *kdc; /* Kernel dump crypto. */
- struct kerneldumpgz *kdgz; /* Kernel dump compression. */
+ struct kerneldumpcrypto *kdcrypto; /* Kernel dump crypto. */
+ struct kerneldumpcomp *kdcomp; /* Kernel dump compression. */
};
#ifndef __rtems__
diff --git a/freebsd/sys/sys/domainset.h b/freebsd/sys/sys/domainset.h
new file mode 100644
index 00000000..6580e1ed
--- /dev/null
+++ b/freebsd/sys/sys/domainset.h
@@ -0,0 +1,102 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2017, Jeffrey Roberson <jeff@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 unmodified, 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 ``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 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 _SYS_DOMAINSETSET_H_
+#define _SYS_DOMAINSETSET_H_
+
+#include <sys/_domainset.h>
+
+#include <sys/bitset.h>
+
+#define _NDOMAINSETBITS _BITSET_BITS
+#define _NDOMAINSETWORDS __bitset_words(DOMAINSET_SETSIZE)
+
+#define DOMAINSETSETBUFSIZ ((2 + sizeof(long) * 2) * _NDOMAINSETWORDS)
+
+#define DOMAINSET_CLR(n, p) BIT_CLR(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_COPY(f, t) BIT_COPY(DOMAINSET_SETSIZE, f, t)
+#define DOMAINSET_ISSET(n, p) BIT_ISSET(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_SET(n, p) BIT_SET(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_ZERO(p) BIT_ZERO(DOMAINSET_SETSIZE, p)
+#define DOMAINSET_FILL(p) BIT_FILL(DOMAINSET_SETSIZE, p)
+#define DOMAINSET_SETOF(n, p) BIT_SETOF(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_EMPTY(p) BIT_EMPTY(DOMAINSET_SETSIZE, p)
+#define DOMAINSET_ISFULLSET(p) BIT_ISFULLSET(DOMAINSET_SETSIZE, p)
+#define DOMAINSET_SUBSET(p, c) BIT_SUBSET(DOMAINSET_SETSIZE, p, c)
+#define DOMAINSET_OVERLAP(p, c) BIT_OVERLAP(DOMAINSET_SETSIZE, p, c)
+#define DOMAINSET_CMP(p, c) BIT_CMP(DOMAINSET_SETSIZE, p, c)
+#define DOMAINSET_OR(d, s) BIT_OR(DOMAINSET_SETSIZE, d, s)
+#define DOMAINSET_AND(d, s) BIT_AND(DOMAINSET_SETSIZE, d, s)
+#define DOMAINSET_NAND(d, s) BIT_NAND(DOMAINSET_SETSIZE, d, s)
+#define DOMAINSET_CLR_ATOMIC(n, p) BIT_CLR_ATOMIC(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_SET_ATOMIC(n, p) BIT_SET_ATOMIC(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_SET_ATOMIC_ACQ(n, p) \
+ BIT_SET_ATOMIC_ACQ(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_AND_ATOMIC(n, p) BIT_AND_ATOMIC(DOMAINSET_SETSIZE, n, p)
+#define DOMAINSET_OR_ATOMIC(d, s) BIT_OR_ATOMIC(DOMAINSET_SETSIZE, d, s)
+#define DOMAINSET_COPY_STORE_REL(f, t) \
+ BIT_COPY_STORE_REL(DOMAINSET_SETSIZE, f, t)
+#define DOMAINSET_FFS(p) BIT_FFS(DOMAINSET_SETSIZE, p)
+#define DOMAINSET_FLS(p) BIT_FLS(DOMAINSET_SETSIZE, p)
+#define DOMAINSET_COUNT(p) BIT_COUNT(DOMAINSET_SETSIZE, p)
+#define DOMAINSET_FSET BITSET_FSET(_NDOMAINSETWORDS)
+#define DOMAINSET_T_INITIALIZER BITSET_T_INITIALIZER
+
+#define DOMAINSET_POLICY_INVALID 0
+#define DOMAINSET_POLICY_ROUNDROBIN 1
+#define DOMAINSET_POLICY_FIRSTTOUCH 2
+#define DOMAINSET_POLICY_PREFER 3
+#define DOMAINSET_POLICY_MAX DOMAINSET_POLICY_PREFER
+
+#ifdef _KERNEL
+#include <sys/queue.h>
+LIST_HEAD(domainlist, domainset);
+
+struct domainset {
+ LIST_ENTRY(domainset) ds_link;
+ domainset_t ds_mask; /* allowed domains. */
+ uint16_t ds_policy; /* Policy type. */
+ int16_t ds_prefer; /* Preferred domain or -1. */
+ uint16_t ds_cnt; /* popcnt from above. */
+ uint16_t ds_max; /* Maximum domain in set. */
+};
+
+void domainset_zero(void);
+
+#else
+__BEGIN_DECLS
+int cpuset_getdomain(cpulevel_t, cpuwhich_t, id_t, size_t, domainset_t *,
+ int *);
+int cpuset_setdomain(cpulevel_t, cpuwhich_t, id_t, size_t,
+ const domainset_t *, int);
+
+__END_DECLS
+#endif
+#endif /* !_SYS_DOMAINSETSET_H_ */
diff --git a/freebsd/sys/sys/gtaskqueue.h b/freebsd/sys/sys/gtaskqueue.h
index e8519637..41094603 100644
--- a/freebsd/sys/sys/gtaskqueue.h
+++ b/freebsd/sys/sys/gtaskqueue.h
@@ -1,6 +1,8 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2014 Jeffrey Roberson <jeff@freebsd.org>
- * Copyright (c) 2016 Matthew Macy <mmacy@nextbsd.org>
+ * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/freebsd/sys/sys/kernel.h b/freebsd/sys/sys/kernel.h
index 1cc03275..81ceca04 100644
--- a/freebsd/sys/sys/kernel.h
+++ b/freebsd/sys/sys/kernel.h
@@ -54,6 +54,9 @@
/* for intrhook below */
#include <sys/queue.h>
+/* for timestamping SYSINITs; other files may assume this is included here */
+#include <sys/tslog.h>
+
/* Global variables for the kernel. */
#ifndef __rtems__
@@ -240,6 +243,35 @@ struct sysinit {
* correct warnings when -Wcast-qual is used.
*
*/
+#ifdef TSLOG
+struct sysinit_tslog {
+ sysinit_cfunc_t func;
+ const void * data;
+ const char * name;
+};
+static inline void
+sysinit_tslog_shim(const void * data)
+{
+ const struct sysinit_tslog * x = data;
+
+ TSRAW(curthread, TS_ENTER, "SYSINIT", x->name);
+ (x->func)(x->data);
+ TSRAW(curthread, TS_EXIT, "SYSINIT", x->name);
+}
+#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \
+ static struct sysinit_tslog uniquifier ## _sys_init_tslog = { \
+ func, \
+ (ident), \
+ #uniquifier \
+ }; \
+ static struct sysinit uniquifier ## _sys_init = { \
+ subsystem, \
+ order, \
+ sysinit_tslog_shim, \
+ &uniquifier ## _sys_init_tslog \
+ }; \
+ DATA_SET(sysinit_set,uniquifier ## _sys_init)
+#else
#ifndef __rtems__
#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \
static struct sysinit uniquifier ## _sys_init = { \
@@ -274,6 +306,7 @@ struct sysinit {
#define SYSINIT_DOMAIN_REFERENCE(dom) \
SYSINIT_REFERENCE(domain_add_ ## dom)
#endif /* __rtems__ */
+#endif
#define SYSINIT(uniquifier, subsystem, order, func, ident) \
C_SYSINIT(uniquifier, subsystem, order, \
diff --git a/freebsd/sys/sys/libkern.h b/freebsd/sys/sys/libkern.h
index 4d043f5a..dc24036b 100644
--- a/freebsd/sys/sys/libkern.h
+++ b/freebsd/sys/sys/libkern.h
@@ -86,6 +86,13 @@ hex2ascii(int hex)
return (hex2ascii_data[hex]);
}
+static inline bool
+validbcd(int bcd)
+{
+
+ return (bcd == 0 || (bcd > 0 && bcd <= 0x99 && bcd2bin_data[bcd] != 0));
+}
+
static __inline int imax(int a, int b) { return (a > b ? a : b); }
static __inline int imin(int a, int b) { return (a < b ? a : b); }
static __inline long lmax(long a, long b) { return (a > b ? a : b); }
diff --git a/freebsd/sys/sys/malloc.h b/freebsd/sys/sys/malloc.h
index c5ab6125..1920ff69 100644
--- a/freebsd/sys/sys/malloc.h
+++ b/freebsd/sys/sys/malloc.h
@@ -41,6 +41,7 @@
#include <sys/queue.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
+#include <machine/_limits.h>
#define MINALLOCSIZE UMA_SMALLEST_UNIT
@@ -156,13 +157,6 @@ MALLOC_DECLARE(M_DEVBUF);
MALLOC_DECLARE(M_TEMP);
/*
- * Deprecated macro versions of not-quite-malloc() and free().
- */
-#define MALLOC(space, cast, size, type, flags) \
- ((space) = (cast)malloc((u_long)(size), (type), (flags)))
-#define FREE(addr, type) free((addr), (type))
-
-/*
* XXX this should be declared in <sys/uio.h>, but that tends to fail
* because <sys/uio.h> is included in a header before the source file
* has a chance to include <sys/malloc.h> to get MALLOC_DECLARE() defined.
@@ -181,21 +175,45 @@ void *contigmalloc(unsigned long size, struct malloc_type *type, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
vm_paddr_t boundary) __malloc_like __result_use_check
__alloc_size(1) __alloc_align(6);
+void *contigmalloc_domain(unsigned long size, struct malloc_type *type,
+ int domain, int flags, vm_paddr_t low, vm_paddr_t high,
+ unsigned long alignment, vm_paddr_t boundary)
+ __malloc_like __result_use_check __alloc_size(1) __alloc_align(6);
void free(void *addr, struct malloc_type *type);
-void *malloc(unsigned long size, struct malloc_type *type, int flags)
- __malloc_like __result_use_check __alloc_size(1);
+void free_domain(void *addr, struct malloc_type *type);
+void *malloc(size_t size, struct malloc_type *type, int flags) __malloc_like
+ __result_use_check __alloc_size(1);
+void *malloc_domain(size_t size, struct malloc_type *type, int domain,
+ int flags) __malloc_like __result_use_check __alloc_size(1);
+void *mallocarray(size_t nmemb, size_t size, struct malloc_type *type,
+ int flags) __malloc_like __result_use_check
+ __alloc_size2(1, 2);
void malloc_init(void *);
int malloc_last_fail(void);
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
void malloc_type_freed(struct malloc_type *type, unsigned long size);
void malloc_type_list(malloc_type_list_func_t *, void *);
void malloc_uninit(void *);
-void *realloc(void *addr, unsigned long size, struct malloc_type *type,
- int flags) __result_use_check __alloc_size(2);
-void *reallocf(void *addr, unsigned long size, struct malloc_type *type,
- int flags) __alloc_size(2);
+void *realloc(void *addr, size_t size, struct malloc_type *type, int flags)
+ __result_use_check __alloc_size(2);
+void *reallocf(void *addr, size_t size, struct malloc_type *type, int flags)
+ __result_use_check __alloc_size(2);
struct malloc_type *malloc_desc2type(const char *desc);
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 8 / 2))
+static inline bool
+WOULD_OVERFLOW(size_t nmemb, size_t size)
+{
+
+ return ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && __SIZE_T_MAX / nmemb < size);
+}
+#undef MUL_NO_OVERFLOW
#endif /* _KERNEL */
#endif /* !_SYS_MALLOC_H_ */
diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h
index 362c54e9..9d499004 100644
--- a/freebsd/sys/sys/mount.h
+++ b/freebsd/sys/sys/mount.h
@@ -40,6 +40,7 @@
#ifdef _KERNEL
#include <sys/lock.h>
#include <sys/lockmgr.h>
+#include <sys/tslog.h>
#include <sys/_mutex.h>
#include <sys/_sx.h>
#endif
@@ -708,9 +709,11 @@ vfs_statfs_t __vfs_statfs;
#define VFS_MOUNT(MP) ({ \
int _rc; \
\
+ TSRAW(curthread, TS_ENTER, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\
VFS_PROLOGUE(MP); \
_rc = (*(MP)->mnt_op->vfs_mount)(MP); \
VFS_EPILOGUE(MP); \
+ TSRAW(curthread, TS_EXIT, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\
_rc; })
#define VFS_UNMOUNT(MP, FORCE) ({ \
diff --git a/freebsd/sys/sys/mouse.h b/freebsd/sys/sys/mouse.h
index 9fd1d6d8..a1f950cf 100644
--- a/freebsd/sys/sys/mouse.h
+++ b/freebsd/sys/sys/mouse.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-1-Clause
+ *
* Copyright (c) 1992, 1993 Erik Forsberg.
* Copyright (c) 1996, 1997 Kazutaka YOKOTA
* All rights reserved.
@@ -135,6 +137,7 @@ typedef struct synapticshw {
int maximumYCoord;
int infoXupmm;
int infoYupmm;
+ int forcePad;
} synapticshw_t;
/* iftype */
diff --git a/freebsd/sys/sys/nv.h b/freebsd/sys/sys/nv.h
index fcea2b3e..bf40f8f3 100644
--- a/freebsd/sys/sys/nv.h
+++ b/freebsd/sys/sys/nv.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2009-2013 The FreeBSD Foundation
* Copyright (c) 2013-2015 Mariusz Zaborski <oshogbo@FreeBSD.org>
* All rights reserved.
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index 7178c316..ab292769 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -62,11 +62,18 @@
#include <sys/time.h> /* For structs itimerval, timeval. */
#else
#include <sys/pcpu.h>
+#include <sys/systm.h>
#endif
#include <sys/ucontext.h>
#include <sys/ucred.h>
-#include <sys/_vm_domain.h>
+#include <sys/types.h>
+#include <sys/domainset.h>
+
#include <machine/proc.h> /* Machine-dependent proc substruct. */
+#ifdef _KERNEL
+#include <machine/cpu.h>
+#endif
+
/*
* One structure allocated per session.
@@ -179,11 +186,14 @@ struct procdesc;
struct racct;
struct sbuf;
struct sleepqueue;
+struct socket;
struct syscall_args;
struct td_sched;
struct thread;
struct trapframe;
struct turnstile;
+struct vm_map;
+struct vm_map_entry;
/*
* XXX: Does this belong in resource.h or resourcevar.h instead?
@@ -239,6 +249,7 @@ struct thread {
TAILQ_ENTRY(thread) td_lockq; /* (t) Lock queue. */
LIST_ENTRY(thread) td_hash; /* (d) Hash chain. */
struct cpuset *td_cpuset; /* (t) CPU affinity mask. */
+ struct domainset_ref td_domain; /* (a) NUMA policy */
#endif /* __rtems__ */
struct seltd *td_sel; /* Select queue/channel. */
struct sleepqueue *td_sleepqueue; /* (k) Associated sleep queue. */
@@ -246,7 +257,6 @@ struct thread {
struct turnstile *td_turnstile; /* (k) Associated turnstile. */
struct rl_q_entry *td_rlqe; /* (k) Associated range lock entry. */
struct umtx_q *td_umtxq; /* (c?) Link for when we're blocked. */
- struct vm_domain_policy td_vm_dom_policy; /* (c) current numa domain policy */
lwpid_t td_tid; /* (b) Thread ID. */
sigqueue_t td_sigqueue; /* (c) Sigs arrived, not delivered. */
#define td_siglist td_sigqueue.sq_signals
@@ -315,7 +325,6 @@ struct thread {
pid_t td_dbg_forked; /* (c) Child pid for debugger. */
u_int td_vp_reserv; /* (k) Count of reserved vnodes. */
int td_no_sleeping; /* (k) Sleeping disabled count. */
- int td_dom_rr_idx; /* (k) RR Numa domain selection. */
void *td_su; /* (k) FFS SU private */
sbintime_t td_sleeptimo; /* (t) Sleep timeout. */
int td_rtcgen; /* (s) rtc_generation of abs. sleep */
@@ -698,7 +707,6 @@ struct proc {
uint64_t p_prev_runtime; /* (c) Resource usage accounting. */
struct racct *p_racct; /* (b) Resource accounting. */
int p_throttled; /* (c) Flag for racct pcpu throttling */
- struct vm_domain_policy p_vm_dom_policy; /* (c) process default VM domain, or -1 */
/*
* An orphan is the child that has beed re-parented to the
* debugger as a result of attaching to it. Need to keep
@@ -1060,6 +1068,8 @@ void fork_exit(void (*)(void *, struct trapframe *), void *,
struct trapframe *);
void fork_return(struct thread *, struct trapframe *);
int inferior(struct proc *p);
+void kern_proc_vmmap_resident(struct vm_map *map, struct vm_map_entry *entry,
+ int *resident_count, bool *super);
#ifndef __rtems__
void kern_yield(int);
void kick_proc0(void);
diff --git a/freebsd/sys/sys/random.h b/freebsd/sys/sys/random.h
index b022f5a3..78acaf9d 100644
--- a/freebsd/sys/sys/random.h
+++ b/freebsd/sys/sys/random.h
@@ -104,6 +104,7 @@ enum random_entropy_source {
RANDOM_PURE_RNDTEST,
RANDOM_PURE_VIRTIO,
RANDOM_PURE_BROADCOM,
+ RANDOM_PURE_CCP,
ENTROPYSOURCE
};
diff --git a/freebsd/sys/sys/rman.h b/freebsd/sys/sys/rman.h
index 4de6022f..9c2f4653 100644
--- a/freebsd/sys/sys/rman.h
+++ b/freebsd/sys/sys/rman.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: MIT
+ *
* Copyright 1998 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, and distribute this software and
diff --git a/freebsd/sys/sys/sf_buf.h b/freebsd/sys/sys/sf_buf.h
index 08f1d9d7..b4ea671a 100644
--- a/freebsd/sys/sys/sf_buf.h
+++ b/freebsd/sys/sys/sf_buf.h
@@ -77,9 +77,6 @@ struct sfstat { /* sendfile statistics */
* that do no invalidate cache on the rest of CPUs.
* SFBUF_NOMD This machine doesn't have machine/sf_buf.h
*
- * SFBUF_OPTIONAL_DIRECT_MAP Value of this define is used as boolean
- * variable that tells whether machine is
- * capable of direct map or not at runtime.
* SFBUF_MAP This machine provides its own sf_buf_map() and
* sf_buf_unmap().
* SFBUF_PROCESS_PAGE This machine provides sf_buf_process_page()
@@ -109,9 +106,6 @@ struct sf_buf;
#ifndef SFBUF_NOMD
#include <machine/sf_buf.h>
#endif
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
-#include <machine/md_var.h>
-#endif
#ifdef SFBUF
struct sf_buf *sf_buf_alloc(struct vm_page *, int);
@@ -121,10 +115,8 @@ void sf_buf_ref(struct sf_buf *);
static inline vm_offset_t
sf_buf_kva(struct sf_buf *sf)
{
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
- return (SFBUF_PHYS_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf)));
-#endif
+ if (PMAP_HAS_DMAP)
+ return (PHYS_TO_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf)));
return (sf->kva);
}
@@ -132,10 +124,8 @@ sf_buf_kva(struct sf_buf *sf)
static inline vm_page_t
sf_buf_page(struct sf_buf *sf)
{
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
+ if (PMAP_HAS_DMAP)
return ((vm_page_t)sf);
-#endif
return (sf->m);
}
diff --git a/freebsd/sys/sys/smp.h b/freebsd/sys/sys/smp.h
index f1950fa2..aa0c3119 100644
--- a/freebsd/sys/sys/smp.h
+++ b/freebsd/sys/sys/smp.h
@@ -155,10 +155,13 @@ struct cpu_group *smp_topo_find(struct cpu_group *top, int cpu);
extern void (*cpustop_restartfunc)(void);
extern int smp_cpus;
-extern volatile cpuset_t started_cpus;
-extern volatile cpuset_t stopped_cpus;
-extern volatile cpuset_t suspended_cpus;
-extern cpuset_t hlt_cpus_mask;
+/* The suspend/resume cpusets are x86 only, but minimize ifdefs. */
+extern volatile cpuset_t resuming_cpus; /* woken up cpus in suspend pen */
+extern volatile cpuset_t started_cpus; /* cpus to let out of stop pen */
+extern volatile cpuset_t stopped_cpus; /* cpus in stop pen */
+extern volatile cpuset_t suspended_cpus; /* cpus [near] sleeping in susp pen */
+extern volatile cpuset_t toresume_cpus; /* cpus to let out of suspend pen */
+extern cpuset_t hlt_cpus_mask; /* XXX 'mask' is detail in old impl */
extern cpuset_t logical_cpus_mask;
#endif /* SMP */
diff --git a/freebsd/sys/sys/socketvar.h b/freebsd/sys/sys/socketvar.h
index d58ac2ea..f877a0df 100644
--- a/freebsd/sys/sys/socketvar.h
+++ b/freebsd/sys/sys/socketvar.h
@@ -71,7 +71,7 @@ struct socket;
* (a) constant after allocation, no locking required.
* (b) locked by SOCK_LOCK(so).
* (cr) locked by SOCKBUF_LOCK(&so->so_rcv).
- * (cs) locked by SOCKBUF_LOCK(&so->so_rcv).
+ * (cs) locked by SOCKBUF_LOCK(&so->so_snd).
* (e) locked by SOLISTEN_LOCK() of corresponding listening socket.
* (f) not locked since integer reads/writes are atomic.
* (g) used only as a sleep/wakeup address, no value.
diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h
index d5cda835..9148a395 100644
--- a/freebsd/sys/sys/sysproto.h
+++ b/freebsd/sys/sys/sysproto.h
@@ -11,6 +11,7 @@
#include <sys/signal.h>
#include <sys/acl.h>
#include <sys/cpuset.h>
+#include <sys/domainset.h>
#include <sys/_ffcounter.h>
#include <sys/_semaphore.h>
#include <sys/ucontext.h>
@@ -1738,16 +1739,6 @@ struct utimensat_args {
char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)];
char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)];
};
-struct numa_getaffinity_args {
- char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
- char policy_l_[PADL_(struct vm_domain_policy_entry *)]; struct vm_domain_policy_entry * policy; char policy_r_[PADR_(struct vm_domain_policy_entry *)];
-};
-struct numa_setaffinity_args {
- char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
- char policy_l_[PADL_(const struct vm_domain_policy_entry *)]; const struct vm_domain_policy_entry * policy; char policy_r_[PADR_(const struct vm_domain_policy_entry *)];
-};
struct fdatasync_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
};
@@ -1808,6 +1799,22 @@ struct kevent_args {
char timeout_l_[PADL_(const struct timespec *)]; const struct timespec * timeout; char timeout_r_[PADR_(const struct timespec *)];
};
#ifndef __rtems__
+struct cpuset_getdomain_args {
+ char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
+ char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
+ char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+ char domainsetsize_l_[PADL_(size_t)]; size_t domainsetsize; char domainsetsize_r_[PADR_(size_t)];
+ char mask_l_[PADL_(domainset_t *)]; domainset_t * mask; char mask_r_[PADR_(domainset_t *)];
+ char policy_l_[PADL_(int *)]; int * policy; char policy_r_[PADR_(int *)];
+};
+struct cpuset_setdomain_args {
+ char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
+ char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
+ char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+ char domainsetsize_l_[PADL_(size_t)]; size_t domainsetsize; char domainsetsize_r_[PADR_(size_t)];
+ char mask_l_[PADL_(domainset_t *)]; domainset_t * mask; char mask_r_[PADR_(domainset_t *)];
+ char policy_l_[PADL_(int)]; int policy; char policy_r_[PADR_(int)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *);
@@ -2175,8 +2182,6 @@ int sys_procctl(struct thread *, struct procctl_args *);
int sys_ppoll(struct thread *, struct ppoll_args *);
int sys_futimens(struct thread *, struct futimens_args *);
int sys_utimensat(struct thread *, struct utimensat_args *);
-int sys_numa_getaffinity(struct thread *, struct numa_getaffinity_args *);
-int sys_numa_setaffinity(struct thread *, struct numa_setaffinity_args *);
int sys_fdatasync(struct thread *, struct fdatasync_args *);
int sys_fstat(struct thread *, struct fstat_args *);
int sys_fstatat(struct thread *, struct fstatat_args *);
@@ -2188,6 +2193,8 @@ int sys_getfsstat(struct thread *, struct getfsstat_args *);
int sys_fhstatfs(struct thread *, struct fhstatfs_args *);
int sys_mknodat(struct thread *, struct mknodat_args *);
int sys_kevent(struct thread *, struct kevent_args *);
+int sys_cpuset_getdomain(struct thread *, struct cpuset_getdomain_args *);
+int sys_cpuset_setdomain(struct thread *, struct cpuset_setdomain_args *);
#ifdef COMPAT_43
@@ -3067,8 +3074,6 @@ int freebsd11_mknodat(struct thread *, struct freebsd11_mknodat_args *);
#define SYS_AUE_ppoll AUE_POLL
#define SYS_AUE_futimens AUE_FUTIMES
#define SYS_AUE_utimensat AUE_FUTIMESAT
-#define SYS_AUE_numa_getaffinity AUE_NULL
-#define SYS_AUE_numa_setaffinity AUE_NULL
#define SYS_AUE_fdatasync AUE_FSYNC
#define SYS_AUE_fstat AUE_FSTAT
#define SYS_AUE_fstatat AUE_FSTATAT
@@ -3080,6 +3085,8 @@ int freebsd11_mknodat(struct thread *, struct freebsd11_mknodat_args *);
#define SYS_AUE_fhstatfs AUE_FHSTATFS
#define SYS_AUE_mknodat AUE_MKNODAT
#define SYS_AUE_kevent AUE_KEVENT
+#define SYS_AUE_cpuset_getdomain AUE_NULL
+#define SYS_AUE_cpuset_setdomain AUE_NULL
#endif /* __rtems__ */
#undef PAD_
diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h
index e89719b8..2dfe959b 100644
--- a/freebsd/sys/sys/systm.h
+++ b/freebsd/sys/sys/systm.h
@@ -610,6 +610,22 @@ void intr_prof_stack_use(struct thread *td, struct trapframe *frame);
void counted_warning(unsigned *counter, const char *msg);
+/*
+ * APIs to manage deprecation and obsolescence.
+ */
+struct device;
+void _gone_in(int major, const char *msg);
+void _gone_in_dev(struct device *dev, int major, const char *msg);
+#ifdef NO_OBSOLETE_CODE
+#define __gone_ok(m, msg) \
+ _Static_assert(m < P_OSREL_MAJOR(__FreeBSD_version)), \
+ "Obsolete code" msg);
+#else
+#define __gone_ok(m, msg)
+#endif
+#define gone_in(major, msg) __gone_ok(major, msg) _gone_in(major, msg)
+#define gone_in_dev(dev, major, msg) __gone_ok(major, msg) _gone_in_dev(dev, major, msg)
+
__NULLABILITY_PRAGMA_POP
#endif /* !_SYS_SYSTM_H_ */
diff --git a/freebsd/sys/sys/tslog.h b/freebsd/sys/sys/tslog.h
new file mode 100644
index 00000000..4b2971e4
--- /dev/null
+++ b/freebsd/sys/sys/tslog.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2017 Colin Percival
+ * 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 ``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 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 _TSLOG_H_
+#define _TSLOG_H_
+
+#ifdef TSLOG
+#include <sys/_types.h>
+#include <sys/pcpu.h>
+#endif
+
+#define TS_ENTER 0
+#define TS_EXIT 1
+#define TS_THREAD 2
+#define TS_EVENT 3
+
+#define TSENTER() TSRAW(curthread, TS_ENTER, __func__, NULL)
+#define TSENTER2(x) TSRAW(curthread, TS_ENTER, __func__, x)
+#define TSEXIT() TSRAW(curthread, TS_EXIT, __func__, NULL)
+#define TSEXIT2(x) TSRAW(curthread, TS_EXIT, __func__, x)
+#define TSTHREAD(td, x) TSRAW(td, TS_THREAD, x, NULL)
+#define TSEVENT(x) TSRAW(curthread, TS_EVENT, x, NULL)
+#define TSEVENT2(x, y) TSRAW(curthread, TS_EVENT, x, y)
+#define TSLINE() TSEVENT2(__FILE__, __XSTRING(__LINE__))
+#define TSWAIT(x) TSEVENT2("WAIT", x);
+#define TSUNWAIT(x) TSEVENT2("UNWAIT", x);
+#define TSHOLD(x) TSEVENT2("HOLD", x);
+#define TSRELEASE(x) TSEVENT2("RELEASE", x);
+
+#ifdef TSLOG
+#define TSRAW(a, b, c, d) tslog(a, b, c, d)
+void tslog(void *, int, const char *, const char *);
+#else
+#define TSRAW(a, b, c, d) /* Timestamp logging disabled */
+#endif
+
+#endif /* _TSLOG_H_ */
diff --git a/freebsd/sys/sys/vmmeter.h b/freebsd/sys/sys/vmmeter.h
index 33d96b26..901604ae 100644
--- a/freebsd/sys/sys/vmmeter.h
+++ b/freebsd/sys/sys/vmmeter.h
@@ -41,7 +41,6 @@
*/
#define MAXSLP 20
-/* Systemwide totals computed every five seconds. */
struct vmtotal {
uint64_t t_vm; /* total virtual memory */
uint64_t t_avm; /* active virtual memory */
@@ -53,12 +52,12 @@ struct vmtotal {
uint64_t t_armshr; /* active shared real memory */
uint64_t t_free; /* free memory pages */
int16_t t_rq; /* length of the run queue */
- int16_t t_dw; /* jobs in ``disk wait'' (neg
+ int16_t t_dw; /* threads in ``disk wait'' (neg
priority) */
- int16_t t_pw; /* jobs in page wait */
- int16_t t_sl; /* jobs sleeping in core */
+ int16_t t_pw; /* threads in page wait */
+ int16_t t_sl; /* threads sleeping in core */
int16_t t_sw; /* swapped out runnable/short
- block jobs */
+ block threads */
uint16_t t_pad[3];
};
diff --git a/freebsd/sys/sys/watchdog.h b/freebsd/sys/sys/watchdog.h
index 1b85ce7a..191456a4 100644
--- a/freebsd/sys/sys/watchdog.h
+++ b/freebsd/sys/sys/watchdog.h
@@ -112,6 +112,14 @@ EVENTHANDLER_DECLARE(watchdog_list, watchdog_fn);
u_int wdog_kern_last_timeout(void);
int wdog_kern_pat(u_int utim);
+
+/*
+ * The following function pointer is used to attach a software watchdog
+ * if no hardware watchdog has been attached, and if the software module
+ * has initialized the function pointer.
+ */
+
+extern void (*wdog_software_attach)(void);
#endif
#endif /* _SYS_WATCHDOG_H */
diff --git a/freebsd/sys/vm/uma.h b/freebsd/sys/vm/uma.h
index 6fbe6588..2f80a448 100644
--- a/freebsd/sys/vm/uma.h
+++ b/freebsd/sys/vm/uma.h
@@ -128,7 +128,8 @@ typedef void (*uma_fini)(void *mem, int size);
/*
* Import new memory into a cache zone.
*/
-typedef int (*uma_import)(void *arg, void **store, int count, int flags);
+typedef int (*uma_import)(void *arg, void **store, int count, int domain,
+ int flags);
/*
* Free memory from a cache zone.
@@ -281,6 +282,10 @@ uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor,
* Allocates mp_maxid + 1 slabs sized to
* sizeof(struct pcpu).
*/
+#define UMA_ZONE_NUMA 0x10000 /*
+ * NUMA aware Zone. Implements a best
+ * effort first-touch policy.
+ */
/*
* These flags are shared between the keg and zone. In zones wishing to add
@@ -326,6 +331,19 @@ void uma_zdestroy(uma_zone_t zone);
void *uma_zalloc_arg(uma_zone_t zone, void *arg, int flags);
/*
+ * Allocate an item from a specific NUMA domain. This uses a slow path in
+ * the allocator but is guaranteed to allocate memory from the requested
+ * domain if M_WAITOK is set.
+ *
+ * Arguments:
+ * zone The zone we are allocating from
+ * arg This data is passed to the ctor function
+ * domain The domain to allocate from.
+ * flags See sys/malloc.h for available flags.
+ */
+void *uma_zalloc_domain(uma_zone_t zone, void *arg, int domain, int flags);
+
+/*
* Allocates an item out of a zone without supplying an argument
*
* This is just a wrapper for uma_zalloc_arg for convenience.
@@ -354,6 +372,16 @@ uma_zalloc(uma_zone_t zone, int flags)
void uma_zfree_arg(uma_zone_t zone, void *item, void *arg);
/*
+ * Frees an item back to the specified zone's domain specific pool.
+ *
+ * Arguments:
+ * zone The zone the item was originally allocated out of.
+ * item The memory to be freed.
+ * arg Argument passed to the destructor
+ */
+void uma_zfree_domain(uma_zone_t zone, void *item, void *arg);
+
+/*
* Frees an item back to a zone without supplying an argument
*
* This is just a wrapper for uma_zfree_arg for convenience.
@@ -373,25 +401,21 @@ uma_zfree(uma_zone_t zone, void *item)
void uma_zwait(uma_zone_t zone);
/*
- * XXX The rest of the prototypes in this header are h0h0 magic for the VM.
- * If you think you need to use it for a normal zone you're probably incorrect.
- */
-
-/*
* Backend page supplier routines
*
* Arguments:
* zone The zone that is requesting pages.
* size The number of bytes being requested.
* pflag Flags for these memory pages, see below.
+ * domain The NUMA domain that we prefer for this allocation.
* wait Indicates our willingness to block.
*
* Returns:
* A pointer to the allocated memory or NULL on failure.
*/
-typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, uint8_t *pflag,
- int wait);
+typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, int domain,
+ uint8_t *pflag, int wait);
/*
* Backend page free routines
@@ -406,8 +430,6 @@ typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, uint8_t *pflag,
*/
typedef void (*uma_free)(void *item, vm_size_t size, uint8_t pflag);
-
-
/*
* Sets up the uma allocator. (Called by vm_mem_init)
*
@@ -702,6 +724,14 @@ struct uma_percpu_stat {
void uma_reclaim_wakeup(void);
void uma_reclaim_worker(void *);
+unsigned long uma_limit(void);
+
+/* Return the amount of memory managed by UMA. */
+unsigned long uma_size(void);
+
+/* Return the amount of memory remaining. May be negative. */
+long uma_avail(void);
+
#ifdef __rtems__
void rtems_uma_drain_timeout(void);
#endif /* __rtems__ */
diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c
index 3d4abec0..a1c45c93 100644
--- a/freebsd/sys/vm/uma_core.c
+++ b/freebsd/sys/vm/uma_core.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/types.h>
+#include <sys/limits.h>
#include <sys/queue.h>
#include <sys/malloc.h>
#include <sys/ktr.h>
@@ -84,6 +85,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <vm/vm_param.h>
+#include <vm/vm_phys.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
@@ -93,21 +95,28 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#ifdef __rtems__
- #include <rtems/bsd/bsd.h>
-
- #ifdef RTEMS_SMP
- #include <rtems/score/smp.h>
-
- /*
- * It is essential that we have a per-processor cache, otherwise the
- * critical_enter()/critical_exit() protection would be insufficient.
- */
- #undef curcpu
- #define curcpu _SMP_Get_current_processor()
- #undef mp_maxid
- #define mp_maxid (rtems_get_processor_count() - 1)
- #define SMP
- #endif
+#include <rtems/bsd/bsd.h>
+#include <rtems/malloc.h>
+#include <rtems.h>
+
+#undef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE CPU_CACHE_LINE_BYTES
+
+#ifdef RTEMS_SMP
+#include <rtems/score/smp.h>
+
+/*
+* It is essential that we have a per-processor cache, otherwise the
+* critical_enter()/critical_exit() protection would be insufficient.
+*/
+#undef curcpu
+#define curcpu _SMP_Get_current_processor()
+#undef mp_maxid
+#define mp_maxid (rtems_get_processor_count() - 1)
+#undef mp_ncpus
+#define mp_ncpus rtems_get_processor_count()
+#define SMP
+#endif /* RTEMS_SMP */
#endif /* __rtems__ */
#ifdef DEBUG_MEMGUARD
@@ -115,17 +124,12 @@ __FBSDID("$FreeBSD$");
#endif
/*
- * This is the zone and keg from which all zones are spawned. The idea is that
- * even the zone & keg heads are allocated from the allocator, so we use the
- * bss section to bootstrap us.
+ * This is the zone and keg from which all zones are spawned.
*/
-static struct uma_keg masterkeg;
-static struct uma_zone masterzone_k;
-static struct uma_zone masterzone_z;
-static uma_zone_t kegs = &masterzone_k;
-static uma_zone_t zones = &masterzone_z;
+static uma_zone_t kegs;
+static uma_zone_t zones;
-/* This is the zone from which all of uma_slab_t's are allocated. */
+/* This is the zone from which all offpage uma_slab_ts are allocated. */
static uma_zone_t slabzone;
/*
@@ -173,7 +177,7 @@ static struct mtx uma_boot_pages_mtx;
static struct sx uma_drain_lock;
/* kmem soft limit. */
-static unsigned long uma_kmem_limit;
+static unsigned long uma_kmem_limit = LONG_MAX;
static volatile unsigned long uma_kmem_total;
#ifndef __rtems__
@@ -258,17 +262,19 @@ struct uma_bucket_zone bucket_zones[] = {
*/
enum zfreeskip { SKIP_NONE = 0, SKIP_DTOR, SKIP_FINI };
+#define UMA_ANYDOMAIN -1 /* Special value for domain search. */
+
/* Prototypes.. */
#ifndef __rtems__
-static void *noobj_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
+static void *noobj_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
#endif /* __rtems__ */
-static void *page_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
+static void *page_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
#ifndef __rtems__
-static void *startup_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
+static void *startup_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
#endif /* __rtems__ */
static void page_free(void *, vm_size_t, uint8_t);
-static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int);
+static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int, int);
static void cache_drain(uma_zone_t);
static void bucket_drain(uma_zone_t, uma_bucket_t);
static void bucket_cache_drain(uma_zone_t zone);
@@ -286,25 +292,25 @@ static int hash_expand(struct uma_hash *, struct uma_hash *);
static void hash_free(struct uma_hash *hash);
static void uma_timeout(void *);
static void uma_startup3(void);
-static void *zone_alloc_item(uma_zone_t, void *, int);
+static void *zone_alloc_item(uma_zone_t, void *, int, int);
static void zone_free_item(uma_zone_t, void *, void *, enum zfreeskip);
static void bucket_enable(void);
static void bucket_init(void);
static uma_bucket_t bucket_alloc(uma_zone_t zone, void *, int);
static void bucket_free(uma_zone_t zone, uma_bucket_t, void *);
static void bucket_zone_drain(void);
-static uma_bucket_t zone_alloc_bucket(uma_zone_t zone, void *, int flags);
-static uma_slab_t zone_fetch_slab(uma_zone_t zone, uma_keg_t last, int flags);
+static uma_bucket_t zone_alloc_bucket(uma_zone_t, void *, int, int);
+static uma_slab_t zone_fetch_slab(uma_zone_t, uma_keg_t, int, int);
#ifndef __rtems__
-static uma_slab_t zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int flags);
+static uma_slab_t zone_fetch_slab_multi(uma_zone_t, uma_keg_t, int, int);
#endif /* __rtems__ */
static void *slab_alloc_item(uma_keg_t keg, uma_slab_t slab);
static void slab_free_item(uma_keg_t keg, uma_slab_t slab, void *item);
static uma_keg_t uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit,
uma_fini fini, int align, uint32_t flags);
-static int zone_import(uma_zone_t zone, void **bucket, int max, int flags);
-static void zone_release(uma_zone_t zone, void **bucket, int cnt);
-static void uma_zero_item(void *item, uma_zone_t zone);
+static int zone_import(uma_zone_t, void **, int, int, int);
+static void zone_release(uma_zone_t, void **, int);
+static void uma_zero_item(void *, uma_zone_t);
void uma_print_zone(uma_zone_t);
void uma_print_stats(void);
@@ -372,7 +378,7 @@ bucket_init(void)
size += sizeof(void *) * ubz->ubz_entries;
ubz->ubz_zone = uma_zcreate(ubz->ubz_name, size,
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
- UMA_ZONE_MTXCLASS | UMA_ZFLAG_BUCKET);
+ UMA_ZONE_MTXCLASS | UMA_ZFLAG_BUCKET | UMA_ZONE_NUMA);
}
}
@@ -612,7 +618,7 @@ hash_alloc(struct uma_hash *hash)
} else {
alloc = sizeof(hash->uh_slab_hash[0]) * UMA_HASH_SIZE_INIT;
hash->uh_slab_hash = zone_alloc_item(hashzone, NULL,
- M_WAITOK);
+ UMA_ANYDOMAIN, M_WAITOK);
hash->uh_hashsize = UMA_HASH_SIZE_INIT;
}
if (hash->uh_slab_hash) {
@@ -779,6 +785,7 @@ cache_drain_safe_cpu(uma_zone_t zone)
{
uma_cache_t cache;
uma_bucket_t b1, b2;
+ int domain;
if (zone->uz_flags & UMA_ZFLAG_INTERNAL)
return;
@@ -786,10 +793,14 @@ cache_drain_safe_cpu(uma_zone_t zone)
b1 = b2 = NULL;
ZONE_LOCK(zone);
critical_enter();
+ if (zone->uz_flags & UMA_ZONE_NUMA)
+ domain = PCPU_GET(domain);
+ else
+ domain = 0;
cache = &zone->uz_cpu[curcpu];
if (cache->uc_allocbucket) {
if (cache->uc_allocbucket->ub_cnt != 0)
- LIST_INSERT_HEAD(&zone->uz_buckets,
+ LIST_INSERT_HEAD(&zone->uz_domain[domain].uzd_buckets,
cache->uc_allocbucket, ub_link);
else
b1 = cache->uc_allocbucket;
@@ -797,7 +808,7 @@ cache_drain_safe_cpu(uma_zone_t zone)
}
if (cache->uc_freebucket) {
if (cache->uc_freebucket->ub_cnt != 0)
- LIST_INSERT_HEAD(&zone->uz_buckets,
+ LIST_INSERT_HEAD(&zone->uz_domain[domain].uzd_buckets,
cache->uc_freebucket, ub_link);
else
b2 = cache->uc_freebucket;
@@ -853,18 +864,22 @@ cache_drain_safe(uma_zone_t zone)
static void
bucket_cache_drain(uma_zone_t zone)
{
+ uma_zone_domain_t zdom;
uma_bucket_t bucket;
+ int i;
/*
- * Drain the bucket queues and free the buckets, we just keep two per
- * cpu (alloc/free).
+ * Drain the bucket queues and free the buckets.
*/
- while ((bucket = LIST_FIRST(&zone->uz_buckets)) != NULL) {
- LIST_REMOVE(bucket, ub_link);
- ZONE_UNLOCK(zone);
- bucket_drain(zone, bucket);
- bucket_free(zone, bucket, NULL);
- ZONE_LOCK(zone);
+ for (i = 0; i < vm_ndomains; i++) {
+ zdom = &zone->uz_domain[i];
+ while ((bucket = LIST_FIRST(&zdom->uzd_buckets)) != NULL) {
+ LIST_REMOVE(bucket, ub_link);
+ ZONE_UNLOCK(zone);
+ bucket_drain(zone, bucket);
+ bucket_free(zone, bucket, NULL);
+ ZONE_LOCK(zone);
+ }
}
/*
@@ -909,7 +924,9 @@ static void
keg_drain(uma_keg_t keg)
{
struct slabhead freeslabs = { 0 };
+ uma_domain_t dom;
uma_slab_t slab, tmp;
+ int i;
/*
* We don't want to take pages from statically allocated kegs at this
@@ -924,22 +941,27 @@ keg_drain(uma_keg_t keg)
if (keg->uk_free == 0)
goto finished;
- LIST_FOREACH_SAFE(slab, &keg->uk_free_slab, us_link, tmp) {
+ for (i = 0; i < vm_ndomains; i++) {
+ dom = &keg->uk_domain[i];
+ LIST_FOREACH_SAFE(slab, &dom->ud_free_slab, us_link, tmp) {
#ifndef __rtems__
- /* We have nowhere to free these to. */
- if (slab->us_flags & UMA_SLAB_BOOT)
- continue;
+ /* We have nowhere to free these to. */
+ if (slab->us_flags & UMA_SLAB_BOOT)
+ continue;
#endif /* __rtems__ */
- LIST_REMOVE(slab, us_link);
- keg->uk_pages -= keg->uk_ppera;
- keg->uk_free -= keg->uk_ipers;
+ LIST_REMOVE(slab, us_link);
+ keg->uk_pages -= keg->uk_ppera;
+ keg->uk_free -= keg->uk_ipers;
- if (keg->uk_flags & UMA_ZONE_HASH)
- UMA_HASH_REMOVE(&keg->uk_hash, slab, slab->us_data);
+ if (keg->uk_flags & UMA_ZONE_HASH)
+ UMA_HASH_REMOVE(&keg->uk_hash, slab,
+ slab->us_data);
- SLIST_INSERT_HEAD(&freeslabs, slab, us_hlink);
+ SLIST_INSERT_HEAD(&freeslabs, slab, us_hlink);
+ }
}
+
finished:
KEG_UNLOCK(keg);
@@ -999,7 +1021,7 @@ zone_drain(uma_zone_t zone)
* caller specified M_NOWAIT.
*/
static uma_slab_t
-keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
+keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int domain, int wait)
{
uma_alloc allocf;
uma_slab_t slab;
@@ -1008,6 +1030,8 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
uint8_t flags;
int i;
+ KASSERT(domain >= 0 && domain < vm_ndomains,
+ ("keg_alloc_slab: domain %d out of range", domain));
mtx_assert(&keg->uk_lock, MA_OWNED);
slab = NULL;
mem = NULL;
@@ -1017,7 +1041,7 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
size = keg->uk_ppera * PAGE_SIZE;
if (keg->uk_flags & UMA_ZONE_OFFPAGE) {
- slab = zone_alloc_item(keg->uk_slabzone, NULL, wait);
+ slab = zone_alloc_item(keg->uk_slabzone, NULL, domain, wait);
if (slab == NULL)
goto out;
}
@@ -1038,7 +1062,7 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
wait |= M_NODUMP;
/* zone is passed for legacy reasons. */
- mem = allocf(zone, size, &flags, wait);
+ mem = allocf(zone, size, domain, &flags, wait);
if (mem == NULL) {
if (keg->uk_flags & UMA_ZONE_OFFPAGE)
zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE);
@@ -1059,6 +1083,7 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
slab->us_data = mem;
slab->us_freecount = keg->uk_ipers;
slab->us_flags = flags;
+ slab->us_domain = domain;
BIT_FILL(SLAB_SETSIZE, &slab->us_free);
#ifdef INVARIANTS
BIT_ZERO(SLAB_SETSIZE, &slab->us_debugfree);
@@ -1099,7 +1124,8 @@ out:
* the VM is ready.
*/
static void *
-startup_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait)
+startup_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag,
+ int wait)
{
uma_keg_t keg;
void *mem;
@@ -1132,7 +1158,7 @@ startup_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait)
#else
keg->uk_allocf = page_alloc;
#endif
- return keg->uk_allocf(zone, bytes, pflag, wait);
+ return keg->uk_allocf(zone, bytes, domain, pflag, wait);
}
#endif /* __rtems__ */
@@ -1148,13 +1174,14 @@ startup_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait)
* NULL if M_NOWAIT is set.
*/
static void *
-page_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait)
+page_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag,
+ int wait)
{
void *p; /* Returned page */
#ifndef __rtems__
*pflag = UMA_SLAB_KERNEL;
- p = (void *) kmem_malloc(kernel_arena, bytes, wait);
+ p = (void *) kmem_malloc_domain(domain, bytes, wait);
#else /* __rtems__ */
*pflag = 0;
p = rtems_bsd_page_alloc(bytes, wait);
@@ -1176,7 +1203,8 @@ page_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait)
* NULL if M_NOWAIT is set.
*/
static void *
-noobj_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait)
+noobj_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *flags,
+ int wait)
{
TAILQ_HEAD(, vm_page) alloctail;
u_long npages;
@@ -1189,7 +1217,7 @@ noobj_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait)
npages = howmany(bytes, PAGE_SIZE);
while (npages > 0) {
- p = vm_page_alloc(NULL, 0, VM_ALLOC_INTERRUPT |
+ p = vm_page_alloc_domain(NULL, 0, domain, VM_ALLOC_INTERRUPT |
VM_ALLOC_WIRED | VM_ALLOC_NOOBJ |
((wait & M_WAITOK) != 0 ? VM_ALLOC_WAITOK :
VM_ALLOC_NOWAIT));
@@ -1469,6 +1497,7 @@ keg_ctor(void *mem, int size, void *udata, int flags)
keg->uk_init = arg->uminit;
keg->uk_fini = arg->fini;
keg->uk_align = arg->align;
+ keg->uk_cursor = 0;
keg->uk_free = 0;
keg->uk_reserve = 0;
keg->uk_pages = 0;
@@ -1614,6 +1643,8 @@ zone_ctor(void *mem, int size, void *udata, int flags)
zone->uz_count_min = 0;
zone->uz_flags = 0;
zone->uz_warning = NULL;
+ /* The domain structures follow the cpu structures. */
+ zone->uz_domain = (struct uma_zone_domain *)&zone->uz_cpu[mp_ncpus];
timevalclear(&zone->uz_ratecheck);
keg = arg->keg;
@@ -1819,22 +1850,60 @@ void
uma_startup(void *mem, int npages)
{
struct uma_zctor_args args;
+ uma_keg_t masterkeg;
+ uintptr_t m;
+#ifndef __rtems__
+ int zsize;
+ int ksize;
+#else /* __rtems__ */
+ size_t zsize, ksize, size;
+#endif /* __rtems__ */
rw_init(&uma_rwlock, "UMA lock");
+ ksize = sizeof(struct uma_keg) +
+ (sizeof(struct uma_domain) * vm_ndomains);
+ zsize = sizeof(struct uma_zone) +
+ (sizeof(struct uma_cache) * mp_ncpus) +
+ (sizeof(struct uma_zone_domain) * vm_ndomains);
+#ifdef __rtems__
+ size = 2 * roundup(zsize, CACHE_LINE_SIZE) +
+ roundup(ksize, CACHE_LINE_SIZE);
+#endif /* __rtems__ */
+
+#ifndef __rtems__
+ /* Use bootpages memory for the zone of zones and zone of kegs. */
+ m = (uintptr_t)mem;
+#else /* __rtems__ */
+ m = (uintptr_t)rtems_heap_allocate_aligned_with_boundary(
+ size, CACHE_LINE_SIZE, 0);
+ BSD_ASSERT(m != 0);
+ memset((void *)m, 0, size);
+#endif /* __rtems__ */
+ zones = (uma_zone_t)m;
+ m += roundup(zsize, CACHE_LINE_SIZE);
+ kegs = (uma_zone_t)m;
+ m += roundup(zsize, CACHE_LINE_SIZE);
+ masterkeg = (uma_keg_t)m;
+#ifndef __rtems__
+ m += roundup(ksize, CACHE_LINE_SIZE);
+ m = roundup(m, PAGE_SIZE);
+ npages -= (m - (uintptr_t)mem) / PAGE_SIZE;
+ mem = (void *)m;
+#endif /* __rtems__ */
+
/* "manually" create the initial zone */
memset(&args, 0, sizeof(args));
args.name = "UMA Kegs";
- args.size = sizeof(struct uma_keg);
+ args.size = ksize;
args.ctor = keg_ctor;
args.dtor = keg_dtor;
args.uminit = zero_init;
args.fini = NULL;
- args.keg = &masterkeg;
+ args.keg = masterkeg;
args.align = 32 - 1;
args.flags = UMA_ZFLAG_INTERNAL;
- /* The initial zone has no Per cpu queues so it's smaller */
- zone_ctor(kegs, sizeof(struct uma_zone), &args, M_WAITOK);
+ zone_ctor(kegs, zsize, &args, M_WAITOK);
#ifndef __rtems__
mtx_init(&uma_boot_pages_mtx, "UMA boot pages", NULL, MTX_DEF);
@@ -1844,7 +1913,8 @@ uma_startup(void *mem, int npages)
args.name = "UMA Zones";
args.size = sizeof(struct uma_zone) +
- (sizeof(struct uma_cache) * (mp_maxid + 1));
+ (sizeof(struct uma_cache) * (mp_maxid + 1)) +
+ (sizeof(struct uma_zone_domain) * vm_ndomains);
args.ctor = zone_ctor;
args.dtor = zone_dtor;
args.uminit = zero_init;
@@ -1852,8 +1922,7 @@ uma_startup(void *mem, int npages)
args.keg = NULL;
args.align = 32 - 1;
args.flags = UMA_ZFLAG_INTERNAL;
- /* The initial zone has no Per cpu queues so it's smaller */
- zone_ctor(zones, sizeof(struct uma_zone), &args, M_WAITOK);
+ zone_ctor(zones, zsize, &args, M_WAITOK);
/* Now make a zone for slab headers */
slabzone = uma_zcreate("UMA Slabs",
@@ -1924,7 +1993,7 @@ uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini,
args.align = (align == UMA_ALIGN_CACHE) ? uma_align_cache : align;
args.flags = flags;
args.zone = zone;
- return (zone_alloc_item(kegs, &args, M_WAITOK));
+ return (zone_alloc_item(kegs, &args, UMA_ANYDOMAIN, M_WAITOK));
}
/* See uma.h */
@@ -1987,7 +2056,7 @@ uma_zcreate(const char *name, size_t size, uma_ctor ctor, uma_dtor dtor,
locked = true;
}
#endif /* __rtems__ */
- res = zone_alloc_item(zones, &args, M_WAITOK);
+ res = zone_alloc_item(zones, &args, UMA_ANYDOMAIN, M_WAITOK);
#ifndef __rtems__
if (locked)
#endif /* __rtems__ */
@@ -2030,7 +2099,7 @@ uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor,
}
#endif /* __rtems__ */
/* XXX Attaches only one keg of potentially many. */
- res = zone_alloc_item(zones, &args, M_WAITOK);
+ res = zone_alloc_item(zones, &args, UMA_ANYDOMAIN, M_WAITOK);
#ifndef __rtems__
if (locked)
#endif /* __rtems__ */
@@ -2059,7 +2128,7 @@ uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor,
args.align = 0;
args.flags = flags;
- return (zone_alloc_item(zones, &args, M_WAITOK));
+ return (zone_alloc_item(zones, &args, UMA_ANYDOMAIN, M_WAITOK));
}
#ifndef __rtems__
@@ -2166,11 +2235,11 @@ uma_zwait(uma_zone_t zone)
void *
uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)
{
- void *item;
- uma_cache_t cache;
+ uma_zone_domain_t zdom;
uma_bucket_t bucket;
- int lockfail;
- int cpu;
+ uma_cache_t cache;
+ void *item;
+ int cpu, domain, lockfail;
/* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */
random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA);
@@ -2269,6 +2338,11 @@ zalloc_start:
if (bucket != NULL)
bucket_free(zone, bucket, udata);
+ if (zone->uz_flags & UMA_ZONE_NUMA)
+ domain = PCPU_GET(domain);
+ else
+ domain = UMA_ANYDOMAIN;
+
/* Short-circuit for zones without buckets and low memory. */
if (zone->uz_count == 0 || bucketdisable)
goto zalloc_item;
@@ -2309,7 +2383,11 @@ zalloc_start:
/*
* Check the zone's cache of buckets.
*/
- if ((bucket = LIST_FIRST(&zone->uz_buckets)) != NULL) {
+ if (domain == UMA_ANYDOMAIN)
+ zdom = &zone->uz_domain[0];
+ else
+ zdom = &zone->uz_domain[domain];
+ if ((bucket = LIST_FIRST(&zdom->uzd_buckets)) != NULL) {
KASSERT(bucket->ub_cnt != 0,
("uma_zalloc_arg: Returning an empty bucket."));
@@ -2334,7 +2412,7 @@ zalloc_start:
* works we'll restart the allocation from the beginning and it
* will use the just filled bucket.
*/
- bucket = zone_alloc_bucket(zone, udata, flags);
+ bucket = zone_alloc_bucket(zone, udata, domain, flags);
CTR3(KTR_UMA, "uma_zalloc: zone %s(%p) bucket zone returned %p",
zone->uz_name, zone, bucket);
if (bucket != NULL) {
@@ -2347,10 +2425,12 @@ zalloc_start:
* initialized bucket to make this less likely or claim
* the memory directly.
*/
- if (cache->uc_allocbucket == NULL)
- cache->uc_allocbucket = bucket;
+ if (cache->uc_allocbucket != NULL ||
+ (zone->uz_flags & UMA_ZONE_NUMA &&
+ domain != PCPU_GET(domain)))
+ LIST_INSERT_HEAD(&zdom->uzd_buckets, bucket, ub_link);
else
- LIST_INSERT_HEAD(&zone->uz_buckets, bucket, ub_link);
+ cache->uc_allocbucket = bucket;
ZONE_UNLOCK(zone);
goto zalloc_start;
}
@@ -2359,38 +2439,103 @@ zalloc_start:
* We may not be able to get a bucket so return an actual item.
*/
zalloc_item:
- item = zone_alloc_item(zone, udata, flags);
+ item = zone_alloc_item(zone, udata, domain, flags);
return (item);
}
+void *
+uma_zalloc_domain(uma_zone_t zone, void *udata, int domain, int flags)
+{
+
+ /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */
+ random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA);
+
+ /* This is the fast path allocation */
+ CTR5(KTR_UMA,
+ "uma_zalloc_domain thread %x zone %s(%p) domain %d flags %d",
+ curthread, zone->uz_name, zone, domain, flags);
+
+ if (flags & M_WAITOK) {
+ WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
+ "uma_zalloc_domain: zone \"%s\"", zone->uz_name);
+ }
+ KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
+ ("uma_zalloc_domain: called with spinlock or critical section held"));
+
+ return (zone_alloc_item(zone, udata, domain, flags));
+}
+
+/*
+ * Find a slab with some space. Prefer slabs that are partially used over those
+ * that are totally full. This helps to reduce fragmentation.
+ *
+ * If 'rr' is 1, search all domains starting from 'domain'. Otherwise check
+ * only 'domain'.
+ */
+static uma_slab_t
+keg_first_slab(uma_keg_t keg, int domain, int rr)
+{
+ uma_domain_t dom;
+ uma_slab_t slab;
+ int start;
+
+ KASSERT(domain >= 0 && domain < vm_ndomains,
+ ("keg_first_slab: domain %d out of range", domain));
+
+ slab = NULL;
+ start = domain;
+ do {
+ dom = &keg->uk_domain[domain];
+ if (!LIST_EMPTY(&dom->ud_part_slab))
+ return (LIST_FIRST(&dom->ud_part_slab));
+ if (!LIST_EMPTY(&dom->ud_free_slab)) {
+ slab = LIST_FIRST(&dom->ud_free_slab);
+ LIST_REMOVE(slab, us_link);
+ LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link);
+ return (slab);
+ }
+ if (rr)
+ domain = (domain + 1) % vm_ndomains;
+ } while (domain != start);
+
+ return (NULL);
+}
+
static uma_slab_t
-keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int flags)
+keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, int flags)
{
+ uma_domain_t dom;
uma_slab_t slab;
- int reserve;
+ int allocflags, domain, reserve, rr, start;
mtx_assert(&keg->uk_lock, MA_OWNED);
slab = NULL;
reserve = 0;
+ allocflags = flags;
if ((flags & M_USE_RESERVE) == 0)
reserve = keg->uk_reserve;
- for (;;) {
- /*
- * Find a slab with some space. Prefer slabs that are partially
- * used over those that are totally full. This helps to reduce
- * fragmentation.
- */
- if (keg->uk_free > reserve) {
- if (!LIST_EMPTY(&keg->uk_part_slab)) {
- slab = LIST_FIRST(&keg->uk_part_slab);
- } else {
- slab = LIST_FIRST(&keg->uk_free_slab);
- LIST_REMOVE(slab, us_link);
- LIST_INSERT_HEAD(&keg->uk_part_slab, slab,
- us_link);
- }
+ /*
+ * Round-robin for non first-touch zones when there is more than one
+ * domain.
+ */
+ if (vm_ndomains == 1)
+ rdomain = 0;
+ rr = rdomain == UMA_ANYDOMAIN;
+ if (rr) {
+ keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains;
+ domain = start = keg->uk_cursor;
+ /* Only block on the second pass. */
+ if ((flags & (M_WAITOK | M_NOVM)) == M_WAITOK)
+ allocflags = (allocflags & ~M_WAITOK) | M_NOWAIT;
+ } else
+ domain = start = rdomain;
+
+again:
+ do {
+ if (keg->uk_free > reserve &&
+ (slab = keg_first_slab(keg, domain, rr)) != NULL) {
MPASS(slab->us_keg == keg);
return (slab);
}
@@ -2413,12 +2558,12 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int flags)
zone_maxaction(zone);
}
if (flags & M_NOWAIT)
- break;
+ return (NULL);
zone->uz_sleeps++;
msleep(keg, &keg->uk_lock, PVM, "keglimit", 0);
continue;
}
- slab = keg_alloc_slab(keg, zone, flags);
+ slab = keg_alloc_slab(keg, zone, domain, allocflags);
/*
* If we got a slab here it's safe to mark it partially used
* and return. We assume that the caller is going to remove
@@ -2426,21 +2571,37 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int flags)
*/
if (slab) {
MPASS(slab->us_keg == keg);
- LIST_INSERT_HEAD(&keg->uk_part_slab, slab, us_link);
+ dom = &keg->uk_domain[slab->us_domain];
+ LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link);
return (slab);
}
- /*
- * We might not have been able to get a slab but another cpu
- * could have while we were unlocked. Check again before we
- * fail.
- */
- flags |= M_NOVM;
+ if (rr) {
+ keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains;
+ domain = keg->uk_cursor;
+ }
+ } while (domain != start);
+
+ /* Retry domain scan with blocking. */
+ if (allocflags != flags) {
+ allocflags = flags;
+ goto again;
}
- return (slab);
+
+ /*
+ * We might not have been able to get a slab but another cpu
+ * could have while we were unlocked. Check again before we
+ * fail.
+ */
+ if (keg->uk_free > reserve &&
+ (slab = keg_first_slab(keg, domain, rr)) != NULL) {
+ MPASS(slab->us_keg == keg);
+ return (slab);
+ }
+ return (NULL);
}
static uma_slab_t
-zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int flags)
+zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int domain, int flags)
{
uma_slab_t slab;
@@ -2450,7 +2611,7 @@ zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int flags)
}
for (;;) {
- slab = keg_fetch_slab(keg, zone, flags);
+ slab = keg_fetch_slab(keg, zone, domain, flags);
if (slab)
return (slab);
if (flags & (M_NOWAIT | M_NOVM))
@@ -2468,7 +2629,7 @@ zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int flags)
* The last pointer is used to seed the search. It is not required.
*/
static uma_slab_t
-zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags)
+zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int domain, int rflags)
{
uma_klink_t klink;
uma_slab_t slab;
@@ -2488,7 +2649,7 @@ zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags)
* the search.
*/
if (last != NULL) {
- slab = keg_fetch_slab(last, zone, flags);
+ slab = keg_fetch_slab(last, zone, domain, flags);
if (slab)
return (slab);
KEG_UNLOCK(last);
@@ -2509,7 +2670,7 @@ zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags)
keg = klink->kl_keg;
KEG_LOCK(keg);
if ((keg->uk_flags & UMA_ZFLAG_FULL) == 0) {
- slab = keg_fetch_slab(keg, zone, flags);
+ slab = keg_fetch_slab(keg, zone, domain, flags);
if (slab)
return (slab);
}
@@ -2546,6 +2707,7 @@ zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags)
static void *
slab_alloc_item(uma_keg_t keg, uma_slab_t slab)
{
+ uma_domain_t dom;
void *item;
uint8_t freei;
@@ -2561,32 +2723,48 @@ slab_alloc_item(uma_keg_t keg, uma_slab_t slab)
/* Move this slab to the full list */
if (slab->us_freecount == 0) {
LIST_REMOVE(slab, us_link);
- LIST_INSERT_HEAD(&keg->uk_full_slab, slab, us_link);
+ dom = &keg->uk_domain[slab->us_domain];
+ LIST_INSERT_HEAD(&dom->ud_full_slab, slab, us_link);
}
return (item);
}
static int
-zone_import(uma_zone_t zone, void **bucket, int max, int flags)
+zone_import(uma_zone_t zone, void **bucket, int max, int domain, int flags)
{
uma_slab_t slab;
uma_keg_t keg;
+ int stripe;
int i;
slab = NULL;
keg = NULL;
/* Try to keep the buckets totally full */
for (i = 0; i < max; ) {
- if ((slab = zone->uz_slab(zone, keg, flags)) == NULL)
+ if ((slab = zone->uz_slab(zone, keg, domain, flags)) == NULL)
break;
keg = slab->us_keg;
+ stripe = howmany(max, vm_ndomains);
while (slab->us_freecount && i < max) {
bucket[i++] = slab_alloc_item(keg, slab);
if (keg->uk_free <= keg->uk_reserve)
break;
+#ifdef NUMA
+ /*
+ * If the zone is striped we pick a new slab for every
+ * N allocations. Eliminating this conditional will
+ * instead pick a new domain for each bucket rather
+ * than stripe within each bucket. The current option
+ * produces more fragmentation and requires more cpu
+ * time but yields better distribution.
+ */
+ if ((zone->uz_flags & UMA_ZONE_NUMA) == 0 &&
+ vm_ndomains > 1 && --stripe == 0)
+ break;
+#endif
}
- /* Don't grab more than one slab at a time. */
+ /* Don't block if we allocated any successfully. */
flags &= ~M_WAITOK;
flags |= M_NOWAIT;
}
@@ -2597,7 +2775,7 @@ zone_import(uma_zone_t zone, void **bucket, int max, int flags)
}
static uma_bucket_t
-zone_alloc_bucket(uma_zone_t zone, void *udata, int flags)
+zone_alloc_bucket(uma_zone_t zone, void *udata, int domain, int flags)
{
uma_bucket_t bucket;
int max;
@@ -2609,7 +2787,7 @@ zone_alloc_bucket(uma_zone_t zone, void *udata, int flags)
max = MIN(bucket->ub_entries, zone->uz_count);
bucket->ub_cnt = zone->uz_import(zone->uz_arg, bucket->ub_bucket,
- max, flags);
+ max, domain, flags);
/*
* Initialize the memory if necessary.
@@ -2651,6 +2829,7 @@ zone_alloc_bucket(uma_zone_t zone, void *udata, int flags)
* Arguments
* zone The zone to alloc for.
* udata The data to be passed to the constructor.
+ * domain The domain to allocate from or UMA_ANYDOMAIN.
* flags M_WAITOK, M_NOWAIT, M_ZERO.
*
* Returns
@@ -2659,13 +2838,13 @@ zone_alloc_bucket(uma_zone_t zone, void *udata, int flags)
*/
static void *
-zone_alloc_item(uma_zone_t zone, void *udata, int flags)
+zone_alloc_item(uma_zone_t zone, void *udata, int domain, int flags)
{
void *item;
item = NULL;
- if (zone->uz_import(zone->uz_arg, &item, 1, flags) != 1)
+ if (zone->uz_import(zone->uz_arg, &item, 1, domain, flags) != 1)
goto fail;
atomic_add_long(&zone->uz_allocs, 1);
@@ -2711,8 +2890,8 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
{
uma_cache_t cache;
uma_bucket_t bucket;
- int lockfail;
- int cpu;
+ uma_zone_domain_t zdom;
+ int cpu, domain, lockfail;
/* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */
random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA);
@@ -2828,6 +3007,12 @@ zfree_start:
/* We are no longer associated with this CPU. */
critical_exit();
+ if ((zone->uz_flags & UMA_ZONE_NUMA) != 0)
+ domain = PCPU_GET(domain);
+ else
+ domain = 0;
+ zdom = &zone->uz_domain[0];
+
/* Can we throw this on the zone full list? */
if (bucket != NULL) {
CTR3(KTR_UMA,
@@ -2836,7 +3021,7 @@ zfree_start:
/* ub_cnt is pointing to the last free item */
KASSERT(bucket->ub_cnt != 0,
("uma_zfree: Attempting to insert an empty bucket onto the full list.\n"));
- LIST_INSERT_HEAD(&zone->uz_buckets, bucket, ub_link);
+ LIST_INSERT_HEAD(&zdom->uzd_buckets, bucket, ub_link);
}
/*
@@ -2854,7 +3039,9 @@ zfree_start:
critical_enter();
cpu = curcpu;
cache = &zone->uz_cpu[cpu];
- if (cache->uc_freebucket == NULL) {
+ if (cache->uc_freebucket == NULL &&
+ ((zone->uz_flags & UMA_ZONE_NUMA) == 0 ||
+ domain == PCPU_GET(domain))) {
cache->uc_freebucket = bucket;
goto zfree_start;
}
@@ -2876,21 +3063,43 @@ zfree_item:
return;
}
+void
+uma_zfree_domain(uma_zone_t zone, void *item, void *udata)
+{
+
+ /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */
+ random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA);
+
+ CTR2(KTR_UMA, "uma_zfree_domain thread %x zone %s", curthread,
+ zone->uz_name);
+
+ KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
+ ("uma_zfree_domain: called with spinlock or critical section held"));
+
+ /* uma_zfree(..., NULL) does nothing, to match free(9). */
+ if (item == NULL)
+ return;
+ zone_free_item(zone, item, udata, SKIP_NONE);
+}
+
static void
slab_free_item(uma_keg_t keg, uma_slab_t slab, void *item)
{
+ uma_domain_t dom;
uint8_t freei;
mtx_assert(&keg->uk_lock, MA_OWNED);
MPASS(keg == slab->us_keg);
+ dom = &keg->uk_domain[slab->us_domain];
+
/* Do we need to remove from any lists? */
if (slab->us_freecount+1 == keg->uk_ipers) {
LIST_REMOVE(slab, us_link);
- LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link);
+ LIST_INSERT_HEAD(&dom->ud_free_slab, slab, us_link);
} else if (slab->us_freecount == 0) {
LIST_REMOVE(slab, us_link);
- LIST_INSERT_HEAD(&keg->uk_part_slab, slab, us_link);
+ LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link);
}
/* Slab management. */
@@ -3223,24 +3432,28 @@ uma_zone_reserve_kva(uma_zone_t zone, int count)
void
uma_prealloc(uma_zone_t zone, int items)
{
- int slabs;
+ uma_domain_t dom;
uma_slab_t slab;
uma_keg_t keg;
+ int domain, slabs;
keg = zone_first_keg(zone);
if (keg == NULL)
return;
KEG_LOCK(keg);
slabs = items / keg->uk_ipers;
+ domain = 0;
if (slabs * keg->uk_ipers < items)
slabs++;
while (slabs > 0) {
- slab = keg_alloc_slab(keg, zone, M_WAITOK);
+ slab = keg_alloc_slab(keg, zone, domain, M_WAITOK);
if (slab == NULL)
break;
MPASS(slab->us_keg == keg);
- LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link);
+ dom = &keg->uk_domain[slab->us_domain];
+ LIST_INSERT_HEAD(&dom->ud_free_slab, slab, us_link);
slabs--;
+ domain = (domain + 1) % vm_ndomains;
}
KEG_UNLOCK(keg);
}
@@ -3295,7 +3508,7 @@ uma_reclaim_worker(void *arg __unused)
for (;;) {
sx_xlock(&uma_drain_lock);
- while (uma_reclaim_needed == 0)
+ while (atomic_load_int(&uma_reclaim_needed) == 0)
sx_sleep(uma_reclaim, &uma_drain_lock, PVM, "umarcl",
hz);
#ifndef __rtems__
@@ -3304,7 +3517,7 @@ uma_reclaim_worker(void *arg __unused)
sx_xlock(&uma_drain_lock);
#endif /* __rtems__ */
uma_reclaim_locked(true);
- atomic_set_int(&uma_reclaim_needed, 0);
+ atomic_store_int(&uma_reclaim_needed, 0);
sx_xunlock(&uma_drain_lock);
/* Don't fire more than once per-second. */
pause("umarclslp", hz);
@@ -3331,34 +3544,47 @@ uma_zone_exhausted_nolock(uma_zone_t zone)
#ifndef __rtems__
void *
-uma_large_malloc(vm_size_t size, int wait)
+uma_large_malloc_domain(vm_size_t size, int domain, int wait)
{
- void *mem;
+ vm_offset_t addr;
uma_slab_t slab;
- uint8_t flags;
- slab = zone_alloc_item(slabzone, NULL, wait);
+ slab = zone_alloc_item(slabzone, NULL, domain, wait);
if (slab == NULL)
return (NULL);
- mem = page_alloc(NULL, size, &flags, wait);
- if (mem) {
- vsetslab((vm_offset_t)mem, slab);
- slab->us_data = mem;
- slab->us_flags = flags | UMA_SLAB_MALLOC;
+ if (domain == UMA_ANYDOMAIN)
+ addr = kmem_malloc(kernel_arena, size, wait);
+ else
+ addr = kmem_malloc_domain(domain, size, wait);
+ if (addr != 0) {
+ vsetslab(addr, slab);
+ slab->us_data = (void *)addr;
+ slab->us_flags = UMA_SLAB_KERNEL | UMA_SLAB_MALLOC;
slab->us_size = size;
+ slab->us_domain = vm_phys_domidx(PHYS_TO_VM_PAGE(
+ pmap_kextract(addr)));
uma_total_inc(size);
} else {
zone_free_item(slabzone, slab, NULL, SKIP_NONE);
}
- return (mem);
+ return ((void *)addr);
+}
+
+void *
+uma_large_malloc(vm_size_t size, int wait)
+{
+
+ return uma_large_malloc_domain(size, UMA_ANYDOMAIN, wait);
}
void
uma_large_free(uma_slab_t slab)
{
- page_free(slab->us_data, slab->us_size, slab->us_flags);
+ KASSERT((slab->us_flags & UMA_SLAB_KERNEL) != 0,
+ ("uma_large_free: Memory not allocated with uma_large_malloc."));
+ kmem_free(kernel_arena, (vm_offset_t)slab->us_data, slab->us_size);
uma_total_dec(slab->us_size);
zone_free_item(slabzone, slab, NULL, SKIP_NONE);
}
@@ -3394,7 +3620,14 @@ unsigned long
uma_size(void)
{
- return uma_kmem_total;
+ return (uma_kmem_total);
+}
+
+long
+uma_avail(void)
+{
+
+ return (uma_kmem_limit - uma_kmem_total);
}
void
@@ -3423,7 +3656,9 @@ cache_print(uma_cache_t cache)
static void
uma_print_keg(uma_keg_t keg)
{
+ uma_domain_t dom;
uma_slab_t slab;
+ int i;
printf("keg: %s(%p) size %d(%d) flags %#x ipers %d ppera %d "
"out %d free %d limit %d\n",
@@ -3431,15 +3666,18 @@ uma_print_keg(uma_keg_t keg)
keg->uk_ipers, keg->uk_ppera,
(keg->uk_pages / keg->uk_ppera) * keg->uk_ipers - keg->uk_free,
keg->uk_free, (keg->uk_maxpages / keg->uk_ppera) * keg->uk_ipers);
- printf("Part slabs:\n");
- LIST_FOREACH(slab, &keg->uk_part_slab, us_link)
- slab_print(slab);
- printf("Free slabs:\n");
- LIST_FOREACH(slab, &keg->uk_free_slab, us_link)
- slab_print(slab);
- printf("Full slabs:\n");
- LIST_FOREACH(slab, &keg->uk_full_slab, us_link)
- slab_print(slab);
+ for (i = 0; i < vm_ndomains; i++) {
+ dom = &keg->uk_domain[i];
+ printf("Part slabs:\n");
+ LIST_FOREACH(slab, &dom->ud_part_slab, us_link)
+ slab_print(slab);
+ printf("Free slabs:\n");
+ LIST_FOREACH(slab, &dom->ud_free_slab, us_link)
+ slab_print(slab);
+ printf("Full slabs:\n");
+ LIST_FOREACH(slab, &dom->ud_full_slab, us_link)
+ slab_print(slab);
+ }
}
void
@@ -3531,6 +3769,7 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
struct uma_type_header uth;
struct uma_percpu_stat ups;
uma_bucket_t bucket;
+ uma_zone_domain_t zdom;
struct sbuf sbuf;
uma_cache_t cache;
uma_klink_t kl;
@@ -3586,8 +3825,12 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
(LIST_FIRST(&kz->uk_zones) != z))
uth.uth_zone_flags = UTH_ZONE_SECONDARY;
- LIST_FOREACH(bucket, &z->uz_buckets, ub_link)
- uth.uth_zone_free += bucket->ub_cnt;
+ for (i = 0; i < vm_ndomains; i++) {
+ zdom = &z->uz_domain[i];
+ LIST_FOREACH(bucket, &zdom->uzd_buckets,
+ ub_link)
+ uth.uth_zone_free += bucket->ub_cnt;
+ }
uth.uth_allocs = z->uz_allocs;
uth.uth_frees = z->uz_frees;
uth.uth_fails = z->uz_fails;
@@ -3754,11 +3997,12 @@ uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item)
#ifdef DDB
DB_SHOW_COMMAND(uma, db_show_uma)
{
- uint64_t allocs, frees, sleeps;
uma_bucket_t bucket;
uma_keg_t kz;
uma_zone_t z;
- int cachefree;
+ uma_zone_domain_t zdom;
+ uint64_t allocs, frees, sleeps;
+ int cachefree, i;
db_printf("%18s %8s %8s %8s %12s %8s %8s\n", "Zone", "Size", "Used",
"Free", "Requests", "Sleeps", "Bucket");
@@ -3775,8 +4019,12 @@ DB_SHOW_COMMAND(uma, db_show_uma)
if (!((z->uz_flags & UMA_ZONE_SECONDARY) &&
(LIST_FIRST(&kz->uk_zones) != z)))
cachefree += kz->uk_free;
- LIST_FOREACH(bucket, &z->uz_buckets, ub_link)
- cachefree += bucket->ub_cnt;
+ for (i = 0; i < vm_ndomains; i++) {
+ zdom = &z->uz_domain[i];
+ LIST_FOREACH(bucket, &zdom->uzd_buckets,
+ ub_link)
+ cachefree += bucket->ub_cnt;
+ }
db_printf("%18s %8ju %8jd %8d %12ju %8ju %8u\n",
z->uz_name, (uintmax_t)kz->uk_size,
(intmax_t)(allocs - frees), cachefree,
@@ -3789,17 +4037,21 @@ DB_SHOW_COMMAND(uma, db_show_uma)
DB_SHOW_COMMAND(umacache, db_show_umacache)
{
- uint64_t allocs, frees;
uma_bucket_t bucket;
uma_zone_t z;
- int cachefree;
+ uma_zone_domain_t zdom;
+ uint64_t allocs, frees;
+ int cachefree, i;
db_printf("%18s %8s %8s %8s %12s %8s\n", "Zone", "Size", "Used", "Free",
"Requests", "Bucket");
LIST_FOREACH(z, &uma_cachezones, uz_link) {
uma_zone_sumstat(z, &cachefree, &allocs, &frees, NULL);
- LIST_FOREACH(bucket, &z->uz_buckets, ub_link)
- cachefree += bucket->ub_cnt;
+ for (i = 0; i < vm_ndomains; i++) {
+ zdom = &z->uz_domain[i];
+ LIST_FOREACH(bucket, &zdom->uzd_buckets, ub_link)
+ cachefree += bucket->ub_cnt;
+ }
db_printf("%18s %8ju %8jd %8d %12ju %8u\n",
z->uz_name, (uintmax_t)z->uz_size,
(intmax_t)(allocs - frees), cachefree,
diff --git a/freebsd/sys/vm/uma_int.h b/freebsd/sys/vm/uma_int.h
index 592e79d7..5852a1c3 100644
--- a/freebsd/sys/vm/uma_int.h
+++ b/freebsd/sys/vm/uma_int.h
@@ -39,7 +39,22 @@
*/
/*
- * Here's a quick description of the relationship between the objects:
+ * The brief summary; Zones describe unique allocation types. Zones are
+ * organized into per-CPU caches which are filled by buckets. Buckets are
+ * organized according to memory domains. Buckets are filled from kegs which
+ * are also organized according to memory domains. Kegs describe a unique
+ * allocation type, backend memory provider, and layout. Kegs are associated
+ * with one or more zones and zones reference one or more kegs. Kegs provide
+ * slabs which are virtually contiguous collections of pages. Each slab is
+ * broken down int one or more items that will satisfy an individual allocation.
+ *
+ * Allocation is satisfied in the following order:
+ * 1) Per-CPU cache
+ * 2) Per-domain cache of buckets
+ * 3) Slab from any of N kegs
+ * 4) Backend page provider
+ *
+ * More detail on individual objects is contained below:
*
* Kegs contain lists of slabs which are stored in either the full bin, empty
* bin, or partially allocated bin, to reduce fragmentation. They also contain
@@ -47,6 +62,13 @@
* and rsize is the result of that. The Keg also stores information for
* managing a hash of page addresses that maps pages to uma_slab_t structures
* for pages that don't have embedded uma_slab_t's.
+ *
+ * Keg slab lists are organized by memory domain to support NUMA allocation
+ * policies. By default allocations are spread across domains to reduce the
+ * potential for hotspots. Special keg creation flags may be specified to
+ * prefer location allocation. However there is no strict enforcement as frees
+ * may happen on any CPU and these are returned to the CPU-local cache
+ * regardless of the originating domain.
*
* The uma_slab_t may be embedded in a UMA_SLAB_SIZE chunk of memory or it may
* be allocated off the page from a special slab zone. The free list within a
@@ -182,6 +204,17 @@ struct uma_cache {
typedef struct uma_cache * uma_cache_t;
/*
+ * Per-domain memory list. Embedded in the kegs.
+ */
+struct uma_domain {
+ LIST_HEAD(,uma_slab) ud_part_slab; /* partially allocated slabs */
+ LIST_HEAD(,uma_slab) ud_free_slab; /* empty slab list */
+ LIST_HEAD(,uma_slab) ud_full_slab; /* full slabs */
+};
+
+typedef struct uma_domain * uma_domain_t;
+
+/*
* Keg management structure
*
* TODO: Optimize for cache line size
@@ -192,10 +225,8 @@ struct uma_keg {
struct uma_hash uk_hash;
LIST_HEAD(,uma_zone) uk_zones; /* Keg's zones */
- LIST_HEAD(,uma_slab) uk_part_slab; /* partially allocated slabs */
- LIST_HEAD(,uma_slab) uk_free_slab; /* empty slab list */
- LIST_HEAD(,uma_slab) uk_full_slab; /* full slabs */
+ uint32_t uk_cursor; /* Domain alloc cursor. */
uint32_t uk_align; /* Alignment mask */
uint32_t uk_pages; /* Total page count */
uint32_t uk_free; /* Count of items free in slabs */
@@ -221,6 +252,9 @@ struct uma_keg {
/* Least used fields go to the last cache line. */
const char *uk_name; /* Name of creating zone. */
LIST_ENTRY(uma_keg) uk_link; /* List of all kegs */
+
+ /* Must be last, variable sized. */
+ struct uma_domain uk_domain[]; /* Keg's slab lists. */
};
typedef struct uma_keg * uma_keg_t;
@@ -250,7 +284,7 @@ struct uma_slab {
#endif
uint16_t us_freecount; /* How many are free? */
uint8_t us_flags; /* Page flags see uma.h */
- uint8_t us_pad; /* Pad to 32bits, unused. */
+ uint8_t us_domain; /* Backing NUMA domain. */
};
#define us_link us_type._us_link
@@ -258,8 +292,12 @@ struct uma_slab {
#define us_size us_type._us_size
#endif /* __rtems__ */
+#if MAXMEMDOM >= 255
+#error "Slab domain type insufficient"
+#endif
+
typedef struct uma_slab * uma_slab_t;
-typedef uma_slab_t (*uma_slaballoc)(uma_zone_t, uma_keg_t, int);
+typedef uma_slab_t (*uma_slaballoc)(uma_zone_t, uma_keg_t, int, int);
struct uma_klink {
LIST_ENTRY(uma_klink) kl_link;
@@ -267,6 +305,12 @@ struct uma_klink {
};
typedef struct uma_klink *uma_klink_t;
+struct uma_zone_domain {
+ LIST_HEAD(,uma_bucket) uzd_buckets; /* full buckets */
+};
+
+typedef struct uma_zone_domain * uma_zone_domain_t;
+
/*
* Zone management structure
*
@@ -279,7 +323,7 @@ struct uma_zone {
const char *uz_name; /* Text name of the zone */
LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */
- LIST_HEAD(,uma_bucket) uz_buckets; /* full buckets */
+ struct uma_zone_domain *uz_domain; /* per-domain buckets */
LIST_HEAD(,uma_klink) uz_kegs; /* List of kegs. */
struct uma_klink uz_klink; /* klink for first keg. */
@@ -313,7 +357,9 @@ struct uma_zone {
* This HAS to be the last item because we adjust the zone size
* based on NCPU and then allocate the space for the zones.
*/
- struct uma_cache uz_cpu[1]; /* Per cpu caches */
+ struct uma_cache uz_cpu[]; /* Per cpu caches */
+
+ /* uz_domain follows here. */
};
/*
@@ -344,6 +390,7 @@ zone_first_keg(uma_zone_t zone)
/* Internal prototypes */
static __inline uma_slab_t hash_sfind(struct uma_hash *hash, uint8_t *data);
void *uma_large_malloc(vm_size_t size, int wait);
+void *uma_large_malloc_domain(vm_size_t size, int domain, int wait);
void uma_large_free(uma_slab_t slab);
/* Lock Macros */
@@ -437,16 +484,12 @@ vsetslab(vm_offset_t va, uma_slab_t slab)
* if they can provide more efficient allocation functions. This is useful
* for using direct mapped addresses.
*/
-void *uma_small_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag,
- int wait);
+void *uma_small_alloc(uma_zone_t zone, vm_size_t bytes, int domain,
+ uint8_t *pflag, int wait);
void uma_small_free(void *mem, vm_size_t size, uint8_t flags);
/* Set a global soft limit on UMA managed memory. */
void uma_set_limit(unsigned long limit);
-unsigned long uma_limit(void);
-
-/* Return the amount of memory managed by UMA. */
-unsigned long uma_size(void);
#endif /* _KERNEL */
#endif /* VM_UMA_INT_H */
diff --git a/freebsd/sys/vm/vm.h b/freebsd/sys/vm/vm.h
index f674fc56..b5de53d3 100644
--- a/freebsd/sys/vm/vm.h
+++ b/freebsd/sys/vm/vm.h
@@ -146,6 +146,8 @@ extern void vm_ksubmap_init(struct kva_md_info *);
extern int old_mlock;
+#define vm_ndomains 1
+
struct ucred;
int swap_reserve(vm_ooffset_t incr);
int swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred);
diff --git a/freebsd/sys/vm/vm_extern.h b/freebsd/sys/vm/vm_extern.h
index c92933ca..e64637c1 100644
--- a/freebsd/sys/vm/vm_extern.h
+++ b/freebsd/sys/vm/vm_extern.h
@@ -56,14 +56,21 @@ void kmap_free_wakeup(vm_map_t, vm_offset_t, vm_size_t);
/* These operate on virtual addresses backed by memory. */
vm_offset_t kmem_alloc_attr(struct vmem *, vm_size_t size, int flags,
vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr);
+vm_offset_t kmem_alloc_attr_domain(int domain, vm_size_t size, int flags,
+ vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr);
vm_offset_t kmem_alloc_contig(struct vmem *, vm_size_t size, int flags,
vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary,
vm_memattr_t memattr);
+vm_offset_t kmem_alloc_contig_domain(int domain, vm_size_t size, int flags,
+ vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary,
+ vm_memattr_t memattr);
vm_offset_t kmem_malloc(struct vmem *, vm_size_t size, int flags);
+vm_offset_t kmem_malloc_domain(int domain, vm_size_t size, int flags);
void kmem_free(struct vmem *, vm_offset_t, vm_size_t);
/* This provides memory for previously allocated address space. */
int kmem_back(vm_object_t, vm_offset_t, vm_size_t, int);
+int kmem_back_domain(int, vm_object_t, vm_offset_t, vm_size_t, int);
void kmem_unback(vm_object_t, vm_offset_t, vm_size_t);
/* Bootstrapping. */
diff --git a/freebsd/sys/x86/include/machine/bus.h b/freebsd/sys/x86/include/machine/bus.h
index 041ab156..297b5edc 100644
--- a/freebsd/sys/x86/include/machine/bus.h
+++ b/freebsd/sys/x86/include/machine/bus.h
@@ -118,6 +118,7 @@
#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
#if defined(__amd64__) || defined(PAE)
+#define BUS_SPACE_MAXADDR_48BIT 0xFFFFFFFFFFFFULL
#define BUS_SPACE_MAXADDR 0xFFFFFFFFFFFFFFFFULL
#else
#define BUS_SPACE_MAXADDR 0xFFFFFFFF
diff --git a/freebsd/sys/x86/pci/pci_bus.c b/freebsd/sys/x86/pci/pci_bus.c
index 8d37bdcd..0db41c18 100644
--- a/freebsd/sys/x86/pci/pci_bus.c
+++ b/freebsd/sys/x86/pci/pci_bus.c
@@ -686,8 +686,7 @@ DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, hostb_devclass, 0, 0);
* ID is available and the PCI BIOS isn't, but for now we just
* eat the PnP ID and do nothing else.
*
- * XXX we should silence this probe, as it will generally confuse
- * people.
+ * we silence this probe, as it will generally confuse people.
*/
static struct isa_pnp_id pcibus_pnp_ids[] = {
{ 0x030ad041 /* PNP0A03 */, "PCI Bus" },
@@ -751,6 +750,7 @@ static devclass_t pcib_devclass;
DEFINE_CLASS_1(pcib, pcibios_pcib_driver, pcibios_pcib_pci_methods,
sizeof(struct pcib_softc), pcib_driver);
DRIVER_MODULE(pcibios_pcib, pci, pcibios_pcib_driver, pcib_devclass, 0, 0);
+ISA_PNP_INFO(pcibus_pnp_ids);
static int
pcibios_pcib_probe(device_t dev)