diff options
author | Mike Zeller <mike@mikezeller.net> | 2020-03-11 16:42:06 -0400 |
---|---|---|
committer | Mike Zeller <mike@mikezeller.net> | 2020-03-11 16:42:06 -0400 |
commit | 2803e163cd303fbc63f832f544bc59c4ee562252 (patch) | |
tree | c901ef8fa7580dcebfb11316f6bb49d498bd40a8 | |
parent | dd05dd221f0e26bb86692b7b69c8dbeab8f4c0e5 (diff) | |
parent | 1de02da27664d38cedeccf227bd4ae92d32619d9 (diff) | |
download | illumos-joyent-2803e163cd303fbc63f832f544bc59c4ee562252.tar.gz |
Merge remote-tracking branch 'origin/master' into bhyve-syncbhyve-sync
301 files changed, 21021 insertions, 4821 deletions
diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000..f318090a88 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,62 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Copyright 2020 Joyent, Inc. + */ + +@Library('jenkins-joylib@v1.0.4') _ + +pipeline { + + agent { + label 'platform:true && image_ver:18.4.0 && pkgsrc_arch:x86_64 && ' + + 'dram:8gb && !virt:kvm && fs:pcfs && fs:ufs && jenkins_agent:2' + } + + options { + buildDiscarder(logRotator(numToKeepStr: '30')) + timestamps() + parallelsAlwaysFailFast() + } + + stages { + stage('trigger smartos-live') { + when { + anyOf { + branch 'master' + triggeredBy cause: 'UserIdCause' + } + // Prevent a user from starting a UserIdCause build on a + // release branch, since that would trigger the smartos-live + // 'master' branch build below, which is not what we want. + not { + branch pattern: 'release-\\d+', comparator: 'REGEXP' + } + } + steps { + build(job:'joyent-org/smartos-live/master', + wait: false, + parameters: [ + text(name: 'CONFIGURE_PROJECTS', + value: + "illumos-extra: master: origin\n" + + 'illumos: $BRANCH_NAME: origin\n' + + 'local/kbmd: master: origin\n' + + 'local/kvm-cmd: master: origin\n' + + 'local/kvm: master: origin\n' + + 'local/mdata-client: master: origin\n' + + 'local/ur-agent: master: origin') + ]) + } + } + } + post { + always { + joyMattermostNotification(channel: 'jenkins') + } + } +} @@ -704,6 +704,7 @@ f kernel/drv/amd64/log 0755 root sys f kernel/drv/amd64/lsimega 0755 root sys f kernel/drv/amd64/marvell88sx 0755 root sys f kernel/drv/amd64/mega_sas 0755 root sys +f kernel/drv/amd64/mlxcx 0755 root sys f kernel/drv/amd64/mm 0755 root sys f kernel/drv/amd64/mpt 0755 root sys f kernel/drv/amd64/mpt_sas 0755 root sys @@ -872,6 +873,7 @@ f kernel/drv/lofi.conf 0644 root sys f kernel/drv/log.conf 0644 root sys f kernel/drv/lsimega.conf 0644 root sys f kernel/drv/mega_sas.conf 0644 root sys +f kernel/drv/mlxcx.conf 0644 root sys f kernel/drv/mm.conf 0644 root sys f kernel/drv/mpt.conf 0644 root sys f kernel/drv/mpt_sas.conf 0644 root sys @@ -5732,6 +5734,7 @@ f usr/lib/fm/dict/FMD.dict 0444 root bin f usr/lib/fm/dict/FMNOTIFY.dict 0444 root bin f usr/lib/fm/dict/GMCA.dict 0444 root bin f usr/lib/fm/dict/INTEL.dict 0444 root bin +f usr/lib/fm/dict/NIC.dict 0444 root bin f usr/lib/fm/dict/NXGE.dict 0444 root bin f usr/lib/fm/dict/PCI.dict 0444 root bin f usr/lib/fm/dict/PCIEX.dict 0444 root bin @@ -5747,6 +5750,7 @@ d usr/lib/fm/eft 0755 root bin f usr/lib/fm/eft/disk.eft 0444 root bin f usr/lib/fm/eft/neptune_xaui.eft 0444 root bin f usr/lib/fm/eft/neptune_xfp.eft 0444 root bin +f usr/lib/fm/eft/nic.eft 0444 root bin f usr/lib/fm/eft/pci.eft 0444 root bin f usr/lib/fm/eft/pciex.eft 0444 root bin f usr/lib/fm/eft/pciexrc.eft 0444 root bin @@ -7002,6 +7006,8 @@ f usr/lib/locale/C/LC_MESSAGES/GMCA.mo 0444 root bin f usr/lib/locale/C/LC_MESSAGES/GMCA.po 0644 root bin f usr/lib/locale/C/LC_MESSAGES/INTEL.mo 0444 root bin f usr/lib/locale/C/LC_MESSAGES/INTEL.po 0644 root bin +f usr/lib/locale/C/LC_MESSAGES/NIC.mo 0444 root bin +f usr/lib/locale/C/LC_MESSAGES/NIC.po 0644 root bin f usr/lib/locale/C/LC_MESSAGES/NXGE.mo 0444 root bin f usr/lib/locale/C/LC_MESSAGES/NXGE.po 0644 root bin f usr/lib/locale/C/LC_MESSAGES/PCI.mo 0444 root bin @@ -12414,6 +12420,7 @@ f usr/share/man/man1m/gsscred.1m 0444 root bin f usr/share/man/man1m/gssd.1m 0444 root bin f usr/share/man/man1m/halt.1m 0444 root bin f usr/share/man/man1m/hostconfig.1m 0444 root bin +f usr/share/man/man1m/hotplug.1m 0444 root bin f usr/share/man/man1m/id.1m 0444 root bin f usr/share/man/man1m/idmap.1m 0444 root bin f usr/share/man/man1m/idmapd.1m 0444 root bin @@ -12652,6 +12659,7 @@ f usr/share/man/man1m/trapstat.1m 0444 root bin f usr/share/man/man1m/ttyadm.1m 0444 root bin f usr/share/man/man1m/ttymon.1m 0444 root bin f usr/share/man/man1m/tunefs.1m 0444 root bin +f usr/share/man/man1m/tzreload.1m 0444 root bin f usr/share/man/man1m/tzselect.1m 0444 root bin f usr/share/man/man1m/uadmin.1m 0444 root bin f usr/share/man/man1m/ucodeadm.1m 0444 root bin @@ -16365,6 +16373,7 @@ f usr/share/man/man3lib/libkstat.3lib 0444 root bin f usr/share/man/man3lib/libkvm.3lib 0444 root bin f usr/share/man/man3lib/libl.3lib 0444 root bin f usr/share/man/man3lib/liblgrp.3lib 0444 root bin +f usr/share/man/man3lib/libm.3lib 0444 root bin f usr/share/man/man3lib/libmail.3lib 0444 root bin f usr/share/man/man3lib/libmalloc.3lib 0444 root bin f usr/share/man/man3lib/libmapmalloc.3lib 0444 root bin @@ -16374,6 +16383,7 @@ f usr/share/man/man3lib/libmenu.3lib 0444 root bin f usr/share/man/man3lib/libmp.3lib 0444 root bin s usr/share/man/man3lib/libmpapi.3lib=libMPAPI.3lib f usr/share/man/man3lib/libmtmalloc.3lib 0444 root bin +f usr/share/man/man3lib/libmvec.3lib 0444 root bin f usr/share/man/man3lib/libnls.3lib 0444 root bin f usr/share/man/man3lib/libnsl.3lib 0444 root bin f usr/share/man/man3lib/libnvpair.3lib 0444 root bin @@ -19535,6 +19545,7 @@ f usr/share/man/man7d/lofi.7d 0444 root bin f usr/share/man/man7d/log.7d 0444 root bin f usr/share/man/man7d/mega_sas.7d 0444 root bin f usr/share/man/man7d/mem.7d 0444 root bin +f usr/share/man/man7d/mlxcx.7d 0444 root bin f usr/share/man/man7d/mpt_sas.7d 0444 root bin f usr/share/man/man7d/mr_sas.7d 0444 root bin f usr/share/man/man7d/msglog.7d 0444 root bin diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master index d2402d2fff..02242189d8 100644 --- a/usr/src/Makefile.master +++ b/usr/src/Makefile.master @@ -27,8 +27,8 @@ # Copyright 2015 Gary Mills # Copyright 2015 Igor Kozhukhov <ikozhukhov@gmail.com> # Copyright 2016 Toomas Soome <tsoome@me.com> -# Copyright 2020 Joyent, Inc. # Copyright 2018 OmniOS Community Edition (OmniOSce) Association. +# Copyright 2020 Joyent, Inc. # Copyright 2019 RackTop Systems. # @@ -827,12 +827,16 @@ COMPILE.java= $(JAVAC) $(JAVAFLAGS) -classpath $(CLASSPATH) # CCNEEDED = -lC CCEXTNEEDED = -lCrun -lCstd +NATIVECCNEEDED = -lC $(__GNUC)CCNEEDED = -L$(GCCLIBDIR) -lstdc++ -lgcc_s $(__GNUC)CCEXTNEEDED = $(CCNEEDED) +$(__GNUC)NATIVECCNEEDED = -R$(GCCLIBDIR) -L$(GCCLIBDIR) -lstdc++ -lgcc_s CCNEEDED64 = -lCrun CCEXTNEEDED64 = -lCrun -lCstd +NATIVECCNEEDED64 = -lCrun $(__GNUC64)CCNEEDED64 = -L$(GCCLIBDIR) -lstdc++ -lgcc_s +$(__GNUC64)NATIVECCNEEDED64 = -R$(GCCLIBDIR) -L$(GCCLIBDIR) -lstdc++ -lgcc_s $(__GNUC64)CCEXTNEEDED = $(CCNEEDED64) # Libraries we expect to use natively on the build machine diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index 4c3af63cb9..600cec3537 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -33,4 +33,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2020.02.03.1 +BOOT_VERSION = $(LOADER_VERSION)-2020.02.26.1 diff --git a/usr/src/boot/lib/libstand/zfs/zfsimpl.c b/usr/src/boot/lib/libstand/zfs/zfsimpl.c index c291ef771e..a5c0d4fc73 100644 --- a/usr/src/boot/lib/libstand/zfs/zfsimpl.c +++ b/usr/src/boot/lib/libstand/zfs/zfsimpl.c @@ -137,9 +137,6 @@ static spa_list_t zfs_pools; static const dnode_phys_t *dnode_cache_obj; static uint64_t dnode_cache_bn; static char *dnode_cache_buf; -static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_ptr; - -#define TEMP_SIZE (1024 * 1024) static int zio_read(const spa_t *spa, const blkptr_t *bp, void *buf); static int zfs_get_root(const spa_t *spa, uint64_t *objid); @@ -162,38 +159,11 @@ zfs_init(void) STAILQ_INIT(&zfs_vdevs); STAILQ_INIT(&zfs_pools); - zfs_temp_buf = malloc(TEMP_SIZE); - zfs_temp_end = zfs_temp_buf + TEMP_SIZE; - zfs_temp_ptr = zfs_temp_buf; dnode_cache_buf = malloc(SPA_MAXBLOCKSIZE); zfs_init_crc(); } -static void * -zfs_alloc(size_t size) -{ - char *ptr; - - if (zfs_temp_ptr + size > zfs_temp_end) { - panic("ZFS: out of temporary buffer space"); - } - ptr = zfs_temp_ptr; - zfs_temp_ptr += size; - - return (ptr); -} - -static void -zfs_free(void *ptr, size_t size) -{ - - zfs_temp_ptr -= size; - if (zfs_temp_ptr != ptr) { - panic("ZFS: zfs_alloc()/zfs_free() mismatch"); - } -} - static int xdr_int(const unsigned char **xdr, int *ip) { @@ -2151,17 +2121,20 @@ zio_read(const spa_t *spa, const blkptr_t *bp, void *buf) ASSERT(size <= BPE_PAYLOAD_SIZE); if (cpfunc != ZIO_COMPRESS_OFF) - pbuf = zfs_alloc(size); + pbuf = malloc(size); else pbuf = buf; + if (pbuf == NULL) + return (ENOMEM); + decode_embedded_bp_compressed(bp, pbuf); error = 0; if (cpfunc != ZIO_COMPRESS_OFF) { error = zio_decompress_data(cpfunc, pbuf, size, buf, BP_GET_LSIZE(bp)); - zfs_free(pbuf, size); + free(pbuf); } if (error != 0) printf("ZFS: i/o error - unable to decompress " @@ -2198,10 +2171,15 @@ zio_read(const spa_t *spa, const blkptr_t *bp, void *buf) size = P2ROUNDUP(size, align); } if (size != BP_GET_PSIZE(bp) || cpfunc != ZIO_COMPRESS_OFF) - pbuf = zfs_alloc(size); + pbuf = malloc(size); else pbuf = buf; + if (pbuf == NULL) { + error = ENOMEM; + break; + } + if (DVA_GET_GANG(dva)) error = zio_read_gang(spa, bp, pbuf); else @@ -2214,12 +2192,13 @@ zio_read(const spa_t *spa, const blkptr_t *bp, void *buf) bcopy(pbuf, buf, BP_GET_PSIZE(bp)); } if (buf != pbuf) - zfs_free(pbuf, size); + free(pbuf); if (error == 0) break; } if (error != 0) printf("ZFS: i/o error - all block copies unavailable\n"); + return (error); } @@ -3425,10 +3404,14 @@ zfs_dnode_stat(const spa_t *spa, dnode_phys_t *dn, struct stat *sb) int error; size = BP_GET_LSIZE(bp); - buf = zfs_alloc(size); - error = zio_read(spa, bp, buf); + buf = malloc(size); + if (buf == NULL) + error = ENOMEM; + else + error = zio_read(spa, bp, buf); + if (error != 0) { - zfs_free(buf, size); + free(buf); return (error); } sahdrp = buf; @@ -3445,8 +3428,7 @@ zfs_dnode_stat(const spa_t *spa, dnode_phys_t *dn, struct stat *sb) SA_GID_OFFSET); sb->st_size = *(uint64_t *)((char *)sahdrp + hdrsize + SA_SIZE_OFFSET); - if (buf != NULL) - zfs_free(buf, size); + free(buf); } return (0); @@ -3464,9 +3446,9 @@ zfs_dnode_readlink(const spa_t *spa, dnode_phys_t *dn, char *path, size_t psize) int hdrsize; char *p; - if (dn->dn_bonuslen != 0) + if (dn->dn_bonuslen != 0) { sahdrp = (sa_hdr_phys_t *)DN_BONUS(dn); - else { + } else { blkptr_t *bp; if ((dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR) == 0) @@ -3474,10 +3456,13 @@ zfs_dnode_readlink(const spa_t *spa, dnode_phys_t *dn, char *path, size_t psize) bp = DN_SPILL_BLKPTR(dn); size = BP_GET_LSIZE(bp); - buf = zfs_alloc(size); - rc = zio_read(spa, bp, buf); + buf = malloc(size); + if (buf == NULL) + rc = ENOMEM; + else + rc = zio_read(spa, bp, buf); if (rc != 0) { - zfs_free(buf, size); + free(buf); return (rc); } sahdrp = buf; @@ -3485,8 +3470,7 @@ zfs_dnode_readlink(const spa_t *spa, dnode_phys_t *dn, char *path, size_t psize) hdrsize = SA_HDR_SIZE(sahdrp); p = (char *)((uintptr_t)sahdrp + hdrsize + SA_SYMLINK_OFFSET); memcpy(path, p, psize); - if (buf != NULL) - zfs_free(buf, size); + free(buf); return (0); } /* diff --git a/usr/src/boot/sys/boot/common/module.c b/usr/src/boot/sys/boot/common/module.c index 14aa790973..4936ec5a3c 100644 --- a/usr/src/boot/sys/boot/common/module.c +++ b/usr/src/boot/sys/boot/common/module.c @@ -671,7 +671,8 @@ file_loadraw(const char *fname, char *type, int argc, char **argv, int insert) "error reading '%s': %s", name, strerror(errno)); free(name); close(fd); - if (archsw.arch_free_loadaddr != NULL) { + if (archsw.arch_free_loadaddr != NULL && + st.st_size != 0) { archsw.arch_free_loadaddr(loadaddr, (uint64_t) (roundup2(st.st_size, PAGE_SIZE) >> 12)); @@ -684,7 +685,7 @@ file_loadraw(const char *fname, char *type, int argc, char **argv, int insert) /* Looks OK so far; create & populate control structure */ fp = file_alloc(); if (fp == NULL) { - if (archsw.arch_free_loadaddr != NULL) + if (archsw.arch_free_loadaddr != NULL && st.st_size != 0) archsw.arch_free_loadaddr(loadaddr, (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12)); snprintf(command_errbuf, sizeof (command_errbuf), @@ -1151,7 +1152,8 @@ file_discard(struct preloaded_file *fp) if (fp == NULL) return; - if (archsw.arch_free_loadaddr != NULL && fp->f_addr) { + if (archsw.arch_free_loadaddr != NULL && fp->f_addr && + fp->f_size != 0) { archsw.arch_free_loadaddr(fp->f_addr, (uint64_t)(roundup2(fp->f_size, PAGE_SIZE) >> 12)); } diff --git a/usr/src/boot/sys/boot/efi/loader/copy.c b/usr/src/boot/sys/boot/efi/loader/copy.c index 0dd8e8a5cc..77a0703136 100644 --- a/usr/src/boot/sys/boot/efi/loader/copy.c +++ b/usr/src/boot/sys/boot/efi/loader/copy.c @@ -174,6 +174,10 @@ efi_loadaddr(uint_t type, void *data, vm_offset_t addr) size = st.st_size; } + /* AllocatePages can not allocate 0 pages. */ + if (size == 0) + return (addr); + pages = EFI_SIZE_TO_PAGES(size); /* 4GB upper limit */ paddr = UINT32_MAX; diff --git a/usr/src/boot/sys/cddl/boot/zfs/zfssubr.c b/usr/src/boot/sys/cddl/boot/zfs/zfssubr.c index 0d509ed4a1..d4bcb9ac06 100644 --- a/usr/src/boot/sys/cddl/boot/zfs/zfssubr.c +++ b/usr/src/boot/sys/cddl/boot/zfs/zfssubr.c @@ -36,9 +36,6 @@ static uint64_t zfs_crc64_table[256]; #define ASSERT0(x) ((void)0) #define ASSERT(x) ((void)0) -#define kmem_alloc(size, flag) zfs_alloc((size)) -#define kmem_free(ptr, size) zfs_free((ptr), (size)) - static void zfs_init_crc(void) { @@ -377,9 +374,6 @@ zap_hash(uint64_t salt, const char *name) return (crc); } -static void *zfs_alloc(size_t size); -static void zfs_free(void *ptr, size_t size); - typedef struct raidz_col { uint64_t rc_devidx; /* child device index for I/O */ uint64_t rc_offset; /* device offset */ @@ -982,7 +976,11 @@ vdev_raidz_matrix_reconstruct(raidz_map_t *rm, int n, int nmissing, log = 0; /* gcc */ psize = sizeof (invlog[0][0]) * n * nmissing; - p = zfs_alloc(psize); + p = malloc(psize); + if (p == NULL) { + printf("Out of memory\n"); + return; + } for (pp = p, i = 0; i < nmissing; i++) { invlog[i] = pp; @@ -1038,7 +1036,7 @@ vdev_raidz_matrix_reconstruct(raidz_map_t *rm, int n, int nmissing, } } - zfs_free(p, psize); + free(p); } static int @@ -1099,7 +1097,11 @@ vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts) psize = (sizeof (rows[0][0]) + sizeof (invrows[0][0])) * nmissing_rows * n + sizeof (used[0]) * n; - p = kmem_alloc(psize, KM_SLEEP); + p = malloc(psize); + if (p == NULL) { + printf("Out of memory\n"); + return (code); + } for (pp = p, i = 0; i < nmissing_rows; i++) { rows[i] = pp; @@ -1142,7 +1144,7 @@ vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts) vdev_raidz_matrix_reconstruct(rm, n, nmissing_rows, missing_rows, invrows, used); - kmem_free(p, psize); + free(p); return (code); } @@ -1215,7 +1217,9 @@ vdev_raidz_map_alloc(void *data, off_t offset, size_t size, uint64_t unit_shift, ASSERT3U(acols, <=, scols); - rm = zfs_alloc(offsetof(raidz_map_t, rm_col[scols])); + rm = malloc(offsetof(raidz_map_t, rm_col[scols])); + if (rm == NULL) + return (rm); rm->rm_cols = acols; rm->rm_scols = scols; @@ -1260,8 +1264,16 @@ vdev_raidz_map_alloc(void *data, off_t offset, size_t size, uint64_t unit_shift, ASSERT3U(rm->rm_asize - asize, ==, rm->rm_nskip << unit_shift); ASSERT3U(rm->rm_nskip, <=, nparity); - for (c = 0; c < rm->rm_firstdatacol; c++) - rm->rm_col[c].rc_data = zfs_alloc(rm->rm_col[c].rc_size); + for (c = 0; c < rm->rm_firstdatacol; c++) { + rm->rm_col[c].rc_data = malloc(rm->rm_col[c].rc_size); + if (rm->rm_col[c].rc_data == NULL) { + c++; + while (c != 0) + free(rm->rm_col[--c].rc_data); + free(rm); + return (NULL); + } + } rm->rm_col[c].rc_data = data; @@ -1313,9 +1325,9 @@ vdev_raidz_map_free(raidz_map_t *rm) int c; for (c = rm->rm_firstdatacol - 1; c >= 0; c--) - zfs_free(rm->rm_col[c].rc_data, rm->rm_col[c].rc_size); + free(rm->rm_col[c].rc_data); - zfs_free(rm, offsetof(raidz_map_t, rm_col[rm->rm_scols])); + free(rm); } static vdev_t * @@ -1360,8 +1372,12 @@ raidz_parity_verify(raidz_map_t *rm) rc = &rm->rm_col[c]; if (!rc->rc_tried || rc->rc_error != 0) continue; - orig[c] = zfs_alloc(rc->rc_size); - bcopy(rc->rc_data, orig[c], rc->rc_size); + orig[c] = malloc(rc->rc_size); + if (orig[c] != NULL) { + bcopy(rc->rc_data, orig[c], rc->rc_size); + } else { + printf("Out of memory\n"); + } } vdev_raidz_generate_parity(rm); @@ -1370,11 +1386,12 @@ raidz_parity_verify(raidz_map_t *rm) rc = &rm->rm_col[c]; if (!rc->rc_tried || rc->rc_error != 0) continue; - if (bcmp(orig[c], rc->rc_data, rc->rc_size) != 0) { + if (orig[c] == NULL || + bcmp(orig[c], rc->rc_data, rc->rc_size) != 0) { rc->rc_error = ECKSUM; ret++; } - zfs_free(orig[c], rc->rc_size); + free(orig[c]); } return (ret); @@ -1443,7 +1460,11 @@ vdev_raidz_combrec(const spa_t *spa, raidz_map_t *rm, const blkptr_t *bp, ASSERT(orig[i] != NULL); } - orig[n - 1] = zfs_alloc(rm->rm_col[0].rc_size); + orig[n - 1] = malloc(rm->rm_col[0].rc_size); + if (orig[n - 1] == NULL) { + ret = ENOMEM; + goto done; + } current = 0; next = tgts[current]; @@ -1526,7 +1547,7 @@ vdev_raidz_combrec(const spa_t *spa, raidz_map_t *rm, const blkptr_t *bp, n--; done: for (i = n - 1; i >= 0; i--) { - zfs_free(orig[i], rm->rm_col[0].rc_size); + free(orig[i]); } return (ret); @@ -1555,6 +1576,8 @@ vdev_raidz_read(vdev_t *vd, const blkptr_t *bp, void *data, rm = vdev_raidz_map_alloc(data, offset, bytes, tvd->v_ashift, vd->v_nchildren, vd->v_nparity); + if (rm == NULL) + return (ENOMEM); /* * Iterate over the columns in reverse order so that we hit the parity diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c index 92f3bfb665..a69b3da081 100644 --- a/usr/src/cmd/dladm/dladm.c +++ b/usr/src/cmd/dladm/dladm.c @@ -23,6 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2017 Joyent, Inc. * Copyright 2016 Nexenta Systems, Inc. + * Copyright 2020 Peter Tribble. */ #include <stdio.h> @@ -1148,7 +1149,7 @@ typedef struct usage_fields_buf_s { char usage_rbytes[10]; char usage_opackets[9]; char usage_obytes[10]; - char usage_bandwidth[14]; + char usage_bandwidth[15]; } usage_fields_buf_t; static const ofmt_field_t usage_fields[] = { @@ -1164,7 +1165,7 @@ static const ofmt_field_t usage_fields[] = { offsetof(usage_fields_buf_t, usage_opackets), print_default_cb}, { "OBYTES", 11, offsetof(usage_fields_buf_t, usage_obytes), print_default_cb}, -{ "BANDWIDTH", 15, +{ "BANDWIDTH", 16, offsetof(usage_fields_buf_t, usage_bandwidth), print_default_cb}, { NULL, 0, 0, NULL}} ; @@ -1180,7 +1181,7 @@ typedef struct usage_l_fields_buf_s { char usage_l_etime[13]; char usage_l_rbytes[8]; char usage_l_obytes[8]; - char usage_l_bandwidth[14]; + char usage_l_bandwidth[15]; } usage_l_fields_buf_t; static const ofmt_field_t usage_l_fields[] = { @@ -1195,7 +1196,7 @@ static const ofmt_field_t usage_l_fields[] = { offsetof(usage_l_fields_buf_t, usage_l_rbytes), print_default_cb}, { "OBYTES", 9, offsetof(usage_l_fields_buf_t, usage_l_obytes), print_default_cb}, -{ "BANDWIDTH", 15, +{ "BANDWIDTH", 16, offsetof(usage_l_fields_buf_t, usage_l_bandwidth), print_default_cb}, { NULL, 0, 0, NULL}} ; diff --git a/usr/src/cmd/dlstat/dlstat.c b/usr/src/cmd/dlstat/dlstat.c index 8c1749475b..d11e623206 100644 --- a/usr/src/cmd/dlstat/dlstat.c +++ b/usr/src/cmd/dlstat/dlstat.c @@ -27,6 +27,10 @@ * Copyright 2017 Joyent, Inc. */ +/* + * Copyright 2020 Peter Tribble. + */ + #include <stdio.h> #include <ctype.h> #include <locale.h> @@ -417,7 +421,7 @@ typedef struct history_fields_buf_s { char h_rbytes[10]; char h_opackets[9]; char h_obytes[10]; - char h_bandwidth[14]; + char h_bandwidth[15]; } history_fields_buf_t; static ofmt_field_t history_fields[] = { @@ -433,7 +437,7 @@ static ofmt_field_t history_fields[] = { offsetof(history_fields_buf_t, h_opackets), print_default_cb}, { "OBYTES", 11, offsetof(history_fields_buf_t, h_obytes), print_default_cb}, -{ "BANDWIDTH", 15, +{ "BANDWIDTH", 16, offsetof(history_fields_buf_t, h_bandwidth), print_default_cb}, { NULL, 0, 0, NULL}}; @@ -446,7 +450,7 @@ typedef struct history_l_fields_buf_s { char hl_etime[13]; char hl_rbytes[8]; char hl_obytes[8]; - char hl_bandwidth[14]; + char hl_bandwidth[15]; } history_l_fields_buf_t; static ofmt_field_t history_l_fields[] = { @@ -461,7 +465,7 @@ static ofmt_field_t history_l_fields[] = { offsetof(history_l_fields_buf_t, hl_rbytes), print_default_cb}, { "OBYTES", 9, offsetof(history_l_fields_buf_t, hl_obytes), print_default_cb}, -{ "BANDWIDTH", 15, +{ "BANDWIDTH", 16, offsetof(history_l_fields_buf_t, hl_bandwidth), print_default_cb}, { NULL, 0, 0, NULL}} ; @@ -569,7 +573,7 @@ show_history_time(dladm_usage_t *history, void *arg) { show_history_state_t *state = arg; char buf[DLADM_STRSIZE]; - history_l_fields_buf_t ubuf; + history_l_fields_buf_t ubuf; time_t time; double bw; dladm_status_t status; @@ -754,7 +758,7 @@ do_show_history(int argc, char *argv[], const char *use) die("show-link -h requires a file"); if (optind == (argc-1)) { - uint32_t flags; + uint32_t flags; resource = argv[optind]; if (!state.hs_showall && @@ -1500,7 +1504,7 @@ static int show_queried_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg) { show_state_t *state = arg; - int i; + int i; dladm_stat_chain_t *diff_stat; char linkname[DLPI_LINKNAME_MAX]; char zonename[DLADM_PROP_VAL_MAX + 1]; @@ -1654,7 +1658,7 @@ do_show(int argc, char *argv[], const char *use) ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = OFMT_RIGHTJUST; - ofmt_field_t *oftemplate; + ofmt_field_t *oftemplate; bzero(&state, sizeof (state)); opterr = 0; @@ -1855,7 +1859,7 @@ do_show_phys(int argc, char *argv[], const char *use) ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = OFMT_RIGHTJUST; - ofmt_field_t *oftemplate; + ofmt_field_t *oftemplate; bzero(&state, sizeof (state)); opterr = 0; @@ -2037,7 +2041,7 @@ do_show_link(int argc, char *argv[], const char *use) ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = OFMT_RIGHTJUST; - ofmt_field_t *oftemplate; + ofmt_field_t *oftemplate; bzero(&state, sizeof (state)); opterr = 0; @@ -2242,7 +2246,7 @@ do_show_aggr(int argc, char *argv[], const char *use) ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = OFMT_RIGHTJUST; - ofmt_field_t *oftemplate; + ofmt_field_t *oftemplate; bzero(&state, sizeof (state)); opterr = 0; diff --git a/usr/src/cmd/ed/ed.c b/usr/src/cmd/ed/ed.c index e8593cadbf..a2fae9c409 100644 --- a/usr/src/cmd/ed/ed.c +++ b/usr/src/cmd/ed/ed.c @@ -24,7 +24,7 @@ */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * Editor @@ -41,7 +41,7 @@ #include <errno.h> #include <paths.h> -static const char *msgtab[] = +static const char *msgtab[] = { "write or open on pipe failed", /* 0 */ "warning: expecting `w'", /* 1 */ @@ -161,7 +161,6 @@ static const char *msgtab[] = extern char *optarg; /* Value of argument */ extern int optind; /* Indicator of argument */ -extern int __xpg4; /* defined in xpg4.c; 0 if not xpg4-compiled program */ struct Fspec { char Ftabs[22]; @@ -253,15 +252,15 @@ static int fflg, shflg; static char prompt[16] = "*"; static int rflg; static int readflg; -static int eflg; -static int qflg = 0; -static int ncflg; -static int listn; -static int listf; -static int pflag; -static int flag28 = 0; /* Prevents write after a partial read */ -static int save28 = 0; /* Flag whether buffer empty at start of read */ -static long savtime; +static int eflg; +static int qflg = 0; +static int ncflg; +static int listn; +static int listf; +static int pflag; +static int flag28 = 0; /* Prevents write after a partial read */ +static int save28 = 0; /* Flag whether buffer empty at start of read */ +static long savtime; static char *name = "SHELL"; static char *rshell = "/usr/lib/rsh"; static char *val; @@ -466,7 +465,7 @@ main(int argc, char **argv) ; globp = "e"; fflg++; - } else /* editing with no file so set savtime to 0 */ + } else /* editing with no file so set savtime to 0 */ savtime = 0; eflg++; if ((tfname = tempnam("", "ea")) == NULL) { @@ -3061,8 +3060,8 @@ static char stdtabs[] = { 'f', 0, 1, 7, 11, 15, 19, 23, 0, /* FORTRAN */ 'p', 0, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 0, /* PL/I */ -'s', 0, 1, 10, 55, 0, /* SNOBOL */ -'u', 0, 1, 12, 20, 44, 0, /* UNIVAC ASM */ +'s', 0, 1, 10, 55, 0, /* SNOBOL */ +'u', 0, 1, 12, 20, 44, 0, /* UNIVAC ASM */ 0 }; diff --git a/usr/src/cmd/find/find.c b/usr/src/cmd/find/find.c index 5b5811ea6a..8860e9b711 100644 --- a/usr/src/cmd/find/find.c +++ b/usr/src/cmd/find/find.c @@ -22,6 +22,7 @@ * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013 Andrew Stormont. All rights reserved. + * Copyright 2020 Joyent, Inc. */ @@ -1027,9 +1028,12 @@ execute(const char *name, const struct stat *statb, int type, struct FTW *state) * /usr/bin/find will not pattern match a leading * '.' in a filename, unless '.' is explicitly * specified. + * + * The legacy behavior makes no sense for PATH. */ #ifndef XPG4 - fnmflags |= FNM_PERIOD; + if (np->action == NAME || np->action == INAME) + fnmflags |= FNM_PERIOD; #endif val = !fnmatch(np->first.cp, diff --git a/usr/src/cmd/flowstat/flowstat.c b/usr/src/cmd/flowstat/flowstat.c index e772470f9d..a0e2b85f32 100644 --- a/usr/src/cmd/flowstat/flowstat.c +++ b/usr/src/cmd/flowstat/flowstat.c @@ -31,6 +31,10 @@ * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. */ +/* + * Copyright 2020 Peter Tribble. + */ + #include <stdio.h> #include <locale.h> #include <stdarg.h> @@ -139,7 +143,7 @@ typedef struct history_fields_buf_s { char history_rbytes[10]; char history_opackets[9]; char history_obytes[10]; - char history_bandwidth[14]; + char history_bandwidth[15]; } history_fields_buf_t; static ofmt_field_t history_fields[] = { @@ -156,7 +160,7 @@ static ofmt_field_t history_fields[] = { offsetof(history_fields_buf_t, history_opackets), print_default_cb}, { "OBYTES", 11, offsetof(history_fields_buf_t, history_obytes), print_default_cb}, -{ "BANDWIDTH", 15, +{ "BANDWIDTH", 16, offsetof(history_fields_buf_t, history_bandwidth), print_default_cb}, NULL_OFMT} ; @@ -167,7 +171,7 @@ typedef struct history_l_fields_buf_s { char history_l_etime[13]; char history_l_rbytes[8]; char history_l_obytes[8]; - char history_l_bandwidth[14]; + char history_l_bandwidth[15]; } history_l_fields_buf_t; static ofmt_field_t history_l_fields[] = { @@ -182,7 +186,7 @@ static ofmt_field_t history_l_fields[] = { offsetof(history_l_fields_buf_t, history_l_rbytes), print_default_cb}, { "OBYTES", 9, offsetof(history_l_fields_buf_t, history_l_obytes), print_default_cb}, -{ "BANDWIDTH", 15, +{ "BANDWIDTH", 16, offsetof(history_l_fields_buf_t, history_l_bandwidth), print_default_cb}, NULL_OFMT} @@ -544,7 +548,7 @@ dump_all_flow_stats(dladm_flow_attr_t *attrp, void *arg, datalink_id_t linkid, int main(int argc, char *argv[]) { - dladm_status_t status; + dladm_status_t status; int option; boolean_t r_arg = B_FALSE; boolean_t t_arg = B_FALSE; @@ -790,7 +794,7 @@ show_history_time(dladm_usage_t *history, void *arg) { show_history_state_t *state = (show_history_state_t *)arg; char buf[DLADM_STRSIZE]; - history_l_fields_buf_t ubuf; + history_l_fields_buf_t ubuf; time_t time; double bw; dladm_flow_attr_t attr; diff --git a/usr/src/cmd/fm/dicts/Makefile b/usr/src/cmd/fm/dicts/Makefile index 22bebd3ae8..93e0303f83 100644 --- a/usr/src/cmd/fm/dicts/Makefile +++ b/usr/src/cmd/fm/dicts/Makefile @@ -38,7 +38,8 @@ common_DCNAMES = \ SCA1000 \ SENSOR \ STORAGE \ - TEST + TEST \ + NIC i386_DCNAMES = \ AMD \ diff --git a/usr/src/cmd/fm/dicts/NIC.dict b/usr/src/cmd/fm/dicts/NIC.dict new file mode 100644 index 0000000000..670dc53d46 --- /dev/null +++ b/usr/src/cmd/fm/dicts/NIC.dict @@ -0,0 +1,21 @@ +# +# Copyright 2020 the University of Queensland +# Use is subject to license terms. +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +FMDICT: name=NIC version=1 maxkey=4 + +fault.io.nic.transceiver.notsupp=0 +fault.io.nic.transceiver.whitelist=1 +fault.io.nic.transceiver.overtemp=2 +fault.io.nic.transceiver.hwfail=3 +fault.io.nic.transceiver.unknown=4 diff --git a/usr/src/cmd/fm/dicts/NIC.po b/usr/src/cmd/fm/dicts/NIC.po new file mode 100644 index 0000000000..46f1c859b9 --- /dev/null +++ b/usr/src/cmd/fm/dicts/NIC.po @@ -0,0 +1,98 @@ +# +# Copyright 2020 the University of Queensland +# Use is subject to license terms. +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# code: NIC-8000-0Q +# keys: fault.io.nic.transceiver.notsupp +# +msgid "NIC-8000-0Q.type" +msgstr "Fault" +msgid "NIC-8000-0Q.severity" +msgstr "Critical" +msgid "NIC-8000-0Q.description" +msgstr "NIC transceiver module %<fault-list[0].resource.hc-specific.txr_index> (SFP/SFP+/QSFP+ etc.) in %<fault-list[0].resource.hc-specific.link-name> is of a type that is not supported. This may be due to an incompatible link type or speed. In some NICs, this may also be caused by enforcement of a vendor or part whitelist.\n\n NIC data link: %<fault-list[0].resource.hc-specific.link-name> (%<fault-list[0].resource.hc-specific.primary-mac-address>)\n Module vendor: %<fault-list[0].resource.hc-specific.vendor>\n Module part: %<fault-list[0].resource.part>\n Module serial: %<fault-list[0].resource.serial>\n\n Refer to %s for more information." +msgid "NIC-8000-0Q.response" +msgstr "The transceiver module has been disabled, and the network data link associated with it (%<fault-list[0].resource.hc-specific.link-name>) has been marked as down.\n" +msgid "NIC-8000-0Q.impact" +msgstr "No network traffic will pass through the data link or network interfaces associated with this transceiver slot.\n" +msgid "NIC-8000-0Q.action" +msgstr "Replace the transceiver module with one of a supported type.\n" + +# +# code: NIC-8000-1C +# keys: fault.io.nic.transceiver.whitelist +# +msgid "NIC-8000-1C.type" +msgstr "Fault" +msgid "NIC-8000-1C.severity" +msgstr "Critical" +msgid "NIC-8000-1C.description" +msgstr "NIC transceiver module %<fault-list[0].resource.hc-specific.txr_index> (SFP/SFP+/QSFP+ etc.) in %<fault-list[0].resource.hc-specific.link-name> is of a type that is not allowed to be used with this NIC (due to a hardware-enforced vendor or part whitelist).\n\n NIC data link: %<fault-list[0].resource.hc-specific.link-name> (%<fault-list[0].resource.hc-specific.primary-mac-address>)\n Module vendor: %<fault-list[0].resource.hc-specific.vendor>\n Module part: %<fault-list[0].resource.part>\n Module serial: %<fault-list[0].resource.serial>\n\n Refer to %s for more information." +msgid "NIC-8000-1C.response" +msgstr "The transceiver module has been disabled, and the network data link associated with it (%<fault-list[0].resource.hc-specific.link-name>) has been marked as down.\n" +msgid "NIC-8000-1C.impact" +msgstr "No network traffic will pass through the data link or network\ninterfaces associated with this transceiver slot.\n" +msgid "NIC-8000-1C.action" +msgstr "Replace the transceiver module with one of a supported type.\n" + +# +# code: NIC-8000-2R +# keys: fault.io.nic.transceiver.overtemp +# +msgid "NIC-8000-2R.type" +msgstr "Fault" +msgid "NIC-8000-2R.severity" +msgstr "Critical" +msgid "NIC-8000-2R.description" +msgstr "NIC transceiver module %<fault-list[0].resource.hc-specific.txr_index> (SFP/SFP+/QSFP+ etc.) in %<fault-list[0].resource.hc-specific.link-name> has overheated.\n\n NIC data link: %<fault-list[0].resource.hc-specific.link-name> (%<fault-list[0].resource.hc-specific.primary-mac-address>)\n Module vendor: %<fault-list[0].resource.hc-specific.vendor>\n Module part: %<fault-list[0].resource.part>\n Module serial: %<fault-list[0].resource.serial>\n\n Refer to %s for more information." +msgid "NIC-8000-2R.response" +msgstr "The transceiver module has been disabled, and the network data link associated with it (%<fault-list[0].resource.hc-specific.link-name>) has been marked as down.\n" +msgid "NIC-8000-2R.impact" +msgstr "No network traffic will pass through the data link or network interfaces associated with this transceiver slot.\n" +msgid "NIC-8000-2R.action" +msgstr "Remove the transceiver module and check for adequate ventilation\nand cooling. Re-inserting the module after it has cooled will restore service.\n" + +# +# code: NIC-8000-34 +# keys: fault.io.nic.transceiver.hwfail +# +msgid "NIC-8000-34.type" +msgstr "Fault" +msgid "NIC-8000-34.severity" +msgstr "Critical" +msgid "NIC-8000-34.description" +msgstr "NIC transceiver module %<fault-list[0].resource.hc-specific.txr_index> (SFP/SFP+/QSFP+ etc.) in %<fault-list[0].resource.hc-specific.link-name> has experienced a hardware failure.\n\n NIC data link: %<fault-list[0].resource.hc-specific.link-name> (%<fault-list[0].resource.hc-specific.primary-mac-address>)\n Module vendor: %<fault-list[0].resource.hc-specific.vendor>\n Module part: %<fault-list[0].resource.part>\n Module serial: %<fault-list[0].resource.serial>\n\n Refer to %s for more information." +msgid "NIC-8000-34.response" +msgstr "The transceiver module has been disabled, and the network data link associated with it (%<fault-list[0].resource.hc-specific.link-name>) has been marked as down.\n" +msgid "NIC-8000-34.impact" +msgstr "No network traffic will pass through the data link or network\ninterfaces associated with this transceiver slot.\n" +msgid "NIC-8000-34.action" +msgstr "Remove and check the transceiver module, and consider replacing it.\n" + +# +# code: NIC-8000-4X +# keys: fault.io.nic.transceiver.unknown +# +msgid "NIC-8000-4X.type" +msgstr "Fault" +msgid "NIC-8000-4X.severity" +msgstr "Critical" +msgid "NIC-8000-4X.description" +msgstr "The slot for NIC transceiver module %<fault-list[0].resource.hc-specific.txr_index> (SFP/SFP+/QSFP+ etc.) in %<fault-list[0].resource.hc-specific.link-name> is occupied, but hardware did not find a valid transceiver in it.\n Refer to %s for more information." +msgid "NIC-8000-4X.response" +msgstr "The transceiver module slot has been disabled, and the network data link associated with it (%<fault-list[0].resource.hc-specific.link-name>) has been marked as down.\n" +msgid "NIC-8000-4X.impact" +msgstr "No network traffic will pass through the data link or network\ninterfaces associated with this transceiver slot.\n" +msgid "NIC-8000-4X.action" +msgstr "Remove and check the transceiver module. It may be faulty,\ninserted incorrectly, or not of the correct type for the slot.\nIf problems persist, consider replacing the module.\n" diff --git a/usr/src/cmd/fm/eversholt/files/common/nic.esc b/usr/src/cmd/fm/eversholt/files/common/nic.esc new file mode 100644 index 0000000000..6dfaf5fa5b --- /dev/null +++ b/usr/src/cmd/fm/eversholt/files/common/nic.esc @@ -0,0 +1,127 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ +/* + * Copyright 2020, the University of Queensland + */ + +#pragma dictionary "NIC" + +/* + * Rules for the generic NIC (non-driver-specific) fault events. + */ + +/* + * Transceiver events are emitted by drivers under ereport.io.nic.txr-err. + * + * These are emitted with detector = the PCI/PCIex function of the NIC. + * They must always have a string property "error", set to one of the + * generic transceiver fault type names (notsupp, whitelist, overtemp etc). + * + * As well as "error", they must have both the "port_index" and "txr_index" + * properties set in the event payload (both integer types). + * + * It is expected that drivers will call ddi_fm_service_impact() immediately + * after noticing a transceiver error, with an argument of DDI_SERVICE_LOST or + * DDI_SERVICE_DEGRADED (depending on the specific error -- at time of writing + * all the supported events expect DDI_SERVICE_LOST). + */ + +asru pcifn; +fru pcifn/port/transceiver; + +asru pciexfn; +fru pciexfn/port/transceiver; + +#define EV_DECL_TXR_FAULT(TYPE) \ + event fault.io.nic.transceiver.TYPE@pcifn/port/transceiver \ + FRU=pcifn/port/transceiver, ASRU=pcifn; \ + event fault.io.nic.transceiver.TYPE@pciexfn/port/transceiver \ + FRU=pciexfn/port/transceiver, ASRU=pciexfn; + +EV_DECL_TXR_FAULT(notsupp) +EV_DECL_TXR_FAULT(whitelist) +EV_DECL_TXR_FAULT(overtemp) +EV_DECL_TXR_FAULT(hwfail) +EV_DECL_TXR_FAULT(unknown) + +event ereport.io.nic.txr-err@pcifn; +event ereport.io.service.lost@pcifn; + +event ereport.io.nic.txr-err@pciexfn; +event ereport.io.service.lost@pciexfn; + +#define EV_PROP_TXR_FAULT(TYPE) \ + prop fault.io.nic.transceiver.TYPE@pcifn/port[pn]/transceiver[tn] (2) -> \ + ereport.io.nic.txr-err@pcifn { \ + payloadprop("txr_index") == tn && \ + payloadprop("port_index") == pn && \ + payloadprop("error") == "TYPE" && \ + setpayloadprop("txr_index", tn) && \ + setpayloadprop("link-name", confprop(pcifn/port[pn], "link-name")) && \ + setpayloadprop("primary-mac-address", confprop(pcifn/port[pn], "primary-mac-address")) && \ + (!confprop_defined(pcifn/port[pn]/transceiver[tn], "vendor") || \ + setpayloadprop("vendor", confprop(pcifn/port[pn]/transceiver[tn], "vendor"))) \ + }, \ + ereport.io.service.lost@pcifn { within(1s) }; \ + prop fault.io.nic.transceiver.TYPE@pciexfn/port[pn]/transceiver[tn] (2) -> \ + ereport.io.nic.txr-err@pciexfn { \ + payloadprop("txr_index") == tn && \ + payloadprop("port_index") == pn && \ + payloadprop("error") == "TYPE" && \ + setpayloadprop("txr_index", tn) && \ + setpayloadprop("link-name", confprop(pciexfn/port[pn], "link-name")) && \ + setpayloadprop("primary-mac-address", confprop(pciexfn/port[pn], "primary-mac-address")) && \ + (!confprop_defined(pciexfn/port[pn]/transceiver[tn], "vendor") || \ + setpayloadprop("vendor", confprop(pciexfn/port[pn]/transceiver[tn], "vendor"))) \ + }, \ + ereport.io.service.lost@pciexfn { within(1s) }; + +EV_PROP_TXR_FAULT(notsupp) +EV_PROP_TXR_FAULT(whitelist) +EV_PROP_TXR_FAULT(overtemp) +EV_PROP_TXR_FAULT(hwfail) +EV_PROP_TXR_FAULT(unknown) + +/* + * Allow drivers (e.g. i40e) which can't tell the difference between the events + * notsupp/unknown/whitelist to generate a single ereport covering all 3. + * + * If transceiver information is available in topo, we will turn it into + * a "notsupp" fault. If it isn't, we'll turn it into an "unknown" fault + * instead. The text in "notsupp" explicitly notes that certain drivers might + * have difficulty telling the difference between it and "whitelist". + * + * If you want this for a pcifn driver rather than pciexfn, you'll have to + * make another copy. + */ +prop fault.io.nic.transceiver.notsupp@pciexfn/port[pn]/transceiver[tn] (2) -> + ereport.io.nic.txr-err@pciexfn { + payloadprop("txr_index") == tn && + payloadprop("port_index") == pn && + payloadprop("error") == "notsupp/unknown" && + confprop_defined(pciexfn/port[pn]/transceiver[tn], "vendor") && + setpayloadprop("txr_index", tn) && + setpayloadprop("link-name", confprop(pciexfn/port[pn], "link-name")) && + setpayloadprop("primary-mac-address", confprop(pciexfn/port[pn], "primary-mac-address")) && + setpayloadprop("vendor", confprop(pciexfn/port[pn]/transceiver[tn], "vendor")) + }, + ereport.io.service.lost@pciexfn { within(1s) }; +prop fault.io.nic.transceiver.unknown@pciexfn/port[pn]/transceiver[tn] (2) -> + ereport.io.nic.txr-err@pciexfn { + payloadprop("txr_index") == tn && + payloadprop("port_index") == pn && + payloadprop("error") == "notsupp/unknown" && + !confprop_defined(pciexfn/port[pn]/transceiver[tn], "vendor") && + setpayloadprop("txr_index", tn) && + setpayloadprop("link-name", confprop(pciexfn/port[pn], "link-name")) && + setpayloadprop("primary-mac-address", confprop(pciexfn/port[pn], "primary-mac-address")) + }, + ereport.io.service.lost@pciexfn { within(1s) }; diff --git a/usr/src/cmd/fm/eversholt/files/i386/Makefile b/usr/src/cmd/fm/eversholt/files/i386/Makefile index bb6cda3b38..67caa4468e 100644 --- a/usr/src/cmd/fm/eversholt/files/i386/Makefile +++ b/usr/src/cmd/fm/eversholt/files/i386/Makefile @@ -33,7 +33,8 @@ EFT_COMMON_FILES= \ sca500.eft \ sca1000.eft \ sensor.eft \ - storage.eft + storage.eft \ + nic.eft include ../../../Makefile.subdirs diff --git a/usr/src/cmd/fm/eversholt/files/sparc/Makefile b/usr/src/cmd/fm/eversholt/files/sparc/Makefile index 4e5655cbf7..0482b12b33 100644 --- a/usr/src/cmd/fm/eversholt/files/sparc/Makefile +++ b/usr/src/cmd/fm/eversholt/files/sparc/Makefile @@ -34,7 +34,8 @@ EFT_COMMON_FILES= \ sca500.eft \ sca1000.eft \ sensor.eft \ - storage.eft + storage.eft \ + nic.eft include ../../../Makefile.subdirs diff --git a/usr/src/cmd/fm/fmd/common/fmd.c b/usr/src/cmd/fm/fmd/common/fmd.c index 8177c81049..7369a68047 100644 --- a/usr/src/cmd/fm/fmd/common/fmd.c +++ b/usr/src/cmd/fm/fmd/common/fmd.c @@ -169,8 +169,8 @@ fmd_trmode_set(fmd_conf_param_t *pp, const char *value) else return (fmd_set_errno(EFMD_CONF_INVAL)); - fmd.d_thr_trace = (void (*)())func; - pp->cp_value.cpv_ptr = (void *)func; + fmd.d_thr_trace = func; + pp->cp_value.cpv_ptr = func; return (0); } diff --git a/usr/src/cmd/fm/fmd/common/fmd.h b/usr/src/cmd/fm/fmd/common/fmd.h index 272fa3c305..fa2d4710b7 100644 --- a/usr/src/cmd/fm/fmd/common/fmd.h +++ b/usr/src/cmd/fm/fmd/common/fmd.h @@ -36,6 +36,7 @@ extern "C" { #include <fmd_list.h> #include <fmd_time.h> #include <fmd_api.h> +#include <fmd_trace.h> struct fmd_conf; /* see <fmd_conf.h> */ struct fmd_dispq; /* see <fmd_dispq.h> */ @@ -89,7 +90,7 @@ typedef struct fmd { pthread_mutex_t d_thr_lock; /* lock for d_thr_list */ fmd_list_t d_thr_list; /* list of all fmd_thread_t's */ - void (*d_thr_trace)(); /* thread trace buffer function */ + fmd_tracebuf_f *d_thr_trace; /* thread trace buffer function */ int d_thr_sig; /* cached copy of client.thrsig */ pthread_mutex_t d_mod_lock; /* lock for d_mod_list */ diff --git a/usr/src/cmd/fm/fmd/common/fmd_api.c b/usr/src/cmd/fm/fmd/common/fmd_api.c index 008a55c90f..594e41896d 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_api.c +++ b/usr/src/cmd/fm/fmd/common/fmd_api.c @@ -1872,7 +1872,7 @@ fmd_doorthr_create(door_info_t *dip, void *(*crf)(void *), void *crarg, return (0); } - if ((new_tp = fmd_doorthread_create(mp, (fmd_thread_f *)crf, + if ((new_tp = fmd_doorthread_create(mp, (fmd_thread_f *)(uintptr_t)crf, crarg)) != NULL) { tid = new_tp->thr_tid; mp->mod_stats->ms_doorthrtotal.fmds_value.ui32++; diff --git a/usr/src/cmd/fm/fmd/common/fmd_case.c b/usr/src/cmd/fm/fmd/common/fmd_case.c index dff15220a7..9ffa939cd1 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_case.c +++ b/usr/src/cmd/fm/fmd/common/fmd_case.c @@ -1572,9 +1572,9 @@ fmd_case_rele_locked(fmd_case_t *cp) } int -fmd_case_insert_principal(fmd_case_t *cp, fmd_event_t *ep) +fmd_case_insert_principal(void *cp, fmd_event_t *ep) { - fmd_case_impl_t *cip = (fmd_case_impl_t *)cp; + fmd_case_impl_t *cip = cp; fmd_case_item_t *cit; fmd_event_t *oep; uint_t state; @@ -1611,9 +1611,9 @@ fmd_case_insert_principal(fmd_case_t *cp, fmd_event_t *ep) } int -fmd_case_insert_event(fmd_case_t *cp, fmd_event_t *ep) +fmd_case_insert_event(void *cp, fmd_event_t *ep) { - fmd_case_impl_t *cip = (fmd_case_impl_t *)cp; + fmd_case_impl_t *cip = cp; fmd_case_item_t *cit; uint_t state; int new; diff --git a/usr/src/cmd/fm/fmd/common/fmd_case.h b/usr/src/cmd/fm/fmd/common/fmd_case.h index 733826e91c..92b6a91de5 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_case.h +++ b/usr/src/cmd/fm/fmd/common/fmd_case.h @@ -130,8 +130,8 @@ extern void fmd_case_rele(fmd_case_t *); extern void fmd_case_rele_locked(fmd_case_t *); extern void fmd_case_update(fmd_case_t *); -extern int fmd_case_insert_principal(fmd_case_t *, fmd_event_t *); -extern int fmd_case_insert_event(fmd_case_t *, fmd_event_t *); +extern int fmd_case_insert_principal(void *, fmd_event_t *); +extern int fmd_case_insert_event(void *, fmd_event_t *); extern void fmd_case_insert_suspect(fmd_case_t *, nvlist_t *); extern void fmd_case_recreate_suspect(fmd_case_t *, nvlist_t *); diff --git a/usr/src/cmd/fm/fmd/common/fmd_ckpt.c b/usr/src/cmd/fm/fmd/common/fmd_ckpt.c index 4bae10f7b4..c923cbbb22 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_ckpt.c +++ b/usr/src/cmd/fm/fmd/common/fmd_ckpt.c @@ -894,7 +894,7 @@ fmd_ckpt_strptr(fmd_ckpt_t *ckp, fcf_stridx_t sid, const char *defstr) static void fmd_ckpt_restore_events(fmd_ckpt_t *ckp, fcf_secidx_t sid, - void (*func)(void *, fmd_event_t *), void *arg) + int (*func)(void *, fmd_event_t *), void *arg) { const fcf_event_t *fcfe; const fcf_sec_t *sp; @@ -942,7 +942,7 @@ fmd_ckpt_restore_events(fmd_ckpt_t *ckp, fcf_secidx_t sid, ep = fmd_event_recreate(FMD_EVT_PROTOCOL, &ftv, NULL, NULL, lp, fcfe->fcfe_offset, 0); fmd_event_hold(ep); - func(arg, ep); + (void) func(arg, ep); fmd_event_rele(ep); fcfe = (fcf_event_t *)((uintptr_t)fcfe + sp->fcfs_entsize); @@ -1050,10 +1050,10 @@ fmd_ckpt_restore_case(fmd_ckpt_t *ckp, fmd_module_t *mp, const fcf_sec_t *sp) } fmd_ckpt_restore_events(ckp, fcfc->fcfc_principal, - (void (*)(void *, fmd_event_t *))fmd_case_insert_principal, cp); + fmd_case_insert_principal, cp); fmd_ckpt_restore_events(ckp, fcfc->fcfc_events, - (void (*)(void *, fmd_event_t *))fmd_case_insert_event, cp); + fmd_case_insert_event, cp); /* * Once solved, treat suspects from resource cache as master copy. @@ -1105,7 +1105,7 @@ fmd_ckpt_restore_serd(fmd_ckpt_t *ckp, fmd_module_t *mp, const fcf_sec_t *sp) fmd_module_lock(mp); fmd_ckpt_restore_events(ckp, fcfd->fcfd_events, - (void (*)(void *, fmd_event_t *))fmd_serd_eng_record, + fmd_serd_eng_record, fmd_serd_eng_lookup(&mp->mod_serds, s)); fmd_module_unlock(mp); diff --git a/usr/src/cmd/fm/fmd/common/fmd_mdb.c b/usr/src/cmd/fm/fmd/common/fmd_mdb.c index 8ad141ab27..c24d0cee39 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_mdb.c +++ b/usr/src/cmd/fm/fmd/common/fmd_mdb.c @@ -208,8 +208,11 @@ trwalk_fini(mdb_walk_state_t *wsp) /*ARGSUSED*/ static int -trprint_msg(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) +trprint_msg(uintptr_t addr, const void *arg, void *arg1) { + const fmd_tracerec_t *trp = arg; + uintptr_t tid = (uintptr_t)arg1; + if (tid == 0) mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]); else if (trp->tr_stack[trp->tr_depth] != tid) @@ -223,8 +226,10 @@ trprint_msg(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) /*ARGSUSED*/ static int -trprint_cpp(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) +trprint_cpp(uintptr_t addr, const void *arg, void *arg1) { + const fmd_tracerec_t *trp = arg; + uintptr_t tid = (uintptr_t)arg1; char file[64]; if (tid == 0) @@ -254,17 +259,19 @@ trprint_stack(const fmd_tracerec_t *trp) } static int -trprint_msg_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) +trprint_msg_stack(uintptr_t addr, const void *arg, void *arg1) { - int status = trprint_msg(addr, trp, tid); + const fmd_tracerec_t *trp = arg; + int status = trprint_msg(addr, trp, arg1); trprint_stack(trp); return (status); } static int -trprint_cpp_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) +trprint_cpp_stack(uintptr_t addr, const void *arg, void *arg1) { - int status = trprint_cpp(addr, trp, tid); + const fmd_tracerec_t *trp = arg; + int status = trprint_cpp(addr, trp, arg1); trprint_stack(trp); return (status); } @@ -272,7 +279,7 @@ trprint_cpp_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) static int fmd_trace(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) { - int (*func)(uintptr_t, const fmd_tracerec_t *, uintptr_t); + int (*func)(uintptr_t, const void *, void *); uint_t opt_c = FALSE, opt_s = FALSE; if (mdb_getopts(argc, argv, @@ -293,7 +300,7 @@ fmd_trace(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) func = opt_s ? trprint_msg_stack : trprint_msg; } - if (mdb_walk("fmd_trace", (mdb_walk_cb_t)func, (void *)tid) == -1) { + if (mdb_walk("fmd_trace", func, (void *)tid) == -1) { mdb_warn("failed to walk fmd_trace"); return (DCMD_ERR); } diff --git a/usr/src/cmd/fm/fmd/common/fmd_module.c b/usr/src/cmd/fm/fmd/common/fmd_module.c index ad3b8f424d..5fe1c701ce 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_module.c +++ b/usr/src/cmd/fm/fmd/common/fmd_module.c @@ -641,8 +641,7 @@ fmd_module_gc(fmd_module_t *mp) fmd_module_lock(mp); if ((info = mp->mod_info) != NULL) { - fmd_serd_hash_apply(&mp->mod_serds, - (fmd_serd_eng_f *)fmd_serd_eng_gc, NULL); + fmd_serd_hash_apply(&mp->mod_serds, fmd_serd_eng_gc, NULL); } fmd_module_unlock(mp); @@ -657,8 +656,7 @@ void fmd_module_trygc(fmd_module_t *mp) { if (fmd_module_trylock(mp)) { - fmd_serd_hash_apply(&mp->mod_serds, - (fmd_serd_eng_f *)fmd_serd_eng_gc, NULL); + fmd_serd_hash_apply(&mp->mod_serds, fmd_serd_eng_gc, NULL); fmd_module_unlock(mp); } } @@ -715,7 +713,7 @@ fmd_module_clrdirty(fmd_module_t *mp) if (mp->mod_flags & FMD_MOD_MDIRTY) { fmd_serd_hash_apply(&mp->mod_serds, - (fmd_serd_eng_f *)fmd_serd_eng_clrdirty, NULL); + fmd_serd_eng_clrdirty, NULL); fmd_buf_hash_commit(&mp->mod_bufs); } @@ -740,8 +738,7 @@ fmd_module_commit(fmd_module_t *mp) } if (mp->mod_flags & FMD_MOD_MDIRTY) { - fmd_serd_hash_apply(&mp->mod_serds, - (fmd_serd_eng_f *)fmd_serd_eng_commit, NULL); + fmd_serd_hash_apply(&mp->mod_serds, fmd_serd_eng_commit, NULL); fmd_buf_hash_commit(&mp->mod_bufs); } diff --git a/usr/src/cmd/fm/fmd/common/fmd_scheme.c b/usr/src/cmd/fm/fmd/common/fmd_scheme.c index 4ddad713a6..367ecde455 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_scheme.c +++ b/usr/src/cmd/fm/fmd/common/fmd_scheme.c @@ -142,21 +142,38 @@ fmd_scheme_fmd_unusable(nvlist_t *nvl) return (rv); } -/*ARGSUSED*/ static nvlist_t * -fmd_scheme_notranslate(nvlist_t *fmri, nvlist_t *auth) +fmd_scheme_notranslate(nvlist_t *fmri, nvlist_t *auth __unused) { (void) nvlist_xdup(fmri, &fmri, &fmd.d_nva); return (fmri); } -static long -fmd_scheme_notsup(void) +static ssize_t +fmd_scheme_notsup_nvl2str(nvlist_t *fmri __unused, char *arg1 __unused, + size_t arg2 __unused) +{ + return (fmd_set_errno(EFMD_FMRI_NOTSUP)); +} + +static int +fmd_scheme_notsup(nvlist_t *fmri __unused) { return (fmd_set_errno(EFMD_FMRI_NOTSUP)); } static int +fmd_scheme_notsup2(nvlist_t *fmri1 __unused, nvlist_t *fmri2 __unused) +{ + return (fmd_set_errno(EFMD_FMRI_NOTSUP)); +} + +static void +fmd_scheme_vnop(void) +{ +} + +static int fmd_scheme_nop(void) { return (0); @@ -167,29 +184,29 @@ fmd_scheme_nop(void) * the module, then this operation is implemented using the default function. */ static const fmd_scheme_ops_t _fmd_scheme_default_ops = { - (int (*)())fmd_scheme_nop, /* sop_init */ - (void (*)())fmd_scheme_nop, /* sop_fini */ - (ssize_t (*)())fmd_scheme_notsup, /* sop_nvl2str */ - (int (*)())fmd_scheme_nop, /* sop_expand */ - (int (*)())fmd_scheme_notsup, /* sop_present */ - (int (*)())fmd_scheme_notsup, /* sop_replaced */ - (int (*)())fmd_scheme_notsup, /* sop_service_state */ - (int (*)())fmd_scheme_notsup, /* sop_unusable */ - (int (*)())fmd_scheme_notsup, /* sop_contains */ - fmd_scheme_notranslate /* sop_translate */ + .sop_init = fmd_scheme_nop, + .sop_fini = fmd_scheme_vnop, + .sop_nvl2str = fmd_scheme_notsup_nvl2str, + .sop_expand = fmd_scheme_notsup, + .sop_present = fmd_scheme_notsup, + .sop_replaced = fmd_scheme_notsup, + .sop_service_state = fmd_scheme_notsup, + .sop_unusable = fmd_scheme_notsup, + .sop_contains = fmd_scheme_notsup2, + .sop_translate = fmd_scheme_notranslate }; static const fmd_scheme_ops_t _fmd_scheme_builtin_ops = { - (int (*)())fmd_scheme_nop, /* sop_init */ - (void (*)())fmd_scheme_nop, /* sop_fini */ - fmd_scheme_fmd_nvl2str, /* sop_nvl2str */ - (int (*)())fmd_scheme_nop, /* sop_expand */ - fmd_scheme_fmd_present, /* sop_present */ - fmd_scheme_fmd_replaced, /* sop_replaced */ - fmd_scheme_fmd_service_state, /* sop_service_state */ - fmd_scheme_fmd_unusable, /* sop_unusable */ - (int (*)())fmd_scheme_notsup, /* sop_contains */ - fmd_scheme_notranslate /* sop_translate */ + .sop_init = fmd_scheme_nop, + .sop_fini = fmd_scheme_vnop, + .sop_nvl2str = fmd_scheme_fmd_nvl2str, + .sop_expand = fmd_scheme_notsup, + .sop_present = fmd_scheme_fmd_present, + .sop_replaced = fmd_scheme_fmd_replaced, + .sop_service_state = fmd_scheme_fmd_service_state, + .sop_unusable = fmd_scheme_fmd_unusable, + .sop_contains = fmd_scheme_notsup2, + .sop_translate = fmd_scheme_notranslate }; /* diff --git a/usr/src/cmd/fm/fmd/common/fmd_serd.c b/usr/src/cmd/fm/fmd/common/fmd_serd.c index 166b565666..0c817ef07d 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_serd.c +++ b/usr/src/cmd/fm/fmd/common/fmd_serd.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <fmd_alloc.h> #include <fmd_string.h> #include <fmd_subr.h> @@ -189,8 +187,9 @@ fmd_serd_eng_contains(fmd_serd_eng_t *sgp, fmd_event_t *ep) } int -fmd_serd_eng_record(fmd_serd_eng_t *sgp, fmd_event_t *ep) +fmd_serd_eng_record(void *ptr, fmd_event_t *ep) { + fmd_serd_eng_t *sgp = ptr; fmd_serd_elem_t *sep, *oep; /* @@ -253,7 +252,7 @@ fmd_serd_eng_reset(fmd_serd_eng_t *sgp) } void -fmd_serd_eng_gc(fmd_serd_eng_t *sgp) +fmd_serd_eng_gc(fmd_serd_eng_t *sgp, void *arg __unused) { fmd_serd_elem_t *sep, *nep; hrtime_t hrt; @@ -275,7 +274,7 @@ fmd_serd_eng_gc(fmd_serd_eng_t *sgp) } void -fmd_serd_eng_commit(fmd_serd_eng_t *sgp) +fmd_serd_eng_commit(fmd_serd_eng_t *sgp, void *arg __unused) { fmd_serd_elem_t *sep; @@ -290,7 +289,7 @@ fmd_serd_eng_commit(fmd_serd_eng_t *sgp) } void -fmd_serd_eng_clrdirty(fmd_serd_eng_t *sgp) +fmd_serd_eng_clrdirty(fmd_serd_eng_t *sgp, void *arg __unused) { sgp->sg_flags &= ~FMD_SERD_DIRTY; } diff --git a/usr/src/cmd/fm/fmd/common/fmd_serd.h b/usr/src/cmd/fm/fmd/common/fmd_serd.h index 3841f91999..48190a9058 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_serd.h +++ b/usr/src/cmd/fm/fmd/common/fmd_serd.h @@ -27,8 +27,6 @@ #ifndef _FMD_SERD_H #define _FMD_SERD_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -75,14 +73,14 @@ extern fmd_serd_eng_t *fmd_serd_eng_lookup(fmd_serd_hash_t *, const char *); extern void fmd_serd_eng_delete(fmd_serd_hash_t *, const char *); extern int fmd_serd_eng_contains(fmd_serd_eng_t *, fmd_event_t *); -extern int fmd_serd_eng_record(fmd_serd_eng_t *, fmd_event_t *); +extern int fmd_serd_eng_record(void *, fmd_event_t *); extern int fmd_serd_eng_fired(fmd_serd_eng_t *); extern int fmd_serd_eng_empty(fmd_serd_eng_t *); extern void fmd_serd_eng_reset(fmd_serd_eng_t *); -extern void fmd_serd_eng_gc(fmd_serd_eng_t *); -extern void fmd_serd_eng_commit(fmd_serd_eng_t *); -extern void fmd_serd_eng_clrdirty(fmd_serd_eng_t *); +extern void fmd_serd_eng_gc(fmd_serd_eng_t *, void *); +extern void fmd_serd_eng_commit(fmd_serd_eng_t *, void*); +extern void fmd_serd_eng_clrdirty(fmd_serd_eng_t *, void*); #ifdef __cplusplus } diff --git a/usr/src/cmd/fm/fmd/common/fmd_thread.c b/usr/src/cmd/fm/fmd/common/fmd_thread.c index cb0cb0745d..5de69238b5 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_thread.c +++ b/usr/src/cmd/fm/fmd/common/fmd_thread.c @@ -41,7 +41,7 @@ fmd_thread_xcreate(fmd_module_t *mp, pthread_t tid) tp->thr_func = NULL; tp->thr_arg = NULL; tp->thr_trdata = fmd_trace_create(); - tp->thr_trfunc = (fmd_tracebuf_f *)fmd.d_thr_trace; + tp->thr_trfunc = fmd.d_thr_trace; tp->thr_errdepth = 0; tp->thr_isdoor = 0; @@ -81,7 +81,7 @@ fmd_thread_create_cmn(fmd_module_t *mp, fmd_thread_f *func, void *arg, tp->thr_func = func; tp->thr_arg = arg; tp->thr_trdata = fmd_trace_create(); - tp->thr_trfunc = (fmd_tracebuf_f *)fmd.d_thr_trace; + tp->thr_trfunc = fmd.d_thr_trace; tp->thr_errdepth = 0; tp->thr_isdoor = isdoor; diff --git a/usr/src/cmd/fm/fmd/common/fmd_time.c b/usr/src/cmd/fm/fmd/common/fmd_time.c index ace772a476..a735ba03bf 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_time.c +++ b/usr/src/cmd/fm/fmd/common/fmd_time.c @@ -186,7 +186,7 @@ fmd_time_tod2hrt(hrtime_t hrt_base, const fmd_timeval_t *tod_base, * period between 'hrt' and 't0', therefore to check which one came first, we * test their subtraction against the highest bit of mask, if the bit is not * set, then 't0' is earlier. This is equivalent to - * ((hrt - t0) & mask) < ((mask + 1) / 2) + * ((hrt - t0) & mask) < ((mask + 1) / 2) */ hrtime_t fmd_time_ena2hrt(hrtime_t hrt, uint64_t ena) @@ -366,6 +366,11 @@ fmd_native_cancel(pthread_t tid) (void) pthread_kill(tid, SIGALRM); } +static void +fmd_time_vnop(void) +{ +} + static void * fmd_time_nop(void) { @@ -374,10 +379,10 @@ fmd_time_nop(void) const fmd_timeops_t fmd_timeops_native = { (void *(*)())fmd_time_nop, /* fto_init */ - (void (*)())fmd_time_nop, /* fto_fini */ + (void (*)())fmd_time_vnop, /* fto_fini */ gettimeofday, /* fto_gettimeofday */ gethrtime, /* fto_gethrtime */ - (void (*)())fmd_time_nop, /* fto_addhrtime */ + (void (*)())fmd_time_vnop, /* fto_addhrtime */ fmd_native_wait, /* fto_waithrtime */ fmd_native_cancel, /* fto_waitcancel */ }; diff --git a/usr/src/cmd/fm/fmdump/common/scheme.c b/usr/src/cmd/fm/fmdump/common/scheme.c index 425fbd302c..20cad01a50 100644 --- a/usr/src/cmd/fm/fmdump/common/scheme.c +++ b/usr/src/cmd/fm/fmdump/common/scheme.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/systeminfo.h> @@ -79,6 +77,11 @@ fmd_scheme_notsup(void) return (-1); } +static void +fmd_scheme_vnop(void) +{ +} + static int fmd_scheme_nop(void) { @@ -91,7 +94,7 @@ fmd_scheme_nop(void) */ static const fmd_scheme_ops_t _fmd_scheme_default_ops = { (int (*)())fmd_scheme_nop, /* sop_init */ - (void (*)())fmd_scheme_nop, /* sop_fini */ + (void (*)())fmd_scheme_vnop, /* sop_fini */ (ssize_t (*)())fmd_scheme_notsup, /* sop_nvl2str */ }; diff --git a/usr/src/cmd/fm/modules/common/eversholt/eval.c b/usr/src/cmd/fm/modules/common/eversholt/eval.c index a3c47f91dc..78ce797d28 100644 --- a/usr/src/cmd/fm/modules/common/eversholt/eval.c +++ b/usr/src/cmd/fm/modules/common/eversholt/eval.c @@ -32,6 +32,7 @@ #include <stdlib.h> #include <ctype.h> #include <string.h> +#include <fm/libtopo.h> #include "alloc.h" #include "out.h" #include "stable.h" @@ -507,7 +508,7 @@ eval_func(struct node *funcnp, struct lut *ex, struct node *events[], valuep->v = 1; return (1); } else if (funcname == L_has_fault) { - nvlist_t *asru = NULL, *fru = NULL, *rsrc = NULL; + nvlist_t *rsrc = NULL; nodep = eval_getname(funcnp, ex, events, np->u.expr.left, globals, croot, arrowp, try, &duped); @@ -519,7 +520,8 @@ eval_func(struct node *funcnp, struct lut *ex, struct node *events[], } path = ipath2str(NULL, ipath(nodep)); - platform_units_translate(0, croot, &asru, &fru, &rsrc, path); + platform_unit_translate(0, croot, TOPO_PROP_RESOURCE, + &rsrc, path); outfl(O_ALTFP|O_VERB2|O_NONL, np->file, np->line, "has_fault("); ptree_name_iter(O_ALTFP|O_VERB2|O_NONL, nodep); out(O_ALTFP|O_VERB2|O_NONL, "(%s), \"%s\") ", path, diff --git a/usr/src/cmd/fm/modules/common/eversholt/fme.c b/usr/src/cmd/fm/modules/common/eversholt/fme.c index e153385551..0f7edab994 100644 --- a/usr/src/cmd/fm/modules/common/eversholt/fme.c +++ b/usr/src/cmd/fm/modules/common/eversholt/fme.c @@ -38,6 +38,7 @@ #include <libnvpair.h> #include <sys/fm/protocol.h> #include <fm/fmd_api.h> +#include <fm/libtopo.h> #include "alloc.h" #include "out.h" #include "stats.h" @@ -340,7 +341,7 @@ newfme(const char *e0class, const struct ipath *e0ipp, fmd_hdl_t *hdl, ipathlastcomp(e0ipp); pathstr = ipath2str(NULL, e0ipp); cfgdata = config_snapshot(); - platform_units_translate(0, cfgdata->cooked, NULL, NULL, + platform_unit_translate(0, cfgdata->cooked, TOPO_PROP_RESOURCE, &detector, pathstr); FREE(pathstr); structconfig_free(cfgdata->cooked); @@ -392,7 +393,7 @@ newfme(const char *e0class, const struct ipath *e0ipp, fmd_hdl_t *hdl, nvlist_free(detector); pathstr = ipath2str(NULL, e0ipp); cfgdata = config_snapshot(); - platform_units_translate(0, cfgdata->cooked, NULL, NULL, + platform_unit_translate(0, cfgdata->cooked, TOPO_PROP_RESOURCE, &detector, pathstr); FREE(pathstr); platform_save_config(hdl, fmcase); @@ -2181,7 +2182,8 @@ void get_resources(struct event *sp, struct rsl *rsrcs, struct config *croot) { struct node *asrudef, *frudef; - nvlist_t *asru, *fru; + const struct ipath *asrupath, *frupath; + nvlist_t *asru = NULL, *fru = NULL; nvlist_t *rsrc = NULL; char *pathstr; @@ -2193,19 +2195,29 @@ get_resources(struct event *sp, struct rsl *rsrcs, struct config *croot) frudef = eventprop_lookup(sp, L_FRU); /* - * Create FMRIs based on those definitions + * Create ipaths based on those definitions */ - asru = node2fmri(asrudef); - fru = node2fmri(frudef); - pathstr = ipath2str(NULL, sp->ipp); + asrupath = ipath(asrudef); + frupath = ipath(frudef); /* * Allow for platform translations of the FMRIs */ - platform_units_translate(is_defect(sp->t), croot, &asru, &fru, &rsrc, - pathstr); + pathstr = ipath2str(NULL, sp->ipp); + platform_unit_translate(is_defect(sp->t), croot, TOPO_PROP_RESOURCE, + &rsrc, pathstr); + FREE(pathstr); + pathstr = ipath2str(NULL, asrupath); + platform_unit_translate(is_defect(sp->t), croot, TOPO_PROP_ASRU, + &asru, pathstr); FREE(pathstr); + + pathstr = ipath2str(NULL, frupath); + platform_unit_translate(is_defect(sp->t), croot, TOPO_PROP_FRU, + &fru, pathstr); + FREE(pathstr); + rsrcs->suspect = sp; rsrcs->asru = asru; rsrcs->fru = fru; @@ -3115,8 +3127,8 @@ fme_undiagnosable(struct fme *f) fmd_case_add_ereport(f->hdl, f->fmcase, ep->ffep); pathstr = ipath2str(NULL, ipath(platform_getpath(ep->nvp))); - platform_units_translate(0, f->config, NULL, NULL, &detector, - pathstr); + platform_unit_translate(0, f->config, TOPO_PROP_RESOURCE, + &detector, pathstr); FREE(pathstr); /* add defect */ diff --git a/usr/src/cmd/fm/modules/common/eversholt/platform.c b/usr/src/cmd/fm/modules/common/eversholt/platform.c index 1fe49bd9b4..a3972400e4 100644 --- a/usr/src/cmd/fm/modules/common/eversholt/platform.c +++ b/usr/src/cmd/fm/modules/common/eversholt/platform.c @@ -767,7 +767,7 @@ platform_config_snapshot(void) } static const char * -cfgstrprop_lookup(struct config *croot, char *path, char *pname) +cfgstrprop_lookup(struct config *croot, char *path, const char *pname) { struct config *cresource; const char *fmristr; @@ -790,43 +790,45 @@ cfgstrprop_lookup(struct config *croot, char *path, char *pname) } /* - * Get resource FMRI from libtopo + * Get FMRI for a particular unit from libtopo. The unit is specified by the + * "path" argument (a stringified ipath). "prop" argument should be one + * of the constants TOPO_PROP_RESOURCE, TOPO_PROP_ASRU, TOPO_PROP_FRU, etc. */ /*ARGSUSED*/ void -platform_units_translate(int isdefect, struct config *croot, - nvlist_t **dfltasru, nvlist_t **dfltfru, nvlist_t **dfltrsrc, char *path) +platform_unit_translate(int isdefect, struct config *croot, const char *prop, + nvlist_t **fmrip, char *path) { const char *fmristr; char *serial; - nvlist_t *rsrc; + nvlist_t *fmri; int err; - fmristr = cfgstrprop_lookup(croot, path, TOPO_PROP_RESOURCE); + fmristr = cfgstrprop_lookup(croot, path, prop); if (fmristr == NULL) { - out(O_ALTFP, "Cannot rewrite resource for %s.", path); + out(O_ALTFP, "Cannot rewrite unit FMRI for %s.", path); return; } - if (topo_fmri_str2nvl(Eft_topo_hdl, fmristr, &rsrc, &err) < 0) { + if (topo_fmri_str2nvl(Eft_topo_hdl, fmristr, &fmri, &err) < 0) { out(O_ALTFP, "Can not convert config info: %s", topo_strerror(err)); - out(O_ALTFP, "Cannot rewrite resource for %s.", path); + out(O_ALTFP, "Cannot rewrite unit FMRI for %s.", path); return; } /* - * If we don't have a serial number in the resource then check if it + * If we don't have a serial number in the unit then check if it * is available as a separate property and if so then add it. */ - if (nvlist_lookup_string(rsrc, FM_FMRI_HC_SERIAL_ID, &serial) != 0) { + if (nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID, &serial) != 0) { serial = (char *)cfgstrprop_lookup(croot, path, FM_FMRI_HC_SERIAL_ID); if (serial != NULL) - (void) nvlist_add_string(rsrc, FM_FMRI_HC_SERIAL_ID, + (void) nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, serial); } - *dfltrsrc = rsrc; + *fmrip = fmri; } /* diff --git a/usr/src/cmd/fm/modules/common/eversholt/platform.h b/usr/src/cmd/fm/modules/common/eversholt/platform.h index 30cab516ed..23e1f6f41e 100644 --- a/usr/src/cmd/fm/modules/common/eversholt/platform.h +++ b/usr/src/cmd/fm/modules/common/eversholt/platform.h @@ -28,8 +28,6 @@ #ifndef _EFT_PLATFORM_H #define _EFT_PLATFORM_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libnvpair.h> #ifdef __cplusplus @@ -38,6 +36,7 @@ extern "C" { #include <config.h> #include <fm/fmd_api.h> +#include <fm/libtopo.h> nvlist_t *Action_nvl; /* nvl for problem with action=... prop on it */ @@ -45,8 +44,8 @@ void platform_init(void); void platform_fini(void); void platform_run_poller(const char *poller); void platform_set_payloadnvp(nvlist_t *nvlp); -void platform_units_translate(int, struct config *, nvlist_t **, nvlist_t **, - nvlist_t **, char *); +void platform_unit_translate(int, struct config *, const char *, nvlist_t **, + char *); struct cfgdata *platform_config_snapshot(void); void platform_restore_config(fmd_hdl_t *hdl, fmd_case_t *fmcase); diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_storage.c b/usr/src/cmd/hal/hald/solaris/devinfo_storage.c index bfe027ad25..d1fea0c577 100644 --- a/usr/src/cmd/hal/hald/solaris/devinfo_storage.c +++ b/usr/src/cmd/hal/hald/solaris/devinfo_storage.c @@ -1522,19 +1522,17 @@ devinfo_storage_mnttab_event (HalDevice *hal_volume) /* cleanup if was mounted by us */ if (hal_util_is_mounted_by_hald (mount_point)) { - char *cleanup_stdin; char *extra_env[2]; HAL_INFO (("Cleaning up '%s'", mount_point)); extra_env[0] = g_strdup_printf ("HALD_CLEANUP=%s", mount_point); extra_env[1] = NULL; - cleanup_stdin = "\n"; hald_runner_run_method (d, "hal-storage-cleanup-mountpoint", extra_env, - cleanup_stdin, TRUE, + "", TRUE, 0, devinfo_storage_cleanup_mountpoint_cb, g_strdup (mount_point), NULL); @@ -1577,7 +1575,6 @@ static void devinfo_volume_force_unmount (HalDevice *d, void *end_token) { const char *mount_point; - char *unmount_stdin; char *extra_env[2]; extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0"; extra_env[1] = NULL; @@ -1591,12 +1588,10 @@ devinfo_volume_force_unmount (HalDevice *d, void *end_token) HAL_INFO (("devinfo_volume_force_unmount for udi='%s'", hal_device_get_udi (d))); - unmount_stdin = "\n"; - hald_runner_run_method (d, "hal-storage-unmount", extra_env, - unmount_stdin, TRUE, + "", TRUE, 0, devinfo_volume_force_unmount_cb, end_token, NULL); diff --git a/usr/src/cmd/hal/tools/hal-storage-mount.c b/usr/src/cmd/hal/tools/hal-storage-mount.c index 5622123274..5e687bea9e 100644 --- a/usr/src/cmd/hal/tools/hal-storage-mount.c +++ b/usr/src/cmd/hal/tools/hal-storage-mount.c @@ -228,7 +228,7 @@ canonicalize_filename (gchar *filename) static char * resolve_symlink (const char *file) { - GError *error; + GError *error = NULL; char *dir; char *link; char *f; diff --git a/usr/src/cmd/iscsiadm/cmdparse.c b/usr/src/cmd/iscsiadm/cmdparse.c index 882ff3c673..b1a2f84692 100644 --- a/usr/src/cmd/iscsiadm/cmdparse.c +++ b/usr/src/cmd/iscsiadm/cmdparse.c @@ -23,6 +23,10 @@ * Use is subject to license terms. */ +/* + * Copyright 2020 Joyent Inc. + */ + #include <stdlib.h> #include <stdio.h> #include <sys/types.h> @@ -70,7 +74,7 @@ static void subUsage(uint_t, subcommand_t *); static void subUsageObject(uint_t, subcommand_t *, object_t *); static int getObject(char *, object_t **); static int getObjectRules(uint_t, objectRules_t **); -static char *getLongOption(int); +static const char *getLongOption(int); static optionProp_t *getOptions(uint_t, uint_t); static char *getOptionArgDesc(int); extern void seeMan(void); @@ -208,7 +212,7 @@ getOptions(uint_t object, uint_t subcommand) * on success, long option name * on failure, NULL */ -static char * +static const char * getLongOption(int shortOption) { struct option *op; @@ -319,7 +323,7 @@ subUsageObject(uint_t usageType, subcommand_t *subcommand, object_t *objp) opCmd_t *opCmd = NULL; optionProp_t *options; char *optionArgDesc; - char *longOpt; + const char *longOpt; if (getObjectRules(objp->value, &objRules) != 0) { diff --git a/usr/src/cmd/isns/isnsadm/cmdparse.c b/usr/src/cmd/isns/isnsadm/cmdparse.c index ccad6df26c..7303b347ac 100644 --- a/usr/src/cmd/isns/isnsadm/cmdparse.c +++ b/usr/src/cmd/isns/isnsadm/cmdparse.c @@ -22,6 +22,9 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright 2020 Joyent Inc. + */ #include <stdlib.h> #include <stdio.h> @@ -69,7 +72,7 @@ static int getSubcommandProps(char *, subCommandProps_t **); static char *getExecBasename(char *); static void usage(uint_t); static void subUsage(uint_t, subCommandProps_t *); -static char *getLongOption(int); +static const char *getLongOption(int); static char *getOptionArgDesc(int); /* global data */ @@ -119,7 +122,7 @@ getSubcommandProps(char *subCommand, subCommandProps_t **subCommandProps) * on success, long option name * on failure, NULL */ -static char * +static const char * getLongOption(int shortOption) { struct option *op; @@ -169,7 +172,7 @@ subUsage(uint_t usageType, subCommandProps_t *subcommand) { int i; char *optionArgDesc; - char *longOpt; + const char *longOpt; if (usageType == GENERAL_USAGE) { (void) printf("%s:\t%s %s [", gettext("Usage"), commandName, diff --git a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c index ad6a388b49..cd50cdce17 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c @@ -3205,6 +3205,7 @@ const mdb_dcmd_t mdb_dcmd_builtins[] = { { "typeset", "[+/-t] var ...", "set variable attributes", cmd_typeset }, { "typedef", "[-c model | -d | -l | -r file | -w file ] [type] [name]", "create synthetic types", cmd_typedef, cmd_typedef_help }, + { "typelist", NULL, "list known types", cmd_typelist }, { "unset", "[name ...]", "unset variables", cmd_unset }, { "vars", "[-npt]", "print listing of variables", cmd_vars }, { "version", NULL, "print debugger version string", cmd_version }, diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c index f2854bb6d6..9cc7c6f1a0 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c @@ -2272,3 +2272,35 @@ mdb_ctf_synthetics_to_file(const char *file) return (err); } + +static int +cmd_typelist_type(mdb_ctf_id_t id, void *arg) +{ + char buf[1024]; + + if (mdb_ctf_type_name(id, buf, sizeof (buf)) != NULL) { + mdb_printf("%s\n", buf); + } + return (0); +} + +static int +cmd_typelist_module(void *data, const mdb_map_t *mp, const char *name) +{ + (void) mdb_ctf_type_iter(name, cmd_typelist_type, data); + return (0); +} + +int +cmd_typelist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + if ((flags & DCMD_ADDRSPEC) != 0) { + return (DCMD_USAGE); + } + + (void) mdb_tgt_object_iter(mdb.m_target, cmd_typelist_module, NULL); + (void) mdb_ctf_type_iter(MDB_CTF_SYNTHETIC_ITER, cmd_typelist_type, + NULL); + + return (DCMD_OK); +} diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h index 74bc8e95da..639e7b2bdc 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h @@ -35,6 +35,7 @@ #ifdef _MDB #include <sys/machelf.h> +#include <mdb/mdb_modapi.h> #endif /* @@ -159,6 +160,8 @@ extern int mdb_ctf_synthetics_init(void); /* Internal */ extern void mdb_ctf_synthetics_fini(void); /* Internal */ extern int mdb_ctf_synthetics_from_file(const char *); /* Internal */ extern int mdb_ctf_synthetics_to_file(const char *); /* Internal */ +extern int cmd_typelist(uintptr_t, uint_t, int, /* Internal */ + const mdb_arg_t *); #endif diff --git a/usr/src/cmd/mdb/common/mdb/mdb_fmt.c b/usr/src/cmd/mdb/common/mdb/mdb_fmt.c index c68f20b107..6a745b2ac4 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_fmt.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_fmt.c @@ -21,7 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. * Copyright (c) 2017 by Delphix. All rights reserved. */ @@ -739,7 +739,7 @@ mdb_fmt_print(mdb_tgt_t *t, mdb_tgt_as_t as, * Unless a format has explicitly opted out, we force autowrap * for the duration of mdb_fmt_print(). */ - mdb.m_flags |= MDB_FL_AUTOWRAP; + mdb_iob_set_autowrap(mdb.m_out); } switch (FMT_TYPE(fp->f_type)) { diff --git a/usr/src/cmd/mdb/common/mdb/mdb_io.c b/usr/src/cmd/mdb/common/mdb/mdb_io.c index f1ad8d051c..752c6f5c35 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_io.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_io.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2019, Joyent, Inc. All rights reserved. + * Copyright 2020 Joyent, Inc. * Copyright (c) 2016 by Delphix. All rights reserved. */ @@ -1777,6 +1777,27 @@ mdb_iob_snprintf(char *buf, size_t nbytes, const char *format, ...) return (nbytes); } +/* + * Return how many bytes we can copy into our buffer, limited by either cols or + * bufsiz depending on whether AUTOWRAP is on. Note that typically, + * mdb_iob_set_autowrap() will have already checked for an existing + * "->iob_nbytes > ->iob_cols" situation, but we double check here anyway. + */ +static size_t +iob_bufleft(mdb_iob_t *iob) +{ + if (IOB_AUTOWRAP(iob)) { + if (iob->iob_cols < iob->iob_nbytes) { + mdb_iob_nl(iob); + ASSERT(iob->iob_cols >= iob->iob_nbytes); + } + return (iob->iob_cols - iob->iob_nbytes); + } + + ASSERT(iob->iob_bufsiz >= iob->iob_nbytes); + return (iob->iob_bufsiz - iob->iob_nbytes); +} + void mdb_iob_nputs(mdb_iob_t *iob, const char *s, size_t nbytes) { @@ -1810,20 +1831,11 @@ mdb_iob_nputs(mdb_iob_t *iob, const char *s, size_t nbytes) } /* - * For a given string component, we determine how many bytes (n) we can - * copy into our buffer (limited by either cols or bufsiz depending - * on whether AUTOWRAP is on), copy a chunk into the buffer, and + * For a given string component, we copy a chunk into the buffer, and * flush the buffer if we reach the end of a line. */ while (nleft != 0) { - if (IOB_AUTOWRAP(iob)) { - ASSERT(iob->iob_cols >= iob->iob_nbytes); - n = iob->iob_cols - iob->iob_nbytes; - } else { - ASSERT(iob->iob_bufsiz >= iob->iob_nbytes); - n = iob->iob_bufsiz - iob->iob_nbytes; - } - + n = iob_bufleft(iob); m = MIN(nleft, n); /* copy at most n bytes in this pass */ bcopy(q, iob->iob_bufp, m); @@ -1884,14 +1896,7 @@ mdb_iob_fill(mdb_iob_t *iob, int c, size_t nfill) ASSERT(iob->iob_flags & MDB_IOB_WRONLY); while (nfill != 0) { - if (IOB_AUTOWRAP(iob)) { - ASSERT(iob->iob_cols >= iob->iob_nbytes); - n = iob->iob_cols - iob->iob_nbytes; - } else { - ASSERT(iob->iob_bufsiz >= iob->iob_nbytes); - n = iob->iob_bufsiz - iob->iob_nbytes; - } - + n = iob_bufleft(iob); m = MIN(nfill, n); /* fill at most n bytes in this pass */ for (i = 0; i < m; i++) @@ -2169,6 +2174,26 @@ mdb_iob_stack_size(mdb_iob_stack_t *stk) } /* + * This only enables autowrap for iobs that are already autowrap themselves such + * as mdb.m_out typically. + * + * Note that we might be the middle of the iob buffer at this point, and + * specifically, iob->iob_nbytes could be more than iob->iob_cols. As that's + * not a valid situation, we may need to do an autowrap *now*. + * + * In theory, we would need to do this across all MDB_IOB_AUTOWRAP iob's; + * instead, we have a failsafe in iob_bufleft(). + */ +void +mdb_iob_set_autowrap(mdb_iob_t *iob) +{ + mdb.m_flags |= MDB_FL_AUTOWRAP; + if (IOB_WRAPNOW(iob, 0)) + mdb_iob_nl(iob); + ASSERT(iob->iob_cols >= iob->iob_nbytes); +} + +/* * Stub functions for i/o backend implementors: these stubs either act as * pass-through no-ops or return ENOTSUP as appropriate. */ @@ -2267,14 +2292,14 @@ no_io_resume(mdb_io_t *io) /* * Iterate over the varargs. The first item indicates the mode: * MDB_TBL_PRNT - * pull out the next vararg as a const char * and pass it and the - * remaining varargs to iob_doprnt; if we want to print the column, - * direct the output to mdb.m_out otherwise direct it to mdb.m_null + * pull out the next vararg as a const char * and pass it and the + * remaining varargs to iob_doprnt; if we want to print the column, + * direct the output to mdb.m_out otherwise direct it to mdb.m_null * * MDB_TBL_FUNC - * pull out the next vararg as type mdb_table_print_f and the - * following one as a void * argument to the function; call the - * function with the given argument if we want to print the column + * pull out the next vararg as type mdb_table_print_f and the + * following one as a void * argument to the function; call the + * function with the given argument if we want to print the column * * The second item indicates the flag; if the flag is set in the flags * argument, then the column is printed. A flag value of 0 indicates diff --git a/usr/src/cmd/mdb/common/mdb/mdb_io.h b/usr/src/cmd/mdb/common/mdb/mdb_io.h index 2ef4677db4..0c41c5c740 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_io.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_io.h @@ -21,13 +21,13 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2020 Joyent, Inc. */ #ifndef _MDB_IO_H #define _MDB_IO_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -149,6 +149,8 @@ extern size_t mdb_iob_lineno(mdb_iob_t *); extern size_t mdb_iob_gettabstop(mdb_iob_t *); extern size_t mdb_iob_getmargin(mdb_iob_t *); +extern void mdb_iob_set_autowrap(mdb_iob_t *); + extern void mdb_iob_stack_create(mdb_iob_stack_t *); extern void mdb_iob_stack_destroy(mdb_iob_stack_t *); extern void mdb_iob_stack_push(mdb_iob_stack_t *, mdb_iob_t *, size_t); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_print.c b/usr/src/cmd/mdb/common/mdb/mdb_print.c index 2c0af13a25..bd23ef681f 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_print.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_print.c @@ -25,7 +25,7 @@ /* * Copyright (c) 2012, 2014 by Delphix. All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2020 Joyent, Inc. * Copyright (c) 2014 Nexenta Systems, Inc. All rights reserved. */ @@ -931,6 +931,30 @@ print_bitfield(ulong_t off, printarg_t *pap, ctf_encoding_t *ep) } /* + * We want to print an escaped char as e.g. '\0'. We don't use mdb_fmt_print() + * as it won't get auto-wrap right here (although even now, we don't include any + * trailing comma). + */ +static int +print_char_val(mdb_tgt_addr_t addr, printarg_t *pap) +{ + char cval; + char *s; + + if (mdb_tgt_aread(pap->pa_tgt, pap->pa_as, &cval, 1, addr) != 1) + return (1); + + if (mdb.m_flags & MDB_FL_ADB) + s = strchr2adb(&cval, 1); + else + s = strchr2esc(&cval, 1); + + mdb_printf("'%s'", s); + strfree(s); + return (0); +} + +/* * Print out a character or integer value. We use some simple heuristics, * described below, to determine the appropriate radix to use for output. */ @@ -971,14 +995,8 @@ print_int_val(const char *type, ctf_encoding_t *ep, ulong_t off, if (size > 8 || (ep->cte_bits % NBBY) != 0 || (size & (size - 1)) != 0) return (print_bitfield(off, pap, ep)); - if (IS_CHAR(*ep)) { - mdb_printf("'"); - if (mdb_fmt_print(pap->pa_tgt, pap->pa_as, - addr, 1, 'C') == addr) - return (1); - mdb_printf("'"); - return (0); - } + if (IS_CHAR(*ep)) + return (print_char_val(addr, pap)); if (mdb_tgt_aread(pap->pa_tgt, pap->pa_as, &u.i8, size, addr) != size) { mdb_warn("failed to read %lu bytes at %llx", diff --git a/usr/src/cmd/mdb/common/mdb/mdb_set.c b/usr/src/cmd/mdb/common/mdb/mdb_set.c index cd8926fbcc..8d4a1d30f7 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_set.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_set.c @@ -24,7 +24,7 @@ */ /* - * Copyright 2017 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* @@ -275,7 +275,7 @@ print_properties(void) * we enable it for the duration of the command. */ oflags = mdb.m_flags; - mdb.m_flags |= MDB_FL_AUTOWRAP; + mdb_iob_set_autowrap(mdb.m_out); mdb_printf("follow_exec_mode="); switch (mdb.m_execmode) { diff --git a/usr/src/cmd/mpathadm/cmdparse.c b/usr/src/cmd/mpathadm/cmdparse.c index 9080e1cfdd..c4c2dd744a 100644 --- a/usr/src/cmd/mpathadm/cmdparse.c +++ b/usr/src/cmd/mpathadm/cmdparse.c @@ -22,6 +22,10 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright 2020 Joyent Inc. + */ + #include <stdlib.h> #include <stdio.h> @@ -70,7 +74,7 @@ static void subUsage(uint_t, subcommand_t *); static void subUsageObject(uint_t, subcommand_t *, object_t *); static int getObject(char *, object_t **); static int getObjectRules(uint_t, objectRules_t **); -static char *getLongOption(int); +static const char *getLongOption(int); static optionProp_t *getOptions(uint_t, uint_t); static char *getOptionArgDesc(int); @@ -207,7 +211,7 @@ getOptions(uint_t object, uint_t subcommand) * on success, long option name * on failure, NULL */ -static char * +static const char * getLongOption(int shortOption) { struct option *op; @@ -317,7 +321,7 @@ subUsageObject(uint_t usageType, subcommand_t *subcommand, object_t *objp) opCmd_t *opCmd = NULL; optionProp_t *options; char *optionArgDesc; - char *longOpt; + const char *longOpt; if (getObjectRules(objp->value, &objRules) != 0) { diff --git a/usr/src/cmd/ptools/pfiles/pfiles.c b/usr/src/cmd/ptools/pfiles/pfiles.c index c9540a466c..474650faa4 100644 --- a/usr/src/cmd/ptools/pfiles/pfiles.c +++ b/usr/src/cmd/ptools/pfiles/pfiles.c @@ -205,13 +205,19 @@ intr(int sig) /* ------ begin specific code ------ */ +static int +show_paths(uint_t type, const void *data, size_t len, void *arg __unused) +{ + if (type == PR_PATHNAME) + (void) printf(" %.*s\n", len, data); + return (0); +} static int show_file(void *data, const prfdinfo_t *info) { struct ps_prochandle *Pr = data; char unknown[12]; - const char *path; char *s; mode_t mode; @@ -259,8 +265,6 @@ show_file(void *data, const prfdinfo_t *info) (void) printf(" rdev:%u,%u\n", (unsigned)info->pr_rmajor, (unsigned)info->pr_rminor); - path = proc_fdinfo_misc(info, PR_PATHNAME, NULL); - if (!nflag) { dofcntl(Pr, info, (mode & (S_IFMT|S_ENFMT|S_IXGRP)) == (S_IFREG|S_ENFMT), @@ -285,8 +289,7 @@ show_file(void *data, const prfdinfo_t *info) } } - if (path != NULL) - (void) printf(" %s\n", path); + (void) proc_fdinfowalk(info, show_paths, NULL); if (info->pr_offset != -1) { (void) printf(" offset:%lld\n", diff --git a/usr/src/cmd/svc/milestone/fs-joyent b/usr/src/cmd/svc/milestone/fs-joyent index 9082f22e46..f8b4ffb53d 100755 --- a/usr/src/cmd/svc/milestone/fs-joyent +++ b/usr/src/cmd/svc/milestone/fs-joyent @@ -11,7 +11,7 @@ # # -# Copyright (c) 2018, Joyent, Inc. +# Copyright 2020 Joyent, Inc. # set -o xtrace @@ -70,6 +70,24 @@ function mount_zfs echo ${output} 1>&2 } +function unlock_pool +{ + local pool=$1 + + # If the key is already loaded, don't bother trying again + local keystatus="$(zfs get -Hpo value keystatus $pool)" + if [[ "$keystatus" == "available" ]]; then + return + fi + + kbmadm unlock $pool && return + + echo "Failed to unlock $pool; recovery may be required" | \ + tee -a /dev/console >&2 + + exit $SMF_EXIT_ERR_FATAL +} + /bin/bootparams | grep "^noimport=true" >/dev/null if [ $? -ne 0 ]; then # If the zpool doesn't exist, then there's nothing to mount. @@ -87,11 +105,17 @@ if [ $? -ne 0 ]; then for pool in $pools; do zpool import -f $pool - # Due to early, failed attempts to support the filesystem_limits - # feature we now need to ensure the dependent feature is enabled. - zpool set feature@extensible_dataset=enabled $pool + + is_encr="$(zfs get -Hpo value encryption $pool)" + + [[ "$is_encr" != "off" ]] && unlock_pool $pool + + # Due to early, failed attempts to support the filesystem_limits + # feature we now need to ensure the dependent feature is enabled. + zpool set feature@extensible_dataset=enabled $pool if [[ -f /$pool/.system_pool ]]; then SYS_ZPOOL=$pool + [[ "$is_encr" != "off" ]] && kbmadm set-syspool $pool fi done diff --git a/usr/src/cmd/svc/milestone/joyent-fs.xml b/usr/src/cmd/svc/milestone/joyent-fs.xml index 3d004e8d33..f21eae27d8 100644 --- a/usr/src/cmd/svc/milestone/joyent-fs.xml +++ b/usr/src/cmd/svc/milestone/joyent-fs.xml @@ -44,6 +44,14 @@ <service_fmri value='svc:/system/filesystem/usr' /> </dependency> + <dependency + name='kbmd' + grouping='optional_all' + restart_on='none' + type='service'> + <service_fmri value='svc:/system/kbmd:default' /> + </dependency> + <!-- Start method timeout is infinite to handle potentially unbounded fsck times. diff --git a/usr/src/cmd/zlogin/zlogin.c b/usr/src/cmd/zlogin/zlogin.c index f2da6a3d74..fb219918c5 100644 --- a/usr/src/cmd/zlogin/zlogin.c +++ b/usr/src/cmd/zlogin/zlogin.c @@ -24,7 +24,7 @@ * Copyright (c) 2014 Gary Mills * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright 2020 Joyent, Inc. - * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -127,8 +127,6 @@ static int pollerr = 0; static const char *pname; static char *username; -extern int __xpg4; /* 0 if not an xpg4/6-compiled program */ - /* * When forced_login is true, the user is not prompted * for an authentication password in the target zone. @@ -835,16 +833,8 @@ process_output(int in_fd, int out_fd) cc = read(in_fd, ibuf, ZLOGIN_BUFSIZ); if (cc == -1 && (errno != EINTR || dead)) return (-1); - if (cc == 0) { - /* - * A return value of 0 when calling read() on a terminal - * indicates end-of-file pre-XPG4 and no data available - * for XPG4 and above. - */ - if (__xpg4 == 0) - return (-1); - return (0); - } + if (cc == 0) + return (-1); /* EOF */ if (cc == -1) /* The read was interrupted. */ return (0); diff --git a/usr/src/cmd/zpool/zpool_main.c b/usr/src/cmd/zpool/zpool_main.c index 7242a156c7..31ce0c7e11 100644 --- a/usr/src/cmd/zpool/zpool_main.c +++ b/usr/src/cmd/zpool/zpool_main.c @@ -350,7 +350,7 @@ get_usage(zpool_help_t idx) case HELP_IOSTAT: return (gettext("\tiostat " "[[-lq]|[-rw]] [-T d | u] [-ghHLpPvy]\n" - "\t [pool] ..." + "\t [[pool] ...]|[pool vdev ...]|[vdev ...]]" " [[-n] interval [count]]\n")); case HELP_LABELCLEAR: return (gettext("\tlabelclear [-f] <vdev>\n")); @@ -4987,6 +4987,7 @@ zpool_do_iostat(int argc, char **argv) cb.cb_vdev_names_count)) && !cb.cb_scripted) { print_iostat_separator(&cb); + printf("\n"); } } diff --git a/usr/src/common/cmdparse/cmdparse.c b/usr/src/common/cmdparse/cmdparse.c index 07ad6ed13a..bc55dc8dce 100644 --- a/usr/src/common/cmdparse/cmdparse.c +++ b/usr/src/common/cmdparse/cmdparse.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Joyent Inc. */ #include <stdlib.h> @@ -71,7 +71,7 @@ static int getSubcommandProps(char *, subCommandProps_t **); static char *getExecBasename(char *); static void usage(uint_t); static void subUsage(uint_t, subCommandProps_t *); -static char *getLongOption(int); +static const char *getLongOption(int); static char *getOptionArgDesc(int); /* global data */ @@ -121,7 +121,7 @@ getSubcommandProps(char *subCommand, subCommandProps_t **subCommandProps) * on success, long option name * on failure, NULL */ -static char * +static const char * getLongOption(int shortOption) { struct option *op; @@ -171,7 +171,7 @@ subUsage(uint_t usageType, subCommandProps_t *subcommand) { int i; char *optionArgDesc; - char *longOpt; + const char *longOpt; if (usageType == GENERAL_USAGE) { (void) printf("%s:\t%s %s [", gettext("Usage"), commandName, diff --git a/usr/src/data/hwdata/pci.ids b/usr/src/data/hwdata/pci.ids index 09ef6d8bf1..be8b8dfabb 100644 --- a/usr/src/data/hwdata/pci.ids +++ b/usr/src/data/hwdata/pci.ids @@ -1,8 +1,8 @@ # # List of PCI ID's # -# Version: 2019.09.11 -# Date: 2019-09-11 03:15:02 +# Version: 2020.02.22 +# Date: 2020-02-22 03:15:04 # # Maintained by Albert Pool, Martin Mares, and other volunteers from # the PCI ID Project at https://pci-ids.ucw.cz/. @@ -13,6 +13,10 @@ # This file can be distributed under either the GNU General Public License # (version 2 or higher) or the 3-clause BSD License. # +# The database is a compilation of factual data, and as such the copyright +# only covers the aggregation and formatting. The copyright is held by +# Martin Mares and Albert Pool. +# # Vendors, devices and subsystems. Please keep sorted. @@ -63,6 +67,7 @@ # 018a is not LevelOne but there is a board misprogrammed 018a LevelOne 0106 FPC-0106TX misprogrammed [RTL81xx] +01de Oxide Computer Company # 021b is not Compaq but there is a board misprogrammed 021b Compaq Computer Corporation 8139 HNE-300 (RealTek RTL8139c) [iPaq Networking] @@ -432,6 +437,8 @@ 1028 1fd1 PERC H730P MX 17aa 1052 ThinkServer RAID 720i 17aa 1053 ThinkServer RAID 720ix + 1bd4 0014 6G SAS3108 2G + 1bd4 0015 6G SAS3108 4G 1d49 0600 ThinkSystem RAID 730-8i 1GB Cache PCIe 12Gb Adapter 1d49 0608 ThinkSystem RAID 730-8i 2GB Flash PCIe 12Gb Adapter 1d49 0609 ThinkSystem RAID 730-8i 4GB Flash PCIe 12Gb Adapter @@ -491,6 +498,7 @@ 006e SAS2308 PCI-Express Fusion-MPT SAS-2 0070 SAS2004 PCI-Express Fusion-MPT SAS-2 [Spitfire] 1000 3010 SAS9211-4i + 1014 040e ServeRAID H1110 0071 MR SAS HBA 2004 0072 SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] 1000 3040 9210-8i @@ -502,6 +510,12 @@ 1028 1f1f PERC H200 Modular 1028 1f20 PERC H200 Embedded 1028 1f22 PERC H200 Internal Tape Adapter +# Fujitsu D2607 SAS2008 HBA controller + 1734 1177 HBA Ctrl SAS 6G 0/1 [D2607] + 1bd4 000d 6G SAS2008IT + 1bd4 000e 6G SAS2008IR + 1bd4 000f 6G SAS2008IT SA5248 + 1bd4 0010 6G SAS2008IR SA5248 8086 350f RMS2LL040 RAID Controller 8086 3700 SSD 910 Series 0073 MegaRAID SAS 2008 [Falcon] @@ -610,6 +624,8 @@ 1590 0041 H220i 1590 0042 H221 / 9207-8e 1590 0044 H220i + 1bd4 0009 6G SAS2308IR + 1bd4 000a 6G SAS2308IT 8086 3000 RS25GB008 RAID Controller 8086 3060 RS25FB044 RAID Controller 8086 3516 RMS25JB080 RAID Controller @@ -638,10 +654,22 @@ 1028 1fd3 HBA330 MMZ # Supermicro AOC-S3008L-L8e uses 0808 for their SAS3008 SAS controller 15d9 0808 AOC-S3008L-L8e + 1bd4 000b 12G SAS3008IR + 1bd4 000c 12G SAS3008IT 1bd4 0011 Inspur 12Gb 8i-3008 IT SAS HBA + 1bd4 0012 12Gb SAS3008IR UDM + 1bd4 0026 12G SAS3008IT RACK + 1bd4 0027 12G SAS3008IMR RACK + 1bd4 0028 12G SAS3008IR RACK 00ab SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) +# 8 Internal and 8 External port channel 9400 HBA + 1000 3040 HBA 9400-8i8e 8086 3530 Integrated RAID Module RMSP3JD160J 00ac SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) +# Channel 16 internal port HBA + 1000 3000 HBA 9400-16i +# Channel 16 external port HBA + 1000 3020 HBA 9400-16e 1028 1fe3 HBA345 Adapter 1028 1fe4 HBA345 Front 1d49 0201 ThinkSystem 430-16i SAS/SATA 12Gb HBA @@ -651,6 +679,8 @@ 00ae SAS3508 Fusion-MPT Tri-Mode RAID On Chip (ROC) 00af SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) 1000 3010 HBA 9400-8i +# 9400 Channel 8 external port HBA + 1000 3030 HBA 9400-8e 1d49 0200 ThinkSystem 430-8i SAS/SATA 12Gb HBA 1d49 0202 ThinkSystem 430-8e SAS/SATA 12Gb HBA 1d49 0204 ThinkSystem 430-8i SAS/SATA 12Gb Dense HBA @@ -672,18 +702,39 @@ 00cf MegaRAID SAS-3 3324 [Intruder] 1000 9370 MegaRAID SAS 9361-24i 00d0 SAS3716 Fusion-MPT Tri-Mode RAID Controller Chip (ROC) +# 9405W 16 internal port channel HBA + 1000 3050 HBA 9405W-16i +# 9405W 8 internal and 8 external port channel HBA + 1000 3070 HBA 9405W-8i8e 00d1 SAS3616 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) +# 9405W 16 external port Channel HBA + 1000 3080 HBA 9405W-16e +# 9405W 16 internal port Channel HBA + 1000 3090 HBA 9405W-16i 00d3 MegaRAID Tri-Mode SAS3716W 00e0 Fusion-MPT 12GSAS/PCIe Unsupported SAS39xx 00e1 Fusion-MPT 12GSAS/PCIe SAS39xx 00e2 Fusion-MPT 12GSAS/PCIe Secure SAS39xx 00e3 Fusion-MPT 12GSAS/PCIe Unsupported SAS39xx 00e4 Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx +# Invalid part + 1028 200b HBA355i Adapter Invalid +# Invalid part + 1028 200c HBA355i Front Invalid +# Invalid part + 1028 200d HBA355e Adapter Invalid +# Invalid part + 1028 200e HBA350i MX Invalid +# Soft Secure 00e5 Fusion-MPT 12GSAS/PCIe SAS38xx +# Soft Secure 1028 200b HBA355i Adapter +# Soft Secure 1028 200c HBA355i Front +# Soft Secure 1028 200d HBA355e Adapter - 1028 200e HBA355i MX +# Soft Secure + 1028 200e HBA350i MX 1d49 0205 ThinkSystem 440-16i SAS/SATA PCIe Gen4 12Gb Internal HBA 1d49 0206 ThinkSystem 440-16e SAS/SATA PCIe Gen4 12Gb HBA 00e6 Fusion-MPT 12GSAS/PCIe Secure SAS38xx @@ -694,6 +745,14 @@ 1d49 0205 ThinkSystem 440-16i SAS/SATA PCIe Gen4 12Gb Internal HBA 1d49 0206 ThinkSystem 440-16e SAS/SATA PCIe Gen4 12Gb HBA 00e7 Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx +# Tampered part + 1028 200b HBA355i Adapter Tampered +# Tampered part + 1028 200c HBA355i Front Tampered +# Tampered part + 1028 200d HBA355e Adapter Tampered +# Tampered part + 1028 200e HBA350i MX Tampered 02b0 Virtual Endpoint on PCIe Switch 1d49 0001 ThinkSystem 1610-4P NVMe Switch Adapter 1d49 0002 ThinkSystem 810-4P NVMe Switch Adapter @@ -770,6 +829,10 @@ 0901 61C102 1000 63C815 10e0 MegaRAID 12GSAS/PCIe Unsupported SAS39xx + 1028 1ae0 PERC H755 Adapter - Invalid Device + 1028 1ae1 PERC H755 Front - Invalid Device + 1028 1ae2 PERC H755N Front - Invalid Device + 1028 1ae3 PERC H755 MX - Invalid Device 10e1 MegaRAID 12GSAS/PCIe SAS39xx 1028 1ae0 PERC H755 Adapter 1028 1ae1 PERC H755 Front @@ -793,6 +856,10 @@ 1d49 060e ThinkSystem RAID 940-32i 8GB Flash PCIe Gen4 12Gb Adapter 1d49 060f ThinkSystem RAID 940-8e 4GB Flash PCIe Gen4 12Gb Adapter 10e3 MegaRAID 12GSAS/PCIe Unsupported SAS39xx + 1028 1ae0 PERC H755 Adapter - Tampered Device + 1028 1ae1 PERC H755 Front - Tampered Device + 1028 1ae2 PERC H755N Front - Tampered Device + 1028 1ae3 PERC H755 MX - Tampered Device 10e4 MegaRAID 12GSAS/PCIe Unsupported SAS38xx 10e5 MegaRAID 12GSAS/PCIe SAS38xx 10e6 MegaRAID 12GSAS/PCIe Secure SAS38xx @@ -829,7 +896,9 @@ 1306 Kaveri 1307 Kaveri 1308 Kaveri HDMI/DP Audio Controller + 17aa 3988 Z50-75 1309 Kaveri [Radeon R6/R7 Graphics] + 17aa 3830 Z50-75 130a Kaveri [Radeon R6 Graphics] 130b Kaveri [Radeon R4 Graphics] 130c Kaveri [Radeon R7 Graphics] @@ -850,17 +919,22 @@ 131c Kaveri [Radeon R7 Graphics] 131d Kaveri [Radeon R6 Graphics] 13e9 Ariel + 1478 Navi 10 XL Upstream Port of PCI Express Switch + 1479 Navi 10 XL Downstream Port of PCI Express Switch 154c Kryptos 154e Garfield 1551 Arlene 1552 Pooky 1561 Anubis 15d8 Picasso + 103c 8615 Pavilion Laptop 15-cw1xxx 15dd Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] 103c 83c6 Radeon Vega 8 Mobile 1458 d000 Radeon RX Vega 11 15de Raven/Raven2/Fenghuang HDMI/DP Audio Controller + 103c 8615 Pavilion Laptop 15-cw1xxx 15df Raven/Raven2/Fenghuang/Renoir Cryptographic Coprocessor + 103c 8615 Pavilion Laptop 15-cw1xxx 15ff Fenghuang [Zhongshan Subor Z+] 1607 Arden 1636 Renoir @@ -1035,7 +1109,7 @@ 4382 SB600 AC97 Audio 4383 SBx00 Azalia (Intel HDA) 1019 2120 A785GM-M - 103c 1611 Pavilion DM1Z-3000 + 103c 1611 Pavilion dm1z-3000 103c 280a DC5750 Microtower 1043 8230 M3A78-EH Motherboard 1043 836c M4A785TD Motherboard @@ -1109,6 +1183,7 @@ 1458 b002 GA-MA770-DS3rev2.0 Motherboard 1849 4390 Motherboard (one of many) 4391 SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] + 103c 1609 ProLiant MicroServer N36L 103c 1611 Pavilion DM1Z-3000 1043 82ef M3A78-EH Motherboard 1043 8443 M5A88-V EVO @@ -1122,6 +1197,7 @@ 4395 SB8x0/SB9x0 SATA Controller [Storage mode] 4396 SB7x0/SB8x0/SB9x0 USB EHCI Controller 1019 2120 A785GM-M + 103c 1609 ProLiant MicroServer N36L 103c 1611 Pavilion DM1Z-3000 1043 82ef M3A78-EH Motherboard 1043 8443 M5A88-V EVO @@ -1130,6 +1206,7 @@ 174b 1001 PURE Fusion Mini 4397 SB7x0/SB8x0/SB9x0 USB OHCI0 Controller 1019 2120 A785GM-M + 103c 1609 ProLiant MicroServer N36L 103c 1611 Pavilion DM1Z-3000 1043 82ef M3A78-EH Motherboard 1043 8443 M5A88-V EVO @@ -1150,10 +1227,12 @@ 439c SB7x0/SB8x0/SB9x0 IDE Controller 1002 4392 MSI MS-7713 motherboard 1019 2120 A785GM-M + 103c 1609 ProLiant MicroServer N36L 1043 82ef M3A78-EH Motherboard 105b 0e13 N15235/A74MX mainboard / AMD SB700 439d SB7x0/SB8x0/SB9x0 LPC host controller 1019 2120 A785GM-M + 103c 1609 ProLiant MicroServer N36L 103c 1611 Pavilion DM1Z-3000 1043 82ef M3A78-EH Motherboard 1043 8443 M5A88-V EVO @@ -1800,6 +1879,7 @@ 1642 3f09 Radeon R7 350 6611 Oland [Radeon HD 8570 / R7 240/340 OEM] 1028 210b Radeon R5 240 OEM + 1642 1869 AMD Radeon 520 174b 4248 Radeon R7 240 OEM 174b a240 Radeon R7 240 OEM 174b d340 Radeon R7 340 OEM @@ -1865,7 +1945,7 @@ 17aa 3805 Radeon HD 8570M 6664 Jet XT [Radeon R5 M240] 6665 Jet PRO [Radeon R5 M230 / R7 M260DX / Radeon 520 Mobile] - 17aa 1309 Radeon R7 M260DX + 17aa 1309 Z50-75 Radeon R7 M260DX 17aa 368f Radeon R5 A230 6667 Jet ULT [Radeon R5 M230] 666f Sun LE [Radeon HD 8550M / R5 M230] @@ -2496,7 +2576,7 @@ 1462 3418 Radeon RX 580 Armor 4G OC 1462 341e Radeon RX 570 Armor 4G OC 1462 8a92 Radeon RX 580 - 148c 2372 Radeon RX 480 + 148c 2372 Radeon RX 480 [Red Dragon] 148c 2373 Radeon RX 470 1682 9470 Radeon RX 470 1682 9480 Radeon RX 480 @@ -2507,8 +2587,9 @@ 1787 a470 Radeon RX 470 1787 a480 Radeon RX 480 1849 5001 Phantom Gaming X RX 580 OC + 1849 5030 Phantom Gaming D Radeon RX580 8G OC 1da2 e353 Radeon RX 570 Pulse 4GB - 1da2 e366 Nitro+ Radeon RX 570/580 + 1da2 e366 Nitro+ Radeon RX 570/580/590 67e0 Baffin [Radeon Pro WX 4170] 103c 8270 Radeon Pro WX 4170 103c 8272 Radeon Pro WX 4170 @@ -2526,6 +2607,7 @@ 67e9 Baffin [Polaris11] 67eb Baffin [Radeon Pro V5300X] 67ef Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] + 1028 1703 RX 560D OEM OC 2 GB 103c 3421 Radeon RX 460 106b 0160 Radeon Pro 460 106b 0166 Radeon Pro 455 @@ -3446,7 +3528,12 @@ 1043 04a0 Radeon R9 FURY X 174b e329 Radeon R9 FURY 7310 Navi 10 - 731f Navi 10 [Radeon RX 5700 / 5700 XT] + 7312 Navi 10 [Radeon Pro W5700] + 731f Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] + 7340 Navi 14 [Radeon RX 5500/5500M / Pro 5500M] + 7341 Navi 14 [Radeon Pro W5500] + 7347 Navi 14 [Radeon Pro W5500M] + 734f Navi 14 [Radeon Pro W5300M] 7833 RS350 Host Bridge 7834 RS350 [Radeon 9100 PRO/XT IGP] 7835 RS350M [Mobility Radeon 9000 IGP] @@ -3682,6 +3769,7 @@ 1019 2120 A785GM-M 1043 83a2 M4A785TD Motherboard 9712 RS880M [Mobility Radeon HD 4225/4250] + 103c 1609 ProLiant MicroServer N36L 9713 RS880M [Mobility Radeon HD 4100] 9714 RS880 [Radeon HD 4290] 9715 RS880 [Radeon HD 4250] @@ -3700,6 +3788,7 @@ 9830 Kabini [Radeon HD 8400 / R3 Series] 9831 Kabini [Radeon HD 8400E] 9832 Kabini [Radeon HD 8330] + 1849 9832 QC5000-ITX/PH 9833 Kabini [Radeon HD 8330E] 9834 Kabini [Radeon HD 8210] 9835 Kabini [Radeon HD 8310E] @@ -3709,6 +3798,7 @@ 9839 Kabini [Radeon HD 8180] 983d Temash [Radeon HD 8250/8280G] 9840 Kabini HDMI/DP Audio + 1849 9840 QC5000-ITX/PH 9850 Mullins [Radeon R3 Graphics] 9851 Mullins [Radeon R4/R5 Graphics] 1179 f928 Beema [Radeon R5 Graphics] @@ -4477,6 +4567,7 @@ 1467 Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 7 1468 Zeppelin Cryptographic Coprocessor NTBCCP 1480 Starship/Matisse Root Complex + 1462 7c37 X570-A PRO motherboard 1481 Starship/Matisse IOMMU 1482 Starship/Matisse PCIe Dummy Host Bridge 1483 Starship/Matisse GPP Bridge @@ -4484,6 +4575,7 @@ 1485 Starship/Matisse Reserved SPP 1486 Starship/Matisse Cryptographic Coprocessor PSPCPP 1487 Starship/Matisse HD Audio Controller + 1462 9c37 X570-A PRO motherboard 1488 Starship Reserved SSP 1489 Starship Reserved SSP 148a Starship/Matisse PCIe Dummy Function @@ -4505,6 +4597,7 @@ 149a Starship PCIe GPP Bridge [1:0] 149b Starship Reserved SSP 149c Matisse USB 3.0 Host Controller + 1462 7c37 X570-A PRO motherboard 1510 Family 14h Processor Root Complex 174b 1001 PURE Fusion Mini 1512 Family 14h Processor Root Port @@ -4519,6 +4612,7 @@ 1534 Family 16h Processor Function 4 1535 Family 16h Processor Function 5 1536 Family 16h Processor Root Complex + 1849 1536 QC5000-ITX/PH 1537 Kabini/Mullins PSP-Platform Security Processor 1538 Family 16h Processor Function 0 1539 Kabini P2P Bridge for PCIe Ports[4:0] @@ -4587,7 +4681,9 @@ 15bc Stoney PCIe [GFX,GPP] Bridge [4:0] 15be Stoney Audio Processor 15d0 Raven/Raven2 Root Complex + 103c 8615 Pavilion Laptop 15-cw1xxx 15d1 Raven/Raven2 IOMMU + 103c 8615 Pavilion Laptop 15-cw1xxx 15d2 Raven/Raven2 PCIe Dummy Host Bridge 15d3 Raven/Raven2 PCIe GPP Bridge [6:0] 15d4 FireFlight USB 3.1 @@ -4598,12 +4694,16 @@ 15de Raven/Raven2/FireFlight HD Audio Controller 15df Family 17h (Models 10h-1fh) Platform Security Processor 15e0 Raven USB 3.1 + 103c 8615 Pavilion Laptop 15-cw1xxx 15e1 Raven USB 3.1 + 103c 8615 Pavilion Laptop 15-cw1xxx 15e2 Raven/Raven2/FireFlight/Renoir Audio Processor 15e3 Family 17h (Models 10h-1fh) HD Audio Controller + 103c 8615 Pavilion Laptop 15-cw1xxx 15e4 Raven/Raven2/Renoir Sensor Fusion Hub 15e5 Raven2 USB 3.1 15e6 Raven/Raven2/Renoir Non-Sensor Fusion Hub KMDF driver + 1022 15e4 Raven/Raven2/Renoir Sensor Fusion Hub 15e8 Raven/Raven2 Device 24: Function 0 15e9 Raven/Raven2 Device 24: Function 1 15ea Raven/Raven2 Device 24: Function 2 @@ -4747,6 +4847,9 @@ 43c7 400 Series Chipset PCIe Port 43c8 400 Series Chipset SATA Controller 43d5 400 Series Chipset USB 3.1 XHCI Controller + 57a3 Matisse PCIe GPP Bridge + 57a4 Matisse PCIe GPP Bridge + 57ad Matisse Switch Upstream 7006 AMD-751 [Irongate] System Controller 7007 AMD-751 [Irongate] AGP Bridge 700a AMD-IGR4 AGP Host to PCI Bridge @@ -4805,6 +4908,8 @@ 7801 FCH SATA Controller [AHCI mode] 103c 168b ProBook 4535s Notebook 103c 194e ProBook 455 G1 Notebook + 17aa 3988 Z50-75 + 1849 7801 QC5000-ITX/PH 7802 FCH SATA Controller [RAID mode] 7803 FCH SATA Controller [RAID mode] 7804 FCH SATA Controller [AHCI mode] @@ -4814,38 +4919,57 @@ 7807 FCH USB OHCI Controller 103c 194e ProBook 455 G1 Notebook 103c 1985 Pavilion 17-e163sg Notebook PC + 17aa 3988 Z50-75 + 1849 7807 QC5000-ITX/PH 7808 FCH USB EHCI Controller 103c 194e ProBook 455 G1 Notebook 103c 1985 Pavilion 17-e163sg Notebook PC + 17aa 3988 Z50-75 + 1849 7808 QC5000-ITX/PH 7809 FCH USB OHCI Controller 103c 194e ProBook 455 G1 Notebook + 17aa 3988 Z50-75 780a Kabini/Mullins SATA Raid/AHCI Mode (DotHill driver) 780b FCH SMBus Controller 103c 194e ProBook 455 G1 Notebook 103c 1985 Pavilion 17-e163sg Notebook PC + 17aa 3988 Z50-75 + 1849 780b QC5000-ITX/PH 780c FCH IDE Controller 780d FCH Azalia Controller 103c 194e ProBook 455 G1 Notebook 103c 1985 Pavilion 17-e163sg Notebook PC 1043 8444 F2A85-M Series + 17aa 3988 Z50-75 + 1849 8892 QC5000-ITX/PH 780e FCH LPC Bridge 103c 194e ProBook 455 G1 Notebook 103c 1985 Pavilion 17-e163sg Notebook PC + 17aa 3988 Z50-75 + 1849 780e QC5000-ITX/PH 780f FCH PCI Bridge 7812 FCH USB XHCI Controller 7813 FCH SD Flash Controller 7814 FCH USB XHCI Controller 103c 194e ProBook 455 G1 Notebook 103c 1985 Pavilion 17-e163sg Notebook PC + 17aa 3988 Z50-75 + 1849 7814 QC5000-ITX/PH 7900 FCH SATA Controller [IDE mode] 7901 FCH SATA Controller [AHCI mode] + 103c 8615 Pavilion Laptop 15-cw1xxx + 1462 7c37 X570-A PRO motherboard 7902 FCH SATA Controller [RAID mode] 7903 FCH SATA Controller [RAID mode] 7904 FCH SATA Controller [AHCI mode] 7906 FCH SD Flash Controller 7908 FCH USB EHCI Controller 790b FCH SMBus Controller + 103c 8615 Pavilion Laptop 15-cw1xxx + 1462 7c37 X570-A PRO motherboard 790e FCH LPC Bridge + 103c 8615 Pavilion Laptop 15-cw1xxx + 1462 7c37 X570-A PRO motherboard 790f FCH PCI Bridge 7914 FCH USB XHCI Controller 9600 RS780 Host Bridge @@ -4853,13 +4977,16 @@ 1043 82f1 M3A78-EH Motherboard 9601 RS880 Host Bridge 1019 2120 A785GM-M + 103c 1609 ProLiant MicroServer N36L 1043 83a2 M4A785-M Mainboard 1043 843e M5A88-V EVO 9602 RS780/RS880 PCI to PCI bridge (int gfx) 9603 RS780 PCI to PCI bridge (ext gfx port 0) + 103c 1609 ProLiant MicroServer N36L 9604 RS780/RS880 PCI to PCI bridge (PCIE port 0) 9605 RS780/RS880 PCI to PCI bridge (PCIE port 1) 9606 RS780 PCI to PCI bridge (PCIE port 2) + 103c 1609 ProLiant MicroServer N36L 9607 RS780/RS880 PCI to PCI bridge (PCIE port 3) 9608 RS780/RS880 PCI to PCI bridge (PCIE port 4) 9609 RS780/RS880 PCI to PCI bridge (PCIE port 5) @@ -5815,6 +5942,7 @@ 4031 zx2 I/O Controller 4037 PCIe Local Bus Adapter 9602 AMD RS780/RS880 PCI to PCI bridge (int gfx) + 103c 1609 ProLiant MicroServer N36L 103e Solliday Engineering 103f Synopsys/Logic Modeling Group 1040 Accelgraphics Inc. @@ -6400,6 +6528,8 @@ 4802 Falcon 4803 Hawk 4806 CPX8216 +# MPC7410 PowerPC microprocessor and PCI host bridge + 480b MPC7410 4d68 20268 5600 SM56 PCI Modem 1057 0300 SM56 PCI Speakerphone Modem @@ -6830,6 +6960,10 @@ 1077 02e4 QLE2772 Dual Port 32GFC PCIe Gen4 x8 Adapter 1077 02ee QLE2870 Single Port 64GFC PCIe Gen4 x8 Adapter 1077 02f0 QLE2770 Single Port 32GFC PCIe Gen4 x8 Adapter + 1077 02f2 QLogic 1x32Gb QLE2770 FC HBA + 1077 02f3 QLogic 2x32Gb QLE2772 FC HBA + 1590 02d3 SN1610Q - 1P Enhanced 32GFC Single Port Fibre Channel Host Bus Adapter + 1590 02d4 SN1610Q – 2P Enhanced 32GFC Dual Port Fibre Channel Host Bus Adapter 2300 QLA2300 64-bit Fibre Channel Adapter 2312 ISP2312-based 2Gb Fibre Channel to PCI-X HBA 103c 0131 2Gb Fibre Channel - Single port [A7538A] @@ -6901,6 +7035,20 @@ 1077 0012 FastLinQ QL41112H 10GbE Adapter 1077 0019 QL41232HOCU - Dual Port 25/10GbE SFP28 OCP Adapter 1077 0039 QLogic QL41262 PCIe 25Gb 2-Port SFP28 Ethernet Adapter + 1077 0053 QLogic 2x25GE QL41232HQCU NIC + 1077 0054 2x10GE QL41132HQRJ NIC + 1077 0055 QLogic 2x10GE QL41132HQCU NIC + 1077 0056 2x10GE QL41132HxRJ NIC + 1077 0057 2x25GE QL41232HxCU NIC + 1077 0065 QLogic 4x10GE QL41154HQRJ CNA + 1077 0066 QLogic 4x10GE QL41154HQCU CNA + 1077 0068 10GbE 2p SFP+ QL41132HLCU-HC Adapter + 1077 0069 10GbE 2p BASE-T QL41132HQRJ-HC OCP3 Adapter + 1077 0070 10GbE 2p BASE-T QL41132HLRJ-HC Adapter + 1077 0071 10GbE 2p SFP+ QL41132HQCU-HC OCP3 Adapter + 1077 0072 10GbE 4p SFP+ QL41134HLCU-HC Adapter + 1077 0073 10/25GbE 2p SFP28 QL41232HQCU-HC OCP3 Adapter + 1077 0074 10/25GbE 2p SFP28 QL41232HLCU-HC Adapter 1590 021a 10GbE 2P QL41162HLRJ-HP Adapter 1590 021b 10GbE 2P QL41162HLRJ-HP Adapter 1590 021d 10/25GbE 2P QL41222HLCU-HP Adapter @@ -6937,6 +7085,8 @@ 1077 000d FastLinQ QL41262H 25GbE iSCSI Adapter 1077 000e FastLinQ QL41162H 10GbE iSCSI Adapter 1077 000f 2x25GE QL41262HMKR CNA + 1077 0065 QLogic 4x10GE QL41154HQRJ CNA + 1077 0066 QLogic 4x10GE QL41154HQCU CNA 1590 021a 10GbE 2P QL41162HLRJ-HP Adapter 1590 021b 10GbE 2P QL41162HLRJ-HP Adapter 8090 FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) @@ -6956,6 +7106,13 @@ 1077 0010 2x25GE QL41232HMKR NIC 1077 0011 FastLinQ QL41212H 25GbE Adapter (SR-IOV VF) 1077 0012 FastLinQ QL41112H 10GbE Adapter (SR-IOV VF) + 1077 0053 QLogic 2x25GE QL41232HQCU NIC + 1077 0054 QLogic 2x10GE QL41132HQRJ NIC + 1077 0055 QLogic 2x10GE QL41132HQCU NIC + 1077 0056 2x10GE QL41132HxRJ NIC + 1077 0057 2x25GE QL41232HxCU NIC + 1077 0065 QLogic 4x10GE QL41154HQRJ CNA + 1077 0066 QLogic 4x10GE QL41154HQCU CNA 1590 021a 10GbE 2P QL41162HLRJ-HP Adapter 1590 021b 10GbE 2P QL41162HLRJ-HP Adapter 1590 021e 10/25GbE 2P QL41162HMRJ-HP Adapter @@ -10792,7 +10949,7 @@ 0e0f GK208 HDMI/DP Audio Controller 0e12 TegraK1 PCIe x4 Bridge 0e13 TegraK1 PCIe x1 Bridge - 0e1a GK110 HDMI Audio + 0e1a GK110 High Definition Audio Controller 0e1b GK107 HDMI Audio Controller 103c 197b ZBook 15 1043 8428 GTX650-DC-1GD5 @@ -10997,6 +11154,7 @@ 10f0 GP104 High Definition Audio Controller 10f1 GP106 High Definition Audio Controller 10f7 TU102 High Definition Audio Controller + 10f8 TU104 HD Audio Controller 10f9 TU106 High Definition Audio Controller 1043 8673 TURBO-RTX2070-8G 1140 GF117M [GeForce 610M/710M/810M/820M / GT 620M/625M/630M/720M] @@ -11380,8 +11538,7 @@ 106b 010d iMac 13,2 11a7 GK104M [GeForce GTX 675MX] 11af GK104GLM [GRID IceCube] -# GRID K2 Quadro USM - 11b0 GK104GL [GRID K240Q\K260Q vGPU] + 11b0 GK104GL [GRID K240Q / K260Q vGPU] 10de 101a GRID K240Q 10de 101b GRID K260Q 11b1 GK104GL [GRID K2 Tesla USM] @@ -11593,6 +11750,7 @@ 1406 GM206 [GeForce GTX 960 OEM] 1407 GM206 [GeForce GTX 750 v2] 1427 GM206M [GeForce GTX 965M] + 103c 825b OMEN-17-w001nv 1430 GM206GL [Quadro M2000] 1431 GM206GL [Tesla M4] 1436 GM206GLM [Quadro M2200 Mobile] @@ -11616,14 +11774,19 @@ 17c2 GM200 [GeForce GTX TITAN X] 17c8 GM200 [GeForce GTX 980 Ti] 17f0 GM200GL [Quadro M6000] + 10de 1141 VCA 6000 17f1 GM200GL [Quadro M6000 24GB] 17fd GM200GL [Tesla M40] - 1ad6 TU102 USB 3.1 Controller - 1ad7 TU102 UCSI Controller + 1ad6 TU102 USB 3.1 Host Controller + 1ad7 TU102 USB Type-C UCSI Controller + 1ad8 TU104 USB 3.1 Host Controller + 1ad9 TU104 USB Type-C UCSI Controller 1ada TU106 USB 3.1 Host Controller 1043 8673 TURBO-RTX2070-8G - 1adb TU106 USB Type-C Port Policy Controller + 1adb TU106 USB Type-C UCSI Controller 1043 8673 TURBO-RTX2070-8G + 1aeb TU116 High Definition Audio Controller + 1aed TU116 [GeForce GTX 1650 SUPER] 1b00 GP102 [TITAN X] 1b01 GP102 [GeForce GTX 1080 Ti 10GB] 1b02 GP102 [TITAN Xp] @@ -11685,6 +11848,7 @@ 1414 0020 GTX 1060 Mobile 1c2d GP106M 1c30 GP106GL [Quadro P2000] + 1c31 GP106GL [Quadro P2200] 1c35 GP106 1c60 GP106BM [GeForce GTX 1060 Mobile 6GB] 103c 8390 GeForce GTX 1060 Max-Q 6GB @@ -11693,6 +11857,8 @@ 1c70 GP106GL 1c81 GP107 [GeForce GTX 1050] 1c82 GP107 [GeForce GTX 1050 Ti] + 1043 8613 PH-GTX1050TI-4G + 1458 3763 GV-N105TOC-4GD 1c83 GP107 [GeForce GTX 1050 3GB] 1c8c GP107M [GeForce GTX 1050 Ti Mobile] 1c8d GP107M [GeForce GTX 1050 Mobile] @@ -11701,6 +11867,7 @@ 1c90 GP107M [GeForce MX150] 1c91 GP107M [GeForce GTX 1050 3 GB Max-Q] 1c92 GP107M [GeForce GTX 1050 Mobile] + 1c94 GP107M [GeForce MX350] 1ca7 GP107GL 1ca8 GP107GL 1caa GP107GL @@ -11717,8 +11884,11 @@ 103c 842f P1000 [Zbook 17 G5 mobile workstation] 103c 8451 P1000 [Zbook Studio x360 G5 mobile workstation] 1cbc GP107GLM [Quadro P600 Mobile] + 1cbd GP107GLM [Quadro P620] 1ccc GP107BM [GeForce GTX 1050 Ti Mobile] 1ccd GP107BM [GeForce GTX 1050 Mobile] + 1cfa GP107GL [Quadro P2000] + 1cfb GP107GL [Quadro P1000] 1d01 GP108 [GeForce GT 1030] 1d10 GP108M [GeForce MX150] 17aa 225e ThinkPad T480 @@ -11726,18 +11896,26 @@ 1d12 GP108M [GeForce MX150] 1d72 1701 Mi Notebook Pro [GeForce MX150] 1d13 GP108M [GeForce MX250] + 1d16 GP108M [GeForce MX330] 1d33 GP108GLM [Quadro P500 Mobile] + 1d34 GP108GLM [Quadro P520] 1d52 GP108BM [GeForce MX250] 1d81 GV100 [TITAN V] 1db1 GV100GL [Tesla V100 SXM2 16GB] - 1db2 GV100GL [Tesla V100-DGXS-16GB] + 1db2 GV100GL [Tesla V100 DGXS 16GB] 1db3 GV100GL [Tesla V100 FHHL 16GB] 1db4 GV100GL [Tesla V100 PCIe 16GB] 1db5 GV100GL [Tesla V100 SXM2 32GB] 1db6 GV100GL [Tesla V100 PCIe 32GB] 1db7 GV100GL [Tesla V100 DGXS 32GB] + 1db8 GV100GL [Tesla V100 SXM3 32GB] + 10de 131d Tesla V100-SXM3-32GB-H 1dba GV100GL [Quadro GV100] 10de 12eb TITAN V CEO Edition + 1df0 GV100GL [Tesla PG500-216] + 1df2 GV100GL [Tesla PG503-216] + 1df5 GV100GL [Tesla V100 SXM2 16GB] + 1df6 GV100GL [Tesla V100S PCIe 32GB] 1e02 TU102 [TITAN RTX] 1e04 TU102 [GeForce RTX 2080 Ti] 1e07 TU102 [GeForce RTX 2080 Ti Rev. A] @@ -11747,14 +11925,22 @@ 1e30 TU102GL [Quadro RTX 6000/8000] 10de 129e Quadro RTX 8000 10de 12ba Quadro RTX 6000 + 1e37 TU102GL [GRID RTX T10-4/T10-8/T10-16] + 10de 1347 GRID RTX T10-8 + 10de 1348 GRID RTX T10-4 + 10de 1370 GRID RTX T10-16 1e38 TU102GL 1e3c TU102GL 1e3d TU102GL 1e3e TU102GL + 1e78 TU102GL [Quadro RTX 6000/8000] + 10de 13d8 Quadro RTX 8000 + 10de 13d9 Quadro RTX 6000 1e81 TU104 [GeForce RTX 2080 SUPER] 1e82 TU104 [GeForce RTX 2080] 1e84 TU104 [GeForce RTX 2070 SUPER] 1e87 TU104 [GeForce RTX 2080 Rev. A] + 1e89 TU104 [GeForce RTX 2060] 1e90 TU104M [GeForce RTX 2080 Mobile] 1eab TU104M 1eae TU104M @@ -11765,6 +11951,8 @@ 1eb8 TU104GL [Tesla T4] 1eb9 TU104GL 1ebe TU104GL + 1ec2 TU104 [GeForce RTX 2070 SUPER] + 1ec7 TU104 [GeForce RTX 2070 SUPER] 1ed0 TU104BM [GeForce RTX 2080 Mobile] 1f02 TU106 [GeForce RTX 2070] 1043 8673 TURBO RTX 2070 @@ -11776,11 +11964,15 @@ 1f11 TU106M [GeForce RTX 2060 Mobile] 1f2e TU106M 1f36 TU106GLM [Quadro RTX 3000 Mobile / Max-Q] + 1f42 TU106 [GeForce RTX 2060 SUPER] + 1f47 TU106 [GeForce RTX 2060 SUPER] 1f50 TU106BM [GeForce RTX 2070 Mobile] 1f51 TU106BM [GeForce RTX 2060 Mobile] 1f81 TU117 1f82 TU117 [GeForce GTX 1650] + 1f91 TU117M [GeForce GTX 1650 Mobile / Max-Q] 1f92 TU117M [GeForce GTX 1650 Mobile] + 1f96 TU117M [GeForce GTX 1650 Mobile / Max-Q] 1fae TU117GL 1fb8 TU117GLM [Quadro T2000 Mobile / Max-Q] 1fb9 TU117GLM [Quadro T1000 Mobile] @@ -11788,9 +11980,11 @@ 2182 TU116 [GeForce GTX 1660 Ti] 2183 TU116 2184 TU116 [GeForce GTX 1660] + 2187 TU116 [GeForce GTX 1650 SUPER] 2191 TU116M [GeForce GTX 1660 Ti Mobile] 21ae TU116GL 21bf TU116GL + 21c4 TU116 [GeForce GTX 1660 SUPER] 21d1 TU116BM [GeForce GTX 1660 Ti Mobile] 10df Emulex Corporation 0720 OneConnect NIC (Skyhawk) @@ -12005,6 +12199,7 @@ 17aa 3832 Yoga 520 522a RTS522A PCI Express Card Reader 103c 8079 EliteBook 840 G3 + 103c 825b OMEN-17-w001nv 5249 RTS5249 PCI Express Card Reader 103c 1909 ZBook 15 524a RTS524A PCI Express Card Reader @@ -12026,6 +12221,7 @@ 1186 0300 DE-528 1259 2400 AT-2400 1af4 1100 QEMU Virtual Machine + 8125 RTL8125 2.5GbE Controller 8129 RTL-8129 10ec 8129 RT8129 Fast Ethernet Adapter 11ec 8129 RTL8111/8168 PCIe Gigabit Ethernet (misconfigured) @@ -12047,7 +12243,7 @@ 103c 006a NX9500 103c 2a20 Pavilion t3030.de Desktop PC 103c 30d9 Presario C700 - 1043 1045 L8400B or L3C/S notebook + 1043 1045 L8400B, L3C/S, X58LE notebook 1043 8109 P5P800-MX Mainboard 1071 8160 MIM2000 10bd 0320 EP-320X-R @@ -12105,6 +12301,9 @@ 103c 1611 Pavilion DM1Z-3000 103c 1950 ProBook 450/455 103c 2a6f Asus IPIBL-LB Motherboard + 103c 825b OMEN-17-w001nv + 103c 8615 Pavilion Laptop 15-cw1xxx + 1043 11f5 Notebook motherboard (one of many models) 1043 16d5 U6V/U31J laptop 1043 81aa P5B 1043 82c6 M3A78 Series Motherboard @@ -12120,7 +12319,9 @@ 1462 368c K9AG Neo2 1462 4180 Wind PC MS-7418 1462 7522 X58 Pro-E + 1462 7c37 X570-A PRO motherboard 1775 11cc CC11/CL11 + 17aa 3814 Z50-75 1849 8168 Motherboard (one of many) 7470 3468 TG-3468 Gigabit PCI Express Network Adapter 8086 2055 NUC Kit DN2820FYKH @@ -12171,8 +12372,11 @@ 8821 RTL8821AE 802.11ac PCIe Wireless Network Adapter b723 RTL8723BE PCIe Wireless Network Adapter 10ec 8739 Dell Wireless 1801 + 17aa b736 Z50-75 b822 RTL8822BE 802.11a/b/g/n/ac WiFi adapter + 103c 831b Realtek RTL8822BE 802.11ac 2 × 2 Wi-Fi + Bluetooth 4.2 Combo Adapter (MU-MIMO supported) c821 RTL8821CE 802.11ac PCIe Wireless Network Adapter + c822 RTL8822CE 802.11ac PCIe Wireless Network Adapter d723 RTL8723DE 802.11b/g/n PCIe Adapter 10ed Ascii Corporation 7310 V7310 @@ -13835,7 +14039,7 @@ 1259 2975 AT-2970SX/2SC Gigabit Ethernet Adapter 1259 2976 AT-2970LX/2SC Gigabit Ethernet Adapter 1259 2977 AT-2970TX/2TX Gigabit Ethernet Adapter - 4320 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC + 4320 SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] 1148 0121 Marvell RDK-8001 Adapter 1148 0221 Marvell RDK-8002 Adapter 1148 0321 Marvell RDK-8003 Adapter @@ -13854,9 +14058,23 @@ 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter 1148 9521 SK-9521 10/100/1000Base-T Adapter + 1259 2916 AT-2916T 4400 SK-9Dxx Gigabit Ethernet Adapter 4500 SK-9Mxx Gigabit Ethernet Adapter - 9000 SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45 + 9000 SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] + 1148 2100 SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45 + 1148 2200 SK-9S22 10/100/1000Base-T Dual Port Server Adapter, PCI-X, 2 Copper RJ-45 + 1148 2210 SK-9P22 10/100/1000 Base-T Dual Port PMC card + 1148 2220 TPMC-GBE-CO + 1148 8100 SK-9S81 1000Base-SX Server Adapter,PCI-X, Fiber SX/LC + 1148 8200 SK-9S82 1000Base-SX Dual Port Server Adapter, PCI-X, 2 Fiber SX/LC + 1148 8210 SK-9P82 1000 Base-SX Dual Port PMC card + 1148 8220 TPMC-GBE-FI + 1148 9100 SK-9S91 1000Base-LX Server Adapter,PCI-X, Fiber LX/LC + 1148 9200 SK-9S92 1000Base-LX Dual Port Server Adapter, PCI-X, 2 Fiber LX/LC + 1259 2973 AT-2971SX v2 Gigabit Adapter + 1259 2974 AT-2971T v2 Gigabit Adapter + 1259 2978 AT-2971LX Gigabit Adapter 9843 [Fujitsu] Gigabit Ethernet 9e00 SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 1148 2100 SK-9E21 Server Adapter @@ -14121,7 +14339,7 @@ 1177 Silicon Engineering 1178 Alfa, Inc. afa1 Fast Ethernet Adapter -1179 Toshiba America Info Systems +1179 Toshiba Corporation 0102 Extended IDE Controller 0103 EX-IDE Type-B 010f NVMe Controller @@ -14130,6 +14348,8 @@ 1028 1ffc Express Flash NVMe 1.92T (RI) U.2 (CD5) 1028 1ffd Express Flash NVMe 3.84T (RI) U.2 (CD5) 1028 1ffe Express Flash NVMe 7.68T (RI) U.2 (CD5) + 1179 0001 KIOXIA CM5-R series SSD + 1179 0021 KIOXIA CD5 series SSD 1d49 4039 Thinksystem U.2 CM5 NVMe SSD 1d49 403a Thinksystem AIC CM5 NVMe SSD 0113 BG3 NVMe SSD Controller @@ -14223,6 +14443,7 @@ 1028 0188 Inspiron 6000 laptop 103c 30c0 Compaq 6710b 103c 30c1 Compaq 6910p + 1043 1017 X58LE 1043 1237 A6J-Q008 1043 1967 V6800V 1043 1987 A4K and Z81K notebooks, possibly others ( mid-2005 machines ) @@ -14267,6 +14488,7 @@ 103c 30b7 Presario V6133CL 103c 30cc Pavilion dv6700 103c 30cf Pavilion dv95xx/96xx/97xx/98xx series + 1043 1017 X58LE 1043 1237 A6J-Q008 1043 1967 V6800V 104d 9035 VAIO VGN-FW11ZRU @@ -14287,6 +14509,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30cf Pavilion dv9668eg Laptop + 1043 1017 X58LE 1043 1237 A6J-Q008 1043 1967 V6800V 10f7 8338 Panasonic CF-Y5 laptop @@ -14318,6 +14541,7 @@ 103c 1521 HP EliteBook 8540w 103c 30b7 Presario V6133CL 103c 30cf Pavilion dv9500/9600/9700 series + 1043 1017 X58LE 1183 0843 Alienware Aurora m9700 0852 xD-Picture Card Controller 1025 0121 Aspire 5920G @@ -14660,6 +14884,8 @@ 4380 88E8057 PCI-E Gigabit Ethernet Controller # AVB = "Audio Video Bridging" 4381 Yukon Optima 88E8059 [PCIe Gigabit Ethernet Controller with AVB] + 1259 2803 AT-2814FX + 1259 2804 AT-2874xx 4611 GT-64115 System Controller 4620 GT-64120/64120A/64121A System Controller 4801 GT-48001 @@ -15029,7 +15255,7 @@ 11fb Datel Inc 11fc Silicon Magic 11fd High Street Consultants -11fe Comtrol Corporation +11fe Pepperl+Fuchs Comtrol, Inc. 0001 RocketPort PCI 32-port w/external I/F 0002 RocketPort PCI 8-port w/external I/F 0003 RocketPort PCI 16-port w/external I/F @@ -15272,7 +15498,7 @@ 000e PM/PPC 1224 Interactive Images 1225 Power I/O, Inc. -1227 Tech-Source +1227 EIZO Rugged Solutions 0006 Raptor GFX 8P 0023 Raptor GFX [1100T] 0045 Raptor 4000-L [Linux version] @@ -15861,7 +16087,7 @@ 12b4 FutureTel Inc 12b5 Granite Systems Inc. 12b6 Natural Microsystems -12b7 Cognex Modular Vision Systems Div. - Acumen Inc. +12b7 Cognex Corporation 12b8 Korg # Nee US Robotics 12b9 3Com Corp, Modem Division @@ -15998,6 +16224,7 @@ 12d8 Pericom Semiconductor 01a7 7C21P100 2-port PCI-X to PCI-X Bridge 2304 PI7C9X2G304 EL/SL PCIe2 3-Port/4-Lane Packet Switch + 2404 PI7C9X2G404 EL/SL PCIe2 4-Port/4-Lane Packet Switch 2608 PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch 400a PI7C9X442SL PCI Express Bridge Port 400e PI7C9X442SL USB OHCI Controller @@ -17889,6 +18116,7 @@ 1028 1ff8 Express Flash PM1725b 3.2TB AIC 1028 1ff9 Express Flash PM1725b 6.4TB AIC 1028 1ffa Express Flash PM1725b 12.8TB AIC + a824 NVMe SSD Controller PM173X 144e OLITEC 144f Askey Computer Corp. 1450 Octave Communications Ind. @@ -18338,6 +18566,9 @@ 10cf 1279 LifeBook E8010D 165f NetXtreme BCM5720 2-port Gigabit Ethernet PCIe 1028 04f7 PowerEdge R320 server + 1028 08fd PowerEdge R6515/R7515 LOM + 1028 08ff PowerEdge Rx5xx LOM Board + 1028 0900 PowerEdge C6525 LOM 103c 1786 NC332T Adapter 103c 193d NC332i Adapter 103c 2133 NC332i Adapter @@ -18363,6 +18594,7 @@ 1028 0179 Optiplex GX280 1028 0182 Latitude D610 1028 0187 Precision M70 + 1028 01a3 Latitude X1 1028 01a8 Precision 380 1028 01ad OptiPlex GX620 103c 3006 DC7100 SFF(DX878AV) @@ -18627,6 +18859,11 @@ 1028 0209 XPS M1330 103c 30c0 Compaq 6710b 17aa 3a23 IdeaPad S10e + 1750 BCM57508 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet + 1751 BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet + 1752 BCM57502 NetXtreme-E 10Gb/25Gb/40Gb/50Gb Ethernet + 1806 BCM5750X NetXtreme-E Ethernet Virtual Function + 1807 BCM5750X NetXtreme-E RDMA Virtual Function 3352 BCM3352 3360 BCM3360 4210 BCM4210 iLine10 HomePNA 2.0 @@ -18811,6 +19048,7 @@ 43bc BCM43602 802.11ac Wireless LAN SoC 43d3 BCM43567 802.11ac Wireless Network Adapter 43d9 BCM43570 802.11ac Wireless Network Adapter + 43dc BCM4355 802.11ac Wireless LAN SoC 43df BCM4354 802.11ac Wireless LAN SoC 43e9 BCM4358 802.11ac Wireless LAN SoC 43ec BCM4356 802.11ac Wireless Network Adapter @@ -18827,7 +19065,9 @@ 4412 BCM4412 10/100BaseT 4430 BCM44xx CardBus iLine32 HomePNA 2.0 4432 BCM4432 CardBus 10/100BaseT - 4464 BCM4464 802.11ac Wireless Network Adapter + 4464 BCM4364 802.11ac Wireless Network Adapter +# brcmfmac reports it as BCM4377/4 but macOS drivers call it BCM4377b + 4488 BCM4377b Wireless Network Adapter 4610 BCM4610 Sentry5 PCI to SB Bridge 4611 BCM4610 Sentry5 iLine32 HomePNA 1.0 4612 BCM4610 Sentry5 V.90 56k Modem @@ -18874,6 +19114,7 @@ 5841 BCM5841 Crypto Accelerator 5850 BCM5850 Crypto Accelerator 5e87 Valkyrie offload engine + 5e88 Viper Offload Engine 8602 BCM7400/BCM7405 Serial ATA Controller 9026 CN99xx [ThunderX2] Integrated USB 3.0 xHCI Host Controller 9027 CN99xx [ThunderX2] Integrated AHCI/SATA 3 Host Controller @@ -19192,6 +19433,7 @@ 0070 2259 WinTV HVR-1250 0070 6a18 WinTV-quadHD 0070 c108 WinTV-HVR-4400-HD model 1278 + 1461 3100 CE310B SD PCIe Video Capture Card 5654 2389 GoTView X5 DVD Hybrid PCI-E 5654 2390 GoTView X5 3D HYBRID PCI-E 14f2 MOBILITY Electronics @@ -19572,15 +19814,23 @@ 0213 MT2892 Family [ConnectX-6 Dx Secure Flash Recovery] 0214 MT42822 Family [BlueField-2 SoC Flash Recovery] 0215 MT42822 Family [BlueField-2 Secure Flash Recovery] + 0216 MT2894 Family [ConnectX-6 Lx Flash Recovery] + 0217 MT2894 Family [ConnectX-6 Lx Secure Flash Recovery] 024e MT53100 [Spectrum-2, Flash recovery mode] 024f MT53100 [Spectrum-2, Secure Flash recovery mode] 0250 Spectrum-3, Flash recovery mode 0251 Spectrum-3, Secure Flash recovery mode 0252 Amos chiplet + 0254 Spectrum-4, Flash recovery mode + 0255 Spectrum-4, Secure Flash recovery mode + 0256 Ofek chiplet + 0257 Quantum-2 in Flash Recovery Mode 0262 MT27710 [ConnectX-4 Lx Programmable] EN 0263 MT27710 [ConnectX-4 Lx Programmable Virtual Function] EN 0264 Innova-2 Flex Burn image 0281 NPS-600 Flash Recovery + 0538 MT2910 Family [ConnectX-7 Flash Recovery] + 0539 MT2910 Family [ConnectX-7 Secure Flash Recovery] 1002 MT25400 Family [ConnectX-2 Virtual Function] 1003 MT27500 Family [ConnectX-3] 1014 04b5 PCIe3 40GbE RoCE Converged Host Bus Adapter for Power @@ -19635,6 +19885,7 @@ 15b3 0003 Mellanox Technologies ConnectX-4 Stand-up single-port 40GbE MCX413A-BCAT 15b3 0005 Mellanox Technologies ConnectX-4 Stand-up single-port 40GbE MCX415A-BCAT 15b3 0006 MCX416A-BCAT, ConnectX-4 EN, 40/56GbE 2P, PCIe3.0 x16 + 15b3 0007 ConnectX-4 EN network interface card, 40/56GbE dual-port QSFP28, PCIe3.0 x16, tall bracket 15b3 0008 ConnectX-4 Stand-up dual-port 100GbE MCX416A-CCAT 15b3 0033 ConnectX-4 VPI IB EDR/100 GbE Single Port QSFP28 Adapter 15b3 0034 ConnectX-4 VPI IB EDR/100 GbE Dual Port QSFP28 Adapter @@ -19662,9 +19913,9 @@ 101c MT28908 Family [ConnectX-6 Virtual Function] 101d MT2892 Family [ConnectX-6 Dx] 101e ConnectX Family mlx5Gen Virtual Function - 101f MT28851 + 101f MT2894 Family [ConnectX-6 Lx] 1020 MT28860 - 1021 MT28861 + 1021 MT2910 Family [ConnectX-7] 1974 MT28800 Family [ConnectX-5 PCIe Bridge] 1975 MT416842 Family [BlueField SoC PCIe Bridge] 1976 MT28908 Family [ConnectX-6 PCIe Bridge] @@ -19672,6 +19923,7 @@ 1978 MT42822 Family [BlueField-2 SoC PCIe Bridge] 4117 MT27712A0-FDCF-AE 1bd4 0039 SN10XMP2P25 + 1bd4 003a 10G SFP28 SP EO251FM9 Adapter 1bd4 004d SN10XMP2P25,YZPC-01191-101 5274 MT21108 InfiniBridge 5a44 MT23108 InfiniHost @@ -19736,7 +19988,9 @@ cf08 Switch-IB2 cf6c MT53100 [Spectrum-2] cf70 Spectrum-3 + cf80 Spectrum-4 d2f0 Quantum HDR (200Gbps) switch + d2f2 Quantum-2 NDR (400Gbps) switch 15b4 CCI/TRIAD 15b5 Cimetrics Inc 15b6 Texas Memory Systems Inc @@ -20246,6 +20500,7 @@ 1a32 0303 EM303 802.11bgn Wireless Mini PCIe Card [AR9281] 1a32 0306 EM306 802.11bgn Wireless Half-size Mini PCIe Card [AR9283] 1a3b 1067 AW-NE771 802.11bgn Wireless Mini PCIe Card [AR9281] + 1a3b 1071 AW-NE772 802.11abgn Wireless Mini PCIe Card [AR9280] 1a3b 1081 AW-NE773 802.11abgn Wireless Half-size Mini PCIe Card [AR9280] 002b AR9285 Wireless Network Adapter (PCI-Express) 1028 0204 Wireless 1502 802.11bgn Half-size Mini PCIe Card @@ -20330,7 +20585,7 @@ 16b8 Sonnet Technologies, Inc. 16be Creatix Polymedia GmbH 16c3 Synopsys, Inc. - abcd DWC_usb3 + abcd DWC_usb3 / PCIe bridge abce DWC_usb3 abcf DWC_usb31 edda EPMockUp @@ -20770,6 +21025,7 @@ 17d3 1882 ARC-1882 8/12/16/24 Port PCIe 3.0 to SAS/SATA 6Gb RAID Controller 17d3 1883 ARC-1883 8/12/16/24 Port PCIe 3.0 to SAS/SATA 12Gb RAID Controller 1884 ARC-1884 series PCIe 3.0 to SAS/SATA 12/6Gb RAID Controller + 188a ARC-1886 series PCIe 4.0 to NVMe/SAS/SATA 16/12/6Gb RAID Controller # nee Neterion Inc., previously S2io Inc. 17d5 Exar Corp. 5731 Xframe 10-Gigabit Ethernet PCI-X @@ -20998,6 +21254,10 @@ # HT1000 uses 3 IDs 1166:024a (Native SATA Mode), 1166:024b (PATA/IDE Mode), 182f:000b (RAID Mode) depends on SATA BIOS setting 000b BCM5785 [HT1000] SATA (RAID Mode) 1830 Credence Systems Corporation + 8000 CPIn + 8001 CPId + 8002 CPIx + 8003 CPIq 183b MikroM GmbH 08a7 MVC100 DVI 08a8 MVC101 SDI @@ -21524,7 +21784,7 @@ 1026 AR8121/AR8113/AR8114 Gigabit or Fast Ethernet 1043 8304 P5KPL-CM Motherboard 1048 Attansic L1 Gigabit Ethernet - 1043 8226 P5KPL-VM Motherboard + 1043 8226 P5B-MX/WiFi-AP, P5KPL-VM Motherboard 1062 AR8132 Fast Ethernet 1063 AR8131 Gigabit Ethernet 1458 e000 GA-G31M-ES2L Motherboard @@ -21599,6 +21859,7 @@ 1987 Phison Electronics Corporation 5007 E7 NVMe Controller 5012 E12 NVMe Controller + 5016 E16 PCIe4 NVMe Controller 1989 Montilio Inc. 0001 RapidFile Bridge 8001 RapidFile @@ -21681,15 +21942,35 @@ 19e5 3034 NVMe SSD ES3600C V3 1600GB HHHL AIC 19e5 3036 NVMe SSD ES3600C V3 3200GB HHHL AIC 0200 Hi1822 Family (2*100GE) + 19e5 d139 Hi1822 SP572 (2*100GE) 0202 Hi1822 Family (2*32G FC) + 19e5 d302 Hi1822 SP521 (2*32G FC) + 19e5 d304 Hi1822 SP526 (2*32G FC) 0203 Hi1822 Family (2*16G FC) + 19e5 d301 Hi1822 SP520 (2*16G FC) + 19e5 d305 Hi1822 SP525 (2*16G FC) 0205 Hi1822 Family (2*100GE) + 19e5 df27 Hi1822 MZ731 MEZZ (2*100GE) + 0206 Hi1822 Family (2*25GE) + 19e5 d138 Hi1822 SP582 (2*25GE) 0210 Hi1822 Family (4*25GE) + 19e5 df2e Hi1822 MZ532 MEZZ (4*25GE) + 0211 Hi1822 Family (4*25GE) + 19e5 d12f Hi1822 SP571 (4*25GE) + 19e5 d137 Hi1822 SP581 (4*25GE) + 19e5 d142 Hi1822 SP583 (4*25GE) 0212 Hi1822 Family (2*8G FC) + 19e5 d303 Hi1822 SP522 (2*8G FC) + 19e5 d306 Hi1822 SP523 (2*8G FC) 1710 iBMA Virtual Network Adapter 1711 Hi1710 [iBMC Intelligent Management system chip w/VGA support] 1822 Hi1822 Family (4*25GE) + 19e5 d129 Hi1822 SP570 (4*25GE) + 19e5 d136 Hi1822 SP580 (4*25GE) + 19e5 d141 Hi1822 SP583 (4*25GE) 371e Hi1822 Family Virtual Bridge + 375e Hi1822 Family Virtual Function + 379e Hi1822 Family Virtual Function a120 HiSilicon PCIe Root Port with Gen4 a121 HiSilicon PCI-PCI Bridge a122 HiSilicon Embedded DMA Engine @@ -21752,6 +22033,7 @@ 1a29 Fortinet, Inc. 4338 CP8 Content Processor ASIC 4e36 NP6 Network Processor + 4e37 NP7 Network Processor 1a2b Ascom AG 0000 GESP v1.2 0001 GESP v1.3 @@ -21845,6 +22127,8 @@ 4005 Accelerated Virtual Video Adapter 4006 Memory Ballooning Controller 1ab9 Espia Srl +1ac1 Global Unichip Corp. + 089a Coral Edge TPU 1ac8 Aeroflex Gaisler 1acc Point of View BV 1ad7 Spectracom Corporation @@ -21874,6 +22158,8 @@ 0310 Wil6200 802.11ad Wireless Network Adapter 1aea Alcor Micro 6601 AU6601 PCI-E Flash card reader controller + 6621 AU6621 PCI-E Flash card reader controller + 6625 AU6625 PCI-E Flash card reader controller 1aec Wolfson Microelectronics # nee Fusion-io 1aed SanDisk @@ -22051,6 +22337,7 @@ 1b6f Etron Technology, Inc. 7023 EJ168 USB 3.0 Host Controller 7052 EJ188/EJ198 USB 3.0 Host Controller + 1849 7052 QC5000-ITX/PH 1b73 Fresco Logic 1000 FL1000G USB 3.0 Host Controller 1d5c 1000 Anker USB 3.0 Express Card @@ -22177,25 +22464,34 @@ 5001 25G-PCIE3-8B-2S Security Intelligent Adapter 1c1c Symphony 0001 82C101 +1c1f SoftLab-NSK 1c28 Lite-On IT Corp. / Plextor 0122 M6e PCI Express SSD [Marvell 88SS9183] # previously Fiberblaze 1c2c Silicom Denmark 000a Capture 000f SmartNIC - 00a0 FBC4G Capture 4x1Gb - 00a1 FBC4XG Capture 4x10Gb - 00a2 FBC8XG Capture 8x10Gb - 00a3 FBC2XG Capture 2x10Gb - 00a4 FBC4XGG3 Capture 4x10Gb - 00a5 FBC2XLG Capture 2x40Gb + 00a0 FBC4G Capture 4x1Gb [Herculaneum] + 00a1 FBC4XG Capture 4x10Gb [Ancona] + 00a2 FBC8XG Capture 8x10Gb [Livorno] + 00a3 FBC2XG Capture 2x10Gb [Genoa] + 00a4 FBC4XGG3 Capture 4x10Gb [Livigno] + 00a5 FBC2XLG Capture 2x40Gb [Livorno] 00a6 FBC1CG Capture 1x100Gb - 00a9 FBC2XGHH Capture 2x10Gb + 00a9 FBC2XGHH Capture 2x10Gb [Latina] 00ad FBC2CGG3HL Capture 2x100Gb [Padua] 00af Capture slave device 00e0 PacketMover 2x100Gb [Savona] 00e1 PacketMover 2x100Gb [Tivoli] - a001 FBC2CGG3 Capture 2x100Gb [Mango] + 00e3 PacketMover 2x10Gb [Tivoli] + 00e5 PacketMover 2x10Gb [Corfu] + a000 FBC2CGG3 Capture 2x40Gb [Mango_02] + a001 FBC2CGG3 Capture 2x100Gb [Mango_02] + a003 FBC2CGG3 Capture 16x10Gb [Mango] + a007 FBC2CGG3 Capture 2x40Gb [Mango] + a008 FBC2CGG3 Capture 2x25Gb [Mango] + a009 FBC2CGG3 Capture 16x10Gb [Mango] + a00a FBC2CGG3 Capture 8x10Gb [Mango] a00e FB2CG Capture 2x100Gb [Savona] a00f FB2CG Capture 2x40Gb [Savona] a011 FB2CG Capture 2x25Gb [Savona] @@ -22223,9 +22519,17 @@ 1c5c SK hynix 1283 PC300 NVMe Solid State Drive 256GB 1284 PC300 NVMe Solid State Drive 512GB + 1285 PC300 NVMe Solid State Drive 1TB 1504 SC300 512GB M.2 2280 SATA Solid State Drive 1c5f Beijing Memblaze Technology Co. Ltd. + 000d PBlaze5 520/526 AIC + 003d PBlaze5 920/926 AIC + 010d PBlaze5 520/526 U.2 + 013d PBlaze5 920/926 U.2 0540 PBlaze4 NVMe SSD + 0550 PBlaze5 700/900 + 0555 PBlaze5 510/516 + 0557 PBlaze5 910/916 # http://www.nicevt.ru/ (in Russian) 1c63 Science and Research Centre of Computer Technology (JSC "NICEVT") # http://www.radiotec.ru/catalog.php?cat=jr8&art=14109 @@ -22239,6 +22543,12 @@ 1c8c Mobiveil, Inc. 1cb0 Shannon Systems d000 Venice NVMe SSD + 1cb0 2f10 Venice-E Series U.2 SSD + 1cb0 2f11 Venice Series U.2 SSD + 1cb0 2f12 Venice-X Series U.2 SSD + 1cb0 af10 Venice-E Series AIC SSD + 1cb0 af11 Venice Series AIC SSD + 1cb0 af12 Venice-X Series AIC SSD 1cb1 Collion UG & Co.KG 1cb5 Focusrite Audio Engineering Ltd 0002 Clarett @@ -22260,6 +22570,8 @@ 0303 Simulyzer-RT CompactPCI Serial PSI5-SIM-1 card 0304 Simulyzer-RT CompactPCI Serial PWR-ANA-1 card 0305 Simulyzer-RT CompactPCI Serial CAN-1 card +# supports 8x CAN (-FD) interfaces + 0306 Simulyzer-RT CompactPCI Serial CAN-2 card (CAN-FD) 1cd7 Nanjing Magewell Electronics Co., Ltd. 0010 Pro Capture Endpoint 0014 PRO CAPTURE AIO 4K PLUS @@ -22309,6 +22621,7 @@ 0722 ZX-200 PCIE P2C bridge 1000 ZX-D Standard Host Bridge 1001 ZX-D/ZX-E Miscellaneous Bus + 1003 ZX-E Standard Host Bridge 3001 ZX-100 Standard Host Bridge 300a ZX-100 Miscellaneous Bus 3038 ZX-100/ZX-200/ZX-E Standard Universal PCI to USB Host Controller @@ -22325,6 +22638,7 @@ 345b ZX-100/ZX-D/ZX-E Miscellaneous Bus 3a02 ZX-100 C-320 GPU 3a03 ZX-D C-860 GPU + 3a04 ZX-E C-960 GPU 9002 ZX-100/ZX-200 EIDE Controller 9003 ZX-100/ZX-E EIDE Controller 9045 ZX-100/ZX-D/ZX-E RAID Accelerator 0 @@ -22335,6 +22649,7 @@ 9101 ZX-200 Traffic Controller 9141 ZX-100 High Definition Audio Controller 9142 ZX-D High Definition Audio Controller + 9144 ZX-E High Definition Audio Controller 9180 ZX-200 Networking Gigabit Ethernet Adapter 9202 ZX-100 USB eXtensible Host Controller 9203 ZX-200 USB eXtensible Host Controller @@ -22402,6 +22717,10 @@ 1d6c 2001 DPDK-Aware Virtual Function [Arkville VF] 100f AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Versal] 1010 AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Agilex] + 1011 AR-MAN-U50 [Manitou Class Accelerator for U50] + 1012 AR-MAN-U200 [Manitou Class Accelerator for U200] + 1013 AR-MAN-U250 [Manitou Class Accelerator for U250] + 1014 AR-MAN-U280 [Manitou Class Accelerator for U280] 4200 A5PL-E1-10GETI [10 GbE Ethernet Traffic Instrument] 1d72 Xiaomi 1d78 DERA @@ -22455,9 +22774,40 @@ 1da2 Sapphire Technology Limited 1da3 Habana Labs Ltd. 0001 HL-1000 AI Inference Accelerator [Goya] +# PCIe accelerator card for Deep Learning training tasks + 1000 HL-2000 AI Training Accelerator [Gaudi] 1dbb NGD Systems, Inc. 1dbf Guizhou Huaxintong Semiconductor Technology Co., Ltd 0401 StarDragon4800 PCI Express Root Port +1dc5 FADU Inc. +1dcd Liqid Inc. +1dd8 Pensando Systems Inc + 1000 DSC Capri Upstream Port + 1dd8 4000 Naples 100Gb 2-port QSFP28 x16 8GB + 1dd8 4001 Naples 100Gb 2-port QSFP28 x16 4GB + 1dd8 4002 Naples 25Gb 2-port SFP28 x8 4GB + 1001 DSC Virtual Downstream Port + 1dd8 4000 Naples 100Gb 2-port QSFP28 x16 8GB + 1dd8 4001 Naples 100Gb 2-port QSFP28 x16 4GB + 1dd8 4002 Naples 25Gb 2-port SFP28 x8 4GB + 1002 DSC Ethernet Controller + 1dd8 4000 Naples 100Gb 2-port QSFP28 x16 8GB + 1dd8 4001 Naples 100Gb 2-port QSFP28 x16 4GB + 1dd8 4002 Naples 25Gb 2-port SFP28 x8 4GB + 1003 DSC Ethernet Controller VF + 1dd8 4000 Naples 100Gb 2-port QSFP28 x16 8GB + 1dd8 4001 Naples 100Gb 2-port QSFP28 x16 4GB + 1dd8 4002 Naples 25Gb 2-port SFP28 x8 4GB + 1004 DSC Management Controller + 1dd8 4000 Naples 100Gb 2-port QSFP28 x16 8GB + 1dd8 4001 Naples 100Gb 2-port QSFP28 x16 4GB + 1dd8 4002 Naples 25Gb 2-port SFP28 x8 4GB + 1007 DSC Storage Accelerator + 1dd8 4000 Naples 100Gb 2-port QSFP28 x16 8GB + 1dd8 4001 Naples 100Gb 2-port QSFP28 x16 4GB + 1dd8 4002 Naples 25Gb 2-port SFP28 x8 4GB +1de0 Groq + 0000 Q100 Tensor Streaming Processor 1de1 Tekram Technology Co.,Ltd. 0391 TRM-S1040 [DC-315 / DC-395 series] 2020 DC-390 @@ -22488,6 +22838,7 @@ 1df3 0001 ENA2080F 1df3 0002 ENA2080FS 1df3 0003 ENA2100F + 1df3 0004 ENA2040F 0204 ACE-NIC-NID Programmable Network Accelerator 1df3 0001 ENA1020Z 1df3 0002 ENA1020ZS @@ -22510,7 +22861,8 @@ # JungleCat VU35P Module 1635 JCM35 1e26 Fujitsu Client Computing Limited -1e38 Thinci, Inc +# nee Thinci, Inc +1e38 Blaize, Inc 1e3d Burlywood, Inc 1e49 Yangtze Memory Technologies Co.,Ltd 1e4c GSI Technology @@ -22518,10 +22870,14 @@ 0010 Gemini [ Lida ] 1e4c 0120 SE120 1e57 Beijing Panyi Technology Co., Ltd - 0001 PY8800 - 0100 PY8800 + 0100 The device has already been deleted. 0000 0100 PY8800 64GB Accelerator 1e6b Axiado Corp. +1e89 ID Quantique SA + 0002 Quantis-PCIe-40M + 0003 Quantis-PCIe-240M +# aka SED Systems +1e94 Calian SED # nee Tumsan Oy 1fc0 Ascom (Finland) Oy 0300 E2200 Dual E1/Rawpipe Card @@ -23406,6 +23762,7 @@ 1043 108d VivoBook X202EV 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A + 10cf 16bf LIFEBOOK E752 0155 Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port 8086 2010 Server Board S1200BTS 0156 3rd Gen Core processor Graphics Controller @@ -23425,10 +23782,19 @@ 0166 3rd Gen Core processor Graphics Controller 1043 1517 Zenbook Prime UX31A 1043 2103 N56VZ + 10cf 16c1 LIFEBOOK E752 016a Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller 1043 844d P8B WS Motherboard 0172 Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller 0176 3rd Gen Core processor Graphics Controller + 02a4 Comet Lake SPI (flash) Controller + 02a6 Comet Lake North Peak + 02d3 Comet Lake SATA AHCI Controller + 02e0 Comet Lake Management Engine Interface + 02e8 Serial IO I2C Host Controller + 02f0 Wireless-AC 9462 + 02f9 Comet Lake Thermal Subsytem + 02fc Comet Lake Integrated Sensor Solution 0309 80303 I/O Processor PCI-to-PCI Bridge 030d 80312 I/O Companion Chip PCI-to-PCI Bridge 0326 6700/6702PXH I/OxAPIC Interrupt Controller A @@ -24457,6 +24823,7 @@ 104e Ethernet Controller X710 for 10 Gigabit SFP+ 104f Ethernet Controller X710 for 10 Gigabit backplane 1050 82562EZ 10/100 Ethernet Controller + 1014 0287 ThinkCentre S50 1028 019d Dimension 3000 1462 728c 865PE Neo2 (MS-6728) 1462 758c MS-6758 (875P Neo) @@ -25016,6 +25383,7 @@ 8086 357a Server Board S1200BTS 1503 82579V Gigabit Network Connection 1043 849c P8P67 Deluxe Motherboard + 10cf 161c LIFEBOOK E752 1507 Ethernet Express Module X520-P2 1508 82598EB Gigabit BX Network Connection 1509 82580 Gigabit Network Connection @@ -25090,6 +25458,7 @@ 8086 00a1 Ethernet Server Adapter I350-T4 8086 00a2 Ethernet Server Adapter I350-T2 8086 00a3 Ethernet Network Adapter I350-T4 for OCP NIC 3.0 + 8086 00aa Ethernet Network Adapter I350-T4 for OCP NIC 3.0 8086 5001 Ethernet Server Adapter I350-T4 8086 5002 Ethernet Server Adapter I350-T2 8086 5003 Ethernet 1G 4P I350-t OCP @@ -25149,6 +25518,7 @@ 1531 I210 Gigabit Unprogrammed 1533 I210 Gigabit Network Connection 103c 0003 Ethernet I210-T1 GbE NIC + 1059 0180 RD10019 1GbE interface 1093 7706 Compact Vision System Ethernet Adapter 10a9 802c UV300 BaseIO single-port GbE 10a9 802d UV3000 BaseIO GbE Network @@ -25211,6 +25581,7 @@ 18d4 0c08 X550 10Gb 2-port RJ45 OCP Mezz Card MOP81-I-10GT2 193d 1008 560T-B 193d 1009 560T-L + 193d 1011 UN-NIC-ETH563T-sL-2P 8086 0001 Ethernet Converged Network Adapter X550-T2 8086 001a Ethernet Converged Network Adapter X550-T2 8086 001b Ethernet Server Adapter X550-T2 for OCP @@ -25342,6 +25713,22 @@ 1137 0000 Ethernet Network Adapter XXV710 1137 0225 Ethernet Network Adapter XXV710 1137 02b4 Ethernet Network Adapter XXV710 OCP 2.0 +# UEFI PXE Disabled + 1374 0230 Single Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G1I71) +# With UEFI PXE Enabled + 1374 0231 Single Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G1I71EU) +# UEFI PXE Disabled + 1374 0234 Dual Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G2I71) +# With UEFI PXE Enabled + 1374 0235 Dual Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G2I71EU) +# PCIe x8 Bifurcated as x4x4, UEFI PXE Disabled, low profile + 1374 0238 Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G4I71L) +# PCIe x8 Bifurcated as x4x4, UEFI PXE Enabled, low profile + 1374 0239 Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G4I71LEU) +# PCIe x16 Bifurcated as x8x8, UEFI PXE Disabled, low profile + 1374 023a Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE31625G4I71L) +# PCIe x16 Bifurcated as x8x8, UEFI PXE Enabled, low profile + 1374 023b Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE31625G4I71LEU) 1590 0000 Ethernet Network Adapter XXV710-2 1590 0253 Ethernet 10/25/Gb 2-port 661SFP28 Adapter 8086 0000 Ethernet Network Adapter XXV710 @@ -25358,7 +25745,18 @@ 8086 4001 Ethernet Network Adapter XXV710-2 1591 Ethernet Controller E810-C for backplane 1592 Ethernet Controller E810-C for QSFP + 8086 0002 Ethernet Network Adapter E810-C-Q2 + 8086 0004 Ethernet Network Adapter E810-C-Q2 + 8086 0005 Ethernet Network Adapter E810-C-Q1 for OCP3.0 + 8086 0006 Ethernet Network Adapter E810-C-Q2 for OCP3.0 + 8086 0009 Ethernet Network Adapter E810-C-Q1 1593 Ethernet Controller E810-C for SFP + 8086 0002 Ethernet Network Adapter E810-L-2 + 8086 0005 Ethernet Network Adapter E810-XXV-4 + 8086 0006 Ethernet Network Adapter E810-XXV-4 + 8086 0007 Ethernet Network Adapter E810-XXV-4 + 8086 0008 Ethernet Network Adapter E810-XXV-2 + 8086 0009 Ethernet Network Adapter E810-XXV-2 for OCP 2.0 15a0 Ethernet Connection (2) I218-LM 15a1 Ethernet Connection (2) I218-V 15a2 Ethernet Connection (3) I218-LM @@ -25435,8 +25833,17 @@ 15ec JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018] 15ef JHL7540 Thunderbolt 3 Bridge [Titan Ridge DD 2018] 15f0 JHL7540 Thunderbolt 3 USB Controller [Titan Ridge DD 2018] + 15f4 Ethernet Connection (15) I219-LM + 15f5 Ethernet Connection (15) I219-V 15f6 I210 Gigabit Ethernet Connection + 15f9 Ethernet Connection (14) I219-LM + 15fa Ethernet Connection (14) I219-V + 15fb Ethernet Connection (13) I219-LM + 15fc Ethernet Connection (13) I219-V 15ff Ethernet Controller X710 for 10GBASE-T + 1137 0000 X710TLG GbE RJ45 PCIe NIC + 1137 02c1 X710T2LG 2x10 GbE RJ45 PCIe NIC + 1137 02c2 X710T4LG 4x10 GbE RJ45 PCIe NIC 8086 0000 Ethernet Network Adapter X710-TL 8086 0001 Ethernet Network Adapter X710-T4L 8086 0002 Ethernet Network Adapter X710-T4L @@ -25446,6 +25853,11 @@ 8086 0006 Ethernet 10G 4P X710-T4L-t Adapter 8086 0007 Ethernet 10G 2P X710-T2L-t OCP 8086 0008 Ethernet 10G 4P X710-T4L-t OCP + 8086 0009 Ethernet Network Adapter X710-T4L for OCP 3.0 + 8086 000a Ethernet Network Adapter X710-T4L for OCP 3.0 + 8086 000b Ethernet Network Adapter X710-T2L for OCP 3.0 + 8086 000c Ethernet Network Adapter X710-T2L for OCP 3.0 + 8086 000f Ethernet Network Adapter X710-T2L for OCP 3.0 1600 Broadwell-U Host Bridge -OPI 1601 Broadwell-U PCI Express x16 Controller 1602 Broadwell-U Integrated Graphics @@ -25493,6 +25905,7 @@ 1903 Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem 1028 06dc Latitude E7470 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv 17aa 225d ThinkPad T480 1904 Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers 1028 06dc Latitude E7470 @@ -25508,6 +25921,7 @@ 190f Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers 1910 Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv 1911 Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model 17aa 2247 ThinkPad T570 17aa 224f ThinkPad X1 Carbon 5th Gen @@ -25521,6 +25935,7 @@ 1919 Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Imaging Unit 191b HD Graphics 530 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv 191d HD Graphics P530 191e HD Graphics 515 191f Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers @@ -25608,6 +26023,10 @@ 19df Atom Processor C3000 Series SMBus controller 19e0 Atom Processor C3000 Series SPI Controller 19e2 Atom Processor C3000 Series QuickAssist Technology + 1a1c Ethernet Connection (17) I219-LM + 1a1d Ethernet Connection (17) I219-V + 1a1e Ethernet Connection (16) I219-LM + 1a1f Ethernet Connection (16) I219-V 1a21 82840 840 [Carmel] Chipset Host Bridge (Hub A) 1a23 82840 840 [Carmel] Chipset AGP Bridge 1a24 82840 840 [Carmel] Chipset PCI Bridge (Hub B) @@ -25858,6 +26277,7 @@ 1043 108d VivoBook X202EV 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A + 10cf 16e2 LIFEBOOK E752 144d c652 NP300E5C series laptop 1e04 7 Series/C210 Series Chipset Family SATA Controller [RAID mode] 1e05 7 Series Chipset SATA Controller [RAID mode] @@ -25872,6 +26292,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1043 84ca P8H77-I Motherboard + 10cf 16e9 LIFEBOOK E752 144d c652 NP300E5C series laptop 1849 1e10 Motherboard 1e12 7 Series/C210 Series Chipset Family PCI Express Root Port 2 @@ -25879,6 +26300,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1e14 7 Series/C210 Series Chipset Family PCI Express Root Port 3 + 10cf 16e9 LIFEBOOK E752 1e16 7 Series/C216 Chipset Family PCI Express Root Port 4 1043 108d VivoBook X202EV 1043 1477 N56VZ @@ -25891,6 +26313,7 @@ 1849 1e1a Motherboard 1e1c 7 Series/C210 Series Chipset Family PCI Express Root Port 7 1e1e 7 Series/C210 Series Chipset Family PCI Express Root Port 8 + 10cf 16e9 LIFEBOOK E752 1849 1e1e Motherboard 1e20 7 Series/C216 Chipset Family High Definition Audio Controller 1028 054b XPS One 2710 @@ -25899,6 +26322,7 @@ 1043 1517 Zenbook Prime UX31A 1043 8415 P8H77-I Motherboard 1043 8445 P8Z77-V LX Motherboard + 10cf 1757 LIFEBOOK E752 144d c652 NP300E5C series laptop 1849 1898 Z77 Extreme4 motherboard 1e22 7 Series/C216 Chipset Family SMBus Controller @@ -25906,6 +26330,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1043 84ca P8 series motherboard + 10cf 16e6 LIFEBOOK E752 144d c652 NP300E5C series laptop 1849 1e22 Motherboard 1e24 7 Series/C210 Series Chipset Family Thermal Management Controller @@ -25916,6 +26341,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1043 84ca P8 series motherboard + 10cf 16e8 LIFEBOOK E752 144d c652 NP300E5C series laptop 1849 1e26 Motherboard 1e2d 7 Series/C216 Chipset Family USB Enhanced Host Controller #2 @@ -25923,6 +26349,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1043 84ca P8 series motherboard + 10cf 16e8 LIFEBOOK E752 144d c652 NP300E5C series laptop 1849 1e2d Motherboard 1e31 7 Series/C210 Series Chipset Family USB xHCI Host Controller @@ -25932,6 +26359,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1043 84ca P8 series motherboard + 10cf 16ee LIFEBOOK E752 17aa 21f3 ThinkPad T430 1849 1e31 Motherboard 1e33 7 Series/C210 Series Chipset Family LAN Controller @@ -25940,6 +26368,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1043 84ca P8 series motherboard + 10cf 16ea LIFEBOOK E752 144d c652 NP300E5C series laptop 1849 1e3a Motherboard 1e3b 7 Series/C210 Series Chipset Family MEI Controller #2 @@ -25975,6 +26404,7 @@ 1e59 HM76 Express Chipset LPC Controller 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A + 10cf 16e0 LIFEBOOK E752 1e5a 7 Series Chipset Family LPC Controller 1e5b UM77 Express Chipset LPC Controller 1e5c 7 Series Chipset Family LPC Controller @@ -26047,6 +26477,7 @@ 2018 Sky Lake-E M2PCI Registers 201a Sky Lake-E Non-Transparent Bridge Registers 201c Sky Lake-E Non-Transparent Bridge Registers + 201d Volume Management Device NVMe RAID Controller 2020 Sky Lake-E DMI3 Registers 15d9 095d X11SPM-TF 2021 Sky Lake-E CBDMA Registers @@ -26102,7 +26533,7 @@ 2241 Larrabee 2250 Xeon Phi coprocessor 5100 series 225c Xeon Phi coprocessor SE10/7120 series - 225d Xeon Phi coprocessor 3120 series + 225d Xeon Phi coprocessor 3120 series 225e Xeon Phi coprocessor 31S1 2262 Xeon Phi coprocessor 7220 2280 Atom/Celeron/Pentium Processor x5-E8000/J3xxx/N3xxx Series SoC Transaction Register @@ -26266,6 +26697,7 @@ 103c 309f Compaq nx9420 Notebook 103c 30a3 Compaq nw8440 103c 30c1 Compaq 6910p + 1043 1017 X58LE 104d 902d VAIO VGN-NR120E 105b 0d7c D270S/D250S Motherboard 1071 8209 Medion MIM 2240 Notebook PC [MD98100] @@ -26342,6 +26774,7 @@ # same ID possibly also on other ASUS boards 1043 8277 P5K PRO Motherboard 1043 844d P8 series motherboard + 1043 8534 ASUS B85-PLUS 1458 5000 Motherboard 1462 7345 MS-7345 Motherboard: Intel 82801I/IR [ICH9/ICH9R] 1462 7418 Wind PC MS-7418 @@ -26639,6 +27072,7 @@ 8086 4c43 Desktop Board D865GLC 8086 524c D865PERL mainboard 24d2 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 + 1014 0287 ThinkCentre S50 1014 02dd eServer xSeries server mainboard 1014 02ed eServer xSeries server mainboard 1028 0168 Precision Workstation 670 Mainboard @@ -26662,6 +27096,7 @@ 8086 4c43 Desktop Board D865GLC 8086 524c D865PERL mainboard 24d3 82801EB/ER (ICH5/ICH5R) SMBus Controller + 1014 0287 ThinkCentre S50 1014 02dd eServer xSeries server mainboard 1014 02ed eServer xSeries server mainboard 1028 0156 Precision 360 @@ -26681,6 +27116,7 @@ 8086 4c43 Desktop Board D865GLC 8086 524c D865PERL mainboard 24d4 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 + 1014 0287 ThinkCentre S50 1014 02dd eServer xSeries server mainboard 1014 02ed eServer xSeries server mainboard 1028 0168 Precision Workstation 670 Mainboard @@ -26706,6 +27142,7 @@ 8086 524c D865PERL mainboard 24d5 82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller 100a 147b Abit IS7-E motherboard + 1014 0287 ThinkCentre S50 1028 0168 Precision Workstation 670 Mainboard 1028 0169 Precision 470 103c 006a NX9500 @@ -26723,6 +27160,7 @@ 24d6 82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller 103c 006a NX9500 24d7 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 + 1014 0287 ThinkCentre S50 1014 02ed xSeries server mainboard 1028 0168 Precision Workstation 670 Mainboard 1028 0169 Precision 470 @@ -26744,6 +27182,7 @@ 8086 4c43 Desktop Board D865GLC 8086 524c D865PERL mainboard 24db 82801EB/ER (ICH5/ICH5R) IDE Controller + 1014 0287 ThinkCentre S50 1014 02dd eServer xSeries server mainboard 1014 02ed eServer xSeries server mainboard 1028 0168 Precision Workstation 670 Mainboard @@ -26769,6 +27208,7 @@ 8086 524c D865PERL mainboard 24dc 82801EB (ICH5) LPC Interface Bridge 24dd 82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller + 1014 0287 ThinkCentre S50 1014 02dd eServer xSeries server mainboard 1014 02ed eServer xSeries server mainboard 1028 0168 Precision Workstation 670 Mainboard @@ -26790,6 +27230,7 @@ 8086 4c43 Desktop Board D865GLC 8086 524c D865PERL mainboard 24de 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 + 1014 0287 ThinkCentre S50 1014 02ed xSeries server mainboard 1028 0168 Precision Workstation 670 Mainboard 1028 0169 Precision 470 @@ -26897,6 +27338,7 @@ 1458 2570 GA-8IPE1000 Pro2 motherboard (865PE) 2571 82865G/PE/P AGP Bridge 2572 82865G Integrated Graphics Controller + 1014 0287 ThinkCentre S50 1028 019d Dimension 3000 103c 12bc D530 sff(dc578av) 1043 80a5 P5P800-MX Mainboard @@ -27426,7 +27868,7 @@ 27b8 82801GB/GR (ICH7 Family) LPC Interface Bridge 1028 01e6 PowerEdge 860 103c 2a8c Compaq 500B Microtower - 1043 8179 P5KPL-VM Motherboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM Motherboard 107b 5048 E4500 1462 7418 Wind PC MS-7418 1775 11cc CC11/CL11 @@ -27454,7 +27896,7 @@ 1028 01df PowerEdge SC440 1028 01e6 PowerEdge 860 103c 2a8c Compaq 500B Microtower - 1043 8179 P5KPL-VM Motherboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM Motherboard 107b 5048 E4500 1462 2310 MSI Hetis 945 1462 7236 945P Neo3-F Rev. 2.2 motherboard @@ -27499,7 +27941,7 @@ 103c 30a3 Compaq nw8440 103c 30d5 530 Laptop 1043 1237 A6J-Q008 - 1043 8179 P5KPL-VM,P5LD2-VM Mainboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard 1043 83ad Eee PC 1015PX 105b 0d7c D270S/D250S Motherboard 1071 8209 Medion MIM 2240 Notebook PC [MD98100] @@ -27524,7 +27966,7 @@ 103c 30a1 NC2400 103c 30a3 Compaq nw8440 1043 1237 A6J-Q008 - 1043 8179 P5KPL-VM,P5LD2-VM Mainboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard 1043 83ad Eee PC 1015PX 105b 0d7c D270S/D250S Motherboard 1071 8209 Medion MIM 2240 Notebook PC [MD98100] @@ -27549,7 +27991,7 @@ 103c 30a1 NC2400 103c 30a3 Compaq nw8440 1043 1237 A6J-Q008 - 1043 8179 P5KPL-VM,P5LD2-VM Mainboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard 1043 83ad Eee PC 1015PX 105b 0d7c D270S/D250S Motherboard 1071 8209 Medion MIM 2240 Notebook PC [MD98100] @@ -27572,7 +28014,7 @@ 103c 30a1 NC2400 103c 30a3 Compaq nw8440 1043 1237 A6J-Q008 - 1043 8179 P5KPL-VM,P5LD2-VM Mainboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard 1043 83ad Eee PC 1015PX 105b 0d7c D270S/D250S Motherboard 1071 8209 Medion MIM 2240 Notebook PC [MD98100] @@ -27597,7 +28039,7 @@ 103c 30a3 Compaq nw8440 103c 30d5 530 Laptop 1043 1237 A6J-Q008 - 1043 8179 P5KPL-VM,P5LD2-VM Mainboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard 1043 83ad Eee PC 1015PX 105b 0d7c D270S/D250S Motherboard 1071 8209 Medion MIM 2240 Notebook PC [MD98100] @@ -27655,6 +28097,7 @@ 1043 1123 A6J-Q008 1043 13c4 G2P 1043 817f P5LD2-VM Mainboard (Realtek ALC 882 codec) + 1043 8249 P5B-MX/WiFi-AP 1043 8290 P5KPL-VM Motherboard 1043 82ea P5KPL-CM Motherboard 1043 8437 Eee PC 1015PX @@ -27685,7 +28128,7 @@ 1028 01e6 PowerEdge 860 103c 2a3b Pavilion A1512X 103c 2a8c Compaq 500B Microtower - 1043 8179 P5KPL-VM Motherboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM Motherboard 105b 0d7c D270S/D250S Motherboard 1071 8209 Medion MIM 2240 Notebook PC [MD98100] 10f7 8338 Panasonic CF-Y5 laptop @@ -27716,7 +28159,7 @@ 103c 30a3 Compaq nw8440 103c 30d5 530 Laptop 1043 1237 A6J-Q008 - 1043 8179 P5KPL-VM Motherboard + 1043 8179 P5B-MX/WiFi-AP, P5KPL-VM Motherboard 107b 5048 E4500 10f7 8338 Panasonic CF-Y5 laptop 1462 7418 Wind PC MS-7418 @@ -27743,6 +28186,7 @@ 103c 30c0 Compaq 6710b 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E 17aa 20a5 ThinkPad R61 @@ -27782,6 +28226,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E 17aa 20a7 ThinkPad T61/R61 @@ -27799,6 +28244,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E @@ -27815,6 +28261,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E @@ -27831,6 +28278,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E @@ -27847,6 +28295,7 @@ 103c 30c0 Compaq 6710b 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E @@ -27862,6 +28311,7 @@ 103c 30c0 Compaq 6710b 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E @@ -27877,6 +28327,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E @@ -27892,6 +28343,7 @@ 103c 30c0 Compaq 6710b 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E @@ -27904,6 +28356,7 @@ 1028 01f3 Inspiron 1420 1028 022f Inspiron 1525 103c 30d9 Presario C700 + 1043 1017 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 9008 Vaio VGN-SZ79SN_C @@ -27915,19 +28368,23 @@ 283f 82801H (ICH8 Family) PCI Express Port 1 1028 01da OptiPlex 745 103c 30c1 Compaq 6910p + 1043 1017 X58LE 104d 902d VAIO VGN-NR120E 17aa 20ad ThinkPad T61/R61 17c0 4083 Medion WIM 2210 Notebook PC [MD96850] 2841 82801H (ICH8 Family) PCI Express Port 2 103c 30c1 Compaq 6910p + 1043 1017 X58LE 104d 902d VAIO VGN-NR120E 17aa 20ad ThinkPad T61/R61 17c0 4083 Medion WIM 2210 Notebook PC [MD96850] 2843 82801H (ICH8 Family) PCI Express Port 3 + 1043 1017 X58LE 104d 902d VAIO VGN-NR120E 17aa 20ad ThinkPad T61/R61 17c0 4083 Medion WIM 2210 Notebook PC [MD96850] 2845 82801H (ICH8 Family) PCI Express Port 4 + 1043 1017 X58LE 17aa 20ad ThinkPad T61/R61 17c0 4083 Medion WIM 2210 Notebook PC [MD96850] 2847 82801H (ICH8 Family) PCI Express Port 5 @@ -27951,6 +28408,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 1043 1339 M51S series + 1043 17f3 X58LE 1043 81ec P5B 104d 9005 Vaio VGN-FZ260E 104d 9008 Vaio VGN-SZ79SN_C @@ -27970,11 +28428,13 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E 17aa 20a6 ThinkPad T61/R61 17c0 4083 Medion WIM 2210 Notebook PC [MD96850] e4bf cc47 CCG-RUMBA + 28c0 Volume Management Device NVMe RAID Controller 2912 82801IH (ICH9DH) LPC Interface Controller 2914 82801IO (ICH9DO) LPC Interface Controller 1028 0211 Optiplex 755 @@ -28222,8 +28682,10 @@ 294c 82566DC-2 Gigabit Network Connection 17aa 302e 82566DM-2 Gigabit Network Connection 2970 82946GZ/PL/GL Memory Controller Hub + 1043 823b P5B-MX/WiFi-AP 2971 82946GZ/PL/GL PCI Express Root Port 2972 82946GZ/GL Integrated Graphics Controller + 1043 823b P5B-MX/WiFi-AP 2973 82946GZ/GL Integrated Graphics Controller 2974 82946GZ/GL HECI Controller 2975 82946GZ/GL HECI Controller @@ -28323,6 +28785,7 @@ 103c 30c1 Compaq 6910p 103c 30cc Pavilion dv6700 103c 30d9 Presario C700 + 1043 1017 X58LE 104d 9005 Vaio VGN-FZ260E 104d 902d VAIO VGN-NR120E 17aa 20b1 ThinkPad T61 @@ -28336,6 +28799,7 @@ 1028 022f Inspiron 1525 103c 30c0 Compaq 6710b 103c 30d9 Presario C700 + 1043 14e2 X58LE 104d 902d VAIO VGN-NR120E 17aa 20b5 GM965 [X3100] on ThinkPad T61/R61 17c0 4082 GM965 on Medion WIM 2210 Notebook PC [MD96850] @@ -28345,6 +28809,7 @@ 1028 022f Inspiron 1525 103c 30c0 Compaq 6710b 103c 30d9 Presario C700 + 1043 14e2 X58LE 104d 902d VAIO VGN-NR120E 17aa 20b5 GM965 [X3100] on ThinkPad T61/R61 17c0 4082 GM965 on Medion WIM 2210 Notebook PC [MD96850] @@ -28898,12 +29363,15 @@ 34bc Ice Lake-LP PCI Express Root Port #5 34c5 Ice Lake-LP Serial IO I2c Controller #4 34c6 Ice Lake-LP Serial IO I2c Controller #5 + 34c8 Smart Sound Technology Audio Controller 34d3 Ice Lake-LP SATA Controller [AHCI mode] + 34e0 Management Engine Interface 34e8 Ice Lake-LP Serial IO I2C Controller #0 34e9 Ice Lake-LP Serial IO I2C Controller #1 34ea Ice Lake-LP Serial IO I2C Controller #2 34eb Ice Lake-LP Serial IO I2C Controller #3 34ed Ice Lake-LP USB 3.1 xHCI Host Controller + 34f0 Killer Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW) 34f8 Ice Lake-LP SD Controller 3500 6311ESB/6321ESB PCI Express Upstream Port 103c 31fe ProLiant DL140 G3 @@ -29123,6 +29591,7 @@ 17aa 4022 Ethernet Connection X722 for 1GbE 17aa 4024 Ethernet Connection X722 for 1GbE 37d2 Ethernet Connection X722 for 10GBASE-T + 1059 0180 RD10019 10GbE interface 1170 37d2 Ethernet Connection X722 for 10GBASE-T 14cd 0030 Ethernet OCP 2x10G RJ45 Phy Card [USI-X557-10GbaseT] 1590 0218 Ethernet 10Gb 2-port 568FLR-MMT Adapter @@ -29384,6 +29853,7 @@ 1028 02da OptiPlex 980 1028 040a Latitude E6410 1028 040b Latitude E6510 + 103c 1521 EliteBook 8540p 144d c06a R730 Laptop 15d9 060d C7SIM-Q Motherboard 17c0 10d2 Medion Akoya E7214 Notebook PC [MD98410] @@ -29508,6 +29978,7 @@ 3e1f 8th Gen Core 4-core Desktop Processor Host Bridge/DRAM Registers [Coffee Lake S] 1458 5000 Z370 AORUS Gaming K3-CF 3e30 8th Gen Core 8-core Desktop Processor Host Bridge/DRAM Registers [Coffee Lake S] + 3e33 8th/9th Gen Core Processor Host Bridge/DRAM Registers [Coffee Lake] 3e34 Coffee Lake HOST and DRAM Controller 3e81 8th Gen Core Processor PCIe Controller (x16) 3e85 8th Gen Core Processor PCIe Controller (x8) @@ -29650,6 +30121,8 @@ 8086 1311 WiMAX/WiFi Link 5150 AGN 8086 1316 WiMAX/WiFi Link 5150 ABG 444e Turbo Memory Controller + 467f Volume Management Device NVMe RAID Controller + 4c3d Volume Management Device NVMe RAID Controller 5001 LE80578 5002 LE80578 Graphics Processor Unit 5009 LE80578 Video Display Controller @@ -29734,6 +30207,7 @@ 5926 Iris Plus Graphics 640 5927 Iris Plus Graphics 650 5a84 Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller + 5a85 HD Graphics 500 5a88 Celeron N3350/Pentium N4200/Atom E3900 Series Imaging Unit 5a98 Celeron N3350/Pentium N4200/Atom E3900 Series Audio Cluster 5a9a Celeron N3350/Pentium N4200/Atom E3900 Series Trusted Execution Engine @@ -30129,6 +30603,7 @@ 8a1f Ice Lake Thunderbolt 3 PCI Express Root Port #1 8a21 Ice Lake Thunderbolt 3 PCI Express Root Port #2 8a23 Ice Lake Thunderbolt 3 PCI Express Root Port #3 + 8a52 Iris Plus Graphics G7 8c00 8 Series/C220 Series Chipset Family 4-port SATA Controller 1 [IDE mode] 8c01 8 Series Chipset Family 4-port SATA Controller 1 [IDE mode] - Mobile 8c02 8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] @@ -30346,6 +30821,8 @@ 9622 Integrated RAID 9641 Integrated RAID 96a1 Integrated RAID + 9a0b Volume Management Device NVMe RAID Controller + 9b41 UHD Graphics 9c00 8 Series SATA Controller 1 [IDE mode] 9c01 8 Series SATA Controller 1 [IDE mode] 9c02 8 Series SATA Controller 1 [AHCI mode] @@ -30555,17 +31032,20 @@ 9da4 Cannon Point-LP SPI Controller 9db0 Cannon Point-LP PCI Express Root Port #9 9db1 Cannon Point-LP PCI Express Root Port #10 + 9db2 Cannon Point-LP PCI Express Root Port #1 9db4 Cannon Point-LP PCI Express Root Port #13 1028 089e Inspiron 5482 9db6 Cannon Point-LP PCI Express Root Port #15 9db8 Cannon Point-LP PCI Express Root Port #1 9dbc Cannon Point-LP PCI Express Root Port #5 + 9dbe Cannon Point-LP PCI Express Root Port #7 9dbf Cannon Point PCI Express Root Port #8 9dc5 Cannon Point-LP Serial IO I2C Host Controller 9dc8 Cannon Point-LP High Definition Audio Controller 1028 089e Inspiron 5482 9dd3 Cannon Point-LP SATA Controller [AHCI Mode] 9de0 Cannon Point-LP MEI Controller #1 + 9de3 Cannon Point-LP Keyboard and Text (KT) Redirection 9de8 Cannon Point-LP Serial IO I2C Controller #0 1028 089e Inspiron 5482 9de9 Cannon Point-LP Serial IO I2C Controller #1 @@ -30599,6 +31079,7 @@ a102 Q170/Q150/B150/H170/H110/Z170/CM236 Chipset SATA Controller [AHCI Mode] a103 HM170/QM170 Chipset SATA Controller [AHCI Mode] 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a105 Sunrise Point-H SATA Controller [RAID mode] a106 Q170/H170/Z170/CM236 Chipset SATA Controller [RAID Mode] a107 HM170/QM170 Chipset SATA Controller [RAID Mode] @@ -30622,9 +31103,11 @@ a120 100 Series/C230 Series Chipset Family P2SB a121 100 Series/C230 Series Chipset Family Power Management Controller 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a122 Sunrise Point-H cAVS a123 100 Series/C230 Series Chipset Family SMBus 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a124 100 Series/C230 Series Chipset Family SPI Controller a125 100 Series/C230 Series Chipset Family Gigabit Ethernet Controller a126 100 Series/C230 Series Chipset Family Trace Hub @@ -30634,13 +31117,16 @@ a12a 100 Series/C230 Series Chipset Family Serial IO GSPI #1 a12f 100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a130 100 Series/C230 Series Chipset Family USB Device Controller (OTG) a131 100 Series/C230 Series Chipset Family Thermal Subsystem 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a133 Sunrise Point-H Northpeak ACPI Function a135 100 Series/C230 Series Chipset Family Integrated Sensor Hub a13a 100 Series/C230 Series Chipset Family MEI Controller #1 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a13b 100 Series/C230 Series Chipset Family MEI Controller #2 a13c 100 Series/C230 Series Chipset Family IDE Redirection a13d 100 Series/C230 Series Chipset Family KT Redirection @@ -30661,6 +31147,7 @@ a14d QM170 Chipset LPC/eSPI Controller a14e HM170 Chipset LPC/eSPI Controller 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a14f Sunrise Point-H LPC Controller a150 CM236 Chipset LPC/eSPI Controller a151 Sunrise Point-H LPC Controller @@ -30680,6 +31167,7 @@ a15f Sunrise Point-H LPC Controller a160 100 Series/C230 Series Chipset Family Serial IO I2C Controller #0 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a161 100 Series/C230 Series Chipset Family Serial IO I2C Controller #1 1028 06e4 XPS 15 9550 a162 100 Series/C230 Series Chipset Family Serial IO I2C Controller #2 @@ -30691,6 +31179,7 @@ a16a 100 Series/C230 Series Chipset Family PCI Express Root Port #20 a170 100 Series/C230 Series Chipset Family HD Audio Controller 1028 06e4 XPS 15 9550 + 103c 825b OMEN-17-w001nv a171 CM238 HD Audio Controller a182 C620 Series Chipset Family SATA Controller [AHCI mode] a186 C620 Series Chipset Family SATA Controller [RAID mode] @@ -30821,6 +31310,7 @@ a30c QM370 Chipset LPC/eSPI Controller a323 Cannon Lake PCH SMBus Controller a324 Cannon Lake PCH SPI Controller + a328 Cannon Lake PCH Serial IO UART Host Controller a32c Cannon Lake PCH PCI Express Root Port #21 a32d Cannon Lake PCH PCI Express Root Port #22 a32e Cannon Lake PCH PCI Express Root Port #23 @@ -30850,6 +31340,7 @@ a353 Cannon Lake Mobile PCH SATA AHCI Controller a360 Cannon Lake PCH HECI Controller a363 Cannon Lake PCH Active Management Technology - SOL + a364 Cannon Lake PCH HECI Controller #2 a368 Cannon Lake PCH Serial IO I2C Controller #0 a369 Cannon Lake PCH Serial IO I2C Controller #1 a36a Cannon Lake PCH Serial IO I2C Controller #2 @@ -30900,6 +31391,23 @@ f1a6 SSD Pro 7600p/760p/E 6100p Series f1a8 SSD 660P Series 8088 Beijing Wangxun Technology Co., Ltd. + 0101 WX1860A2 Gigabit Ethernet Controller + 8088 0201 Dual-Port Ethernet Network Adaptor SF200T + 0102 WX1860A2S Gigabit Ethernet Controller + 8088 0210 Dual-Port Ethernet Network Adaptor SF200T-S + 0103 WX1860A4 Gigabit Ethernet Controller + 8088 0401 Qual-Port Ethernet Network Adaptor SF400T + 8088 0440 Qual-Port Ethernet Network Adaptor SF400-OCP + 0104 WX1860A4S Gigabit Ethernet Controller + 8088 0410 Qual-Port Ethernet Network Adaptor SF400T-S + 0105 WX1860AL2 Gigabit Ethernet Controller + 8088 0202 Dual-Port Ethernet Network Adaptor SF200HT + 0106 WX1860AL2S Gigabit Ethernet Controller + 8088 0220 Dual-Port Ethernet Network Adaptor SF200HT-S + 0107 WX1860AL4 Gigabit Ethernet Controller + 8088 0402 Qual-Port Ethernet Network Adaptor SF400HT + 0108 WX1860AL4S Gigabit Ethernet Controller + 8088 0420 Qual-Port Ethernet Network Adaptor SF400HT-S 1001 Ethernet Controller RP1000 for 10GbE SFP+ 8088 0000 Ethernet Network Adaptor RP1000 for 10GbE SFP+ 2001 Ethernet Controller RP2000 for 10GbE SFP+ @@ -31504,6 +32012,7 @@ bdbd Blackmagic Design a1ff eGPU RX580 c001 TSI Telsys c0a9 Micron/Crucial Technology + 2263 P1 NVMe PCIe SSD c0de Motorola c0fe Motion Engineering, Inc. ca3b Cambrionix Ltd. @@ -31560,6 +32069,10 @@ d161 Digium, Inc. 8010 Wildcard A4B 4-port analog card (PCI-Express) 8013 Wildcard TE236/TE436 quad-span T1/E1/J1 card b410 Wildcard B410 quad-BRI card +d209 Ultimarc + 1500 PAC Drive + 15a2 SpinTrak + 1601 AimTrak d4d4 Dy4 Systems Inc 0601 PCI Mezzanine Card d531 I+ME ACTIA GmbH @@ -31735,14 +32248,38 @@ f1d0 AJA Video c0ff Kona/Xena 2 cafe Kona SD cfee Xena LS/SD-22-DA/SD-DA + dafe Corvid 1 daff KONA LHi + db00 IoExpress db01 Corvid22 + db02 Kona 3G + db03 Corvid 3G + db04 Kona 3G QUAD + db05 Kona LHe+ + db06 IoXT + db07 Kona 3G P2P + db08 Kona 3G QUAD P2P db09 Corvid 24 + db11 T-Tap dcaf Kona HD dfee Xena HD-DA + eb07 Io4K + eb0a Io4K UFC + eb0b Kona 4 + eb0c Kona 4 UFC eb0d Corvid 88 eb0e Corvid 44 - eb1d Kona 5 + eb16 Corvid HEVC + 10cf 1049 Corvid HEVC M31 + eb18 Corvid HB-R + eb1a Kona IP 1SFP + eb1c Kona IP 2SFP + eb1d Io4KPlus + eb1e IoIP + eb1f Kona 5 + eb23 Kona 1 + eb24 Kona HDMI + eb25 Corvid 44 12g efac Xena SD-MM/SD-22-MM facd Xena HD-MM f5f5 F5 Networks, Inc. diff --git a/usr/src/data/hwdata/usb.ids b/usr/src/data/hwdata/usb.ids index 7d136519fb..1e63bb5177 100644 --- a/usr/src/data/hwdata/usb.ids +++ b/usr/src/data/hwdata/usb.ids @@ -9,8 +9,8 @@ # The latest version can be obtained from # http://www.linux-usb.org/usb.ids # -# Version: 2019.08.21 -# Date: 2019-08-21 20:34:05 +# Version: 2020.02.28 +# Date: 2020-02-28 20:34:06 # # Vendors, devices and interfaces. Please keep sorted. @@ -42,6 +42,7 @@ a001 Digitus DA-71114 SATA 0085 Boeye Technology Co., Ltd. 0600 eBook Reader +0102 miniSTREAK 0105 Trust International B.V. 145f NW-3100 802.11b/g 54Mbps Wireless Network Adapter [zd1211] 0127 IBP @@ -75,6 +76,7 @@ 03e7 Intel 2150 Myriad VPU [Movidius Neural Compute Stick] 2485 Movidius MyriadX + f63b Myriad VPU [Movidius Neural Compute Stick] 03e8 EndPoints, Inc. 0004 SE401 Webcam 0008 101 Ethernet [klsi] @@ -171,6 +173,7 @@ 7617 AT76C505AS Wireless Adapter 7800 Mini Album 800c Airspy HF+ + ff01 WootingOne ff02 WootingTwo ff07 Tux Droid fish dongle 03ec Iwatsu America, Inc. @@ -252,6 +255,7 @@ 0601 ScanJet 6300c 0604 DeskJet 840c 0605 ScanJet 2200c + 0610 Z24i Monitor Hub 0611 OfficeJet K60xi 0612 business inkjet 3000 0624 Bluetooth Dongle @@ -274,6 +278,7 @@ 0912 Printing Support 0917 LaserJet 3330 0924 Modular Smartcard Keyboard + 0941 X500 Optical Mouse 094a Optical Mouse [672662-001] 0a01 ScanJet 2400c 0a17 color LaserJet 3700 @@ -699,6 +704,7 @@ c102 PhotoSmart 8000 series c111 Deskjet 1510 c202 PhotoSmart 8200 series + c211 Deskjet 2540 series c302 DeskJet D2300 c402 PhotoSmart D5100 series c502 PhotoSmart D6100 series @@ -795,6 +801,7 @@ 8370 7 Port Hub 8371 PS/2 Keyboard And Mouse 8372 FT8U100AX Serial Port + 8508 Selectronic SP PRO 87d0 Cressi Dive Computer Interface 8a28 Rainforest Automation ZigBee Controller 8a98 TIAO Multi-Protocol Adapter @@ -809,6 +816,7 @@ 9135 Rotary Pub alarm 9136 Pulsecounter 9e90 Marvell OpenRD Base/Client + 9f08 CIB-1894 Conclusion SmartLink Box: 9f80 Ewert Energy Systems CANdapter a6d0 Texas Instruments XDS100v2 JTAG / BeagleBone A3 a951 HCP HIT GSM/GPRS modem [Cinterion MC55i] @@ -961,6 +969,7 @@ 1030 FV TouchCam N1 (Video) 3000 Optical dual-touch panel 3001 Optical Touch Screen + a060 HD Webcam 0409 NEC Corp. 0011 PC98 Series Layout Keyboard Mouse 0012 ATerm IT75DSU ISDN TA @@ -1142,6 +1151,10 @@ 402b Photo Printer 6850 402e 605 Photo Printer 4034 805 Photo Printer + 4035 7000 Photo Printer + 4037 7010 Photo Printer + 4038 7015 Photo Printer + 404d 8810 Photo Printer 404f 305 Photo Printer 4056 ESP 7200 Series AiO 4109 EasyShare Printer Dock Series 3 @@ -1157,6 +1170,7 @@ 602a i900 040b Weltrend Semiconductor 0a68 Func MS-3 gaming mouse [WT6573F MCU] + 2000 wired Keyboard [Dynex DX-WRK1401] 2367 Human Interface Device [HP CalcPad 200 Calculator and Numeric Keypad] 6510 Weltrend Bar Code Reader 6520 Xploder Xbox Memory Unit (8MB) @@ -1294,6 +1308,7 @@ 7721 Memory Stick Reader/Writer 7722 Memory Stick Reader/Writer 7723 SD Card Reader + c141 Barcode Scanner 0417 Symbios Logic 0418 AST Research 0419 Samsung Info. Systems America, Inc. @@ -1609,7 +1624,7 @@ 0301 2500H Tracer Trainer 030a PETracer x1 1237 Andromeda Hub -0424 Standard Microsystems Corp. +0424 Microchip Technology, Inc. (formerly SMSC) 0001 Integrated Hub 0140 LPC47M14x hub 0acd Sitecom Internal Multi Memory reader/writer MD-005 @@ -1638,6 +1653,29 @@ 4041 Hub and media card controller 4060 Ultra Fast Media Reader 4064 Ultra Fast Media Reader + 4712 USB4712 high-speed hub + 4713 USB4715 high-speed hub (2 ports disabled) + 4714 USB4715 high-speed hub (1 port disabled) + 4715 USB4715 high-speed hub + 4910 USB491x hub integrated functions (primary) + 4912 USB4912 high-speed hub (1 port disabled) + 4914 USB4914 high-speed hub + 4916 USB4916 high-speed hub + 4920 USB491x hub integrated functions (secondary) + 4925 USB4925 high-speed hub (primary upstream) + 4927 USB4927 high-speed hub (primary upstream) + 4931 USB4925/4927 high-speed hub (secondary upstream) + 4940 USB47xx/49xx hub integrated WinUSB + 4942 USB47xx/49xx hub integrated I2S audio port + 4943 USB47xx/49xx hub integrated I2S audio + HID port + 4944 USB47xx/49xx hub integrated serial port + 4946 USB47xx/49xx hub integrated serial + I2S audio port + 4947 USB47xx/49xx hub integrated serial + I2S audio + HID port + 494a USB47xx/49xx hub integrated WinUSB + I2S audio port + 494b USB47xx/49xx hub integrated WinUSB + I2S audio + HID port + 494c USB47xx/49xx hub integrated WinUSB + serial port + 494e USB47xx/49xx hub integrated WinUSB + serial + I2S audio port + 494f USB47xx/49xx hub integrated WinUSB + serial + I2S audio + HID port 5434 Hub 5534 Hub 5744 Hub @@ -1676,6 +1714,7 @@ 0083 109 Japanese Keyboard 00a2 Type 7 Keyboard 0100 3-button Mouse + 0502 Panasonic CF-19 HID Touch Panel 100e 24.1" LCD Monitor v4 / FID-638 Mouse 36ba Bus Powered Hub a101 remote key/mouse for P3 chip @@ -1699,6 +1738,7 @@ 0005 CameraMate (DPCM_USB) 0437 Framatome Connectors USA 0438 Advanced Micro Devices, Inc. + 7900 Root Hub 0439 Voice Technologies Group 043d Lexmark International, Inc. 0001 Laser Printer @@ -1808,6 +1848,7 @@ 008c to CF/SM/SD/MS Card Reader 008e InkJet Color Printer 008f X422 + 0091 Laser Printer E232 0093 X5250 0095 E220 Printer 0096 2200 series @@ -1945,10 +1986,14 @@ b700 Tacticalboard 0450 DFI, Inc. 0451 Texas Instruments, Inc. + 0422 TUSB422 Port Controller with Power Delivery 1234 Bluetooth Device 1428 Hub 1446 TUSB2040/2070 Hub + 16a2 CC Debugger 16a6 BM-USBD1 BlueRobin RF heart rate sensor receiver + 16a8 CC2531 ZigBee + 16ae CC2531 Dongle 2036 TUSB2036 Hub 2046 TUSB2046 Hub 2077 TUSB2077 Hub @@ -1976,7 +2021,17 @@ e003 TI-84 Plus Calculator e004 TI-89 Titanium Calculator e008 TI-84 Plus Silver Calculator + e00e TI-89 Titanium Presentation Link + e00f TI-84 Plus Presentation Link + e010 TI SmartPad Keyboard + e011 Nspire CAS+ prototype e012 TI-Nspire Calculator + e013 Network Bridge + e01c Data Collection Sled [Nspire Lab Cradle, Nspire Datatracker Cradle] + e01e Nspire™ CX Navigator™ Access Point + e01f Python Adapter (firmware install mode) + e020 Python Adapter + e022 Nspire CX II f430 MSP-FET430UIF JTAG Tool f432 eZ430 Development Tool ffff Bluetooth Device @@ -2006,6 +2061,7 @@ 0002 Genius NetMouse Pro 0003 Genius NetScroll+ 0006 Easy Mouse+ + 0007 Trackbar Emotion 000b NetMouse Wheel(P+U) 000c TACOMA Fingerprint V1.06.01 000e Genius NetScroll Optical @@ -2033,6 +2089,7 @@ 0100 EasyPen Tablet 0101 CueCat 011b NetScroll T220 + 0186 Genius DX-120 Mouse 1001 Joystick 1002 Game Pad 1003 Genius VideoCam @@ -2065,11 +2122,15 @@ 3018 Wireless 2.4Ghz Game Pad 3019 10-Button USB Joystick with Vibration 301a MaxFire G-12U Vibration + 301c Genius MaxFighter F-16U 301d Genius MaxFire MiniPad 400f Genius TVGo DVB-T02Q MCE 4012 TVGo DVB-T03 [AF9015] 5003 G-pen 560 Tablet 5004 G-pen Tablet + 5005 Genius EasyPen M406 + 5012 Genius EasyPen M406W + 5014 Genius EasyPen 340 505e Genius iSlim 330 6001 GF3000F Ethernet Adapter 7004 VideoCAM Express V2 @@ -2207,6 +2268,7 @@ 00cb Basic Optical Mouse v2.0 00ce Generic PPC Flash device 00d1 Optical Mouse with Tilt Wheel + 00d2 Notebook Optical Mouse with Tilt Wheel 00da eHome Infrared Receiver 00db Natural Ergonomic Keyboard 4000 V1.0 00dd Comfort Curve Keyboard 2000 V1.0 @@ -2425,6 +2487,7 @@ 07cd Surface Keyboard 07f8 Wired Keyboard 600 (model 1576) 07fd Nano Transceiver 1.1 + 0810 LifeCam HD-3000 0900 Surface Dock Hub 0901 Surface Dock Hub 0902 Surface Dock Hub @@ -2502,12 +2565,14 @@ 4d62 HP Laser Mobile Mini Mouse 4d75 Rocketfish RF-FLBTAD Bluetooth Adapter 4d81 Dell N889 Optical Mouse + 4d8a HP Multimedia Keyboard 4d91 Laser mouse M-D16DL 4d92 Optical mouse M-D17DR 4db1 Dell Laptop Integrated Webcam 2Mpix 4de3 HP 5-Button Optical Comfort Mouse 4de7 webcam 4e04 Lenovo Keyboard KB1021 + 4e6f Acer Wired Keyboard Model KBAY211 0463 MGE UPS Systems 0001 UPS ffff UPS @@ -2536,6 +2601,7 @@ 00a1 SmartCard Reader Keyboard KC 1000 SC 0106 R-300 Wireless Mouse Receiver 010d MX-Board 3.0 Keyboard + 0180 Strait 3.0 b090 Keyboard b091 Mouse 046b American Megatrends, Inc. @@ -2693,6 +2759,7 @@ 0a45 960 Headset 0a4d G430 Surround Sound Gaming Headset 0a5b G933 Wireless Headset Dongle + 0a5d G933 Headset Battery Charger 0a66 [G533 Wireless Headset Dongle] 0b02 C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode) 8801 Video Camera @@ -2822,6 +2889,7 @@ c231 G13 Virtual Mouse c245 G400 Optical Mouse c246 Gaming Mouse G300 + c247 G100S Optical Gaming Mouse c248 G105 Gaming Keyboard c24a G600 Gaming Mouse c24c G400s Optical Mouse @@ -2870,6 +2938,7 @@ c31f Comfort Keyboard K290 c326 Washable Keyboard K310 c328 Corded Keyboard K280e + c32b G910 Orion Spark Mechanical Keyboard c332 G502 Proteus Spectrum Optical Mouse c335 G910 Orion Spectrum Mechanical Keyboard c33a G413 Gaming Keyboard @@ -2911,6 +2980,8 @@ c531 C-U0007 [Unifying Receiver] c532 Unifying Receiver c534 Unifying Receiver + c537 Cordless Mouse Receiver + c53a PowerPlay Wireless Charging System c603 3Dconnexion Spacemouse Plus XT c605 3Dconnexion CADman c606 3Dconnexion Spacemouse Classic @@ -3198,6 +3269,7 @@ f101 Atlas Modem 047f Plantronics, Inc. 0101 Bulk Driver + 02ee BT600 0301 Bulk Driver 0411 Savi Office Base Station 0ca1 USB DSP v4 Audio Interface @@ -3207,6 +3279,7 @@ af01 DA80 c008 Audio 655 DSP c00e Blackwire C310 headset + c03b HD1 0480 Toshiba America Inc 0001 InTouch Module 0004 InTouch Module @@ -3216,6 +3289,7 @@ 0200 External Disk 0820 Canvio Advance Disk 0821 Canvio Advance 2TB model DTC920 + 0900 MQ04UBF100 a006 External Disk 1.5TB a007 External Disk USB 3.0 a009 Stor.E Basics @@ -3285,6 +3359,7 @@ 8259 Probe 91d1 Sensor Hub a171 ThermaData WiFi + a2e0 BMeasure instrument df11 STM Device in DFU Mode ff10 Swann ST56 Modem 0484 Specialix @@ -3314,6 +3389,7 @@ 048d Integrated Technology Express, Inc. 1165 IT1165 Flash Controller 1172 Flash Drive + 1234 Mass storage 1336 SD/MMC Cardreader 1345 Multi Cardreader 9006 IT9135 BDA Afatech DVB-T HDTV Dongle @@ -3659,6 +3735,7 @@ 10c9 PIXMA iP4600 Printer 10ca PIXMA iP3600 Printer 10e3 PIXMA iX6850 Printer + 12fe Printer in service mode 1404 W6400PG 1405 W8400PG 150f BIJ2350 PCL @@ -3774,6 +3851,7 @@ 178a PIXMA MG3600 Series 178d PIXMA MG6853 180b PIXMA MG3000 series + 1856 PIXMA TS6250 1900 CanoScan LiDE 90 1901 CanoScan 8800F 1904 CanoScan LiDE 100 @@ -3842,6 +3920,7 @@ 2633 LASERCLASS 500 2634 PC-D300/FAX-L400/ICD300 2635 MPC190 + 2636 LBP3200 2637 iR C6800 2638 iR C3100 263c PIXMA MP360 @@ -3856,8 +3935,10 @@ 264f MF5650 (FAX) 2650 iR 6800C EUR 2651 iR 3100C EUR + 2654 LBP3600 2655 FP-L170/MF350/L380/L398 2656 iR1510-1670 CAPT Printer + 2657 LBP3210 2659 MF8100 265b CAPT Printer 265c iR C3220 @@ -3871,7 +3952,7 @@ 2666 iR C5800 2667 iR85PLUS 2669 iR105PLUS - 266a CAPT Device + 266a LBP3000 266b iR8070 266c iR9070 266d iR 5800C EUR @@ -3886,31 +3967,46 @@ 2676 LBP2900 2677 iR C2570 2678 iR 2570C EUR - 2679 CAPT Device + 2679 LBP5000 267a iR2016 267b iR2020 267d MF7100 series + 267e LBP3300 2684 MF3200 series 2686 MF6500 series 2687 iR4530 2688 LBP3460 2689 FAX-L180/L380S/L398S 268a LC310/L390/L408S + 268b LBP3500 268c iR C6870 268d iR 6870C EUR 268e iR C5870 268f iR 5870C EUR 2691 iR7105 + 26a1 LBP5300 26a3 MF4100 series + 26a4 LBP5100 26b0 MF4600 series 26b4 MF4010 series 26b5 MF4200 series 26b6 FAX-L140/L130 - 26da LBP3010B printer + 26b9 LBP3310 + 26ba LBP5050 + 26da LBP3010/LBP3018/LBP3050 + 26db LBP3100/LBP3108/LBP3150 26e6 iR1024 + 26ea LBP9100C + 26ee MF4320-4350 + 26f1 LBP7200C + 26ff LBP6300 271a LBP6000 + 271b LBP6200 + 271c LBP7010C/7018C 2736 I-SENSYS MF4550d 2737 MF4410 + 2771 LBP6020 + 2796 LBP6230/6240 3041 PowerShot S10 3042 CanoScan FS4000US Film Scanner 3043 PowerShot S20 @@ -4313,6 +4409,7 @@ 0429 D5100 042a D800 (ptp) 0430 D7100 + 0436 D810 043f D5600 0f03 PD-10 Wireless Printer Adapter 4000 Coolscan LS 40 ED @@ -4374,6 +4471,7 @@ 4611 Storage Adapter FX2 (CY) 4616 Flash Disk (TPP) 4624 DS-Xtreme Flash Card + 4717 West Bridge 5201 Combi Keyboard-Hub (Hub) 5202 Combi Keyboard-Hub (Keyboard) 5500 HID->COM RS232 Adapter @@ -11638,10 +11736,16 @@ 09c1 Arris Interactive LLC 1337 TOUCHSTONE DEVICE 09c2 Nisca Corp. -09c3 ActivCard, Inc. +09c3 HID Global 0007 Reader V2 0008 ZFG-9800-AC SmartCard Reader 0014 ActivIdentity ActivKey SIM USB Token + 0028 Crescendo Key + 0029 Crescendo Key + 002a Crescendo Key + 002b Crescendo Key + 002c Crescendo Key + 002e Crescendo Key 09c4 ACTiSYS Corp. 0011 ACT-IR2000U IrDA Dongle 09c5 Memory Corp. @@ -15165,7 +15269,7 @@ 10c3 Universal Laser Systems, Inc. 00a4 ULS PLS Series Laser Engraver Firmware Loader 00a5 ULS Print Support -10c4 Cygnal Integrated Products, Inc. +10c4 Silicon Labs 0002 F32x USBXpress Device 0003 CommandIR 800a SPORTident @@ -15204,12 +15308,29 @@ 8973 C8051F38x HDMI Extender [UHBX-8X] 89c6 SPORTident HID device 89e1 C8051F38x HDMI Extender [UHBX-SW3-WP] - ea60 CP2102/CP2109 UART Bridge Controller [CP210x family] + 89fb Qivicon ZigBee Stick + 8a3c C8051F38x HDBaseT Receiver [UHBX-R-XT] + 8a6c C8051F38x 4K HDMI Audio Extractor [EMX-AMP] + 8acb C8051F38x HDBaseT Wall Plate Receiver with IR, RS-232, and PoH [UHBX-R-WP] + 8af8 C8051F38x 4K HDMI Audio Extractor w/Audio Amplifier, HDBT Input, Line Audio Input RS-232 Ports and IP Control [VSA-X21] + 8b8c C8051F38x 4K HDMI Audio Extractor w/Audio Amplifier, HDBT Input, Line Audio Input RS-232 Ports and IP Control [SC-3H] + 8db5 C8051F38x CATx HDMI Receiver with USB [EX-HDU-R] + 8db6 C8051F38x CATx HDMI Receiver + ea60 CP210x UART Bridge ea61 CP210x UART Bridge - ea70 CP210x UART Bridge - ea80 CP210x UART Bridge + ea63 CP210x UART Bridge + ea70 CP2105 Dual UART Bridge + ea71 CP2108 Quad UART Bridge + ea80 CP2110 HID UART Bridge + ea90 CP2112 HID I2C Bridge + ea91 CP2112 HID SMBus/I2C Bridge for CP2614 Evaluation Kit + ea93 CP2112 HID SMBus/I2C Bridge for CP2615 Evaluation Kit + eab0 CP2114 I2S Audio Bridge + eac0 CP2614 MFi Accessory Digital Audio Bridge + eac1 CP2615 I2S Audio Bridge eac9 EFM8UB1 Bootloader eaca EFM8UB2 Bootloader + eacb EFM8UB3 Bootloader 10c5 Sanei Electric, Inc. 819a FM Radio 10c6 Intec, Inc. @@ -16548,6 +16669,7 @@ 001b Emu [Ambit3 Peak] 001c Finch [Ambit3 Sport] 001d Greentit [Ambit2 R] + 001e Ibisbill [Ambit3 Run] 1497 Panstrong Company Ltd. 1498 Microtek International Inc. a090 DVB-T Tuner @@ -18704,6 +18826,7 @@ 2cf6 Pyra Mouse (wireless) 2d50 Kova+ Mouse 2d51 Kone+ Mouse + 2e22 Kone XTD Mouse 30d4 Arvo Keyboard 1ea7 SHARKOON Technologies GmbH 0066 [Mediatrack Edge Mini Keyboard] @@ -19030,6 +19153,14 @@ 6323 USB Electronic Scale 2237 Kobo Inc. 4161 eReader White +224f APDM + 0001 Access Point + 0002 Docking Station + 0004 V2 Opal ACM + 0005 V2 Opal + 0006 V2 Docking Station + 0007 V2 Access Point ACM + 0008 V2 Access Point 225d Morpho 0001 FINGER VP Multimodal Biometric Sensor 0008 CBM-E3 Fingerprint Sensor @@ -19240,6 +19371,8 @@ 2548 Pulse-Eight 1001 CEC Adapter 1002 CEC Adapter +25b5 FlatFrog + 0002 Multitouch 3200 2632 TwinMOS 3209 7-in-1 Card Reader 2639 Xsens @@ -19346,6 +19479,17 @@ 930c CCD Webcam(PC370R) 27b8 ThingM 01ed blink(1) +27c6 Shenzhen Goodix Technology Co.,Ltd. + 5117 Fingerprint Reader + 5201 Fingerprint Reader + 5301 Fingerprint Reader + 530c Fingerprint Reader + 5385 Fingerprint Reader + 538c Fingerprint Reader + 5395 Fingerprint Reader + 5584 Fingerprint Reader + 55b4 Fingerprint Reader + 5740 Fingerprint Reader 2821 ASUSTek Computer Inc. 0161 WL-161 802.11b Wireless Adapter [SiS 162U] 160f WL-160g 802.11g Wireless Adapter [Envara WiND512] @@ -19440,6 +19584,8 @@ 0296 BG96 CAT-M1/NB-IoT modem 0306 EG06/EP06/EM06 LTE-A modem 0435 AG35 LTE modem +2cdc Sea & Sun Technology GmbH + f232 CTD48Mc CTD Probe 2dcf Dialog Semiconductor c952 Audio Class 2.0 Devices 2fb2 Fujitsu, Ltd diff --git a/usr/src/head/getopt.h b/usr/src/head/getopt.h index adf98d096c..2b72c23ddc 100644 --- a/usr/src/head/getopt.h +++ b/usr/src/head/getopt.h @@ -27,6 +27,10 @@ */ /* + * Copyright 2020 Joyent Inc. + */ + +/* * GNU-like getopt_long(), getopt_long_only(). * Solaris-specific getopt_clip(). */ @@ -49,11 +53,13 @@ extern "C" { #define optional_argument 2 struct option { - char *name; /* name of long option */ - int has_arg; /* whether option takes an argument */ - int *flag; /* if not NULL, set *flag to val when option found */ - int val; /* if flag is not NULL, value to set *flag to. */ - /* if flag is NULL, return value */ + const char *name; /* name of long option */ + int has_arg; /* whether option takes an argument */ + int *flag; /* if not NULL, set *flag to val when option */ + /* found */ + int val; /* if flag is not NULL, value to set *flag */ + /* to. */ + /* if flag is NULL, return value */ }; /* diff --git a/usr/src/head/stdlib.h b/usr/src/head/stdlib.h index 6b0d224e07..337311a978 100644 --- a/usr/src/head/stdlib.h +++ b/usr/src/head/stdlib.h @@ -28,7 +28,7 @@ /* * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. - * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1988 AT&T */ @@ -250,6 +250,19 @@ extern int setenv(const char *, const char *, int); extern int unsetenv(const char *); #endif +/* + * In strict XPG4v2 mode, slave pseudo terminal devices behave differently. + * See the block comment in usr/src/lib/libc/port/gen/pt.c + */ +#if defined(_STRICT_SYMBOLS) && defined(_XPG4_2) +#ifdef __PRAGMA_REDEFINE_EXTNAME +#pragma redefine_extname unlockpt __unlockpt_xpg4 +#else +extern int __unlockpt_xpg4(int); +#define unlockpt __unlockpt_xpg4 +#endif +#endif /* defined(_STRICT_SYMBOLS) && defined(_XPG4_2) */ + #if defined(__EXTENSIONS__) || \ (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) extern char *canonicalize_file_name(const char *); diff --git a/usr/src/lib/fm/libfmd_snmp/common/module.c b/usr/src/lib/fm/libfmd_snmp/common/module.c index 6f6161f366..0521cf40fb 100644 --- a/usr/src/lib/fm/libfmd_snmp/common/module.c +++ b/usr/src/lib/fm/libfmd_snmp/common/module.c @@ -270,9 +270,8 @@ modinfo_update(sunFmModule_update_ctx_t *update_ctx) return (SNMP_ERR_NOERROR); } -/*ARGSUSED*/ -static void -update_thread(void *arg) +__NORETURN static void * +update_thread(void *arg __unused) { /* * The current modinfo_update implementation offers minimal savings @@ -357,8 +356,7 @@ sunFmModuleTable_init(void) return (MIB_REGISTRATION_FAILED); } - if ((err = pthread_create(NULL, NULL, (void *(*)(void *))update_thread, - NULL)) != 0) { + if ((err = pthread_create(NULL, NULL, update_thread, NULL)) != 0) { (void) snmp_log(LOG_ERR, MODNAME_STR ": error creating update " "thread: %s\n", strerror(err)); return (MIB_REGISTRATION_FAILED); diff --git a/usr/src/lib/fm/libfmd_snmp/common/problem.c b/usr/src/lib/fm/libfmd_snmp/common/problem.c index dc1fc7a158..21835ec8a0 100644 --- a/usr/src/lib/fm/libfmd_snmp/common/problem.c +++ b/usr/src/lib/fm/libfmd_snmp/common/problem.c @@ -274,9 +274,8 @@ problem_update(sunFmProblem_update_ctx_t *update_ctx) return (SNMP_ERR_NOERROR); } -/*ARGSUSED*/ -static void -update_thread(void *arg) +__NORETURN static void * +update_thread(void *arg __unused) { /* * The current problem_update implementation offers minimal savings @@ -348,8 +347,7 @@ sunFmProblemTable_init(void) return (MIB_REGISTRATION_FAILED); } - if ((err = pthread_create(NULL, NULL, (void *(*)(void *))update_thread, - NULL)) != 0) { + if ((err = pthread_create(NULL, NULL, update_thread, NULL)) != 0) { (void) snmp_log(LOG_ERR, MODNAME_STR ": error creating update " "thread: %s\n", strerror(err)); return (MIB_REGISTRATION_FAILED); diff --git a/usr/src/lib/fm/libfmd_snmp/common/resource.c b/usr/src/lib/fm/libfmd_snmp/common/resource.c index 59e202337e..7cf3e1131c 100644 --- a/usr/src/lib/fm/libfmd_snmp/common/resource.c +++ b/usr/src/lib/fm/libfmd_snmp/common/resource.c @@ -265,9 +265,8 @@ rsrcinfo_update(sunFmResource_update_ctx_t *update_ctx) return (SNMP_ERR_NOERROR); } -/*ARGSUSED*/ -static void -update_thread(void *arg) +__NORETURN static void * +update_thread(void *arg __unused) { /* * The current rsrcinfo_update implementation offers minimal savings @@ -354,8 +353,7 @@ sunFmResourceTable_init(void) return (MIB_REGISTRATION_FAILED); } - if ((err = pthread_create(NULL, NULL, (void *(*)(void *))update_thread, - NULL)) != 0) { + if ((err = pthread_create(NULL, NULL, update_thread, NULL)) != 0) { (void) snmp_log(LOG_ERR, MODNAME_STR ": error creating update " "thread: %s\n", strerror(err)); return (MIB_REGISTRATION_FAILED); diff --git a/usr/src/lib/fm/libfmd_snmp/common/scheme.c b/usr/src/lib/fm/libfmd_snmp/common/scheme.c index 55c45a7ae3..771763f6d1 100644 --- a/usr/src/lib/fm/libfmd_snmp/common/scheme.c +++ b/usr/src/lib/fm/libfmd_snmp/common/scheme.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/fm/protocol.h> #include <sys/types.h> #include <sys/systeminfo.h> @@ -75,13 +73,19 @@ static fmd_scheme_t *sch_list; /* list of cached schemes */ static char *g_root; /* fmd root dir */ static struct topo_hdl *g_thp; -static long -fmd_scheme_notsup(void) +static ssize_t +fmd_scheme_notsup(nvlist_t *nv __unused, char *arg1 __unused, + size_t arg2 __unused) { errno = ENOTSUP; return (-1); } +static void +fmd_scheme_vnop(void) +{ +} + static int fmd_scheme_nop(void) { @@ -93,9 +97,9 @@ fmd_scheme_nop(void) * the module, then this operation is implemented using the default function. */ static const fmd_scheme_ops_t _fmd_scheme_default_ops = { - (int (*)())fmd_scheme_nop, /* sop_init */ - (void (*)())fmd_scheme_nop, /* sop_fini */ - (ssize_t (*)())fmd_scheme_notsup, /* sop_nvl2str */ + .sop_init = fmd_scheme_nop, /* sop_init */ + .sop_fini = fmd_scheme_vnop, /* sop_fini */ + .sop_nvl2str = fmd_scheme_notsup /* sop_nvl2str */ }; /* diff --git a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c index b8d89db32d..8968c70c95 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c +++ b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c @@ -93,6 +93,18 @@ pci_hostbridges_find(topo_mod_t *mod, tnode_t *ptn) pnode = di_drv_first_node(PCI, devtree); while (pnode != DI_NODE_NIL) { + /* + * We've seen cases where certain phantom PCI hostbridges have + * appeared on systems. If we encounter a host bridge without a + * bus address assigned to it, then we should skip processing it + * here as that indicates that it generally doesn't have any + * devices under it and we'll otherwise blow up in devinfo. + */ + if (di_bus_addr(pnode) == NULL) { + pnode = di_drv_next_node(pnode); + continue; + } + if (hb_process(mod, ptn, hbcnt, pnode) < 0) { if (hbcnt == 0) topo_node_range_destroy(ptn, HOSTBRIDGE); diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com b/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com index 72a6b80cab..966241305e 100644 --- a/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com +++ b/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com @@ -22,6 +22,7 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2020 Joyent, Inc. # LIBRARY= kldap.a @@ -46,7 +47,7 @@ include $(SRC)/lib/gss_mechs/mech_krb5/Makefile.mech_krb5 #override liblink INS.liblink= -$(RM) $@; $(SYMLINK) $(LIBLINKS)$(VERS) $@ -CPPFLAGS += -DHAVE_CONFIG_H \ +CPPFLAGS += -DHAVE_CONFIG_H \ -I$(SRC)/cmd/krb5/iprop \ -I$(SRC)/lib/krb5 \ -I$(SRC)/lib/krb5/kdb \ @@ -65,15 +66,12 @@ CERRWARN += -_gcc=-Wno-unused-function DYNFLAGS += $(KERBRUNPATH) # setting -L $(ROOT)/usr/lib/gss because libkdb_ldap needs mech_krb5 -LDLIBS += -L $(ROOT)/usr/lib/gss -L $(ROOTLIBDIR) -lkdb_ldap \ - -lc +LDLIBS += -L $(ROOT)/usr/lib/gss -L $(ROOTLIBDIR) -lkdb_ldap .KEEP_STATE: all: $(LIBS) -lint: lintcheck - # include library targets include $(SRC)/lib/krb5/Makefile.targ diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index dfd4069e85..c0a065c9df 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -24,7 +24,7 @@ # Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2013 Garrett D'Amore <garrett@damore.org> # Copyright 2018 Nexenta Systems, Inc. -# Copyright (c) 2019, Joyent, Inc. +# Copyright 2019 Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # diff --git a/usr/src/lib/libc/i386/sys/gettimeofday.c b/usr/src/lib/libc/i386/sys/gettimeofday.c index 7539c2143e..c2396e582a 100644 --- a/usr/src/lib/libc/i386/sys/gettimeofday.c +++ b/usr/src/lib/libc/i386/sys/gettimeofday.c @@ -28,7 +28,7 @@ gettimeofday(struct timeval *tv, void *tz) /* * Perform a NULL check before attempting to store the result directly. - * The old fasttrop logic would perform this same check, but after the + * The old fasttrap logic would perform this same check, but after the * call into hrestime(). */ if (tv == NULL) { diff --git a/usr/src/lib/libc/port/gen/pt.c b/usr/src/lib/libc/port/gen/pt.c index 26dd4dd376..3372f7133c 100644 --- a/usr/src/lib/libc/port/gen/pt.c +++ b/usr/src/lib/libc/port/gen/pt.c @@ -24,10 +24,12 @@ * Use is subject to license terms. */ -/* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ +/* + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* Copyright (c) 1988 AT&T */ +/* All Rights Reserved */ #pragma weak _ptsname = ptsname #pragma weak _grantpt = grantpt @@ -133,6 +135,45 @@ unlockpt(int fd) return (0); } +/* + * XPG4v2 requires that open of a slave pseudo terminal device + * provides the process with an interface that is identical to + * the terminal interface. + * + * To satisfy this, in strict XPG4v2 mode, this routine also sends + * a message down the stream that sets a flag in the kernel module + * so that additional actions are performed when opening an + * associated slave PTY device. When this happens, modules are + * automatically pushed onto the stream to provide terminal + * semantics and those modules are then informed that they should + * behave in strict XPG4v2 mode which modifies their behaviour. In + * particular, in strict XPG4v2 mode, empty blocks will be sent up + * the master side of the stream rather than being suppressed. + * + * Most applications do not expect this behaviour so it is only + * enabled for programs compiled in strict XPG4v2 mode (see + * stdlib.h). + */ +int +__unlockpt_xpg4(int fd) +{ + int ret; + + if ((ret = unlockpt(fd)) == 0) { + struct strioctl istr; + + istr.ic_cmd = PTSSTTY; + istr.ic_len = 0; + istr.ic_timout = 0; + istr.ic_dp = NULL; + + if (ioctl(fd, I_STR, &istr) < 0) + ret = -1; + } + + return (ret); +} + int grantpt(int fd) { diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index f2c12c1b4b..dbe33eb9d1 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -27,7 +27,7 @@ # Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright (c) 2013 Gary Mills # Copyright 2014 Garrett D'Amore <garrett@damore.org> -# Copyright 2019 OmniOS Community Edition (OmniOSce) Association. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # @@ -78,6 +78,11 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.31 { + protected: + __unlockpt_xpg4; +} ILLUMOS_0.30; + SYMBOL_VERSION ILLUMOS_0.30 { protected: reallocf; diff --git a/usr/src/lib/libc/port/sys/open.c b/usr/src/lib/libc/port/sys/open.c index 067bb72d69..2ea6c567f4 100644 --- a/usr/src/lib/libc/port/sys/open.c +++ b/usr/src/lib/libc/port/sys/open.c @@ -22,44 +22,32 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ #include "lint.h" -#include <sys/mkdev.h> #include <limits.h> #include <stdarg.h> #include <unistd.h> -#include <strings.h> -#include <errno.h> -#include <sys/stat.h> #include <sys/fcntl.h> -#include <sys/stropts.h> -#include <sys/stream.h> -#include <sys/ptms.h> #include <sys/syscall.h> #include "libc.h" -static int xpg4_fixup(int fd); -static void push_module(int fd); -static int isptsfd(int fd); -static void itoa(int i, char *ptr); - int __openat(int dfd, const char *path, int oflag, mode_t mode) { - int fd = syscall(SYS_openat, dfd, path, oflag, mode); - return (xpg4_fixup(fd)); + return (syscall(SYS_openat, dfd, path, oflag, mode)); } int __open(const char *path, int oflag, mode_t mode) { #if defined(_RETAIN_OLD_SYSCALLS) - int fd = syscall(SYS_open, path, oflag, mode); - return (xpg4_fixup(fd)); + return (syscall(SYS_open, path, oflag, mode)); #else return (__openat(AT_FDCWD, path, oflag, mode)); #endif @@ -70,114 +58,17 @@ __open(const char *path, int oflag, mode_t mode) int __openat64(int dfd, const char *path, int oflag, mode_t mode) { - int fd = syscall(SYS_openat64, dfd, path, oflag, mode); - return (xpg4_fixup(fd)); + return (syscall(SYS_openat64, dfd, path, oflag, mode)); } int __open64(const char *path, int oflag, mode_t mode) { #if defined(_RETAIN_OLD_SYSCALLS) - int fd = syscall(SYS_open64, path, oflag, mode); - return (xpg4_fixup(fd)); + return (syscall(SYS_open64, path, oflag, mode)); #else return (__openat64(AT_FDCWD, path, oflag, mode)); #endif } #endif /* !_LP64 */ - -/* - * XPG4v2 requires that open of a slave pseudo terminal device - * provides the process with an interface that is identical to - * the terminal interface. For a more detailed discussion, - * see bugid 4025044. - */ -static int -xpg4_fixup(int fd) -{ - if (libc__xpg4 != 0 && fd >= 0 && isptsfd(fd)) - push_module(fd); - return (fd); -} - -/* - * Check if the file matches an entry in the /dev/pts directory. - * Be careful to preserve errno. - */ -static int -isptsfd(int fd) -{ - char buf[TTYNAME_MAX]; - char *str1 = buf; - const char *str2 = "/dev/pts/"; - struct stat64 fsb, stb; - int oerrno = errno; - int rval = 0; - - if (fstat64(fd, &fsb) == 0 && S_ISCHR(fsb.st_mode)) { - /* - * Do this without strcpy() or strlen(), - * to avoid invoking the dynamic linker. - */ - while (*str2 != '\0') - *str1++ = *str2++; - /* - * Inline version of minor(dev), to avoid the dynamic linker. - */ - itoa(fsb.st_rdev & MAXMIN, str1); - if (stat64(buf, &stb) == 0) - rval = (stb.st_rdev == fsb.st_rdev); - } - errno = oerrno; - return (rval); -} - -/* - * Converts a number to a string (null terminated). - */ -static void -itoa(int i, char *ptr) -{ - int dig = 0; - int tempi; - - tempi = i; - do { - dig++; - tempi /= 10; - } while (tempi); - - ptr += dig; - *ptr = '\0'; - while (--dig >= 0) { - *(--ptr) = i % 10 + '0'; - i /= 10; - } -} - -/* - * Push modules to provide tty semantics - */ -static void -push_module(int fd) -{ - struct strioctl istr; - int oerrno = errno; - - istr.ic_cmd = PTSSTTY; - istr.ic_len = 0; - istr.ic_timout = 0; - istr.ic_dp = NULL; - if (ioctl(fd, I_STR, &istr) != -1) { - (void) ioctl(fd, __I_PUSH_NOCTTY, "ptem"); - (void) ioctl(fd, __I_PUSH_NOCTTY, "ldterm"); - (void) ioctl(fd, __I_PUSH_NOCTTY, "ttcompat"); - istr.ic_cmd = PTSSTTY; - istr.ic_len = 0; - istr.ic_timout = 0; - istr.ic_dp = NULL; - (void) ioctl(fd, I_STR, &istr); - } - errno = oerrno; -} diff --git a/usr/src/lib/libdisasm/common/dis_riscv.c b/usr/src/lib/libdisasm/common/dis_riscv.c index fa7cc30610..f246a19137 100644 --- a/usr/src/lib/libdisasm/common/dis_riscv.c +++ b/usr/src/lib/libdisasm/common/dis_riscv.c @@ -313,7 +313,7 @@ typedef void (*dis_riscv_func_t)(dis_handle_t *, uint32_t, struct dis_riscv_instr *, char *, size_t); typedef struct dis_riscv_instr { - const char *drv_name; + const char *drv_name; dis_riscv_itype_t drv_type; dis_riscv_func_t drv_print; uint_t drv_opcode; @@ -959,7 +959,7 @@ dis_riscv_fp_rm(dis_handle_t *dhp, uint32_t instr, #define DIS_RISCV_FP_R_RS2_IFP_NR(str, op, f3, rs2, f7) \ { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_ifp_nr, op, f3, \ f7, rs2 } -#define DIS_RISCV_FP_RI(str, op, f3, f7) \ +#define DIS_RISCV_FP_RI(str, op, f3, f7) \ { str, DIS_RISCV_I_R_TYPE, dis_riscv_fp_r_fpi, op, f3, f7 } /* @@ -1300,7 +1300,7 @@ typedef struct dis_riscv_c_instr { const char *drv_c_name; dis_riscv_ctype_t drv_c_type; dis_riscv_c_func_t drv_c_print; - dis_riscv_c_class_t drv_c_class; + dis_riscv_c_class_t drv_c_class; uint_t drv_c_opcode; uint_t drv_c_funct; uint_t drv_c_mask; @@ -1680,7 +1680,7 @@ dis_riscv_c_int(dis_handle_t *dhp, uint32_t instr, #define DIS_RISCV_CFUNCT3(name, class, op, funct, print) \ { name, DIS_RISCV_C_FUNCT3, print, class, op, funct, 0, 0 } -#define DIS_RISCV_CMATCH(name, class, op, funct, mask, match, print) \ +#define DIS_RISCV_CMATCH(name, class, op, funct, mask, match, print) \ { name, DIS_RISCV_C_MATCH, print, class, op, funct, mask, match } static dis_riscv_c_instr_t dis_riscv_2byte[] = { @@ -1972,7 +1972,6 @@ dis_riscv_max_instrlen(dis_handle_t *dhp) static int dis_riscv_instrlen(dis_handle_t *dhp, uint64_t addr) { - int ret; uint16_t parcel; dhp->dh_addr = addr; @@ -1980,15 +1979,7 @@ dis_riscv_instrlen(dis_handle_t *dhp, uint64_t addr) if (dis_riscv_read_parcel(dhp, &parcel) != 0) return (-1); - /* - * Get length based on this parcel. Check for required alignment. 2-byte - * alignment was already taken care of when we read the parcel. - */ - ret = dis_riscv_decode_len(parcel); - if (ret >= 4 && (addr % 4) != 0) - return (-1); - - return (ret); + return (dis_riscv_decode_len(parcel)); } dis_arch_t dis_arch_riscv = { diff --git a/usr/src/lib/libdladm/common/libdladm.c b/usr/src/lib/libdladm/common/libdladm.c index d0a34ef23d..446a15893b 100644 --- a/usr/src/lib/libdladm/common/libdladm.c +++ b/usr/src/lib/libdladm/common/libdladm.c @@ -27,6 +27,10 @@ * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. */ +/* + * Copyright 2020 Peter Tribble. + */ + #include <unistd.h> #include <errno.h> #include <ctype.h> @@ -70,23 +74,23 @@ static media_type_t media_type_table[] = { { DL_HDLC, "HDLC" }, { DL_CHAR, "SyncCharacter" }, { DL_CTCA, "CTCA" }, - { DL_FDDI, "FDDI" }, - { DL_FC, "FiberChannel" }, - { DL_ATM, "ATM" }, - { DL_IPATM, "ATM(ClassicIP)" }, - { DL_X25, "X.25" }, - { DL_IPX25, "X.25(ClassicIP)" }, - { DL_ISDN, "ISDN" }, - { DL_HIPPI, "HIPPI" }, - { DL_100VG, "100BaseVGEthernet" }, - { DL_100VGTPR, "100BaseVGTokenRing" }, - { DL_ETH_CSMA, "IEEE802.3" }, - { DL_100BT, "100BaseT" }, - { DL_FRAME, "FrameRelay" }, - { DL_MPFRAME, "MPFrameRelay" }, - { DL_ASYNC, "AsyncCharacter" }, - { DL_IPNET, "IPNET" }, - { DL_OTHER, "Other" } + { DL_FDDI, "FDDI" }, + { DL_FC, "FiberChannel" }, + { DL_ATM, "ATM" }, + { DL_IPATM, "ATM(ClassicIP)" }, + { DL_X25, "X.25" }, + { DL_IPX25, "X.25(ClassicIP)" }, + { DL_ISDN, "ISDN" }, + { DL_HIPPI, "HIPPI" }, + { DL_100VG, "100BaseVGEthernet" }, + { DL_100VGTPR, "100BaseVGTokenRing" }, + { DL_ETH_CSMA, "IEEE802.3" }, + { DL_100BT, "100BaseT" }, + { DL_FRAME, "FrameRelay" }, + { DL_MPFRAME, "MPFrameRelay" }, + { DL_ASYNC, "AsyncCharacter" }, + { DL_IPNET, "IPNET" }, + { DL_OTHER, "Other" } }; #define MEDIATYPECOUNT (sizeof (media_type_table) / sizeof (media_type_t)) @@ -452,6 +456,9 @@ dladm_status2str(dladm_status_t status, char *buf) case DLADM_STATUS_BAD_ENCAP: s = "invalid encapsulation protocol"; break; + case DLADM_STATUS_PERSIST_ON_TEMP: + s = "can't create persistent object on top of temporary object"; + break; default: s = "<unknown error>"; break; @@ -594,11 +601,7 @@ dladm_bw2str(int64_t bw, char *buf) kbps = (bw%1000000)/1000; mbps = bw/1000000; if (kbps != 0) { - if (mbps == 0) - (void) snprintf(buf, DLADM_STRSIZE, "0.%03u", kbps); - else - (void) snprintf(buf, DLADM_STRSIZE, "%5u.%03u", mbps, - kbps); + (void) snprintf(buf, DLADM_STRSIZE, "%5u.%03u", mbps, kbps); } else { (void) snprintf(buf, DLADM_STRSIZE, "%5u", mbps); } diff --git a/usr/src/lib/libdladm/common/libdladm.h b/usr/src/lib/libdladm/common/libdladm.h index f5ae0e6ace..685356fa64 100644 --- a/usr/src/lib/libdladm/common/libdladm.h +++ b/usr/src/lib/libdladm/common/libdladm.h @@ -24,7 +24,7 @@ */ /* - * Copyright 2019 OmniOS Community Edition (OmniOSce) Association + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association */ #ifndef _LIBDLADM_H @@ -185,7 +185,8 @@ typedef enum { DLADM_STATUS_INVALID_PKEY_TBL_SIZE, DLADM_STATUS_PORT_NOPROTO, DLADM_STATUS_INVALID_MTU, - DLADM_STATUS_BAD_ENCAP + DLADM_STATUS_BAD_ENCAP, + DLADM_STATUS_PERSIST_ON_TEMP } dladm_status_t; typedef enum { diff --git a/usr/src/lib/libdladm/common/libdlvnic.c b/usr/src/lib/libdladm/common/libdlvnic.c index 47d007a1e2..7ff0cd5530 100644 --- a/usr/src/lib/libdladm/common/libdlvnic.c +++ b/usr/src/lib/libdladm/common/libdlvnic.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015, Joyent Inc. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #include <stdio.h> @@ -406,6 +407,7 @@ dladm_vnic_create(dladm_handle_t handle, const char *vnic, datalink_id_t linkid, datalink_id_t vnic_id; datalink_class_t class; uint32_t media = DL_ETHER; + uint32_t link_flags; char name[MAXLINKNAMELEN]; uchar_t tmp_addr[MAXMACADDRLEN]; dladm_status_t status; @@ -421,6 +423,15 @@ dladm_vnic_create(dladm_handle_t handle, const char *vnic, datalink_id_t linkid, if ((flags & DLADM_OPT_ACTIVE) == 0) return (DLADM_STATUS_NOTSUP); + /* + * It's an anchor VNIC - linkid must be set to DATALINK_INVALID_LINKID + * and the VLAN id must be 0 + */ + if ((flags & DLADM_OPT_ANCHOR) != 0 && + (linkid != DATALINK_INVALID_LINKID || vid != 0)) { + return (DLADM_STATUS_BADARG); + } + is_vlan = ((flags & DLADM_OPT_VLAN) != 0); if (is_vlan && ((vid < 1 || vid > 4094))) return (DLADM_STATUS_VIDINVAL); @@ -430,18 +441,20 @@ dladm_vnic_create(dladm_handle_t handle, const char *vnic, datalink_id_t linkid, if (!dladm_vnic_macaddrtype2str(mac_addr_type)) return (DLADM_STATUS_INVALIDMACADDRTYPE); - if ((flags & DLADM_OPT_ANCHOR) == 0) { - if ((status = dladm_datalink_id2info(handle, linkid, NULL, - &class, &media, NULL, 0)) != DLADM_STATUS_OK) + if (!is_etherstub) { + if ((status = dladm_datalink_id2info(handle, linkid, + &link_flags, &class, &media, NULL, 0)) != DLADM_STATUS_OK) return (status); + /* Disallow persistent objects on top of temporary ones */ + if ((flags & DLADM_OPT_PERSIST) != 0 && + (link_flags & DLMGMT_PERSIST) == 0) + return (DLADM_STATUS_PERSIST_ON_TEMP); + + /* Links cannot be created on top of these object types */ if (class == DATALINK_CLASS_VNIC || class == DATALINK_CLASS_VLAN) return (DLADM_STATUS_BADARG); - } else { - /* it's an anchor VNIC */ - if (linkid != DATALINK_INVALID_LINKID || vid != 0) - return (DLADM_STATUS_BADARG); } /* diff --git a/usr/src/lib/libfakekernel/common/callout.c b/usr/src/lib/libfakekernel/common/callout.c index b2e5048bab..6752e2f44a 100644 --- a/usr/src/lib/libfakekernel/common/callout.c +++ b/usr/src/lib/libfakekernel/common/callout.c @@ -46,7 +46,7 @@ timeout(void (*func)(void *), void *arg, clock_t delta) bzero(&sev, sizeof (sev)); sev.sigev_notify = SIGEV_THREAD; sev.sigev_value.sival_ptr = arg; - sev.sigev_notify_function = (sigev_notify_func_t)func; + sev.sigev_notify_function = (sigev_notify_func_t)(uintptr_t)func; err = timer_create(CLOCK_REALTIME, &sev, &tid); if (err != 0) return (NULL); diff --git a/usr/src/lib/libfakekernel/common/thread.c b/usr/src/lib/libfakekernel/common/thread.c index 7cfac712a8..31421a723b 100644 --- a/usr/src/lib/libfakekernel/common/thread.c +++ b/usr/src/lib/libfakekernel/common/thread.c @@ -70,7 +70,7 @@ thread_create( break; } - thr_func = (void *(*)(void *))func; + thr_func = (void *(*)(void *))(uintptr_t)func; rc = thr_create(NULL, 0, thr_func, arg, thr_flags, &newtid); if (rc != 0) cmn_err(CE_PANIC, "thread_create failed, rc=%d", rc); diff --git a/usr/src/lib/libidspace/Makefile.com b/usr/src/lib/libidspace/Makefile.com index 8cc60ffc4c..ef259c3d2f 100644 --- a/usr/src/lib/libidspace/Makefile.com +++ b/usr/src/lib/libidspace/Makefile.com @@ -10,7 +10,7 @@ # # -# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# Copyright 2020 Joyent, Inc. # LIBRARY = libidspace.a @@ -23,18 +23,14 @@ include ../../Makefile.lib SRCDIR = ../common SRCS = ../../../common/idspace/id_space.c -LIBS = $(DYNLIB) $(LINTLIB) +LIBS = $(DYNLIB) -LDLIBS += -lc -lumem - -$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) +LDLIBS += -lumem .KEEP_STATE: all: $(LIBS) -lint: lintcheck - include ../../Makefile.targ objs/%.o pics/%.o: $(COMDIR)/%.c diff --git a/usr/src/lib/libjedec/Makefile.com b/usr/src/lib/libjedec/Makefile.com index 755004d099..a2138ed9ea 100644 --- a/usr/src/lib/libjedec/Makefile.com +++ b/usr/src/lib/libjedec/Makefile.com @@ -10,7 +10,7 @@ # # -# Copyright (c) 2018 Joyent, Inc. +# Copyright 2020 Joyent, Inc. # LIBRARY = libjedec.a @@ -19,8 +19,7 @@ OBJECTS = libjedec.o include ../../Makefile.lib -LIBS = $(DYNLIB) $(LINTLIB) -LDLIBS += -lc +LIBS = $(DYNLIB) CPPFLAGS += -I../common SRCDIR = ../common @@ -29,6 +28,4 @@ SRCDIR = ../common all: $(LIBS) -lint: lintcheck - include ../../Makefile.targ diff --git a/usr/src/lib/libprtdiag/Makefile.com b/usr/src/lib/libprtdiag/Makefile.com index 6994883b47..406fcfc96f 100644 --- a/usr/src/lib/libprtdiag/Makefile.com +++ b/usr/src/lib/libprtdiag/Makefile.com @@ -21,6 +21,7 @@ # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2020 Peter Tribble. # # @@ -39,8 +40,7 @@ include $(SRC)/Makefile.psm LIBS = $(DYNLIB) $(LINTLIB) IFLAGS = -I ../../inc -I $(USR_PSM_INCL_DIR) IFLAGS += -I $(SRC)/cmd/picl/plugins/inc -IFLAGS += -I $(UTSBASE)/sun4u -IFLAGS += -I $(UTSBASE)/sun4u/sunfire +IFLAGS += -I $(UTSBASE)/sun4u IFLAGS += -I $(UTSBASE)/sun4u/serengeti CPPFLAGS = $(IFLAGS) $(CPPFLAGS.master) CFLAGS += $(CCVERBOSE) diff --git a/usr/src/lib/libprtdiag/common/display_sun4u.c b/usr/src/lib/libprtdiag/common/display_sun4u.c index a68246600f..56e2716e38 100644 --- a/usr/src/lib/libprtdiag/common/display_sun4u.c +++ b/usr/src/lib/libprtdiag/common/display_sun4u.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020 Peter Tribble. */ #include <stdio.h> @@ -62,7 +63,6 @@ display(Sys_tree *tree, int exit_code = 0; /* init to all OK */ void *value; /* used for opaque PROM data */ struct mem_total memory_total; /* Total memory in system */ - struct grp_info grps; /* Info on all groups in system */ sys_clk = -1; /* System clock freq. (in MHz) */ @@ -96,7 +96,7 @@ display(Sys_tree *tree, } /* Display the Memory Size */ - display_memorysize(tree, kstats, &grps, &memory_total); + display_memorysize(tree, kstats, &memory_total); /* Display platform specific configuration info */ display_platform_specific_header(); @@ -105,7 +105,7 @@ display(Sys_tree *tree, display_cpu_devices(tree); /* Display the Memory configuration */ - display_memoryconf(tree, &grps); + display_memoryconf(tree); /* Display all the IO cards. */ (void) display_io_devices(tree); diff --git a/usr/src/lib/libprtdiag/common/display_sun4v.c b/usr/src/lib/libprtdiag/common/display_sun4v.c index e4a2408537..9ec03878b5 100644 --- a/usr/src/lib/libprtdiag/common/display_sun4v.c +++ b/usr/src/lib/libprtdiag/common/display_sun4v.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020 Peter Tribble. */ #include <stdio.h> @@ -119,7 +120,6 @@ sun4v_display(Sys_tree *tree, Prom_node *root, int log, { void *value; /* used for opaque PROM data */ struct mem_total memory_total; /* Total memory in system */ - struct grp_info grps; /* Info on all groups in system */ char machine[MAXSTRLEN]; int exit_code = 0; @@ -155,7 +155,7 @@ sun4v_display(Sys_tree *tree, Prom_node *root, int log, } /* Display the Memory Size */ - display_memorysize(tree, NULL, &grps, &memory_total); + display_memorysize(tree, NULL, &memory_total); /* Display the CPU devices */ sun4v_display_cpu_devices(plafh); diff --git a/usr/src/lib/libprtdiag/common/kstat.c b/usr/src/lib/libprtdiag/common/kstat.c index 1c29e96642..5aaf523441 100644 --- a/usr/src/lib/libprtdiag/common/kstat.c +++ b/usr/src/lib/libprtdiag/common/kstat.c @@ -22,10 +22,9 @@ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. + * Copyright (c) 2020 Peter Tribble. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -54,369 +53,33 @@ /* * This module does the reading and interpreting of sun4u system - * kstats. These kstats are created by the following drivers: - * fhc, environ, sysctrl. Each board in the tree should have - * kstats created for it. There are also system wide kstats that - * are created. + * kstats. It is overlaid by a platform-specific implementation as + * appropriate. */ void read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep) + struct envctrl_kstat_data *ep) { - Board_node *bnode; - kstat_ctl_t *kc; - kstat_t *ksp; - kstat_named_t *knp; - int i; - struct hp_info *hp; - -#ifdef lint - ep = ep; -#endif - if ((kc = kstat_open()) == NULL) { - return; - } - - /* For each board in the system, read the kstats for it. */ - for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) { - int board; - - /* - * Kstat instances numbers are set by fhc, ac, simmstat, - * and environ drivers based on their board# property. - */ - board = bnode->board_num; - bdp = &sys_kstat->bd_ksp_list[board]; - - /* Try to find an FHC instance for this board number */ - ksp = kstat_lookup(kc, UNIX, board, FHC_KSTAT_NAME); - - /* Atempt to read the FHC kstat */ - if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) == -1)) { - ksp = NULL; - } - - /* Now read out the data if the kstat read OK */ - if (ksp != NULL) { - /* - * We set the kstats_ok flag to good here. If we - * fail one of the data reads, we set it to bad. - */ - bdp->fhc_kstats_ok = 1; - - /* - * For each data value, If the Kstat named struct - * is found, then get the data out. - */ - knp = kstat_data_lookup(ksp, CSR_KSTAT_NAMED); - if (knp != NULL) { - bdp->fhc_csr = knp->value.ul; - } else { - bdp->fhc_kstats_ok = 0; - } - knp = kstat_data_lookup(ksp, BSR_KSTAT_NAMED); - if (knp != NULL) { - bdp->fhc_bsr = knp->value.ul; - } else { - bdp->fhc_kstats_ok = 0; - } - } - - /* Try to find an AC instance for this board number */ - ksp = kstat_lookup(kc, UNIX, board, AC_KSTAT_NAME); - - /* Attempt to read the AC kstat. */ - if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) == -1)) { - ksp = NULL; - } - - /* If the AC kstat exists, try to read the data from it. */ - if (ksp != NULL) { - /* - * We set the kstats_ok flag to good here. If we - * fail one of the data reads, we set it to bad. - */ - bdp->ac_kstats_ok = 1; - bdp->ac_memstat_ok = 1; - - /* - * For each data value, If the Kstat named struct - * is found, then get the data out. - */ - - knp = kstat_data_lookup(ksp, MEMCTL_KSTAT_NAMED); - if (knp != NULL) { - bdp->ac_memctl = knp->value.ull; - } else { - bdp->ac_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, MEMDECODE0_KSTAT_NAMED); - if (knp != NULL) { - bdp->ac_memdecode[0] = knp->value.ull; - } else { - bdp->ac_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, MEMDECODE1_KSTAT_NAMED); - if (knp != NULL) { - bdp->ac_memdecode[1] = knp->value.ull; - } else { - bdp->ac_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, BANK_0_KSTAT_NAMED); - if (knp != NULL) { - bdp->mem_stat[0].status = knp->value.c[0]; - bdp->mem_stat[0].condition = knp->value.c[1]; - } else { - bdp->ac_memstat_ok = 0; - } - - knp = kstat_data_lookup(ksp, BANK_1_KSTAT_NAMED); - if (knp != NULL) { - bdp->mem_stat[1].status = knp->value.c[0]; - bdp->mem_stat[1].condition = knp->value.c[1]; - } else { - bdp->ac_memstat_ok = 0; - } - - } - - /* Try to find an simmstat instance for this board number */ - ksp = kstat_lookup(kc, UNIX, board, SIMMSTAT_KSTAT_NAME); - - if (ksp != NULL) { - if (kstat_read(kc, ksp, NULL) == -1) { - bdp->simmstat_kstats_ok = 0; - } else { - bdp->simmstat_kstats_ok = 1; - (void) memcpy(&bdp->simm_status, ksp->ks_data, - sizeof (bdp->simm_status)); - } - } - - /* Try to find an overtemp kstat instance for this board */ - ksp = kstat_lookup(kc, UNIX, board, OVERTEMP_KSTAT_NAME); - - if (ksp != NULL) { - if (kstat_read(kc, ksp, NULL) == -1) { - bdp->temp_kstat_ok = 0; - } else { - bdp->temp_kstat_ok = 1; - (void) memcpy(&bdp->tempstat, ksp->ks_data, - sizeof (bdp->tempstat)); - /* XXX - this is for 2.5.1 testing. remove */ - if (sizeof (bdp->tempstat) > ksp->ks_data_size) - bdp->tempstat.trend = TREND_UNKNOWN; - } - } - } - - /* Read the kstats for the system control board */ - ksp = kstat_lookup(kc, UNIX, 0, SYSCTRL_KSTAT_NAME); - - if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) == -1)) { - sys_kstat->sys_kstats_ok = 0; - ksp = NULL; - } - - if (ksp != NULL) { - sys_kstat->sys_kstats_ok = 1; - - knp = kstat_data_lookup(ksp, CSR_KSTAT_NAMED); - if (knp != NULL) { - sys_kstat->sysctrl = knp->value.c[0]; - } else { - sys_kstat->sys_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, STAT1_KSTAT_NAMED); - if (knp != NULL) { - sys_kstat->sysstat1 = knp->value.c[0]; - } else { - sys_kstat->sys_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, STAT2_KSTAT_NAMED); - if (knp != NULL) { - sys_kstat->sysstat2 = knp->value.c[0]; - } else { - sys_kstat->sys_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, CLK_FREQ2_KSTAT_NAMED); - if (knp != NULL) { - sys_kstat->clk_freq2 = knp->value.c[0]; - } else { - sys_kstat->sys_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, FAN_KSTAT_NAMED); - if (knp != NULL) { - sys_kstat->fan_status = knp->value.c[0]; - } else { - sys_kstat->sys_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, KEY_KSTAT_NAMED); - if (knp != NULL) { - sys_kstat->keysw_status = knp->value.c[0]; - } else { - sys_kstat->sys_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, POWER_KSTAT_NAMED); - if (knp != NULL) { - sys_kstat->power_state = - (enum power_state)knp->value.l; - } else { - sys_kstat->sys_kstats_ok = 0; - } - - knp = kstat_data_lookup(ksp, CLK_VER_KSTAT_NAME); - if (knp != NULL) { - sys_kstat->clk_ver = knp->value.c[0]; - } else { - /* - * the clock version register only appears - * on new clock boards - */ - sys_kstat->clk_ver = 0; - } - - } - - /* Read the kstats for the power supply stats */ - ksp = kstat_lookup(kc, UNIX, 0, PSSHAD_KSTAT_NAME); - - if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) != -1)) { - sys_kstat->psstat_kstat_ok = 1; - (void) memcpy(&sys_kstat->ps_shadow[0], ksp->ks_data, - sizeof (sys_kstat->ps_shadow)); - } else { - sys_kstat->psstat_kstat_ok = 0; - } - - /* read the overtemp kstat for the system control board */ - /* Try to find an overtemp kstat instance for this board */ - ksp = kstat_lookup(kc, UNIX, CLOCK_BOARD_INDEX, OVERTEMP_KSTAT_NAME); - - if (ksp != NULL) { - if (kstat_read(kc, ksp, NULL) == -1) { - sys_kstat->temp_kstat_ok = 0; - } else { - sys_kstat->temp_kstat_ok = 1; - (void) memcpy(&sys_kstat->tempstat, ksp->ks_data, - sizeof (sys_kstat->tempstat)); - /* XXX - this is for 2.5.1 testing. remove */ - if (sizeof (sys_kstat->tempstat) > ksp->ks_data_size) - sys_kstat->tempstat.trend = TREND_UNKNOWN; - } - } - - /* Read the reset-info kstat from one of the boards. */ - ksp = kstat_lookup(kc, UNIX, 0, RESETINFO_KSTAT_NAME); - - if (ksp == NULL) { - sys_kstat->reset_kstats_ok = 0; - } else if (kstat_read(kc, ksp, NULL) == -1) { - sys_kstat->reset_kstats_ok = 0; - } else { - sys_kstat->reset_kstats_ok = 1; - (void) memcpy(&sys_kstat->reset_info, ksp->ks_data, - sizeof (sys_kstat->reset_info)); - } - - /* read kstats for hotplugged boards */ - for (i = 0, hp = &sys_kstat->hp_info[0]; i < MAX_BOARDS; i++, hp++) { - ksp = kstat_lookup(kc, UNIX, i, BDLIST_KSTAT_NAME); - - if (ksp == NULL) { - continue; - } - - if (kstat_read(kc, ksp, NULL) == -1) { - hp->kstat_ok = 0; - } else { - hp->kstat_ok = 1; - (void) memcpy(&hp->bd_info, ksp->ks_data, - sizeof (hp->bd_info)); - } - } - - /* read in the kstat for the fault list. */ - ksp = kstat_lookup(kc, UNIX, 0, FT_LIST_KSTAT_NAME); - - if (ksp == NULL) { - sys_kstat->ft_kstat_ok = 0; - } else { - if (kstat_read(kc, ksp, NULL) == -1) { - perror("kstat read"); - sys_kstat->ft_kstat_ok = 0; - return; - } - - sys_kstat->nfaults = ksp->ks_data_size / - sizeof (struct ft_list); - - sys_kstat->ft_array = - (struct ft_list *)malloc(ksp->ks_data_size); - - if (sys_kstat->ft_array == NULL) { - perror("Malloc"); - exit(2); - } - sys_kstat->ft_kstat_ok = 1; - (void) memcpy(sys_kstat->ft_array, ksp->ks_data, - ksp->ks_data_size); - } } /* * This function does the reading and interpreting of sun4u system - * kstats. These kstats are created by the following drivers: - * fhc, environ, sysctrl. Each board in the tree should have - * kstats created for it. There are also system wide kstats that - * are created. + * kstats. */ void read_sun4u_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat) { -#if 0 - Board_node *bnode; - kstat_t *ksp; - kstat_named_t *knp; - struct hp_info *hp; - struct envctrltwo_kstat_data *ecp; -#endif - kstat_ctl_t *kc; + kstat_ctl_t *kc; int i; - struct bd_kstat_data *bdp; struct envctrl_kstat_data *ep; if ((kc = kstat_open()) == NULL) { return; } -#ifdef lint - kc = kc; -#endif /* Initialize the kstats structure */ sys_kstat->sys_kstats_ok = 0; - sys_kstat->temp_kstat_ok = 0; - sys_kstat->reset_kstats_ok = 0; - sys_kstat->ft_kstat_ok = 0; sys_kstat->envctrl_kstat_ok = 0; - for (i = 0; i < MAX_BOARDS; i++) { - bdp = &sys_kstat->bd_ksp_list[i]; - bdp->ac_kstats_ok = 0; - bdp->fhc_kstats_ok = 0; - bdp->simmstat_kstats_ok = 0; - bdp->temp_kstat_ok = 0; - - sys_kstat->hp_info[i].kstat_ok = 0; - } for (i = 0; i < MAX_DEVS; i++) { ep = &sys_kstat->env_data; ep->ps_kstats[i].instance = I2C_NODEV; @@ -424,5 +87,5 @@ read_sun4u_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat) ep->encl_kstats[i].instance = I2C_NODEV; } - read_platform_kstats(tree, sys_kstat, bdp, ep); + read_platform_kstats(tree, sys_kstat, ep); } diff --git a/usr/src/lib/libprtdiag/common/memory.c b/usr/src/lib/libprtdiag/common/memory.c index 1e1aaff425..575f94e956 100644 --- a/usr/src/lib/libprtdiag/common/memory.c +++ b/usr/src/lib/libprtdiag/common/memory.c @@ -22,10 +22,9 @@ /* * Copyright (c) 1999-2001 by Sun Microsystems, Inc. * All rights reserved. + * Copyright (c) 2020 Peter Tribble. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -86,7 +85,7 @@ static memory_seg_t *match_seg(uint64_t); /*ARGSUSED0*/ void display_memorysize(Sys_tree *tree, struct system_kstat_data *kstats, - struct grp_info *grps, struct mem_total *memory_total) + struct mem_total *memory_total) { log_printf(dgettext(TEXT_DOMAIN, "Memory size: "), 0); @@ -110,7 +109,7 @@ display_memorysize(Sys_tree *tree, struct system_kstat_data *kstats, /*ARGSUSED0*/ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { /* * This function is intentionally blank diff --git a/usr/src/lib/libprtdiag/inc/libprtdiag.h b/usr/src/lib/libprtdiag/inc/libprtdiag.h index e9361b8e9c..41e6227c18 100644 --- a/usr/src/lib/libprtdiag/inc/libprtdiag.h +++ b/usr/src/lib/libprtdiag/inc/libprtdiag.h @@ -21,13 +21,12 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. */ #ifndef _SYS_LIBPRTDIAG_H #define _SYS_LIBPRTDIAG_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -132,15 +131,15 @@ void decode_qlc_card_model_prop(Prom_node *card_node, struct io_card *card); */ void read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep); + struct envctrl_kstat_data *ep); void read_sun4u_kstats(Sys_tree *, struct system_kstat_data *); /* * memory functions */ void display_memorysize(Sys_tree *tree, struct system_kstat_data *kstats, - struct grp_info *grps, struct mem_total *memory_total); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); + struct mem_total *memory_total); +void display_memoryconf(Sys_tree *tree); /* * prom functions diff --git a/usr/src/lib/libprtdiag/inc/pdevinfo_sun4u.h b/usr/src/lib/libprtdiag/inc/pdevinfo_sun4u.h index 7273d62b8d..c4038e4535 100644 --- a/usr/src/lib/libprtdiag/inc/pdevinfo_sun4u.h +++ b/usr/src/lib/libprtdiag/inc/pdevinfo_sun4u.h @@ -22,68 +22,45 @@ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. + * Copyright (c) 2020 Peter Tribble. */ #ifndef _PDEVINFO_SUN4U_H #define _PDEVINFO_SUN4U_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/obpdefs.h> -#include <sys/fhc.h> -#include <sys/sysctrl.h> -#include <sys/environ.h> #include <sys/envctrl_gen.h> #include <sys/envctrl_ue250.h> #include <sys/envctrl_ue450.h> -#include <sys/simmstat.h> -#include <sys/ac.h> -#include <sys/sram.h> -#include <reset_info.h> #ifdef __cplusplus extern "C" { #endif -#define UNIX "unix" +/* + * These were formerly defined in sys/ac.h, which was specific to sunfire, + * but usage has leaked into generic code. + */ +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif + +/* + * These were formerly defined as part of the board_type enum in sys/fhc.h, + * which was specific to sunfire, but usage has leaked into generic code. + */ +#define UNKNOWN_BOARD 1 +#define CPU_BOARD 2 /* Define names of nodes to search for */ -#define CPU_NAME "SUNW,UltraSPARC" #define SBUS_NAME "sbus" #define PCI_NAME "pci" #define FFB_NAME "SUNW,ffb" #define AFB_NAME "SUNW,afb" -struct mem_stat_data { - enum ac_bank_status status; /* bank status values */ - enum ac_bank_condition condition; /* bank conditions */ -}; - -struct bd_kstat_data { - u_longlong_t ac_memctl; /* Memctl register contents */ - u_longlong_t ac_memdecode[2]; /* memory decode registers . */ - int ac_kstats_ok; /* successful kstat read occurred */ - uint_t fhc_bsr; /* FHC Board Status Register */ - uint_t fhc_csr; /* FHC Control Status Register */ - int fhc_kstats_ok; /* successful kstat read occurred */ - uchar_t simm_status[SIMM_COUNT]; /* SIMM status */ - int simmstat_kstats_ok; /* successful read occurred */ - struct temp_stats tempstat; - int temp_kstat_ok; - struct mem_stat_data mem_stat[2]; /* raw kstat bank information */ - int ac_memstat_ok; /* successful read of memory status */ -}; - -/* - * Hot plug info structure. If a hotplug kstat is found, the bd_info - * structure from the kstat is filled in the the hp_info structure - * is marked OK. - */ -struct hp_info { - struct bd_info bd_info; - int kstat_ok; -}; - /* Environmental info for Tazmo */ struct envctrl_kstat_data { envctrl_ps_t ps_kstats[MAX_DEVS]; /* kstats for powersupplies */ @@ -106,69 +83,15 @@ struct envctrltwo_kstat_data { }; struct system_kstat_data { - uchar_t sysctrl; /* sysctrl register contents */ - uchar_t sysstat1; /* system status1 register contents. */ - uchar_t sysstat2; /* system status2 register contents. */ - uchar_t ps_shadow[SYS_PS_COUNT]; /* power supply shadow */ - int psstat_kstat_ok; - uchar_t clk_freq2; /* clock frequency register 2 contents */ - uchar_t fan_status; /* shadow fan status */ - uchar_t keysw_status; /* status of the key switch */ - enum power_state power_state; /* redundant power state */ - uchar_t clk_ver; /* clock version register */ int sys_kstats_ok; /* successful kstat read occurred */ - struct temp_stats tempstat; - int temp_kstat_ok; - struct reset_info reset_info; - int reset_kstats_ok; /* kstat read OK */ - struct bd_kstat_data bd_ksp_list[MAX_BOARDS]; - struct hp_info hp_info[MAX_BOARDS]; - struct ft_list *ft_array; /* fault array */ - int nfaults; /* number of faults in fault array */ - int ft_kstat_ok; /* Fault kstats OK */ struct envctrl_kstat_data env_data; /* environment data for Tazmo */ int envctrl_kstat_ok; struct envctrltwo_kstat_data envc_data; /* environ data for Javelin */ int envctrltwo_kstat_ok; }; -/* Description of a single memory group */ -struct grp { - int valid; /* active memory group present */ - u_longlong_t base; /* Phyiscal base of group */ - uint_t size; /* size in bytes */ - uint_t curr_size; /* current size in bytes */ - int board; /* board number */ - enum board_type type; /* board type */ - int group; /* group # on board (0 or 1) */ - int factor; /* interleave factor (0,2,4,8,16) */ - int speed; /* Memory speed (in ns) */ - char groupid; /* Alpha tag for group ID */ - enum ac_bank_status status; /* bank status values */ - enum ac_bank_condition condition; /* bank conditions */ -}; - -#define MAX_GROUPS 32 #define MAXSTRLEN 256 -/* Array of all possible groups in the system. */ -struct grp_info { - struct grp grp[MAX_GROUPS]; -}; - -/* A memory interleave structure */ -struct inter_grp { - u_longlong_t base; /* Physical base of group */ - int valid; - int count; - char groupid; -}; - -/* Array of all possible memory interleave structures */ -struct mem_inter { - struct inter_grp i_grp[MAX_GROUPS]; -}; - /* FFB info structure */ struct ffbinfo { int board; diff --git a/usr/src/lib/libprtdiag/inc/reset_info.h b/usr/src/lib/libprtdiag/inc/reset_info.h deleted file mode 100644 index 8f94813a6f..0000000000 --- a/usr/src/lib/libprtdiag/inc/reset_info.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1999 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _RESET_INFO_H -#define _RESET_INFO_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * All of the following data structures and defines come from sun4u server - * POST. If the data in POST changes, then these structures must reflect - * those changes. - */ - -#include <sys/fhc.h> /* To get MAX_BOARDS constant */ - -/* BDA bit assignments */ -#define BOARD_PRESENT (1<<0) -#define BOARD_OK (1<<1) -#define BOARD_TYPE_MSK (7<<2) -#define BOARD_TYPE(x) (((x) & BOARD_TYPE_MSK) >> 2) - -/* Board state mask and defines */ -#define BD_STATE_MASK 0x3 -#define BD_LPM_FZN 0 -#define BD_ONLINE_FAIL 1 -#define BD_NOT_PRESENT 2 -#define BD_ONLINE_NORMAL 3 - -/* define CPU 0 fields */ -#define CPU0_PRESENT (1<<8) -#define CPU0_OK (1<<9) -#define CPU0_FAIL_CODE_MSK (7<<10) - -/* define CPU 1 fields */ -#define CPU1_PRESENT (1<<16) -#define CPU1_OK (1<<17) -#define CPU1_FAIL_CODE_MSK (7<<18) - -/* supported board types */ -#define CPU_TYPE 0 -#define MEM_TYPE 1 /* CPU/MEM board with only memory */ -#define IO_TYPE1 2 -#define IO_TYPE2 3 -#define IO_TYPE3 4 -#define IO_TYPE4 5 /* same as IO TYPE 1 but no HM or PHY chip */ -#define CLOCK_TYPE 7 - -/* for CPU type UPA ports */ -typedef struct { - u_longlong_t afsr; /* Fault status register for CPU */ - u_longlong_t afar; /* Fault address register for CPU */ -} cpu_reset_state; - -/* For the clock board */ -typedef struct { - unsigned long clk_ssr_1; /* reset status for the clock board */ -} clock_reset_state; - -struct board_info { - u_longlong_t board_desc; - cpu_reset_state cpu[2]; /* could be a CPU */ - u_longlong_t ac_error_status; - u_longlong_t dc_shadow_chain; - uint_t fhc_csr; - uint_t fhc_rcsr; -}; - -struct reset_info { - int length; /* size of the structure */ - int version; /* Version of the structure */ - struct board_info bd_reset_info[MAX_BOARDS]; - clock_reset_state clk; /* one clock board */ - unsigned char tod_timestamp[7]; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _RESET_INFO_H */ diff --git a/usr/src/lib/libprtdiag_psr/sparc/Makefile b/usr/src/lib/libprtdiag_psr/sparc/Makefile index 2755dcd558..5ca9074498 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/Makefile +++ b/usr/src/lib/libprtdiag_psr/sparc/Makefile @@ -21,11 +21,11 @@ # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. -# Copyright 2019 Peter Tribble. +# Copyright 2020 Peter Tribble. # # lib/libprtdiag_psr/sparc/Makefile -PRTDIAG_PLATFORMS= desktop tazmo javelin sunfire serengeti \ +PRTDIAG_PLATFORMS= desktop tazmo javelin serengeti \ littleneck daktari cherrystone \ lw8 ontario schumacher opl montoya monza diff --git a/usr/src/lib/libprtdiag_psr/sparc/Makefile.com b/usr/src/lib/libprtdiag_psr/sparc/Makefile.com index af44a80223..d3f93b3e06 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/Makefile.com +++ b/usr/src/lib/libprtdiag_psr/sparc/Makefile.com @@ -21,7 +21,7 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. -# Copyright 2019 Peter Tribble. +# Copyright 2020 Peter Tribble. # LIBRARY= libprtdiag_psr.a @@ -34,7 +34,7 @@ VERS= .1 # PSR_MACH= sun4u # -# PLATFORM_OBJECTS is defined in ./desktop ./wgs ./sunfire Makefiles +# PLATFORM_OBJECTS is defined in ./desktop ./wgs Makefiles # OBJECTS= $(PLATFORM_OBJECTS) @@ -56,9 +56,8 @@ CERRWARN += -_gcc=-Wno-unused-value CERRWARN += -_gcc=-Wno-unused-function CERRWARN += $(CNOWARN_UNINIT) CERRWARN += -_gcc=-Wno-address -IFLAGS += -I $(UTSBASE)/sun4u -IFLAGS += -I $(UTSCLOSED)/sun4u -IFLAGS += -I $(UTSCLOSED)/sun4u/sunfire -I $(UTSBASE)/sun4u/sunfire +IFLAGS += -I $(UTSBASE)/sun4u +IFLAGS += -I $(UTSCLOSED)/sun4u CPPFLAGS = $(IFLAGS) $(CPPFLAGS.master) LDLIBS += -L $(ROOT)/usr/platform/$(PSR_MACH)/lib -lprtdiag -lc DYNFLAGS += -R /usr/platform/$(PSR_MACH)/lib diff --git a/usr/src/lib/libprtdiag_psr/sparc/cherrystone/common/cherrystone.c b/usr/src/lib/libprtdiag_psr/sparc/cherrystone/common/cherrystone.c index 74731ac662..29e8703a5a 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/cherrystone/common/cherrystone.c +++ b/usr/src/lib/libprtdiag_psr/sparc/cherrystone/common/cherrystone.c @@ -21,6 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. */ /* @@ -29,8 +30,6 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -75,7 +74,7 @@ void display_io_cards(struct io_card *list); void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, struct system_kstat_data *kstats); void display_ffb(Board_node *board, int table); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_memoryconf(Sys_tree *tree); /* local functions */ static void disp_envc_status(void); @@ -229,9 +228,8 @@ display_cpus(Board_node *board) } } -/*ARGSUSED0*/ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { Board_node *bnode = tree->bd_list; diff --git a/usr/src/lib/libprtdiag_psr/sparc/daktari/common/daktari.c b/usr/src/lib/libprtdiag_psr/sparc/daktari/common/daktari.c index d4fc81913b..fd28266b86 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/daktari/common/daktari.c +++ b/usr/src/lib/libprtdiag_psr/sparc/daktari/common/daktari.c @@ -21,18 +21,17 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. */ /* * Daktari Platform specific functions. * - * called when : + * called when : * machine_type == MTYPE_DAKTARI * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -85,7 +84,7 @@ void display_io_cards(struct io_card *list); void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, struct system_kstat_data *kstats); void display_ffb(Board_node *board, int table); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_memoryconf(Sys_tree *tree); /* local functions */ static int disp_envc_status(void); @@ -241,9 +240,8 @@ display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats) (void) disp_fail_parts(tree); } -/*ARGSUSED*/ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { Board_node *bnode = tree->bd_list; diff --git a/usr/src/lib/libprtdiag_psr/sparc/desktop/common/desktop.c b/usr/src/lib/libprtdiag_psr/sparc/desktop/common/desktop.c index 29d72ee246..91c02cb8ae 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/desktop/common/desktop.c +++ b/usr/src/lib/libprtdiag_psr/sparc/desktop/common/desktop.c @@ -22,6 +22,7 @@ /* * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. * * Desktop Platform specific functions. * @@ -31,8 +32,6 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -89,15 +88,11 @@ extern int print_flag; * at runtime (desktop systems only) */ int error_check(Sys_tree *tree, struct system_kstat_data *kstats); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); int disp_fail_parts(Sys_tree *tree); void display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats); void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, struct system_kstat_data *kstats); void display_pci(Board_node *bnode); -void read_platform_kstats(Sys_tree *tree, - struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep); void display_sbus(Board_node *); @@ -130,22 +125,13 @@ error_check(Sys_tree *tree, struct system_kstat_data *kstats) } -void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) -{ -#ifdef lint - tree = tree; - grps = grps; -#endif -} - /* * disp_fail_parts * * Display the failed parts in the system. This function looks for * the status property in all PROM nodes. On systems where - * the PROM does not supports passing diagnostic information - * thruogh the device tree, this routine will be silent. + * the PROM does not support passing diagnostic information + * through the device tree, this routine will be silent. */ int disp_fail_parts(Sys_tree *tree) @@ -318,20 +304,6 @@ display_pci(Board_node *bnode) } } -void -read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep) - -{ -#ifdef lint - tree = tree; - sys_kstat = sys_kstat; - bdp = bdp; - ep = ep; -#endif -} - - /* * local functions */ diff --git a/usr/src/lib/libprtdiag_psr/sparc/javelin/common/javelin.c b/usr/src/lib/libprtdiag_psr/sparc/javelin/common/javelin.c index 1327ae9248..cae193a670 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/javelin/common/javelin.c +++ b/usr/src/lib/libprtdiag_psr/sparc/javelin/common/javelin.c @@ -22,6 +22,7 @@ /* * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. * * Javelin Platform specific functions. * @@ -67,7 +68,7 @@ extern int print_flag; * at runtime (workgroup server systems only) */ int error_check(Sys_tree *tree, struct system_kstat_data *kstats); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_memoryconf(Sys_tree *tree); int disp_fail_parts(Sys_tree *tree); void display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats); void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, @@ -78,7 +79,7 @@ void display_io_cards(struct io_card *list); void display_ffb(Board_node *, int); void read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep); + struct envctrl_kstat_data *ep); /* local functions */ static int disp_envc_status(struct system_kstat_data *); @@ -129,7 +130,7 @@ dev_next_node_sibling(Prom_node *root, char *name) * DIMM sizes, DIMM socket names. */ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { Board_node *bnode; Prom_node *memory; @@ -144,9 +145,6 @@ display_memoryconf(Sys_tree *tree, struct grp_info *grps) Prop *status_prop; char interleave[8]; int total_size = 0; -#ifdef lint - grps = grps; -#endif log_printf("\n", 0); log_printf("=========================", 0); @@ -752,11 +750,11 @@ display_ffb(Board_node *board, int table) /* * This module does the reading and interpreting of javelin system - * kstats. These kstats are created by the environ drivers. + * kstats. These kstats are created by the envctrl drivers. */ void read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep) + struct envctrl_kstat_data *ep) { kstat_ctl_t *kc; struct envctrltwo_kstat_data *ecp; @@ -765,11 +763,6 @@ read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, if ((kc = kstat_open()) == NULL) { return; } -#ifdef lint - tree = tree; - bdp = bdp; - ep = ep; -#endif /* read the envctrltwo kstats */ ecp = &sys_kstat->envc_data; diff --git a/usr/src/lib/libprtdiag_psr/sparc/littleneck/common/littleneck.c b/usr/src/lib/libprtdiag_psr/sparc/littleneck/common/littleneck.c index 89321c0455..828b26a95e 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/littleneck/common/littleneck.c +++ b/usr/src/lib/libprtdiag_psr/sparc/littleneck/common/littleneck.c @@ -21,16 +21,15 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. * * Littleneck Platform specific functions. * - * called when : + * called when : * machine_type == MTYPE_LITTLENECK * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -81,7 +80,7 @@ void display_io_cards(struct io_card *list); void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, struct system_kstat_data *kstats); void display_ffb(Board_node *board, int table); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_memoryconf(Sys_tree *tree); /* local functions */ static int disp_envc_status(void); @@ -231,9 +230,8 @@ display_cpus(Board_node *board) } } -/*ARGSUSED0*/ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { Board_node *bnode = tree->bd_list; diff --git a/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c b/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c index e12330a75a..640cda2970 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c +++ b/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c @@ -21,10 +21,11 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. * * Opl Platform specific functions. * - * called when : + * called when : * machine_type == MTYPE_OPL */ @@ -85,12 +86,12 @@ void display_ffb(Board_node *, int); void display_sbus(Board_node *board); void display_cpu_devices(Sys_tree *tree); void display_cpus(Board_node *board); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_memoryconf(Sys_tree *tree); void display_io_cards(struct io_card *list); void display_io_devices(Sys_tree *tree); void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, struct system_kstat_data *kstats); -Prop *find_prop(Prom_node *pnode, char *name); +Prop *find_prop(Prom_node *pnode, char *name); int do_piclinfo(int); int get_proc_mode(void); @@ -500,9 +501,8 @@ get_opl_mem_regs(Board_node *bnode) /* * Display memory information. */ -/*ARGSUSED*/ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { Board_node *bnode = tree->bd_list; uint64_t total_mem = 0, total_sys_mem = 0; diff --git a/usr/src/lib/libprtdiag_psr/sparc/serengeti/common/serengeti.c b/usr/src/lib/libprtdiag_psr/sparc/serengeti/common/serengeti.c index d77455e83d..6d95747413 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/serengeti/common/serengeti.c +++ b/usr/src/lib/libprtdiag_psr/sparc/serengeti/common/serengeti.c @@ -21,6 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. * * Serengeti Platform specific functions. * @@ -136,7 +137,7 @@ void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, void display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats); void get_failed_parts(void); int display_failed_parts(Sys_tree *tree); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_memoryconf(Sys_tree *tree); void print_us3_memory_line(int portid, int bank_id, uint64_t bank_size, char *bank_status, uint64_t dimm_size, uint32_t intlv, int seg_id); @@ -1766,9 +1767,8 @@ display_failed_parts(Sys_tree *tree) * This routine displays the memory configuration for all boards in the * system. */ -/*ARGSUSED0*/ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { Board_node *bnode = tree->bd_list; diff --git a/usr/src/lib/libprtdiag_psr/sparc/sunfire/Makefile b/usr/src/lib/libprtdiag_psr/sparc/sunfire/Makefile deleted file mode 100644 index 8bec1ea7d7..0000000000 --- a/usr/src/lib/libprtdiag_psr/sparc/sunfire/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2016 Gary Mills -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# lib/libprtdiag_psr/sparc/sunfire/Makefile - -UTSBASE = ../../../../uts - -PLATFORM_OBJECTS= sunfire.o - -include ../Makefile.com - -IFLAGS += -I$(USR_PLAT_DIR)/sun4u/include -I ../../../libprtdiag/inc -LINTFLAGS += $(IFLAGS) - -PLATFORM=SUNW,Ultra-Enterprise - -$(USR_PLAT_DIR)/$(PLATFORM)/lib/libprtdiag_psr.so.1 := FILEMODE= 0755 - -.KEEP_STATE: - -PLATLIBS= $(USR_PLAT_DIR)/$(PLATFORM)/lib/ - -install: all $(USR_PSM_LIBS) - -$(USR_PSM_LIB_DIR): - cd $(UTSBASE)/sun4u/sunfire; $(MAKE) $(USR_PSM_LIB_DIR) - -# -# install rule -# -$(USR_PSM_LIB_DIR)/%: % $(USR_PSM_LIB_DIR) - $(INS.file) - - -POFILE= libprtdiag_psr_sunfire.po -POFILES= sunfire.po - -_msg: $(MSGDOMAIN) $(POFILE) - $(RM) $(MSGDOMAIN)/$(POFILE) - $(CP) $(POFILE) $(MSGDOMAIN) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -$(POFILES): - $(RM) messages.po - $(XGETTEXT) $(XGETFLAGS) `$(GREP) -l gettext common/sunfire.c` - $(SED) -e '/^# msg/d' -e '/^domain/d' messages.po > $@ - $(RM) messages.po diff --git a/usr/src/lib/libprtdiag_psr/sparc/sunfire/common/sunfire.c b/usr/src/lib/libprtdiag_psr/sparc/sunfire/common/sunfire.c deleted file mode 100644 index cfb83f25a0..0000000000 --- a/usr/src/lib/libprtdiag_psr/sparc/sunfire/common/sunfire.c +++ /dev/null @@ -1,2284 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Sunfire Platform specific functions. - * - * called when : - * machine_type == MTYPE_SUNFIRE - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <ctype.h> -#include <string.h> -#include <kvm.h> -#include <varargs.h> -#include <time.h> -#include <dirent.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/utsname.h> -#include <sys/openpromio.h> -#include <libintl.h> -#include <syslog.h> -#include <sys/dkio.h> -#include "pdevinfo.h" -#include "display.h" -#include "pdevinfo_sun4u.h" -#include "display_sun4u.h" -#include "libprtdiag.h" - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - -/* Macros for manipulating UPA IDs and board numbers on Sunfire. */ -#define bd_to_upa(bd) ((bd) << 1) -#define upa_to_bd(upa) ((upa) >> 1) - -#define MAX_MSGS 64 - -extern int print_flag; - -/* - * these functions will overlay the symbol table of libprtdiag - * at runtime (sunfire systems only) - */ -int error_check(Sys_tree *tree, struct system_kstat_data *kstats); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); -int disp_fail_parts(Sys_tree *tree); -void display_memorysize(Sys_tree *tree, struct system_kstat_data *kstats, - struct grp_info *grps, struct mem_total *memory_total); -void display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats); -void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, - struct system_kstat_data *kstats); -void display_mid(int mid); -void display_pci(Board_node *); -void display_ffb(Board_node *, int); -void add_node(Sys_tree *, Prom_node *); -void resolve_board_types(Sys_tree *); - -/* local functions */ -static void build_mem_tables(Sys_tree *, struct system_kstat_data *, - struct grp_info *); -static void get_mem_total(struct mem_total *, struct grp_info *); -static int disp_fault_list(Sys_tree *, struct system_kstat_data *); -static int disp_err_log(struct system_kstat_data *); -static int disp_env_status(struct system_kstat_data *); -static int disp_keysw_and_leds(struct system_kstat_data *); -static void sunfire_disp_prom_versions(Sys_tree *); -static void erase_msgs(char **); -static void display_msgs(char **msgs, int board); -static void sunfire_disp_asic_revs(Sys_tree *, struct system_kstat_data *); -static void display_hp_boards(struct system_kstat_data *); -static int disp_parts(char **, u_longlong_t, int); -/* - * Error analysis routines. These routines decode data from specified - * error registers. They are meant to be used for decoding the fatal - * hardware reset data passed to the kernel by sun4u POST. - */ -static int analyze_cpu(char **, int, u_longlong_t); -static int analyze_ac(char **, u_longlong_t); -static int analyze_dc(int, char **, u_longlong_t); - -#define RESERVED_STR "Reserved" - -#define MAX_PARTS 5 -#define MAX_FRUS 5 - -#define MAXSTRLEN 256 - -/* Define special bits */ -#define UPA_PORT_A 0x1 -#define UPA_PORT_B 0x2 - - -/* - * These defines comne from async.h, but it does not get exported from - * uts/sun4u/sys, so they must be redefined. - */ -#define P_AFSR_ISAP 0x0000000040000000ULL /* incoming addr. parity err */ -#define P_AFSR_ETP 0x0000000020000000ULL /* ecache tag parity */ -#define P_AFSR_ETS 0x00000000000F0000ULL /* cache tag parity syndrome */ -#define ETS_SHIFT 16 - -/* List of parts possible */ -#define RSVD_PART 1 -#define UPA_PART 2 -#define UPA_A_PART 3 -#define UPA_B_PART 4 -#define SOFTWARE_PART 5 -#define AC_PART 6 -#define AC_ANY_PART 7 -#define DTAG_PART 8 -#define DTAG_A_PART 9 -#define DTAG_B_PART 10 -#define FHC_PART 11 -#define BOARD_PART 12 -#define BOARD_ANY_PART 13 -#define BOARD_CONN_PART 14 -#define BACK_PIN_PART 15 -#define BACK_TERM_PART 16 -#define CPU_PART 17 - -/* List of possible parts */ -static char *part_str[] = { - "", /* 0, a placeholder for indexing */ - "", /* 1, reserved strings shouldn't be printed */ - "UPA devices", /* 2 */ - "UPA Port A device", /* 3 */ - "UPA Port B device", /* 4 */ - "Software error", /* 5 */ - "Address Controller", /* 6 */ - "Undetermined Address Controller in system", /* 7 */ - "Data Tags", /* 8 */ - "Data Tags for UPA Port A", /* 9 */ - "Data Tags for UPA Port B", /* 10 */ - "Firehose Controller", /* 11 */ - "This Board", /* 12 */ - "Undetermined Board in system", /* 13 */ - "Board Connector", /* 14 */ - "Centerplane pins ", /* 15 */ - "Centerplane terminators", /* 16 */ - "CPU", /* 17 */ -}; - -/* Ecache parity error messages. Tells which bits are bad. */ -static char *ecache_parity[] = { - "Bits 7:0 ", - "Bits 15:8 ", - "Bits 21:16 ", - "Bits 24:22 " -}; - - -struct ac_error { - char *error; - int part[MAX_PARTS]; -}; - -typedef struct ac_error ac_err; - -/* - * Hardware error register meanings, failed parts and FRUs. The - * following strings are indexed for the bit positions of the - * corresponding bits in the hardware. The code checks bit x of - * the hardware error register and prints out string[x] if the bit - * is turned on. - * - * This database of parts which are probably failed and which FRU's - * to replace was based on knowledge of the Sunfire Programmers Spec. - * and discussions with the hardware designers. The order of the part - * lists and consequently the FRU lists are in the order of most - * likely cause first. - */ -static ac_err ac_errors[] = { - { /* 0 */ - "UPA Port A Error", - { UPA_A_PART, 0, 0, 0, 0 }, - }, - { /* 1 */ - "UPA Port B Error", - { UPA_B_PART, 0, 0, 0, 0 }, - }, - { /* 2 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 3 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 4 */ - "UPA Interrupt to unmapped destination", - { BOARD_PART, 0, 0, 0, 0 }, - }, - { /* 5 */ - "UPA Non-cacheable write to unmapped destination", - { BOARD_PART, 0, 0, 0, 0 }, - }, - { /* 6 */ - "UPA Cacheable write to unmapped destination", - { BOARD_PART, 0, 0, 0, 0 }, - }, - { /* 7 */ - "Illegal Write Received", - { BOARD_PART, 0, 0, 0, 0 }, - }, - { /* 8 */ - "Local Writeback match with line in state S", - { AC_PART, DTAG_PART, 0, 0, 0 }, - }, - { /* 9 */ - "Local Read match with valid line in Tags", - { AC_PART, DTAG_PART, 0, 0, 0 }, - }, - { /* 10 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 11 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 12 */ - "Tag and Victim were valid during lookup", - { AC_PART, DTAG_PART, 0, 0, 0 }, - }, - { /* 13 */ - "Local Writeback matches a victim in state S", - { AC_PART, CPU_PART, 0, 0, 0 }, - }, - { /* 14 */ - "Local Read matches valid line in victim buffer", - { AC_PART, CPU_PART, 0, 0, 0 }, - }, - { /* 15 */ - "Local Read victim bit set and victim is S state", - { AC_PART, CPU_PART, 0, 0, 0 }, - }, - { /* 16 */ - "Local Read Victim bit set and Valid Victim Buffer", - { AC_PART, CPU_PART, 0, 0, 0 }, - }, - { /* 17 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 18 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 19 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 20 */ - "UPA Transaction received in Sleep mode", - { AC_PART, 0, 0, 0, 0 }, - }, - { /* 21 */ - "P_FERR error P_REPLY received from UPA Port", - { CPU_PART, AC_PART, 0, 0, 0 }, - }, - { /* 22 */ - "Illegal P_REPLY received from UPA Port", - { CPU_PART, AC_PART, 0, 0, 0 }, - }, - { /* 23 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 24 */ - "Timeout on a UPA Master Port", - { AC_ANY_PART, BOARD_ANY_PART, 0, 0, 0 }, - }, - { /* 25 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 26 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 27 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 28 */ - "Coherent Transactions Queue Overflow Error", - { BACK_PIN_PART, BOARD_CONN_PART, AC_PART, AC_ANY_PART, 0 }, - }, - { /* 29 */ - "Non-cacheable Request Queue Overflow Error", - { AC_PART, AC_ANY_PART, 0, 0, 0 }, - }, - { /* 30 */ - "Non-cacheable Reply Queue Overflow Error", - { AC_PART, 0, 0, 0, 0 }, - }, - { /* 31 */ - "PREQ Queue Overflow Error", - { CPU_PART, AC_PART, 0, 0, 0 }, - }, - { /* 32 */ - "Foreign DID CAM Overflow Error", - { AC_PART, AC_ANY_PART, 0, 0, 0 }, - }, - { /* 33 */ - "FT->UPA Queue Overflow Error", - { BACK_PIN_PART, BOARD_CONN_PART, AC_PART, AC_ANY_PART, 0 }, - }, - { /* 34 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 35 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 36 */ - "UPA Port B Dtag Parity Error", - { DTAG_B_PART, AC_PART, 0, 0, 0 }, - }, - { /* 37 */ - "UPA Port A Dtag Parity Error", - { DTAG_A_PART, AC_PART, 0, 0, 0 }, - }, - { /* 38 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 39 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 40 */ - "UPA Bus Parity Error", - { UPA_PART, AC_PART, 0, 0, 0 }, - }, - { /* 41 */ - "Data ID Line Mismatch", - { BACK_PIN_PART, BOARD_CONN_PART, AC_PART, 0, 0 }, - }, - { /* 42 */ - "Arbitration Line Mismatch", - { BACK_PIN_PART, BOARD_CONN_PART, AC_PART, 0, 0 }, - }, - { /* 43 */ - "Shared Line Parity Mismatch", - { BACK_PIN_PART, BOARD_CONN_PART, AC_PART, 0, 0 }, - }, - { /* 44 */ - "FireTruck Control Line Parity Error", - { AC_PART, BACK_PIN_PART, 0, 0, 0 }, - }, - { /* 45 */ - "FireTruck Address Bus Parity Error", - { AC_PART, BACK_PIN_PART, 0, 0, 0 }, - }, - { /* 46 */ - "Internal RAM Parity Error", - { AC_PART, 0, 0, 0, 0 }, - }, - { /* 47 */ - NULL, - { RSVD_PART, 0, 0, 0, 0 }, - }, - { /* 48 */ - "Internal Hardware Error", - { AC_PART, 0, 0, 0, 0 }, - }, - { /* 49 */ - "FHC Communications Error", - { FHC_PART, AC_PART, 0, 0, 0 }, - }, - /* Bits 50-63 are reserved in this implementation. */ -}; - - -#define MAX_BITS (sizeof (ac_errors)/ sizeof (ac_err)) - -/* - * There are only two error bits in the DC shadow chain that are - * important. They indicate an overflow error and a parity error, - * respectively. The other bits are not error bits and should not - * be checked for. - */ -#define DC_OVERFLOW 0x2 -#define DC_PARITY 0x4 - -static char dc_overflow_txt[] = "Board %d DC %d Overflow Error"; -static char dc_parity_txt[] = "Board %d DC %d Parity Error"; - -/* defines for the sysio */ -#define UPA_APERR 0x4 - -int -error_check(Sys_tree *tree, struct system_kstat_data *kstats) -{ - int exit_code = 0; /* init to all OK */ - - /* - * silently check for any types of machine errors - */ - print_flag = 0; - if (disp_fail_parts(tree) || disp_fault_list(tree, kstats) || - disp_err_log(kstats) || disp_env_status(kstats)) { - /* set exit_code to show failures */ - exit_code = 1; - } - print_flag = 1; - - return (exit_code); -} - -/* - * disp_fail_parts - * - * Display the failed parts in the system. This function looks for - * the status property in all PROM nodes. On systems where - * the PROM does not supports passing diagnostic information - * thruogh the device tree, this routine will be silent. - */ -int -disp_fail_parts(Sys_tree *tree) -{ - int exit_code; - int system_failed = 0; - Board_node *bnode = tree->bd_list; - Prom_node *pnode; - - exit_code = 0; - - /* go through all of the boards looking for failed units. */ - while (bnode != NULL) { - /* find failed chips */ - pnode = find_failed_node(bnode->nodes); - if ((pnode != NULL) && !system_failed) { - system_failed = 1; - exit_code = 1; - if (print_flag == 0) { - return (exit_code); - } - log_printf("\n", 0); - log_printf(dgettext(TEXT_DOMAIN, - "Failed Field Replaceable Units (FRU) " - "in System:\n"), 0); - log_printf("==========================" - "====================\n", 0); - } - - while (pnode != NULL) { - void *value; - char *name; /* node name string */ - char *type; /* node type string */ - char *board_type = NULL; - - value = get_prop_val(find_prop(pnode, "status")); - name = get_node_name(pnode); - - /* sanity check of data retreived from PROM */ - if ((value == NULL) || (name == NULL)) { - pnode = next_failed_node(pnode); - continue; - } - - /* Find the board type of this board */ - if (bnode->board_type == CPU_BOARD) { - board_type = "CPU"; - } else { - board_type = "IO"; - } - - log_printf(dgettext(TEXT_DOMAIN, - "%s unavailable on %s Board #%d\n"), - name, board_type, bnode->board_num, 0); - - log_printf(dgettext(TEXT_DOMAIN, - "\tPROM fault string: %s\n"), value, 0); - - log_printf(dgettext(TEXT_DOMAIN, - "\tFailed Field Replaceable Unit is "), 0); - - /* - * Determine whether FRU is CPU module, system - * board, or SBus card. - */ - if ((name != NULL) && (strstr(name, "sbus"))) { - - log_printf(dgettext(TEXT_DOMAIN, - "SBus Card %d\n"), - get_sbus_slot(pnode), 0); - - } else if (((name = get_node_name(pnode->parent)) != - NULL) && (strstr(name, "pci"))) { - - log_printf(dgettext(TEXT_DOMAIN, - "PCI Card %d"), - get_pci_device(pnode), 0); - - } else if (((type = get_node_type(pnode)) != NULL) && - (strstr(type, "cpu"))) { - - log_printf(dgettext(TEXT_DOMAIN, - "UltraSPARC module " - "Board %d Module %d\n"), - get_id(pnode) >> 1, - get_id(pnode) & 0x1); - - } else { - log_printf(dgettext(TEXT_DOMAIN, - "%s board %d\n"), board_type, - bnode->board_num, 0); - } - pnode = next_failed_node(pnode); - } - bnode = bnode->next; - } - - if (!system_failed) { - log_printf("\n", 0); - log_printf(dgettext(TEXT_DOMAIN, - "No failures found in System\n"), 0); - log_printf("===========================\n", 0); - } - - if (system_failed) - return (1); - else - return (0); -} - -void -display_memorysize(Sys_tree *tree, struct system_kstat_data *kstats, - struct grp_info *grps, struct mem_total *memory_total) { - - /* Build the memory group tables and interleave data */ - build_mem_tables(tree, kstats, grps); - - /* display total usable installed memory */ - get_mem_total(memory_total, grps); - (void) log_printf(dgettext(TEXT_DOMAIN, - "Memory size: %4dMb\n"), memory_total->dram, 0); - - /* We display the NVSIMM size totals separately. */ - if (memory_total->nvsimm != 0) { - (void) log_printf(dgettext(TEXT_DOMAIN, - "NVSIMM size: %4dMb\n"), memory_total->nvsimm); - } -} - -/* - * This routine displays the memory configuration for all boards in the - * system. - */ -void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) -{ - int group; - char *status_str[] = { "Unknown", " Empty ", " Failed", " Active", - " Spare " }; - char *cond_str[] = { " Unknown ", " OK ", " Failing ", - " Failed ", " Uninit. " }; - -#ifdef lint - tree = tree; -#endif - /* Print the header for the memory section. */ - log_printf("\n", 0); - log_printf("=========================", 0); - log_printf(dgettext(TEXT_DOMAIN, " Memory "), 0); - log_printf("=========================", 0); - log_printf("\n", 0); - log_printf("\n", 0); - log_printf(" Intrlv. " - "Intrlv.\n", 0); - log_printf("Brd Bank MB Status Condition Speed Factor " - " With\n", 0); - log_printf("--- ----- ---- ------- ---------- ----- ------- " - "-------\n", 0); - - /* Print the Memory groups information. */ - for (group = 0; group < MAX_GROUPS; group++) { - struct grp *grp; - - grp = &grps->grp[group]; - - /* If this board is not a CPU or MEM board, skip it. */ - if ((grp->type != MEM_BOARD) && (grp->type != CPU_BOARD)) { - continue; - } - - if (grp->valid) { - log_printf("%2d ", grp->board, 0); - log_printf(" %1d ", grp->group, 0); - log_printf("%4d ", grp->size, 0); - log_printf("%7s ", status_str[grp->status], 0); - log_printf("%10s ", cond_str[grp->condition], 0); - log_printf("%3dns ", grp->speed, 0); - log_printf("%3d-way ", grp->factor, 0); - if (grp->factor > 1) { - log_printf("%4c", grp->groupid, 0); - } - log_printf("\n", 0); - } - } - -} - - -void -display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats) -{ - /* Display Hot plugged, disabled and failed boards */ - (void) display_hp_boards(kstats); - - /* Display failed units */ - (void) disp_fail_parts(tree); - - /* Display fault info */ - (void) disp_fault_list(tree, kstats); -} - -void -display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, - struct system_kstat_data *kstats) -{ - /* - * Now display the last powerfail time and the fatal hardware - * reset information. We do this under a couple of conditions. - * First if the user asks for it. The second is iof the user - * told us to do logging, and we found a system failure. - */ - if (flag) { - /* - * display time of latest powerfail. Not all systems - * have this capability. For those that do not, this - * is just a no-op. - */ - disp_powerfail(root); - - /* Display system environmental conditions. */ - (void) disp_env_status(kstats); - - /* Display ASIC Chip revs for all boards. */ - sunfire_disp_asic_revs(tree, kstats); - - /* Print the PROM revisions here */ - sunfire_disp_prom_versions(tree); - - /* - * Display the latest system fatal hardware - * error data, if any. The system holds this - * data in SRAM, so it does not persist - * across power-on resets. - */ - (void) disp_err_log(kstats); - } -} - -void -display_mid(int mid) -{ - log_printf(" %2d ", mid % 2, 0); -} - -/* - * display_pci - * Call the generic psycho version of this function. - */ -void -display_pci(Board_node *board) -{ - display_psycho_pci(board); -} - -/* - * display_ffb - * Display all FFBs on this board. It can either be in tabular format, - * or a more verbose format. - */ -void -display_ffb(Board_node *board, int table) -{ - Prom_node *ffb; - void *value; - struct io_card *card_list = NULL; - struct io_card card; - - if (board == NULL) - return; - - /* Fill in common information */ - card.display = 1; - card.board = board->board_num; - (void) sprintf(card.bus_type, "UPA"); - card.freq = sys_clk; - - for (ffb = dev_find_node(board->nodes, FFB_NAME); ffb != NULL; - ffb = dev_next_node(ffb, FFB_NAME)) { - if (table == 1) { - /* Print out in table format */ - - /* XXX - Get the slot number (hack) */ - card.slot = get_id(ffb); - - /* Find out if it's single or double buffered */ - (void) sprintf(card.name, "FFB"); - value = get_prop_val(find_prop(ffb, "board_type")); - if (value != NULL) - if ((*(int *)value) & FFB_B_BUFF) - (void) sprintf(card.name, "FFB, " - "Double Buffered"); - else - (void) sprintf(card.name, "FFB, " - "Single Buffered"); - - /* Print model number */ - card.model[0] = '\0'; - value = get_prop_val(find_prop(ffb, "model")); - if (value != NULL) - (void) sprintf(card.model, "%s", - (char *)value); - - card_list = insert_io_card(card_list, &card); - } else { - /* print in long format */ - char device[MAXSTRLEN]; - int fd = -1; - struct dirent *direntp; - DIR *dirp; - union strap_un strap; - struct ffb_sys_info fsi; - - /* Find the device node using upa address */ - value = get_prop_val(find_prop(ffb, "upa-portid")); - if (value == NULL) - continue; - - (void) sprintf(device, "%s@%x", FFB_NAME, - *(int *)value); - if ((dirp = opendir("/devices")) == NULL) - continue; - - while ((direntp = readdir(dirp)) != NULL) { - if (strstr(direntp->d_name, device) != NULL) { - (void) sprintf(device, "/devices/%s", - direntp->d_name); - fd = open(device, O_RDWR, 0666); - break; - } - } - (void) closedir(dirp); - - if (fd == -1) - continue; - - if (ioctl(fd, FFB_SYS_INFO, &fsi) < 0) - continue; - - log_printf("Board %d FFB Hardware Configuration:\n", - board->board_num, 0); - log_printf("-----------------------------------\n", 0); - - strap.ffb_strap_bits = fsi.ffb_strap_bits; - log_printf("\tBoard rev: %d\n", - (int)strap.fld.board_rev, 0); - log_printf("\tFBC version: 0x%x\n", fsi.fbc_version, 0); - log_printf("\tDAC: %s\n", - fmt_manf_id(fsi.dac_version, device), 0); - log_printf("\t3DRAM: %s\n", - fmt_manf_id(fsi.fbram_version, device), 0); - log_printf("\n", 0); - } - } - - display_io_cards(card_list); - free_io_cards(card_list); -} - -/* - * add_node - * - * This function adds a board node to the board structure where that - * that node's physical component lives. - */ -void -add_node(Sys_tree *root, Prom_node *pnode) -{ - int board; - Board_node *bnode; - char *name = get_node_name(pnode); - Prom_node *p; - - /* add this node to the Board list of the appropriate board */ - if ((board = get_board_num(pnode)) == -1) { - void *value; - - /* - * if it is a server, pci nodes and ffb nodes never have - * board number properties and software can find the board - * number from the reg property. It is derived from the - * high word of the 'reg' property, which contains the - * mid. - */ - if ((name != NULL) && - ((strcmp(name, FFB_NAME) == 0) || - (strcmp(name, "pci") == 0) || - (strcmp(name, "counter-timer") == 0))) { - /* extract the board number from the 'reg' prop. */ - if ((value = get_prop_val(find_prop(pnode, - "reg"))) == NULL) { - (void) printf("add_node() no reg property\n"); - exit(2); - } - board = (*(int *)value - 0x1c0) / 4; - } - } - - /* find the node with the same board number */ - if ((bnode = find_board(root, board)) == NULL) { - bnode = insert_board(root, board); - bnode->board_type = UNKNOWN_BOARD; - } - - /* now attach this prom node to the board list */ - /* Insert this node at the end of the list */ - pnode->sibling = NULL; - if (bnode->nodes == NULL) - bnode->nodes = pnode; - else { - p = bnode->nodes; - while (p->sibling != NULL) - p = p->sibling; - p->sibling = pnode; - } - -} - -/* - * Function resolve_board_types - * - * After the tree is walked and all the information is gathered, this - * function is called to resolve the type of each board. - */ -void -resolve_board_types(Sys_tree *tree) -{ - Board_node *bnode; - Prom_node *pnode; - char *type; - - bnode = tree->bd_list; - while (bnode != NULL) { - bnode->board_type = UNKNOWN_BOARD; - - pnode = dev_find_node(bnode->nodes, "fhc"); - type = get_prop_val(find_prop(pnode, "board-type")); - if (type == NULL) { - bnode = bnode->next; - continue; - } - - if (strcmp(type, CPU_BD_NAME) == 0) { - bnode->board_type = CPU_BOARD; - } else if (strcmp(type, MEM_BD_NAME) == 0) { - bnode->board_type = MEM_BOARD; - } else if (strcmp(type, DISK_BD_NAME) == 0) { - bnode->board_type = DISK_BOARD; - } else if (strcmp(type, IO_SBUS_FFB_BD_NAME) == 0) { - bnode->board_type = IO_SBUS_FFB_BOARD; - } else if (strcmp(type, IO_2SBUS_BD_NAME) == 0) { - bnode->board_type = IO_2SBUS_BOARD; - } else if (strcmp(type, IO_PCI_BD_NAME) == 0) { - bnode->board_type = IO_PCI_BOARD; - } else if (strcmp(type, IO_2SBUS_SOCPLUS_BD_NAME) == 0) { - bnode->board_type = IO_2SBUS_SOCPLUS_BOARD; - } else if (strcmp(type, IO_SBUS_FFB_SOCPLUS_BD_NAME) == 0) { - bnode->board_type = IO_SBUS_FFB_SOCPLUS_BOARD; - } - - bnode = bnode->next; - } - -} - -/* - * local functions - */ - -static void -sunfire_disp_prom_versions(Sys_tree *tree) -{ - Board_node *bnode; - - /* Display Prom revision header */ - log_printf("System Board PROM revisions:\n", 0); - log_printf("----------------------------\n", 0); - - /* For each board, print the POST and OBP versions */ - for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) { - Prom_node *flashprom; /* flashprom device node */ - - /* find a flashprom node for this board */ - flashprom = dev_find_node(bnode->nodes, "flashprom"); - - /* If no flashprom node found, continue */ - if (flashprom == NULL) - continue; - - /* flashprom node found, display board# */ - log_printf("Board %2d: ", bnode->board_num, 0); - - disp_prom_version(flashprom); - } -} - - -/* - * functions that are only needed inside this library - */ - -/* - * build_mem_tables - * - * This routine builds the memory table which tells how much memory - * is present in each SIMM group of each board, what the interleave - * factors are, and the group ID of the interleave group. - * - * The algorithms used are: - * First fill in the sizes of groups. - * Next build lists of all groups with same physical base. - * From #of members in each list, interleave factor is - * determined. - * All members of a certain list get the same interleave - * group ID. - */ -static void -build_mem_tables(Sys_tree *tree, - struct system_kstat_data *kstats, - struct grp_info *grps) -{ - struct mem_inter inter_grps; /* temp structure for interleaves */ - struct inter_grp *intrp; - int group; - int i; - - /* initialize the interleave lists */ - for (i = 0, intrp = &inter_grps.i_grp[0]; i < MAX_GROUPS; i++, - intrp++) { - intrp->valid = 0; - intrp->count = 0; - intrp->groupid = '\0'; - intrp->base = 0; - } - - for (group = 0; group < MAX_GROUPS; group++) { - int found; - int board; - struct grp *grp; - struct bd_kstat_data *bksp; - uchar_t simm_reg; - Board_node *bnode; - - board = group/2; - bksp = &kstats->bd_ksp_list[board]; - grp = &grps->grp[group]; - grp->group = group % 2; - - /* - * Copy the board type field into the group record. - */ - if ((bnode = find_board(tree, board)) != NULL) { - grp->type = bnode->board_type; - } else { - grp->type = UNKNOWN_BOARD; - continue; - } - - /* Make sure we have kstats for this board */ - if (bksp->ac_kstats_ok == 0) { - /* Mark this group as invalid and move to next one */ - grp->valid = 0; - continue; - } - - /* Find the bank status property */ - if (bksp->ac_memstat_ok) { - grp->status = bksp->mem_stat[grp->group].status; - grp->condition = bksp->mem_stat[grp->group].condition; - } else { - grp->status = StUnknown; - grp->condition = ConUnknown; - } - - switch (grp->status) { - case StBad: - case StActive: - case StSpare: - break; - default: - grp->status = StUnknown; - break; - } - - switch (grp->condition) { - case ConOK: - case ConFailing: - case ConFailed: - case ConTest: - case ConBad: - break; - default: - grp->condition = ConUnknown; - break; - } - - /* base the group size off of the simmstat kstat. */ - if (bksp->simmstat_kstats_ok == 0) { - grp->valid = 0; - continue; - } - - /* Is it bank 0 or bank 1 */ - if (grp->group == 0) { - simm_reg = bksp->simm_status[0]; - } else { - simm_reg = bksp->simm_status[1]; - } - - /* Now decode the size field. */ - switch (simm_reg & 0x1f) { - case MEM_SIZE_64M: - grp->size = 64; - break; - case MEM_SIZE_256M: - grp->size = 256; - break; - case MEM_SIZE_1G: - grp->size = 1024; - break; - case MEM_SIZE_2G: - grp->size = 2048; - break; - default: - grp->valid = 0; - continue; - } - - /* Decode the speed field */ - switch ((simm_reg & 0x60) >> 5) { - case MEM_SPEED_50ns: - grp->speed = 50; - break; - case MEM_SPEED_60ns: - grp->speed = 60; - break; - case MEM_SPEED_70ns: - grp->speed = 70; - break; - case MEM_SPEED_80ns: - grp->speed = 80; - break; - } - - grp->valid = 1; - grp->base = GRP_BASE(bksp->ac_memdecode[grp->group]); - grp->board = board; - if (grp->group == 0) { - grp->factor = INTLV0(bksp->ac_memctl); - } else { /* assume it is group 1 */ - grp->factor = INTLV1(bksp->ac_memctl); - } - grp->groupid = '\0'; /* Not in a group yet */ - - /* - * find the interleave list this group belongs on. If the - * interleave list corresponding to this base address is - * not found, then create a new one. - */ - - i = 0; - intrp = &inter_grps.i_grp[0]; - found = 0; - while ((i < MAX_GROUPS) && !found && (intrp->valid != 0)) { - if ((intrp->valid != 0) && - (intrp->base == grp->base)) { - grp->groupid = intrp->groupid; - intrp->count++; - found = 1; - } - i++; - intrp++; - } - /* - * We did not find a matching base. So now i and intrp - * now point to the next interleave group in the list. - */ - if (!found) { - intrp->count++; - intrp->valid = 1; - intrp->groupid = 'A' + (char)i; - intrp->base = grp->base; - grp->groupid = intrp->groupid; - } - } -} - - -static void -get_mem_total(struct mem_total *mem_total, struct grp_info *grps) -{ - struct grp *grp; - int i; - - /* Start with total of zero */ - mem_total->dram = 0; - mem_total->nvsimm = 0; - - /* For now we ignore NVSIMMs. We might want to fix this later. */ - for (i = 0, grp = &grps->grp[0]; i < MAX_GROUPS; i++, grp++) { - if (grp->valid == 1 && grp->status == StActive) { - mem_total->dram += grp->size; - } - } -} - -static int -disp_fault_list(Sys_tree *tree, struct system_kstat_data *kstats) -{ - struct ft_list *ftp; - int i; - int result = 0; - time_t t; - - if (!kstats->ft_kstat_ok) { - return (result); - } - - for (i = 0, ftp = kstats->ft_array; i < kstats->nfaults; i++, ftp++) { - if (!result) { - log_printf("\n", 0); - log_printf("Detected System Faults\n", 0); - log_printf("======================\n", 0); - } - result = 1; - if (ftp->fclass == FT_BOARD) { - log_printf("Board %d fault: %s\n", ftp->unit, - ftp->msg, 0); - - /* - * If the fault on this board is PROM inherited, see - * if we can find some failed component information - * in the PROM device tree. The general solution - * would be to fix the fhc driver and have it put in - * more descriptive messages, but that's for another - * day. - */ - - if (ftp->type == FT_PROM) { - Board_node *bn; - Prom_node *pn; - char *str; - - bn = find_board(tree, ftp->unit); - /* - * If any nodes under this board have a - * status containing "fail", print it out. - */ - pn = find_failed_node(bn->nodes); - while (pn) { - str = get_prop_val(find_prop(pn, - "status")); - if (str != NULL) { - log_printf("Fault: %s\n", str, - 0); - } - - pn = next_failed_node(pn); - } - } - } else if ((ftp->type == FT_CORE_PS) || (ftp->type == FT_PPS)) { - log_printf("Unit %d %s failure\n", ftp->unit, - ftp->msg, 0); - } else if ((ftp->type == FT_OVERTEMP) && - (ftp->fclass == FT_SYSTEM)) { - log_printf("Clock board %s\n", ftp->msg, 0); - } else { - log_printf("%s failure\n", ftp->msg, 0); - } - - t = (time_t)ftp->create_time; - log_printf("\tDetected %s", - asctime(localtime(&t)), 0); - } - - if (!result) { - log_printf("\n", 0); - log_printf("No System Faults found\n", 0); - log_printf("======================\n", 0); - } - - log_printf("\n", 0); - - return (result); -} - - -/* - * disp_err_log - * - * Display the fatal hardware reset system error logs. These logs are - * collected by POST and passed up through the kernel to userland. - * They will not necessarily be present in all systems. Their form - * might also be different in different systems. - * - * NOTE - We are comparing POST defined board types here. Do not confuse - * them with kernel board types. The structure being analyzed in this - * function is created by POST. All the defines for it are in reset_info.h, - * which was ported from POST header files. - */ -static int -disp_err_log(struct system_kstat_data *kstats) -{ - int exit_code = 0; - int i; - struct reset_info *rst_info; - struct board_info *bdp; - char *err_msgs[MAX_MSGS]; /* holds all messages for a system board */ - int msg_idx; /* current msg number */ - int count; /* number added by last analyze call */ - char **msgs; - - /* start by initializing the err_msgs array to all NULLs */ - for (i = 0; i < MAX_MSGS; i++) { - err_msgs[i] = NULL; - } - - /* First check to see that the reset-info kstats are present. */ - if (kstats->reset_kstats_ok == 0) { - return (exit_code); - } - - rst_info = &kstats->reset_info; - - /* Everything is OK, so print out time/date stamp first */ - log_printf("\n", 0); - log_printf( - dgettext(TEXT_DOMAIN, - "Analysis of most recent Fatal Hardware Watchdog:\n"), - 0); - log_printf("======================================================\n", - 0); - log_printf("Log Date: %s\n", - get_time(&kstats->reset_info.tod_timestamp[0]), 0); - - /* initialize the vector and the message index. */ - msgs = err_msgs; - msg_idx = 0; - - /* Loop Through all of the boards. */ - bdp = &rst_info->bd_reset_info[0]; - for (i = 0; i < MAX_BOARDS; i++, bdp++) { - - /* Is there data for this board? */ - if ((bdp->board_desc & BD_STATE_MASK) == BD_NOT_PRESENT) { - continue; - } - - /* If it is a CPU Board, look for CPU data. */ - if (BOARD_TYPE(bdp->board_desc) == CPU_TYPE) { - /* analyze CPU 0 if present */ - if (bdp->board_desc & CPU0_OK) { - count = analyze_cpu(msgs, 0, - bdp->cpu[0].afsr); - msgs += count; - msg_idx += count; - } - - /* analyze CPU1 if present. */ - if (bdp->board_desc & CPU1_OK) { - count = analyze_cpu(msgs, 1, - bdp->cpu[1].afsr); - msgs += count; - msg_idx += count; - } - } - - /* Always Analyze the AC and the DCs on a board. */ - count = analyze_ac(msgs, bdp->ac_error_status); - msgs += count; - msg_idx += count; - - count = analyze_dc(i, msgs, bdp->dc_shadow_chain); - msgs += count; - msg_idx += count; - - if (msg_idx != 0) - display_msgs(err_msgs, i); - - erase_msgs(err_msgs); - - /* If any messages are logged, we have errors */ - if (msg_idx != 0) { - exit_code = 1; - } - - /* reset the vector and the message index */ - msg_idx = 0; - msgs = &err_msgs[0]; - } - - return (exit_code); -} - -static void -erase_msgs(char **msgs) -{ - int i; - - for (i = 0; (*msgs != NULL) && (i < MAX_MSGS); i++, msgs++) { - free(*msgs); - *msgs = NULL; - } -} - - -static void -display_msgs(char **msgs, int board) -{ - int i; - - /* display the header for this board */ - print_header(board); - - for (i = 0; (*msgs != NULL) && (i < MAX_MSGS); i++, msgs++) { - log_printf(*msgs, 0); - } -} - - - -/* - * disp_keysw_and_leds - * - * This routine displays the position of the keyswitch and the front panel - * system LEDs. The keyswitch can be in either normal, diagnostic, or - * secure position. The three front panel LEDs are of importance because - * the center LED indicates component failure on the system. - */ -static int -disp_keysw_and_leds(struct system_kstat_data *kstats) -{ - int board; - int diag_mode = 0; - int secure_mode = 0; - int result = 0; - - /* Check the first valid board to determeine the diag bit */ - /* Find the first valid board */ - for (board = 0; board < MAX_BOARDS; board++) { - if (kstats->bd_ksp_list[board].fhc_kstats_ok != 0) { - /* If this was successful, break out of loop */ - if ((kstats->bd_ksp_list[board].fhc_bsr & - FHC_DIAG_MODE) == 0) - diag_mode = 1; - break; - } - } - - /* - * Check the register on the clock-board to determine the - * secure bit. - */ - if (kstats->sys_kstats_ok) { - /* The secure bit is negative logic. */ - if (kstats->keysw_status == KEY_SECURE) { - secure_mode = 1; - } - } - - /* - * The system cannot be in diag and secure mode. This is - * illegal. - */ - if (secure_mode && diag_mode) { - result = 2; - return (result); - } - - /* Now print the keyswitch position. */ - log_printf("Keyswitch position is in ", 0); - - if (diag_mode) { - log_printf("Diagnostic Mode\n"); - } else if (secure_mode) { - log_printf("Secure Mode\n", 0); - } else { - log_printf("Normal Mode\n"); - } - - /* display the redundant power status */ - if (kstats->sys_kstats_ok) { - log_printf("System Power Status: ", 0); - - switch (kstats->power_state) { - case REDUNDANT: - log_printf("Redundant\n", 0); - break; - - case MINIMUM: - log_printf("Minimum Available\n", 0); - break; - - case BELOW_MINIMUM: - log_printf("Insufficient Power Available\n", 0); - break; - - default: - log_printf("Unknown\n", 0); - break; - } - } - - if (kstats->sys_kstats_ok) { - /* - * If the center LED is on, then we return a non-zero - * result. - */ - log_printf("System LED Status: GREEN YELLOW " - "GREEN\n", 0); - if ((kstats->sysctrl & SYS_LED_MID) != 0) { - log_printf("WARNING ", 0); - } else { - log_printf("Normal ", 0); - } - - /* - * Left LED is negative logic, center and right LEDs - * are positive logic. - */ - if ((kstats->sysctrl & SYS_LED_LEFT) == 0) { - log_printf("ON ", 0); - } else { - log_printf("OFF", 0); - } - - log_printf(" ", 0); - if ((kstats->sysctrl & SYS_LED_MID) != 0) { - log_printf("ON ", 0); - } else { - log_printf("OFF", 0); - } - - log_printf(" BLINKING", 0); - } - - log_printf("\n", 0); - return (result); -} - -/* - * disp_env_status - * - * This routine displays the environmental status passed up from - * device drivers via kstats. The kstat names are defined in - * kernel header files included by this module. - */ -static int -disp_env_status(struct system_kstat_data *kstats) -{ - struct bd_kstat_data *bksp; - int exit_code = 0; - int i; - uchar_t curr_temp; - int is4slot = 0; - - /* - * Define some message arrays to make life simpler. These - * messages correspond to definitions in <sys/fhc.c> for - * temperature trend (enum temp_trend) and temperature state - * (enum temp_state). - */ - static char *temp_trend_msg[] = { "unknown", - "rapidly falling", - "falling", - "stable", - "rising", - "rapidly rising", - "unknown (noisy)" - }; - static char *temp_state_msg[] = { " OK ", - "WARNING ", - " DANGER " - }; - - log_printf("\n", 0); - log_printf("=========================", 0); - log_printf(dgettext(TEXT_DOMAIN, " Environmental Status "), 0); - log_printf("=========================", 0); - log_printf("\n", 0); - - exit_code = disp_keysw_and_leds(kstats); - - if (!kstats->sys_kstats_ok) { - log_printf(dgettext(TEXT_DOMAIN, - "*** Error: Unavailable ***\n\n")); - return (1); - } - - /* - * for purposes within this routine, - * 5 slot behaves the same as a 4 slot - */ - if (SYS_TYPE(kstats->sysstat1) == SYS_4_SLOT) - is4slot = 1; - - log_printf("\n", 0); - log_printf("\nFans:\n", 0); - log_printf("-----\n", 0); - - log_printf("Unit Status\n", 0); - log_printf("---- ------\n", 0); - - log_printf("%-4s ", is4slot ? "Disk" : "Rack", 0); - /* Check the status of the Rack Fans */ - if ((kstats->fan_status & SYS_RACK_FANFAIL) == 0) { - log_printf("OK\n", 0); - } else { - log_printf("FAIL\n", 0); - exit_code = 1; - } - - if (!is4slot) { - /* - * keyswitch and ac box are on 8 & 16 slot only - */ - /* Check the status of the Keyswitch Fan assembly. */ - log_printf("%-4s ", "Key", 0); - if ((kstats->fan_status & SYS_KEYSW_FAN_OK) != 0) { - log_printf("OK\n", 0); - } else { - log_printf("FAIL\n", 0); - exit_code = 1; - } - - log_printf("%-4s ", "AC", 0); - if ((kstats->fan_status & SYS_AC_FAN_OK) != 0) { - log_printf("OK\n", 0); - } else { - log_printf("FAIL\n", 0); - exit_code = 1; - } - } else { - /* - * peripheral fan is on 4 slot only - * XXX might want to indicate transient states too - */ - if (kstats->psstat_kstat_ok) { - if (kstats->ps_shadow[SYS_P_FAN_INDEX] == PS_OK) { - log_printf("PPS OK\n", 0); - } else if (kstats->ps_shadow[SYS_P_FAN_INDEX] == - PS_FAIL) { - log_printf("PPS FAIL\n", 0); - exit_code = 1; - } - } - } - - log_printf("\n", 0); - - - log_printf("System Temperatures (Celsius):\n", 0); - log_printf("------------------------------\n", 0); - log_printf("Brd State Current Min Max Trend\n", 0); - log_printf("--- ------- ------- --- --- -----\n", 0); - - for (i = 0, bksp = &kstats->bd_ksp_list[0]; i < MAX_BOARDS; - i++, bksp++) { - - /* Make sure we have kstats for this board first */ - if (!bksp->temp_kstat_ok) { - continue; - } - log_printf("%2d ", i, 0); - - /* Print the current state of the temperature */ - log_printf("%s", temp_state_msg[bksp->tempstat.state], 0); - /* Set exit code for WARNING and DANGER */ - if (bksp->tempstat.state != 0) - exit_code = 1; - - /* Print the current temperature */ - curr_temp = bksp->tempstat.l1[bksp->tempstat.index % L1_SZ]; - log_printf(" %2d ", curr_temp, 0); - - /* Print the minimum recorded temperature */ - log_printf(" %2d ", bksp->tempstat.min, 0); - - /* Print the maximum recorded temperature */ - log_printf(" %2d ", bksp->tempstat.max, 0); - - /* Print the current trend in temperature (if available) */ - if (bksp->tempstat.version < 2) - log_printf("unknown\n", 0); - else - log_printf("%s\n", temp_trend_msg[bksp->tempstat.trend], 0); - } - if (kstats->temp_kstat_ok) { - log_printf("CLK ", 0); - - /* Print the current state of the temperature */ - log_printf("%s", temp_state_msg[kstats->tempstat.state], 0); - /* Set exit code for WARNING or DANGER */ - if (kstats->tempstat.state != 0) - exit_code = 1; - - /* Print the current temperature */ - curr_temp = kstats->tempstat.l1[kstats->tempstat.index % L1_SZ]; - log_printf(" %2d ", curr_temp, 0); - - /* Print the minimum recorded temperature */ - log_printf(" %2d ", kstats->tempstat.min, 0); - - /* Print the maximum recorded temperature */ - log_printf(" %2d ", kstats->tempstat.max, 0); - - /* Print the current trend in temperature (if available) */ - if (kstats->tempstat.version < 2) - log_printf("unknown\n\n", 0); - else - log_printf("%s\n\n", - temp_trend_msg[kstats->tempstat.trend], 0); - } else { - log_printf("\n"); - } - - log_printf("\n", 0); - log_printf("Power Supplies:\n", 0); - log_printf("---------------\n", 0); - log_printf("Supply Status\n", 0); - log_printf("--------- ------\n", 0); - if (kstats->psstat_kstat_ok) { - for (i = 0; i < SYS_PS_COUNT; i++) { - char *ps, *state; - - /* skip core power supplies that are not present */ - if (i <= SYS_PPS0_INDEX && kstats->ps_shadow[i] == - PS_OUT) - continue; - - /* Display the unit Number */ - switch (i) { - case 0: ps = "0"; break; - case 1: ps = "1"; break; - case 2: ps = "2"; break; - case 3: ps = "3"; break; - case 4: ps = "4"; break; - case 5: ps = "5"; break; - case 6: ps = "6"; break; - case 7: ps = is4slot ? "2nd PPS" : "7"; break; - - case SYS_PPS0_INDEX: ps = "PPS"; break; - case SYS_CLK_33_INDEX: ps = " System 3.3v"; break; - case SYS_CLK_50_INDEX: ps = " System 5.0v"; break; - case SYS_V5_P_INDEX: ps = " Peripheral 5.0v"; break; - case SYS_V12_P_INDEX: ps = " Peripheral 12v"; break; - case SYS_V5_AUX_INDEX: ps = " Auxiliary 5.0v"; break; - case SYS_V5_P_PCH_INDEX: ps = - " Peripheral 5.0v precharge"; - break; - case SYS_V12_P_PCH_INDEX: ps = - " Peripheral 12v precharge"; - break; - case SYS_V3_PCH_INDEX: ps = - " System 3.3v precharge"; break; - case SYS_V5_PCH_INDEX: ps = - " System 5.0v precharge"; break; - - /* skip the peripheral fan here */ - case SYS_P_FAN_INDEX: - continue; - } - - /* what is the state? */ - switch (kstats->ps_shadow[i]) { - case PS_OK: - state = "OK"; - break; - - case PS_FAIL: - state = "FAIL"; - exit_code = 1; - break; - - /* XXX is this an exit_code condition? */ - case PS_OUT: - state = "PPS Out"; - exit_code = 1; - break; - - case PS_UNKNOWN: - state = "Unknown"; - break; - - default: - state = "Illegal State"; - break; - } - - log_printf("%-32s %s\n", ps, state, 0); - } - } - - /* Check status of the system AC Power Source */ - log_printf("%-32s ", "AC Power", 0); - if ((kstats->sysstat2 & SYS_AC_FAIL) == 0) { - log_printf("OK\n", 0); - } else { - log_printf("failed\n", 0); - exit_code = 1; - } - log_printf("\n", 0); - - return (exit_code); -} - - -/* - * Many of the ASICs present in fusion machines have implementation and - * version numbers stored in the OBP device tree. These codes are displayed - * in this routine in an effort to aid Engineering and Field service - * in detecting old ASICs which may have bugs in them. - */ -static void -sunfire_disp_asic_revs(Sys_tree *tree, struct system_kstat_data *kstats) -{ - Board_node *bnode; - Prom_node *pnode; - int isplusbrd; - char *board_str[] = { "Uninitialized", "Unknown", "CPU", - "Memory", "Dual-SBus", "UPA-SBus", - "Dual-PCI", "Disk", "Clock", - "Dual-SBus-SOC+", "UPA-SBus-SOC+"}; - - /* Print the header */ - log_printf("\n", 0); - log_printf("=========================", 0); - log_printf(" HW Revisions ", 0); - log_printf("=========================", 0); - log_printf("\n", 0); - log_printf("\n", 0); - - /* Else this is a Sunfire or campfire */ - log_printf("ASIC Revisions:\n", 0); - log_printf("---------------\n", 0); - - /* Display Firetruck ASIC Revisions first */ - log_printf("Brd FHC AC SBus0 SBus1 PCI0 PCI1 FEPS", 0); - log_printf(" Board Type Attributes", 0); - log_printf("\n", 0); - log_printf("--- --- -- ----- ----- ---- ---- ----", 0); - log_printf(" ---------- ----------", 0); - log_printf("\n", 0); - - /* - * Display all of the FHC, AC, and chip revisions for the entire - * machine. The AC anf FHC chip revs are available from the device - * tree that was read out of the PROM, but the DC chip revs will be - * read via a kstat. The interfaces for this are not completely - * available at this time. - */ - bnode = tree->bd_list; - while (bnode != NULL) { - int *version; - int upa = bd_to_upa(bnode->board_num); - - /* Display the header with the board number */ - log_printf("%2d ", bnode->board_num, 0); - - /* display the FHC version */ - if ((pnode = dev_find_node(bnode->nodes, "fhc")) == NULL) { - log_printf(" ", 0); - } else { - if ((version = (int *)get_prop_val(find_prop(pnode, - "version#"))) == NULL) { - log_printf(" ", 0); - } else { - log_printf(" %d ", *version, 0); - } - } - - /* display the AC version */ - if ((pnode = dev_find_node(bnode->nodes, "ac")) == NULL) { - log_printf(" ", 0); - } else { - if ((version = (int *)get_prop_val(find_prop(pnode, - "version#"))) == NULL) { - log_printf(" ", 0); - } else { - log_printf(" %d ", *version, 0); - } - } - - /* Find sysio 0 on board and print rev */ - if ((pnode = find_device(bnode, upa, "sbus")) == NULL) { - log_printf(" ", 0); - } else { - if ((version = (int *)get_prop_val(find_prop(pnode, - "version#"))) == NULL) { - log_printf(" ", 0); - } else { - log_printf(" %d ", *version, 0); - } - } - - /* Find sysio 1 on board and print rev */ - if ((pnode = find_device(bnode, upa+1, "sbus")) == NULL) { - log_printf(" ", 0); - } else { - if ((version = (int *)get_prop_val(find_prop(pnode, - "version#"))) == NULL) { - log_printf(" ", 0); - } else { - log_printf(" %d ", *version, 0); - } - } - - /* Find Psycho 0 on board and print rev */ - if ((pnode = find_device(bnode, upa, "pci")) == NULL) { - log_printf(" ", 0); - } else { - if ((version = (int *)get_prop_val(find_prop(pnode, - "version#"))) == NULL) { - log_printf(" ", 0); - } else { - log_printf(" %d ", *version, 0); - } - } - - /* Find Psycho 1 on board and print rev */ - if ((pnode = find_device(bnode, upa+1, "pci")) == NULL) { - log_printf(" ", 0); - } else { - if ((version = (int *)get_prop_val(find_prop(pnode, - "version#"))) == NULL) { - log_printf(" ", 0); - } else { - log_printf(" %d ", *version, 0); - } - } - - /* Find the FEPS on board and print rev */ - if ((pnode = dev_find_node(bnode->nodes, "SUNW,hme")) != NULL) { - if ((version = (int *)get_prop_val(find_prop(pnode, - "hm-rev"))) != NULL) { - if (*version == 0xa0) { - log_printf(" 2.0 ", 0); - } else if (*version == 0x20) { - log_printf(" 2.1 ", 0); - } else { - log_printf(" %2x ", *version, 0); - } - } - } else - log_printf(" ", 0); - - /* print out the board type */ - isplusbrd = ISPLUSBRD(kstats->bd_ksp_list - [bnode->board_num].fhc_bsr); - - log_printf("%-16s", board_str[bnode->board_type], 0); - if (isplusbrd) - log_printf("100MHz Capable", 0); - else - log_printf("84MHz Capable", 0); - - log_printf("\n", 0); - bnode = bnode->next; - } - log_printf("\n", 0); - - /* Now display the FFB board component revisions */ - for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) { - display_ffb(bnode, 0); - } -} - -static void -display_hp_boards(struct system_kstat_data *kstats) -{ - int i; - int j; - int hp_found = 0; - struct hp_info *hp; - char *state; - - for (i = 0, hp = &kstats->hp_info[0]; i < MAX_BOARDS; i++, hp++) { - if (!hp->kstat_ok) { - continue; - } - - hp_found = 1; - } - - /* return if there are no hotplug boards in the system. */ - if (!hp_found) { - return; - } - - if (hp_found != 0) { - log_printf("\n", 0); - log_printf("Detached Boards\n", 0); - log_printf("===============\n", 0); - log_printf(" Slot State Type Info\n", 0); - log_printf(" ---- --------- ------ ----" - "-------------------------------------\n", 0); - } - - /* Display all detached boards */ - for (i = 0, hp = &kstats->hp_info[0]; i < MAX_BOARDS; i++, hp++) { - struct cpu_info *cpu; - - if (hp->kstat_ok == 0) { - continue; - } - - - switch (hp->bd_info.state) { - case UNKNOWN_STATE: - state = "unknown"; - break; - - case ACTIVE_STATE: - state = "active"; - break; - - case LOWPOWER_STATE: - state = "low-power"; - break; - - case HOTPLUG_STATE: - state = "hot-plug"; - break; - - case DISABLED_STATE: - state = "disabled"; - break; - - case FAILED_STATE: - state = "failed"; - break; - - default: - state = "unknown"; - break; - } - - log_printf(" %2d %9s ", i, state, 0); - - switch (hp->bd_info.type) { - case MEM_BOARD: - log_printf("%-14s ", MEM_BD_NAME, 0); - break; - - case CPU_BOARD: - log_printf("%-14s ", CPU_BD_NAME, 0); - - /* Cannot display CPU info for disabled boards */ - if ((hp->bd_info.state == DISABLED_STATE) || - (hp->bd_info.state == FAILED_STATE)) { - break; - } - - /* Display both CPUs if present */ - cpu = &hp->bd_info.bd.cpu[0]; - for (j = 0; j < 2; j++, cpu++) { - log_printf("CPU %d: ", j, 0); - /* Print the rated speed of the CPU. */ - if (cpu->cpu_speed > 1) { - log_printf("%3d MHz", cpu->cpu_speed, - 0); - } else { - log_printf("no CPU ", 0); - continue; - } - - /* Display the size of the cache */ - if (cpu->cache_size != 0) { - log_printf(" %0.1fM ", - (float)cpu->cache_size / - (float)(1024*1024), 0); - } else { - log_printf(" ", 0); - } - } - break; - - case IO_2SBUS_BOARD: - log_printf("%-14s ", IO_2SBUS_BD_NAME, 0); - break; - - case IO_2SBUS_SOCPLUS_BOARD: - log_printf("%-14s ", IO_2SBUS_SOCPLUS_BD_NAME, 0); - break; - - case IO_SBUS_FFB_BOARD: - log_printf("%-14s ", IO_SBUS_FFB_BD_NAME, 0); - switch (hp->bd_info.bd.io2.ffb_size) { - case FFB_SINGLE: - log_printf("Single buffered FFB", 0); - break; - - case FFB_DOUBLE: - log_printf("Double buffered FFB", 0); - break; - - case FFB_NOT_FOUND: - log_printf("No FFB installed", 0); - break; - - default: - log_printf("Illegal FFB size", 0); - break; - } - break; - - case IO_SBUS_FFB_SOCPLUS_BOARD: - log_printf("%-14s ", IO_SBUS_FFB_SOCPLUS_BD_NAME, 0); - switch (hp->bd_info.bd.io2.ffb_size) { - case FFB_SINGLE: - log_printf("Single buffered FFB", 0); - break; - - case FFB_DOUBLE: - log_printf("Double buffered FFB", 0); - break; - - case FFB_NOT_FOUND: - log_printf("No FFB installed", 0); - break; - - default: - log_printf("Illegal FFB size", 0); - break; - } - break; - - case IO_PCI_BOARD: - log_printf("%-14s ", IO_PCI_BD_NAME, 0); - break; - - case DISK_BOARD: - log_printf("%-14s ", "disk", 0); - for (j = 0; j < 2; j++) { - log_printf("Disk %d:", j, 0); - if (hp->bd_info.bd.dsk.disk_pres[j]) { - log_printf(" Target: %2d ", - hp->bd_info.bd.dsk.disk_id[j], - 0); - } else { - log_printf(" no disk ", 0); - } - } - break; - - case UNKNOWN_BOARD: - case UNINIT_BOARD: - default: - log_printf("UNKNOWN ", 0); - break; - } - log_printf("\n"); - } -} - -/* - * Analysis functions: - * - * Most of the Fatal error data analyzed from error registers is not - * very complicated. This is because the FRUs for errors detected by - * most parts is either a CPU module, a FFB, or the system board - * itself. - * The analysis of the Address Controller errors is the most complicated. - * These errors can be caused by other boards as well as the local board. - */ - -/* - * analyze_cpu - * - * Analyze the CPU MFSR passed in and determine what type of fatal - * hardware errors occurred at the time of the crash. This function - * returns a pointer to a string to the calling routine. - */ -static int -analyze_cpu(char **msgs, int cpu_id, u_longlong_t afsr) -{ - int count = 0; - int i; - int syndrome; - char msgbuf[MAXSTRLEN]; - - if (msgs == NULL) { - return (count); - } - - if (afsr & P_AFSR_ETP) { - (void) sprintf(msgbuf, "CPU %d Ecache Tag Parity Error, ", - cpu_id); - - /* extract syndrome for afsr */ - syndrome = (afsr & P_AFSR_ETS) >> ETS_SHIFT; - - /* now concat the parity syndrome msg */ - for (i = 0; i < 4; i++) { - if ((0x1 << i) & syndrome) { - (void) strcat(msgbuf, ecache_parity[i]); - } - } - (void) strcat(msgbuf, "\n"); - *msgs++ = strdup(msgbuf); - count++; - } - - if (afsr & P_AFSR_ISAP) { - (void) sprintf(msgbuf, - "CPU %d Incoming System Address Parity Error\n", - cpu_id); - *msgs++ = strdup(msgbuf); - count++; - } - - return (count); -} - -/* - * analyze_ac - * - * This function checks the AC error register passed in and checks - * for any errors that occured during the fatal hardware reset. - */ -static int -analyze_ac(char **msgs, u_longlong_t ac_error) -{ - int i; - int count = 0; - char msgbuf[MAXSTRLEN]; - int tmp_cnt; - - if (msgs == NULL) { - return (count); - } - - for (i = 2; i < MAX_BITS; i++) { - if ((((u_longlong_t)0x1 << i) & ac_error) != 0) { - if (ac_errors[i].error != NULL) { - (void) sprintf(msgbuf, "AC: %s\n", - ac_errors[i].error); - *msgs++ = strdup(msgbuf); - count++; - - /* display the part that might cause this */ - tmp_cnt = disp_parts(msgs, ac_error, i); - count += tmp_cnt; - msgs += tmp_cnt; - } - } - } - - return (count); -} - -/* - * analyze_dc - * - * This routine checks the DC shdow chain and tries to determine - * what type of error might have caused the fatal hardware reset - * error. - */ -static int -analyze_dc(int board, char **msgs, u_longlong_t dc_error) -{ - int i; - int count = 0; - char msgbuf[MAXSTRLEN]; - - if (msgs == NULL) { - return (count); - } - - /* - * The DC scan data is contained in 8 bytes, one byte per - * DC. There are 8 DCs on a system board. - */ - - for (i = 0; i < 8; i++) { - if (dc_error & DC_OVERFLOW) { - (void) sprintf(msgbuf, dc_overflow_txt, board, i); - *msgs++ = strdup(msgbuf); - count++; - } - - if (dc_error & DC_PARITY) { - (void) sprintf(msgbuf, dc_parity_txt, board, i); - *msgs++ = strdup(msgbuf); - count++; - } - dc_error = dc_error >> 8; /* shift over to next byte */ - } - - return (count); -} - -static int -disp_parts(char **msgs, u_longlong_t ac_error, int type) -{ - int count = 0; - int part; - char msgbuf[MAXSTRLEN]; - int i; - - if (msgs == NULL) { - return (count); - } - - (void) sprintf(msgbuf, "\tThe error could be caused by:\n"); - *msgs++ = strdup(msgbuf); - count++; - - for (i = 0; (i < MAX_FRUS) && ac_errors[type].part[i]; i++) { - part = ac_errors[type].part[i]; - - if (part == UPA_PART) { - if (ac_error & UPA_PORT_A) { - part = UPA_A_PART; - } else if (ac_error & UPA_PORT_B) { - part = UPA_B_PART; - } - } - - if (part == DTAG_PART) { - if (ac_error & UPA_PORT_A) { - part = DTAG_A_PART; - } else if (ac_error & UPA_PORT_B) { - part = DTAG_B_PART; - } - } - - (void) sprintf(msgbuf, "\t\t%s\n", part_str[part]); - - *msgs++ = strdup(msgbuf); - count++; - } - - return (count); -} diff --git a/usr/src/lib/libprtdiag_psr/sparc/tazmo/common/tazmo.c b/usr/src/lib/libprtdiag_psr/sparc/tazmo/common/tazmo.c index 58d4634164..9b3e739f76 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/tazmo/common/tazmo.c +++ b/usr/src/lib/libprtdiag_psr/sparc/tazmo/common/tazmo.c @@ -22,6 +22,7 @@ /* * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2020 Peter Tribble. * * Tazmo Platform specific functions. * @@ -67,7 +68,7 @@ extern int print_flag; * at runtime (workgroup server systems only) */ int error_check(Sys_tree *tree, struct system_kstat_data *kstats); -void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_memoryconf(Sys_tree *tree); int disp_fail_parts(Sys_tree *tree); void display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats); void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, @@ -78,7 +79,7 @@ void display_io_cards(struct io_card *list); void display_ffb(Board_node *, int); void read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep); + struct envctrl_kstat_data *ep); /* local functions */ static int disp_envctrl_status(Sys_tree *, struct system_kstat_data *); @@ -132,7 +133,7 @@ dev_next_node_sibling(Prom_node *root, char *name) * DIMM sizes, DIMM socket names. */ void -display_memoryconf(Sys_tree *tree, struct grp_info *grps) +display_memoryconf(Sys_tree *tree) { Board_node *bnode; Prom_node *memory; @@ -147,9 +148,6 @@ display_memoryconf(Sys_tree *tree, struct grp_info *grps) Prop *status_prop; char interleave[8]; int total_size = 0; -#ifdef lint - grps = grps; -#endif log_printf("\n", 0); log_printf("=========================", 0); @@ -755,11 +753,11 @@ display_ffb(Board_node *board, int table) /* * This module does the reading and interpreting of tazmo system - * kstats. These kstats are created by the environ driver: + * kstats. These kstats are created by the envctrl driver: */ void read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, - struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep) + struct envctrl_kstat_data *ep) { kstat_ctl_t *kc; kstat_t *ksp; @@ -767,10 +765,6 @@ read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat, if ((kc = kstat_open()) == NULL) { return; } -#ifdef lint - tree = tree; - bdp = bdp; -#endif ep = &sys_kstat->env_data; diff --git a/usr/src/lib/librsc/sparc/mpxu/common/librsc.c b/usr/src/lib/librsc/sparc/mpxu/common/librsc.c index 863c304fcc..c39719f473 100644 --- a/usr/src/lib/librsc/sparc/mpxu/common/librsc.c +++ b/usr/src/lib/librsc/sparc/mpxu/common/librsc.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ENXS platform-specific functions */ @@ -151,7 +149,7 @@ rscp_init(void) /* * 'erase' the rx buffer */ - (void) memset(rsc_rx_buffer, 0, sizeof (RSC_MAX_RX_BUFFER)); + (void) memset(rsc_rx_buffer, 0, sizeof (rsc_rx_buffer)); rsc_rx_resp_len = 0; rsc_rx_error = 0; rsc_rx_resp_type = DP_NULL_MSG; diff --git a/usr/src/lib/libzfs_core/common/libzfs_core.c b/usr/src/lib/libzfs_core/common/libzfs_core.c index aad4104fa5..628b1cc8ff 100644 --- a/usr/src/lib/libzfs_core/common/libzfs_core.c +++ b/usr/src/lib/libzfs_core/common/libzfs_core.c @@ -25,6 +25,7 @@ * Copyright (c) 2014 Integros [integros.com] * Copyright 2017 RackTop Systems. * Copyright (c) 2017 Datto Inc. + * Copyright 2020 Joyent, Inc. */ /* @@ -1021,6 +1022,7 @@ lzc_channel_program_impl(const char *pool, const char *program, boolean_t sync, { int error; nvlist_t *args; + nvlist_t *hidden_args = NULL; args = fnvlist_alloc(); fnvlist_add_string(args, ZCP_ARG_PROGRAM, program); @@ -1028,6 +1030,22 @@ lzc_channel_program_impl(const char *pool, const char *program, boolean_t sync, fnvlist_add_boolean_value(args, ZCP_ARG_SYNC, sync); fnvlist_add_uint64(args, ZCP_ARG_INSTRLIMIT, instrlimit); fnvlist_add_uint64(args, ZCP_ARG_MEMLIMIT, memlimit); + + /* + * If any hidden arguments are passed, we pull them out of 'args' + * and into a separate nvlist so spa_history_nvl() doesn't log + * their values. + */ + if (nvlist_lookup_nvlist(argnvl, ZPOOL_HIDDEN_ARGS, + &hidden_args) == 0) { + nvlist_t *argcopy = fnvlist_dup(argnvl); + + fnvlist_add_nvlist(args, ZPOOL_HIDDEN_ARGS, hidden_args); + fnvlist_remove(argcopy, ZPOOL_HIDDEN_ARGS); + fnvlist_add_nvlist(args, ZCP_ARG_ARGLIST, argcopy); + nvlist_free(argcopy); + } + error = lzc_ioctl(ZFS_IOC_CHANNEL_PROGRAM, pool, args, outnvl); fnvlist_free(args); diff --git a/usr/src/lib/udapl/udapl_tavor/common/dapl_evd_util.c b/usr/src/lib/udapl/udapl_tavor/common/dapl_evd_util.c index 19e2eaaa5d..b40dd626db 100644 --- a/usr/src/lib/udapl/udapl_tavor/common/dapl_evd_util.c +++ b/usr/src/lib/udapl/udapl_tavor/common/dapl_evd_util.c @@ -77,16 +77,16 @@ dapli_evd_event_alloc( * to create the default async evd. * * Input: - * ia_ptr + * ia_ptr * cno_ptr * qlen * evd_flags * * Output: - * evd_ptr_ptr + * evd_ptr_ptr * * Returns: - * none + * none * */ @@ -136,6 +136,13 @@ dapls_evd_internal_create( goto bail; } +#if 0 + /* + * Current implementation of dapls_ib_setup_async_callback() does + * nothing and returns DAT_SUCCESS. However, it is declared to expect + * function pointers with different signatures. We do leave the code + * block out till dapls_ib_setup_async_callback() is implemented. + */ dat_status = dapls_ib_setup_async_callback( ia_ptr, DAPL_ASYNC_CQ_COMPLETION, @@ -145,6 +152,7 @@ dapls_evd_internal_create( if (dat_status != DAT_SUCCESS) { goto bail; } +#endif /* * cq_notify is not required since when evd_wait is called * time we go and poll cq anyways. @@ -181,13 +189,13 @@ bail: * alloc and initialize an EVD struct * * Input: - * ia + * ia * * Output: - * evd_ptr + * evd_ptr * * Returns: - * none + * none * */ DAPL_EVD * @@ -250,14 +258,14 @@ bail: * alloc events into an EVD. * * Input: - * evd_ptr + * evd_ptr * qlen * * Output: - * NONE + * NONE * * Returns: - * DAT_SUCCESS + * DAT_SUCCESS * ERROR * */ @@ -328,13 +336,13 @@ bail: * error. * * Input: - * evd_ptr + * evd_ptr * * Output: - * none + * none * * Returns: - * status + * status * */ DAT_RETURN @@ -413,8 +421,7 @@ bail: #ifdef DAPL_DBG /* For debugging. */ void -dapli_evd_eh_print_cqe( - IN ib_work_completion_t cqe) +dapli_evd_eh_print_cqe(IN ib_work_completion_t cqe) { static char *optable[] = { "", @@ -481,7 +488,7 @@ dapli_evd_eh_print_cqe( * that the lock is held. * * Input: - * evd_ptr + * evd_ptr * * Output: * event @@ -518,8 +525,8 @@ dapli_evd_get_event( * entry to this function. * * Input: - * evd_ptr - * event + * evd_ptr + * event * * Output: * none @@ -532,7 +539,7 @@ dapli_evd_post_event( IN const DAT_EVENT *event_ptr) { DAT_RETURN dat_status; - DAPL_CNO *cno_to_trigger = NULL; + DAPL_CNO *cno_to_trigger = NULL; dapl_dbg_log(DAPL_DBG_TYPE_EVD, "dapli_evd_post_event: Called with event # %x\n", @@ -606,8 +613,8 @@ dapli_evd_post_event( * entry to this function. * * Input: - * evd_ptr - * event + * evd_ptr + * event * * Output: * none @@ -643,8 +650,8 @@ dapli_evd_post_event_nosignal( * format an overflow event for posting * * Input: - * evd_ptr - * event_ptr + * evd_ptr + * event_ptr * * Output: * none @@ -671,8 +678,8 @@ dapli_evd_format_overflow_event( * post an overflow event * * Input: - * async_evd_ptr - * evd_ptr + * async_evd_ptr + * evd_ptr * * Output: * none @@ -711,7 +718,7 @@ dapli_evd_get_and_init_event( IN DAPL_EVD *evd_ptr, IN DAT_EVENT_NUMBER event_number) { - DAT_EVENT *event_ptr; + DAT_EVENT *event_ptr; event_ptr = dapli_evd_get_event(evd_ptr); if (NULL == event_ptr) { @@ -734,7 +741,7 @@ dapls_evd_post_cr_arrival_event( DAT_CONN_QUAL conn_qual, DAT_CR_HANDLE cr_handle) { - DAT_EVENT *event_ptr; + DAT_EVENT *event_ptr; event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number); /* * Note event lock may be held on successful return @@ -765,7 +772,7 @@ dapls_evd_post_connection_event( IN DAT_COUNT private_data_size, IN DAT_PVOID private_data) { - DAT_EVENT *event_ptr; + DAT_EVENT *event_ptr; event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number); /* * Note event lock may be held on successful return @@ -793,7 +800,7 @@ dapls_evd_post_async_error_event( IN DAT_EVENT_NUMBER event_number, IN DAT_IA_HANDLE ia_handle) { - DAT_EVENT *event_ptr; + DAT_EVENT *event_ptr; event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number); /* * Note event lock may be held on successful return @@ -818,7 +825,7 @@ dapls_evd_post_software_event( IN DAT_EVENT_NUMBER event_number, IN DAT_PVOID pointer) { - DAT_EVENT *event_ptr; + DAT_EVENT *event_ptr; event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number); /* * Note event lock may be held on successful return @@ -911,13 +918,13 @@ dapls_evd_post_premature_events(IN DAPL_EP *ep_ptr) * * Input: * evd_ptr - * cqe_ptr + * cqe_ptr * * Output: - * event_ptr + * event_ptr * * Returns: - * none + * none * */ static DAT_BOOLEAN @@ -1206,10 +1213,10 @@ dapli_evd_cqe_to_event( * evd_ptr * * Output: - * nevents + * nevents * * Returns: - * none + * none * */ void @@ -1296,16 +1303,14 @@ dapls_evd_copy_cq( * timeout * * Output: - * return status + * return status * * Returns: - * none + * none * */ DAT_RETURN -dapls_evd_copy_events( - DAPL_EVD *evd_ptr, - DAT_TIMEOUT timeout) +dapls_evd_copy_events(DAPL_EVD *evd_ptr, DAT_TIMEOUT timeout) { dapl_ib_event_t evp_arr[NUM_EVENTS_PER_POLL]; dapl_ib_event_t *evpp_start; @@ -1584,16 +1589,14 @@ dapls_evd_copy_events( * evd_ptr * * Output: - * event + * event * * Returns: - * Status of operation + * Status of operation * */ DAT_RETURN -dapls_evd_cq_poll_to_event( - IN DAPL_EVD *evd_ptr, - OUT DAT_EVENT *event) +dapls_evd_cq_poll_to_event(IN DAPL_EVD *evd_ptr, OUT DAT_EVENT *event) { DAT_RETURN dat_status; ib_work_completion_t cur_cqe; diff --git a/usr/src/lib/udapl/udapl_tavor/common/dapl_ia_util.c b/usr/src/lib/udapl/udapl_tavor/common/dapl_ia_util.c index bc16ef69b4..714d60eac7 100644 --- a/usr/src/lib/udapl/udapl_tavor/common/dapl_ia_util.c +++ b/usr/src/lib/udapl/udapl_tavor/common/dapl_ia_util.c @@ -55,13 +55,13 @@ void dapli_ia_release_hca( * alloc and initialize an IA INFO struct * * Input: - * none + * none * * Output: - * ia_ptr + * ia_ptr * * Returns: - * none + * none * */ DAPL_IA * @@ -123,19 +123,18 @@ dapl_ia_alloc(DAT_PROVIDER * provider, DAPL_HCA * hca_ptr) * Performs an abrupt close of the IA * * Input: - * ia_ptr + * ia_ptr * * Output: - * none + * none * * Returns: - * status + * status * */ DAT_RETURN -dapl_ia_abrupt_close( - IN DAPL_IA *ia_ptr) +dapl_ia_abrupt_close(IN DAPL_IA *ia_ptr) { DAT_RETURN dat_status; DAPL_EP *ep_ptr, *next_ep_ptr; @@ -346,24 +345,23 @@ dapl_ia_abrupt_close( * Performs an graceful close of the IA * * Input: - * ia_ptr + * ia_ptr * * Output: - * none + * none * * Returns: - * status + * status * */ DAT_RETURN -dapl_ia_graceful_close( - IN DAPL_IA *ia_ptr) +dapl_ia_graceful_close(IN DAPL_IA *ia_ptr) { DAT_RETURN dat_status; DAT_RETURN cur_dat_status; DAPL_EVD *evd_ptr; - DAPL_LLIST_ENTRY *entry; + DAPL_LLIST_ENTRY *entry; DAPL_HCA *hca_ptr; dat_status = DAT_SUCCESS; @@ -491,13 +489,13 @@ dapli_ia_release_hca( * free an IA INFO struct * * Input: - * ia_ptr + * ia_ptr * * Output: - * one + * one * * Returns: - * none + * none * */ void @@ -535,10 +533,10 @@ dapls_ia_free(DAPL_IA *ia_ptr) * ep_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -563,10 +561,10 @@ dapl_ia_link_ep( * ep_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -590,10 +588,10 @@ dapl_ia_unlink_ep( * lmr_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -618,10 +616,10 @@ dapl_ia_link_lmr( * lmr_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -645,10 +643,10 @@ dapl_ia_unlink_lmr( * rmr_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -673,10 +671,10 @@ dapl_ia_link_rmr( * rmr_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -700,10 +698,10 @@ dapl_ia_unlink_rmr( * pz_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -728,10 +726,10 @@ dapl_ia_link_pz( * pz_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -755,10 +753,10 @@ dapl_ia_unlink_pz( * evd_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -783,10 +781,10 @@ dapl_ia_link_evd( * evd_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -810,10 +808,10 @@ dapl_ia_unlink_evd( * cno_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -838,10 +836,10 @@ dapl_ia_link_cno( * cno_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -865,10 +863,10 @@ dapl_ia_unlink_cno( * sp_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -893,10 +891,10 @@ dapl_ia_link_psp( * sp_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -930,10 +928,10 @@ dapls_ia_unlink_sp( * sp_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ DAPL_SP * @@ -980,10 +978,10 @@ dapls_ia_sp_search( * sp_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -1008,10 +1006,10 @@ dapl_ia_link_rsp( * srq_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -1036,10 +1034,10 @@ dapl_ia_link_srq( * srq_ptr * * Output: - * none + * none * * Returns: - * none + * none * */ void @@ -1060,6 +1058,13 @@ dapls_ia_setup_callbacks( { DAT_RETURN dat_status = DAT_SUCCESS; +#if 0 + /* + * Current implementation of dapls_ib_setup_async_callback() does + * nothing and returns DAT_SUCCESS. However, it is declared to expect + * function pointers with different signatures. We do leave the code + * block out till dapls_ib_setup_async_callback() is implemented. + */ /* unaffiliated handler */ dat_status = dapls_ib_setup_async_callback( @@ -1104,8 +1109,8 @@ dapls_ia_setup_callbacks( dat_status); goto bail; } - bail: +#endif return (dat_status); } diff --git a/usr/src/man/man1/find.1 b/usr/src/man/man1/find.1 index 47f3870d12..d393a3197d 100644 --- a/usr/src/man/man1/find.1 +++ b/usr/src/man/man1/find.1 @@ -45,12 +45,12 @@ .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved .\" Copyright 2011 Nexenta Systems, Inc. All rights reserved. .\" Copyright (c) 2013 Andrew Stormont. All rights reserved. +.\" Copyright 2020 Joyent, Inc. .\" -.TH FIND 1 "Sep 5, 2011" +.TH FIND 1 "Feb 20, 2020" .SH NAME find \- find files .SH SYNOPSIS -.LP .nf \fB/usr/bin/find\fR [\fB-E\fR] [\fB-H\fR | \fB-L\fR] \fIpath\fR... \fIexpression\fR .fi @@ -61,7 +61,6 @@ find \- find files .fi .SH DESCRIPTION -.LP The \fBfind\fR utility recursively descends the directory hierarchy for each \fIpath\fR seeking files that match a Boolean \fIexpression\fR written in the primaries specified below. @@ -75,7 +74,6 @@ by the application exceeds \fIPATH_MAX\fR requirements). \fBfind\fR detects infinite loops; that is, entering a previously visited directory that is an ancestor of the last file encountered. .SH OPTIONS -.LP The following options are supported: .sp .ne 2 @@ -117,7 +115,6 @@ Specifying more than one of the mutually-exclusive options \fB-H\fR and \fB-L\fR is not considered an error. The last option specified determines the behavior of the utility. .SH OPERANDS -.LP The following operands are supported: .sp .ne 2 @@ -169,7 +166,6 @@ less than \fIn\fR .RE .SS "Expressions" -.LP Valid expressions are: .sp .ne 2 @@ -549,7 +545,8 @@ question mark first, and is executed only if the response is affirmative. \fB\fB-path\fR\fR .ad .RS 17n -Like \fB-name\fR, but matches the entire file path and not just basename. +Like \fB-name\fR, but matches the entire file path and not just basename, and +without any special treatment of leading periods. .RE .sp @@ -717,7 +714,6 @@ True if the file has extended attributes. .RE .SS "Complex Expressions" -.LP The primaries can be combined using the following operators (in order of decreasing precedence): .sp @@ -783,11 +779,9 @@ The \fB-user\fR, \fB-group\fR, and \fB-newer\fR primaries each evaluate their respective arguments only once. Invocation of \fIcommand\fR specified by \fB-exec\fR or \fB-ok\fR does not affect subsequent primaries on the same file. .SH USAGE -.LP See \fBlargefile\fR(5) for the description of the behavior of \fBfind\fR when encountering files greater than or equal to 2 Gbyte (2^31 bytes). .SH EXAMPLES -.LP \fBExample 1 \fRWriting Out the Hierarchy Directory .sp .LP @@ -957,7 +951,6 @@ example% \fBfind . -xattr\fR .sp .SH ENVIRONMENT VARIABLES -.LP See \fBenviron\fR(5) for descriptions of the following environment variables that affect the execution of \fBfind\fR: \fBLANG\fR, \fBLC_ALL\fR, \fBLC_COLLATE\fR, \fBLC_CTYPE\fR, \fBLC_MESSAGES\fR, and \fBNLSPATH\fR. @@ -982,7 +975,6 @@ in \fBLC_CTYPE\fR determines the locale for interpretation of sequences of bytes of text data a characters, the behavior of character classes used in the expression defined for the \fByesexpr\fR. See \fBlocale\fR(5). .SH EXIT STATUS -.LP The following exit values are returned: .sp .ne 2 @@ -1030,7 +1022,6 @@ File that registers distributed file system packages .RE .SH ATTRIBUTES -.LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -1049,13 +1040,11 @@ Standard See \fBstandards\fR(5). .TE .SH SEE ALSO -.LP \fBchmod\fR(1), \fBcpio\fR(1), \fBsh\fR(1), \fBtest\fR(1), \fBls\fR(1B), \fBacl\fR(5), \fBregex\fR(5), \fBstat\fR(2), \fBumask\fR(2), \fBattributes\fR(5), \fBenviron\fR(5), \fBfsattr\fR(5), \fBlargefile\fR(5), \fBlocale\fR(5), \fBstandards\fR(5) .SH WARNINGS -.LP The following options are obsolete and will not be supported in future releases: .sp @@ -1079,7 +1068,6 @@ format (5120-byte records). .RE .SH NOTES -.LP When using \fBfind\fR to determine files modified within a range of time, use the \fB-mtime\fR argument \fBbefore\fR the \fB-print\fR argument. Otherwise, \fBfind\fR gives all files. diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile index a571d4ca86..1eaa441df3 100644 --- a/usr/src/man/man1m/Makefile +++ b/usr/src/man/man1m/Makefile @@ -11,7 +11,7 @@ # # Copyright 2011, Richard Lowe -# Copyright 2019 Joyent, Inc. +# Copyright 2020 Joyent, Inc. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 2013, 2016 by Delphix. All rights reserved. # Copyright 2016 Toomas Soome <tsoome@me.com> @@ -170,6 +170,7 @@ _MANFILES= 6to4relay.1m \ halt.1m \ hextoalabel.1m \ hostconfig.1m \ + hotplug.1m \ id.1m \ idmap.1m \ idmapd.1m \ @@ -490,6 +491,7 @@ _MANFILES= 6to4relay.1m \ ttymon.1m \ tunefs.1m \ txzonemgr.1m \ + tzreload.1m \ tzselect.1m \ uadmin.1m \ ucodeadm.1m \ diff --git a/usr/src/man/man1m/flowadm.1m b/usr/src/man/man1m/flowadm.1m index 860d5f1faa..fcaa518a41 100644 --- a/usr/src/man/man1m/flowadm.1m +++ b/usr/src/man/man1m/flowadm.1m @@ -1,10 +1,11 @@ '\" te +.\" Copyright 2020 Peter Tribble .\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved .\" Copyright (c) 2011, Joyent, Inc. All Rights Reserved .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FLOWADM 1M "April 9, 2016" +.TH FLOWADM 1M "February 26, 2020" .SH NAME flowadm \- administer bandwidth resource control and priority for protocols, services, containers, and virtual machines @@ -30,14 +31,7 @@ services, containers, and virtual machines [\fB-p\fR \fIprop\fR[,...]] [\fIflow\fR] .fi -.LP -.nf -\fBflowadm show-usage\fR [\fB-a\fR] [\fB-d\fR | {\fB-p\fR \fIplotfile\fR \fB-F\fR \fIformat\fR}] [\fB-s\fR \fItime\fR] - [\fB-e\fR \fItime\fR] \fB-f\fR \fIfilename\fR [\fIflow\fR] -.fi - .SH DESCRIPTION -.LP The \fBflowadm\fR command is used to create, modify, remove, and show networking bandwidth and associated resources for a type of traffic on a particular link. @@ -62,7 +56,7 @@ Inbound and outbound packet are matched to flows in a very fast and scalable way, so that limits can be enforced with minimal performance impact. .sp .LP -The \fBflowadm\fR command can be used to identify a flow without imposing any +The \fBflowadm\fR command can be used to define a flow without imposing any bandwidth resource control. This would result in the traffic type getting its own resources and queues so that it is isolated from rest of the networking traffic for more observable and deterministic behavior. @@ -71,7 +65,6 @@ traffic for more observable and deterministic behavior. \fBflowadm\fR is implemented as a set of subcommands with corresponding options. Options are described in the context of each subcommand. .SH SUBCOMMANDS -.LP The following subcommands are supported: .sp .ne 2 @@ -80,140 +73,139 @@ The following subcommands are supported: .ad .sp .6 .RS 4n -Show flow configuration information (the default) or statistics, either for all -flows, all flows on a link, or for the specified \fIflow\fR. +Adds a flow to the system. The flow is identified by its flow attributes and +properties. .sp -.ne 2 -.na -\fB\fB-o\fR \fIfield\fR[,...]\fR -.ad -.sp .6 -.RS 4n -A case-insensitive, comma-separated list of output fields to display. The field -name must be one of the fields listed below, or a special value \fBall\fR, to -display all fields. For each flow found, the following fields can be displayed: +As part of identifying a particular flow, its bandwidth resource can be limited +and its relative priority to other traffic can be specified. If no bandwidth +limit or priority is specified, the traffic still gets its unique layer 2, 3, +and 4 queues and processing threads, including NIC hardware resources (when +supported), so that the selected traffic can be separated from others and can +flow with minimal impact from other traffic. .sp .ne 2 .na -\fB\fBflow\fR\fR +\fB\fB-t\fR, \fB--temporary\fR\fR .ad .sp .6 .RS 4n -The name of the flow. +The changes are temporary and will not persist across reboots. Persistence is +the default. .RE .sp .ne 2 .na -\fB\fBlink\fR\fR +\fB\fB-R\fR \fIroot-dir\fR, \fB--root-dir\fR=\fIroot-dir\fR\fR .ad .sp .6 .RS 4n -The name of the link the flow is on. +Specifies an alternate root directory where \fBflowadm\fR should apply +persistent creation. .RE .sp .ne 2 .na -\fB\fBipaddr\fR\fR +\fB\fB-l\fR \fIlink\fR, \fB--link\fR=\fIlink\fR\fR .ad .sp .6 .RS 4n -IP address of the flow. This can be either local or remote depending on how the -flow was defined. +Specify the link to which the flow will be added. .RE .sp .ne 2 .na -\fB\fBtransport\fR\fR +\fB\fB-a\fR \fIattr\fR=\fIvalue\fR[,...], \fB--attr\fR=\fIvalue\fR\fR .ad .sp .6 .RS 4n -The name of the layer for protocol to be used. +A mandatory comma-separated list of attributes to be set to the specified +values. .RE .sp .ne 2 .na -\fB\fBport\fR\fR +\fB\fB-p\fR \fIprop\fR=\fIvalue\fR[,...], \fB--prop\fR=\fIvalue\fR[,...]\fR .ad .sp .6 .RS 4n -Local port of service for flow. +An optional comma-separated list of properties to be set to the specified +values. Flow properties are documented in the "Flow Properties" section, below. +.RE + .RE .sp .ne 2 .na -\fB\fBdsfield\fR\fR +\fB\fBflowadm remove-flow\fR [\fB-t\fR] [\fB-R\fR \fIroot-dir\fR] \fB-l\fR +{\fIlink\fR | \fIflow\fR}\fR .ad .sp .6 .RS 4n -Differentiated services value for flow and mask used with \fBDSFIELD\fR value -to state the bits of interest in the differentiated services field of the IP -header. -.RE - -.RE - +Remove an existing flow identified by its link or name. .sp .ne 2 .na -\fB\fB-p\fR, \fB--parsable\fR\fR +\fB\fB-t\fR, \fB--temporary\fR\fR .ad .sp .6 .RS 4n -Display using a stable machine-parsable format. +The changes are temporary and will not persist across reboots. Persistence is +the default. .RE .sp .ne 2 .na -\fB\fB-P\fR, \fB--persistent\fR\fR +\fB\fB-R\fR \fIroot-dir\fR, \fB--root-dir\fR=\fIroot-dir\fR\fR .ad .sp .6 .RS 4n -Display persistent flow property information. +Specifies an alternate root directory where \fBflowadm\fR should apply +persistent removal. .RE .sp .ne 2 .na -\fB\fB-S\fR, \fB--continuous\fR\fR +\fB\fB-l\fR \fIlink\fR | \fIflow\fR, \fB--link\fR=\fIlink\fR | \fIflow\fR\fR .ad .sp .6 .RS 4n -Continuously display network utilization by flow in a manner similar to the way -that \fBprstat\fR(1M) displays CPU utilization by process. +If a link is specified, remove all flows from that link. If a single flow is +specified, remove only that flow. +.RE + .RE .sp .ne 2 .na -\fB\fB-s\fR, \fB--statistics\fR\fR +\fB\fBflowadm show-flow\fR [\fB-pP\fR] [\fB-s\fR [\fB-i\fR \fIinterval\fR]] +[\fB-o\fR \fIfield\fR[,...]] [\fB-l\fR \fIlink\fR] [\fIflow\fR]\fR .ad .sp .6 .RS 4n -Displays flow statistics. -.RE - +Show flow configuration information, either for all +flows, all flows on a link, or for the specified \fIflow\fR. .sp .ne 2 .na -\fB\fB-i\fR \fIinterval\fR, \fB--interval\fR=\fIinterval\fR\fR +\fB\fB-o\fR \fIfield\fR[,...]\fR .ad .sp .6 .RS 4n -Used with the \fB-s\fR option to specify an interval, in seconds, at which -statistics should be displayed. If this option is not specified, statistics are -displayed once. -.RE - +A case-insensitive, comma-separated list of output fields to display. The field +name must be one of the fields listed below, or a special value \fBall\fR, to +display all fields. For each flow found, the following fields can be displayed: .sp .ne 2 .na -\fB\fB-l\fR \fIlink\fR, \fB--link\fR=\fIlink\fR | \fIflow\fR\fR +\fB\fBflow\fR\fR .ad .sp .6 .RS 4n @@ -240,35 +232,28 @@ Operate on a link that has been delegated to the specified zone. .ad .sp .6 .RS 4n -Adds a flow to the system. The flow is identified by its flow attributes and -properties. -.sp -As part of identifying a particular flow, its bandwidth resource can be limited -and its relative priority to other traffic can be specified. If no bandwidth -limit or priority is specified, the traffic still gets its unique layer 2, 3, -and 4 queues and processing threads, including NIC hardware resources (when -supported), so that the selected traffic can be separated from others and can -flow with minimal impact from other traffic. +The name of the link the flow is on. +.RE + .sp .ne 2 .na -\fB\fB-t\fR, \fB--temporary\fR\fR +\fB\fBipaddr\fR\fR .ad .sp .6 .RS 4n -The changes are temporary and will not persist across reboots. Persistence is -the default. +IP address of the flow. This can be either local or remote depending on how the +flow was defined. .RE .sp .ne 2 .na -\fB\fB-R\fR \fIroot-dir\fR, \fB--root-dir\fR=\fIroot-dir\fR\fR +\fB\fBproto\fR\fR .ad .sp .6 .RS 4n -Specifies an alternate root directory where \fBflowadm\fR should apply -persistent creation. +The name of the layer for protocol to be used. .RE .sp @@ -288,27 +273,29 @@ Operate on a link that has been delegated to the specified zone. .ad .sp .6 .RS 4n -Specify the link to which the flow will be added. +Local port of service for flow. .RE .sp .ne 2 .na -\fB\fB-a\fR \fIattr\fR=\fIvalue\fR[,...], \fB--attr\fR=\fIvalue\fR\fR +\fB\fBrport\fR\fR .ad .sp .6 .RS 4n -A comma-separated list of attributes to be set to the specified values. +Remote port of service for flow. .RE .sp .ne 2 .na -\fB\fB-p\fR \fIprop\fR=\fIvalue\fR[,...], \fB--prop\fR=\fIvalue\fR[,...]\fR +\fB\fBdsfld\fR\fR .ad .sp .6 .RS 4n -A comma-separated list of properties to be set to the specified values. +Differentiated services value for flow and mask used with \fBDSFIELD\fR value +to state the bits of interest in the differentiated services field of the IP +header. .RE .RE @@ -328,19 +315,17 @@ Remove an existing flow identified by its link or name. .ad .sp .6 .RS 4n -The changes are temporary and will not persist across reboots. Persistence is -the default. +Display using a stable machine-parsable format. .RE .sp .ne 2 .na -\fB\fB-R\fR \fIroot-dir\fR, \fB--root-dir\fR=\fIroot-dir\fR\fR +\fB\fB-P\fR, \fB--persistent\fR\fR .ad .sp .6 .RS 4n -Specifies an alternate root directory where \fBflowadm\fR should apply -persistent removal. +Display persistent flow property information. .RE .sp @@ -360,8 +345,8 @@ Operate on a link that has been delegated to the specified zone. .ad .sp .6 .RS 4n -If a link is specified, remove all flows from that link. If a single flow is -specified, remove only that flow. +Display information for all flows on the named link or information for the +named flow. .RE .RE @@ -375,7 +360,7 @@ specified, remove only that flow. .sp .6 .RS 4n Set values of one or more properties on the flow specified by name. The -complete list of properties can be retrieved using the \fBshow-flow\fR +complete list of properties can be retrieved using the \fBshow-flowprop\fR subcommand. .sp .ne 2 @@ -561,100 +546,7 @@ A comma-separated list of properties to show. .RE -.sp -.ne 2 -.na -\fB\fBflowadm show-usage\fR [\fB-a\fR] [\fB-d\fR | {\fB-p\fR \fIplotfile\fR -\fB-F\fR \fIformat\fR}] [\fB-s\fR \fItime\fR] [\fB-e\fR \fItime\fR] -[\fIflow\fR]\fR -.ad -.sp .6 -.RS 4n -Show the historical network flow usage from a stored extended accounting file. -Configuration and enabling of network accounting through \fBacctadm\fR(1M) is -required. The default output will be the summary of flow usage for the entire -period of time in which extended accounting was enabled. -.sp -.ne 2 -.na -\fB\fB-a\fR\fR -.ad -.sp .6 -.RS 4n -Display all historical network usage for the specified period of time during -which extended accounting is enabled. This includes the usage information for -the flows that have already been deleted. -.RE - -.sp -.ne 2 -.na -\fB\fB-d\fR\fR -.ad -.sp .6 -.RS 4n -Display the dates for which there is logging information. The date is in the -format \fIDD\fR/\fIMM\fR/\fIYYYY\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-F\fR \fIformat\fR\fR -.ad -.sp .6 -.RS 4n -Specifies the format of \fIplotfile\fR that is specified by the \fB-p\fR -option. As of this release, \fBgnuplot\fR is the only supported format. -.RE - -.sp -.ne 2 -.na -\fB\fB-p\fR \fIplotfile\fR\fR -.ad -.sp .6 -.RS 4n -When specified with \fB-s\fR or \fB-e\fR (or both), outputs flow usage data to -a file of the format specified by the \fB-F\fR option, which is required. -.RE - -.sp -.ne 2 -.na -\fB\fB-s\fR \fItime\fR, \fB-e\fR \fItime\fR\fR -.ad -.sp .6 -.RS 4n -Start and stop times for data display. Time is in the format -\fIYYYY\fR.\fIMM\fR.\fIDD\fR,\fIhh\fR:\fImm\fR:\fIss\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-f\fR \fIfilename\fR\fR -.ad -.sp .6 -.RS 4n -Read extended accounting records of network flow usage from \fIfilename\fR. -.RE - -.sp -.ne 2 -.na -\fB\fIflow\fR\fR -.ad -.sp .6 -.RS 4n -If specified, display the network flow usage only from the named flow. -Otherwise, display network usage from all flows. -.RE - -.RE - .SS "Flow Attributes" -.LP The flow operand that identify a flow in a \fBflowadm\fR command is a comma-separated list of one or more keyword, value pairs from the list below. .sp @@ -683,7 +575,7 @@ address is \fB/32\fR and for IPv6 is \fB/128\fR. .sp .6 .RS 4n Identifies a network flow by the remote IP address. The syntax is the same as -\fBlocal_ip\fR attributes +the \fBlocal_ip\fR attribute. .RE .sp @@ -710,6 +602,16 @@ Identifies a service specified by the local port. .sp .ne 2 .na +\fB\fBremote_port\fR\fR +.ad +.sp .6 +.RS 4n +Identifies a service specified by the remote port. +.RE + +.sp +.ne 2 +.na \fB\fBdsfield\fR[\fB:\fR\fIdsfield_mask\fR]\fR .ad .sp .6 @@ -726,7 +628,7 @@ is used. Both the \fBdsfield\fR value and mask must be in hexadecimal. .sp .LP -The following five types of combinations of attributes are supported: +The following six types of combinations of attributes are supported: .sp .in +2 .nf @@ -734,6 +636,7 @@ local_ip[/\fIprefixlen\fR]=\fIaddress\fR remote_ip[/\fIprefixlen\fR]=\fIaddress\fR transport={tcp|udp|sctp|icmp|icmpv6} transport={tcp|udp|sctp},local_port=\fIport\fR +transport={tcp|udp|sctp},remote_port=\fIport\fR dsfield=\fIval\fR[:\fIdsfield_mask\fR] .fi .in -2 @@ -741,13 +644,11 @@ dsfield=\fIval\fR[:\fIdsfield_mask\fR] .sp .LP -On a given link, the combinations above are mutually exclusive. An attempt to -create flows of different combinations will fail. +On a given link, the types of combinations above are mutually exclusive. An +attempt to create flows of different types on a given link will fail. .SS "Restrictions" -.LP There are individual flow restrictions and flow restrictions per zone. .SS "Individual Flow Restrictions" -.LP Restrictions on individual flows do not require knowledge of other flows that have been added to the link. .sp @@ -793,12 +694,10 @@ flow16\fR .sp .SS "Flow Restrictions Per Zone" -.LP Within a zone, no two flows can have the same name. After adding a flow with the link specified, the link will not be required for display, modification, or deletion of the flow. .SS "Flow Properties" -.LP The following flow properties are supported. Note that the ability to set a given property to a given value depends on the driver and hardware. .sp @@ -826,7 +725,6 @@ tokens \fBhigh\fR, \fBmedium\fR, or \fBlow\fR. The default is \fBmedium\fR. .RE .SH EXAMPLES -.LP \fBExample 1 \fRCreating a Policy Around a Mission-Critical Port .sp .LP @@ -840,8 +738,8 @@ delete the policy. .nf # \fBflowadm add-flow -l bge0 -a transport=TCP,local_port=443 https-1\fR # \fBflowadm show-flow -l bge0\fR -FLOW LINK IP ADDR PROTO PORT DSFLD -https1 bge0 -- tcp 443 -- +FLOW LINK IPADDR PROTO LPORT RPORT DSFLD +https1 bge0 -- tcp 443 -- -- .fi .in -2 .sp @@ -859,13 +757,13 @@ priority. .nf # \fBflowadm set-flowprop -p maxbw=500M,priority=high https-1\fR # \fBflowadm show-flow https-1\fR -FLOW LINK IP ADDR PROTO PORT DSFLD -https1 bge0 -- tcp 443 -- +FLOW LINK IPADDR PROTO LPORT RPORT DSFLD +https-1 bge0 -- tcp 443 -- -- # \fBflowadm show-flowprop https-1\fR -FLOW PROPERTY VALUE DEFAULT POSSIBLE -https-1 maxbw 500 -- -- -https-1 priority HIGH -- LOW,NORMAL,HIGH +FLOW PROPERTY VALUE DEFAULT POSSIBLE +https-1 maxbw 500 -- -- +https-1 priority high -- low,medium,high .fi .in -2 .sp @@ -888,33 +786,7 @@ priority=low limit-udp-1\fR .sp .LP -\fBExample 4 \fRShowing Flow Usage -.sp -.LP -Flow usage statistics can be stored using the extended accounting facility, -\fBacctadm\fR(1M). - -.sp -.in +2 -.nf -# \fBacctadm -e extended -f /var/log/net.log net\fR - -# \fBacctadm net\fR -Network accounting: active -Network accounting file: /var/log/net.log -Tracked Network resources: extended -Untracked Network resources: none -.fi -.in -2 -.sp - -.sp -.LP -The historical data that was saved can be retrieved in summary form using the -\fBshow-usage\fR subcommand of \fBflowadm\fR. - -.LP -\fBExample 5 \fRSetting Policy, Making Use of \fBdsfield\fR Attribute +\fBExample 4 \fRSetting Policy, Making Use of \fBdsfield\fR Attribute .sp .LP The following command sets a policy for EF PHB (DSCP value of 101110 from RFC @@ -931,71 +803,6 @@ for this flow will be \fB0x2e\fR (101110) with the \fBdsfield_mask\fR being .in -2 .sp -.sp -.LP -Display summary information: - -.sp -.in +2 -.nf -# \fBflowadm show-usage -f /var/log/net.log\fR -FLOW DURATION IPACKETS RBYTES OPACKETS OBYTES BANDWIDTH -flowtcp 100 1031 546908 0 0 43.76 Kbps -flowudp 0 0 0 0 0 0.00 Mbps -.fi -.in -2 -.sp - -.sp -.LP -Display dates for which logging information is available: - -.sp -.in +2 -.nf -# \fBflowadm show-usage -d -f /var/log/net.log\fR -02/19/2008 -.fi -.in -2 -.sp - -.sp -.LP -Display logging information for \fBflowtcp\fR starting at 02/19/2008, 10:38:46 -and ending at 02/19/2008, 10:40:06: - -.sp -.in +2 -.nf -# \fBflowadm show-usage -s 02/19/2008,10:39:06 -e 02/19/2008,10:40:06 \e --f /var/log/net.log flowtcp\fR -FLOW TIME IPACKETS RBYTES OPACKETS OBYTES BANDWIDTH -flowtcp 10:39:06 1 1546 4 6539 3.23 Kbps -flowtcp 10:39:26 2 3586 5 9922 5.40 Kbps -flowtcp 10:39:46 1 240 1 216 182.40 bps -flowtcp 10:40:06 0 0 0 0 0.00 bps -.fi -.in -2 -.sp - -.sp -.LP -Output the same information as above as a plotfile: - -.sp -.in +2 -.nf -# \fBflowadm show-usage -s 02/19/2008,10:39:06 -e 02/19/2008,10:40:06 \e --p /home/plot/myplot -F gnuplot -f /var/log/net.log flowtcp\fR -# \fBTime tcp-flow\fR -10:39:06 3.23 -10:39:26 5.40 -10:39:46 0.18 -10:40:06 0.00 -.fi -.in -2 -.sp - .SH EXIT STATUS .ne 2 .na @@ -1017,7 +824,6 @@ An error occurred. .RE .SH ATTRIBUTES -.LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -1032,6 +838,10 @@ Interface Stability Committed .TE .SH SEE ALSO -.LP -\fBacctadm\fR(1M), \fBdladm\fR(1M), \fBifconfig\fR(1M), \fBprstat\fR(1M), -\fBroute\fR(1M), \fBattributes\fR(5), \fBdlpi\fR(7P) +\fBdladm\fR(1M), \fBflowstat\fR(1M), \fBifconfig\fR(1M), +\fBroute\fR(1M), \fBattributes\fR(5) + +.SH NOTES +The display of statistics by the \fBshow-flow\fR subcommand, and the +\fBshow-usage\fR subcommand, have been removed. This functionality can +now be accessed using the \fBflowstat\fR(1M) utility. diff --git a/usr/src/man/man1m/hotplug.1m b/usr/src/man/man1m/hotplug.1m new file mode 100644 index 0000000000..0c5c8266fc --- /dev/null +++ b/usr/src/man/man1m/hotplug.1m @@ -0,0 +1,330 @@ +.\" +.\" The contents of this file are subject to the terms of the +.\" Common Development and Distribution License (the "License"). +.\" You may not use this file except in compliance with the License. +.\" +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +.\" or http://www.opensolaris.org/os/licensing. +.\" See the License for the specific language governing permissions +.\" and limitations under the License. +.\" +.\" When distributing Covered Code, include this CDDL HEADER in each +.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. +.\" If applicable, add the following below this CDDL HEADER, with the +.\" fields enclosed by brackets "[]" replaced with your own identifying +.\" information: Portions Copyright [yyyy] [name of copyright owner] +.\" +.\" +.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved +.\" Copyright 2020 Joyent, Inc. +.\" +.Dd March 2, 2020 +.Dt HOTPLUG 1M +.Os +.Sh NAME +.Nm hotplug +.Nd configure hotplug connectors and ports +.Sh SYNOPSIS +.Nm +.Fl \&? +.Nm +.Cm list +.Op Fl lv +.Op Ar path +.Op Ar connection +.Nm +.Cm online +.Ar path +.Ar port +.Nm +.Cm offline +.Op Fl fq +.Ar path +.Ar port +.Nm +.Cm enable +.Ar path +.Ar connector +.Nm +.Cm disable +.Op Fl fq +.Ar path +.Ar connector +.Nm +.Cm poweron +.Ar path +.Ar connector +.Nm +.Cm poweroff +.Op Fl fq +.Ar path +.Ar connector +.Nm +.Cm set +.Fl o Ar options +.Ar path +.Ar connector +.Nm +.Cm get +.Fl o Ar options +.Ar path +.Ar connector +.Sh DESCRIPTION +The +.Nm +command is used to manage hotplug connections. +A connection can be a connector or port. +A hotplug connector is a representation of a physical point in the system where +components can be inserted or removed. +A hotplug port is a representation of a logical point in the system device tree +where the connection of a device to the system is managed. +.Pp +The +.Nm +command only supports hotplug operations on hotplug connectors for PCI Express +buses and PCI buses that implement the Standard PCI Hotplug feature. +Hotplug ports on PCI Express and PCI buses in systems with PCI Express fabrics +are also supported. +Additional buses may be supported in the future. +.Pp +The +.Nm +command operates on the following kinds of objects: +.Bl -tag -width "connection" +.It Cm path +Hotplug connectors and ports are integrated into the system device tree. +The names of connectors and ports are unique relative only to their bus +controller. +A device path is required to uniquely reference a connector or port. +.It Cm connector +If a hardware component supports being physically inserted or removed, then a +hotplug connector represents the location where this action may occur. +When a connector exists, it has a hierarchy of ports and device nodes that +depend upon it. +.It Cm port +All device nodes can be virtually hotplugged, even if their hardware does not +support physical hotplugging. +A hotplug port exists between a device node and its parent node in the system +device tree. +It represents the location where the device node and its dependents can be +managed. +.It Cm connection +A hotplug connection is a generic term to refer to either a hotplug connector or +a hotplug port. +.El +.Pp +Hotplug connectors and ports are managed according to a state model. +The +.Nm +command can list information about the hotplug connections in a system, or it +can initiate change of state operations on specific hotplug connections. +.Pp +Hotplug connectors can be in the following states: +.Bl -tag -width "present" +.It Cm empty +A component is not physically inserted in the connector. +.It Cm present +A component is physically inserted in the connector, but the component is +powered off. +The component is not in use. +.It Cm powered +A component is physically inserted in the connector, and the component is +powered on. +The component is disabled and is not in use. +.It Cm enabled +A component is physically inserted in the connector. +The component is powered on and has been probed and tested. +The component is enabled and devices that represent its functions can be used. +.El +.Pp +Hotplug ports can be in the following states: +.Bl -tag -width "port-present" +.It Cm port-empty +No device exists for the hotplug port. +.It Cm port-present +A device exists for the hotplug port, but the device has not been probed and it +has no attached device driver. +The device is not in use. +.It Cm offline +A device exists for the hotplug port, and the device has been probed. +A device driver is not attached, and the device is not in use. +.It Cm online +A device exists for the hotplug port, and its device driver is fully attached. +The device is in use. +.It Cm maintenance +A device exists for the hotplug port, and its device driver is fully attached. +The device is in use, but not fully operational. +A maintenance or fault management operation is affecting the device. +.El +.Pp +The +.Nm +command can also access bus private properties for each hotplug connector. +The current values of bus private properties can be displayed. +New values for each bus private property can be set directly. +.Sh EXIT STATUS +.Bl -diag +.It 0 +Successful completion. +.It 1 +Invalid command line options were specified. +.It 2 +The specified path or connection does not exist. +.It 3 +A fatal error occurred. +One or more error messages are displayed on standard error. +.It 4 +The hotplug service is not available. +.El +.Sh EXAMPLES +.Bl -tag -width 0n +.It Sy Example 1 No Showing All Hotplug Connections +The following command shows all hotplug connections: +.Bd -literal +# hotplug list -v +pci@0,0 + <pci.2,1> (ONLINE) + pci108e,534a@2,1 + [pci30] (EMPTY) + <pci.e,0> (ONLINE) + pci10de,5d@e + <pci.b,0> (ONLINE) + display@b + [NEM0] (ENABLED) + <pci.a,0> (ONLINE) + pci108e,534a@a,0 + { Network interface nge0 } + { nge0: hosts IP addresses: 10.0.0.1 } + <pci.a,1> (MAINTENANCE) + pci108e,534a@a,1 + [NEM1] (EMPTY) + <pci.c,0> (OFFLINE) + pci108e,534a@4 +.Ed +.Pp +To show the full paths of hotplug connections and devices, enter the following +command: +.Bd -literal +# hotplug list -l +/pci@0,0 <pci.2,1> (ONLINE) +/pci@0,0/pci108e,534a@2,1 [pci30] (EMPTY) +/pci@0,0 pci.e,0> (ONLINE) +/pci@0,0/pci10de,5d@e <pci.b,0> (ONLINE) +/pci@0,0/pci10de,5d@e/display@b +/pci@0,0/pci10de,5d@e [NEM0] (ENABLED) +/pci@0,0/pci10de,5d@e <pci.a,0> (ONLINE) +/pci@0,0/pci10de,5d@e/pci108e,534a@a,0 +/pci@0,0/pci10de,5d@e <pci.a,1> (MAINTENANCE) +/pci@0,0/pci10de,5d@e/pci108e,534a@a,0 +/pci@0,0/pci10de,5d@e [NEM1] (EMPTY) +/pci@0,0 pci.c,0> (OFFLINE) +/pci@0,0/pci108e,534a@4 +.Ed +.It Sy Example 2 No Reporting Failure During State Change Operation +If a change of state operation fails, an explanation is displayed to describe +the failure. +An attempt to offline a hotplug port with dependent devices that are currently +in use by the system might fail as follows: +.Bd -literal +# hotplug offline /pci@0,0/pci10de,5d@e pci.a,0 +ERROR: devices or resources are busy. +pci108e,534a@a,0: + { Network interface nge0 } + { nge0: hosts IP addresses: 10.0.0.1 } + { Plumbed IP Address } +.Ed +.It Sy Example 3 No Displaying Bus-Specific Properties and Values +The following command displays all supported bus-specific properties and their +possible values: +.Bd -literal +# hotplug get -o help /pci@0,0 pci.2,1 +power_led=<on|off|blink> +fault_led=<on|off|blink> +active_led=<on|off|blink> +attn_led=<on|off|blink> +card_type=<type description> +board_type=<type description> +.Ed +.It Sy Example 4 Displaying Bus-Specific Options +The following command displays the card type and the current state of the Power +LED of a PCI hotplug connector: +.Bd -literal +# hotplug get -o card_type,power_led /pci@0,0 pci.2,1 +card_type=fibre +power_led=on +.Ed +.It Sy Example 5 No Setting a Bus-Specific Property +The following command turns on the attention LED of a PCI hotplug connector: +.Bd -literal +# hotplug set -o attn_led=on /pci@0,0 pci.2,1 +.Ed +.El +.Sh DIAGNOSTICS +The following error message is displayed on systems that do not have any +supported I/O buses: +.Bd -literal +ERROR: there are no connections to display. +(See hotplug(1m) for more information.) +.Ed +.Pp +If this error message is seen, note that the system might still have other I/O +devices that support hotplugging, through the +.Xr cfgadm 1M +command instead of +.Nm . +.Sh INTERFACE STABILITY +.Sy Committed +.Sh SEE ALSO +.Xr cfgadm 1M , +.Xr hotplugd 1M , +.Xr getsubopt 3C , +.Xr rcmscript 4 , +.Xr attributes 5 +.Sh NOTES +The +.Nm +service +.Po FMRI +.Pa svc:/system/hotplug +.Pc +must be enabled as a prerequisite for using the +.Nm +command. +See +.Xr hotplugd 1M . +.Pp +The authorization +.Pa solaris.hotplug.modify +must be granted in order to perform change-of-state operations. +Alternatively, the rights profile +.Qq Hotplug Management +can be granted, which includes that authorization. +.Pp +Verbose usage information is gathered from the RCM framework. +Its format and content is subject to change. +.Pp +The following bus specific properties are supported in PCI bus controllers: +.Bl -tag -width Ds +.It Cm power_led No \&| Cm fault_led No \&| Cm attn_led No \&| Cm active_led +States of a specific LED of a slot. +The value could be +.Cm on , off , +or +.Cm blink . +.Pp +They can all be used with +.Cm get +subcommand, but only property +.Cm attn_led +can be used with +.Cm set +subcommand. +.It Cm card_type No \&| Cm board_type +Type of a card or board of a slot. +.Pp +They can all be used with +.Cm get +subcommand, but neither can be used with +.Cm set +subcommand. +.El diff --git a/usr/src/man/man1m/tzreload.1m b/usr/src/man/man1m/tzreload.1m new file mode 100644 index 0000000000..335812f177 --- /dev/null +++ b/usr/src/man/man1m/tzreload.1m @@ -0,0 +1,78 @@ +.\" +.\" The contents of this file are subject to the terms of the +.\" Common Development and Distribution License (the "License"). +.\" You may not use this file except in compliance with the License. +.\" +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +.\" or http://www.opensolaris.org/os/licensing. +.\" See the License for the specific language governing permissions +.\" and limitations under the License. +.\" +.\" When distributing Covered Code, include this CDDL HEADER in each +.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. +.\" If applicable, add the following below this CDDL HEADER, with the +.\" fields enclosed by brackets "[]" replaced with your own identifying +.\" information: Portions Copyright [yyyy] [name of copyright owner] +.\" +.\" +.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved +.\" Copyright 2020 Joyent, Inc. +.\" +.Dd February 27, 2020 +.Dt TZRELOAD 1M +.Os +.Sh NAME +.Nm tzreload +.Nd notify timezone update +.Sh SYNOPSIS +.Nm Op Fl a +.Sh DESCRIPTION +The +.Nm +command triggers processes to reread timezone information. +The timezone information is cached in each process. +In response to a +.Nm +command, this cache is updated on the next call to +.Xr ctime 3C +and +.Xr mktime 3C +by each process. +By default, +.Nm +only triggers this update for the current zone. +.Pp +In addition to updating processes, the +.Nm +command also notifies +.Xr cron 1M +to reinitialize the job scheduler with the new timezone information. +.Sh OPTIONS +The following options are supported: +.Bl -tag -width Ds +.It Fl a +Update processes in all zones. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa /usr/share/lib/zoneinfo +Standard zone information directory. +.El +.Sh INTERFACE STABILITY +.Sy Committed +.Sh SEE ALSO +.Xr cron 1M , +.Xr zdump 1M , +.Xr zic 1M , +.Xr zoneadm 1M , +.Xr ctime 3C , +.Xr mktime 3C , +.Xr attributes 5 +.Sh NOTES +Although +.Nm +reinitializes +.Xr cron 1M , +applications that are affected by timezone changes still need to be restarted or +reinitialized if they do not reread the new timezone information before timezone +changes take place. diff --git a/usr/src/man/man3c/directio.3c b/usr/src/man/man3c/directio.3c index 9ca847bec3..f90bf3dcb7 100644 --- a/usr/src/man/man3c/directio.3c +++ b/usr/src/man/man3c/directio.3c @@ -1,9 +1,10 @@ '\" te .\" Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright 2020 Joyent, Inc. .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH DIRECTIO 3C "Apr 9, 2003" +.TH DIRECTIO 3C "Feb 28, 2020" .SH NAME directio \- provide advice to file system .SH SYNOPSIS @@ -130,7 +131,7 @@ when a file is sparse or is being extended and is opened with \fBO_SYNC\fR or \fBO_DSYNC\fR (see \fBopen\fR(2)). .sp .LP -The \fBdirectio()\fR function is supported for the NFS and UFS file system +The \fBdirectio()\fR function is supported for the NFS, UFS and ZFS file system types (see \fBfstyp\fR(1M)). .SH ATTRIBUTES .sp diff --git a/usr/src/man/man3lib/Makefile b/usr/src/man/man3lib/Makefile index a470f408fa..6beb4fcb31 100644 --- a/usr/src/man/man3lib/Makefile +++ b/usr/src/man/man3lib/Makefile @@ -12,103 +12,106 @@ # # Copyright 2011, Richard Lowe # Copyright 2013 Nexenta Systems, Inc. All rights reserved. +# Copyright 2020 Joyent, Inc. # include $(SRC)/Makefile.master -MANSECT= 3lib +MANSECT= 3lib -MANFILES= libMPAPI.3lib \ - libSMHBAAPI.3lib \ - libadm.3lib \ - libaio.3lib \ +MANFILES= libMPAPI.3lib \ + libSMHBAAPI.3lib \ + libadm.3lib \ + libaio.3lib \ libavl.3lib \ - libbsdmalloc.3lib \ - libbsm.3lib \ - libc.3lib \ - libc_db.3lib \ - libcfgadm.3lib \ - libcommputil.3lib \ - libcontract.3lib \ - libcpc.3lib \ - libcrypt.3lib \ - libcurses.3lib \ - libdat.3lib \ - libdevid.3lib \ - libdevinfo.3lib \ - libdl.3lib \ - libdlpi.3lib \ - libdns_sd.3lib \ - libdoor.3lib \ - libdtrace.3lib \ - libefi.3lib \ - libelf.3lib \ - libexacct.3lib \ - libfcoe.3lib \ - libform.3lib \ - libfstyp.3lib \ - libgen.3lib \ - libgss.3lib \ - libintl.3lib \ - libiscsit.3lib \ - libkmf.3lib \ - libkrb5.3lib \ - libkstat.3lib \ - libkvm.3lib \ - libl.3lib \ - liblgrp.3lib \ - libmail.3lib \ - libmalloc.3lib \ - libmapmalloc.3lib \ - libmd.3lib \ - libmd5.3lib \ - libmenu.3lib \ - libmp.3lib \ - libmtmalloc.3lib \ - libnls.3lib \ - libnsl.3lib \ - libnvpair.3lib \ - libpam.3lib \ - libpanel.3lib \ - libpapi.3lib \ - libpctx.3lib \ - libpicl.3lib \ - libpicltree.3lib \ - libpkcs11.3lib \ - libpool.3lib \ + libbsdmalloc.3lib \ + libbsm.3lib \ + libc.3lib \ + libc_db.3lib \ + libcfgadm.3lib \ + libcommputil.3lib \ + libcontract.3lib \ + libcpc.3lib \ + libcrypt.3lib \ + libcurses.3lib \ + libdat.3lib \ + libdevid.3lib \ + libdevinfo.3lib \ + libdl.3lib \ + libdlpi.3lib \ + libdns_sd.3lib \ + libdoor.3lib \ + libdtrace.3lib \ + libefi.3lib \ + libelf.3lib \ + libexacct.3lib \ + libfcoe.3lib \ + libform.3lib \ + libfstyp.3lib \ + libgen.3lib \ + libgss.3lib \ + libintl.3lib \ + libiscsit.3lib \ + libkmf.3lib \ + libkrb5.3lib \ + libkstat.3lib \ + libkvm.3lib \ + libl.3lib \ + liblgrp.3lib \ + libm.3lib \ + libmail.3lib \ + libmalloc.3lib \ + libmapmalloc.3lib \ + libmd.3lib \ + libmd5.3lib \ + libmenu.3lib \ + libmp.3lib \ + libmtmalloc.3lib \ + libmvec.3lib \ + libnls.3lib \ + libnsl.3lib \ + libnvpair.3lib \ + libpam.3lib \ + libpanel.3lib \ + libpapi.3lib \ + libpctx.3lib \ + libpicl.3lib \ + libpicltree.3lib \ + libpkcs11.3lib \ + libpool.3lib \ libproc.3lib \ - libproject.3lib \ - libpthread.3lib \ - libresolv.3lib \ - librpcsvc.3lib \ - librsm.3lib \ - librt.3lib \ - librtld_db.3lib \ - libsasl.3lib \ - libscf.3lib \ - libsctp.3lib \ - libsec.3lib \ - libsecdb.3lib \ - libsendfile.3lib \ - libsip.3lib \ - libslp.3lib \ - libsocket.3lib \ - libstmf.3lib \ - libsys.3lib \ - libsysevent.3lib \ - libtecla.3lib \ - libthread.3lib \ - libtnfctl.3lib \ - libtsalarm.3lib \ - libtsnet.3lib \ - libtsol.3lib \ - libumem.3lib \ - libuuid.3lib \ - libvolmgt.3lib \ + libproject.3lib \ + libpthread.3lib \ + libresolv.3lib \ + librpcsvc.3lib \ + librsm.3lib \ + librt.3lib \ + librtld_db.3lib \ + libsasl.3lib \ + libscf.3lib \ + libsctp.3lib \ + libsec.3lib \ + libsecdb.3lib \ + libsendfile.3lib \ + libsip.3lib \ + libslp.3lib \ + libsocket.3lib \ + libstmf.3lib \ + libsys.3lib \ + libsysevent.3lib \ + libtecla.3lib \ + libthread.3lib \ + libtnfctl.3lib \ + libtsalarm.3lib \ + libtsnet.3lib \ + libtsol.3lib \ + libumem.3lib \ + libuuid.3lib \ libvnd.3lib \ - libw.3lib \ - libxnet.3lib \ - liby.3lib + libvolmgt.3lib \ + libw.3lib \ + libxnet.3lib \ + liby.3lib MANLINKS= SMHBA_GetAdapterAttributes.3lib \ SMHBA_GetAdapterPortAttributes.3lib \ diff --git a/usr/src/man/man3lib/libc.3lib b/usr/src/man/man3lib/libc.3lib index 3978eabae8..83df10408b 100644 --- a/usr/src/man/man3lib/libc.3lib +++ b/usr/src/man/man3lib/libc.3lib @@ -1,4 +1,5 @@ '\" te +.\" Copyright 2020 OmniOS Community Edition (OmniOSce) Association. .\" Copyright 2014 Garrett D'Amore <garrett@damore.org> .\" Copyright (c) 2009, Sun Microsystems, Inc. All rights reserved. .\" Copyright 2016 Joyent, Inc. @@ -6,7 +7,7 @@ .\" See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with .\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] .\" Copyright 2011 by Delphix. All rights reserved. -.TH LIBC 3LIB "Dec 10, 2015" +.TH LIBC 3LIB "Feb 14, 2020" .SH NAME libc \- C library .SH DESCRIPTION @@ -43,54 +44,54 @@ l l . \fB__posix_sigwait\fR \fB__posix_ttyname_r\fR \fB__priocntl\fR \fB__priocntlset\fR \fB__pthread_cleanup_pop\fR \fB__pthread_cleanup_push\fR -\fB__sysconf_xpg5\fR \fB__xpg4\fR -\fB__xpg4_putmsg\fR \fB__xpg4_putpmsg\fR -\fB_Exit\fR \fB_altzone\fR -\fB_assert\fR \fB_cleanup\fR -\fB_ctype\fR \fB_daylight\fR -\fB_environ\fR \fB_exit\fR -\fB_exithandle\fR \fB_filbuf\fR -\fB_flsbuf\fR \fB_flushlbf\fR -\fB_getdate_err\fR \fB_getdate_err_addr\fR -\fB_iob\fR \fB_isnan\fR -\fB_isnand\fR \fB_lwp_cond_broadcast\fR -\fB_lwp_cond_reltimedwait\fR \fB_lwp_cond_signal\fR -\fB_lwp_cond_timedwait\fR \fB_lwp_cond_wait\fR -\fB_lwp_continue\fR \fB_lwp_info\fR -\fB_lwp_kill\fR \fB_lwp_mutex_lock\fR -\fB_lwp_mutex_trylock\fR \fB_lwp_mutex_unlock\fR -\fB_lwp_self\fR \fB_lwp_sema_init\fR -\fB_lwp_sema_post\fR \fB_lwp_sema_trywait\fR -\fB_lwp_sema_wait\fR \fB_lwp_suspend\fR -\fB_lwp_suspend2\fR \fB_modf\fR -\fB_nextafter\fR \fB_nsc_trydoorcall\fR -\fB_nss_XbyY_buf_alloc\fR \fB_nss_XbyY_buf_free\fR -\fB_nss_netdb_aliases\fR \fB_numeric\fR -\fB_scalb\fR \fB_sibuf\fR -\fB_sobuf\fR \fB_stack_grow\fR -\fB_sys_buslist\fR \fB_sys_cldlist\fR -\fB_sys_fpelist\fR \fB_sys_illlist\fR -\fB_sys_segvlist\fR \fB_sys_siginfolistp\fR -\fB_sys_siglist\fR \fB_sys_siglistn\fR -\fB_sys_siglistp\fR \fB_sys_traplist\fR -\fB_timezone\fR \fB_tolower\fR -\fB_toupper\fR \fB_tzname\fR -\fB_xftw\fR \fB\fR -\fBa64l\fR \fBabort\fR -\fBabs\fR \fBaccess\fR -\fBacct\fR \fBacl\fR -\fBaddrtosymstr\fR \fBaddsev\fR -\fBaddseverity\fR \fBadjtime\fR -\fBaio_cancel\fR \fBaio_error\fR -\fBaio_fsync\fR \fBaio_read\fR -\fBaio_return\fR \fBaio_suspend\fR -\fBaio_waitn\fR \fBaio_write\fR -\fBaiocancel\fR \fBaioread\fR -\fBaiowait\fR \fBaiowrite\fR -\fBalarm\fR \fBalphasort\fR -\fBaltzone\fR \fBascftime\fR -\fBasctime\fR \fBasctime_r\fR -\fBasprintf\fR +\fB__sysconf_xpg5\fR \fB__unlockpt_xpg4\fR +\fB__xpg4\fR \fB__xpg4_putmsg\fR +\fB__xpg4_putpmsg\fR \fB_Exit\fR +\fB_altzone\fR \fB_assert\fR +\fB_cleanup\fR \fB_ctype\fR +\fB_daylight\fR \fB_environ\fR +\fB_exit\fR \fB_exithandle\fR +\fB_filbuf\fR \fB_flsbuf\fR +\fB_flushlbf\fR \fB_getdate_err\fR +\fB_getdate_err_addr\fR \fB_iob\fR +\fB_isnan\fR \fB_isnand\fR +\fB_lwp_cond_broadcast\fR \fB_lwp_cond_reltimedwait\fR +\fB_lwp_cond_signal\fR \fB_lwp_cond_timedwait\fR +\fB_lwp_cond_wait\fR \fB_lwp_continue\fR +\fB_lwp_info\fR \fB_lwp_kill\fR +\fB_lwp_mutex_lock\fR \fB_lwp_mutex_trylock\fR +\fB_lwp_mutex_unlock\fR \fB_lwp_self\fR +\fB_lwp_sema_init\fR \fB_lwp_sema_post\fR +\fB_lwp_sema_trywait\fR \fB_lwp_sema_wait\fR +\fB_lwp_suspend\fR \fB_lwp_suspend2\fR +\fB_modf\fR \fB_nextafter\fR +\fB_nsc_trydoorcall\fR \fB_nss_XbyY_buf_alloc\fR +\fB_nss_XbyY_buf_free\fR \fB_nss_netdb_aliases\fR +\fB_numeric\fR \fB_scalb\fR +\fB_sibuf\fR \fB_sobuf\fR +\fB_stack_grow\fR \fB_sys_buslist\fR +\fB_sys_cldlist\fR \fB_sys_fpelist\fR +\fB_sys_illlist\fR \fB_sys_segvlist\fR +\fB_sys_siginfolistp\fR \fB_sys_siglist\fR +\fB_sys_siglistn\fR \fB_sys_siglistp\fR +\fB_sys_traplist\fR \fB_timezone\fR +\fB_tolower\fR \fB_toupper\fR +\fB_tzname\fR \fB_xftw\fR +\fB\fR \fBa64l\fR +\fBabort\fR \fBabs\fR +\fBaccess\fR \fBacct\fR +\fBacl\fR \fBaddrtosymstr\fR +\fBaddsev\fR \fBaddseverity\fR +\fBadjtime\fR \fBaio_cancel\fR +\fBaio_error\fR \fBaio_fsync\fR +\fBaio_read\fR \fBaio_return\fR +\fBaio_suspend\fR \fBaio_waitn\fR +\fBaio_write\fR \fBaiocancel\fR +\fBaioread\fR \fBaiowait\fR +\fBaiowrite\fR \fBalarm\fR +\fBalphasort\fR \fBaltzone\fR +\fBascftime\fR \fBasctime\fR +\fBasctime_r\fR \fBasprintf\fR \fBatexit\fR \fBatof\fR \fBatoi\fR \fBatol\fR \fBatoll\fR \fBatomic_add_16\fR @@ -152,10 +153,9 @@ l l . \fBbcmp\fR \fBbcopy\fR \fBbindtextdomain\fR \fBbind_textdomain_codeset\fR \fBbrk\fR \fBbsd_signal\fR -\fBbsearch\fR -\fBbtowc\fR \fBbtowc_l\fR -\fBbzero\fR \fBcalloc\fR -\fBcanonicalize_file_name\fR +\fBbsearch\fR \fBbtowc\fR +\fBbtowc_l\fR \fBbzero\fR +\fBcalloc\fR \fBcanonicalize_file_name\fR \fBcatclose\fR \fBcatgets\fR \fBcatopen\fR \fBcfgetispeed\fR \fBcfgetospeed\fR \fBcfsetispeed\fR @@ -163,22 +163,21 @@ l l . \fBchdir\fR \fBchmod\fR \fBchown\fR \fBchroot\fR \fBclearerr\fR \fBclearenv\fR -\fBclock\fR -\fBclock_getres\fR \fBclock_gettime\fR -\fBclock_nanosleep\fR \fBclock_settime\fR -\fBclose\fR \fBclosedir\fR -\fBclosefrom\fR \fBcloselog\fR -\fBcond_broadcast\fR \fBcond_destroy\fR -\fBcond_init\fR \fBcond_reltimedwait\fR -\fBcond_signal\fR \fBcond_timedwait\fR -\fBcond_wait\fR \fBconfstr\fR -\fBcreat\fR \fBcrypt\fR -\fBcrypt_genhash_impl\fR \fBcrypt_gensalt\fR -\fBcrypt_gensalt_impl\fR \fBcsetcol\fR -\fBcsetlen\fR \fBctermid\fR -\fBctermid_r\fR \fBctime\fR -\fBctime_r\fR \fBcuserid\fR -\fBdaemon\fR +\fBclock\fR \fBclock_getres\fR +\fBclock_gettime\fR \fBclock_nanosleep\fR +\fBclock_settime\fR \fBclose\fR +\fBclosedir\fR \fBclosefrom\fR +\fBcloselog\fR \fBcond_broadcast\fR +\fBcond_destroy\fR \fBcond_init\fR +\fBcond_reltimedwait\fR \fBcond_signal\fR +\fBcond_timedwait\fR \fBcond_wait\fR +\fBconfstr\fR \fBcreat\fR +\fBcrypt\fR \fBcrypt_genhash_impl\fR +\fBcrypt_gensalt\fR \fBcrypt_gensalt_impl\fR +\fBcsetcol\fR \fBcsetlen\fR +\fBctermid\fR \fBctermid_r\fR +\fBctime\fR \fBctime_r\fR +\fBcuserid\fR \fBdaemon\fR \fBdaylight\fR \fBdbm_clearerr\fR \fBdbm_close\fR \fBdbm_delete\fR \fBdbm_error\fR \fBdbm_fetch\fR @@ -203,9 +202,8 @@ l l . \fBdoor_ucred\fR \fBdoor_unbind\fR \fBdouble_to_decimal\fR \fBdrand48\fR \fBdup\fR \fBdup2\fR -\fBduplocale\fR -\fBeconvert\fR \fBecvt\fR -\fBenable_extended_FILE_stdio\fR +\fBduplocale\fR \fBeconvert\fR +\fBecvt\fR \fBenable_extended_FILE_stdio\fR \fBencrypt\fR \fBendgrent\fR \fBendnetgrent\fR \fBendpwent\fR \fBendspent\fR \fBendusershell\fR @@ -218,10 +216,9 @@ l l . \fBexeclp\fR \fBexecv\fR \fBexecve\fR \fBexecvp\fR \fBexit\fR \fBextended_to_decimal\fR -\fBfaccessat\fR -\fBfacl\fR \fBfattach\fR -\fBfchdir\fR \fBfchmod\fR -\fBfchmodat\fR +\fBfaccessat\fR \fBfacl\fR +\fBfattach\fR \fBfchdir\fR +\fBfchmod\fR \fBfchmodat\fR \fBfchown\fR \fBfchownat\fR \fBfchroot\fR \fBfclose\fR \fBfcloseall\fR \fBfcntl\fR @@ -239,69 +236,66 @@ l l . \fBfgetpwent_r\fR \fBfgets\fR \fBfgetspent\fR \fBfgetspent_r\fR \fBfgetwc\fR \fBfgetwc_l\fR -\fBfgetws\fR -\fBfile_to_decimal\fR \fBfileno\fR -\fBfinite\fR \fBflockfile\fR -\fBfmtmsg\fR \fBfnmatch\fR -\fBfopen\fR \fBfork\fR -\fBfork1\fR \fBforkall\fR -\fBforkallx\fR \fBforkx\fR -\fBfpathconf\fR \fBfpclass\fR -\fBfpgetmask\fR \fBfpgetround\fR -\fBfpgetsticky\fR \fBfprintf\fR -\fBfpsetmask\fR \fBfpsetround\fR -\fBfpsetsticky\fR \fBfputc\fR -\fBfputs\fR \fBfputwc\fR -\fBfputws\fR \fBfread\fR -\fBfree\fR \fBfreelocale\fR -\fBfreopen\fR +\fBfgetws\fR \fBfile_to_decimal\fR +\fBfileno\fR \fBfinite\fR +\fBflockfile\fR \fBfmtmsg\fR +\fBfnmatch\fR \fBfopen\fR +\fBfork\fR \fBfork1\fR +\fBforkall\fR \fBforkallx\fR +\fBforkx\fR \fBfpathconf\fR +\fBfpclass\fR \fBfpgetmask\fR +\fBfpgetround\fR \fBfpgetsticky\fR +\fBfprintf\fR \fBfpsetmask\fR +\fBfpsetround\fR \fBfpsetsticky\fR +\fBfputc\fR \fBfputs\fR +\fBfputwc\fR \fBfputws\fR +\fBfread\fR \fBfree\fR +\fBfreelocale\fR \fBfreopen\fR \fBfrexp\fR \fBfscanf\fR \fBfseek\fR \fBfseeko\fR -\fBfsetattr\fR -\fBfsetpos\fR \fBfstat\fR -\fBfstatat\fR \fBfstatfs\fR -\fBfstatvfs\fR \fBfsync\fR -\fBftell\fR \fBftello\fR -\fBftime\fR \fBftok\fR -\fBftruncate\fR \fBftrylockfile\fR -\fBftw\fR \fBfunc_to_decimal\fR -\fBfunlockfile\fR \fBfutimens\fR -\fBfutimesat\fR +\fBfsetattr\fR \fBfsetpos\fR +\fBfstat\fR \fBfstatat\fR +\fBfstatfs\fR \fBfstatvfs\fR +\fBfsync\fR \fBftell\fR +\fBftello\fR \fBftime\fR +\fBftok\fR \fBftruncate\fR +\fBftrylockfile\fR \fBftw\fR +\fBfunc_to_decimal\fR \fBfunlockfile\fR +\fBfutimens\fR \fBfutimesat\fR \fBfwide\fR \fBfwprintf\fR \fBfwrite\fR \fBfwscanf\fR \fBgconvert\fR \fBgcvt\fR \fBgetacct\fR \fBgetattrat\fR -\fBgetc\fR -\fBgetc_unlocked\fR \fBgetchar\fR -\fBgetchar_unlocked\fR \fBgetcontext\fR -\fBgetcpuid\fR \fBgetcwd\fR -\fBgetdate\fR \fBgetdate_err\fR -\fBgetdents\fR \fBgetdtablesize\fR -\fBgetegid\fR \fBgetenv\fR -\fBgeteuid\fR \fBgetexecname\fR -\fBgetextmntent\fR \fBgetgid\fR -\fBgetgrent\fR \fBgetgrent_r\fR -\fBgetgrgid\fR \fBgetgrgid_r\fR -\fBgetgrnam\fR \fBgetgrnam_r\fR -\fBgetgroups\fR \fBgethomelgroup\fR -\fBgethostid\fR \fBgethostname\fR -\fBgethrtime\fR \fBgethrvtime\fR -\fBgetisax\fR \fBgetitimer\fR -\fBgetloadavg\fR \fBgetlogin\fR -\fBgetlogin_r\fR \fBgetmntany\fR -\fBgetmntent\fR \fBgetmsg\fR -\fBget_nprocs\fR \fBget_nprocs_conf\fR -\fBgetnetgrent\fR \fBgetnetgrent_r\fR -\fBgetopt\fR \fBgetopt_clip\fR -\fBgetopt_long\fR \fBgetopt_long_only\fR -\fBgetpagesize\fR \fBgetpagesizes\fR -\fBgetpass\fR \fBgetpassphrase\fR -\fBgetpeerucred\fR \fBgetpflags\fR -\fBgetpgid\fR \fBgetpgrp\fR -\fBgetpid\fR \fBgetpmsg\fR -\fBgetppid\fR \fBgetppriv\fR -\fBgetpriority\fR \fBgetprogname\fR -\fBgetprojid\fR +\fBgetc\fR \fBgetc_unlocked\fR +\fBgetchar\fR \fBgetchar_unlocked\fR +\fBgetcontext\fR \fBgetcpuid\fR +\fBgetcwd\fR \fBgetdate\fR +\fBgetdate_err\fR \fBgetdents\fR +\fBgetdtablesize\fR \fBgetegid\fR +\fBgetenv\fR \fBgeteuid\fR +\fBgetexecname\fR \fBgetextmntent\fR +\fBgetgid\fR \fBgetgrent\fR +\fBgetgrent_r\fR \fBgetgrgid\fR +\fBgetgrgid_r\fR \fBgetgrnam\fR +\fBgetgrnam_r\fR \fBgetgroups\fR +\fBgethomelgroup\fR \fBgethostid\fR +\fBgethostname\fR \fBgethrtime\fR +\fBgethrvtime\fR \fBgetisax\fR +\fBgetitimer\fR \fBgetloadavg\fR +\fBgetlogin\fR \fBgetlogin_r\fR +\fBgetmntany\fR \fBgetmntent\fR +\fBgetmsg\fR \fBget_nprocs\fR +\fBget_nprocs_conf\fR \fBgetnetgrent\fR +\fBgetnetgrent_r\fR \fBgetopt\fR +\fBgetopt_clip\fR \fBgetopt_long\fR +\fBgetopt_long_only\fR \fBgetpagesize\fR +\fBgetpagesizes\fR \fBgetpass\fR +\fBgetpassphrase\fR \fBgetpeerucred\fR +\fBgetpflags\fR \fBgetpgid\fR +\fBgetpgrp\fR \fBgetpid\fR +\fBgetpmsg\fR \fBgetppid\fR +\fBgetppriv\fR \fBgetpriority\fR +\fBgetprogname\fR \fBgetprojid\fR \fBgetpw\fR \fBgetpwent\fR \fBgetpwent_r\fR \fBgetpwnam\fR \fBgetpwnam_r\fR \fBgetpwuid\fR @@ -320,10 +314,9 @@ l l . \fBgetutxid\fR \fBgetutxline\fR \fBgetvfsany\fR \fBgetvfsent\fR \fBgetvfsfile\fR \fBgetvfsspec\fR -\fBgetw\fR -\fBgetwc\fR \fBgetwc_l\fR -\fBgetwchar\fR \fBgetwchar_l\fR -\fBgetwd\fR +\fBgetw\fR \fBgetwc\fR +\fBgetwc_l\fR \fBgetwchar\fR +\fBgetwchar_l\fR \fBgetwd\fR \fBgetwidth\fR \fBgetws\fR \fBgetzoneid\fR \fBgetzoneidbyname\fR \fBgetzonenamebyid\fR \fBglob\fR @@ -337,27 +330,23 @@ l l . \fBindex\fR \fBinitgroups\fR \fBinitstate\fR \fBinnetgr\fR \fBinsque\fR \fBioctl\fR -\fBis_system_labeled\fR -\fBisaexec\fR +\fBis_system_labeled\fR \fBisaexec\fR \fBisalnum\fR \fBisalnum_l\fR \fBisalpha\fR \fBisalpha_l\fR \fBisascii\fR \fBisastream\fR -\fBisatty\fR -\fBisblank\fR \fBisblank_l\fR -\fBiscntrl\fR \fBiscntrl_l\fR -\fBisdigit\fR \fBisdigit_l\fR -\fBisenglish\fR +\fBisatty\fR \fBisblank\fR +\fBisblank_l\fR \fBiscntrl\fR +\fBiscntrl_l\fR \fBisdigit\fR +\fBisdigit_l\fR \fBisenglish\fR \fBisgraph\fR \fBisgraph_l\fR -\fBisideogram\fR -\fBislower\fR \fBislower_l\fR -\fBisnan\fR +\fBisideogram\fR \fBislower\fR +\fBislower_l\fR \fBisnan\fR \fBisnand\fR \fBisnanf\fR \fBisnumber\fR \fBisphonogram\fR \fBisprint\fR \fBisprint_l\fR \fBispunct\fR \fBispunct_l\fR -\fBissetugid\fR -\fBisspace\fR \fBisspace_l\fR -\fBisspecial\fR +\fBissetugid\fR \fBisspace\fR +\fBisspace_l\fR \fBisspecial\fR \fBisupper\fR \fBisupper_l\fR \fBiswalnum\fR \fBiswalnum_l\fR \fBiswalpha\fR \fBiswalpha_l\fR @@ -398,31 +387,29 @@ l l . \fBlsub\fR \fBlten\fR \fBlzero\fR \fBmadvise\fR \fBmakecontext\fR \fBmakeutx\fR -\fBmalloc\fR -\fBmblen\fR \fBmblen_l\fR -\fBmbrlen\fR \fBmbrlen_l\fR -\fBmbrtowc\fR \fBmbrtowc_l\fR -\fBmbsinit\fR \fBmbsinit_l\fR -\fBmbsnrtowcs\fR \fBmbsnrtowcs_l\fR -\fBmbsrtowcs\fR \fBmbsrtowcs_l\fR -\fBmbstowcs\fR \fBmbstowcs_l\fR -\fBmbtowc\fR \fBmbtowc_l\fR -\fBmemalign\fR \fBmembar_consumer\fR -\fBmembar_enter\fR \fBmembar_exit\fR -\fBmembar_producer\fR \fBmemccpy\fR -\fBmemchr\fR \fBmemcmp\fR -\fBmemcntl\fR \fBmemcpy\fR -\fBmeminfo\fR \fBmemmem\fR -\fBmemmove\fR +\fBmalloc\fR \fBmblen\fR +\fBmblen_l\fR \fBmbrlen\fR +\fBmbrlen_l\fR \fBmbrtowc\fR +\fBmbrtowc_l\fR \fBmbsinit\fR +\fBmbsinit_l\fR \fBmbsnrtowcs\fR +\fBmbsnrtowcs_l\fR \fBmbsrtowcs\fR +\fBmbsrtowcs_l\fR \fBmbstowcs\fR +\fBmbstowcs_l\fR \fBmbtowc\fR +\fBmbtowc_l\fR \fBmemalign\fR +\fBmembar_consumer\fR \fBmembar_enter\fR +\fBmembar_exit\fR \fBmembar_producer\fR +\fBmemccpy\fR \fBmemchr\fR +\fBmemcmp\fR \fBmemcntl\fR +\fBmemcpy\fR \fBmeminfo\fR +\fBmemmem\fR \fBmemmove\fR \fBmemset\fR \fBmincore\fR \fBmkdir\fR \fBmkdirat\fR \fBmkfifo\fR \fBmkfifoat\fR \fBmknod\fR \fBmknodat\fR -\fBmkstemp\fR -\fBmktemp\fR \fBmktime\fR -\fBmlock\fR \fBmlockall\fR -\fBmmap\fR \fBmmapobj\fR -\fBmodctl\fR +\fBmkstemp\fR \fBmktemp\fR +\fBmktime\fR \fBmlock\fR +\fBmlockall\fR \fBmmap\fR +\fBmmapobj\fR \fBmodctl\fR \fBmodf\fR \fBmodff\fR \fBmodutx\fR \fBmonitor\fR \fBmount\fR \fBmprotect\fR @@ -445,34 +432,31 @@ l l . \fBnfs_getfh\fR \fBnftw\fR \fBngettext\fR \fBnice\fR \fBnl_langinfo\fR \fBnl_langinfo_l\fR -\fBnrand48\fR -\fBnss_default_finders\fR \fBnss_delete\fR -\fBnss_endent\fR \fBnss_getent\fR -\fBnss_search\fR \fBnss_setent\fR -\fBntp_adjtime\fR \fBntp_gettime\fR -\fBopen\fR \fBopenat\fR -\fBopendir\fR \fBopenlog\fR -\fBoptarg\fR \fBopterr\fR -\fBoptind\fR \fBoptopt\fR -\fBp_online\fR \fBpathconf\fR -\fBpause\fR \fBpclose\fR -\fBpcsample\fR \fBperror\fR -\fBpfmt\fR \fBpipe\fR -\fBplock\fR \fBpoll\fR -\fBpopen\fR \fBport_alert\fR -\fBport_associate\fR \fBport_create\fR -\fBport_dissociate\fR \fBport_get\fR -\fBport_getn\fR \fBport_send\fR -\fBport_sendn\fR \fBposix_fadvise\fR -\fBposix_fallocate\fR \fBposix_madvise\fR -\fBposix_memalign\fR \fBposix_openpt\fR -\fBposix_spawn\fR \fBposix_spawn_file_actions_addclose\fR -\fBposix_spawn_file_actions_addclosefrom_np\fR \fBposix_spawn_file_actions_adddup2\fR -\fBposix_spawn_file_actions_addopen\fR -\fBposix_spawn_file_actions_destroy\fR -\fBposix_spawn_file_actions_init\fR -\fBposix_spawn_pipe_np\fR -\fBposix_spawnattr_destroy\fR +\fBnrand48\fR \fBnss_default_finders\fR +\fBnss_delete\fR \fBnss_endent\fR +\fBnss_getent\fR \fBnss_search\fR +\fBnss_setent\fR \fBntp_adjtime\fR +\fBntp_gettime\fR \fBopen\fR +\fBopenat\fR \fBopendir\fR +\fBopenlog\fR \fBoptarg\fR +\fBopterr\fR \fBoptind\fR +\fBoptopt\fR \fBp_online\fR +\fBpathconf\fR \fBpause\fR +\fBpclose\fR \fBpcsample\fR +\fBperror\fR \fBpfmt\fR +\fBpipe\fR \fBplock\fR +\fBpoll\fR \fBpopen\fR +\fBport_alert\fR \fBport_associate\fR +\fBport_create\fR \fBport_dissociate\fR +\fBport_get\fR \fBport_getn\fR +\fBport_send\fR \fBport_sendn\fR +\fBposix_fadvise\fR \fBposix_fallocate\fR +\fBposix_madvise\fR \fBposix_memalign\fR +\fBposix_openpt\fR \fBposix_spawn\fR +\fBposix_spawn_file_actions_addclose\fR \fBposix_spawn_file_actions_addclosefrom_np\fR +\fBposix_spawn_file_actions_adddup2\fR \fBposix_spawn_file_actions_addopen\fR +\fBposix_spawn_file_actions_destroy\fR \fBposix_spawn_file_actions_init\fR +\fBposix_spawn_pipe_np\fR \fBposix_spawnattr_destroy\fR \fBposix_spawnattr_getflags\fR \fBposix_spawnattr_getpgroup\fR \fBposix_spawnattr_getschedparam\fR \fBposix_spawnattr_getschedpolicy\fR \fBposix_spawnattr_getsigdefault\fR \fBposix_spawnattr_getsigignore_np\fR @@ -482,30 +466,29 @@ l l . \fBposix_spawnattr_setsigdefault\fR \fBposix_spawnattr_setsigignore_np\fR \fBposix_spawnattr_setsigmask\fR \fBposix_spawnp\fR \fBpread\fR \fBpreadv\fR -\fBprintf\fR -\fBprintstack\fR \fBpriocntl\fR -\fBpriocntlset\fR \fBpriv_addset\fR -\fBpriv_allocset\fR \fBpriv_copyset\fR -\fBpriv_delset\fR \fBpriv_emptyset\fR -\fBpriv_fillset\fR \fBpriv_freeset\fR -\fBpriv_getbyname\fR \fBpriv_getbynum\fR -\fBpriv_getsetbyname\fR \fBpriv_getsetbynum\fR -\fBpriv_gettext\fR \fBpriv_ineffect\fR -\fBpriv_intersect\fR \fBpriv_inverse\fR -\fBpriv_isemptyset\fR \fBpriv_isequalset\fR -\fBpriv_isfullset\fR \fBpriv_ismember\fR -\fBpriv_issubset\fR \fBpriv_set\fR -\fBpriv_set_to_str\fR \fBpriv_str_to_set\fR -\fBpriv_union\fR \fBprocessor_bind\fR -\fBprocessor_info\fR \fBprofil\fR -\fBpselect\fR \fBpset_assign\fR -\fBpset_bind\fR \fBpset_create\fR -\fBpset_destroy\fR \fBpset_getattr\fR -\fBpset_getloadavg\fR \fBpset_info\fR -\fBpset_list\fR \fBpset_setattr\fR -\fBpsiginfo\fR \fBpsignal\fR -\fBpthread_atfork\fR \fBpthread_attr_destroy\fR -\fBpthread_attr_get_np\fR +\fBprintf\fR \fBprintstack\fR +\fBpriocntl\fR \fBpriocntlset\fR +\fBpriv_addset\fR \fBpriv_allocset\fR +\fBpriv_copyset\fR \fBpriv_delset\fR +\fBpriv_emptyset\fR \fBpriv_fillset\fR +\fBpriv_freeset\fR \fBpriv_getbyname\fR +\fBpriv_getbynum\fR \fBpriv_getsetbyname\fR +\fBpriv_getsetbynum\fR \fBpriv_gettext\fR +\fBpriv_ineffect\fR \fBpriv_intersect\fR +\fBpriv_inverse\fR \fBpriv_isemptyset\fR +\fBpriv_isequalset\fR \fBpriv_isfullset\fR +\fBpriv_ismember\fR \fBpriv_issubset\fR +\fBpriv_set\fR \fBpriv_set_to_str\fR +\fBpriv_str_to_set\fR \fBpriv_union\fR +\fBprocessor_bind\fR \fBprocessor_info\fR +\fBprofil\fR \fBpselect\fR +\fBpset_assign\fR \fBpset_bind\fR +\fBpset_create\fR \fBpset_destroy\fR +\fBpset_getattr\fR \fBpset_getloadavg\fR +\fBpset_info\fR \fBpset_list\fR +\fBpset_setattr\fR \fBpsiginfo\fR +\fBpsignal\fR \fBpthread_atfork\fR +\fBpthread_attr_destroy\fR \fBpthread_attr_get_np\fR \fBpthread_attr_getdetachstate\fR \fBpthread_attr_getguardsize\fR \fBpthread_attr_getinheritsched\fR \fBpthread_attr_getschedparam\fR \fBpthread_attr_getschedpolicy\fR \fBpthread_attr_getscope\fR @@ -531,44 +514,43 @@ l l . \fBpthread_getconcurrency\fR \fBpthread_getschedparam\fR \fBpthread_getspecific\fR \fBpthread_join\fR \fBpthread_key_create\fR \fBpthread_key_create_once_np\fR -\fBpthread_key_delete\fR -\fBpthread_kill\fR \fBpthread_mutex_consistent\fR -\fBpthread_mutex_destroy\fR \fBpthread_mutex_getprioceiling\fR -\fBpthread_mutex_init\fR \fBpthread_mutex_lock\fR -\fBpthread_mutex_reltimedlock_np\fR \fBpthread_mutex_setprioceiling\fR -\fBpthread_mutex_timedlock\fR \fBpthread_mutex_trylock\fR -\fBpthread_mutex_unlock\fR \fBpthread_mutexattr_destroy\fR -\fBpthread_mutexattr_getprioceiling\fR \fBpthread_mutexattr_getprotocol\fR -\fBpthread_mutexattr_getpshared\fR \fBpthread_mutexattr_getrobust\fR -\fBpthread_mutexattr_gettype\fR \fBpthread_mutexattr_init\fR -\fBpthread_mutexattr_setprioceiling\fR \fBpthread_mutexattr_setprotocol\fR -\fBpthread_mutexattr_setpshared\fR \fBpthread_mutexattr_setrobust\fR -\fBpthread_mutexattr_settype\fR \fBpthread_once\fR -\fBpthread_rwlock_destroy\fR \fBpthread_rwlock_init\fR -\fBpthread_rwlock_rdlock\fR \fBpthread_rwlock_reltimedrdlock_np\fR -\fBpthread_rwlock_reltimedwrlock_np\fR \fBpthread_rwlock_timedrdlock\fR -\fBpthread_rwlock_timedwrlock\fR \fBpthread_rwlock_tryrdlock\fR -\fBpthread_rwlock_trywrlock\fR \fBpthread_rwlock_unlock\fR -\fBpthread_rwlock_wrlock\fR \fBpthread_rwlockattr_destroy\fR -\fBpthread_rwlockattr_getpshared\fR \fBpthread_rwlockattr_init\fR -\fBpthread_rwlockattr_setpshared\fR \fBpthread_self\fR -\fBpthread_setcancelstate\fR \fBpthread_setcanceltype\fR -\fBpthread_setconcurrency\fR \fBpthread_setspecific\fR -\fBpthread_sigmask\fR \fBpthread_setschedparam\fR -\fBpthread_setschedprio\fR \fBpthread_spin_destroy\fR -\fBpthread_spin_init\fR \fBpthread_spin_lock\fR -\fBpthread_spin_trylock\fR \fBpthread_spin_unlock\fR -\fBpthread_testcancel\fR \fBptsname\fR -\fBputacct\fR \fBputc\fR -\fBputc_unlocked\fR \fBputchar\fR -\fBputchar_unlocked\fR \fBputenv\fR -\fBputmsg\fR \fBputpmsg\fR -\fBputpwent\fR \fBputs\fR -\fBputspent\fR \fBpututline\fR -\fBpututxline\fR \fBputw\fR -\fBputwc\fR \fBputwchar\fR -\fBputws\fR \fBpwrite\fR -\fBpwritev\fR +\fBpthread_key_delete\fR \fBpthread_kill\fR +\fBpthread_mutex_consistent\fR \fBpthread_mutex_destroy\fR +\fBpthread_mutex_getprioceiling\fR \fBpthread_mutex_init\fR +\fBpthread_mutex_lock\fR \fBpthread_mutex_reltimedlock_np\fR +\fBpthread_mutex_setprioceiling\fR \fBpthread_mutex_timedlock\fR +\fBpthread_mutex_trylock\fR \fBpthread_mutex_unlock\fR +\fBpthread_mutexattr_destroy\fR \fBpthread_mutexattr_getprioceiling\fR +\fBpthread_mutexattr_getprotocol\fR \fBpthread_mutexattr_getpshared\fR +\fBpthread_mutexattr_getrobust\fR \fBpthread_mutexattr_gettype\fR +\fBpthread_mutexattr_init\fR \fBpthread_mutexattr_setprioceiling\fR +\fBpthread_mutexattr_setprotocol\fR \fBpthread_mutexattr_setpshared\fR +\fBpthread_mutexattr_setrobust\fR \fBpthread_mutexattr_settype\fR +\fBpthread_once\fR \fBpthread_rwlock_destroy\fR +\fBpthread_rwlock_init\fR \fBpthread_rwlock_rdlock\fR +\fBpthread_rwlock_reltimedrdlock_np\fR \fBpthread_rwlock_reltimedwrlock_np\fR +\fBpthread_rwlock_timedrdlock\fR \fBpthread_rwlock_timedwrlock\fR +\fBpthread_rwlock_tryrdlock\fR \fBpthread_rwlock_trywrlock\fR +\fBpthread_rwlock_unlock\fR \fBpthread_rwlock_wrlock\fR +\fBpthread_rwlockattr_destroy\fR \fBpthread_rwlockattr_getpshared\fR +\fBpthread_rwlockattr_init\fR \fBpthread_rwlockattr_setpshared\fR +\fBpthread_self\fR \fBpthread_setcancelstate\fR +\fBpthread_setcanceltype\fR \fBpthread_setconcurrency\fR +\fBpthread_setspecific\fR \fBpthread_sigmask\fR +\fBpthread_setschedparam\fR \fBpthread_setschedprio\fR +\fBpthread_spin_destroy\fR \fBpthread_spin_init\fR +\fBpthread_spin_lock\fR \fBpthread_spin_trylock\fR +\fBpthread_spin_unlock\fR \fBpthread_testcancel\fR +\fBptsname\fR \fBputacct\fR +\fBputc\fR \fBputc_unlocked\fR +\fBputchar\fR \fBputchar_unlocked\fR +\fBputenv\fR \fBputmsg\fR +\fBputpmsg\fR \fBputpwent\fR +\fBputs\fR \fBputspent\fR +\fBpututline\fR \fBpututxline\fR +\fBputw\fR \fBputwc\fR +\fBputwchar\fR \fBputws\fR +\fBpwrite\fR \fBpwritev\fR \fBqeconvert\fR \fBqecvt\fR \fBqfconvert\fR \fBqfcvt\fR \fBqgconvert\fR \fBqgcvt\fR @@ -586,58 +568,56 @@ l l . \fBre_comp\fR \fBre_exec\fR \fBread\fR \fBreaddir\fR \fBreaddir_r\fR \fBreadlink\fR -\fBreadlinkat\fR -\fBreadv\fR \fBrealloc\fR -\fBrealpath\fR \fBreboot\fR -\fBregcmp\fR \fBregcomp\fR -\fBregerror\fR \fBregex\fR -\fBregexec\fR \fBregfree\fR -\fBremove\fR \fBremque\fR -\fBrename\fR \fBrenameat\fR -\fBresetmnttab\fR \fBresolvepath\fR -\fBrewind\fR \fBrewinddir\fR -\fBrindex\fR \fBrmdir\fR -\fBrw_rdlock\fR \fBrw_read_held\fR -\fBrw_tryrdlock\fR \fBrw_trywrlock\fR -\fBrw_unlock\fR \fBrw_write_held\fR -\fBrw_wrlock\fR \fBrwlock_destroy\fR -\fBrwlock_init\fR \fBsbrk\fR -\fBscalb\fR \fBscandir\fR -\fBscanf\fR \fBsched_get_priority_max\fR -\fBsched_get_priority_min\fR \fBsched_getparam\fR -\fBsched_getscheduler\fR \fBsched_rr_get_interval\fR -\fBsched_setparam\fR \fBsched_setscheduler\fR -\fBsched_yield\fR \fBschedctl_exit\fR -\fBschedctl_init\fR \fBschedctl_lookup\fR -\fBschedctl_start\fR \fBschedctl_stop\fR -\fBseconvert\fR \fBseed48\fR -\fBseekdir\fR \fBselect\fR -\fBsem_close\fR \fBsem_destroy\fR -\fBsem_getvalue\fR \fBsem_init\fR -\fBsem_open\fR \fBsem_post\fR -\fBsem_reltimedwait_np\fR \fBsem_timedwait\fR -\fBsem_trywait\fR \fBsem_unlink\fR -\fBsem_wait\fR +\fBreadlinkat\fR \fBreadv\fR +\fBrealloc\fR \fBrealpath\fR +\fBreboot\fR \fBregcmp\fR +\fBregcomp\fR \fBregerror\fR +\fBregex\fR \fBregexec\fR +\fBregfree\fR \fBremove\fR +\fBremque\fR \fBrename\fR +\fBrenameat\fR \fBresetmnttab\fR +\fBresolvepath\fR \fBrewind\fR +\fBrewinddir\fR \fBrindex\fR +\fBrmdir\fR \fBrw_rdlock\fR +\fBrw_read_held\fR \fBrw_tryrdlock\fR +\fBrw_trywrlock\fR \fBrw_unlock\fR +\fBrw_write_held\fR \fBrw_wrlock\fR +\fBrwlock_destroy\fR \fBrwlock_init\fR +\fBsbrk\fR \fBscalb\fR +\fBscandir\fR \fBscanf\fR +\fBsched_get_priority_max\fR \fBsched_get_priority_min\fR +\fBsched_getparam\fR \fBsched_getscheduler\fR +\fBsched_rr_get_interval\fR \fBsched_setparam\fR +\fBsched_setscheduler\fR \fBsched_yield\fR +\fBschedctl_exit\fR \fBschedctl_init\fR +\fBschedctl_lookup\fR \fBschedctl_start\fR +\fBschedctl_stop\fR \fBseconvert\fR +\fBseed48\fR \fBseekdir\fR +\fBselect\fR \fBsem_close\fR +\fBsem_destroy\fR \fBsem_getvalue\fR +\fBsem_init\fR \fBsem_open\fR +\fBsem_post\fR \fBsem_reltimedwait_np\fR +\fBsem_timedwait\fR \fBsem_trywait\fR +\fBsem_unlink\fR \fBsem_wait\fR \fBsema_destroy\fR \fBsema_held\fR \fBsema_init\fR \fBsema_post\fR \fBsema_trywait\fR \fBsema_wait\fR \fBsemctl\fR \fBsemget\fR \fBsemids\fR \fBsemop\fR \fBsemtimedop\fR \fBsetattrat\fR -\fBsetbuf\fR -\fBsetbuffer\fR \fBsetcat\fR -\fBsetcontext\fR \fBsetegid\fR -\fBsetenv\fR \fBseteuid\fR -\fBsetgid\fR \fBsetgrent\fR -\fBsetgroups\fR \fBsethostname\fR -\fBsetitimer\fR \fBsetjmp\fR -\fBsetkey\fR \fBsetlabel\fR -\fBsetlinebuf\fR \fBsetlocale\fR -\fBsetlogmask\fR \fBsetnetgrent\fR -\fBsetpflags\fR \fBsetpgid\fR -\fBsetpgrp\fR \fBsetppriv\fR -\fBsetpriority\fR \fBsetprogname\fR -\fBsetpwent\fR +\fBsetbuf\fR \fBsetbuffer\fR +\fBsetcat\fR \fBsetcontext\fR +\fBsetegid\fR \fBsetenv\fR +\fBseteuid\fR \fBsetgid\fR +\fBsetgrent\fR \fBsetgroups\fR +\fBsethostname\fR \fBsetitimer\fR +\fBsetjmp\fR \fBsetkey\fR +\fBsetlabel\fR \fBsetlinebuf\fR +\fBsetlocale\fR \fBsetlogmask\fR +\fBsetnetgrent\fR \fBsetpflags\fR +\fBsetpgid\fR \fBsetpgrp\fR +\fBsetppriv\fR \fBsetpriority\fR +\fBsetprogname\fR \fBsetpwent\fR \fBsetrctl\fR \fBsetregid\fR \fBsetreuid\fR \fBsetrlimit\fR \fBsetsid\fR \fBsetspent\fR @@ -659,14 +639,13 @@ l l . \fBsiglongjmp\fR \fBsignal\fR \fBsigpause\fR \fBsigpending\fR \fBsigprocmask\fR \fBsigqueue\fR -\fBsigrelse\fR -\fBsigsend\fR \fBsigsendset\fR -\fBsigset\fR \fBsigsetjmp\fR -\fBsigstack\fR \fBsigsuspend\fR -\fBsigtimedwait\fR \fBsigwait\fR -\fBsigwaitinfo\fR \fBsingle_to_decimal\fR -\fBsleep\fR \fBsmt_pause\fR -\fBsnprintf\fR +\fBsigrelse\fR \fBsigsend\fR +\fBsigsendset\fR \fBsigset\fR +\fBsigsetjmp\fR \fBsigstack\fR +\fBsigsuspend\fR \fBsigtimedwait\fR +\fBsigwait\fR \fBsigwaitinfo\fR +\fBsingle_to_decimal\fR \fBsleep\fR +\fBsmt_pause\fR \fBsnprintf\fR \fBsprintf\fR \fBsrand\fR \fBsrand48\fR \fBsrandom\fR \fBsscanf\fR \fBssignal\fR @@ -674,16 +653,15 @@ l l . \fBstack_setbounds\fR \fBstack_violation\fR \fBstat\fR \fBstatfs\fR \fBstatvfs\fR \fBstime\fR -\fBstr2sig\fR -\fBstrcasecmp\fR \fBstrcasecmp_l\fR -\fBstrcat\fR \fBstrchr\fR -\fBstrcmp\fR \fBstrcoll\fR -\fBstrcpy\fR \fBstrcspn\fR -\fBstrdup\fR \fBstrerror\fR -\fBstrerror_l\fR \fBstrerror_r\fR -\fBstrfmon\fR \fBstrfmon_l\fR -\fBstrftime\fR \fBstrftime_l\fR -\fBstring_to_decimal\fR +\fBstr2sig\fR \fBstrcasecmp\fR +\fBstrcasecmp_l\fR \fBstrcat\fR +\fBstrchr\fR \fBstrcmp\fR +\fBstrcoll\fR \fBstrcpy\fR +\fBstrcspn\fR \fBstrdup\fR +\fBstrerror\fR \fBstrerror_l\fR +\fBstrerror_r\fR \fBstrfmon\fR +\fBstrfmon_l\fR \fBstrftime\fR +\fBstrftime_l\fR \fBstring_to_decimal\fR \fBstrlcat\fR \fBstrlcpy\fR \fBstrlen\fR \fBstrncasecmp\fR \fBstrncasecmp_l\fR \fBstrncat\fR @@ -702,23 +680,22 @@ l l . \fBswab\fR \fBswapcontext\fR \fBswapctl\fR \fBswprintf\fR \fBswscanf\fR \fBsymlink\fR -\fBsymlinkat\fR -\fBsync\fR \fBsync_instruction_memory\fR -\fBsysconf\fR \fBsysfs\fR -\fBsysinfo\fR \fBsyslog\fR -\fBsystem\fR \fBtcdrain\fR -\fBtcflow\fR \fBtcflush\fR -\fBtcgetattr\fR \fBtcgetpgrp\fR -\fBtcgetsid\fR \fBtcsendbreak\fR -\fBtcsetattr\fR \fBtcsetpgrp\fR -\fBtdelete\fR \fBtell\fR -\fBtelldir\fR \fBtempnam\fR -\fBtextdomain\fR \fBtfind\fR -\fBthr_continue\fR \fBthr_create\fR -\fBthr_exit\fR \fBthr_getconcurrency\fR -\fBthr_getprio\fR \fBthr_getspecific\fR -\fBthr_join\fR \fBthr_keycreate\fR -\fBthr_keycreate_once\fR +\fBsymlinkat\fR \fBsync\fR +\fBsync_instruction_memory\fR \fBsysconf\fR +\fBsysfs\fR \fBsysinfo\fR +\fBsyslog\fR \fBsystem\fR +\fBtcdrain\fR \fBtcflow\fR +\fBtcflush\fR \fBtcgetattr\fR +\fBtcgetpgrp\fR \fBtcgetsid\fR +\fBtcsendbreak\fR \fBtcsetattr\fR +\fBtcsetpgrp\fR \fBtdelete\fR +\fBtell\fR \fBtelldir\fR +\fBtempnam\fR \fBtextdomain\fR +\fBtfind\fR \fBthr_continue\fR +\fBthr_create\fR \fBthr_exit\fR +\fBthr_getconcurrency\fR \fBthr_getprio\fR +\fBthr_getspecific\fR \fBthr_join\fR +\fBthr_keycreate\fR \fBthr_keycreate_once\fR \fBthr_kill\fR \fBthr_main\fR \fBthr_min_stack\fR \fBthr_self\fR \fBthr_setconcurrency\fR \fBthr_setprio\fR @@ -727,42 +704,40 @@ l l . \fBthr_yield\fR \fBtime\fR \fBtimer_create\fR \fBtimer_delete\fR \fBtimer_getoverrun\fR \fBtimer_gettime\fR -\fBtimer_settime\fR -\fBtimes\fR \fBtimezone\fR -\fBtmpfile\fR \fBtmpnam\fR -\fBtmpnam_r\fR \fBtoascii\fR -\fBtolower\fR \fBtolower_l\fR -\fBtoupper\fR \fBtoupper_l\fR -\fBtowctrans\fR \fBtowctrans_l\fR -\fBtowlower\fR \fBtowlower_l\fR -\fBtowupper\fR \fBtowupper_l\fR -\fBtruncate\fR +\fBtimer_settime\fR \fBtimes\fR +\fBtimezone\fR \fBtmpfile\fR +\fBtmpnam\fR \fBtmpnam_r\fR +\fBtoascii\fR \fBtolower\fR +\fBtolower_l\fR \fBtoupper\fR +\fBtoupper_l\fR \fBtowctrans\fR +\fBtowctrans_l\fR \fBtowlower\fR +\fBtowlower_l\fR \fBtowupper\fR +\fBtowupper_l\fR \fBtruncate\fR \fBtsearch\fR \fBttyname\fR \fBttyname_r\fR \fBttyslot\fR \fBtwalk\fR \fBtzname\fR \fBtzset\fR \fBu8_strcmp\fR \fBu8_textprep_str\fR \fBu8_validate\fR -\fBuadmin\fR -\fBualarm\fR \fBuconv_u16tou32\fR -\fBuconv_u16tou8\fR \fBuconv_u32tou16\fR -\fBuconv_u32tou8\fR \fBuconv_u8tou16\fR -\fBuconv_u8tou32\fR \fBucred_free\fR -\fBucred_get\fR \fBucred_getegid\fR -\fBucred_geteuid\fR \fBucred_getgroups\fR -\fBucred_getpflags\fR \fBucred_getpid\fR -\fBucred_getprivset\fR \fBucred_getprojid\fR -\fBucred_getrgid\fR \fBucred_getruid\fR -\fBucred_getsgid\fR \fBucred_getsuid\fR -\fBucred_getzoneid\fR \fBucred_size\fR -\fBulckpwdf\fR \fBulimit\fR -\fBulltostr\fR \fBumask\fR -\fBumount\fR \fBumount2\fR -\fBuname\fR \fBungetc\fR -\fBungetwc\fR \fBunlink\fR -\fBunlinkat\fR \fBunlockpt\fR -\fBunordered\fR \fBunsetenv\fR -\fBupdwtmp\fR \fBupdwtmpx\fR -\fBuselocale\fR +\fBuadmin\fR \fBualarm\fR +\fBuconv_u16tou32\fR \fBuconv_u16tou8\fR +\fBuconv_u32tou16\fR \fBuconv_u32tou8\fR +\fBuconv_u8tou16\fR \fBuconv_u8tou32\fR +\fBucred_free\fR \fBucred_get\fR +\fBucred_getegid\fR \fBucred_geteuid\fR +\fBucred_getgroups\fR \fBucred_getpflags\fR +\fBucred_getpid\fR \fBucred_getprivset\fR +\fBucred_getprojid\fR \fBucred_getrgid\fR +\fBucred_getruid\fR \fBucred_getsgid\fR +\fBucred_getsuid\fR \fBucred_getzoneid\fR +\fBucred_size\fR \fBulckpwdf\fR +\fBulimit\fR \fBulltostr\fR +\fBumask\fR \fBumount\fR +\fBumount2\fR \fBuname\fR +\fBungetc\fR \fBungetwc\fR +\fBunlink\fR \fBunlinkat\fR +\fBunlockpt\fR \fBunordered\fR +\fBunsetenv\fR \fBupdwtmp\fR +\fBupdwtmpx\fR \fBuselocale\fR \fBusleep\fR \fBustat\fR \fButime\fR \fButimensat\fR \fButimes\fR \fButmpname\fR @@ -787,26 +762,24 @@ l l . \fBwcpcpy\fR \fBwcpncpy\fR \fBwcrtomb\fR \fBwcrtomb_l\fR \fBwcscasecmp\fR \fBwcscasecmp_l\fR -\fBwcscat\fR -\fBwcschr\fR \fBwcscmp\fR -\fBwcscoll\fR \fBwcscoll_l\fR -\fBwcscpy\fR \fBwcscspn\fR -\fBwcsdup\fR \fBwcsftime\fR -\fBwcslen\fR \fBwcsncat\fR -\fBwcsncasecmp\fR \fBwcsncasecmp_l\fR -\fBwcsncmp\fR \fBwcsncpy\fR -\fBwcsnrtombs\fR \fBwcsnrtombs_l\fR -\fBwcspbrk\fR \fBwcsrchr\fR -\fBwcsrtombs\fR \fBwcsrtombs_l\fR -\fBwcsspn\fR +\fBwcscat\fR \fBwcschr\fR +\fBwcscmp\fR \fBwcscoll\fR +\fBwcscoll_l\fR \fBwcscpy\fR +\fBwcscspn\fR \fBwcsdup\fR +\fBwcsftime\fR \fBwcslen\fR +\fBwcsncat\fR \fBwcsncasecmp\fR +\fBwcsncasecmp_l\fR \fBwcsncmp\fR +\fBwcsncpy\fR \fBwcsnrtombs\fR +\fBwcsnrtombs_l\fR \fBwcspbrk\fR +\fBwcsrchr\fR \fBwcsrtombs\fR +\fBwcsrtombs_l\fR \fBwcsspn\fR \fBwcsstr\fR \fBwcstod\fR \fBwcstof\fR \fBwcstoimax\fR \fBwcstok\fR \fBwcstol\fR \fBwcstold\fR \fBwcstoll\fR \fBwcstombs\fR \fBwctombs_l\fR -\fBwcstoul\fR -\fBwcstoull\fR \fBwcstoumax\fR -\fBwcswcs\fR +\fBwcstoul\fR \fBwcstoull\fR +\fBwcstoumax\fR \fBwcswcs\fR \fBwcswidth\fR \fBwcswidth_l\fR \fBwcsxfrm\fR \fBwcsxfrm_l\fR \fBwctob\fR \fBwctob_l\fR diff --git a/usr/src/man/man3lib/libm.3lib b/usr/src/man/man3lib/libm.3lib new file mode 100644 index 0000000000..61ada1bbde --- /dev/null +++ b/usr/src/man/man3lib/libm.3lib @@ -0,0 +1,672 @@ +'\" te +.\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright 2020 Joyent, Inc. +.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. +.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] +.TH libm 3LIB "Feb 27, 2020" +.SH NAME +libm \- C math library +.SH SYNOPSIS +.nf +c99 [ \fIflag\fR... ] \fIfile\fR... \fB-lm\fR [ \fIlibrary\fR... ] +.fi + +.SH DESCRIPTION +Functions in this library provide common elementary mathematical functions and +floating point environment routines defined by System V, ANSI C, POSIX, and so +on. See \fBstandards\fR(5). Additional functions in this library provide +extended support for handling floating point exceptions. +.SH INTERFACES +The shared object \fBlibm.so.2\fR provides the public interfaces defined below. +See \fBIntro\fR(3) for additional information on shared object interfaces. +.sp + +.sp +.TS +tab( ); +lw(2.75i) lw(2.75i) +lw(2.75i) lw(2.75i) +. +\fBacos\fR \fBacosf\fR +\fBacosh\fR \fBacoshf\fR +\fBacoshl\fR \fBacosl\fR +\fBasin\fR \fBasinf\fR +\fBasinh\fR \fBasinhf\fR +\fBasinhl\fR \fBasinl\fR +\fBatan\fR \fBatan2\fR +\fBatan2f\fR \fBatan2l\fR +\fBatanf\fR \fBatanh\fR +\fBatanhf\fR \fBatanhl\fR +\fBatanl\fR \fBcabs\fR +\fBcabsf\fR \fBcabsl\fR +\fBcacos\fR \fBcacosf\fR +\fBcacosh\fR \fBcacoshf\fR +\fBcacoshl\fR \fBcacosl\fR +\fBcarg\fR \fBcargf\fR +\fBcargl\fR \fBcasin\fR +\fBcasinf\fR \fBcasinh\fR +\fBcasinhf\fR \fBcasinhl\fR +\fBcasinl\fR \fBcatan\fR +\fBcatanf\fR \fBcatanh\fR +\fBcatanhf\fR \fBcatanhl\fR +\fBcatanl\fR \fBcbrt\fR +\fBcbrtf\fR \fBcbrtl\fR +\fBccos\fR \fBccosf\fR +\fBccosh\fR \fBccoshf\fR +\fBccoshl\fR \fBccosl\fR +\fBceil\fR \fBceilf\fR +\fBceill\fR \fBcexp\fR +\fBcexpf\fR \fBcexpl\fR +\fBcimag\fR \fBcimagf\fR +\fBcimagl\fR \fBclog\fR +\fBclogf\fR \fBclogl\fR +\fBconj\fR \fBconjf\fR +\fBconjl\fR \fBcopysign\fR +\fBcopysignf\fR \fBcopysignl\fR +\fBcos\fR \fBcosf\fR +\fBcosh\fR \fBcoshf\fR +\fBcoshl\fR \fBcosl\fR +\fBcpow\fR \fBcpowf\fR +\fBcpowl\fR \fBcproj\fR +\fBcprojf\fR \fBcprojl\fR +\fBcreal\fR \fBcrealf\fR +\fBcreall\fR \fBcsin\fR +\fBcsinf\fR \fBcsinh\fR +\fBcsinhf\fR \fBcsinhl\fR +\fBcsinl\fR \fBcsqrt\fR +\fBcsqrtf\fR \fBcsqrtl\fR +\fBctan\fR \fBctanf\fR +\fBctanh\fR \fBctanhf\fR +\fBctanhl\fR \fBctanl\fR +\fBerf\fR \fBerfc\fR +\fBerfcf\fR \fBerfcl\fR +\fBerff\fR \fBerfl\fR +\fBexp\fR \fBexp2\fR +\fBexp2f\fR \fBexp2l\fR +\fBexpf\fR \fBexpl\fR +\fBexpm1\fR \fBexpm1f\fR +\fBexpm1l\fR \fBfabs\fR +\fBfabsf\fR \fBfabsl\fR +\fBfdim\fR \fBfdimf\fR +\fBfdiml\fR \fBfeclearexcept\fR +\fBfegetenv\fR \fBfegetexceptflag\fR +\fBfegetround\fR \fBfeholdexcept\fR +\fBferaiseexcept\fR \fBfesetenv\fR +\fBfesetexceptflag\fR \fBfesetround\fR +\fBfetestexcept\fR \fBfeupdateenv\fR +\fBfex_get_handling\fR \fBfex_get_log\fR +\fBfex_get_log_depth\fR \fBfex_getexcepthandler\fR +\fBfex_log_entry\fR \fBfex_merge_flags\fR +\fBfex_set_handling\fR \fBfex_set_log\fR +\fBfex_set_log_depth\fR \fBfex_setexcepthandler\fR +\fBfloor\fR \fBfloorf\fR +\fBfloorl\fR \fBfma\fR +\fBfmaf\fR \fBfmal\fR +\fBfmax\fR \fBfmaxf\fR +\fBfmaxl\fR \fBfmin\fR +\fBfminf\fR \fBfminl\fR +\fBfmod\fR \fBfmodf\fR +\fBfmodl\fR \fBfrexp\fR +\fBfrexpf\fR \fBfrexpl\fR +\fBgamma\fR \fBgamma_r\fR +\fBgammaf\fR \fBgammaf_r\fR +\fBgammal\fR \fBgammal_r\fR +\fBhypot\fR \fBhypotf\fR +\fBhypotl\fR \fBilogb\fR +\fBilogbf\fR \fBilogbl\fR +\fBisnan\fR \fBj0\fR +\fBj0f\fR \fBj0l\fR +\fBj1\fR \fBj1f\fR +\fBj1l\fR \fBjn\fR +\fBjnf\fR \fBjnl\fR +\fBldexp\fR \fBldexpf\fR +\fBldexpl\fR \fBlgamma\fR +\fBlgamma_r\fR \fBlgammaf\fR +\fBlgammaf_r\fR \fBlgammal\fR +\fBlgammal_r\fR \fBllrint\fR +\fBllrintf\fR \fBllrintl\fR +\fBllround\fR \fBllroundf\fR +\fBllroundl\fR \fBlog\fR +\fBlog10\fR \fBlog10f\fR +\fBlog10l\fR \fBlog1p\fR +\fBlog1pf\fR \fBlog1pl\fR +\fBlog2\fR \fBlog2f\fR +\fBlog2l\fR \fBlogb\fR +\fBlogbf\fR \fBlogbl\fR +\fBlogf\fR \fBlogl\fR +\fBlrint\fR \fBlrintf\fR +\fBlrintl\fR \fBlround\fR +\fBlroundf\fR \fBlroundl\fR +\fBmatherr\fR \fBmodf\fR +\fBmodff\fR \fBmodfl\fR +\fBnan\fR \fBnanf\fR +\fBnanl\fR \fBnearbyint\fR +\fBnearbyintf\fR \fBnearbyintl\fR +\fBnextafter\fR \fBnextafterf\fR +\fBnextafterl\fR \fBnexttoward\fR +\fBnexttowardf\fR \fBnexttowardl\fR +\fBpow\fR \fBpowf\fR +\fBpowl\fR \fBremainder\fR +\fBremainderf\fR \fBremainderl\fR +\fBremquo\fR \fBremquof\fR +\fBremquol\fR \fBrint\fR +\fBrintf\fR \fBrintl\fR +\fBround\fR \fBroundf\fR +\fBroundl\fR \fBscalb\fR +\fBscalbf\fR \fBscalbl\fR +\fBscalbln\fR \fBscalblnf\fR +\fBscalblnl\fR \fBscalbn\fR +\fBscalbnf\fR \fBscalbnl\fR +\fBsigngam\fR \fBsigngamf\fR +\fBsigngaml\fR \fBsignificand\fR +\fBsignificandf\fR \fBsignificandl\fR +\fBsin\fR \fBsincos\fR +\fBsincosf\fR \fBsincosl\fR +\fBsinf\fR \fBsinh\fR +\fBsinhf\fR \fBsinhl\fR +\fBsinl\fR \fBsqrt\fR +\fBsqrtf\fR \fBsqrtl\fR +\fBtan\fR \fBtanf\fR +\fBtanh\fR \fBtanhf\fR +\fBtanhl\fR \fBtanl\fR +\fBtgamma\fR \fBtgammaf\fR +\fBtgammal\fR \fBtrunc\fR +\fBtruncf\fR \fBtruncl\fR +\fBy0\fR \fBy0f\fR +\fBy0l\fR \fBy1\fR +\fBy1f\fR \fBy1l\fR +\fByn\fR \fBynf\fR +\fBynl\fR \fB\fR +.TE + +.sp +.LP +The following interfaces are unique to the x86 and amd64 versions of this library: +.sp + +.sp +.TS +tab( ); +lw(2.75i) lw(2.75i) +. +\fBfegetprec\fR \fBfesetprec\fR +.TE + +.SH ACCURACY +ISO/IEC 9899:1999, also known as C99, specifies the functions listed in the +following tables and states that the accuracy of these functions is +"implementation-defined". The information below characterizes the accuracy +of these functions as implemented in \fBlibm.so.2\fR. For each function, +the tables provide an upper bound on the largest error possible for any +argument and the largest error actually observed among a large sample of +arguments. Errors are expressed in "units in the last place", or ulps, relative +to the exact function value for each argument (regarding the argument as +exact). Ulps depend on the precision of the floating point format: if \fIy\fR +is the exact function value, \fIx\fR and \fIx\fR' are adjacent floating point +numbers such that \fIx\fR < \fIy\fR < \fIx\fR', and \fIx\fR'' is the computed +function value, then provided \fIx\fR, \fIx\fR', and \fIx\fR'' all lie in the +same binade, the error in \fIx\fR'' is |\fIy\fR - \fIx\fR''| / |\fIx\fR - +\fIx\fR'| ulps. In particular, when the error is less than one ulp, the computed +value is one of the two floating point numbers adjacent to the exact value. +.sp +.LP +The bounds and observed errors listed below apply only in the default floating +point modes. Specifically, on SPARC, these bounds assume the rounding direction +is round-to-nearest and non-standard mode is disabled. On x86, the bounds assume +the rounding direction is round-to-nearest and the rounding precision is +round-to-64-bits. Moreover, on x86, floating point function values are returned +in a floating point register in extended double precision format, but the bounds +below assume that the result value is then stored to memory in the format +corresponding to the function's type. On amd64, the bounds assume the rounding +direction in both the x87 floating point control word and the MXCSR is +round-to-nearest, the rounding precision in the x87 control word is +round-to-64-bits, and the FTZ and DAZ modes are disabled. +.sp +.LP +The error bounds listed below are believed to be correct, but smaller bounds +might be proved later. The observed errors are the largest ones currently known, +but larger errors might be discovered later. Numbers in the notes column refer +to the notes following the tables. +.SS "Real Functions" +.SS "Single precision real functions (SPARC, x86, and amd64)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBacosf\fR 1.0 < 1 +\fBacoshf\fR 1.0 < 1 +\fBasinf\fR 1.0 < 1 +\fBasinhf\fR 1.0 < 1 +\fBatanf\fR 1.0 < 1 +\fBatan2f\fR 1.0 < 1 +\fBatanhf\fR 1.0 < 1 +\fBcbrtf\fR 1.0 < 1 +\fBcosf\fR 1.0 < 1 +\fBcoshf\fR 1.0 < 1 +\fBerff\fR 1.0 < 1 +\fBerfcf\fR 1.0 < 1 +\fBexpf\fR 1.0 < 1 +\fBexp2f\fR 1.0 < 1 +\fBexpm1f\fR 1.0 < 1 +\fBhypotf\fR 1.0 < 1 +\fBlgammaf\fR 1.0 < 1 +\fBlogf\fR 1.0 < 1 +\fBlog10f\fR 1.0 < 1 +\fBlog1pf\fR 1.0 < 1 +\fBlog2f\fR 1.0 < 1 +\fBpowf\fR 1.0 < 1 +\fBsinf\fR 1.0 < 1 +\fBsinhf\fR 1.0 < 1 +\fBsqrtf\fR 0.5 0.500 [1] +\fBtanf\fR 1.0 < 1 +\fBtanhf\fR 1.0 < 1 +\fBtgammaf\fR 1.0 < 1 +.TE + +.SS "Double precision real functions (SPARC and amd64)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBacos\fR 1.0 < 1 +\fBacosh\fR 4.0 1.878 +\fBasin\fR 1.0 < 1 +\fBasinh\fR 7.0 1.653 +\fBatan\fR 1.0 <1 +\fBatan2\fR 2.5 1.475 +\fBatanh\fR 4.0 1.960 +\fBcbrt\fR 1.0 < 1 +\fBcos\fR 1.0 < 1 +\fBcosh\fR 3.0 1.168 +\fBerf\fR 4.0 0.959 +\fBerfc\fR 6.0 2.816 +\fBexp\fR 1.0 < 1 +\fBexp2\fR 2.0 1.050 +\fBexpm1\fR 1.0 < 1 +\fBhypot\fR 1.0 < 1 +\fBlgamma\fR 61.5 5.629 [2] +\fBlog\fR 1.0 < 1 +\fBlog10\fR 3.5 1.592 +\fBlog1p\fR 1.0 < 1 +\fBlog2\fR 1.0 < 1 +\fBpow\fR 1.0 < 1 +\fBsin\fR 1.0 < 1 +\fBsinh\fR 4.0 2.078 +\fBsqrt\fR 0.5 0.500 [1] +\fBtan\fR 1.0 < 1 +\fBtanh\fR 3.5 2.136 +\fBtgamma\fR 1.0 < 1 +.TE + +.SS "Double precision real functions (x86)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBacos\fR 1.0 < 1 +\fBacosh\fR 4.0 1.694 +\fBasin\fR 1.0 < 1 +\fBasinh\fR 7.0 1.493 +\fBatan\fR 1.0 < 1 +\fBatan2\fR 1.0 < 1 +\fBatanh\fR 4.0 1.445 +\fBcbrt\fR 1.0 < 1 +\fBcos\fR 1.0 < 1 +\fBcosh\fR 3.0 1.001 +\fBerf\fR 4.0 0.932 +\fBerfc\fR 6.0 2.728 +\fBexp\fR 1.0 < 1 +\fBexp2\fR 1.0 < 1 +\fBexpm1\fR 1.0 < 1 +\fBhypot\fR 1.0 < 1 +\fBlgamma\fR 61.5 2.654 [2] +\fBlog\fR 1.0 < 1 +\fBlog10\fR 1.0 < 1 +\fBlog1p\fR 1.0 < 1 +\fBlog2\fR 1.0 < 1 +\fBpow\fR 1.0 < 1 +\fBsin\fR 1.0 < 1 +\fBsinh\fR 4.0 1.458 +\fBsqrt\fR 0.5003 0.500 [1] +\fBtan\fR 1.0 < 1 +\fBtanh\fR 3.5 1.592 +\fBtgamma\fR 1.0 < 1 +.TE + +.SS "Quadruple precision real functions (SPARC)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBacosl\fR 3.5 1.771 +\fBacoshl\fR 8.0 1.275 +\fBasinl\fR 4.0 2.007 +\fBasinhl\fR 9.0 1.823 +\fBatanl\fR 1.0 < 1 +\fBatan2l\fR 2.5 1.102 +\fBatanhl\fR 4.0 1.970 +\fBcbrtl\fR 1.0 < 1 +\fBcosl\fR 1.0 < 1 +\fBcoshl\fR 3.5 0.985 +\fBerfl\fR 2.0 0.779 +\fBerfcl\fR 68.5 13.923 +\fBexpl\fR 1.0 < 1 +\fBexp2l\fR 2.0 0.714 +\fBexpm1l\fR 2.0 1.020 +\fBhypotl\fR 1.0 < 1 +\fBlgammal\fR 18.5 2.916 [2] +\fBlogl\fR 1.0 < 1 +\fBlog10l\fR 3.5 1.156 +\fBlog1pl\fR 2.0 1.216 +\fBlog2l\fR 3.5 1.675 +\fBpowl\fR 1.0 < 1 +\fBsinl\fR 1.0 < 1 +\fBsinhl\fR 4.5 1.589 +\fBsqrtl\fR 0.5 0.500 [1] +\fBtanl\fR 4.5 2.380 +\fBtanhl\fR 4.5 1.692 +\fBtgammal\fR 1.0 < 1 +.TE + +.SS "Extended precision real functions (x86 and amd64)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBacosl\fR 3.0 1.868 +\fBacoshl\fR 8.0 2.352 +\fBasinl\fR 3.0 1.716 +\fBasinhl\fR 9.0 2.346 +\fBatanl\fR 1.0 < 1 +\fBatan2l\fR 1.0 < 1 +\fBatanhl\fR 4.0 2.438 +\fBcbrtl\fR 1.0 < 1 +\fBcosl\fR 1.0 < 1 +\fBcoshl\fR 3.5 1.288 +\fBerfl\fR 1.0 < 1 +\fBerfcl\fR 78.5 13.407 +\fBexpl\fR 3.5 1.291 +\fBexp2l\fR 1.5 0.807 +\fBexpm1l\fR 4.0 1.936 +\fBhypotl\fR 3.5 2.087 +\fBlgammal\fR 22.5 4.197 [2] +\fBlogl\fR 2.0 0.881 +\fBlog10l\fR 2.0 1.284 +\fBlog1pl\fR 5.0 2.370 +\fBlog2l\fR 1.0 < 1 +\fBpowl\fR 32770.0 4478.132 +\fBsinl\fR 1.0 < 1 +\fBsinhl\fR 4.5 2.356 +\fBsqrtl\fR 0.5 0.500 [1] +\fBtanl\fR 4.5 2.366 +\fBtanhl\fR 4.5 2.417 +\fBtgammal\fR 1.0 < 1 +.TE + +.SS "Notes:" +.ne 2 +.mk +.na +\fB[1]\fR +.ad +.RS 7n +.rt +On SPARC and amd64, \fBsqrtf\fR, \fBsqrt\fR, and \fBsqrtl\fR are correctly +rounded in accordance with IEEE 754. On x86, \fBsqrtl\fR is correctly rounded, +\fBsqrtf\fR is correctly rounded provided the result is narrowed to single +precision as discussed above, but \fBsqrt\fR might not be correctly rounded due +to "double rounding": when the intermediate value computed to extended precision +lies exactly halfway between two representable numbers in double precision, the +result of rounding the intermediate value to double precision is determined by +the round-ties-to-even rule. If this rule causes the second rounding to round in +the same direction as the first, the net rounding error can exceed 0.5 ulps. +(The error is bounded instead by 0.5*(1 + 2^-11) ulps.) +.RE + +.sp +.ne 2 +.mk +.na +\fB[2]\fR +.ad +.RS 7n +.rt +Error bounds for lgamma and lgammal apply only for positive arguments. +.RE + +.SS "Complex functions" +The real-valued complex functions \fBcabsf\fR, \fBcabs\fR, \fBcabsl\fR, +\fBcargf\fR, \fBcarg\fR, and \fBcargl\fR are equivalent to the real functions +\fBhypotf\fR, \fBhypot\fR, \fBhypotl\fR, \fBatan2f\fR, \fBatan2\fR, and +\fBatan2l\fR, respectively. The error bounds and observed errors given above for +the latter functions also apply to the former. +.sp +.LP +The complex functions listed below are complex-valued. For each function, the +error bound shown applies separately to both the real and imaginary parts of the +result. (For example, both the real and imaginary parts of \fBcacosf\fR(\fIz\fR) +are accurate to within 1 ulp regardless of their magnitudes.) Similarly, the +largest observed error shown is the largest error found in either the real or +the imaginary part of the result. +.SS "Single precision complex functions (SPARC and amd64)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBcacosf\fR, \fBcacoshf\fR 1 < 1 [1] +\fBcasinf\fR, \fBcasinhf\fR 1 < 1 +\fBcatanf\fR, \fBcatanhf\fR 6 < 1 +\fBccosf\fR, \fBccoshf\fR 10 2.012 +\fBcexpf\fR 3 2.239 +\fBclogf\fR 3 < 1 +\fBcpowf\fR \(em < 1 [2] +\fBcsinf\fR, \fBcsinhf\fR 10 2.009 +\fBcsqrtf\fR 4 < 1 +\fBctanf\fR, \fBctanhf\fR 13 6.987 +.TE + +.SS "Single precision complex functions (x86)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBcacosf\fR, \fBcacoshf\fR 1 < 1 [1] +\fBcasinf\fR, \fBcasinhf\fR 1 < 1 +\fBcatanf\fR, \fBcatanhf\fR 6 < 1 +\fBccosf\fR, \fBccoshf\fR 10 1.984 +\fBcexpf\fR 3 1.984 +\fBclogf\fR 3 < 1 +\fBcpowf\fR \(em < 1 [2] +\fBcsinf\fR, \fBcsinhf\fR 10 1.973 +\fBcsqrtf\fR 4 < 1 +\fBctanf\fR, \fBctanhf\fR 13 4.657 +.TE + +.SS "Double precision complex functions (SPARC and amd64)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBcacos\fR, \fBcacosh\fR 9 3.831 [1] +\fBcasin\fR, \fBcasinh\fR 9 3.732 +\fBcatan\fR, \fBcatanh\fR 6 4.179 +\fBccos\fR, \fBccosh\fR 10 3.832 +\fBcexp\fR 3 2.255 +\fBclog\fR 3 2.870 +\fBcpow\fR - - [2] +\fBcsin\fR, \fBcsinh\fR 10 3.722 +\fBcsqrt\fR 4 3.204 +\fBctan\fR, \fBctanh\fR 13 7.143 +.TE + +.SS "Double precision complex functions (x86)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBcacos\fR, \fBcacosh\fR 9 3.624 [1] +\fBcasin\fR, \fBcasinh\fR 9 3.624 +\fBcatan\fR, \fBcatanh\fR 6 2.500 +\fBccos\fR, \fBccosh\fR 10 2.929 +\fBcexp\fR 3 2.147 +\fBclog\fR 3 1.927 +\fBcpow\fR - - [2] +\fBcsin\fR, \fBcsinh\fR 10 2.918 +\fBcsqrt\fR 4 1.914 +\fBctan\fR, \fBctanh\fR 13 4.630 +.TE + +.SS "Quadruple precision complex functions (SPARC)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBcacosl\fR, \fBcacoshl\fR 9 3 [1] +\fBcasinl\fR, \fBcasinhl\fR 9 3 +\fBcatanl\fR, \fBcatanhl\fR 6 3 +\fBccosl\fR, \fBccoshl\fR 10 3 +\fBcexpl\fR 3 2 +\fBclogl\fR 3 2 +\fBcpowl\fR - - [2] +\fBcsinl\fR, \fBcsinhl\fR 10 3 +\fBcsqrtl\fR 4 3 +\fBctanl\fR, \fBctanhl\fR 13 5 +.TE + +.SS "Extended precision complex functions (x86 and amd64)" + +.TS +tab( ); +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +cw(1.38i) cw(1.38i) cw(1.38i) cw(1.38i) +. + error bound largest error +function (ulps) observed (ulps) notes +\fBcacosl\fR, \fBcacoshl\fR 9 2 [1] +\fBcasinl\fR, \fBcasinhl\fR 9 2 +\fBcatanl\fR, \fBcatanhl\fR 6 2 +\fBccosl\fR, \fBccoshl\fR 10 3 +\fBcexpl\fR 3 2.699 +\fBclogl\fR 3 1 +\fBcpowl\fR - - [2] +\fBcsinl\fR, \fBcsinhl\fR 10 3 +\fBcsqrtl\fR 4 1.452 +\fBctanl\fR, \fBctanhl\fR 13 5 +.TE + +.SS "Notes:" +.ne 2 +.mk +.na +\fB[1]\fR +.ad +.RS 7n +.rt +The complex hyperbolic trigonometric functions are equivalent by symmetries to +their circular trigonometric counterparts. Because the implementations of these +functions exploit these symmetries, corresponding functions have the same error +bounds and observed errors. +.RE + +.sp +.ne 2 +.mk +.na +\fB[2]\fR +.ad +.RS 7n +.rt +For large arguments, the results computed by \fBcpowf\fR, \fBcpow\fR, and +\fBcpowl\fR can have unbounded relative error. It might be possible to give +error bounds for specific domains, but no such bounds are currently available. +The observed errors shown are for the domain {(\fIz\fR,\fIw\fR) : +\fBmax\fR(|\fBRe\fR \fIz\fR|, |\fBIm\fR \fIz\fR|, |\fBRe\fR \fIw\fR|, |\fBIm\fR +\fIw\fR|) <= 1}. +.RE + +.SH FILES +.ne 2 +.mk +.na +\fB\fB/lib/libm.so.2\fR\fR +.ad +.RS 21n +.rt +shared object +.RE + +.sp +.ne 2 +.mk +.na +\fB\fB/lib/64/libm.so.2\fR\fR +.ad +.RS 21n +.rt +64-bit shared object +.RE + +.SH ATTRIBUTES +See \fBattributes\fR(5) for descriptions of the following attributes: +.sp + +.sp +.TS +tab( ) box; +cw(2.75i) |cw(2.75i) +lw(2.75i) |lw(2.75i) +. +ATTRIBUTE TYPE ATTRIBUTE VALUE +_ +MT-Level Safe with exceptions +.TE + +.sp +.LP +As described on the \fBlgamma\fR(3M) manual page, \fBgamma()\fR and +\fBlgamma()\fR and their \fBfloat\fR and \fBlong double\fR counterparts are +Unsafe. All other functions in \fBlibm.so.2\fR are MT-Safe. +.SH SEE ALSO +\fBIntro\fR(3), \fBlgamma\fR(3M), \fBmath.h\fR(3HEAD), \fBattributes\fR(5), +\fBstandards\fR(5) diff --git a/usr/src/man/man3lib/libmvec.3lib b/usr/src/man/man3lib/libmvec.3lib new file mode 100644 index 0000000000..2be5fda4c7 --- /dev/null +++ b/usr/src/man/man3lib/libmvec.3lib @@ -0,0 +1,91 @@ +'\" te +.\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright 2020 Joyent, Inc. +.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. +.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] +.TH libmvec 3LIB "Feb 27, 2020" +.SH NAME +libmvec \- vector math library +.SH SYNOPSIS +.nf +cc [ \fIflag\fR... ] \fIfile\fR... \fB-lmvec\fR [ \fIlibrary\fR... ] +.fi + +.SH DESCRIPTION +This library contains function to evaluate common mathematical functions for +several arguments at once. The argument values are specified by one or more +vectors (arrays) of data, and the corresponding result values are stored in +another vector. +.SH INTERFACES +The shared object \fBlibmvec.so.1\fR provides the public interfaces defined +below. See \fBIntro\fR(3) for additional information on shared object +interfaces. +.sp + +.sp +.TS +tab( ); +lw(2.75i) lw(2.75i) +lw(2.75i) lw(2.75i) +. +\fBvatan_\fR \fBvatanf_\fR +\fBvatan2_\fR \fBvatan2f_\fR +\fBvc_abs_\fR \fBvc_exp_\fR +\fBvc_log_\fR \fBvc_pow_\fR +\fBvcos_\fR \fBvcosf_\fR +\fBvcospi_\fR \fBvcospif_\fR +\fBvexp_\fR \fBvexpf_\fR +\fBvhypot_\fR \fBvhypotf_\fR +\fBvlog_\fR \fBvlogf_\fR +\fBvpow_\fR \fBvpowf_\fR +\fBvrhypot_\fR \fBvrhypotf_\fR +\fBvrsqrt_\fR \fBvrsqrtf_\fR +\fBvsin_\fR \fBvsinf_\fR +\fBvsincos_\fR \fBvsincosf_\fR +\fBvsincospi_\fR \fBvsincospif_\fR +\fBvsinpi_\fR \fBvsinpif_\fR +\fBvsqrt_\fR \fBvsqrtf_\fR +\fBvz_abs_\fR \fBvz_exp_\fR +\fBvz_log_\fR \fBvz_pow_\fR +.TE + +.SH FILES +.ne 2 +.mk +.na +\fB\fB/lib/libmvec.so.1\fR\fR +.ad +.RS 24n +.rt +shared object +.RE + +.sp +.ne 2 +.mk +.na +\fB\fB/lib/64/libmvec.so.1\fR\fR +.ad +.RS 24n +.rt +64-bit shared object +.RE + +.SH ATTRIBUTES +See \fBattributes\fR(5) for descriptions of the following attributes: +.sp + +.sp +.TS +tab( ) box; +cw(2.75i) |cw(2.75i) +lw(2.75i) |lw(2.75i) +. +ATTRIBUTE TYPE ATTRIBUTE VALUE +_ +MT-Level MT-Safe +.TE + +.SH SEE ALSO +\fBIntro\fR(3), \fBcomplex.h\fR(3HEAD), \fBlibm\fR(3LIB), \fBattributes\fR(5) diff --git a/usr/src/man/man7d/Makefile b/usr/src/man/man7d/Makefile index 9de3a14886..a6b063bdfc 100644 --- a/usr/src/man/man7d/Makefile +++ b/usr/src/man/man7d/Makefile @@ -216,6 +216,7 @@ i386_MANFILES= ahci.7d \ iwi.7d \ iwn.7d \ mega_sas.7d \ + mlxcx.7d \ npe.7d \ ntxn.7d \ nv_sata.7d \ diff --git a/usr/src/man/man7d/mlxcx.7d b/usr/src/man/man7d/mlxcx.7d new file mode 100644 index 0000000000..5373b5bec5 --- /dev/null +++ b/usr/src/man/man7d/mlxcx.7d @@ -0,0 +1,340 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright 2020 the University of Queensland +.\" +.Dd January 17, 2020 +.Dt MLXCX 7D +.Os +.Sh NAME +.Nm mlxcx +.Nd Mellanox ConnectX-4/5/6 Ethernet controller driver +.Sh SYNOPSIS +.Pa /dev/net/mlxcx* +.Sh DESCRIPTION +The +.Sy mlxcx +driver is a GLDv3 NIC driver for the ConnectX-4, ConnectX-4 Lx, ConnectX-5 and +ConnectX-6 families of ethernet controllers from Mellanox. +It supports the Data Link Provider Interface, +.Xr dlpi 7P . +.Pp +This driver supports: +.Bl -dash -offset indent +.It +Jumbo frames up to 9000 bytes. +.It +Checksum offload for TCP, UDP, IPv4 and IPv6. +.It +Group support with VLAN and MAC steering to avoid software classification +when using VNICs. +.It +Promiscuous access via +.Xr snoop 1M and +.Xr dlpi 7P +.It +LED control +.It +Transceiver information +.El +.Pp +At this time, the driver does not support Large Send Offload (LSO), energy +efficient Ethernet (EEE), or the use of flow control through hardware pause +frames. +.Sh CONFIGURATION +The +.Sy mlxcx.conf +file contains user configurable parameters, including the ability to set the +number of rings and groups advertised to MAC, the sizes of rings and groups, +and the maximum number of MAC address filters available. +.Sh PROPERTIES +The driver supports the following device properties which may be tuned through +its driver.conf file, +.Pa /kernel/drv/mlxcx.conf . +These properties cannot be changed after the driver has been attached. +.Pp +These properties are not considered stable at this time, and may change. +.Bl -hang -width Ds +.It Sy eq_size_shift +.Bd -filled -compact +Minimum: +.Sy 2 | +Maximum: +.Sy device dependent (up to 255) +.Ed +.Bd -filled +The +.Sy eq_size_shift +property determines the number of entries on Event Queues for the device. +The number of entries is calculated as +.Dv (1 << eq_size_shift) , +so a value of 9 would mean 512 entries are created on each Event Queue. +The default value is +.Sy 9 . +.Ed +.It Sy cq_size_shift +.Bd -filled -compact +Minimum: +.Sy 2 | +Maximum: +.Sy device dependent (up to 255) +.Ed +.Bd -filled +The +.Sy cq_size_shift +property determines the number of entries on Completion Queues for the device. +The number of entries is calculated as +.Li (1 << cq_size_shift) , +so a value of 9 would mean 512 entries are created on each Event Queue. +The default value is +.Sy 10 . +This should be kept very close to the value set for +.Sy rq_size_shift +and +.Sy sq_size_shift . +.Ed +.It Sy rq_size_shift +.Bd -filled -compact +Minimum: +.Sy 2 | +Maximum: +.Sy device dependent (up to 255) +.Ed +.Bd -filled +The +.Sy rq_size_shift +property determines the number of descriptors on Receive Queues for the device. +The number of descriptors is calculated as +.Dv (1 << rq_size_shift) , +so a value of 9 would mean 512 descriptors are created on each Receive Queue. +This sets the number of packets on RX rings advertised to MAC. +The default value is +.Sy 10 . +.Ed +.It Sy sq_size_shift +.Bd -filled -compact +Minimum: +.Sy 2 | +Maximum: +.Sy device dependent (up to 255) +.Ed +.Bd -filled +The +.Sy sq_size_shift +property determines the number of descriptors on Send Queues for the device. +The number of descriptors is calculated as +.Dv (1 << sq_size_shift) , +so a value of 9 would mean 512 descriptors are created on each Send Queue. +This sets the number of packets on RX rings advertised to MAC. +The default value is +.Sy 11 . +Note that large packets often occupy more than one descriptor slot on the SQ, +so it is sometimes a good idea to increase this if using a large MTU. +.Ed +.It Sy tx_ngroups +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy device dependent +.Ed +.Bd -filled +The +.Sy tx_ngroups +property determines the number of TX groups advertised to MAC. +The default value is +.Sy 1 . +.Ed +.It Sy tx_nrings_per_group +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy device dependent +.Ed +.Bd -filled +The +.Sy tx_nrings_per_group +property determines the number of rings in each TX group advertised to MAC. +The default value is +.Sy 64 . +.Ed +.It Sy rx_ngroups_large +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy device dependent +.Ed +.Bd -filled +The +.Sy rx_ngroups_large +property determines the number of "large" RX groups advertised to MAC. +The size of "large" RX groups is set by the +.Sy rx_nrings_per_large_group +property. +The default value is +.Sy 2 . +.Ed +.It Sy rx_nrings_per_large_group +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy device dependent +.Ed +.Bd -filled +The +.Sy rx_nrings_per_large_group +property determines the number of rings in each "large" RX group advertised to +MAC. +The number of such groups is determined by the +.Sy rx_ngroups_large +property. +The default value is +.Sy 16 . +.Ed +.It Sy rx_ngroups_small +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy device dependent +.Ed +.Bd -filled +The +.Sy rx_ngroups_small +property determines the number of "small" RX groups advertised to MAC. +The size of "small" RX groups is set by the +.Sy rx_nrings_per_small_group +property. +It is recommended to use many small groups when using a large number of +VNICs on top of the NIC (e.g. on a system with many zones). +The default value is +.Sy 256 . +.Ed +.It Sy rx_nrings_per_small_group +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy device dependent +.Ed +.Bd -filled +The +.Sy rx_nrings_per_small_group +property determines the number of rings in each "small" RX group advertised to +MAC. +The number of such groups is determined by the +.Sy rx_ngroups_small +property. +The default value is +.Sy 4 . +.Ed +.It Sy ftbl_root_size_shift +.Bd -filled -compact +Minimum: +.Sy 4 | +Maximum: +.Sy device dependent +.Ed +.Bd -filled +The +.Sy ftbl_root_size_shift +property determines the number of flow table entries on the root flow table, +and therefore how many MAC addresses can be filtered into groups across the +entire NIC. +The number of flow entries is calculated as +.Dv (1 << ftbl_root_size_shift) , +so a value of 9 would mean 512 entries are created in the root flow table. +The default value is +.Sy 12 . +.Ed +.It Sy cqemod_period_usec +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy 65535 +.Ed +.Bd -filled +The +.Sy cqemod_period_usec +property determines the maximum delay after a completion event has occurred +before an event queue entry (and thus an interrupt) is generated. +The delay is measured in microseconds. +The default value is +.Sy 50 . +.Ed +.It Sy cqemod_count +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy 65535 +.Ed +.Bd -filled +The +.Sy cqemod_count +property determines the maximum number of completion events that can have +occurred before an event queue entry (and thus an interrupt) is generated. +The default value is +.Sy 80% of the CQ size . +.Ed +.It Sy intrmod_period_usec +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy 65535 +.Ed +.Bd -filled +The +.Sy intrmod_period_usec +property determines the maximum delay after an event queue entry has been +generated before an interrupt is raised. +The delay is measured in microseconds. +The default value is +.Sy 10 . +.Ed +.It Sy tx_bind_threshold +.Bd -filled -compact +Minimum: +.Sy 1 | +Maximum: +.Sy 65535 +.Ed +.Bd -filled +The +.Sy tx_bind_threshold +property determines the minimum number of bytes in a packet before the driver +uses +.Xr ddi_dma_addr_bind_handle 9F +to bind the packet memory for DMA, rather than copying the memory as it does +for small packets. +DMA binds are expensive and involve taking locks in the PCI nexus driver, so it +is seldom worth using them for small packets. +The default value is +.Sy 2048 . +.Ed +.El +.Sh FILES +.Bl -tag -width Pa +.It Pa /kernel/drv/amd64/mlxcx +Device driver (x86) +.It Pa /kernel/drv/mlxcx.conf +Driver configuration file containing user-configurable options +.El +.Sh SEE ALSO +.Xr dladm 1M , +.Xr snoop 1M , +.Xr driver.conf 4 , +.Xr dlpi 7P diff --git a/usr/src/man/man7d/pts.7d b/usr/src/man/man7d/pts.7d index 19f67addc1..6ac5bbcbd1 100644 --- a/usr/src/man/man7d/pts.7d +++ b/usr/src/man/man7d/pts.7d @@ -1,14 +1,13 @@ '\" te +.\" Copyright 2020 OmniOS Community Edition (OmniOSce) Association. .\" Copyright 1992 Sun Microsystems .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH PTS 7D "Aug 21, 1992" +.TH PTS 7D "Feb 29, 2020" .SH NAME pts \- STREAMS pseudo-tty slave driver .SH DESCRIPTION -.sp -.LP The pseudo-tty subsystem simulates a terminal connection, where the master side represents the terminal and the slave represents the user process's special device end point. In order to use the pseudo-tty subsystem, a node for the @@ -26,9 +25,10 @@ Only one open is allowed on a master device. Multiple opens are allowed on the slave device. After both the master and slave have been opened, the user has two file descriptors which are end points of a full duplex connection composed of two streams automatically connected at the master and slave drivers. The -user may then push modules onto either side of the stream pair. The user needs -to push the \fBptem\fR(7M) and \fBldterm\fR(7M) modules onto the slave side of -the pseudo-terminal subsystem to get terminal semantics. +user may then push modules onto either side of the stream pair. Unless compiled +in XPG4v2 mode (see below), the consumer needs to push the \fBptem\fR(7M) and +\fBldterm\fR(7M) modules onto the slave side of the pseudo-terminal subsystem +to get terminal semantics. .sp .LP The master and slave drivers pass all messages to their adjacent queues. Only @@ -48,14 +48,23 @@ device is not closed, the pseudo-tty subsystem will be available to another user to open the slave device. Since 0-length messages are used to indicate that the process on the slave side has closed and should be interpreted that way by the process on the master side, applications on the slave side should -not write 0-length messages. If that occurs, the write returns 0, and the -0-length message is discarded by the \fBptem\fR module. +not write 0-length messages. Unless the application is compiled in XPG4v2 mode +(see below) then any 0-length messages written on the slave side will be +discarded by the \fBptem\fR module. .sp .LP The standard STREAMS system calls can access the pseudo-tty devices. The slave devices support the \fBO_NDELAY\fR and \fBO_NONBLOCK\fR flags. -.SH EXAMPLES +.SH XPG4v2 MODE +XPG4v2 requires that open of a slave pseudo terminal device provides the +process with an interface that is identical to the terminal interface (without +having to explicitly push any modules to achieve this). It also requires that +0-length messages written on the slave side will be propagated to the master. .sp +Experience has shown, however, that most software does not expect slave pty +devices to operate in this manner and therefore this XPG4v2-compliant +behaviour is only enabled in XPG4v2/SUS (see \fBstandards\fR(5)) mode. +.SH EXAMPLES .in +2 .nf int fdm fds; @@ -73,7 +82,6 @@ ioctl(fds, I_PUSH, "ldterm"); /* push ldterm*/ .in -2 .SH FILES -.sp .ne 2 .na \fB\fB/dev/ptmx\fR\fR @@ -92,10 +100,8 @@ slave devices (M = 0 -> N-1) .RE .SH SEE ALSO -.sp -.LP \fBgrantpt\fR(3C), \fBptsname\fR(3C), \fBunlockpt\fR(3C), \fBldterm\fR(7M), -\fBptm\fR(7D), \fBptem\fR(7M) +\fBptm\fR(7D), \fBptem\fR(7M), \fBstandards\fR(5) .sp .LP \fISTREAMS Programming Guide\fR diff --git a/usr/src/pkg/manifests/SUNWcs.man1m.inc b/usr/src/pkg/manifests/SUNWcs.man1m.inc index ac241ac262..f4331d110f 100644 --- a/usr/src/pkg/manifests/SUNWcs.man1m.inc +++ b/usr/src/pkg/manifests/SUNWcs.man1m.inc @@ -15,9 +15,10 @@ # Copyright 2016 Toomas Soome <tsoome@me.com> # Copyright (c) 2017, Chris Fraire <cfraire@me.com>. # Copyright (c) 2016 by Delphix. All rights reserved. -# Copyright 2019 Joyent, Inc. +# Copyright 2020 Joyent, Inc. # +$(i386_ONLY) file path=usr/share/man/man1m/rdmsr.1m variant.opensolaris.zone=global file path=usr/share/man/man1m/6to4relay.1m file path=usr/share/man/man1m/Intro.1m file path=usr/share/man/man1m/acctadm.1m @@ -57,7 +58,6 @@ file path=usr/share/man/man1m/dd.1m file path=usr/share/man/man1m/devattr.1m file path=usr/share/man/man1m/devfree.1m file path=usr/share/man/man1m/devfsadm.1m -link path=usr/share/man/man1m/audlinks.1m target=devfsadm.1m file path=usr/share/man/man1m/devinfo.1m file path=usr/share/man/man1m/devlinks.1m file path=usr/share/man/man1m/devnm.1m @@ -110,6 +110,7 @@ file path=usr/share/man/man1m/groupmod.1m file path=usr/share/man/man1m/growfs.1m file path=usr/share/man/man1m/halt.1m file path=usr/share/man/man1m/hostconfig.1m +file path=usr/share/man/man1m/hotplug.1m file path=usr/share/man/man1m/id.1m file path=usr/share/man/man1m/idmap.1m file path=usr/share/man/man1m/idmapd.1m @@ -203,7 +204,6 @@ file path=usr/share/man/man1m/quotaon.1m file path=usr/share/man/man1m/raidctl.1m file path=usr/share/man/man1m/ramdiskadm.1m file path=usr/share/man/man1m/rctladm.1m -$(i386_ONLY) file path=usr/share/man/man1m/rdmsr.1m variant.opensolaris.zone=global file path=usr/share/man/man1m/reboot.1m file path=usr/share/man/man1m/rem_drv.1m file path=usr/share/man/man1m/repquota.1m @@ -260,6 +260,7 @@ file path=usr/share/man/man1m/trapstat.1m file path=usr/share/man/man1m/ttyadm.1m file path=usr/share/man/man1m/ttymon.1m file path=usr/share/man/man1m/tunefs.1m +file path=usr/share/man/man1m/tzreload.1m file path=usr/share/man/man1m/tzselect.1m file path=usr/share/man/man1m/uadmin.1m file path=usr/share/man/man1m/ucodeadm.1m @@ -280,6 +281,7 @@ file path=usr/share/man/man1m/whodo.1m file path=usr/share/man/man1m/wracct.1m file path=usr/share/man/man1m/zdump.1m file path=usr/share/man/man1m/zic.1m +link path=usr/share/man/man1m/audlinks.1m target=devfsadm.1m link path=usr/share/man/man1m/dcopy.1m target=clri.1m link path=usr/share/man/man1m/devfsadmd.1m target=devfsadm.1m link path=usr/share/man/man1m/grpck.1m target=pwck.1m diff --git a/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf b/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf index 373721a966..a4800aa033 100644 --- a/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf +++ b/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf @@ -282,6 +282,7 @@ file path=usr/lib/locale/C/LC_MESSAGES/FMD.po file path=usr/lib/locale/C/LC_MESSAGES/FMNOTIFY.po file path=usr/lib/locale/C/LC_MESSAGES/GMCA.po file path=usr/lib/locale/C/LC_MESSAGES/INTEL.po +file path=usr/lib/locale/C/LC_MESSAGES/NIC.po file path=usr/lib/locale/C/LC_MESSAGES/NXGE.po file path=usr/lib/locale/C/LC_MESSAGES/PCI.po file path=usr/lib/locale/C/LC_MESSAGES/PCIEX.po diff --git a/usr/src/pkg/manifests/driver-network-mlxcx.mf b/usr/src/pkg/manifests/driver-network-mlxcx.mf new file mode 100644 index 0000000000..dec1aa726c --- /dev/null +++ b/usr/src/pkg/manifests/driver-network-mlxcx.mf @@ -0,0 +1,54 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2020 the University of Queensland +# Author: Alex Wilson <alex@uq.edu.au> +# + +# +# The default for payload-bearing actions in this package is to appear in the +# global zone only. See the include file for greater detail, as well as +# information about overriding the defaults. +# +<include global_zone_only_component> +set name=pkg.fmri value=pkg:/driver/network/mlxcx@$(PKGVERS) +set name=pkg.description value="Mellanox ConnectX-4/5/6 Ethernet Driver" +set name=pkg.summary value="Mellanox ConnectX-4/5/6 Ethernet Driver" +set name=info.classification \ + value=org.opensolaris.category.2008:Drivers/Storage +set name=variant.arch value=i386 +dir path=kernel group=sys +dir path=kernel/drv group=sys +dir path=kernel/drv/$(ARCH64) group=sys +dir path=usr/share/man +dir path=usr/share/man/man7d +driver name=mlxcx \ + alias=pciex15b3,1013 \ + alias=pciex15b3,1014 \ + alias=pciex15b3,1015 \ + alias=pciex15b3,1016 \ + alias=pciex15b3,1017 \ + alias=pciex15b3,1018 \ + alias=pciex15b3,1019 \ + alias=pciex15b3,101a \ + alias=pciex15b3,101b \ + alias=pciex15b3,101c \ + alias=pciex15b3,101d \ + alias=pciex15b3,101e \ + alias=pciex15b3,101f +file path=kernel/drv/$(ARCH64)/mlxcx group=sys +file path=kernel/drv/mlxcx.conf group=sys +file path=usr/share/man/man7d/mlxcx.7d +legacy pkg=SUNWmrsas desc="Mellanox ConnectX-4/5/6 Ethernet Driver" \ + name="Mellanox ConnectX-4/5/6 Ethernet Driver" +license cr_Sun license=cr_Sun +license lic_CDDL license=lic_CDDL diff --git a/usr/src/pkg/manifests/service-fault-management.mf b/usr/src/pkg/manifests/service-fault-management.mf index 3549793ce2..fee5ffe47d 100644 --- a/usr/src/pkg/manifests/service-fault-management.mf +++ b/usr/src/pkg/manifests/service-fault-management.mf @@ -335,6 +335,8 @@ $(i386_ONLY)file path=usr/lib/fm/dict/GMCA.dict mode=0444 \ variant.opensolaris.zone=__NODEFAULT $(i386_ONLY)file path=usr/lib/fm/dict/INTEL.dict mode=0444 \ variant.opensolaris.zone=__NODEFAULT +file path=usr/lib/fm/dict/NIC.dict mode=0444 \ + variant.opensolaris.zone=__NODEFAULT file path=usr/lib/fm/dict/NXGE.dict mode=0444 \ variant.opensolaris.zone=__NODEFAULT file path=usr/lib/fm/dict/PCI.dict mode=0444 \ @@ -366,6 +368,7 @@ file path=usr/lib/fm/eft/disk.eft mode=0444 \ variant.opensolaris.zone=__NODEFAULT file path=usr/lib/fm/eft/neptune_xaui.eft mode=0444 file path=usr/lib/fm/eft/neptune_xfp.eft mode=0444 +file path=usr/lib/fm/eft/nic.eft mode=0444 file path=usr/lib/fm/eft/pci.eft mode=0444 file path=usr/lib/fm/eft/pciex.eft mode=0444 file path=usr/lib/fm/eft/pciexrc.eft mode=0444 @@ -531,6 +534,8 @@ $(i386_ONLY)file path=usr/lib/locale/C/LC_MESSAGES/GMCA.mo mode=0444 \ variant.opensolaris.zone=__NODEFAULT $(i386_ONLY)file path=usr/lib/locale/C/LC_MESSAGES/INTEL.mo mode=0444 \ variant.opensolaris.zone=__NODEFAULT +file path=usr/lib/locale/C/LC_MESSAGES/NIC.mo mode=0444 \ + variant.opensolaris.zone=__NODEFAULT file path=usr/lib/locale/C/LC_MESSAGES/NXGE.mo mode=0444 \ variant.opensolaris.zone=__NODEFAULT file path=usr/lib/locale/C/LC_MESSAGES/PCI.mo mode=0444 \ diff --git a/usr/src/pkg/manifests/system-data-hardware-registry.mf b/usr/src/pkg/manifests/system-data-hardware-registry.mf index 2cbc143786..779d1613e3 100644 --- a/usr/src/pkg/manifests/system-data-hardware-registry.mf +++ b/usr/src/pkg/manifests/system-data-hardware-registry.mf @@ -21,10 +21,11 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2019 OmniOS Community Edition (OmniOSce) Association. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # -set name=pkg.fmri value=pkg:/system/data/hardware-registry@$(PKGVERS) +set name=pkg.fmri \ + value=pkg:/system/data/hardware-registry@2020.2.22,$(PKGVERS_BUILTON)-$(PKGVERS_BRANCH) set name=pkg.description \ value="ASCII databases describing various PCI, USB and other hardware" set name=pkg.summary value="Hardware data files" diff --git a/usr/src/pkg/manifests/system-library-platform.mf b/usr/src/pkg/manifests/system-library-platform.mf index c683f2718e..1af1d2a8f5 100644 --- a/usr/src/pkg/manifests/system-library-platform.mf +++ b/usr/src/pkg/manifests/system-library-platform.mf @@ -21,7 +21,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2019 Peter Tribble. +# Copyright 2020 Peter Tribble. # set name=pkg.fmri value=pkg:/system/library/platform@$(PKGVERS) @@ -157,8 +157,6 @@ $(sparc_ONLY)file path=usr/platform/SUNW,Sun-Fire/lib/libprtdiag_psr.so.1 $(sparc_ONLY)file path=usr/platform/SUNW,Ultra-2/lib/libprtdiag_psr.so.1 $(sparc_ONLY)file path=usr/platform/SUNW,Ultra-250/lib/libprtdiag_psr.so.1 $(sparc_ONLY)file path=usr/platform/SUNW,Ultra-4/lib/libprtdiag_psr.so.1 -$(sparc_ONLY)file \ - path=usr/platform/SUNW,Ultra-Enterprise/lib/libprtdiag_psr.so.1 $(sparc_ONLY)file path=usr/platform/sun4u/lib/cfgadm/$(ARCH64)/ac.so.1 $(sparc_ONLY)file path=usr/platform/sun4u/lib/cfgadm/$(ARCH64)/sbd.so.1 $(sparc_ONLY)file path=usr/platform/sun4u/lib/cfgadm/$(ARCH64)/sysctrl.so.1 diff --git a/usr/src/pkg/manifests/system-library.man3lib.inc b/usr/src/pkg/manifests/system-library.man3lib.inc index c552648c8f..bf60cd2b7a 100644 --- a/usr/src/pkg/manifests/system-library.man3lib.inc +++ b/usr/src/pkg/manifests/system-library.man3lib.inc @@ -12,6 +12,7 @@ # # Copyright 2011, Richard Lowe # Copyright 2012 Nexenta Systems, Inc. All rights reserved. +# Copyright 2020 Joyent, Inc. # file path=usr/share/man/man3lib/libadm.3lib @@ -43,6 +44,7 @@ file path=usr/share/man/man3lib/libkstat.3lib file path=usr/share/man/man3lib/libkvm.3lib file path=usr/share/man/man3lib/libl.3lib file path=usr/share/man/man3lib/liblgrp.3lib +file path=usr/share/man/man3lib/libm.3lib file path=usr/share/man/man3lib/libmail.3lib file path=usr/share/man/man3lib/libmalloc.3lib file path=usr/share/man/man3lib/libmapmalloc.3lib @@ -51,6 +53,7 @@ file path=usr/share/man/man3lib/libmd5.3lib file path=usr/share/man/man3lib/libmenu.3lib file path=usr/share/man/man3lib/libmp.3lib file path=usr/share/man/man3lib/libmtmalloc.3lib +file path=usr/share/man/man3lib/libmvec.3lib file path=usr/share/man/man3lib/libnls.3lib file path=usr/share/man/man3lib/libnsl.3lib file path=usr/share/man/man3lib/libnvpair.3lib diff --git a/usr/src/pkg/manifests/system-test-utiltest.mf b/usr/src/pkg/manifests/system-test-utiltest.mf index 5a5502a28b..a33bea9e2e 100644 --- a/usr/src/pkg/manifests/system-test-utiltest.mf +++ b/usr/src/pkg/manifests/system-test-utiltest.mf @@ -56,6 +56,7 @@ dir path=opt/util-tests/tests/files/make_a/a dir path=opt/util-tests/tests/files/make_a/b dir path=opt/util-tests/tests/files/make_a/c dir path=opt/util-tests/tests/files/make_l +dir path=opt/util-tests/tests/find dir path=opt/util-tests/tests/libcustr dir path=opt/util-tests/tests/libnvpair_json dir path=opt/util-tests/tests/libsff @@ -67,6 +68,11 @@ dir path=opt/util-tests/tests/awk/examples/out dir path=opt/util-tests/tests/awk/gnu dir path=opt/util-tests/tests/awk/syn dir path=opt/util-tests/tests/awk/tests +dir path=opt/util-tests/tests/mdb +dir path=opt/util-tests/tests/mdb/exit-e +dir path=opt/util-tests/tests/mdb/format +dir path=opt/util-tests/tests/mdb/options +dir path=opt/util-tests/tests/mdb/typedef dir path=opt/util-tests/tests/mergeq dir path=opt/util-tests/tests/sleep file path=opt/util-tests/README mode=0444 @@ -1432,6 +1438,7 @@ file path=opt/util-tests/tests/files/test5 mode=0444 file path=opt/util-tests/tests/files/test6 mode=0444 file path=opt/util-tests/tests/files/test7 mode=0444 file path=opt/util-tests/tests/files/testnl mode=0444 +file path=opt/util-tests/tests/find/findtest mode=0555 file path=opt/util-tests/tests/grep_test mode=0555 file path=opt/util-tests/tests/iconv_test mode=0555 file path=opt/util-tests/tests/libcustr/custr_remove mode=0555 @@ -1477,6 +1484,95 @@ file path=opt/util-tests/tests/libsff/libsff_strings mode=0555 file path=opt/util-tests/tests/libsff/libsff_wave mode=0555 file path=opt/util-tests/tests/libsff/libsff_wave.out mode=0444 file path=opt/util-tests/tests/make_test mode=0555 +file path=opt/util-tests/tests/mdb/exit-e/err.cmdbadopt.ksh mode=0444 +file path=opt/util-tests/tests/mdb/exit-e/err.enocmd.ksh mode=0444 +file path=opt/util-tests/tests/mdb/exit-e/err.nowrite.ksh mode=0444 +file path=opt/util-tests/tests/mdb/exit-e/err.unmapped.ksh mode=0444 +file path=opt/util-tests/tests/mdb/exit-e/tst.output.ksh mode=0444 +file path=opt/util-tests/tests/mdb/exit-e/tst.output.ksh.out mode=0444 +file path=opt/util-tests/tests/mdb/exit-e/tst.simple.ksh mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-E.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-E.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-G.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-G.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-J.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-J.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-P.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-P.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-R.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-cap-R.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-e.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-e.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-g.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-g.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-j.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-j.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-p.mdb mode=0444 +file path=opt/util-tests/tests/mdb/format/tst.format-p.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/mdbtest mode=0555 +file path=opt/util-tests/tests/mdb/options/tst.autowrap.mdb mode=0444 +file path=opt/util-tests/tests/mdb/options/tst.autowrap.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badid-leadnum.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badid-leadschar.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badmodel.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-extrabraces.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-neglenarr.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-noarrayclose.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-noarraylen.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-noarrayopen.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-nobraces.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-noclosebrace.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-nomembers.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-nomemname.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-nomemsemi.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-noopenbrace.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-noquotes.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-repmemname.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-vlaonly.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badstruct-zerolenarr.ksh \ + mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.badunion-hasvla.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.extraargs.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.noargs.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.nokeyword.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.nomodel.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.noname.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/err.typeexists.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.anonstruct.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.anonstruct.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.anonunion.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.anonunion.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.cleanupstruct.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.deftypes32.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.deftypes32.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.deftypes64.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.deftypes64.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.dellist.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.emptylist.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.libctype.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.libctype.ksh.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.models.ksh mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.struct.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.struct.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.structselfref.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.structselfref.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.structvla.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.structvla.mdb.out mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.union.mdb mode=0444 +file path=opt/util-tests/tests/mdb/typedef/tst.union.mdb.out mode=0444 file path=opt/util-tests/tests/mergeq/mqt mode=0555 file path=opt/util-tests/tests/mergeq/wqt mode=0555 file path=opt/util-tests/tests/printf_test mode=0555 diff --git a/usr/src/test/util-tests/runfiles/default.run b/usr/src/test/util-tests/runfiles/default.run index 307518139d..a2d463761c 100644 --- a/usr/src/test/util-tests/runfiles/default.run +++ b/usr/src/test/util-tests/runfiles/default.run @@ -13,7 +13,7 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> # Copyright 2014 Nexenta Systems, Inc. All rights reserved. -# Copyright 2019 Joyent, Inc. +# Copyright 2020 Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # @@ -78,3 +78,7 @@ tests = [ 'ctftest' ] [/opt/util-tests/tests/libcustr] tests = ['custr_remove', 'custr_trunc'] + +[/opt/util-tests/tests/find/findtest] + +[/opt/util-tests/tests/mdb/mdbtest] diff --git a/usr/src/test/util-tests/tests/Makefile b/usr/src/test/util-tests/tests/Makefile index 67efd10530..3362ac2941 100644 --- a/usr/src/test/util-tests/tests/Makefile +++ b/usr/src/test/util-tests/tests/Makefile @@ -20,6 +20,6 @@ SUBDIRS = date dis dladm iconv libnvpair_json libsff printf xargs grep_xpg4 SUBDIRS += demangle mergeq workq chown ctf smbios libjedec awk make sleep -SUBDIRS += bunyan libcustr +SUBDIRS += bunyan libcustr find mdb include $(SRC)/test/Makefile.com diff --git a/usr/src/test/util-tests/tests/find/Makefile b/usr/src/test/util-tests/tests/find/Makefile new file mode 100644 index 0000000000..66e2bab009 --- /dev/null +++ b/usr/src/test/util-tests/tests/find/Makefile @@ -0,0 +1,41 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2020 Joyent, Inc. +# + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +ROOTOPTPKG = $(ROOT)/opt/util-tests/tests/find +PROG = findtest + +ROOTPROG = $(PROG:%=$(ROOTOPTPKG)/%) + +all: + +install: $(ROOTPROG) + +clobber: clean + +clean: + +$(CMDS): $(TESTDIR) + +$(ROOTOPTPKG): + $(INS.dir) + +$(ROOTOPTPKG)/%: %.ksh $(ROOTOPTPKG) + $(INS.rename) + +$(ROOTOPTPKG)/%: % $(ROOTOPTPKG) + $(INS.file) diff --git a/usr/src/test/util-tests/tests/find/findtest.ksh b/usr/src/test/util-tests/tests/find/findtest.ksh new file mode 100644 index 0000000000..9e321fb664 --- /dev/null +++ b/usr/src/test/util-tests/tests/find/findtest.ksh @@ -0,0 +1,72 @@ +#!/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2020 Joyent, Inc. +# + +# +# Clearly, grossly incomplete. +# + +export LC_ALL=C.UTF-8 + +set -o pipefail +unalias -a + +find_prog=/usr/bin/find +find_prog_xpg4=/usr/xpg4/bin/find +find_dir="$(mktemp -d -p /tmp/)" +find_exit=0 + +testfind() +{ + exp=$1 + shift + cmd="$@" + + echo "TEST: $cmd" + + out=$(eval $cmd | tr '\n' ',') + + [[ "$exp" = "$out" ]] || { + echo "TEST FAILED: $cmd" >&2 + echo "expected: $exp" >&2 + echo "got: $out" >&2 + find_exit=1 + } +} + +mkdir -p $find_dir/1 +mkdir -p $find_dir/.2 +touch $find_dir/.2/1 +touch $find_dir/.2/c + +testfind "$find_dir/1,$find_dir/.2/1," \ + $find_prog $find_dir -name \"1\" +testfind "$find_dir/1,$find_dir/.2/1," \ + $find_prog $find_dir -path \"*1\" + +cd $find_dir + +testfind "" $find_prog . -name \"*2\" +testfind "./.2," $find_prog_xpg4 . -name \"*2\" +testfind "./.2," $find_prog . -name \".*2\" +testfind "./.2," $find_prog_xpg4 . -name \".*2\" +testfind "./1,./.2/1," $find_prog . -path \"*1\" +testfind "./.2," $find_prog . -path \"*2\" +testfind "./.2,./.2/1,./.2/c," $find_prog . -path \"*2*\" + +cd - +rm -rf $find_dir + +exit $find_exit diff --git a/usr/src/test/util-tests/tests/mdb/Makefile b/usr/src/test/util-tests/tests/mdb/Makefile new file mode 100644 index 0000000000..d7d205bc82 --- /dev/null +++ b/usr/src/test/util-tests/tests/mdb/Makefile @@ -0,0 +1,127 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2020 Joyent, Inc. +# + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +ROOTOPTPKG = $(ROOT)/opt/util-tests +TESTDIR = $(ROOTOPTPKG)/tests/mdb + +PROG = mdbtest + +ROOTPROG = $(PROG:%=$(TESTDIR)/%) + +MAKEDIRS = \ + exit-e \ + format \ + options \ + typedef + +FILES = \ + exit-e/err.cmdbadopt.ksh \ + exit-e/err.enocmd.ksh \ + exit-e/err.nowrite.ksh \ + exit-e/err.unmapped.ksh \ + exit-e/tst.output.ksh \ + exit-e/tst.output.ksh.out \ + exit-e/tst.simple.ksh \ + format/tst.format-cap-E.mdb \ + format/tst.format-cap-E.mdb.out \ + format/tst.format-cap-G.mdb \ + format/tst.format-cap-G.mdb.out \ + format/tst.format-cap-J.mdb \ + format/tst.format-cap-J.mdb.out \ + format/tst.format-cap-P.mdb \ + format/tst.format-cap-P.mdb.out \ + format/tst.format-cap-R.mdb \ + format/tst.format-cap-R.mdb.out \ + format/tst.format-e.mdb \ + format/tst.format-e.mdb.out \ + format/tst.format-g.mdb \ + format/tst.format-g.mdb.out \ + format/tst.format-j.mdb \ + format/tst.format-j.mdb.out \ + format/tst.format-p.mdb \ + format/tst.format-p.mdb.out \ + options/tst.autowrap.mdb \ + options/tst.autowrap.mdb.out \ + typedef/err.badid-leadnum.ksh \ + typedef/err.badid-leadschar.ksh \ + typedef/err.badmodel.ksh \ + typedef/err.badstruct-extrabraces.ksh \ + typedef/err.badstruct-neglenarr.ksh \ + typedef/err.badstruct-noarrayclose.ksh \ + typedef/err.badstruct-noarraylen.ksh \ + typedef/err.badstruct-noarrayopen.ksh \ + typedef/err.badstruct-nobraces.ksh \ + typedef/err.badstruct-noclosebrace.ksh \ + typedef/err.badstruct-nomembers.ksh \ + typedef/err.badstruct-nomemname.ksh \ + typedef/err.badstruct-nomemsemi.ksh \ + typedef/err.badstruct-noopenbrace.ksh \ + typedef/err.badstruct-noquotes.ksh \ + typedef/err.badstruct-repmemname.ksh \ + typedef/err.badstruct-vlaonly.ksh \ + typedef/err.badstruct-zerolenarr.ksh \ + typedef/err.badunion-hasvla.ksh \ + typedef/err.extraargs.ksh \ + typedef/err.noargs.ksh \ + typedef/err.nokeyword.ksh \ + typedef/err.nomodel.ksh \ + typedef/err.noname.ksh \ + typedef/err.typeexists.ksh \ + typedef/tst.anonstruct.mdb \ + typedef/tst.anonstruct.mdb.out \ + typedef/tst.anonunion.mdb \ + typedef/tst.anonunion.mdb.out \ + typedef/tst.cleanupstruct.ksh \ + typedef/tst.deftypes32.mdb \ + typedef/tst.deftypes32.mdb.out \ + typedef/tst.deftypes64.mdb \ + typedef/tst.deftypes64.mdb.out \ + typedef/tst.dellist.mdb \ + typedef/tst.emptylist.mdb \ + typedef/tst.libctype.ksh \ + typedef/tst.libctype.ksh.out \ + typedef/tst.models.ksh \ + typedef/tst.struct.mdb \ + typedef/tst.struct.mdb.out \ + typedef/tst.structselfref.mdb \ + typedef/tst.structselfref.mdb.out \ + typedef/tst.structvla.mdb \ + typedef/tst.structvla.mdb.out \ + typedef/tst.union.mdb \ + typedef/tst.union.mdb.out \ + +ROOTFILES = $(FILES:%=$(TESTDIR)/%) +ROOTMAKEDIRS = $(MAKEDIRS:%=$(TESTDIR)/%) + +FILEMODE = 0444 + +$(TESTDIR)/mdbtest := FILEMODE = 0555 + +all: + +install: all $(ROOTFILES) $(ROOTPROG) + +clean clobber: + +$(ROOTFILES): $(TESTDIR) $(ROOTMAKEDIRS) $(FILES) + +$(TESTDIR) $(ROOTMAKEDIRS): + $(INS.dir) + +$(TESTDIR)/%: % + $(INS.file) diff --git a/usr/src/cmd/mdb/test/README b/usr/src/test/util-tests/tests/mdb/README index 28127e5916..28127e5916 100644 --- a/usr/src/cmd/mdb/test/README +++ b/usr/src/test/util-tests/tests/mdb/README diff --git a/usr/src/cmd/mdb/test/exit-e/err.cmdbadopt.ksh b/usr/src/test/util-tests/tests/mdb/exit-e/err.cmdbadopt.ksh index de50faeb01..de50faeb01 100644 --- a/usr/src/cmd/mdb/test/exit-e/err.cmdbadopt.ksh +++ b/usr/src/test/util-tests/tests/mdb/exit-e/err.cmdbadopt.ksh diff --git a/usr/src/cmd/mdb/test/exit-e/err.enocmd.ksh b/usr/src/test/util-tests/tests/mdb/exit-e/err.enocmd.ksh index 038f121b26..038f121b26 100644 --- a/usr/src/cmd/mdb/test/exit-e/err.enocmd.ksh +++ b/usr/src/test/util-tests/tests/mdb/exit-e/err.enocmd.ksh diff --git a/usr/src/cmd/mdb/test/exit-e/err.nowrite.ksh b/usr/src/test/util-tests/tests/mdb/exit-e/err.nowrite.ksh index 8f0fda2253..8f0fda2253 100644 --- a/usr/src/cmd/mdb/test/exit-e/err.nowrite.ksh +++ b/usr/src/test/util-tests/tests/mdb/exit-e/err.nowrite.ksh diff --git a/usr/src/cmd/mdb/test/exit-e/err.unmapped.ksh b/usr/src/test/util-tests/tests/mdb/exit-e/err.unmapped.ksh index 874283f186..874283f186 100644 --- a/usr/src/cmd/mdb/test/exit-e/err.unmapped.ksh +++ b/usr/src/test/util-tests/tests/mdb/exit-e/err.unmapped.ksh diff --git a/usr/src/cmd/mdb/test/exit-e/tst.output.ksh b/usr/src/test/util-tests/tests/mdb/exit-e/tst.output.ksh index 13b5db072d..13b5db072d 100644 --- a/usr/src/cmd/mdb/test/exit-e/tst.output.ksh +++ b/usr/src/test/util-tests/tests/mdb/exit-e/tst.output.ksh diff --git a/usr/src/cmd/mdb/test/exit-e/tst.output.ksh.out b/usr/src/test/util-tests/tests/mdb/exit-e/tst.output.ksh.out index 7a38ab6e65..7a38ab6e65 100644 --- a/usr/src/cmd/mdb/test/exit-e/tst.output.ksh.out +++ b/usr/src/test/util-tests/tests/mdb/exit-e/tst.output.ksh.out diff --git a/usr/src/cmd/mdb/test/exit-e/tst.simple.ksh b/usr/src/test/util-tests/tests/mdb/exit-e/tst.simple.ksh index 4c8a3c58ad..4c8a3c58ad 100644 --- a/usr/src/cmd/mdb/test/exit-e/tst.simple.ksh +++ b/usr/src/test/util-tests/tests/mdb/exit-e/tst.simple.ksh diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-E.mdb index 18e9053ce4..18e9053ce4 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-E.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-E.mdb.out index 2268a48be9..2268a48be9 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-E.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-G.mdb index f10f78336b..f10f78336b 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-G.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-G.mdb.out index f1dfd5193b..f1dfd5193b 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-G.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-J.mdb index ff9dabbce9..ff9dabbce9 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-J.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-J.mdb.out index 644fee231e..644fee231e 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-J.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-P.mdb index 88928fda29..88928fda29 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-P.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-P.mdb.out index 65e05e7220..65e05e7220 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-P.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-R.mdb index 9f55408276..9f55408276 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-R.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-R.mdb.out index f05b0bac4d..f05b0bac4d 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-cap-R.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-e.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-e.mdb index 79d4b25af4..79d4b25af4 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-e.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-e.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-e.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-e.mdb.out index 909c53cbc0..909c53cbc0 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-e.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-e.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-g.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-g.mdb index b3397d21ed..b3397d21ed 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-g.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-g.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-g.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-g.mdb.out index c46dff3594..c46dff3594 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-g.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-g.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-j.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-j.mdb index 875a1e178f..875a1e178f 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-j.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-j.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-j.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-j.mdb.out index 3f5fa0afaf..3f5fa0afaf 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-j.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-j.mdb.out diff --git a/usr/src/cmd/mdb/test/format/tst.format-p.mdb b/usr/src/test/util-tests/tests/mdb/format/tst.format-p.mdb index ee2b989d1b..ee2b989d1b 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-p.mdb +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-p.mdb diff --git a/usr/src/cmd/mdb/test/format/tst.format-p.mdb.out b/usr/src/test/util-tests/tests/mdb/format/tst.format-p.mdb.out index 65e05e7220..65e05e7220 100644 --- a/usr/src/cmd/mdb/test/format/tst.format-p.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/format/tst.format-p.mdb.out diff --git a/usr/src/cmd/mdb/test/mtest.sh b/usr/src/test/util-tests/tests/mdb/mdbtest index f21d0faa21..96ffdc4c2d 100755 --- a/usr/src/cmd/mdb/test/mtest.sh +++ b/usr/src/test/util-tests/tests/mdb/mdbtest @@ -11,7 +11,7 @@ # # -# Copyright 2012 (c), Joyent, Inc. +# Copyright 2020 Joyent, Inc. # # @@ -40,7 +40,6 @@ function usage Usage: $mt_arg0 [ -o dir ] [ -k ] [ -m executable ] [ -a | test ... ] -o dir Sets 'dir' as the output directory - -a Runs all tests, ignores tests passed in -k Keep output from all tests, not just failures -m mdb binary to test USAGE @@ -180,11 +179,8 @@ EOF fi } -while getopts ":ahko:m:" c $@; do +while getopts ":hko:m:" c $@; do case "$c" in - a) - mt_all="y" - ;; k) mt_keep="y" ;; @@ -208,7 +204,7 @@ done shift $((OPTIND-1)) -[[ -z "$mt_all" && $# == 0 ]] && usage "no tests to run" +[[ $# == 0 ]] && mt_all="y" [[ -x "$mt_mdb" ]] || fatal "unable to execute mdb binary: $mt_mdb" diff --git a/usr/src/cmd/mdb/test/options/tst.autowrap.mdb b/usr/src/test/util-tests/tests/mdb/options/tst.autowrap.mdb index 5904cbf4c7..5904cbf4c7 100644 --- a/usr/src/cmd/mdb/test/options/tst.autowrap.mdb +++ b/usr/src/test/util-tests/tests/mdb/options/tst.autowrap.mdb diff --git a/usr/src/cmd/mdb/test/options/tst.autowrap.mdb.out b/usr/src/test/util-tests/tests/mdb/options/tst.autowrap.mdb.out index 81d3ef5293..81d3ef5293 100644 --- a/usr/src/cmd/mdb/test/options/tst.autowrap.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/options/tst.autowrap.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/err.badid-leadnum.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badid-leadnum.ksh index f297cf99f1..f297cf99f1 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badid-leadnum.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badid-leadnum.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badid-leadschar.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badid-leadschar.ksh index 5c7582b89c..5c7582b89c 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badid-leadschar.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badid-leadschar.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badmodel.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badmodel.ksh index 28d6cf05a5..28d6cf05a5 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badmodel.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badmodel.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-extrabraces.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-extrabraces.ksh index 3543aab1df..3543aab1df 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-extrabraces.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-extrabraces.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-neglenarr.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-neglenarr.ksh index ec41576179..ec41576179 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-neglenarr.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-neglenarr.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-noarrayclose.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noarrayclose.ksh index b91094ae44..b91094ae44 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-noarrayclose.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noarrayclose.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-noarraylen.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noarraylen.ksh index 4fe23fcee2..4fe23fcee2 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-noarraylen.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noarraylen.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-noarrayopen.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noarrayopen.ksh index 9fe7e77200..9fe7e77200 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-noarrayopen.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noarrayopen.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-nobraces.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nobraces.ksh index d50d8e3fb9..d50d8e3fb9 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-nobraces.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nobraces.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-noclosebrace.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noclosebrace.ksh index 4b20fac8c5..4b20fac8c5 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-noclosebrace.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noclosebrace.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-nomembers.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nomembers.ksh index 9fd82a01cc..9fd82a01cc 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-nomembers.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nomembers.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-nomemname.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nomemname.ksh index e1e4eacf13..e1e4eacf13 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-nomemname.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nomemname.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-nomemsemi.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nomemsemi.ksh index 9ab93a792f..9ab93a792f 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-nomemsemi.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-nomemsemi.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-noopenbrace.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noopenbrace.ksh index 450b35ade2..450b35ade2 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-noopenbrace.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noopenbrace.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-noquotes.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noquotes.ksh index 789caf63b0..789caf63b0 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-noquotes.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-noquotes.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-repmemname.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-repmemname.ksh index c00aca88fb..c00aca88fb 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-repmemname.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-repmemname.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-vlaonly.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-vlaonly.ksh index a678d136b6..a678d136b6 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-vlaonly.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-vlaonly.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badstruct-zerolenarr.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-zerolenarr.ksh index 7999c97a5a..7999c97a5a 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badstruct-zerolenarr.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badstruct-zerolenarr.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.badunion-hasvla.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.badunion-hasvla.ksh index 57a82a7752..57a82a7752 100644 --- a/usr/src/cmd/mdb/test/typedef/err.badunion-hasvla.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.badunion-hasvla.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.extraargs.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.extraargs.ksh index 510797265b..510797265b 100644 --- a/usr/src/cmd/mdb/test/typedef/err.extraargs.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.extraargs.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.noargs.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.noargs.ksh index 77eeacc5f2..77eeacc5f2 100644 --- a/usr/src/cmd/mdb/test/typedef/err.noargs.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.noargs.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.nokeyword.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.nokeyword.ksh index 9a5e1a1fcc..9a5e1a1fcc 100644 --- a/usr/src/cmd/mdb/test/typedef/err.nokeyword.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.nokeyword.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.nomodel.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.nomodel.ksh index 4614ac23d6..4614ac23d6 100644 --- a/usr/src/cmd/mdb/test/typedef/err.nomodel.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.nomodel.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.noname.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.noname.ksh index 04ebca1204..04ebca1204 100644 --- a/usr/src/cmd/mdb/test/typedef/err.noname.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.noname.ksh diff --git a/usr/src/cmd/mdb/test/typedef/err.typeexists.ksh b/usr/src/test/util-tests/tests/mdb/typedef/err.typeexists.ksh index a1158cd830..a1158cd830 100644 --- a/usr/src/cmd/mdb/test/typedef/err.typeexists.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/err.typeexists.ksh diff --git a/usr/src/cmd/mdb/test/typedef/tst.anonstruct.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonstruct.mdb index 27de9428c6..27de9428c6 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.anonstruct.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonstruct.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.anonstruct.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonstruct.mdb.out index 605e0facfc..605e0facfc 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.anonstruct.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonstruct.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.anonunion.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonunion.mdb index 1aa17b5366..1aa17b5366 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.anonunion.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonunion.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.anonunion.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonunion.mdb.out index 0a762dc1f8..0a762dc1f8 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.anonunion.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.anonunion.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.cleanupstruct.ksh b/usr/src/test/util-tests/tests/mdb/typedef/tst.cleanupstruct.ksh index fabc7dfb57..fabc7dfb57 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.cleanupstruct.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.cleanupstruct.ksh diff --git a/usr/src/cmd/mdb/test/typedef/tst.deftypes32.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes32.mdb index 12c28075a8..12c28075a8 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.deftypes32.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes32.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.deftypes32.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes32.mdb.out index 792f42fbf2..792f42fbf2 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.deftypes32.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes32.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.deftypes64.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes64.mdb index 5ae94cdea0..5ae94cdea0 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.deftypes64.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes64.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.deftypes64.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes64.mdb.out index 83b85b943a..83b85b943a 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.deftypes64.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.deftypes64.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.dellist.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.dellist.mdb index e9009d7b68..e9009d7b68 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.dellist.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.dellist.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.dellist.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.dellist.mdb.out index e69de29bb2..e69de29bb2 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.dellist.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.dellist.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.emptylist.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.emptylist.mdb index 6c7505ac1c..6c7505ac1c 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.emptylist.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.emptylist.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.emptylist.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.emptylist.mdb.out index e69de29bb2..e69de29bb2 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.emptylist.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.emptylist.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.libctype.ksh b/usr/src/test/util-tests/tests/mdb/typedef/tst.libctype.ksh index cf517cf937..cf517cf937 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.libctype.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.libctype.ksh diff --git a/usr/src/cmd/mdb/test/typedef/tst.libctype.ksh.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.libctype.ksh.out index d37ffafbfb..d37ffafbfb 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.libctype.ksh.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.libctype.ksh.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.models.ksh b/usr/src/test/util-tests/tests/mdb/typedef/tst.models.ksh index 8537ec443c..8537ec443c 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.models.ksh +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.models.ksh diff --git a/usr/src/cmd/mdb/test/typedef/tst.struct.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.struct.mdb index 2e0206e7ec..2e0206e7ec 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.struct.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.struct.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.struct.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.struct.mdb.out index 9a7d801742..9a7d801742 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.struct.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.struct.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.structselfref.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.structselfref.mdb index 85b3068e00..85b3068e00 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.structselfref.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.structselfref.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.structselfref.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.structselfref.mdb.out index a6f4823ad1..a6f4823ad1 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.structselfref.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.structselfref.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.structvla.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.structvla.mdb index 27cd56c186..27cd56c186 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.structvla.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.structvla.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.structvla.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.structvla.mdb.out index 0a0d3d4029..0a0d3d4029 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.structvla.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.structvla.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.union.mdb b/usr/src/test/util-tests/tests/mdb/typedef/tst.union.mdb index 966446caee..966446caee 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.union.mdb +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.union.mdb diff --git a/usr/src/cmd/mdb/test/typedef/tst.union.mdb.out b/usr/src/test/util-tests/tests/mdb/typedef/tst.union.mdb.out index 2afc2eabb9..2afc2eabb9 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.union.mdb.out +++ b/usr/src/test/util-tests/tests/mdb/typedef/tst.union.mdb.out diff --git a/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/Makefile b/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/Makefile index 2034d39599..5f8ea55a97 100644 --- a/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/Makefile +++ b/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/Makefile @@ -11,15 +11,27 @@ # # Copyright (c) 2016 by Delphix. All rights reserved. +# Copyright 2020 Joyent, Inc. # include $(SRC)/Makefile.master +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/cmd/Makefile.ctf ROOTOPTPKG = $(ROOT)/opt/zfs-tests TESTDIR = $(ROOTOPTPKG)/tests/functional/channel_program/synctask_core KSHFILES :sh= ls *.ksh -PROGS = $(KSHFILES:.ksh=) +KSHPROGS = $(KSHFILES:.ksh=) + +SRCS :sh= ls *.c +CPROGS = $(SRCS:%.c=%.exe) +LDLIBS = $(LDLIBS.cmd) +LDLIBS += -lzfs_core -lnvpair +CSTD = $(CSTD_GNU99) +OBJS = $(SRCS:%.c=%.o) + +PROGS = $(KSHPROGS) $(CPROGS) FILES :sh= ls *.zcp *.out *.err 2>/dev/null; true INSTPROGS = $(PROGS:%=$(TESTDIR)/%) @@ -28,7 +40,9 @@ INSTFILES = $(FILES:%=$(TESTDIR)/%) $(INSTPROGS) := FILEMODE = 0555 $(INSTFILES) := FILEMODE = 0444 -all lint clean clobber: +all: $(CPROGS) + +clean clobber: install: $(INSTPROGS) $(INSTFILES) @@ -43,3 +57,16 @@ $(TESTDIR)/%: %.ksh $(TESTDIR)/%: % $(INS.file) + +%.o: ../%.c + $(COMPILE.c) $< + +%.exe: %.o + $(LINK.c) $< -o $@ $(LDLIBS) + $(POST_PROCESS) + +clobber: clean + -$(RM) $(PROGS) + +clean: + -$(RM) $(OBJS) diff --git a/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/change_key.c b/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/change_key.c new file mode 100644 index 0000000000..405c232b4e --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/change_key.c @@ -0,0 +1,98 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright 2020 Joyent, Inc. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/debug.h> +#include <sys/fs/zfs.h> +#include <libzfs_core.h> +#include <libnvpair.h> + +const char prog[] = + "arg = ... \n" + "fs = arg[\"dataset\"]\n" + "hexkey = arg[\"" ZPOOL_HIDDEN_ARGS "\"][\"key\"]\n" + "err = zfs.sync.change_key(fs, hexkey, 'hex')\n" + "msg = \"changing key on \" .. fs .. \" err=\" .. err\n" + "return msg"; + +/* + * Get the pool name from a dataset. This is crude but good enough + * for a test. + */ +static char * +get_pool(const char *dataset) +{ + char *res = strdup(dataset); + + if (res == NULL) + abort(); + + char *p = strchr(res, '/'); + + if (p != NULL) + *p = '\0'; + + return (res); +} + +int +main(int argc, char *argv[]) +{ + const char *dataset = argv[1]; + const char *key = argv[2]; + char *pool = NULL; + nvlist_t *args = fnvlist_alloc(); + nvlist_t *hidden_args = fnvlist_alloc(); + nvlist_t *result = NULL; + int ret = 0; + + if (argc != 3) { + (void) fprintf(stderr, "Usage: %s dataset key\n", argv[0]); + exit(2); + } + + VERIFY0(libzfs_core_init()); + + pool = get_pool(dataset); + + fnvlist_add_string(args, "dataset", dataset); + fnvlist_add_string(hidden_args, "key", key); + fnvlist_add_nvlist(args, ZPOOL_HIDDEN_ARGS, hidden_args); + + ret = lzc_channel_program(pool, prog, ZCP_DEFAULT_INSTRLIMIT, + ZCP_DEFAULT_MEMLIMIT, args, &result); + + (void) printf("lzc_channel_program returned %d", ret); + if (ret != 0) + (void) printf(" (%s)", strerror(ret)); + (void) fputc('\n', stdout); + + dump_nvlist(result, 5); + + nvlist_free(args); + nvlist_free(hidden_args); + nvlist_free(result); + free(pool); + + libzfs_core_fini(); + + return (ret); +} diff --git a/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/tst.change_key.ksh b/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/tst.change_key.ksh new file mode 100644 index 0000000000..5d505226b8 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/channel_program/synctask_core/tst.change_key.ksh @@ -0,0 +1,56 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# CDDL HEADER END +# + +# +# Copyright 2020 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +# +# DESCRIPTION: +# Try to change an encrypted dataset key via a ZFS channel program + +verify_runnable "both" + +function cleanup +{ + datasetexists $TESTPOOL/$TESTFS1 && \ + log_must zfs destroy -f $TESTPOOL/$TESTFS1 +} +log_onexit cleanup + +log_assert "zfs.sync.change_key should change key material" + +log_must eval "echo $HEXKEY | zfs create -o encryption=on" \ + "-o keyformat=hex -o keylocation=prompt $TESTPOOL/$TESTFS1" + +log_must $ZCP_ROOT/synctask_core/change_key.exe $TESTPOOL/$TESTFS1 $HEXKEY1 + +# Key shouldn't appear in zpool history when using change_key.exe +log_mustnot eval "zfs history -il $TESTPOOL | grep $HEXKEY1" + +log_must zfs unmount $TESTPOOL/$TESTFS1 +log_must zfs unload-key $TESTPOOL/$TESTFS1 + +log_mustnot eval "echo $HEXKEY | zfs load-key $TESTPOOL/$TESTFS1" +log_must key_unavailable $TESTPOOL/$TESTFS1 + +log_must eval "echo $HEXKEY1 | zfs load-key $TESTPOOL/$TESTFS1" + +log_pass "zfs.sync.change_key should change key material" diff --git a/usr/src/tools/findunref/exception_list.open b/usr/src/tools/findunref/exception_list.open index 6c432c78c1..ae18a9c8ac 100644 --- a/usr/src/tools/findunref/exception_list.open +++ b/usr/src/tools/findunref/exception_list.open @@ -23,6 +23,7 @@ # # Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright 2020 Joyent, Inc. # # # open-tree exception list @@ -239,4 +240,3 @@ # ld tests which are not currently delivered # ./usr/src/cmd/sgs/test -./usr/src/cmd/mdb/test diff --git a/usr/src/tools/make/Makefile.com b/usr/src/tools/make/Makefile.com index 34074bb00a..8fbe1bc1b4 100644 --- a/usr/src/tools/make/Makefile.com +++ b/usr/src/tools/make/Makefile.com @@ -10,6 +10,7 @@ # # Copyright 2015, Richard Lowe. +# Copyright 2020 Joyent, Inc. MAKE_INCLUDE= $(SRC)/cmd/make/include @@ -19,3 +20,4 @@ CFLAGS = $(NATIVE_CFLAGS) CFLAGS += $(CCVERBOSE) CCFLAGS = $(NATIVE_CCFLAGS) -_gcc4=-std=gnu++0x CPPFLAGS = -I$(MAKE_INCLUDE) $(MAKE_DEFS) +CCNEEDED = $(NATIVECCNEEDED) diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 79f7ca8b47..ce7b7a3e6a 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -1440,6 +1440,7 @@ ZFS_COMMON_OBJS += \ zap_leaf.o \ zap_micro.o \ zcp.o \ + zcp_change_key.o \ zcp_get.o \ zcp_set.o \ zcp_global.o \ @@ -2317,3 +2318,9 @@ BNX_OBJS += \ bnx_lm_main.o \ bnx_lm_recv.o \ bnx_lm_send.o + +# +# mlxcx(7D) +# +MLXCX_OBJS += mlxcx.o mlxcx_dma.o mlxcx_cmd.o mlxcx_intr.o mlxcx_gld.o \ + mlxcx_ring.o diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules index 1d052bdcc2..8a906a2e25 100644 --- a/usr/src/uts/common/Makefile.rules +++ b/usr/src/uts/common/Makefile.rules @@ -956,6 +956,10 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/mii/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) +$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/mlxcx/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/mr_sas/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) diff --git a/usr/src/uts/common/fs/namefs/namevfs.c b/usr/src/uts/common/fs/namefs/namevfs.c index 9952f0a742..63e618de11 100644 --- a/usr/src/uts/common/fs/namefs/namevfs.c +++ b/usr/src/uts/common/fs/namefs/namevfs.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017 by Delphix. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -182,6 +183,31 @@ namefind(vnode_t *vp, vnode_t *mnt) } /* + * For each namenode that has nm_filevp == vp, call the provided function + * with the namenode as an argument. This finds all of the namefs entries + * which are mounted on vp; note that there can be more than one. + */ +int +nm_walk_mounts(const vnode_t *vp, nm_walk_mounts_f *func, cred_t *cr, void *arg) +{ + struct namenode *np; + int ret = 0; + + mutex_enter(&ntable_lock); + + for (np = *NM_FILEVP_HASH(vp); np != NULL; np = np->nm_nextp) { + if (np->nm_filevp == vp) { + if ((ret = func(np, cr, arg)) != 0) + break; + } + } + + mutex_exit(&ntable_lock); + + return (ret); +} + +/* * Force the unmouting of a file descriptor from ALL of the nodes * that it was mounted to. * At the present time, the only usage for this routine is in the @@ -480,6 +506,7 @@ nm_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *crp) newvp->v_rdev = filevp->v_rdev; newvp->v_data = (caddr_t)nodep; VFS_HOLD(vfsp); + vn_copypath(mvp, newvp); vn_exists(newvp); /* diff --git a/usr/src/uts/common/fs/proc/prsubr.c b/usr/src/uts/common/fs/proc/prsubr.c index 0a9589a373..08aee63610 100644 --- a/usr/src/uts/common/fs/proc/prsubr.c +++ b/usr/src/uts/common/fs/proc/prsubr.c @@ -75,6 +75,7 @@ #include <sys/autoconf.h> #include <sys/dtrace.h> #include <sys/timod.h> +#include <sys/fs/namenode.h> #include <netinet/udp.h> #include <netinet/tcp.h> #include <inet/cc.h> @@ -2552,7 +2553,11 @@ prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred) size_t pathlen; size_t sz = 0; - pathlen = MAXPATHLEN + 1; + /* + * The global zone's path to a file in a non-global zone can exceed + * MAXPATHLEN. + */ + pathlen = MAXPATHLEN * 2 + 1; pathname = kmem_alloc(pathlen, KM_SLEEP); if (vnodetopath(NULL, vp, pathname, pathlen, cred) == 0) { @@ -2561,6 +2566,7 @@ prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred) } kmem_free(pathname, pathlen); + return (sz); } @@ -2789,6 +2795,22 @@ prfdinfosockopt(vnode_t *vp, list_t *data, cred_t *cred) return (sz); } +typedef struct prfdinfo_nm_path_cbdata { + proc_t *nmp_p; + u_offset_t nmp_sz; + list_t *nmp_data; +} prfdinfo_nm_path_cbdata_t; + +static int +prfdinfo_nm_path(const struct namenode *np, cred_t *cred, void *arg) +{ + prfdinfo_nm_path_cbdata_t *cb = arg; + + cb->nmp_sz += prfdinfopath(cb->nmp_p, np->nm_vnode, cb->nmp_data, cred); + + return (0); +} + u_offset_t prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred) { @@ -2801,8 +2823,23 @@ prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred) sz = offsetof(prfdinfo_t, pr_misc) + sizeof (pr_misc_header_t); /* Pathname */ - if (vp->v_type != VSOCK && vp->v_type != VDOOR) + switch (vp->v_type) { + case VDOOR: { + prfdinfo_nm_path_cbdata_t cb = { + .nmp_p = p, + .nmp_data = NULL, + .nmp_sz = 0 + }; + + (void) nm_walk_mounts(vp, prfdinfo_nm_path, cred, &cb); + sz += cb.nmp_sz; + break; + } + case VSOCK: + break; + default: sz += prfdinfopath(p, vp, NULL, cred); + } /* Socket options */ if (vp->v_type == VSOCK) @@ -2946,14 +2983,31 @@ prgetfdinfo(proc_t *p, vnode_t *vp, prfdinfo_t *fdinfo, cred_t *cred, } } - /* - * Don't attempt to determine the vnode path for a socket or a door - * as it will cause a linear scan of the dnlc table given there is no - * v_path associated with the vnode. - */ - if (vp->v_type != VSOCK && vp->v_type != VDOOR) + /* pathname */ + + switch (vp->v_type) { + case VDOOR: { + prfdinfo_nm_path_cbdata_t cb = { + .nmp_p = p, + .nmp_data = data, + .nmp_sz = 0 + }; + + (void) nm_walk_mounts(vp, prfdinfo_nm_path, cred, &cb); + break; + } + case VSOCK: + /* + * Don't attempt to determine the path for a socket as the + * vnode has no associated v_path. It will cause a linear scan + * of the dnlc table and result in no path being found. + */ + break; + default: (void) prfdinfopath(p, vp, data, cred); + } + /* socket options */ if (vp->v_type == VSOCK) (void) prfdinfosockopt(vp, data, cred); diff --git a/usr/src/uts/common/fs/zfs/dsl_crypt.c b/usr/src/uts/common/fs/zfs/dsl_crypt.c index c9d02e1c57..a092326a9c 100644 --- a/usr/src/uts/common/fs/zfs/dsl_crypt.c +++ b/usr/src/uts/common/fs/zfs/dsl_crypt.c @@ -1220,12 +1220,7 @@ dsl_crypto_key_sync(dsl_crypto_key_t *dck, dmu_tx_t *tx) tx); } -typedef struct spa_keystore_change_key_args { - const char *skcka_dsname; - dsl_crypto_params_t *skcka_cp; -} spa_keystore_change_key_args_t; - -static int +int spa_keystore_change_key_check(void *arg, dmu_tx_t *tx) { int ret; @@ -1469,7 +1464,7 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj, dsl_dir_rele(dd, FTAG); } -static void +void spa_keystore_change_key_sync(void *arg, dmu_tx_t *tx) { dsl_dataset_t *ds; diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h index cf19665aae..5b7c1a9510 100644 --- a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h +++ b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h @@ -164,6 +164,11 @@ typedef struct spa_keystore { avl_tree_t sk_wkeys; } spa_keystore_t; +typedef struct spa_keystore_change_key_args { + const char *skcka_dsname; + dsl_crypto_params_t *skcka_cp; +} spa_keystore_change_key_args_t; + int dsl_crypto_params_create_nvlist(dcp_cmd_t cmd, nvlist_t *props, nvlist_t *crypto_args, dsl_crypto_params_t **dcp_out); void dsl_crypto_params_free(dsl_crypto_params_t *dcp, boolean_t unload); @@ -199,6 +204,8 @@ int dsl_crypto_recv_raw(const char *poolname, uint64_t dsobj, uint64_t fromobj, dmu_objset_type_t ostype, nvlist_t *nvl, boolean_t do_key); int spa_keystore_change_key(const char *dsname, dsl_crypto_params_t *dcp); +int spa_keystore_change_key_check(void *arg, dmu_tx_t *tx); +void spa_keystore_change_key_sync(void *arg, dmu_tx_t *tx); int dsl_dir_rename_crypt_check(dsl_dir_t *dd, dsl_dir_t *newparent); int dsl_dataset_promote_crypt_check(dsl_dir_t *target, dsl_dir_t *origin); void dsl_dataset_promote_crypt_sync(dsl_dir_t *target, dsl_dir_t *origin, diff --git a/usr/src/uts/common/fs/zfs/sys/zcp_change_key.h b/usr/src/uts/common/fs/zfs/sys/zcp_change_key.h new file mode 100644 index 0000000000..fea520455f --- /dev/null +++ b/usr/src/uts/common/fs/zfs/sys/zcp_change_key.h @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright 2020 Joyent, Inc. + */ + +#ifndef _SYS_ZCP_CHANGE_KEY_H +#define _SYS_ZCP_CHANGE_KEY_H + +#include <sys/types.h> +#include <sys/dmu.h> +#include <sys/dsl_crypt.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void zcp_synctask_change_key_cleanup(void *arg); +int zcp_synctask_change_key_check(void *arg, dmu_tx_t *tx); +void zcp_synctask_change_key_sync(void *arg, dmu_tx_t *tx); +int zcp_synctask_change_key_create_params(const char *key, size_t keylen, + zfs_keyformat_t keyformat, dsl_crypto_params_t **dcpp); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ZCP_CHANGE_KEY_H */ diff --git a/usr/src/uts/common/fs/zfs/zcp_change_key.c b/usr/src/uts/common/fs/zfs/zcp_change_key.c new file mode 100644 index 0000000000..be16a8d5c6 --- /dev/null +++ b/usr/src/uts/common/fs/zfs/zcp_change_key.c @@ -0,0 +1,144 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright 2020 Joyent, Inc. + */ + +#include <sys/ctype.h> +#include <sys/zcp.h> +#include <sys/zcp_change_key.h> + +static uint8_t +hexval(char c) +{ + if (c >= '0' && c <= '9') + return (c - '0'); + else if (c >= 'a' && c <= 'f') + return (c - 'a' + 10); + else if (c >= 'A' && c <= 'F') + return (c - 'A' + 10); + + panic("invalid hex value"); +} + +static int +hex_to_raw(const char *key, uint8_t *buf, size_t buflen) +{ + uint8_t *p; + size_t srclen = strlen(key); + size_t i; + + if (buflen * 2 != srclen) + return (SET_ERROR(EINVAL)); + + for (i = 0, p = buf; i < srclen; i += 2, p++) { + if (!isxdigit(key[i]) || !isxdigit(key[i + 1])) + return (SET_ERROR(EINVAL)); + + *p = hexval(key[i]) << 4 | hexval(key[i + 1]); + } + + return (0); +} + +int +zcp_synctask_change_key_create_params(const char *key, size_t keylen, + zfs_keyformat_t keyformat, dsl_crypto_params_t **dcpp) +{ + nvlist_t *args = fnvlist_alloc(); + nvlist_t *hidden_args = fnvlist_alloc(); + uint8_t rawkey[WRAPPING_KEY_LEN]; + uint_t rawlen = 0; + int err = 0; + + /* + * Currently, only raw and hex keys are supported in channel + * programs (there is no pbkdf2 support in the kernel to convert + * a passphrase). + */ + switch (keyformat) { + case ZFS_KEYFORMAT_RAW: + /* + * dsl_crypto_params_create_nvlist() also verifies the + * raw key is WRAPPING_KEY_LEN bytes, so this is + * _almost_ redundant -- however we still want to + * guarantee we won't overflow rawkey when copying + * the contents over. + */ + if (keylen != WRAPPING_KEY_LEN) { + err = SET_ERROR(EINVAL); + goto done; + } + + bcopy(key, rawkey, keylen); + rawlen = keylen; + break; + case ZFS_KEYFORMAT_HEX: + /* + * hex_to_raw() will reject any input that doesn't exactly + * fit into rawkey + */ + err = hex_to_raw(key, rawkey, sizeof (rawkey)); + if (err != 0) + goto done; + rawlen = sizeof (rawkey); + break; + default: + err = SET_ERROR(EINVAL); + goto done; + } + + fnvlist_add_uint64(args, zfs_prop_to_name(ZFS_PROP_KEYFORMAT), + (uint64_t)keyformat); + fnvlist_add_uint8_array(hidden_args, "wkeydata", rawkey, rawlen); + + err = dsl_crypto_params_create_nvlist(DCP_CMD_NEW_KEY, args, + hidden_args, dcpp); + +done: + fnvlist_free(args); + fnvlist_free(hidden_args); + bzero(rawkey, sizeof (rawkey)); + + return (err); +} + +void +zcp_synctask_change_key_cleanup(void *arg) +{ + spa_keystore_change_key_args_t *skcka = arg; + + dsl_crypto_params_free(skcka->skcka_cp, B_TRUE); +} + +int +zcp_synctask_change_key_check(void *arg, dmu_tx_t *tx) +{ + /* + * zcp_synctask_change_key_create_params() already validates that + * the new key is in an acceptable format and size for a channel + * program. Any future channel program specific checks would go here. + * For now, we just perform all the same checks done for + * 'zfs change-key' by calling spa_keystore_change_key_check(). + */ + return (spa_keystore_change_key_check(arg, tx)); +} + +void +zcp_synctask_change_key_sync(void *arg, dmu_tx_t *tx) +{ + spa_keystore_change_key_sync(arg, tx); +} diff --git a/usr/src/uts/common/fs/zfs/zcp_synctask.c b/usr/src/uts/common/fs/zfs/zcp_synctask.c index 09af25c1c9..9a1dceb044 100644 --- a/usr/src/uts/common/fs/zfs/zcp_synctask.c +++ b/usr/src/uts/common/fs/zfs/zcp_synctask.c @@ -23,6 +23,8 @@ #include <sys/zcp.h> #include <sys/zcp_set.h> +#include <sys/zcp_change_key.h> +#include <sys/dsl_crypt.h> #include <sys/dsl_dir.h> #include <sys/dsl_pool.h> #include <sys/dsl_prop.h> @@ -399,6 +401,74 @@ zcp_synctask_set_prop(lua_State *state, boolean_t sync, nvlist_t *err_details) return (err); } +static int zcp_synctask_change_key(lua_State *, boolean_t, nvlist_t *); +static zcp_synctask_info_t zcp_synctask_change_key_info = { + .name = "change_key", + .func = zcp_synctask_change_key, + .pargs = { + { .za_name = "dataset", .za_lua_type = LUA_TSTRING }, + { .za_name = "key", .za_lua_type = LUA_TSTRING }, + { .za_name = "format", .za_lua_type = LUA_TSTRING }, + { NULL, 0 }, + }, + .kwargs = { + { NULL, 0 } + }, + .space_check = ZFS_SPACE_CHECK_RESERVED, + /* + * This is the same value that is used when zfs change-key is run. + * See spa_keystore_change_key() in dsl_crypt.c + */ + .blocks_modified = 15 +}; + +static int +zcp_synctask_change_key(lua_State *state, boolean_t sync, nvlist_t *err_details) +{ + int err; + spa_keystore_change_key_args_t skcka = { 0 }; + dsl_crypto_params_t *dcp = NULL; + const char *dsname; + const char *key; + const char *format; + size_t keylen; + uint64_t keyformat; + + dsname = lua_tostring(state, 1); + + /* + * The key may be raw key, which could contain NUL within it. + * Use lua_tolstring() instead of lua_tostring() to obtain the length. + */ + key = lua_tolstring(state, 2, &keylen); + + format = lua_tostring(state, 3); + + if (zfs_prop_string_to_index(ZFS_PROP_KEYFORMAT, format, + &keyformat) != 0) + return (SET_ERROR(EINVAL)); + + err = zcp_synctask_change_key_create_params(key, keylen, keyformat, + &dcp); + if (err != 0) + goto done; + + skcka.skcka_dsname = dsname; + skcka.skcka_cp = dcp; + + zcp_cleanup_handler_t *zch = zcp_register_cleanup(state, + (zcp_cleanup_t *)&zcp_synctask_change_key_cleanup, &skcka); + + err = zcp_sync_task(state, zcp_synctask_change_key_check, + zcp_synctask_change_key_sync, &skcka, sync, dsname); + + zcp_deregister_cleanup(state, zch); + +done: + dsl_crypto_params_free(dcp, (err != 0 || !sync) ? B_TRUE : B_FALSE); + return (err); +} + static int zcp_synctask_wrapper(lua_State *state) { @@ -468,6 +538,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync) &zcp_synctask_snapshot_info, &zcp_synctask_inherit_prop_info, &zcp_synctask_set_prop_info, + &zcp_synctask_change_key_info, NULL }; diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c index 2b4c1d55e7..153dcf1502 100644 --- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c @@ -3767,6 +3767,7 @@ zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl, uint64_t instrlimit, memlimit; boolean_t sync_flag; nvpair_t *nvarg = NULL; + nvlist_t *hidden_args = NULL; if (0 != nvlist_lookup_string(innvl, ZCP_ARG_PROGRAM, &program)) { return (EINVAL); @@ -3784,6 +3785,16 @@ zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl, return (EINVAL); } + /* hidden args are optional */ + if (nvlist_lookup_nvlist(innvl, ZPOOL_HIDDEN_ARGS, &hidden_args) == 0) { + nvlist_t *argnvl = fnvpair_value_nvlist(nvarg); + int ret; + + ret = nvlist_add_nvlist(argnvl, ZPOOL_HIDDEN_ARGS, hidden_args); + if (ret != 0) + return (ret); + } + if (instrlimit == 0 || instrlimit > zfs_lua_max_instrlimit) return (EINVAL); if (memlimit == 0 || memlimit > zfs_lua_max_memlimit) diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index f33a1abe4f..99011b83b4 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -23,7 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. * Copyright 2017 Nexenta Systems, Inc. */ @@ -377,6 +377,46 @@ zfs_ioctl(vnode_t *vp, int com, intptr_t data, int flag, cred_t *cred, return (0); } + case _FIODIRECTIO: + { + /* + * ZFS inherently provides the basic semantics for directio. + * This is the summary from the ZFS on Linux support for + * O_DIRECT, which is the common form of directio, and required + * no changes to ZFS. + * + * 1. Minimize cache effects of the I/O. + * + * By design the ARC is already scan-resistant, which helps + * mitigate the need for special O_DIRECT handling. + * + * 2. O_DIRECT _MAY_ impose restrictions on IO alignment and + * length. + * + * No additional alignment or length restrictions are + * imposed by ZFS. + * + * 3. O_DIRECT _MAY_ perform unbuffered IO operations directly + * between user memory and block device. + * + * No unbuffered IO operations are currently supported. In + * order to support features such as compression, encryption, + * and checksumming a copy must be made to transform the + * data. + * + * 4. O_DIRECT _MAY_ imply O_DSYNC (XFS). + * + * O_DIRECT does not imply O_DSYNC for ZFS. + * + * 5. O_DIRECT _MAY_ disable file locking that serializes IO + * operations. + * + * All I/O in ZFS is locked for correctness and this locking + * is not disabled by O_DIRECT. + */ + return (0); + } + case _FIO_SEEK_DATA: case _FIO_SEEK_HOLE: { diff --git a/usr/src/uts/common/inet/ilb/ilb.c b/usr/src/uts/common/inet/ilb/ilb.c index 8ab2a90116..91cd671b12 100644 --- a/usr/src/uts/common/inet/ilb/ilb.c +++ b/usr/src/uts/common/inet/ilb/ilb.c @@ -1679,6 +1679,8 @@ ilb_check(ilb_stack_t *ilbs, ill_t *ill, mblk_t *mp, in6_addr_t *src, uint16_t nat_src_idx; boolean_t busy; + ret = 0; + /* * We don't really need to switch here since both protocols's * ports are at the same offset. Just prepare for future protocol diff --git a/usr/src/uts/common/inet/ilb/ilb_conn.c b/usr/src/uts/common/inet/ilb/ilb_conn.c index 7f79d41dd6..24b0138fbf 100644 --- a/usr/src/uts/common/inet/ilb/ilb_conn.c +++ b/usr/src/uts/common/inet/ilb/ilb_conn.c @@ -132,6 +132,9 @@ ilb_conn_remove_common(ilb_conn_t *connp, boolean_t c2s) ilb_conn_t **next, **prev; ilb_conn_t **next_prev, **prev_next; + next_prev = NULL; + prev_next = NULL; + if (c2s) { hash = connp->conn_c2s_hash; ASSERT(MUTEX_HELD(&hash->ilb_conn_hash_lock)); @@ -698,6 +701,7 @@ update_conn_tcp(ilb_conn_t *connp, void *iph, tcpha_t *tcpha, int32_t pkt_len, uint32_t ack, seq; int32_t seg_len; + ack = 0; if (tcpha->tha_flags & TH_RST) return (B_FALSE); @@ -903,6 +907,11 @@ ilb_check_icmp_conn(ilb_stack_t *ilbs, mblk_t *mp, int l3, void *out_iph, uint32_t adj_ip_sum; boolean_t full_nat; + in_iph4 = NULL; + in_iph6 = NULL; + icmph4 = NULL; + icmph6 = NULL; + if (l3 == IPPROTO_IP) { in6_addr_t in_src, in_dst; diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h index e9a3fcdeeb..89574da71f 100644 --- a/usr/src/uts/common/inet/ip.h +++ b/usr/src/uts/common/inet/ip.h @@ -1730,8 +1730,6 @@ typedef struct ill_s { * Capabilities related fields. */ uint_t ill_dlpi_capab_state; /* State of capability query, IDCS_* */ - kcondvar_t ill_dlpi_capab_cv; /* CV for broadcasting state changes */ - kmutex_t ill_dlpi_capab_lock; /* Lock for accessing above Cond Var */ uint_t ill_capab_pending_cnt; uint64_t ill_capabilities; /* Enabled capabilities, ILL_CAPAB_* */ ill_hcksum_capab_t *ill_hcksum_capab; /* H/W cksumming capabilities */ diff --git a/usr/src/uts/common/inet/ip/conn_opt.c b/usr/src/uts/common/inet/ip/conn_opt.c index b4bff4d7b4..8a05a25b08 100644 --- a/usr/src/uts/common/inet/ip/conn_opt.c +++ b/usr/src/uts/common/inet/ip/conn_opt.c @@ -1209,6 +1209,7 @@ conn_opt_set_ip(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen, return (EINVAL); } + ifindex = UINT_MAX; switch (name) { case IP_TTL: /* Don't allow zero */ @@ -1529,6 +1530,7 @@ conn_opt_set_ipv6(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen, if (connp->conn_family != AF_INET6) return (EINVAL); + ifindex = UINT_MAX; switch (name) { case IPV6_MULTICAST_IF: /* diff --git a/usr/src/uts/common/inet/ip/icmp.c b/usr/src/uts/common/inet/ip/icmp.c index b1a77ae0cc..46c791298a 100644 --- a/usr/src/uts/common/inet/ip/icmp.c +++ b/usr/src/uts/common/inet/ip/icmp.c @@ -739,6 +739,11 @@ rawip_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len, } ASSERT(sa != NULL && len != 0); + sin = NULL; + sin6 = NULL; + dstport = 0; + flowinfo = 0; + v4dst = INADDR_ANY; /* * Determine packet type based on type of address passed in @@ -3592,6 +3597,7 @@ icmp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp, } } else { /* Connected case */ + dstport = connp->conn_fport; v6dst = connp->conn_faddr_v6; flowinfo = connp->conn_flowinfo; } diff --git a/usr/src/uts/common/inet/ip/igmp.c b/usr/src/uts/common/inet/ip/igmp.c index 423bb2a816..de6a91877a 100644 --- a/usr/src/uts/common/inet/ip/igmp.c +++ b/usr/src/uts/common/inet/ip/igmp.c @@ -310,15 +310,15 @@ mld_start_timers(unsigned next, ip_stack_t *ipst) mblk_t * igmp_input(mblk_t *mp, ip_recv_attr_t *ira) { - igmpa_t *igmpa; + igmpa_t *igmpa; ipha_t *ipha = (ipha_t *)(mp->b_rptr); int iphlen, igmplen, mblklen; - ilm_t *ilm; + ilm_t *ilm; uint32_t src, dst; - uint32_t group; + uint32_t group; in6_addr_t v6group; uint_t next; - ipif_t *ipif; + ipif_t *ipif; ill_t *ill = ira->ira_ill; ip_stack_t *ipst = ill->ill_ipst; @@ -778,7 +778,7 @@ igmp_joingroup(ilm_t *ilm) ASSERT(RW_WRITE_HELD(&ill->ill_mcast_lock)); if (ilm->ilm_addr == htonl(INADDR_ALLHOSTS_GROUP)) { - ilm->ilm_rtx.rtx_timer = INFINITY; + ilm->ilm_rtx.rtx_timer = timer = INFINITY; ilm->ilm_state = IGMP_OTHERMEMBER; } else { ip1dbg(("Querier mode %d, sending report, group %x\n", @@ -857,11 +857,10 @@ mld_joingroup(ilm_t *ilm) ill = ilm->ilm_ill; ASSERT(ill->ill_isv6); - ASSERT(RW_WRITE_HELD(&ill->ill_mcast_lock)); if (IN6_ARE_ADDR_EQUAL(&ipv6_all_hosts_mcast, &ilm->ilm_v6addr)) { - ilm->ilm_rtx.rtx_timer = INFINITY; + ilm->ilm_rtx.rtx_timer = timer = INFINITY; ilm->ilm_state = IGMP_OTHERMEMBER; } else { if (ill->ill_mcast_type == MLD_V1_ROUTER) { @@ -1435,7 +1434,7 @@ igmp_timeout_handler(void *arg) uint_t mld_timeout_handler_per_ill(ill_t *ill) { - ilm_t *ilm; + ilm_t *ilm; uint_t next = INFINITY, current; mrec_t *rp, *rtxrp; rtx_state_t *rtxp; @@ -1832,7 +1831,7 @@ igmp_sendpkt(ilm_t *ilm, uchar_t type, ipaddr_t addr) ipha_t *ipha; int hdrlen = sizeof (ipha_t) + RTRALERT_LEN; size_t size = hdrlen + sizeof (igmpa_t); - ill_t *ill = ilm->ilm_ill; + ill_t *ill = ilm->ilm_ill; ip_stack_t *ipst = ill->ill_ipst; ASSERT(RW_LOCK_HELD(&ill->ill_mcast_lock)); @@ -1859,15 +1858,15 @@ igmp_sendpkt(ilm_t *ilm, uchar_t type, ipaddr_t addr) ipha->ipha_version_and_hdr_length = (IP_VERSION << 4) | (IP_SIMPLE_HDR_LENGTH_IN_WORDS + RTRALERT_LEN_IN_WORDS); - ipha->ipha_type_of_service = 0; + ipha->ipha_type_of_service = 0; ipha->ipha_length = htons(size); ipha->ipha_ident = 0; ipha->ipha_fragment_offset_and_flags = 0; - ipha->ipha_ttl = IGMP_TTL; - ipha->ipha_protocol = IPPROTO_IGMP; - ipha->ipha_hdr_checksum = 0; - ipha->ipha_dst = addr ? addr : igmpa->igmpa_group; - ipha->ipha_src = INADDR_ANY; + ipha->ipha_ttl = IGMP_TTL; + ipha->ipha_protocol = IPPROTO_IGMP; + ipha->ipha_hdr_checksum = 0; + ipha->ipha_dst = addr ? addr : igmpa->igmpa_group; + ipha->ipha_src = INADDR_ANY; ill_mcast_queue(ill, mp); @@ -2448,7 +2447,7 @@ mld_sendpkt(ilm_t *ilm, uchar_t type, const in6_addr_t *v6addr) { mblk_t *mp; mld_hdr_t *mldh; - ip6_t *ip6h; + ip6_t *ip6h; ip6_hbh_t *ip6hbh; struct ip6_opt_router *ip6router; size_t size = IPV6_HDR_LEN + sizeof (mld_hdr_t); diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c index 760454861b..925d06c62b 100644 --- a/usr/src/uts/common/inet/ip/ip.c +++ b/usr/src/uts/common/inet/ip/ip.c @@ -2404,6 +2404,7 @@ ipoptp_next(ipoptp_t *optp) * its there, and make sure it points to either something * inside this option, or the end of the option. */ + pointer = IPOPT_EOL; switch (opt) { case IPOPT_RR: case IPOPT_TS: @@ -4124,8 +4125,6 @@ ip_modclose(ill_t *ill) rw_destroy(&ill->ill_mcast_lock); mutex_destroy(&ill->ill_mcast_serializer); list_destroy(&ill->ill_nce); - cv_destroy(&ill->ill_dlpi_capab_cv); - mutex_destroy(&ill->ill_dlpi_capab_lock); /* * Now we are done with the module close pieces that @@ -6340,6 +6339,9 @@ ip_opt_set_multicast_group(conn_t *connp, t_scalar_t name, optfn = ip_opt_delete_group; break; default: + /* Should not be reached. */ + fmode = MODE_IS_INCLUDE; + optfn = NULL; ASSERT(0); } @@ -6469,6 +6471,9 @@ ip_opt_set_multicast_sources(conn_t *connp, t_scalar_t name, optfn = ip_opt_delete_group; break; default: + /* Should not be reached. */ + optfn = NULL; + fmode = 0; ASSERT(0); } @@ -8937,6 +8942,8 @@ ip_forward_options(mblk_t *mp, ipha_t *ipha, ill_t *dst_ill, ip2dbg(("ip_forward_options\n")); dst = ipha->ipha_dst; + opt = NULL; + for (optval = ipoptp_first(&opts, ipha); optval != IPOPT_EOL; optval = ipoptp_next(&opts)) { @@ -9023,6 +9030,7 @@ ip_forward_options(mblk_t *mp, ipha_t *ipha, ill_t *dst_ill, opt[IPOPT_OFFSET] += IP_ADDR_LEN; break; case IPOPT_TS: + off = 0; /* Insert timestamp if there is room */ switch (opt[IPOPT_POS_OV_FLG] & 0x0F) { case IPOPT_TS_TSONLY: @@ -9187,6 +9195,7 @@ ip_input_local_options(mblk_t *mp, ipha_t *ipha, ip_recv_attr_t *ira) ip_stack_t *ipst = ill->ill_ipst; ip2dbg(("ip_input_local_options\n")); + opt = NULL; for (optval = ipoptp_first(&opts, ipha); optval != IPOPT_EOL; @@ -9249,6 +9258,7 @@ ip_input_local_options(mblk_t *mp, ipha_t *ipha, ip_recv_attr_t *ira) opt[IPOPT_OFFSET] += IP_ADDR_LEN; break; case IPOPT_TS: + off = 0; /* Insert timestamp if there is romm */ switch (opt[IPOPT_POS_OV_FLG] & 0x0F) { case IPOPT_TS_TSONLY: @@ -9342,6 +9352,7 @@ ip_input_options(ipha_t *ipha, ipaddr_t dst, mblk_t *mp, ire_t *ire; ip2dbg(("ip_input_options\n")); + opt = NULL; *errorp = 0; for (optval = ipoptp_first(&opts, ipha); optval != IPOPT_EOL; @@ -11890,6 +11901,7 @@ ip_output_local_options(ipha_t *ipha, ip_stack_t *ipst) ipaddr_t dst; uint32_t ts; timestruc_t now; + uint32_t off = 0; for (optval = ipoptp_first(&opts, ipha); optval != IPOPT_EOL; @@ -11898,7 +11910,6 @@ ip_output_local_options(ipha_t *ipha, ip_stack_t *ipst) optlen = opts.ipoptp_len; ASSERT((opts.ipoptp_flags & IPOPTP_ERROR) == 0); switch (optval) { - uint32_t off; case IPOPT_SSRR: case IPOPT_LSRR: off = opt[IPOPT_OFFSET]; @@ -12546,6 +12557,7 @@ ip_process_ioctl(ipsq_t *ipsq, queue_t *q, mblk_t *mp, void *arg) } ci.ci_ipif = NULL; + extract_funcp = NULL; switch (ipip->ipi_cmd_type) { case MISC_CMD: case MSFILT_CMD: @@ -12727,6 +12739,7 @@ ip_wput_nondata(queue_t *q, mblk_t *mp) else connp = NULL; + iocp = NULL; switch (DB_TYPE(mp)) { case M_IOCTL: /* @@ -12937,6 +12950,7 @@ ip_output_options(mblk_t *mp, ipha_t *ipha, ip_xmit_attr_t *ixa, ill_t *ill) ip2dbg(("ip_output_options\n")); + opt = NULL; dst = ipha->ipha_dst; for (optval = ipoptp_first(&opts, ipha); optval != IPOPT_EOL; diff --git a/usr/src/uts/common/inet/ip/ip6.c b/usr/src/uts/common/inet/ip/ip6.c index afaf01024f..26e7be2fe8 100644 --- a/usr/src/uts/common/inet/ip/ip6.c +++ b/usr/src/uts/common/inet/ip/ip6.c @@ -2766,7 +2766,7 @@ ip_process_options_v6(mblk_t *mp, ip6_t *ip6h, uint8_t *optptr, uint_t optlen, uint8_t hdr_type, ip_recv_attr_t *ira) { uint8_t opt_type; - uint_t optused; + uint_t optused = 0; int ret = 0; const char *errtype; ill_t *ill = ira->ira_ill; diff --git a/usr/src/uts/common/inet/ip/ip6_ire.c b/usr/src/uts/common/inet/ip/ip6_ire.c index ad738bc3b7..1145025588 100644 --- a/usr/src/uts/common/inet/ip/ip6_ire.c +++ b/usr/src/uts/common/inet/ip/ip6_ire.c @@ -687,7 +687,7 @@ ire_match_args_v6(ire_t *ire, const in6_addr_t *addr, const in6_addr_t *mask, const in6_addr_t *gateway, int type, const ill_t *ill, zoneid_t zoneid, const ts_label_t *tsl, int match_flags) { - in6_addr_t gw_addr_v6; + in6_addr_t gw_addr_v6 = { 0 }; ill_t *ire_ill = NULL, *dst_ill; ip_stack_t *ipst = ire->ire_ipst; diff --git a/usr/src/uts/common/inet/ip/ip6_output.c b/usr/src/uts/common/inet/ip/ip6_output.c index dc074454e3..143077ed32 100644 --- a/usr/src/uts/common/inet/ip/ip6_output.c +++ b/usr/src/uts/common/inet/ip/ip6_output.c @@ -1023,7 +1023,7 @@ ire_send_wire_v6(ire_t *ire, mblk_t *mp, void *iph_arg, */ if (pktlen > ixa->ixa_fragsize || (ixaflags & (IXAF_IPSEC_SECURE|IXAF_IPV6_ADD_FRAGHDR))) { - uint32_t ident; + uint32_t ident = 0; if (ixaflags & IXAF_IPSEC_SECURE) pktlen += ipsec_out_extra_length(ixa); diff --git a/usr/src/uts/common/inet/ip/ip_ftable.c b/usr/src/uts/common/inet/ip/ip_ftable.c index 980436b578..408b9d0ea1 100644 --- a/usr/src/uts/common/inet/ip/ip_ftable.c +++ b/usr/src/uts/common/inet/ip/ip_ftable.c @@ -76,7 +76,7 @@ (((ire)->ire_type & IRE_DEFAULT) || \ (((ire)->ire_type & IRE_INTERFACE) && ((ire)->ire_addr == 0))) -#define IP_SRC_MULTIHOMING(isv6, ipst) \ +#define IP_SRC_MULTIHOMING(isv6, ipst) \ (isv6 ? ipst->ips_ipv6_strict_src_multihoming : \ ipst->ips_ip_strict_src_multihoming) @@ -470,7 +470,7 @@ ire_get_bucket(ire_t *ire) * routes to this destination, this routine will utilise the * first route it finds to IP address * Return values: - * 0 - FAILURE + * 0 - FAILURE * nonzero - ifindex */ uint_t @@ -807,7 +807,7 @@ ire_round_robin(irb_t *irb_ptr, ire_ftable_args_t *margs, uint_t hash, ire_t *orig_ire, ip_stack_t *ipst) { ire_t *ire, *maybe_ire = NULL; - uint_t maybe_badcnt; + uint_t maybe_badcnt = 0; uint_t maxwalk; /* Fold in more bits from the hint/hash */ diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c index 24e4c200d4..a2ddcb3547 100644 --- a/usr/src/uts/common/inet/ip/ip_if.c +++ b/usr/src/uts/common/inet/ip/ip_if.c @@ -1394,10 +1394,11 @@ ill_capability_wait(ill_t *ill) while (ill->ill_capab_pending_cnt != 0 && (ill->ill_state_flags & ILL_CONDEMNED) == 0) { - mutex_enter(&ill->ill_dlpi_capab_lock); + /* This may enable blocked callers of ill_capability_done(). */ ipsq_exit(ill->ill_phyint->phyint_ipsq); - cv_wait(&ill->ill_dlpi_capab_cv, &ill->ill_dlpi_capab_lock); - mutex_exit(&ill->ill_dlpi_capab_lock); + /* Pause a bit (1msec) before we re-enter the squeue. */ + delay(drv_usectohz(1000000)); + /* * If ipsq_enter() fails, someone set ILL_CONDEMNED * while we dropped the squeue. Indicate such to the caller. @@ -1508,9 +1509,9 @@ ill_capability_id_ack(ill_t *ill, mblk_t *mp, dl_capability_sub_t *outers) id_ic = (dl_capab_id_t *)(outers + 1); + inners = &id_ic->id_subcap; if (outers->dl_length < sizeof (*id_ic) || - (inners = &id_ic->id_subcap, - inners->dl_length > (outers->dl_length - sizeof (*inners)))) { + inners->dl_length > (outers->dl_length - sizeof (*inners))) { cmn_err(CE_WARN, "ill_capability_id_ack: malformed " "encapsulated capab type %d too long for mblk", inners->dl_cap); @@ -3513,9 +3514,6 @@ ill_init_common(ill_t *ill, queue_t *q, boolean_t isv6, boolean_t is_loopback, ill->ill_max_buf = ND_MAX_Q; ill->ill_refcnt = 0; - cv_init(&ill->ill_dlpi_capab_cv, NULL, CV_DEFAULT, NULL); - mutex_init(&ill->ill_dlpi_capab_lock, NULL, MUTEX_DEFAULT, NULL); - return (0); } @@ -4027,6 +4025,7 @@ ill_get_next_ifindex(uint_t index, boolean_t isv6, ip_stack_t *ipst) phyint_t *phyi_initial; uint_t ifindex; + phyi_initial = NULL; rw_enter(&ipst->ips_ill_g_lock, RW_READER); if (index == 0) { @@ -12935,6 +12934,7 @@ void ill_capability_done(ill_t *ill) { ASSERT(ill->ill_capab_pending_cnt != 0); + ASSERT(IAM_WRITER_ILL(ill)); ill_dlpi_done(ill, DL_CAPABILITY_REQ); @@ -12942,10 +12942,6 @@ ill_capability_done(ill_t *ill) if (ill->ill_capab_pending_cnt == 0 && ill->ill_dlpi_capab_state == IDCS_OK) ill_capability_reset_alloc(ill); - - mutex_enter(&ill->ill_dlpi_capab_lock); - cv_broadcast(&ill->ill_dlpi_capab_cv); - mutex_exit(&ill->ill_dlpi_capab_lock); } /* diff --git a/usr/src/uts/common/inet/ip/ip_ndp.c b/usr/src/uts/common/inet/ip/ip_ndp.c index 69506f77d4..2cee123d4a 100644 --- a/usr/src/uts/common/inet/ip/ip_ndp.c +++ b/usr/src/uts/common/inet/ip/ip_ndp.c @@ -2943,6 +2943,8 @@ nce_update(ncec_t *ncec, uint16_t new_state, uchar_t *new_ll_addr) ASSERT(ncec->ncec_lladdr != NULL || new_state == ND_INITIAL || new_state == ND_INCOMPLETE); } + + tid = 0; if (need_stop_timer || (ncec->ncec_flags & NCE_F_STATIC)) { tid = ncec->ncec_timeout_id; ncec->ncec_timeout_id = 0; @@ -4433,6 +4435,7 @@ nce_resolve_src(ncec_t *ncec, in6_addr_t *src) ASSERT(src != NULL); ASSERT(IN6_IS_ADDR_UNSPECIFIED(src)); + src4 = 0; src6 = *src; if (is_myaddr) { src6 = ncec->ncec_addr; @@ -4641,6 +4644,7 @@ nce_add_common(ill_t *ill, uchar_t *hw_addr, uint_t hw_addr_len, ndp = ill->ill_ipst->ips_ndp4; *retnce = NULL; + state = 0; ASSERT(MUTEX_HELD(&ndp->ndp_g_lock)); diff --git a/usr/src/uts/common/inet/ip/ip_output.c b/usr/src/uts/common/inet/ip/ip_output.c index 169859707e..a6ca2aabd5 100644 --- a/usr/src/uts/common/inet/ip/ip_output.c +++ b/usr/src/uts/common/inet/ip/ip_output.c @@ -1100,7 +1100,7 @@ ire_send_local_v4(ire_t *ire, mblk_t *mp, void *iph_arg, int, 1); if (HOOKS4_INTERESTED_LOOPBACK_OUT(ipst)) { - int error; + int error = 0; DTRACE_PROBE4(ip4__loopback__out__start, ill_t *, NULL, ill_t *, ill, ipha_t *, ipha, mblk_t *, mp); @@ -1156,7 +1156,7 @@ ire_send_local_v4(ire_t *ire, mblk_t *mp, void *iph_arg, } if (HOOKS4_INTERESTED_LOOPBACK_IN(ipst)) { - int error; + int error = 0; DTRACE_PROBE4(ip4__loopback__in__start, ill_t *, ill, ill_t *, NULL, ipha_t *, ipha, mblk_t *, mp); diff --git a/usr/src/uts/common/inet/ip/ip_rts.c b/usr/src/uts/common/inet/ip/ip_rts.c index dece7be29d..5df5ad6447 100644 --- a/usr/src/uts/common/inet/ip/ip_rts.c +++ b/usr/src/uts/common/inet/ip/ip_rts.c @@ -114,7 +114,7 @@ rts_queue_input(mblk_t *mp, conn_t *o_connp, sa_family_t af, uint_t flags, ip_stack_t *ipst) { mblk_t *mp1; - conn_t *connp, *next_connp; + conn_t *connp, *next_connp; /* * Since we don't have an ill_t here, RTSQ_DEFAULT must already be @@ -190,7 +190,7 @@ ip_rts_rtmsg(int type, ire_t *ire, int error, ip_stack_t *ipst) mblk_t *mp; rt_msghdr_t *rtm; int rtm_addrs = (RTA_DST | RTA_NETMASK | RTA_GATEWAY); - sa_family_t af; + sa_family_t af = { 0 }; in6_addr_t gw_addr_v6; if (ire == NULL) @@ -199,6 +199,7 @@ ip_rts_rtmsg(int type, ire_t *ire, int error, ip_stack_t *ipst) ire->ire_ipversion == IPV6_VERSION); ASSERT(!(ire->ire_type & IRE_IF_CLONE)); + mp = NULL; if (ire->ire_flags & RTF_SETSRC) rtm_addrs |= RTA_SRC; @@ -306,10 +307,14 @@ ip_rts_request_common(mblk_t *mp, conn_t *connp, cred_t *ioc_cr) ts_label_t *tsl = NULL; zoneid_t zoneid; ip_stack_t *ipst; - ill_t *ill = NULL; + ill_t *ill = NULL; zoneid = connp->conn_zoneid; ipst = connp->conn_netstack->netstack_ip; + net_mask = 0; + src_addr = 0; + dst_addr = 0; + gw_addr = 0; if (mp->b_cont != NULL && !pullupmsg(mp, -1)) { freemsg(mp); @@ -1239,6 +1244,9 @@ rts_rtmget(mblk_t *mp, ire_t *ire, ire_t *ifire, const in6_addr_t *setsrc, ipaddr_t v4setsrc; rtm = (rt_msghdr_t *)mp->b_rptr; + ifaddr = 0; + brdaddr = 0; + rtm_flags = 0; /* * Find the ill used to send packets. This will be NULL in case @@ -1406,7 +1414,7 @@ rts_setmetrics(ire_t *ire, uint_t which, rt_metrics_t *metrics) ill_t *ill; ifrt_t *ifrt; mblk_t *mp; - in6_addr_t gw_addr_v6; + in6_addr_t gw_addr_v6 = { 0 }; /* Need to add back some metrics to the IRE? */ /* @@ -1422,6 +1430,7 @@ rts_setmetrics(ire_t *ire, uint_t which, rt_metrics_t *metrics) * <net/route.h> says: rmx_rtt and rmx_rttvar are stored as * microseconds. */ + rtt = 0; if (which & RTV_RTT) rtt = metrics->rmx_rtt / 1000; if (which & RTV_RTTVAR) diff --git a/usr/src/uts/common/inet/ip/ipclassifier.c b/usr/src/uts/common/inet/ip/ipclassifier.c index 77d9d8df7e..4f3ec2d817 100644 --- a/usr/src/uts/common/inet/ip/ipclassifier.c +++ b/usr/src/uts/common/inet/ip/ipclassifier.c @@ -613,6 +613,7 @@ ipcl_conn_create(uint32_t type, int sleep, netstack_t *ns) break; default: + conn_cache = NULL; connp = NULL; ASSERT(0); } diff --git a/usr/src/uts/common/inet/ip/ipmp.c b/usr/src/uts/common/inet/ip/ipmp.c index 912b489c40..3106b6e2de 100644 --- a/usr/src/uts/common/inet/ip/ipmp.c +++ b/usr/src/uts/common/inet/ip/ipmp.c @@ -1909,6 +1909,7 @@ ipmp_phyint_join_grp(phyint_t *phyi, ipmp_grp_t *grp) ASSERT(IAM_WRITER_IPSQ(ipsq)); ASSERT(phyi->phyint_illv4 != NULL || phyi->phyint_illv6 != NULL); + ill = NULL; /* * Send routing socket messages indicating that the phyint's ills diff --git a/usr/src/uts/common/inet/ip/ipsecah.c b/usr/src/uts/common/inet/ip/ipsecah.c index fc19d7f877..ced3696948 100644 --- a/usr/src/uts/common/inet/ip/ipsecah.c +++ b/usr/src/uts/common/inet/ip/ipsecah.c @@ -215,7 +215,7 @@ static int ah_kstat_update(kstat_t *kp, int rw) { ah_kstats_t *ekp; - netstackid_t stackid = (netstackid_t)(uintptr_t)kp->ks_private; + netstackid_t stackid; netstack_t *ns; ipsec_stack_t *ipss; @@ -225,6 +225,7 @@ ah_kstat_update(kstat_t *kp, int rw) if (rw == KSTAT_WRITE) return (EACCES); + stackid = (netstackid_t)(uintptr_t)kp->ks_private; ns = netstack_find_by_stackid(stackid); if (ns == NULL) return (-1); diff --git a/usr/src/uts/common/inet/ip/ipsecesp.c b/usr/src/uts/common/inet/ip/ipsecesp.c index b3dc7d350a..e0efbbf3ce 100644 --- a/usr/src/uts/common/inet/ip/ipsecesp.c +++ b/usr/src/uts/common/inet/ip/ipsecesp.c @@ -208,7 +208,7 @@ static int esp_kstat_update(kstat_t *kp, int rw) { esp_kstats_t *ekp; - netstackid_t stackid = (zoneid_t)(uintptr_t)kp->ks_private; + netstackid_t stackid; netstack_t *ns; ipsec_stack_t *ipss; @@ -218,6 +218,7 @@ esp_kstat_update(kstat_t *kp, int rw) if (rw == KSTAT_WRITE) return (EACCES); + stackid = (zoneid_t)(uintptr_t)kp->ks_private; ns = netstack_find_by_stackid(stackid); if (ns == NULL) return (-1); diff --git a/usr/src/uts/common/inet/ip/sadb.c b/usr/src/uts/common/inet/ip/sadb.c index 44ebb21db3..288c0e3e18 100644 --- a/usr/src/uts/common/inet/ip/sadb.c +++ b/usr/src/uts/common/inet/ip/sadb.c @@ -113,8 +113,8 @@ extern uint64_t ipsacq_maxpackets; if (((sa)->ipsa_ ## exp) == 0) \ (sa)->ipsa_ ## exp = tmp; \ else \ - (sa)->ipsa_ ## exp = \ - MIN((sa)->ipsa_ ## exp, tmp); \ + (sa)->ipsa_ ## exp = \ + MIN((sa)->ipsa_ ## exp, tmp); \ } \ } @@ -154,8 +154,6 @@ sadb_sa_refrele(void *target) static time_t sadb_add_time(time_t base, uint64_t delta) { - time_t sum; - /* * Clip delta to the maximum possible time_t value to * prevent "overwrapping" back into a shorter-than-desired @@ -163,18 +161,12 @@ sadb_add_time(time_t base, uint64_t delta) */ if (delta > TIME_MAX) delta = TIME_MAX; - /* - * This sum may still overflow. - */ - sum = base + delta; - /* - * .. so if the result is less than the base, we overflowed. - */ - if (sum < base) - sum = TIME_MAX; - - return (sum); + if (base > 0) { + if (TIME_MAX - base < delta) + return (TIME_MAX); /* Overflow */ + } + return (base + delta); } /* @@ -1695,8 +1687,7 @@ sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg, mp->b_cont = mp1; break; default: - if (mp != NULL) - freemsg(mp); + freemsg(mp); return; } @@ -2941,7 +2932,7 @@ sadb_common_add(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg, boolean_t isupdate = (newbie != NULL); uint32_t *src_addr_ptr, *dst_addr_ptr, *isrc_addr_ptr, *idst_addr_ptr; ipsec_stack_t *ipss = ns->netstack_ipsec; - ip_stack_t *ipst = ns->netstack_ip; + ip_stack_t *ipst = ns->netstack_ip; ipsec_alginfo_t *alg; int rcode; boolean_t async = B_FALSE; @@ -4386,8 +4377,8 @@ sadb_update_lifetimes(ipsa_t *assoc, sadb_lifetime_t *hard, if (assoc->ipsa_idletime != 0) { assoc->ipsa_idletime = min(assoc->ipsa_idletime, assoc->ipsa_idleuselt); - assoc->ipsa_idleexpiretime = - current + assoc->ipsa_idletime; + assoc->ipsa_idleexpiretime = + current + assoc->ipsa_idletime; } else { assoc->ipsa_idleexpiretime = current + assoc->ipsa_idleuselt; @@ -5450,7 +5441,7 @@ sadb_acquire(mblk_t *datamp, ip_xmit_attr_t *ixa, boolean_t need_ah, uint32_t seq; uint64_t unique_id = 0; boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL) != 0; - ts_label_t *tsl; + ts_label_t *tsl; netstack_t *ns = ixa->ixa_ipst->ips_netstack; ipsec_stack_t *ipss = ns->netstack_ipsec; ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; @@ -6102,7 +6093,8 @@ sadb_label_from_sens(sadb_sens_t *sens, uint64_t *bitmap) return (NULL); bsllow(&sl); - LCLASS_SET((_bslabel_impl_t *)&sl, sens->sadb_sens_sens_level); + LCLASS_SET((_bslabel_impl_t *)&sl, + (uint16_t)sens->sadb_sens_sens_level); bcopy(bitmap, &((_bslabel_impl_t *)&sl)->compartments, bitmap_len); @@ -6629,7 +6621,7 @@ ipsec_find_listen_conn(uint16_t *pptr, ipsec_selector_t *sel, ip_stack_t *ipst) static void ipsec_tcp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst) { - connf_t *connfp; + connf_t *connfp; conn_t *connp; uint32_t ports; uint16_t *pptr = (uint16_t *)&ports; diff --git a/usr/src/uts/common/inet/ip/spd.c b/usr/src/uts/common/inet/ip/spd.c index d703170c9f..85f06f3d02 100644 --- a/usr/src/uts/common/inet/ip/spd.c +++ b/usr/src/uts/common/inet/ip/spd.c @@ -163,7 +163,7 @@ int ipsec_weird_null_inbound_policy = 0; * Inbound traffic should have matching identities for both SA's. */ -#define SA_IDS_MATCH(sa1, sa2) \ +#define SA_IDS_MATCH(sa1, sa2) \ (((sa1) == NULL) || ((sa2) == NULL) || \ (((sa1)->ipsa_src_cid == (sa2)->ipsa_src_cid) && \ (((sa1)->ipsa_dst_cid == (sa2)->ipsa_dst_cid)))) @@ -3178,6 +3178,7 @@ ipsec_act_find(const ipsec_act_t *a, int n, netstack_t *ns) * TODO: should canonicalize a[] (i.e., zeroize any padding) * so we can use a non-trivial policy_hash function. */ + ap = NULL; for (i = n-1; i >= 0; i--) { hval = policy_hash(IPSEC_ACTION_HASH_SIZE, &a[i], &a[n]); @@ -6282,6 +6283,9 @@ ipsec_fragcache_add(ipsec_fragcache_t *frag, mblk_t *iramp, mblk_t *mp, #ifdef FRAGCACHE_DEBUG cmn_err(CE_WARN, "Fragcache: %s\n", inbound ? "INBOUND" : "OUTBOUND"); #endif + v6_proto = 0; + fraghdr = NULL; + /* * You're on the slow path, so insure that every packet in the * cache is a single-mblk one. diff --git a/usr/src/uts/common/inet/ip/tnet.c b/usr/src/uts/common/inet/ip/tnet.c index e8c7b0c6e2..37a7402d52 100644 --- a/usr/src/uts/common/inet/ip/tnet.c +++ b/usr/src/uts/common/inet/ip/tnet.c @@ -692,7 +692,7 @@ tsol_get_pkt_label(mblk_t *mp, int version, ip_recv_attr_t *ira) const void *src; const ip6_t *ip6h; cred_t *credp; - int proto; + int proto; ASSERT(DB_TYPE(mp) == M_DATA); @@ -1477,6 +1477,9 @@ tsol_ip_forward(ire_t *ire, mblk_t *mp, const ip_recv_attr_t *ira) */ af = (ire->ire_ipversion == IPV4_VERSION) ? AF_INET : AF_INET6; + ipha = NULL; + ip6h = NULL; + gw_rhtp = NULL; if (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION) { ASSERT(ire->ire_ipversion == IPV4_VERSION); diff --git a/usr/src/uts/common/inet/sctp/sctp_asconf.c b/usr/src/uts/common/inet/sctp/sctp_asconf.c index f5edd1994f..db770df30e 100644 --- a/usr/src/uts/common/inet/sctp/sctp_asconf.c +++ b/usr/src/uts/common/inet/sctp/sctp_asconf.c @@ -47,7 +47,7 @@ typedef struct sctp_asconf_s { mblk_t *head; - uint32_t cid; + uint32_t cid; } sctp_asconf_t; /* @@ -636,6 +636,12 @@ sctp_input_asconf_ack(sctp_t *sctp, sctp_chunk_hdr_t *ch, sctp_faddr_t *fp) ASSERT(ch->sch_id == CHUNK_ASCONF_ACK); + ainfo = NULL; + alist = NULL; + dlist = NULL; + aptr = NULL; + dptr = NULL; + snp = (uint32_t *)(ch + 1); rlen = ntohs(ch->sch_len) - sizeof (*ch) - sizeof (*snp); if (rlen < 0) { @@ -915,9 +921,9 @@ sctp_wput_asconf(sctp_t *sctp, sctp_faddr_t *fp) { #define SCTP_SET_SENT_FLAG(mp) ((mp)->b_flag = SCTP_CHUNK_FLAG_SENT) - mblk_t *mp; + mblk_t *mp; mblk_t *ipmp; - uint32_t *snp; + uint32_t *snp; sctp_parm_hdr_t *ph; boolean_t isv4; sctp_stack_t *sctps = sctp->sctp_sctps; @@ -1467,6 +1473,7 @@ sctp_add_ip(sctp_t *sctp, const void *addrs, uint32_t cnt) * If deleting: * o Must be part of the association */ + sin6 = NULL; for (i = 0; i < cnt; i++) { switch (connp->conn_family) { case AF_INET: diff --git a/usr/src/uts/common/inet/sctp/sctp_common.c b/usr/src/uts/common/inet/sctp/sctp_common.c index ef60f6d26a..a640ead3d1 100644 --- a/usr/src/uts/common/inet/sctp/sctp_common.c +++ b/usr/src/uts/common/inet/sctp/sctp_common.c @@ -804,6 +804,8 @@ sctp_unlink_faddr(sctp_t *sctp, sctp_faddr_t *fp) { sctp_faddr_t *fpp; + fpp = NULL; + if (!sctp->sctp_faddrs) { return; } diff --git a/usr/src/uts/common/inet/sctp/sctp_cookie.c b/usr/src/uts/common/inet/sctp/sctp_cookie.c index 53c35183dc..da86faa252 100644 --- a/usr/src/uts/common/inet/sctp/sctp_cookie.c +++ b/usr/src/uts/common/inet/sctp/sctp_cookie.c @@ -427,10 +427,10 @@ sctp_initialize_params(sctp_t *sctp, sctp_init_chunk_t *init, /* * Copy the peer's original source address into addr. This relies on the * following format (see sctp_send_initack() below): - * relative timestamp for the cookie (int64_t) + - * cookie lifetime (uint32_t) + - * local tie-tag (uint32_t) + peer tie-tag (uint32_t) + - * Peer's original src ... + * relative timestamp for the cookie (int64_t) + + * cookie lifetime (uint32_t) + + * local tie-tag (uint32_t) + peer tie-tag (uint32_t) + + * Peer's original src ... */ int cl_sctp_cookie_paddr(sctp_chunk_hdr_t *ch, in6_addr_t *addr) @@ -454,7 +454,7 @@ cl_sctp_cookie_paddr(sctp_chunk_hdr_t *ch, in6_addr_t *addr) sizeof (int64_t) + /* timestamp */ \ sizeof (uint32_t) + /* cookie lifetime */ \ sizeof (sctp_init_chunk_t) + /* INIT ACK */ \ - sizeof (in6_addr_t) + /* peer's original source */ \ + sizeof (in6_addr_t) + /* peer's original source */ \ ntohs((initcp)->sch_len) + /* peer's INIT */ \ sizeof (uint32_t) + /* local tie-tag */ \ sizeof (uint32_t) + /* peer tie-tag */ \ @@ -946,6 +946,8 @@ sctp_send_cookie_echo(sctp_t *sctp, sctp_chunk_hdr_t *iackch, mblk_t *iackmp, uint16_t old_num_str; sctp_stack_t *sctps = sctp->sctp_sctps; + sdc = NULL; + seglen = 0; iack = (sctp_init_chunk_t *)(iackch + 1); cph = NULL; diff --git a/usr/src/uts/common/inet/sctp/sctp_input.c b/usr/src/uts/common/inet/sctp/sctp_input.c index 1b6449cfab..7d856fab28 100644 --- a/usr/src/uts/common/inet/sctp/sctp_input.c +++ b/usr/src/uts/common/inet/sctp/sctp_input.c @@ -831,7 +831,7 @@ sctp_try_partial_delivery(sctp_t *sctp, mblk_t *hmp, sctp_reass_t *srp, * there is a break in the sequence. We want * to chop the reassembly list as follows (the * numbers are TSNs): - * 10 -> 11 -> (end of chunks) + * 10 -> 11 -> (end of chunks) * 10 -> 11 -> | 13 (break in sequence) */ prev = mp; @@ -943,6 +943,7 @@ sctp_data_frag(sctp_t *sctp, mblk_t *dmp, sctp_data_hdr_t **dc, int *error, uint32_t tsn; uint16_t fraglen = 0; + reassq_curr = NULL; *error = 0; /* diff --git a/usr/src/uts/common/inet/sctp/sctp_opt_data.c b/usr/src/uts/common/inet/sctp/sctp_opt_data.c index 23abeccf96..476a6d921e 100644 --- a/usr/src/uts/common/inet/sctp/sctp_opt_data.c +++ b/usr/src/uts/common/inet/sctp/sctp_opt_data.c @@ -1057,7 +1057,10 @@ sctp_set_opt(sctp_t *sctp, int level, int name, const void *invalp, /* In all cases, the size of the option must be bigger than int */ if (inlen >= sizeof (int32_t)) { onoff = ONOFF(*i1); + } else { + return (EINVAL); } + retval = 0; RUN_SCTP(sctp); diff --git a/usr/src/uts/common/inet/sctp/sctp_output.c b/usr/src/uts/common/inet/sctp/sctp_output.c index eced6eccba..0564f5a416 100644 --- a/usr/src/uts/common/inet/sctp/sctp_output.c +++ b/usr/src/uts/common/inet/sctp/sctp_output.c @@ -990,8 +990,8 @@ sctp_output(sctp_t *sctp, uint_t num_pkt) mblk_t *head; mblk_t *meta = sctp->sctp_xmit_tail; mblk_t *fill = NULL; - uint16_t chunklen; - uint32_t cansend; + uint16_t chunklen; + uint32_t cansend; int32_t seglen; int32_t xtralen; int32_t sacklen; @@ -1007,6 +1007,8 @@ sctp_output(sctp_t *sctp, uint_t num_pkt) sctp_stack_t *sctps = sctp->sctp_sctps; uint32_t tsn; + lfp = NULL; + if (sctp->sctp_ftsn == sctp->sctp_lastacked + 1) { sacklen = 0; } else { @@ -1651,7 +1653,7 @@ sctp_check_adv_ack_pt(sctp_t *sctp, mblk_t *meta, mblk_t *mp) * - the chunk is unsent, i.e. new data. */ #define SCTP_CHUNK_RX_CANBUNDLE(mp, fp) \ - (!SCTP_CHUNK_ABANDONED((mp)) && \ + (!SCTP_CHUNK_ABANDONED((mp)) && \ ((SCTP_CHUNK_ISSENT((mp)) && (SCTP_CHUNK_DEST(mp) == (fp) && \ !SCTP_CHUNK_ISACKED(mp))) || \ (((mp)->b_flag & (SCTP_CHUNK_FLAG_REXMIT|SCTP_CHUNK_FLAG_SENT)) != \ @@ -1694,7 +1696,7 @@ sctp_rexmit(sctp_t *sctp, sctp_faddr_t *oldfp) * * if the advanced peer ack point includes the next * chunk to be retransmited - possibly the Forward - * TSN was lost. + * TSN was lost. * * if we are PRSCTP aware and the next chunk to be * retransmitted is now abandoned diff --git a/usr/src/uts/common/inet/tcp/tcp_bind.c b/usr/src/uts/common/inet/tcp/tcp_bind.c index ec2a5d4e29..876e7d48e6 100644 --- a/usr/src/uts/common/inet/tcp/tcp_bind.c +++ b/usr/src/uts/common/inet/tcp/tcp_bind.c @@ -324,7 +324,7 @@ tcp_bind_select_lport(tcp_t *tcp, in_port_t *requested_port_ptr, boolean_t bind_to_req_port_only, cred_t *cr) { in_port_t mlp_port; - mlp_type_t addrtype, mlptype; + mlp_type_t addrtype, mlptype; boolean_t user_specified; in_port_t allocated_port; in_port_t requested_port = *requested_port_ptr; @@ -333,6 +333,7 @@ tcp_bind_select_lport(tcp_t *tcp, in_port_t *requested_port_ptr, tcp_stack_t *tcps = tcp->tcp_tcps; in6_addr_t v6addr = connp->conn_laddr_v6; + zone = NULL; /* * XXX It's up to the caller to specify bind_to_req_port_only or not. */ @@ -697,7 +698,7 @@ tcp_bindi(tcp_t *tcp, in_port_t port, const in6_addr_t *laddr, if (connp->conn_anon_priv_bind) { /* * loopmax = - * (IPPORT_RESERVED-1) - tcp_min_anonpriv_port + 1 + * (IPPORT_RESERVED-1) - tcp_min_anonpriv_port + 1 */ loopmax = IPPORT_RESERVED - tcps->tcps_min_anonpriv_port; diff --git a/usr/src/uts/common/inet/tcp/tcp_fusion.c b/usr/src/uts/common/inet/tcp/tcp_fusion.c index e73c34de34..f2cb8f6dbd 100644 --- a/usr/src/uts/common/inet/tcp/tcp_fusion.c +++ b/usr/src/uts/common/inet/tcp/tcp_fusion.c @@ -160,7 +160,7 @@ tcp_fuse(tcp_t *tcp, uchar_t *iphdr, tcpha_t *tcpha) if (!tcp->tcp_unfusable && !peer_tcp->tcp_unfusable && tcp->tcp_xmit_head == NULL && peer_tcp->tcp_xmit_head == NULL) { - mblk_t *mp; + mblk_t *mp = NULL; queue_t *peer_rq = peer_connp->conn_rq; ASSERT(!TCP_IS_DETACHED(peer_tcp)); diff --git a/usr/src/uts/common/inet/tcp/tcp_input.c b/usr/src/uts/common/inet/tcp/tcp_input.c index ece2abbc04..0aaad871ba 100644 --- a/usr/src/uts/common/inet/tcp/tcp_input.c +++ b/usr/src/uts/common/inet/tcp/tcp_input.c @@ -2469,6 +2469,7 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira) tcp_unfuse(tcp); } + mss = 0; iphdr = mp->b_rptr; rptr = mp->b_rptr; ASSERT(OK_32PTR(rptr)); diff --git a/usr/src/uts/common/inet/tcp/tcp_misc.c b/usr/src/uts/common/inet/tcp/tcp_misc.c index 4f6399c433..0896dd7611 100644 --- a/usr/src/uts/common/inet/tcp/tcp_misc.c +++ b/usr/src/uts/common/inet/tcp/tcp_misc.c @@ -291,6 +291,7 @@ tcp_ioctl_abort_bucket(tcp_ioc_abort_conn_t *acp, int index, int *count, startover: nmatch = 0; + last = NULL; mutex_enter(&connfp->connf_lock); for (tconnp = connfp->connf_head; tconnp != NULL; diff --git a/usr/src/uts/common/inet/tcp/tcp_output.c b/usr/src/uts/common/inet/tcp/tcp_output.c index ae9efe863d..7a0472f3dd 100644 --- a/usr/src/uts/common/inet/tcp/tcp_output.c +++ b/usr/src/uts/common/inet/tcp/tcp_output.c @@ -1787,7 +1787,7 @@ tcp_send(tcp_t *tcp, const int mss, const int total_hdr_len, uint32_t *snxt, int *tail_unsent, mblk_t **xmit_tail, mblk_t *local_time) { int num_lso_seg = 1; - uint_t lso_usable; + uint_t lso_usable = 0; boolean_t do_lso_send = B_FALSE; tcp_stack_t *tcps = tcp->tcp_tcps; conn_t *connp = tcp->tcp_connp; diff --git a/usr/src/uts/common/inet/tcp/tcp_tpi.c b/usr/src/uts/common/inet/tcp/tcp_tpi.c index dbdc5b8dc7..6b32a0ad27 100644 --- a/usr/src/uts/common/inet/tcp/tcp_tpi.c +++ b/usr/src/uts/common/inet/tcp/tcp_tpi.c @@ -154,6 +154,10 @@ tcp_conprim_opt_process(tcp_t *tcp, mblk_t *mp, int *do_disconnectp, opt_offset = tcresp->OPT_offset; opt_lenp = (t_scalar_t *)&tcresp->OPT_length; break; + default: + opt_lenp = 0; + opt_offset = 0; + break; } *t_errorp = 0; diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c index 165adcb852..b2183405eb 100644 --- a/usr/src/uts/common/inet/udp/udp.c +++ b/usr/src/uts/common/inet/udp/udp.c @@ -4984,6 +4984,8 @@ udp_do_bind(conn_t *connp, struct sockaddr *sa, socklen_t len, cred_t *cr, mlp_type_t addrtype, mlptype; udp_stack_t *us = udp->udp_us; + sin = NULL; + sin6 = NULL; switch (len) { case sizeof (sin_t): /* Complete IPv4 address */ sin = (sin_t *)sa; @@ -5697,6 +5699,10 @@ udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len, udp = connp->conn_udp; us = udp->udp_us; + sin = NULL; + sin6 = NULL; + v4dst = INADDR_ANY; + flowinfo = 0; /* * Address has been verified by the caller diff --git a/usr/src/uts/common/inet/udp/udp_stats.c b/usr/src/uts/common/inet/udp/udp_stats.c index 2f5202f693..4ed1ab9773 100644 --- a/usr/src/uts/common/inet/udp/udp_stats.c +++ b/usr/src/uts/common/inet/udp/udp_stats.c @@ -93,7 +93,12 @@ udp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req) */ mp2ctl = copymsg(mpctl); - mp_conn_ctl = mp_attr_ctl = mp6_conn_ctl = NULL; + mp6_info_ctl = NULL; + mp6_attr_ctl = NULL; + mp6_conn_ctl = NULL; + mp_info_ctl = NULL; + mp_attr_ctl = NULL; + mp_conn_ctl = NULL; if (mpctl == NULL || (mpdata = mpctl->b_cont) == NULL || (mp_conn_ctl = copymsg(mpctl)) == NULL || diff --git a/usr/src/uts/common/io/aggr/aggr_grp.c b/usr/src/uts/common/io/aggr/aggr_grp.c index 9097e059b5..82f3989f42 100644 --- a/usr/src/uts/common/io/aggr/aggr_grp.c +++ b/usr/src/uts/common/io/aggr/aggr_grp.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* @@ -1442,8 +1442,7 @@ aggr_grp_create(datalink_id_t linkid, uint32_t key, uint_t nports, grp->lg_rx_group_count = 1; - for (i = 0, port = grp->lg_ports; port != NULL; - i++, port = port->lp_next) { + for (port = grp->lg_ports; port != NULL; port = port->lp_next) { uint_t num_rgroups; mac_perim_enter_by_mh(port->lp_mh, &mph); diff --git a/usr/src/uts/common/io/aggr/aggr_port.c b/usr/src/uts/common/io/aggr/aggr_port.c index c8dbe00336..e764dd104e 100644 --- a/usr/src/uts/common/io/aggr/aggr_port.c +++ b/usr/src/uts/common/io/aggr/aggr_port.c @@ -22,7 +22,7 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2012 OmniTI Computer Consulting, Inc All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* diff --git a/usr/src/uts/common/io/ixgbe/ixgbe_main.c b/usr/src/uts/common/io/ixgbe/ixgbe_main.c index d6200a93b4..b52483d3de 100644 --- a/usr/src/uts/common/io/ixgbe/ixgbe_main.c +++ b/usr/src/uts/common/io/ixgbe/ixgbe_main.c @@ -25,7 +25,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. * Copyright 2012 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013 Saso Kiselkov. All rights reserved. * Copyright (c) 2013 OSN Online Service Nuernberg GmbH. All rights reserved. @@ -6546,8 +6546,10 @@ ixgbe_remvlan(mac_group_driver_t gdriver, uint16_t vid) } vlp = ixgbe_find_vlan(rx_group, vid); - if (vlp == NULL) + if (vlp == NULL) { + mutex_exit(&ixgbe->gen_lock); return (ENOENT); + } /* * See the comment in ixgbe_addvlan() about is_def_grp and @@ -6601,8 +6603,10 @@ ixgbe_remvlan(mac_group_driver_t gdriver, uint16_t vid) /* This shouldn't fail, but if it does return EIO. */ ret = ixgbe_set_vfta(hw, vid, rx_group->index, B_TRUE, B_TRUE); - if (ret != IXGBE_SUCCESS) + if (ret != IXGBE_SUCCESS) { + mutex_exit(&ixgbe->gen_lock); return (EIO); + } } } diff --git a/usr/src/uts/common/io/ixgbe/ixgbe_sw.h b/usr/src/uts/common/io/ixgbe/ixgbe_sw.h index 0dbb3288c3..cfd987787a 100644 --- a/usr/src/uts/common/io/ixgbe/ixgbe_sw.h +++ b/usr/src/uts/common/io/ixgbe/ixgbe_sw.h @@ -92,6 +92,7 @@ extern "C" { #define MAX_NUM_UNICAST_ADDRESSES 0x80 #define MAX_NUM_MULTICAST_ADDRESSES 0x1000 #define MAX_NUM_VLAN_FILTERS 0x40 + #define IXGBE_INTR_NONE 0 #define IXGBE_INTR_MSIX 1 #define IXGBE_INTR_MSI 2 diff --git a/usr/src/uts/common/io/ldterm.c b/usr/src/uts/common/io/ldterm.c index 97a9c1a478..46669ace0c 100644 --- a/usr/src/uts/common/io/ldterm.c +++ b/usr/src/uts/common/io/ldterm.c @@ -22,7 +22,7 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright (c) 2018, Joyent, Inc. - * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -4087,7 +4087,8 @@ ldterm_dosig(queue_t *q, int sig, uchar_t c, int mtype, int mode) if (c != '\0') { if ((tp->t_echomp = allocb(4, BPRI_HI)) != NULL) { - if (ldterm_echo(c, WR(q), 4, tp) > 0) + if (ldterm_echo(c, WR(q), 4, tp) > 0 || + (tp->t_state & TS_ISPTSTTY)) putnext(WR(q), tp->t_echomp); else freemsg(tp->t_echomp); diff --git a/usr/src/uts/common/io/mac/mac.c b/usr/src/uts/common/io/mac/mac.c index f4074a2b91..d698862d81 100644 --- a/usr/src/uts/common/io/mac/mac.c +++ b/usr/src/uts/common/io/mac/mac.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. * Copyright 2015 Garrett D'Amore <garrett@damore.org> */ @@ -1648,7 +1648,8 @@ mac_hwrings_idx_get(mac_handle_t mh, uint_t idx, mac_group_handle_t *hwgh, if (rtype == MAC_RING_TYPE_RX) { grp = mip->mi_rx_groups; - } else if (rtype == MAC_RING_TYPE_TX) { + } else { + ASSERT(rtype == MAC_RING_TYPE_TX); grp = mip->mi_tx_groups; } @@ -5536,6 +5537,11 @@ mac_add_macaddr_vlan(mac_impl_t *mip, mac_group_t *group, uint8_t *addr, return (0); } + /* + * We failed to set promisc mode and we are about to free 'map'. + */ + map->ma_nusers = 0; + bail: if (hw_vlan) { int err2 = mac_group_remvlan(group, vid); @@ -5591,6 +5597,8 @@ mac_remove_macaddr_vlan(mac_address_t *map, uint16_t vid) if (map->ma_nusers > 0) return (0); + VERIFY3S(map->ma_nusers, ==, 0); + /* * The MAC address is no longer used by any MAC client, so * remove it from its associated group. Turn off promiscuous @@ -5615,7 +5623,16 @@ mac_remove_macaddr_vlan(mac_address_t *map, uint16_t vid) * If we fail to remove the MAC address HW * filter but then also fail to re-add the * VLAN HW filter then we are in a busted - * state and should just crash. + * state. We do our best by logging a warning + * and returning the original 'err' that got + * us here. At this point, traffic for this + * address + VLAN combination will be dropped + * until the user reboots the system. In the + * future, it would be nice to have a system + * that can compare the state of expected + * classification according to mac to the + * actual state of the provider, and report + * and fix any inconsistencies. */ if (MAC_GROUP_HW_VLAN(group)) { int err2; @@ -5629,6 +5646,7 @@ mac_remove_macaddr_vlan(mac_address_t *map, uint16_t vid) } } + map->ma_nusers = 1; return (err); } @@ -5642,8 +5660,10 @@ mac_remove_macaddr_vlan(mac_address_t *map, uint16_t vid) map->ma_type, __FILE__, __LINE__); } - if (err != 0) + if (err != 0) { + map->ma_nusers = 1; return (err); + } /* * We created MAC address for the primary one at registration, so we diff --git a/usr/src/uts/common/io/mac/mac_client.c b/usr/src/uts/common/io/mac/mac_client.c index e26a028243..dcfb4803d6 100644 --- a/usr/src/uts/common/io/mac/mac_client.c +++ b/usr/src/uts/common/io/mac/mac_client.c @@ -23,6 +23,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2019 Joyent, Inc. * Copyright 2017 RackTop Systems. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -1287,7 +1288,7 @@ mac_addr_random(mac_client_handle_t mch, uint_t prefix_len, prefix_len, addr_len - prefix_len); } - *diag = 0; + *diag = MAC_DIAG_NONE; return (0); } @@ -2551,6 +2552,8 @@ i_mac_unicast_add(mac_client_handle_t mch, uint8_t *mac_addr, uint16_t flags, */ ASSERT(!((mip->mi_state_flags & MIS_IS_VNIC) && (vid != VLAN_ID_NONE))); + *diag = MAC_DIAG_NONE; + /* * Can't unicast add if the client asked only for minimal datapath * setup. diff --git a/usr/src/uts/common/io/mac/mac_datapath_setup.c b/usr/src/uts/common/io/mac/mac_datapath_setup.c index 656c598e53..e1dbf9a953 100644 --- a/usr/src/uts/common/io/mac/mac_datapath_setup.c +++ b/usr/src/uts/common/io/mac/mac_datapath_setup.c @@ -2892,8 +2892,8 @@ mac_datapath_setup(mac_client_impl_t *mcip, flow_entry_t *flent, mac_group_t *default_rgroup; mac_group_t *default_tgroup; int err; - uint8_t *mac_addr; uint16_t vid; + uint8_t *mac_addr; mac_group_state_t next_state; mac_client_impl_t *group_only_mcip; mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip); diff --git a/usr/src/uts/common/io/mac/mac_provider.c b/usr/src/uts/common/io/mac/mac_provider.c index 2c4ac0a1af..0f917cd8ca 100644 --- a/usr/src/uts/common/io/mac/mac_provider.c +++ b/usr/src/uts/common/io/mac/mac_provider.c @@ -735,7 +735,7 @@ mac_rx_common(mac_handle_t mh, mac_resource_handle_t mrh, mblk_t *mp_chain) { mac_impl_t *mip = (mac_impl_t *)mh; mac_ring_t *mr = (mac_ring_t *)mrh; - mac_soft_ring_set_t *mac_srs; + mac_soft_ring_set_t *mac_srs; mblk_t *bp = mp_chain; /* diff --git a/usr/src/uts/common/io/mac/mac_stat.c b/usr/src/uts/common/io/mac/mac_stat.c index 2244218f20..e1151565a6 100644 --- a/usr/src/uts/common/io/mac/mac_stat.c +++ b/usr/src/uts/common/io/mac/mac_stat.c @@ -262,7 +262,7 @@ static stat_info_t rx_srs_stats_list[] = { {RX_SRS_STAT_OFF(mrs_chaincntover50)}, {RX_SRS_STAT_OFF(mrs_ierrors)} }; -#define RX_SRS_STAT_SIZE \ +#define RX_SRS_STAT_SIZE \ (sizeof (rx_srs_stats_list) / sizeof (stat_info_t)) #define TX_SOFTRING_STAT_OFF(f) (offsetof(mac_tx_stats_t, f)) @@ -274,14 +274,14 @@ static stat_info_t tx_softring_stats_list[] = { {TX_SOFTRING_STAT_OFF(mts_unblockcnt)}, {TX_SOFTRING_STAT_OFF(mts_sdrops)}, }; -#define TX_SOFTRING_STAT_SIZE \ +#define TX_SOFTRING_STAT_SIZE \ (sizeof (tx_softring_stats_list) / sizeof (stat_info_t)) static void i_mac_add_stats(void *sum, void *op1, void *op2, stat_info_t stats_list[], uint_t size) { - int i; + int i; for (i = 0; i < size; i++) { uint64_t *op1_val = (uint64_t *) @@ -679,8 +679,8 @@ i_mac_rx_hwlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname, static uint64_t i_mac_misc_stat_get(void *handle, uint_t stat) { - flow_entry_t *flent = handle; - mac_client_impl_t *mcip = flent->fe_mcip; + flow_entry_t *flent = handle; + mac_client_impl_t *mcip = flent->fe_mcip; mac_misc_stats_t *mac_misc_stat = &mcip->mci_misc_stat; mac_rx_stats_t *mac_rx_stat; mac_tx_stats_t *mac_tx_stat; @@ -871,9 +871,9 @@ i_mac_tx_hwlane_stat_create(mac_soft_ring_t *ringp, const char *modname, static uint64_t i_mac_rx_fanout_stat_get(void *handle, uint_t stat) { - mac_soft_ring_t *tcp_ringp = (mac_soft_ring_t *)handle; + mac_soft_ring_t *tcp_ringp = (mac_soft_ring_t *)handle; mac_soft_ring_t *udp_ringp = NULL, *oth_ringp = NULL; - mac_soft_ring_set_t *mac_srs = tcp_ringp->s_ring_set; + mac_soft_ring_set_t *mac_srs = tcp_ringp->s_ring_set; int index; uint64_t val; @@ -1037,7 +1037,7 @@ void mac_srs_stat_create(mac_soft_ring_set_t *mac_srs) { flow_entry_t *flent = mac_srs->srs_flent; - char statname[MAXNAMELEN]; + char statname[MAXNAMELEN]; boolean_t is_tx_srs; /* No hardware/software lanes for user defined flows */ diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.c b/usr/src/uts/common/io/mlxcx/mlxcx.c new file mode 100644 index 0000000000..12a8d52b3f --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx.c @@ -0,0 +1,2765 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020, The University of Queensland + * Copyright (c) 2018, Joyent, Inc. + */ + +/* + * Mellanox Connect-X 4/5/6 driver. + */ + +/* + * The PRM for this family of parts is freely available, and can be found at: + * https://www.mellanox.com/related-docs/user_manuals/ \ + * Ethernet_Adapters_Programming_Manual.pdf + */ +/* + * ConnectX glossary + * ----------------- + * + * WR Work Request: something we've asked the hardware to do by + * creating a Work Queue Entry (WQE), e.g. send or recv a packet + * + * WQE Work Queue Entry: a descriptor on a work queue descriptor ring + * + * WQ Work Queue: a descriptor ring that we can place WQEs on, usually + * either a Send Queue (SQ) or Receive Queue (RQ). Different WQ + * types have different WQE structures, different commands for + * creating and destroying them, etc, but share a common context + * structure, counter setup and state graph. + * SQ Send Queue, a specific type of WQ that sends packets + * RQ Receive Queue, a specific type of WQ that receives packets + * + * CQ Completion Queue: completion of WRs from a WQ are reported to + * one of these, as a CQE on its entry ring. + * CQE Completion Queue Entry: an entry in a CQ ring. Contains error + * info, as well as packet size, the ID of the WQ, and the index + * of the WQE which completed. Does not contain any packet data. + * + * EQ Event Queue: a ring of event structs from the hardware informing + * us when particular events happen. Many events can point at a + * a particular CQ which we should then go look at. + * EQE Event Queue Entry: an entry on the EQ ring + * + * UAR User Access Region, a page of the device's PCI BAR which is + * tied to particular EQ/CQ/WQ sets and contains doorbells to + * ring to arm them for interrupts or wake them up for new work + * + * RQT RQ Table, a collection of indexed RQs used to refer to the group + * as a single unit (for e.g. hashing/RSS). + * + * TIR Transport Interface Recieve, a bucket of resources for the + * reception of packets. TIRs have to point at either a single RQ + * or a table of RQs (RQT). They then serve as a target for flow + * table entries (FEs). TIRs that point at an RQT also contain the + * settings for hashing for RSS. + * + * TIS Transport Interface Send, a bucket of resources associated with + * the transmission of packets. In particular, the temporary + * resources used for LSO internally in the card are accounted to + * a TIS. + * + * FT Flow Table, a collection of FEs and FGs that can be referred to + * as a single entity (e.g. used as a target from another flow + * entry or set as the "root" table to handle incoming or outgoing + * packets). Packets arriving at a FT are matched against the + * FEs in the table until either one matches with a terminating + * action or all FEs are exhausted (it's first-match-wins but with + * some actions that are non-terminal, like counting actions). + * + * FG Flow Group, a group of FEs which share a common "mask" (i.e. + * they match on the same attributes of packets coming into the + * flow). + * + * FE Flow Entry, an individual set of values to match against + * packets entering the flow table, combined with an action to + * take upon a successful match. The action we use most is + * "forward", which sends the packets to a TIR or another flow + * table and then stops further processing within the FE's FT. + * + * lkey/mkey A reference to something similar to a page table but in the + * device's internal onboard MMU. Since Connect-X parts double as + * IB cards (lots of RDMA) they have extensive onboard memory mgmt + * features which we try very hard not to use. For our WQEs we use + * the "reserved" lkey, which is a special value which indicates + * that addresses we give are linear addresses and should not be + * translated. + * + * PD Protection Domain, an IB concept. We have to allocate one to + * provide as a parameter for new WQs, but we don't do anything + * with it. + * + * TDOM/TD Transport Domain, an IB concept. We allocate one in order to + * provide it as a parameter to TIR/TIS creation, but we don't do + * anything with it. + */ +/* + * + * Data flow overview + * ------------------ + * + * This driver is a MAC ring-enabled driver which maps rings to send and recv + * queues in hardware on the device. + * + * Each SQ and RQ is set up to report to its own individual CQ, to ensure + * sufficient space, and simplify the logic needed to work out which buffer + * was completed. + * + * The CQs are then round-robin allocated onto EQs, of which we set up one per + * interrupt that the system gives us for the device. Normally this means we + * have 8 EQs. + * + * When we have >= 8 EQs available, we try to allocate only RX or only TX + * CQs on each one. The EQs are chosen for RX and TX in an alternating fashion. + * + * EQ #0 is reserved for all event types other than completion events, and has + * no CQs associated with it at any time. EQs #1 and upwards are only used for + * handling CQ completion events. + * + * +------+ +------+ +------+ +---------+ + * | SQ 0 |---->| CQ 0 |-----+ | EQ 0 |------> | MSI-X 0 | mlxcx_intr_0 + * +------+ +------+ | +------+ +---------+ + * | + * +------+ +------+ | + * | SQ 1 |---->| CQ 1 |---+ | +------+ + * +------+ +------+ | +---> | | + * | | | + * +------+ +------+ | | EQ 1 | +---------+ + * | SQ 2 |---->| CQ 2 |---------> | |------> | MSI-X 1 | mlxcx_intr_n + * +------+ +------+ | +---> | | +---------+ + * | | +------+ + * | | + * ... | | + * | | +------+ + * +------+ +------+ +-----> | | + * | RQ 0 |---->| CQ 3 |---------> | | +---------+ + * +------+ +------+ | | EQ 2 |------> | MSI-X 2 | mlxcx_intr_n + * | | | +---------+ + * +------+ +------+ | +-> | | + * | RQ 1 |---->| CQ 4 |-----+ | +------+ + * +------+ +------+ | + * | .... + * +------+ +------+ | + * | RQ 2 |---->| CQ 5 |-------+ + * +------+ +------+ + * + * ... (note this diagram does not show RX-only or TX-only EQs) + * + * For TX, we advertise all of the SQs we create as plain rings to MAC with + * no TX groups. This puts MAC in "virtual group" mode where it will allocate + * and use the rings as it sees fit. + * + * For RX, we advertise actual groups in order to make use of hardware + * classification. + * + * The hardware classification we use is based around Flow Tables, and we + * currently ignore all of the eswitch features of the card. The NIC VPORT + * is always set to promisc mode so that the eswitch sends us all of the + * traffic that arrives on the NIC, and we use flow entries to manage + * everything. + * + * We use 2 layers of flow tables for classification: traffic arrives at the + * root RX flow table which contains MAC address filters. Those then send + * matched traffic to the per-group L1 VLAN filter tables which contain VLAN + * presence and VID filters. + * + * Since these parts only support doing RSS hashing on a single protocol at a + * time, we have to use a third layer of flow tables as well to break traffic + * down by L4 and L3 protocol (TCPv6, TCPv4, UDPv6, UDPv4, IPv6, IPv4 etc) + * so that it can be sent to the appropriate TIR for hashing. + * + * Incoming packets + * + +---------+ +---------+ + * | +->| group 0 | | group 0 | + * | | | vlan ft | +-->| hash ft | + * v | | L1 | | | L2 | + * +----+----+ | +---------+ | +---------+ +-----+ +-----+------+ + * | eswitch | | | | | | TCPv6 |--->| TIR |--->| | RQ0 | + * +----+----+ | | | | +---------+ +-----+ | +------+ + * | | | | | | UDPv6 |--->| TIR |--->| | RQ1 | + * | | | | | +---------+ +-----+ | +------+ + * | | | | | | TCPv4 |--->| TIR |--->| | RQ2 | + * v | | | | +---------+ +-----+ | RQT +------+ + * +----+----+ | +---------+ | | UDPv4 |--->| TIR |--->| | ... | + * | root rx | | | default |--+ +---------+ +-----+ | | | + * | flow tb | | +---------+ | | IPv6 |--->| TIR |--->| | | + * | L0 | | | promisc |--+ +---------+ +-----+ | | | + * +---------+ | +---------+ ^ | IPv4 |--->| TIR |--->| | | + * | bcast |---|---------------+ +---------+ +-----+ +-----+------+ + * +---------+ | ^ | other |-+ + * | MAC 0 |---+ | +---------+ | +-----+ +-----+ + * +---------+ | +->| TIR |--->| RQ0 | + * | MAC 1 |-+ | +-----+ +-----+ + * +---------+ | +---------------+ + * | MAC 2 |-+ | ^ + * +---------+ | | | + * | MAC 3 |-+ | +---------+ | +---------+ + * +---------+ | | | group 1 | | | group 1 | + * | ..... | +--->| vlan ft | | +>| hash ft | + * | | | | L1 | | | | L2 | + * +---------+ | +---------+ | | +---------+ +-----+ +-----+------+ + * | promisc |---+ | VLAN 0 |----+ | TCPv6 |--->| TIR |--->| | RQ3 | + * +---------+ +---------+ | +---------+ +-----+ | +------+ + * | ..... | | | UDPv6 |--->| TIR |--->| | RQ4 | + * | | | +---------+ +-----+ | +------+ + * | | | | TCPv4 |--->| TIR |--->| | RQ5 | + * | | | +---------+ +-----+ | RQT +------+ + * +---------+ | | UDPv4 |--->| TIR |--->| | ... | + * | | | +---------+ +-----+ | | | + * +---------+ | | IPv6 |--->| TIR |--->| | | + * | promisc |--+ +---------+ +-----+ | | | + * +---------+ | IPv4 |--->| TIR |--->| | | + * +---------+ +-----+ +-----+------+ + * | other |-+ + * +---------+ | + * ....... | +-----+ +-----+ + * +->| TIR |--->| RQ3 | + * +-----+ +-----+ + * + * Note that the "promisc" flow entries are only set/enabled when promisc + * mode is enabled for the NIC. All promisc flow entries point directly at + * group 0's hashing flowtable (so all promisc-only traffic lands on group 0, + * the "default group" in MAC). + * + * The "default" entry in the L1 VLAN filter flow tables is used when there + * are no VLANs set for the group, to accept any traffic regardless of tag. It + * is deleted as soon as a VLAN filter is added (and re-instated if the + * last VLAN filter is removed). + * + * The actual descriptor ring structures for RX on Connect-X4 don't contain any + * space for packet data (they're a collection of scatter pointers only). TX + * descriptors contain some space for "inline headers" (and the card requires + * us to put at least the L2 Ethernet headers there for the eswitch to look at) + * but all the rest of the data comes from the gather pointers. + * + * When we get completions back they simply contain the ring index number of + * the WR (work request) which completed. So, we manage the buffers for actual + * packet data completely independently of the descriptors in this driver. When + * a WR is enqueued in a WQE (work queue entry), we stamp the packet data buffer + * with the WQE index that we put it at, and therefore don't have to look at + * the original descriptor at all when handling completions. + * + * For RX, we create sufficient packet data buffers to fill 150% of the + * available descriptors for each ring. These all are pre-set-up for DMA and + * have an mblk_t associated with them (with desballoc()). + * + * For TX we either borrow the mblk's memory and DMA bind it (if the packet is + * large enough), or we copy it into a pre-allocated buffer set up in the same + * as as for RX. + */ + +/* + * Buffer lifecycle: RX + * -------------------- + * + * The lifecycle of an mlxcx_buffer_t (packet buffer) used for RX is pretty + * straightforward. + * + * It is created (and has all its memory allocated) at the time of starting up + * the RX ring it belongs to. Then it is placed on the "free" list in the + * mlxcx_buffer_shard_t associated with its RQ. When mlxcx_rq_refill() wants + * more buffers to add to the RQ, it takes one off and marks it as "on WQ" + * before making a WQE for it. + * + * After a completion event occurs, the packet is either discarded (and the + * buffer_t returned to the free list), or it is readied for loaning to MAC. + * + * Once MAC and the rest of the system have finished with the packet, they call + * freemsg() on its mblk, which will call mlxcx_buf_mp_return and return the + * buffer_t to the free list. + * + * At detach/teardown time, buffers are only every destroyed from the free list. + * + * + * + + * | + * | mlxcx_buf_create + * | + * v + * +----+----+ + * | created | + * +----+----+ + * | + * | + * | mlxcx_buf_return + * | + * v + * mlxcx_buf_destroy +----+----+ + * +---------| free |<---------------+ + * | +----+----+ | + * | | | + * | | | mlxcx_buf_return + * v | mlxcx_buf_take | + * +---+--+ v | + * | dead | +---+---+ | + * +------+ | on WQ |- - - - - - - - >O + * +---+---+ ^ + * | | + * | | + * | mlxcx_buf_loan | mlxcx_buf_mp_return + * v | + * +-------+--------+ | + * | on loan to MAC |----------->O + * +----------------+ freemsg() + * + */ + +/* + * Buffer lifecycle: TX + * -------------------- + * + * mlxcx_buffer_ts used for TX are divided into two kinds: regular buffers, and + * "foreign" buffers. + * + * The former have their memory allocated and DMA bound by this driver, while + * the latter (the "foreign" buffers) are on loan from MAC. Their memory is + * not owned by us, though we do DMA bind it (and take responsibility for + * un-binding it when we're done with them). + * + * We use separate mlxcx_buf_shard_ts for foreign and local buffers on each + * SQ. Thus, there is a separate free list and mutex for each kind. + * + * Since a TX packet might consist of multiple mblks, we translate each mblk + * into exactly one buffer_t. The buffer_ts are chained together in the same + * order as the mblks, using the mlb_tx_chain/mlb_tx_chain_entry list_t. + * + * Each chain of TX buffers may consist of foreign or driver buffers, in any + * mixture. + * + * The head of a TX buffer chain has mlb_tx_head == itself, which distinguishes + * it from the rest of the chain buffers. + * + * TX buffer chains are always returned to the free list by + * mlxcx_buf_return_chain(), which takes care of walking the mlb_tx_chain and + * freeing all of the members. + * + * We only call freemsg() once, on the head of the TX buffer chain's original + * mblk. This is true whether we copied it or bound it in a foreign buffer. + */ + +/* + * Startup and command interface + * ----------------------------- + * + * The command interface is the primary way in which we give control orders to + * the hardware (e.g. actions like "create this queue" or "delete this flow + * entry"). The command interface is never used to transmit or receive packets + * -- that takes place only on the queues that are set up through it. + * + * In mlxcx_cmd.c we implement our use of the command interface on top of a + * simple taskq. Since it's not performance critical, we busy-wait on command + * completions and only process a single command at a time. + * + * If this becomes a problem later we can wire command completions up to EQ 0 + * once we have interrupts running. + * + * The startup/attach process for this card involves a bunch of different steps + * which are summarised pretty well in the PRM. We have to send a number of + * commands which do different things to start the card up, give it some pages + * of our own memory for it to use, then start creating all the entities that + * we need to use like EQs, CQs, WQs, as well as their dependencies like PDs + * and TDoms. + */ + +/* + * UARs + * ---- + * + * The pages of the PCI BAR other than the first few are reserved for use as + * "UAR" sections in this device. Each UAR section can be used as a set of + * doorbells for our queues. + * + * Currently we just make one single UAR for all of our queues. It doesn't + * seem to be a major limitation yet. + * + * When we're sending packets through an SQ, the PRM is not awful clear about + * exactly how we're meant to use the first 16 bytes of the Blueflame buffers + * (it's clear on the pattern of alternation you're expected to use between + * even and odd for Blueflame sends, but not for regular doorbells). + * + * Currently we don't do the even-odd alternating pattern for ordinary + * doorbells, and we don't use Blueflame at all. This seems to work fine, at + * least on Connect-X4 Lx. + */ + +/* + * Lock ordering + * ------------- + * + * Interrupt side: + * + * - mleq_mtx + * - mlcq_mtx + * - mlcq_bufbmtx + * - mlwq_mtx + * - mlbs_mtx + * - mlp_mtx + * + * GLD side: + * + * - mlp_mtx + * - mlg_mtx + * - mlg_*.mlft_mtx + * - mlp_*.mlft_mtx + * - mlwq_mtx + * - mlbs_mtx + * - mlcq_bufbmtx + * - mleq_mtx + * - mlcq_mtx + * + */ + +#include <sys/modctl.h> +#include <sys/conf.h> +#include <sys/devops.h> +#include <sys/sysmacros.h> +#include <sys/time.h> + +#include <sys/mac_provider.h> + +#include <mlxcx.h> + +CTASSERT((1 << MLXCX_RX_HASH_FT_SIZE_SHIFT) >= MLXCX_TIRS_PER_GROUP); + +#define MLXCX_MODULE_NAME "mlxcx" +/* + * We give this to the firmware, so it has to be in a fixed format that it + * understands. + */ +#define MLXCX_DRIVER_VERSION "illumos,mlxcx,1.0.0,1,000,000000" + +/* + * Firmware may take a while to reclaim pages. Try a set number of times. + */ +clock_t mlxcx_reclaim_delay = 1000 * 50; /* 50 ms in us */ +uint_t mlxcx_reclaim_tries = 100; /* Wait at most 5000ms */ + +static void *mlxcx_softstate; + +/* + * Fault detection thresholds. + */ +uint_t mlxcx_doorbell_tries = MLXCX_DOORBELL_TRIES_DFLT; +uint_t mlxcx_stuck_intr_count = MLXCX_STUCK_INTR_COUNT_DFLT; + +static void +mlxcx_load_props(mlxcx_t *mlxp) +{ + mlxcx_drv_props_t *p = &mlxp->mlx_props; + + p->mldp_eq_size_shift = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "eq_size_shift", + MLXCX_EQ_SIZE_SHIFT_DFLT); + p->mldp_cq_size_shift = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "cq_size_shift", + MLXCX_CQ_SIZE_SHIFT_DFLT); + p->mldp_sq_size_shift = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "sq_size_shift", + MLXCX_SQ_SIZE_SHIFT_DFLT); + p->mldp_rq_size_shift = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "rq_size_shift", + MLXCX_RQ_SIZE_SHIFT_DFLT); + + p->mldp_cqemod_period_usec = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "cqemod_period_usec", + MLXCX_CQEMOD_PERIOD_USEC_DFLT); + p->mldp_cqemod_count = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "cqemod_count", + MLXCX_CQEMOD_COUNT_DFLT); + p->mldp_intrmod_period_usec = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "intrmod_period_usec", + MLXCX_INTRMOD_PERIOD_USEC_DFLT); + + p->mldp_tx_ngroups = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "tx_ngroups", + MLXCX_TX_NGROUPS_DFLT); + p->mldp_tx_nrings_per_group = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "tx_nrings_per_group", + MLXCX_TX_NRINGS_PER_GROUP_DFLT); + + p->mldp_rx_ngroups_large = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "rx_ngroups_large", + MLXCX_RX_NGROUPS_LARGE_DFLT); + p->mldp_rx_ngroups_small = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "rx_ngroups_small", + MLXCX_RX_NGROUPS_SMALL_DFLT); + p->mldp_rx_nrings_per_large_group = ddi_getprop(DDI_DEV_T_ANY, + mlxp->mlx_dip, DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, + "rx_nrings_per_large_group", MLXCX_RX_NRINGS_PER_LARGE_GROUP_DFLT); + p->mldp_rx_nrings_per_small_group = ddi_getprop(DDI_DEV_T_ANY, + mlxp->mlx_dip, DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, + "rx_nrings_per_small_group", MLXCX_RX_NRINGS_PER_SMALL_GROUP_DFLT); + + p->mldp_ftbl_root_size_shift = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "ftbl_root_size_shift", + MLXCX_FTBL_ROOT_SIZE_SHIFT_DFLT); + + p->mldp_tx_bind_threshold = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "tx_bind_threshold", + MLXCX_TX_BIND_THRESHOLD_DFLT); + + p->mldp_ftbl_vlan_size_shift = ddi_getprop(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "ftbl_vlan_size_shift", + MLXCX_FTBL_VLAN_SIZE_SHIFT_DFLT); + + p->mldp_eq_check_interval_sec = ddi_getprop(DDI_DEV_T_ANY, + mlxp->mlx_dip, DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, + "eq_check_interval_sec", MLXCX_EQ_CHECK_INTERVAL_SEC_DFLT); + p->mldp_cq_check_interval_sec = ddi_getprop(DDI_DEV_T_ANY, + mlxp->mlx_dip, DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, + "cq_check_interval_sec", MLXCX_CQ_CHECK_INTERVAL_SEC_DFLT); + p->mldp_wq_check_interval_sec = ddi_getprop(DDI_DEV_T_ANY, + mlxp->mlx_dip, DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, + "wq_check_interval_sec", MLXCX_WQ_CHECK_INTERVAL_SEC_DFLT); +} + +void +mlxcx_note(mlxcx_t *mlxp, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (mlxp != NULL && mlxp->mlx_dip != NULL) { + vdev_err(mlxp->mlx_dip, CE_NOTE, fmt, ap); + } else { + vcmn_err(CE_NOTE, fmt, ap); + } + va_end(ap); +} + +void +mlxcx_warn(mlxcx_t *mlxp, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (mlxp != NULL && mlxp->mlx_dip != NULL) { + vdev_err(mlxp->mlx_dip, CE_WARN, fmt, ap); + } else { + vcmn_err(CE_WARN, fmt, ap); + } + va_end(ap); +} + +void +mlxcx_panic(mlxcx_t *mlxp, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (mlxp != NULL && mlxp->mlx_dip != NULL) { + vdev_err(mlxp->mlx_dip, CE_PANIC, fmt, ap); + } else { + vcmn_err(CE_PANIC, fmt, ap); + } + va_end(ap); +} + +uint16_t +mlxcx_get16(mlxcx_t *mlxp, uintptr_t off) +{ + uintptr_t addr = off + (uintptr_t)mlxp->mlx_regs_base; + return (ddi_get16(mlxp->mlx_regs_handle, (void *)addr)); +} + +uint32_t +mlxcx_get32(mlxcx_t *mlxp, uintptr_t off) +{ + uintptr_t addr = off + (uintptr_t)mlxp->mlx_regs_base; + return (ddi_get32(mlxp->mlx_regs_handle, (void *)addr)); +} + +uint64_t +mlxcx_get64(mlxcx_t *mlxp, uintptr_t off) +{ + uintptr_t addr = off + (uintptr_t)mlxp->mlx_regs_base; + return (ddi_get64(mlxp->mlx_regs_handle, (void *)addr)); +} + +void +mlxcx_put32(mlxcx_t *mlxp, uintptr_t off, uint32_t val) +{ + uintptr_t addr = off + (uintptr_t)mlxp->mlx_regs_base; + ddi_put32(mlxp->mlx_regs_handle, (void *)addr, val); +} + +void +mlxcx_put64(mlxcx_t *mlxp, uintptr_t off, uint64_t val) +{ + uintptr_t addr = off + (uintptr_t)mlxp->mlx_regs_base; + ddi_put64(mlxp->mlx_regs_handle, (void *)addr, val); +} + +void +mlxcx_uar_put32(mlxcx_t *mlxp, mlxcx_uar_t *mlu, uintptr_t off, uint32_t val) +{ + /* + * The UAR is always inside the first BAR, which we mapped as + * mlx_regs + */ + uintptr_t addr = off + (uintptr_t)mlu->mlu_base + + (uintptr_t)mlxp->mlx_regs_base; + ddi_put32(mlxp->mlx_regs_handle, (void *)addr, val); +} + +void +mlxcx_uar_put64(mlxcx_t *mlxp, mlxcx_uar_t *mlu, uintptr_t off, uint64_t val) +{ + uintptr_t addr = off + (uintptr_t)mlu->mlu_base + + (uintptr_t)mlxp->mlx_regs_base; + ddi_put64(mlxp->mlx_regs_handle, (void *)addr, val); +} + +static void +mlxcx_fm_fini(mlxcx_t *mlxp) +{ + if (mlxp->mlx_fm_caps == 0) + return; + + if (DDI_FM_ERRCB_CAP(mlxp->mlx_fm_caps)) + ddi_fm_handler_unregister(mlxp->mlx_dip); + + if (DDI_FM_EREPORT_CAP(mlxp->mlx_fm_caps) || + DDI_FM_ERRCB_CAP(mlxp->mlx_fm_caps)) + pci_ereport_teardown(mlxp->mlx_dip); + + ddi_fm_fini(mlxp->mlx_dip); + + mlxp->mlx_fm_caps = 0; +} + +void +mlxcx_fm_ereport(mlxcx_t *mlxp, const char *detail) +{ + uint64_t ena; + char buf[FM_MAX_CLASS]; + + if (!DDI_FM_EREPORT_CAP(mlxp->mlx_fm_caps)) + return; + + (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); + ena = fm_ena_generate(0, FM_ENA_FMT1); + ddi_fm_ereport_post(mlxp->mlx_dip, buf, ena, DDI_NOSLEEP, + FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, + NULL); +} + +static int +mlxcx_fm_errcb(dev_info_t *dip, ddi_fm_error_t *err, const void *arg) +{ + /* + * as the driver can always deal with an error in any dma or + * access handle, we can just return the fme_status value. + */ + pci_ereport_post(dip, err, NULL); + return (err->fme_status); +} + +static void +mlxcx_fm_init(mlxcx_t *mlxp) +{ + ddi_iblock_cookie_t iblk; + int def = DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | + DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE; + + mlxp->mlx_fm_caps = ddi_prop_get_int(DDI_DEV_T_ANY, mlxp->mlx_dip, + DDI_PROP_DONTPASS, "fm_capable", def); + + if (mlxp->mlx_fm_caps < 0) { + mlxp->mlx_fm_caps = 0; + } + mlxp->mlx_fm_caps &= def; + + if (mlxp->mlx_fm_caps == 0) + return; + + ddi_fm_init(mlxp->mlx_dip, &mlxp->mlx_fm_caps, &iblk); + if (DDI_FM_EREPORT_CAP(mlxp->mlx_fm_caps) || + DDI_FM_ERRCB_CAP(mlxp->mlx_fm_caps)) { + pci_ereport_setup(mlxp->mlx_dip); + } + if (DDI_FM_ERRCB_CAP(mlxp->mlx_fm_caps)) { + ddi_fm_handler_register(mlxp->mlx_dip, mlxcx_fm_errcb, + (void *)mlxp); + } +} + +static void +mlxcx_mlbs_teardown(mlxcx_t *mlxp, mlxcx_buf_shard_t *s) +{ + mlxcx_buffer_t *buf; + + mutex_enter(&s->mlbs_mtx); + while (!list_is_empty(&s->mlbs_busy)) + cv_wait(&s->mlbs_free_nonempty, &s->mlbs_mtx); + while ((buf = list_head(&s->mlbs_free)) != NULL) { + mlxcx_buf_destroy(mlxp, buf); + } + list_destroy(&s->mlbs_free); + list_destroy(&s->mlbs_busy); + mutex_exit(&s->mlbs_mtx); + + cv_destroy(&s->mlbs_free_nonempty); + mutex_destroy(&s->mlbs_mtx); +} + +static void +mlxcx_teardown_bufs(mlxcx_t *mlxp) +{ + mlxcx_buf_shard_t *s; + + while ((s = list_remove_head(&mlxp->mlx_buf_shards)) != NULL) { + mlxcx_mlbs_teardown(mlxp, s); + kmem_free(s, sizeof (mlxcx_buf_shard_t)); + } + list_destroy(&mlxp->mlx_buf_shards); + + kmem_cache_destroy(mlxp->mlx_bufs_cache); +} + +static void +mlxcx_teardown_pages(mlxcx_t *mlxp) +{ + uint_t nzeros = 0; + + mutex_enter(&mlxp->mlx_pagemtx); + + while (mlxp->mlx_npages > 0) { + int32_t req, ret; + uint64_t pas[MLXCX_MANAGE_PAGES_MAX_PAGES]; + + ASSERT0(avl_is_empty(&mlxp->mlx_pages)); + req = MIN(mlxp->mlx_npages, MLXCX_MANAGE_PAGES_MAX_PAGES); + + if (!mlxcx_cmd_return_pages(mlxp, req, pas, &ret)) { + mlxcx_warn(mlxp, "hardware refused to return pages, " + "leaking %u remaining pages", mlxp->mlx_npages); + goto out; + } + + for (int32_t i = 0; i < ret; i++) { + mlxcx_dev_page_t *mdp, probe; + bzero(&probe, sizeof (probe)); + probe.mxdp_pa = pas[i]; + + mdp = avl_find(&mlxp->mlx_pages, &probe, NULL); + + if (mdp != NULL) { + avl_remove(&mlxp->mlx_pages, mdp); + mlxp->mlx_npages--; + mlxcx_dma_free(&mdp->mxdp_dma); + kmem_free(mdp, sizeof (mlxcx_dev_page_t)); + } else { + mlxcx_panic(mlxp, "hardware returned a page " + "with PA 0x%" PRIx64 " but we have no " + "record of giving out such a page", pas[i]); + } + } + + /* + * If no pages were returned, note that fact. + */ + if (ret == 0) { + nzeros++; + if (nzeros > mlxcx_reclaim_tries) { + mlxcx_warn(mlxp, "hardware refused to return " + "pages, leaking %u remaining pages", + mlxp->mlx_npages); + goto out; + } + delay(drv_usectohz(mlxcx_reclaim_delay)); + } + } + + avl_destroy(&mlxp->mlx_pages); + +out: + mutex_exit(&mlxp->mlx_pagemtx); + mutex_destroy(&mlxp->mlx_pagemtx); +} + +static boolean_t +mlxcx_eq_alloc_dma(mlxcx_t *mlxp, mlxcx_event_queue_t *mleq) +{ + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + boolean_t ret; + size_t sz, i; + + VERIFY0(mleq->mleq_state & MLXCX_EQ_ALLOC); + + mleq->mleq_entshift = mlxp->mlx_props.mldp_eq_size_shift; + mleq->mleq_nents = (1 << mleq->mleq_entshift); + sz = mleq->mleq_nents * sizeof (mlxcx_eventq_ent_t); + ASSERT3U(sz & (MLXCX_HW_PAGE_SIZE - 1), ==, 0); + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_queue_attr(mlxp, &attr); + + ret = mlxcx_dma_alloc(mlxp, &mleq->mleq_dma, &attr, &acc, + B_TRUE, sz, B_TRUE); + if (!ret) { + mlxcx_warn(mlxp, "failed to allocate EQ memory"); + return (B_FALSE); + } + + mleq->mleq_ent = (mlxcx_eventq_ent_t *)mleq->mleq_dma.mxdb_va; + + for (i = 0; i < mleq->mleq_nents; ++i) + mleq->mleq_ent[i].mleqe_owner = MLXCX_EQ_OWNER_INIT; + + mleq->mleq_state |= MLXCX_EQ_ALLOC; + + return (B_TRUE); +} + +static void +mlxcx_eq_rele_dma(mlxcx_t *mlxp, mlxcx_event_queue_t *mleq) +{ + VERIFY(mleq->mleq_state & MLXCX_EQ_ALLOC); + if (mleq->mleq_state & MLXCX_EQ_CREATED) + VERIFY(mleq->mleq_state & MLXCX_EQ_DESTROYED); + + mlxcx_dma_free(&mleq->mleq_dma); + mleq->mleq_ent = NULL; + + mleq->mleq_state &= ~MLXCX_EQ_ALLOC; +} + +void +mlxcx_teardown_flow_table(mlxcx_t *mlxp, mlxcx_flow_table_t *ft) +{ + mlxcx_flow_group_t *fg; + mlxcx_flow_entry_t *fe; + int i; + + ASSERT(mutex_owned(&ft->mlft_mtx)); + + for (i = ft->mlft_nents - 1; i >= 0; --i) { + fe = &ft->mlft_ent[i]; + if (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + if (!mlxcx_cmd_delete_flow_table_entry(mlxp, fe)) { + mlxcx_panic(mlxp, "failed to delete flow " + "entry %u on table %u", i, + ft->mlft_num); + } + } + } + + while ((fg = list_remove_head(&ft->mlft_groups)) != NULL) { + if (fg->mlfg_state & MLXCX_FLOW_GROUP_CREATED && + !(fg->mlfg_state & MLXCX_FLOW_GROUP_DESTROYED)) { + if (!mlxcx_cmd_destroy_flow_group(mlxp, fg)) { + mlxcx_panic(mlxp, "failed to destroy flow " + "group %u", fg->mlfg_num); + } + } + kmem_free(fg, sizeof (mlxcx_flow_group_t)); + } + list_destroy(&ft->mlft_groups); + if (ft->mlft_state & MLXCX_FLOW_TABLE_CREATED && + !(ft->mlft_state & MLXCX_FLOW_TABLE_DESTROYED)) { + if (!mlxcx_cmd_destroy_flow_table(mlxp, ft)) { + mlxcx_panic(mlxp, "failed to destroy flow table %u", + ft->mlft_num); + } + } + kmem_free(ft->mlft_ent, ft->mlft_entsize); + ft->mlft_ent = NULL; + mutex_exit(&ft->mlft_mtx); + mutex_destroy(&ft->mlft_mtx); + kmem_free(ft, sizeof (mlxcx_flow_table_t)); +} + +static void +mlxcx_teardown_ports(mlxcx_t *mlxp) +{ + uint_t i; + mlxcx_port_t *p; + mlxcx_flow_table_t *ft; + + for (i = 0; i < mlxp->mlx_nports; ++i) { + p = &mlxp->mlx_ports[i]; + if (!(p->mlp_init & MLXCX_PORT_INIT)) + continue; + mutex_enter(&p->mlp_mtx); + if ((ft = p->mlp_rx_flow) != NULL) { + mutex_enter(&ft->mlft_mtx); + /* + * teardown_flow_table() will destroy the mutex, so + * we don't release it here. + */ + mlxcx_teardown_flow_table(mlxp, ft); + } + mutex_exit(&p->mlp_mtx); + mutex_destroy(&p->mlp_mtx); + p->mlp_init &= ~MLXCX_PORT_INIT; + } + + kmem_free(mlxp->mlx_ports, mlxp->mlx_ports_size); + mlxp->mlx_ports = NULL; +} + +static void +mlxcx_teardown_wqs(mlxcx_t *mlxp) +{ + mlxcx_work_queue_t *mlwq; + + while ((mlwq = list_head(&mlxp->mlx_wqs)) != NULL) { + mlxcx_wq_teardown(mlxp, mlwq); + } + list_destroy(&mlxp->mlx_wqs); +} + +static void +mlxcx_teardown_cqs(mlxcx_t *mlxp) +{ + mlxcx_completion_queue_t *mlcq; + + while ((mlcq = list_head(&mlxp->mlx_cqs)) != NULL) { + mlxcx_cq_teardown(mlxp, mlcq); + } + list_destroy(&mlxp->mlx_cqs); +} + +static void +mlxcx_teardown_eqs(mlxcx_t *mlxp) +{ + mlxcx_event_queue_t *mleq; + uint_t i; + + for (i = 0; i < mlxp->mlx_intr_count; ++i) { + mleq = &mlxp->mlx_eqs[i]; + mutex_enter(&mleq->mleq_mtx); + if ((mleq->mleq_state & MLXCX_EQ_CREATED) && + !(mleq->mleq_state & MLXCX_EQ_DESTROYED)) { + if (!mlxcx_cmd_destroy_eq(mlxp, mleq)) { + mlxcx_warn(mlxp, "failed to destroy " + "event queue idx %u eqn %u", + i, mleq->mleq_num); + } + } + if (mleq->mleq_state & MLXCX_EQ_ALLOC) { + mlxcx_eq_rele_dma(mlxp, mleq); + } + mutex_exit(&mleq->mleq_mtx); + } +} + +static void +mlxcx_teardown_checktimers(mlxcx_t *mlxp) +{ + if (mlxp->mlx_props.mldp_eq_check_interval_sec > 0) + ddi_periodic_delete(mlxp->mlx_eq_checktimer); + if (mlxp->mlx_props.mldp_cq_check_interval_sec > 0) + ddi_periodic_delete(mlxp->mlx_cq_checktimer); + if (mlxp->mlx_props.mldp_wq_check_interval_sec > 0) + ddi_periodic_delete(mlxp->mlx_wq_checktimer); +} + +static void +mlxcx_teardown(mlxcx_t *mlxp) +{ + uint_t i; + dev_info_t *dip = mlxp->mlx_dip; + + if (mlxp->mlx_attach & MLXCX_ATTACH_GROUPS) { + mlxcx_teardown_groups(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_GROUPS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_CHKTIMERS) { + mlxcx_teardown_checktimers(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_CHKTIMERS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_WQS) { + mlxcx_teardown_wqs(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_WQS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_CQS) { + mlxcx_teardown_cqs(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_CQS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_BUFS) { + mlxcx_teardown_bufs(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_BUFS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_PORTS) { + mlxcx_teardown_ports(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_PORTS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_INTRS) { + mlxcx_teardown_eqs(mlxp); + mlxcx_intr_teardown(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_INTRS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_UAR_PD_TD) { + if (mlxp->mlx_uar.mlu_allocated) { + if (!mlxcx_cmd_dealloc_uar(mlxp, &mlxp->mlx_uar)) { + mlxcx_warn(mlxp, "failed to release UAR"); + } + for (i = 0; i < MLXCX_BF_PER_UAR; ++i) + mutex_destroy(&mlxp->mlx_uar.mlu_bf[i].mbf_mtx); + } + if (mlxp->mlx_pd.mlpd_allocated && + !mlxcx_cmd_dealloc_pd(mlxp, &mlxp->mlx_pd)) { + mlxcx_warn(mlxp, "failed to release PD"); + } + if (mlxp->mlx_tdom.mltd_allocated && + !mlxcx_cmd_dealloc_tdom(mlxp, &mlxp->mlx_tdom)) { + mlxcx_warn(mlxp, "failed to release TDOM"); + } + mlxp->mlx_attach &= ~MLXCX_ATTACH_UAR_PD_TD; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_INIT_HCA) { + if (!mlxcx_cmd_teardown_hca(mlxp)) { + mlxcx_warn(mlxp, "failed to send teardown HCA " + "command during device detach"); + } + mlxp->mlx_attach &= ~MLXCX_ATTACH_INIT_HCA; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_PAGE_LIST) { + mlxcx_teardown_pages(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_PAGE_LIST; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_ENABLE_HCA) { + if (!mlxcx_cmd_disable_hca(mlxp)) { + mlxcx_warn(mlxp, "failed to send DISABLE HCA command " + "during device detach"); + } + mlxp->mlx_attach &= ~MLXCX_ATTACH_ENABLE_HCA; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_CMD) { + mlxcx_cmd_queue_fini(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_CMD; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_CAPS) { + kmem_free(mlxp->mlx_caps, sizeof (mlxcx_caps_t)); + mlxp->mlx_caps = NULL; + mlxp->mlx_attach &= ~MLXCX_ATTACH_CAPS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_REGS) { + ddi_regs_map_free(&mlxp->mlx_regs_handle); + mlxp->mlx_regs_handle = NULL; + mlxp->mlx_attach &= ~MLXCX_ATTACH_REGS; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_PCI_CONFIG) { + pci_config_teardown(&mlxp->mlx_cfg_handle); + mlxp->mlx_cfg_handle = NULL; + mlxp->mlx_attach &= ~MLXCX_ATTACH_PCI_CONFIG; + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_FM) { + mlxcx_fm_fini(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_FM; + } + + VERIFY3S(mlxp->mlx_attach, ==, 0); + ddi_soft_state_free(mlxcx_softstate, mlxp->mlx_inst); + ddi_set_driver_private(dip, NULL); +} + +static boolean_t +mlxcx_regs_map(mlxcx_t *mlxp) +{ + off_t memsize; + int ret; + ddi_device_acc_attr_t da; + + if (ddi_dev_regsize(mlxp->mlx_dip, MLXCX_REG_NUMBER, &memsize) != + DDI_SUCCESS) { + mlxcx_warn(mlxp, "failed to get register set size"); + return (B_FALSE); + } + + /* + * All data in the main BAR is kept in big-endian even though it's a PCI + * device. + */ + bzero(&da, sizeof (ddi_device_acc_attr_t)); + da.devacc_attr_version = DDI_DEVICE_ATTR_V0; + da.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC; + da.devacc_attr_dataorder = DDI_STRICTORDER_ACC; + if (DDI_FM_ACC_ERR_CAP(mlxp->mlx_fm_caps)) { + da.devacc_attr_access = DDI_FLAGERR_ACC; + } else { + da.devacc_attr_access = DDI_DEFAULT_ACC; + } + + ret = ddi_regs_map_setup(mlxp->mlx_dip, MLXCX_REG_NUMBER, + &mlxp->mlx_regs_base, 0, memsize, &da, &mlxp->mlx_regs_handle); + + if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "failed to map device registers: %d", ret); + return (B_FALSE); + } + + return (B_TRUE); +} + +static boolean_t +mlxcx_check_issi(mlxcx_t *mlxp) +{ + uint32_t issi; + + if (!mlxcx_cmd_query_issi(mlxp, &issi)) { + mlxcx_warn(mlxp, "failed to get ISSI"); + return (B_FALSE); + } + + if ((issi & (1 << MLXCX_CURRENT_ISSI)) == 0) { + mlxcx_warn(mlxp, "hardware does not support software ISSI, " + "hw vector 0x%x, sw version %u", issi, MLXCX_CURRENT_ISSI); + return (B_FALSE); + } + + if (!mlxcx_cmd_set_issi(mlxp, MLXCX_CURRENT_ISSI)) { + mlxcx_warn(mlxp, "failed to set ISSI to %u", + MLXCX_CURRENT_ISSI); + return (B_FALSE); + } + + return (B_TRUE); +} + +boolean_t +mlxcx_give_pages(mlxcx_t *mlxp, int32_t npages) +{ + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + int32_t i; + list_t plist; + mlxcx_dev_page_t *mdp; + const ddi_dma_cookie_t *ck; + + /* + * If there are no pages required, then we're done here. + */ + if (npages <= 0) { + return (B_TRUE); + } + + list_create(&plist, sizeof (mlxcx_dev_page_t), + offsetof(mlxcx_dev_page_t, mxdp_list)); + + for (i = 0; i < npages; i++) { + mdp = kmem_zalloc(sizeof (mlxcx_dev_page_t), KM_SLEEP); + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_page_attr(mlxp, &attr); + if (!mlxcx_dma_alloc(mlxp, &mdp->mxdp_dma, &attr, &acc, + B_TRUE, MLXCX_HW_PAGE_SIZE, B_TRUE)) { + mlxcx_warn(mlxp, "failed to allocate 4k page %u/%u", i, + npages); + kmem_free(mdp, sizeof (mlxcx_dev_page_t)); + goto cleanup_npages; + } + ck = mlxcx_dma_cookie_one(&mdp->mxdp_dma); + mdp->mxdp_pa = ck->dmac_laddress; + + list_insert_tail(&plist, mdp); + } + + /* + * Now that all of the pages have been allocated, given them to hardware + * in chunks. + */ + while (npages > 0) { + mlxcx_dev_page_t *pages[MLXCX_MANAGE_PAGES_MAX_PAGES]; + int32_t togive = MIN(MLXCX_MANAGE_PAGES_MAX_PAGES, npages); + + for (i = 0; i < togive; i++) { + pages[i] = list_remove_head(&plist); + } + + if (!mlxcx_cmd_give_pages(mlxp, + MLXCX_MANAGE_PAGES_OPMOD_GIVE_PAGES, togive, pages)) { + mlxcx_warn(mlxp, "!hardware refused our gift of %u " + "pages!", togive); + for (i = 0; i < togive; i++) { + list_insert_tail(&plist, pages[i]); + } + goto cleanup_npages; + } + + mutex_enter(&mlxp->mlx_pagemtx); + for (i = 0; i < togive; i++) { + avl_add(&mlxp->mlx_pages, pages[i]); + } + mlxp->mlx_npages += togive; + mutex_exit(&mlxp->mlx_pagemtx); + npages -= togive; + } + + list_destroy(&plist); + + return (B_TRUE); + +cleanup_npages: + while ((mdp = list_remove_head(&plist)) != NULL) { + mlxcx_dma_free(&mdp->mxdp_dma); + kmem_free(mdp, sizeof (mlxcx_dev_page_t)); + } + list_destroy(&plist); + return (B_FALSE); +} + +static boolean_t +mlxcx_init_pages(mlxcx_t *mlxp, uint_t type) +{ + int32_t npages; + + if (!mlxcx_cmd_query_pages(mlxp, type, &npages)) { + mlxcx_warn(mlxp, "failed to determine boot pages"); + return (B_FALSE); + } + + return (mlxcx_give_pages(mlxp, npages)); +} + +static int +mlxcx_bufs_cache_constr(void *arg, void *cookie, int kmflags) +{ + mlxcx_t *mlxp = cookie; + mlxcx_buffer_t *b = arg; + + bzero(b, sizeof (mlxcx_buffer_t)); + b->mlb_mlx = mlxp; + b->mlb_state = MLXCX_BUFFER_INIT; + list_create(&b->mlb_tx_chain, sizeof (mlxcx_buffer_t), + offsetof(mlxcx_buffer_t, mlb_tx_chain_entry)); + + return (0); +} + +static void +mlxcx_bufs_cache_destr(void *arg, void *cookie) +{ + mlxcx_t *mlxp = cookie; + mlxcx_buffer_t *b = arg; + VERIFY3P(b->mlb_mlx, ==, mlxp); + VERIFY(b->mlb_state == MLXCX_BUFFER_INIT); + list_destroy(&b->mlb_tx_chain); +} + +mlxcx_buf_shard_t * +mlxcx_mlbs_create(mlxcx_t *mlxp) +{ + mlxcx_buf_shard_t *s; + + s = kmem_zalloc(sizeof (mlxcx_buf_shard_t), KM_SLEEP); + + mutex_init(&s->mlbs_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + list_create(&s->mlbs_busy, sizeof (mlxcx_buffer_t), + offsetof(mlxcx_buffer_t, mlb_entry)); + list_create(&s->mlbs_free, sizeof (mlxcx_buffer_t), + offsetof(mlxcx_buffer_t, mlb_entry)); + cv_init(&s->mlbs_free_nonempty, NULL, CV_DRIVER, NULL); + + list_insert_tail(&mlxp->mlx_buf_shards, s); + + return (s); +} + +static boolean_t +mlxcx_setup_bufs(mlxcx_t *mlxp) +{ + char namebuf[KSTAT_STRLEN]; + + (void) snprintf(namebuf, KSTAT_STRLEN, "mlxcx%d_bufs_cache", + ddi_get_instance(mlxp->mlx_dip)); + mlxp->mlx_bufs_cache = kmem_cache_create(namebuf, + sizeof (mlxcx_buffer_t), sizeof (uint64_t), + mlxcx_bufs_cache_constr, mlxcx_bufs_cache_destr, + NULL, mlxp, NULL, 0); + + list_create(&mlxp->mlx_buf_shards, sizeof (mlxcx_buf_shard_t), + offsetof(mlxcx_buf_shard_t, mlbs_entry)); + + return (B_TRUE); +} + +static void +mlxcx_fm_qstate_ereport(mlxcx_t *mlxp, const char *qtype, uint32_t qnum, + const char *state, uint8_t statenum) +{ + uint64_t ena; + char buf[FM_MAX_CLASS]; + + if (!DDI_FM_EREPORT_CAP(mlxp->mlx_fm_caps)) + return; + + (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", + MLXCX_FM_SERVICE_MLXCX, "qstate.err"); + ena = fm_ena_generate(0, FM_ENA_FMT1); + + ddi_fm_ereport_post(mlxp->mlx_dip, buf, ena, DDI_NOSLEEP, + FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, + "state", DATA_TYPE_STRING, state, + "state_num", DATA_TYPE_UINT8, statenum, + "qtype", DATA_TYPE_STRING, qtype, + "qnum", DATA_TYPE_UINT32, qnum, + NULL); + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_DEGRADED); +} + +static void +mlxcx_eq_check(void *arg) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_event_queue_t *eq; + mlxcx_eventq_ctx_t ctx; + const char *str; + + uint_t i; + + for (i = 0; i < mlxp->mlx_intr_count; ++i) { + eq = &mlxp->mlx_eqs[i]; + if (!(eq->mleq_state & MLXCX_EQ_CREATED) || + (eq->mleq_state & MLXCX_EQ_DESTROYED)) + continue; + mutex_enter(&eq->mleq_mtx); + if (!mlxcx_cmd_query_eq(mlxp, eq, &ctx)) { + mutex_exit(&eq->mleq_mtx); + continue; + } + + str = "???"; + switch (ctx.mleqc_status) { + case MLXCX_EQ_STATUS_OK: + break; + case MLXCX_EQ_STATUS_WRITE_FAILURE: + str = "WRITE_FAILURE"; + break; + } + if (ctx.mleqc_status != MLXCX_EQ_STATUS_OK) { + mlxcx_fm_qstate_ereport(mlxp, "event", + eq->mleq_num, str, ctx.mleqc_status); + mlxcx_warn(mlxp, "EQ %u is in bad status: %x (%s)", + eq->mleq_intr_index, ctx.mleqc_status, str); + } + + if (ctx.mleqc_state != MLXCX_EQ_ST_ARMED && + (eq->mleq_state & MLXCX_EQ_ARMED)) { + if (eq->mleq_cc == eq->mleq_check_disarm_cc && + ++eq->mleq_check_disarm_cnt >= 3) { + mlxcx_fm_ereport(mlxp, DDI_FM_DEVICE_STALL); + mlxcx_warn(mlxp, "EQ %u isn't armed", + eq->mleq_intr_index); + } + eq->mleq_check_disarm_cc = eq->mleq_cc; + } else { + eq->mleq_check_disarm_cc = 0; + eq->mleq_check_disarm_cnt = 0; + } + + mutex_exit(&eq->mleq_mtx); + } +} + +static void +mlxcx_cq_check(void *arg) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_completion_queue_t *cq; + mlxcx_completionq_ctx_t ctx; + const char *str, *type; + uint_t v; + + for (cq = list_head(&mlxp->mlx_cqs); cq != NULL; + cq = list_next(&mlxp->mlx_cqs, cq)) { + mutex_enter(&cq->mlcq_mtx); + if (!(cq->mlcq_state & MLXCX_CQ_CREATED) || + (cq->mlcq_state & MLXCX_CQ_DESTROYED) || + (cq->mlcq_state & MLXCX_CQ_TEARDOWN)) { + mutex_exit(&cq->mlcq_mtx); + continue; + } + if (cq->mlcq_fm_repd_qstate) { + mutex_exit(&cq->mlcq_mtx); + continue; + } + if (!mlxcx_cmd_query_cq(mlxp, cq, &ctx)) { + mutex_exit(&cq->mlcq_mtx); + continue; + } + if (cq->mlcq_wq != NULL) { + mlxcx_work_queue_t *wq = cq->mlcq_wq; + if (wq->mlwq_type == MLXCX_WQ_TYPE_RECVQ) + type = "rx "; + else if (wq->mlwq_type == MLXCX_WQ_TYPE_SENDQ) + type = "tx "; + else + type = ""; + } else { + type = ""; + } + + str = "???"; + v = get_bits32(ctx.mlcqc_flags, MLXCX_CQ_CTX_STATUS); + switch (v) { + case MLXCX_CQC_STATUS_OK: + break; + case MLXCX_CQC_STATUS_OVERFLOW: + str = "OVERFLOW"; + break; + case MLXCX_CQC_STATUS_WRITE_FAIL: + str = "WRITE_FAIL"; + break; + case MLXCX_CQC_STATUS_INVALID: + str = "INVALID"; + break; + } + if (v != MLXCX_CQC_STATUS_OK) { + mlxcx_fm_qstate_ereport(mlxp, "completion", + cq->mlcq_num, str, v); + mlxcx_warn(mlxp, "%sCQ 0x%x is in bad status: %x (%s)", + type, cq->mlcq_num, v, str); + cq->mlcq_fm_repd_qstate = B_TRUE; + } + + v = get_bits32(ctx.mlcqc_flags, MLXCX_CQ_CTX_STATE); + if (v != MLXCX_CQC_STATE_ARMED && + (cq->mlcq_state & MLXCX_CQ_ARMED) && + !(cq->mlcq_state & MLXCX_CQ_POLLING)) { + if (cq->mlcq_cc == cq->mlcq_check_disarm_cc && + ++cq->mlcq_check_disarm_cnt >= 3) { + mlxcx_fm_ereport(mlxp, DDI_FM_DEVICE_STALL); + mlxcx_warn(mlxp, "%sCQ 0x%x (%p) isn't armed", + type, cq->mlcq_num, cq); + } + cq->mlcq_check_disarm_cc = cq->mlcq_cc; + } else { + cq->mlcq_check_disarm_cnt = 0; + cq->mlcq_check_disarm_cc = 0; + } + mutex_exit(&cq->mlcq_mtx); + } +} + +void +mlxcx_check_sq(mlxcx_t *mlxp, mlxcx_work_queue_t *sq) +{ + mlxcx_sq_ctx_t ctx; + mlxcx_sq_state_t state; + + ASSERT(mutex_owned(&sq->mlwq_mtx)); + + if (!mlxcx_cmd_query_sq(mlxp, sq, &ctx)) + return; + + ASSERT3U(from_be24(ctx.mlsqc_cqn), ==, sq->mlwq_cq->mlcq_num); + state = get_bits32(ctx.mlsqc_flags, MLXCX_SQ_STATE); + switch (state) { + case MLXCX_SQ_STATE_RST: + if (sq->mlwq_state & MLXCX_WQ_STARTED) { + mlxcx_fm_qstate_ereport(mlxp, "send", + sq->mlwq_num, "RST", state); + sq->mlwq_fm_repd_qstate = B_TRUE; + } + break; + case MLXCX_SQ_STATE_RDY: + if (!(sq->mlwq_state & MLXCX_WQ_STARTED)) { + mlxcx_fm_qstate_ereport(mlxp, "send", + sq->mlwq_num, "RDY", state); + sq->mlwq_fm_repd_qstate = B_TRUE; + } + break; + case MLXCX_SQ_STATE_ERR: + mlxcx_fm_qstate_ereport(mlxp, "send", + sq->mlwq_num, "ERR", state); + sq->mlwq_fm_repd_qstate = B_TRUE; + break; + default: + mlxcx_fm_qstate_ereport(mlxp, "send", + sq->mlwq_num, "???", state); + sq->mlwq_fm_repd_qstate = B_TRUE; + break; + } +} + +void +mlxcx_check_rq(mlxcx_t *mlxp, mlxcx_work_queue_t *rq) +{ + mlxcx_rq_ctx_t ctx; + mlxcx_rq_state_t state; + + ASSERT(mutex_owned(&rq->mlwq_mtx)); + + if (!mlxcx_cmd_query_rq(mlxp, rq, &ctx)) + return; + + ASSERT3U(from_be24(ctx.mlrqc_cqn), ==, rq->mlwq_cq->mlcq_num); + state = get_bits32(ctx.mlrqc_flags, MLXCX_RQ_STATE); + switch (state) { + case MLXCX_RQ_STATE_RST: + if (rq->mlwq_state & MLXCX_WQ_STARTED) { + mlxcx_fm_qstate_ereport(mlxp, "receive", + rq->mlwq_num, "RST", state); + rq->mlwq_fm_repd_qstate = B_TRUE; + } + break; + case MLXCX_RQ_STATE_RDY: + if (!(rq->mlwq_state & MLXCX_WQ_STARTED)) { + mlxcx_fm_qstate_ereport(mlxp, "receive", + rq->mlwq_num, "RDY", state); + rq->mlwq_fm_repd_qstate = B_TRUE; + } + break; + case MLXCX_RQ_STATE_ERR: + mlxcx_fm_qstate_ereport(mlxp, "receive", + rq->mlwq_num, "ERR", state); + rq->mlwq_fm_repd_qstate = B_TRUE; + break; + default: + mlxcx_fm_qstate_ereport(mlxp, "receive", + rq->mlwq_num, "???", state); + rq->mlwq_fm_repd_qstate = B_TRUE; + break; + } +} + +static void +mlxcx_wq_check(void *arg) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_work_queue_t *wq; + + for (wq = list_head(&mlxp->mlx_wqs); wq != NULL; + wq = list_next(&mlxp->mlx_wqs, wq)) { + mutex_enter(&wq->mlwq_mtx); + if (!(wq->mlwq_state & MLXCX_WQ_CREATED) || + (wq->mlwq_state & MLXCX_WQ_DESTROYED) || + (wq->mlwq_state & MLXCX_WQ_TEARDOWN)) { + mutex_exit(&wq->mlwq_mtx); + continue; + } + if (wq->mlwq_fm_repd_qstate) { + mutex_exit(&wq->mlwq_mtx); + continue; + } + switch (wq->mlwq_type) { + case MLXCX_WQ_TYPE_SENDQ: + mlxcx_check_sq(mlxp, wq); + break; + case MLXCX_WQ_TYPE_RECVQ: + mlxcx_check_rq(mlxp, wq); + break; + } + mutex_exit(&wq->mlwq_mtx); + } +} + +static boolean_t +mlxcx_setup_checktimers(mlxcx_t *mlxp) +{ + if (mlxp->mlx_props.mldp_eq_check_interval_sec > 0) { + mlxp->mlx_eq_checktimer = ddi_periodic_add(mlxcx_eq_check, mlxp, + mlxp->mlx_props.mldp_eq_check_interval_sec * NANOSEC, + DDI_IPL_0); + } + if (mlxp->mlx_props.mldp_cq_check_interval_sec > 0) { + mlxp->mlx_cq_checktimer = ddi_periodic_add(mlxcx_cq_check, mlxp, + mlxp->mlx_props.mldp_cq_check_interval_sec * NANOSEC, + DDI_IPL_0); + } + if (mlxp->mlx_props.mldp_wq_check_interval_sec > 0) { + mlxp->mlx_wq_checktimer = ddi_periodic_add(mlxcx_wq_check, mlxp, + mlxp->mlx_props.mldp_wq_check_interval_sec * NANOSEC, + DDI_IPL_0); + } + return (B_TRUE); +} + +int +mlxcx_dmac_fe_compare(const void *arg0, const void *arg1) +{ + const mlxcx_flow_entry_t *left = arg0; + const mlxcx_flow_entry_t *right = arg1; + int bcmpr; + + bcmpr = memcmp(left->mlfe_dmac, right->mlfe_dmac, + sizeof (left->mlfe_dmac)); + if (bcmpr < 0) + return (-1); + if (bcmpr > 0) + return (1); + if (left->mlfe_vid < right->mlfe_vid) + return (-1); + if (left->mlfe_vid > right->mlfe_vid) + return (1); + return (0); +} + +int +mlxcx_grmac_compare(const void *arg0, const void *arg1) +{ + const mlxcx_group_mac_t *left = arg0; + const mlxcx_group_mac_t *right = arg1; + int bcmpr; + + bcmpr = memcmp(left->mlgm_mac, right->mlgm_mac, + sizeof (left->mlgm_mac)); + if (bcmpr < 0) + return (-1); + if (bcmpr > 0) + return (1); + return (0); +} + +int +mlxcx_page_compare(const void *arg0, const void *arg1) +{ + const mlxcx_dev_page_t *p0 = arg0; + const mlxcx_dev_page_t *p1 = arg1; + + if (p0->mxdp_pa < p1->mxdp_pa) + return (-1); + if (p0->mxdp_pa > p1->mxdp_pa) + return (1); + return (0); +} + +static boolean_t +mlxcx_setup_ports(mlxcx_t *mlxp) +{ + uint_t i, j; + mlxcx_port_t *p; + mlxcx_flow_table_t *ft; + mlxcx_flow_group_t *fg; + mlxcx_flow_entry_t *fe; + + VERIFY3U(mlxp->mlx_nports, >, 0); + mlxp->mlx_ports_size = mlxp->mlx_nports * sizeof (mlxcx_port_t); + mlxp->mlx_ports = kmem_zalloc(mlxp->mlx_ports_size, KM_SLEEP); + + for (i = 0; i < mlxp->mlx_nports; ++i) { + p = &mlxp->mlx_ports[i]; + p->mlp_num = i; + p->mlp_init |= MLXCX_PORT_INIT; + mutex_init(&p->mlp_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + mutex_enter(&p->mlp_mtx); + if (!mlxcx_cmd_query_nic_vport_ctx(mlxp, p)) { + mutex_exit(&p->mlp_mtx); + goto err; + } + if (!mlxcx_cmd_query_port_mtu(mlxp, p)) { + mutex_exit(&p->mlp_mtx); + goto err; + } + if (!mlxcx_cmd_query_port_status(mlxp, p)) { + mutex_exit(&p->mlp_mtx); + goto err; + } + if (!mlxcx_cmd_query_port_speed(mlxp, p)) { + mutex_exit(&p->mlp_mtx); + goto err; + } + if (!mlxcx_cmd_modify_nic_vport_ctx(mlxp, p, + MLXCX_MODIFY_NIC_VPORT_CTX_PROMISC)) { + mutex_exit(&p->mlp_mtx); + goto err; + } + + mutex_exit(&p->mlp_mtx); + } + + for (i = 0; i < mlxp->mlx_nports; ++i) { + p = &mlxp->mlx_ports[i]; + mutex_enter(&p->mlp_mtx); + p->mlp_rx_flow = (ft = kmem_zalloc(sizeof (mlxcx_flow_table_t), + KM_SLEEP)); + mutex_init(&ft->mlft_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + + mutex_enter(&ft->mlft_mtx); + + ft->mlft_type = MLXCX_FLOW_TABLE_NIC_RX; + ft->mlft_port = p; + ft->mlft_entshift = mlxp->mlx_props.mldp_ftbl_root_size_shift; + if (ft->mlft_entshift > mlxp->mlx_caps->mlc_max_rx_ft_shift) + ft->mlft_entshift = mlxp->mlx_caps->mlc_max_rx_ft_shift; + ft->mlft_nents = (1 << ft->mlft_entshift); + ft->mlft_entsize = ft->mlft_nents * sizeof (mlxcx_flow_entry_t); + ft->mlft_ent = kmem_zalloc(ft->mlft_entsize, KM_SLEEP); + list_create(&ft->mlft_groups, sizeof (mlxcx_flow_group_t), + offsetof(mlxcx_flow_group_t, mlfg_entry)); + + for (j = 0; j < ft->mlft_nents; ++j) { + ft->mlft_ent[j].mlfe_table = ft; + ft->mlft_ent[j].mlfe_index = j; + } + + if (!mlxcx_cmd_create_flow_table(mlxp, ft)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&p->mlp_mtx); + goto err; + } + + if (!mlxcx_cmd_set_flow_table_root(mlxp, ft)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&p->mlp_mtx); + goto err; + } + + /* + * We match broadcast at the top of the root flow table, then + * all multicast/unicast MACs, then the promisc entry is down + * the very bottom. + * + * This way when promisc is on, that entry simply catches any + * remaining traffic that earlier flows haven't matched. + */ + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_DMAC; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&p->mlp_mtx); + goto err; + } + p->mlp_bcast = fg; + fe = list_head(&fg->mlfg_entries); + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + (void) memset(fe->mlfe_dmac, 0xff, sizeof (fe->mlfe_dmac)); + fe->mlfe_state |= MLXCX_FLOW_ENTRY_DIRTY; + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = ft->mlft_nents - 2; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_DMAC; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&p->mlp_mtx); + goto err; + } + p->mlp_umcast = fg; + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&p->mlp_mtx); + goto err; + } + p->mlp_promisc = fg; + fe = list_head(&fg->mlfg_entries); + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_state |= MLXCX_FLOW_ENTRY_DIRTY; + + avl_create(&p->mlp_dmac_fe, mlxcx_dmac_fe_compare, + sizeof (mlxcx_flow_entry_t), offsetof(mlxcx_flow_entry_t, + mlfe_dmac_entry)); + + mutex_exit(&ft->mlft_mtx); + mutex_exit(&p->mlp_mtx); + } + + return (B_TRUE); + +err: + mlxcx_teardown_ports(mlxp); + return (B_FALSE); +} + +void +mlxcx_remove_all_vlan_entries(mlxcx_t *mlxp, mlxcx_ring_group_t *g) +{ + mlxcx_flow_table_t *ft = g->mlg_rx_vlan_ft; + mlxcx_flow_group_t *fg = g->mlg_rx_vlan_fg; + mlxcx_flow_group_t *dfg = g->mlg_rx_vlan_def_fg; + mlxcx_flow_entry_t *fe; + mlxcx_group_vlan_t *v; + + ASSERT(mutex_owned(&g->mlg_mtx)); + + mutex_enter(&ft->mlft_mtx); + + if (!list_is_empty(&g->mlg_rx_vlans)) { + fe = list_head(&dfg->mlfg_entries); + (void) mlxcx_cmd_set_flow_table_entry(mlxp, fe); + } + + while ((v = list_remove_head(&g->mlg_rx_vlans)) != NULL) { + fe = v->mlgv_fe; + ASSERT3P(fe->mlfe_table, ==, ft); + ASSERT3P(fe->mlfe_group, ==, fg); + kmem_free(v, sizeof (mlxcx_group_vlan_t)); + + (void) mlxcx_cmd_delete_flow_table_entry(mlxp, fe); + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_RESERVED; + } + + mutex_exit(&ft->mlft_mtx); +} + +boolean_t +mlxcx_remove_vlan_entry(mlxcx_t *mlxp, mlxcx_ring_group_t *g, + boolean_t tagged, uint16_t vid) +{ + mlxcx_flow_table_t *ft = g->mlg_rx_vlan_ft; + mlxcx_flow_group_t *fg = g->mlg_rx_vlan_fg; + mlxcx_flow_group_t *dfg = g->mlg_rx_vlan_def_fg; + mlxcx_flow_entry_t *fe; + mlxcx_group_vlan_t *v; + boolean_t found = B_FALSE; + + ASSERT(mutex_owned(&g->mlg_mtx)); + + mutex_enter(&ft->mlft_mtx); + + for (v = list_head(&g->mlg_rx_vlans); v != NULL; + v = list_next(&g->mlg_rx_vlans, v)) { + if (v->mlgv_tagged == tagged && v->mlgv_vid == vid) { + found = B_TRUE; + break; + } + } + if (!found) { + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + + list_remove(&g->mlg_rx_vlans, v); + + /* + * If this is the last VLAN entry, we have to go back to accepting + * any VLAN (which means re-enabling the default entry). + * + * Do this before we remove the flow entry for the last specific + * VLAN so that we don't lose any traffic in the transition. + */ + if (list_is_empty(&g->mlg_rx_vlans)) { + fe = list_head(&dfg->mlfg_entries); + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + list_insert_tail(&g->mlg_rx_vlans, v); + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + } + + fe = v->mlgv_fe; + ASSERT(fe->mlfe_state & MLXCX_FLOW_ENTRY_RESERVED); + ASSERT(fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED); + ASSERT3P(fe->mlfe_table, ==, ft); + ASSERT3P(fe->mlfe_group, ==, fg); + + if (!mlxcx_cmd_delete_flow_table_entry(mlxp, fe)) { + list_insert_tail(&g->mlg_rx_vlans, v); + fe = list_head(&dfg->mlfg_entries); + if (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + (void) mlxcx_cmd_delete_flow_table_entry(mlxp, fe); + } + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_RESERVED; + + kmem_free(v, sizeof (mlxcx_group_vlan_t)); + + mutex_exit(&ft->mlft_mtx); + return (B_TRUE); +} + +boolean_t +mlxcx_add_vlan_entry(mlxcx_t *mlxp, mlxcx_ring_group_t *g, boolean_t tagged, + uint16_t vid) +{ + mlxcx_flow_table_t *ft = g->mlg_rx_vlan_ft; + mlxcx_flow_group_t *fg = g->mlg_rx_vlan_fg; + mlxcx_flow_group_t *dfg = g->mlg_rx_vlan_def_fg; + mlxcx_flow_entry_t *fe; + mlxcx_group_vlan_t *v; + boolean_t found = B_FALSE; + boolean_t first = B_FALSE; + + ASSERT(mutex_owned(&g->mlg_mtx)); + + mutex_enter(&ft->mlft_mtx); + + for (v = list_head(&g->mlg_rx_vlans); v != NULL; + v = list_next(&g->mlg_rx_vlans, v)) { + if (v->mlgv_tagged == tagged && v->mlgv_vid == vid) { + mutex_exit(&ft->mlft_mtx); + return (B_TRUE); + } + } + if (list_is_empty(&g->mlg_rx_vlans)) + first = B_TRUE; + + for (fe = list_head(&fg->mlfg_entries); fe != NULL; + fe = list_next(&fg->mlfg_entries, fe)) { + if (!(fe->mlfe_state & MLXCX_FLOW_ENTRY_RESERVED)) { + found = B_TRUE; + break; + } + } + if (!found) { + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + + v = kmem_zalloc(sizeof (mlxcx_group_vlan_t), KM_SLEEP); + v->mlgv_fe = fe; + v->mlgv_tagged = tagged; + v->mlgv_vid = vid; + + fe->mlfe_state |= MLXCX_FLOW_ENTRY_RESERVED; + fe->mlfe_state |= MLXCX_FLOW_ENTRY_DIRTY; + fe->mlfe_vid = vid; + if (tagged) { + fe->mlfe_vlan_type = MLXCX_VLAN_TYPE_CVLAN; + } else { + fe->mlfe_vlan_type = MLXCX_VLAN_TYPE_NONE; + } + + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_DIRTY; + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_RESERVED; + kmem_free(v, sizeof (mlxcx_group_vlan_t)); + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + + list_insert_tail(&g->mlg_rx_vlans, v); + + /* + * If the vlan list was empty for this group before adding this one, + * then we no longer want the "default" entry to allow all VLANs + * through. + */ + if (first) { + fe = list_head(&dfg->mlfg_entries); + (void) mlxcx_cmd_delete_flow_table_entry(mlxp, fe); + } + + mutex_exit(&ft->mlft_mtx); + return (B_TRUE); +} + +void +mlxcx_remove_all_umcast_entries(mlxcx_t *mlxp, mlxcx_port_t *port, + mlxcx_ring_group_t *group) +{ + mlxcx_flow_entry_t *fe; + mlxcx_flow_table_t *ft = port->mlp_rx_flow; + mlxcx_group_mac_t *gm, *ngm; + + ASSERT(mutex_owned(&port->mlp_mtx)); + ASSERT(mutex_owned(&group->mlg_mtx)); + + mutex_enter(&ft->mlft_mtx); + + gm = avl_first(&group->mlg_rx_macs); + for (; gm != NULL; gm = ngm) { + ngm = AVL_NEXT(&group->mlg_rx_macs, gm); + + ASSERT3P(gm->mlgm_group, ==, group); + fe = gm->mlgm_fe; + ASSERT3P(fe->mlfe_table, ==, ft); + + avl_remove(&group->mlg_rx_macs, gm); + list_remove(&fe->mlfe_ring_groups, gm); + kmem_free(gm, sizeof (mlxcx_group_mac_t)); + + fe->mlfe_ndest = 0; + for (gm = list_head(&fe->mlfe_ring_groups); gm != NULL; + gm = list_next(&fe->mlfe_ring_groups, gm)) { + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_flow = + gm->mlgm_group->mlg_rx_vlan_ft; + } + fe->mlfe_state |= MLXCX_FLOW_ENTRY_DIRTY; + + if (fe->mlfe_ndest > 0) { + (void) mlxcx_cmd_set_flow_table_entry(mlxp, fe); + continue; + } + + /* + * There are no more ring groups left for this MAC (it wasn't + * attached to any other groups since ndest == 0), so clean up + * its flow entry. + */ + avl_remove(&port->mlp_dmac_fe, fe); + (void) mlxcx_cmd_delete_flow_table_entry(mlxp, fe); + list_destroy(&fe->mlfe_ring_groups); + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_RESERVED; + } + + mutex_exit(&ft->mlft_mtx); +} + +boolean_t +mlxcx_remove_umcast_entry(mlxcx_t *mlxp, mlxcx_port_t *port, + mlxcx_ring_group_t *group, const uint8_t *macaddr) +{ + mlxcx_flow_entry_t *fe; + mlxcx_flow_table_t *ft = port->mlp_rx_flow; + mlxcx_group_mac_t *gm, probe; + + ASSERT(mutex_owned(&port->mlp_mtx)); + ASSERT(mutex_owned(&group->mlg_mtx)); + + bzero(&probe, sizeof (probe)); + bcopy(macaddr, probe.mlgm_mac, sizeof (probe.mlgm_mac)); + + mutex_enter(&ft->mlft_mtx); + + gm = avl_find(&group->mlg_rx_macs, &probe, NULL); + if (gm == NULL) { + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + ASSERT3P(gm->mlgm_group, ==, group); + ASSERT0(bcmp(macaddr, gm->mlgm_mac, sizeof (gm->mlgm_mac))); + + fe = gm->mlgm_fe; + ASSERT3P(fe->mlfe_table, ==, ft); + ASSERT0(bcmp(macaddr, fe->mlfe_dmac, sizeof (fe->mlfe_dmac))); + + list_remove(&fe->mlfe_ring_groups, gm); + avl_remove(&group->mlg_rx_macs, gm); + kmem_free(gm, sizeof (mlxcx_group_mac_t)); + + fe->mlfe_ndest = 0; + for (gm = list_head(&fe->mlfe_ring_groups); gm != NULL; + gm = list_next(&fe->mlfe_ring_groups, gm)) { + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_flow = + gm->mlgm_group->mlg_rx_vlan_ft; + } + fe->mlfe_state |= MLXCX_FLOW_ENTRY_DIRTY; + + if (fe->mlfe_ndest > 0) { + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + mutex_exit(&ft->mlft_mtx); + return (B_TRUE); + } + + /* + * There are no more ring groups left for this MAC (it wasn't attached + * to any other groups since ndest == 0), so clean up its flow entry. + */ + avl_remove(&port->mlp_dmac_fe, fe); + (void) mlxcx_cmd_delete_flow_table_entry(mlxp, fe); + list_destroy(&fe->mlfe_ring_groups); + + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_RESERVED; + + mutex_exit(&ft->mlft_mtx); + + return (B_TRUE); +} + +boolean_t +mlxcx_add_umcast_entry(mlxcx_t *mlxp, mlxcx_port_t *port, + mlxcx_ring_group_t *group, const uint8_t *macaddr) +{ + mlxcx_flow_group_t *fg; + mlxcx_flow_entry_t *fe, probe; + mlxcx_flow_table_t *ft = port->mlp_rx_flow; + mlxcx_group_mac_t *gm; + boolean_t found = B_FALSE; + + ASSERT(mutex_owned(&port->mlp_mtx)); + ASSERT(mutex_owned(&group->mlg_mtx)); + + bzero(&probe, sizeof (probe)); + bcopy(macaddr, probe.mlfe_dmac, sizeof (probe.mlfe_dmac)); + + mutex_enter(&ft->mlft_mtx); + + fe = avl_find(&port->mlp_dmac_fe, &probe, NULL); + + if (fe == NULL) { + fg = port->mlp_umcast; + for (fe = list_head(&fg->mlfg_entries); fe != NULL; + fe = list_next(&fg->mlfg_entries, fe)) { + if (!(fe->mlfe_state & MLXCX_FLOW_ENTRY_RESERVED)) { + found = B_TRUE; + break; + } + } + if (!found) { + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + list_create(&fe->mlfe_ring_groups, sizeof (mlxcx_group_mac_t), + offsetof(mlxcx_group_mac_t, mlgm_fe_entry)); + fe->mlfe_state |= MLXCX_FLOW_ENTRY_RESERVED; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + bcopy(macaddr, fe->mlfe_dmac, sizeof (fe->mlfe_dmac)); + + avl_add(&port->mlp_dmac_fe, fe); + } + + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_flow = group->mlg_rx_vlan_ft; + fe->mlfe_state |= MLXCX_FLOW_ENTRY_DIRTY; + + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_DIRTY; + if (--fe->mlfe_ndest == 0) { + fe->mlfe_state &= ~MLXCX_FLOW_ENTRY_RESERVED; + } + mutex_exit(&ft->mlft_mtx); + return (B_FALSE); + } + + gm = kmem_zalloc(sizeof (mlxcx_group_mac_t), KM_SLEEP); + gm->mlgm_group = group; + gm->mlgm_fe = fe; + bcopy(macaddr, gm->mlgm_mac, sizeof (gm->mlgm_mac)); + avl_add(&group->mlg_rx_macs, gm); + list_insert_tail(&fe->mlfe_ring_groups, gm); + + mutex_exit(&ft->mlft_mtx); + + return (B_TRUE); +} + +boolean_t +mlxcx_setup_flow_group(mlxcx_t *mlxp, mlxcx_flow_table_t *ft, + mlxcx_flow_group_t *fg) +{ + mlxcx_flow_entry_t *fe; + uint_t i, idx; + + ASSERT(mutex_owned(&ft->mlft_mtx)); + ASSERT(ft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + ASSERT3P(fg->mlfg_table, ==, ft); + + if (ft->mlft_next_ent + fg->mlfg_size > ft->mlft_nents) + return (B_FALSE); + fg->mlfg_start_idx = ft->mlft_next_ent; + + if (!mlxcx_cmd_create_flow_group(mlxp, fg)) { + return (B_FALSE); + } + + list_create(&fg->mlfg_entries, sizeof (mlxcx_flow_entry_t), + offsetof(mlxcx_flow_entry_t, mlfe_group_entry)); + for (i = 0; i < fg->mlfg_size; ++i) { + idx = fg->mlfg_start_idx + i; + fe = &ft->mlft_ent[idx]; + fe->mlfe_group = fg; + list_insert_tail(&fg->mlfg_entries, fe); + } + fg->mlfg_avail = fg->mlfg_size; + ft->mlft_next_ent += fg->mlfg_size; + + return (B_TRUE); +} + +static boolean_t +mlxcx_setup_eq0(mlxcx_t *mlxp) +{ + mlxcx_event_queue_t *mleq = &mlxp->mlx_eqs[0]; + + mutex_enter(&mleq->mleq_mtx); + if (!mlxcx_eq_alloc_dma(mlxp, mleq)) { + /* mlxcx_teardown_eqs() will clean this up */ + mutex_exit(&mleq->mleq_mtx); + return (B_FALSE); + } + mleq->mleq_mlx = mlxp; + mleq->mleq_uar = &mlxp->mlx_uar; + mleq->mleq_events = + (1ULL << MLXCX_EVENT_PAGE_REQUEST) | + (1ULL << MLXCX_EVENT_PORT_STATE) | + (1ULL << MLXCX_EVENT_INTERNAL_ERROR) | + (1ULL << MLXCX_EVENT_PORT_MODULE) | + (1ULL << MLXCX_EVENT_SENDQ_DRAIN) | + (1ULL << MLXCX_EVENT_LAST_WQE) | + (1ULL << MLXCX_EVENT_CQ_ERROR) | + (1ULL << MLXCX_EVENT_WQ_CATASTROPHE) | + (1ULL << MLXCX_EVENT_PAGE_FAULT) | + (1ULL << MLXCX_EVENT_WQ_INVALID_REQ) | + (1ULL << MLXCX_EVENT_WQ_ACCESS_VIOL) | + (1ULL << MLXCX_EVENT_NIC_VPORT) | + (1ULL << MLXCX_EVENT_DOORBELL_CONGEST); + if (!mlxcx_cmd_create_eq(mlxp, mleq)) { + /* mlxcx_teardown_eqs() will clean this up */ + mutex_exit(&mleq->mleq_mtx); + return (B_FALSE); + } + if (ddi_intr_enable(mlxp->mlx_intr_handles[0]) != DDI_SUCCESS) { + /* + * mlxcx_teardown_eqs() will handle calling cmd_destroy_eq and + * eq_rele_dma + */ + mutex_exit(&mleq->mleq_mtx); + return (B_FALSE); + } + mlxcx_arm_eq(mlxp, mleq); + mutex_exit(&mleq->mleq_mtx); + return (B_TRUE); +} + +int +mlxcx_cq_compare(const void *arg0, const void *arg1) +{ + const mlxcx_completion_queue_t *left = arg0; + const mlxcx_completion_queue_t *right = arg1; + + if (left->mlcq_num < right->mlcq_num) { + return (-1); + } + if (left->mlcq_num > right->mlcq_num) { + return (1); + } + return (0); +} + +static boolean_t +mlxcx_setup_eqs(mlxcx_t *mlxp) +{ + uint_t i; + mlxcx_event_queue_t *mleq; + + ASSERT3S(mlxp->mlx_intr_count, >, 0); + + for (i = 1; i < mlxp->mlx_intr_count; ++i) { + mleq = &mlxp->mlx_eqs[i]; + mutex_enter(&mleq->mleq_mtx); + if (!mlxcx_eq_alloc_dma(mlxp, mleq)) { + mutex_exit(&mleq->mleq_mtx); + return (B_FALSE); + } + mleq->mleq_uar = &mlxp->mlx_uar; + if (!mlxcx_cmd_create_eq(mlxp, mleq)) { + /* mlxcx_teardown() will handle calling eq_rele_dma */ + mutex_exit(&mleq->mleq_mtx); + return (B_FALSE); + } + if (mlxp->mlx_props.mldp_intrmod_period_usec != 0 && + !mlxcx_cmd_set_int_mod(mlxp, i, + mlxp->mlx_props.mldp_intrmod_period_usec)) { + mutex_exit(&mleq->mleq_mtx); + return (B_FALSE); + } + if (ddi_intr_enable(mlxp->mlx_intr_handles[i]) != DDI_SUCCESS) { + mutex_exit(&mleq->mleq_mtx); + return (B_FALSE); + } + mlxcx_arm_eq(mlxp, mleq); + mutex_exit(&mleq->mleq_mtx); + } + + mlxp->mlx_next_eq = 1; + + return (B_TRUE); +} + +/* + * Snapshot all of the hardware capabilities that we care about and then modify + * the HCA capabilities to get things moving. + */ +static boolean_t +mlxcx_init_caps(mlxcx_t *mlxp) +{ + mlxcx_caps_t *c; + + mlxp->mlx_caps = c = kmem_zalloc(sizeof (mlxcx_caps_t), KM_SLEEP); + + if (!mlxcx_cmd_query_hca_cap(mlxp, MLXCX_HCA_CAP_GENERAL, + MLXCX_HCA_CAP_MODE_CURRENT, &c->mlc_hca_cur)) { + mlxcx_warn(mlxp, "failed to obtain current HCA general caps"); + } + + if (!mlxcx_cmd_query_hca_cap(mlxp, MLXCX_HCA_CAP_GENERAL, + MLXCX_HCA_CAP_MODE_MAX, &c->mlc_hca_max)) { + mlxcx_warn(mlxp, "failed to obtain maximum HCA general caps"); + } + + if (!mlxcx_cmd_query_hca_cap(mlxp, MLXCX_HCA_CAP_ETHERNET, + MLXCX_HCA_CAP_MODE_CURRENT, &c->mlc_ether_cur)) { + mlxcx_warn(mlxp, "failed to obtain current HCA eth caps"); + } + + if (!mlxcx_cmd_query_hca_cap(mlxp, MLXCX_HCA_CAP_ETHERNET, + MLXCX_HCA_CAP_MODE_MAX, &c->mlc_ether_max)) { + mlxcx_warn(mlxp, "failed to obtain maximum HCA eth caps"); + } + + if (!mlxcx_cmd_query_hca_cap(mlxp, MLXCX_HCA_CAP_NIC_FLOW, + MLXCX_HCA_CAP_MODE_CURRENT, &c->mlc_nic_flow_cur)) { + mlxcx_warn(mlxp, "failed to obtain current HCA flow caps"); + } + + if (!mlxcx_cmd_query_hca_cap(mlxp, MLXCX_HCA_CAP_NIC_FLOW, + MLXCX_HCA_CAP_MODE_MAX, &c->mlc_nic_flow_max)) { + mlxcx_warn(mlxp, "failed to obtain maximum HCA flow caps"); + } + + /* + * Check the caps meet our requirements. + */ + const mlxcx_hca_cap_general_caps_t *gen = &c->mlc_hca_cur.mhc_general; + + if (gen->mlcap_general_log_pg_sz != 12) { + mlxcx_warn(mlxp, "!hardware has page size != 4k " + "(log_pg_sz = %u)", (uint_t)gen->mlcap_general_log_pg_sz); + goto err; + } + if (gen->mlcap_general_cqe_version != 1) { + mlxcx_warn(mlxp, "!hardware does not support CQE v1 " + "(cqe_ver = %u)", (uint_t)gen->mlcap_general_cqe_version); + goto err; + } + if (gen->mlcap_general_port_type != + MLXCX_CAP_GENERAL_PORT_TYPE_ETHERNET) { + mlxcx_warn(mlxp, "!hardware has non-ethernet ports"); + goto err; + } + mlxp->mlx_nports = gen->mlcap_general_num_ports; + mlxp->mlx_max_sdu = (1 << (gen->mlcap_general_log_max_msg & 0x1F)); + + c->mlc_max_tir = (1 << gen->mlcap_general_log_max_tir); + + c->mlc_checksum = get_bit32(c->mlc_ether_cur.mhc_eth.mlcap_eth_flags, + MLXCX_ETH_CAP_CSUM_CAP); + c->mlc_vxlan = get_bit32(c->mlc_ether_cur.mhc_eth.mlcap_eth_flags, + MLXCX_ETH_CAP_TUNNEL_STATELESS_VXLAN); + + c->mlc_max_lso_size = (1 << get_bits32(c->mlc_ether_cur.mhc_eth. + mlcap_eth_flags, MLXCX_ETH_CAP_MAX_LSO_CAP)); + if (c->mlc_max_lso_size == 1) { + c->mlc_max_lso_size = 0; + c->mlc_lso = B_FALSE; + } else { + c->mlc_lso = B_TRUE; + } + + c->mlc_max_rqt_size = (1 << get_bits32(c->mlc_ether_cur.mhc_eth. + mlcap_eth_flags, MLXCX_ETH_CAP_RSS_IND_TBL_CAP)); + + if (!get_bit32(c->mlc_nic_flow_cur.mhc_flow.mlcap_flow_nic_rx. + mlcap_flow_prop_flags, MLXCX_FLOW_CAP_PROPS_SUPPORT)) { + mlxcx_warn(mlxp, "!hardware does not support rx flow tables"); + goto err; + } + if (!get_bit32(c->mlc_nic_flow_cur.mhc_flow.mlcap_flow_nic_rx. + mlcap_flow_prop_flags, MLXCX_FLOW_CAP_PROPS_MODIFY)) { + mlxcx_warn(mlxp, "!hardware does not support modifying rx " + "flow table entries"); + goto err; + } + + c->mlc_max_rx_ft_shift = c->mlc_nic_flow_cur.mhc_flow.mlcap_flow_nic_rx. + mlcap_flow_prop_log_max_ft_size; + c->mlc_max_rx_flows = (1 << c->mlc_nic_flow_cur.mhc_flow. + mlcap_flow_nic_rx.mlcap_flow_prop_log_max_flow); + c->mlc_max_rx_fe_dest = (1 << c->mlc_nic_flow_cur.mhc_flow. + mlcap_flow_nic_rx.mlcap_flow_prop_log_max_destination); + + return (B_TRUE); + +err: + kmem_free(mlxp->mlx_caps, sizeof (mlxcx_caps_t)); + return (B_FALSE); +} + +static int +mlxcx_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) +{ + mlxcx_t *mlxp; + + if (cmd != DDI_DETACH) + return (DDI_FAILURE); + + mlxp = ddi_get_driver_private(dip); + if (mlxp == NULL) { + mlxcx_warn(NULL, "asked to detach, but missing instance " + "private data"); + return (DDI_FAILURE); + } + + if (mlxp->mlx_attach & MLXCX_ATTACH_MAC_HDL) { + if (mac_unregister(mlxp->mlx_mac_hdl) != DDI_SUCCESS) { + return (DDI_FAILURE); + } + mlxp->mlx_attach &= ~MLXCX_ATTACH_MAC_HDL; + } + + mlxcx_teardown(mlxp); + return (DDI_SUCCESS); +} + +static size_t +mlxcx_calc_rx_ngroups(mlxcx_t *mlxp) +{ + size_t ngroups = mlxp->mlx_props.mldp_rx_ngroups_large + + mlxp->mlx_props.mldp_rx_ngroups_small; + size_t tirlim, flowlim, gflowlim; + + tirlim = mlxp->mlx_caps->mlc_max_tir / MLXCX_TIRS_PER_GROUP; + if (tirlim < ngroups) { + mlxcx_note(mlxp, "limiting number of rx groups to %u based " + "on number of TIRs available", tirlim); + ngroups = tirlim; + } + + flowlim = (1 << mlxp->mlx_caps->mlc_max_rx_ft_shift) - 2; + if (flowlim < ngroups) { + mlxcx_note(mlxp, "limiting number of rx groups to %u based " + "on max size of RX flow tables", flowlim); + ngroups = flowlim; + } + + do { + gflowlim = mlxp->mlx_caps->mlc_max_rx_flows - 16 * ngroups - 2; + if (gflowlim < ngroups) { + mlxcx_note(mlxp, "limiting number of rx groups to %u " + "based on max total RX flows", gflowlim); + --ngroups; + } + } while (gflowlim < ngroups); + + return (ngroups); +} + +static int +mlxcx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) +{ + mlxcx_t *mlxp; + uint_t i; + int inst, ret; + + if (cmd != DDI_ATTACH) + return (DDI_FAILURE); + + inst = ddi_get_instance(dip); + ret = ddi_soft_state_zalloc(mlxcx_softstate, inst); + if (ret != 0) + return (ret); + + mlxp = ddi_get_soft_state(mlxcx_softstate, inst); + if (mlxp == NULL) + return (DDI_FAILURE); + mlxp->mlx_dip = dip; + mlxp->mlx_inst = inst; + ddi_set_driver_private(dip, mlxp); + + mlxcx_load_props(mlxp); + + mlxcx_fm_init(mlxp); + mlxp->mlx_attach |= MLXCX_ATTACH_FM; + + if (pci_config_setup(mlxp->mlx_dip, &mlxp->mlx_cfg_handle) != + DDI_SUCCESS) { + mlxcx_warn(mlxp, "failed to initial PCI config space"); + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_PCI_CONFIG; + + if (!mlxcx_regs_map(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_REGS; + + if (!mlxcx_cmd_queue_init(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_CMD; + + if (!mlxcx_cmd_enable_hca(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_ENABLE_HCA; + + if (!mlxcx_check_issi(mlxp)) { + goto err; + } + + /* + * We have to get our interrupts now so we know what priority to + * create pagemtx with. + */ + if (!mlxcx_intr_setup(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_INTRS; + + mutex_init(&mlxp->mlx_pagemtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + avl_create(&mlxp->mlx_pages, mlxcx_page_compare, + sizeof (mlxcx_dev_page_t), offsetof(mlxcx_dev_page_t, mxdp_tree)); + mlxp->mlx_attach |= MLXCX_ATTACH_PAGE_LIST; + + if (!mlxcx_init_pages(mlxp, MLXCX_QUERY_PAGES_OPMOD_BOOT)) { + goto err; + } + + if (!mlxcx_init_caps(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_CAPS; + + if (!mlxcx_init_pages(mlxp, MLXCX_QUERY_PAGES_OPMOD_INIT)) { + goto err; + } + + if (!mlxcx_cmd_init_hca(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_INIT_HCA; + + if (!mlxcx_cmd_set_driver_version(mlxp, MLXCX_DRIVER_VERSION)) { + goto err; + } + + /* + * The User Access Region (UAR) is needed so we can ring EQ and CQ + * doorbells. + */ + if (!mlxcx_cmd_alloc_uar(mlxp, &mlxp->mlx_uar)) { + goto err; + } + for (i = 0; i < MLXCX_BF_PER_UAR; ++i) { + mutex_init(&mlxp->mlx_uar.mlu_bf[i].mbf_mtx, NULL, + MUTEX_DRIVER, DDI_INTR_PRI(mlxp->mlx_intr_pri)); + } + mlxp->mlx_attach |= MLXCX_ATTACH_UAR_PD_TD; + + /* + * Set up event queue #0 -- it's special and only handles control + * type events, like PAGE_REQUEST (which we will probably get during + * the commands below). + * + * This will enable and arm the interrupt on EQ 0, too. + */ + if (!mlxcx_setup_eq0(mlxp)) { + goto err; + } + + /* + * Allocate a protection and transport domain. These don't really do + * anything for us (they're IB concepts), but we need to give their + * ID numbers in other commands. + */ + if (!mlxcx_cmd_alloc_pd(mlxp, &mlxp->mlx_pd)) { + goto err; + } + if (!mlxcx_cmd_alloc_tdom(mlxp, &mlxp->mlx_tdom)) { + goto err; + } + /* + * Fetch the "reserved" lkey that lets us give linear addresses in + * work queue entries, rather than having to mess with the NIC's + * internal MMU. + */ + if (!mlxcx_cmd_query_special_ctxs(mlxp)) { + goto err; + } + + /* + * Query our port information and current state, populate the + * mlxcx_port_t structs. + * + * This also sets up the root flow tables and flow groups. + */ + if (!mlxcx_setup_ports(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_PORTS; + + /* + * Set up, enable and arm the rest of the interrupt EQs which will + * service events from CQs. + * + * The MLXCX_ATTACH_INTRS flag covers checking if these need to be + * cleaned up. + */ + if (!mlxcx_setup_eqs(mlxp)) { + goto err; + } + + /* Completion queues */ + list_create(&mlxp->mlx_cqs, sizeof (mlxcx_completion_queue_t), + offsetof(mlxcx_completion_queue_t, mlcq_entry)); + mlxp->mlx_attach |= MLXCX_ATTACH_CQS; + + /* Work queues (send queues, receive queues) */ + list_create(&mlxp->mlx_wqs, sizeof (mlxcx_work_queue_t), + offsetof(mlxcx_work_queue_t, mlwq_entry)); + mlxp->mlx_attach |= MLXCX_ATTACH_WQS; + + /* Set up periodic fault check timers which check the queue states */ + if (!mlxcx_setup_checktimers(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_CHKTIMERS; + + /* + * Construct our arrays of mlxcx_ring_group_ts, which represent the + * "groups" we advertise to MAC. + */ + mlxp->mlx_rx_ngroups = mlxcx_calc_rx_ngroups(mlxp); + mlxp->mlx_rx_groups_size = mlxp->mlx_rx_ngroups * + sizeof (mlxcx_ring_group_t); + mlxp->mlx_rx_groups = kmem_zalloc(mlxp->mlx_rx_groups_size, KM_SLEEP); + + mlxp->mlx_tx_ngroups = mlxp->mlx_props.mldp_tx_ngroups; + mlxp->mlx_tx_groups_size = mlxp->mlx_tx_ngroups * + sizeof (mlxcx_ring_group_t); + mlxp->mlx_tx_groups = kmem_zalloc(mlxp->mlx_tx_groups_size, KM_SLEEP); + + mlxp->mlx_attach |= MLXCX_ATTACH_GROUPS; + + /* + * Sets up the free/busy buffers list for keeping track of packet + * buffers. + */ + if (!mlxcx_setup_bufs(mlxp)) + goto err; + mlxp->mlx_attach |= MLXCX_ATTACH_BUFS; + + /* + * Before we tell MAC about our rings/groups, we need to do enough + * setup on them to be sure about the numbers and configuration that + * we have. This will do basically everything short of allocating + * packet buffers and starting the rings up. + */ + for (i = 0; i < mlxp->mlx_tx_ngroups; ++i) { + if (!mlxcx_tx_group_setup(mlxp, &mlxp->mlx_tx_groups[i])) + goto err; + } + for (i = 0; i < mlxp->mlx_rx_ngroups; ++i) { + if (!mlxcx_rx_group_setup(mlxp, &mlxp->mlx_rx_groups[i])) + goto err; + } + + /* + * Finally, tell MAC that we exist! + */ + if (!mlxcx_register_mac(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_MAC_HDL; + + return (DDI_SUCCESS); + +err: + mlxcx_teardown(mlxp); + return (DDI_FAILURE); +} + +static struct cb_ops mlxcx_cb_ops = { + .cb_open = nulldev, + .cb_close = nulldev, + .cb_strategy = nodev, + .cb_print = nodev, + .cb_dump = nodev, + .cb_read = nodev, + .cb_write = nodev, + .cb_ioctl = nodev, + .cb_devmap = nodev, + .cb_mmap = nodev, + .cb_segmap = nodev, + .cb_chpoll = nochpoll, + .cb_prop_op = ddi_prop_op, + .cb_flag = D_MP, + .cb_rev = CB_REV, + .cb_aread = nodev, + .cb_awrite = nodev +}; + +static struct dev_ops mlxcx_dev_ops = { + .devo_rev = DEVO_REV, + .devo_refcnt = 0, + .devo_getinfo = NULL, + .devo_identify = nulldev, + .devo_probe = nulldev, + .devo_attach = mlxcx_attach, + .devo_detach = mlxcx_detach, + .devo_reset = nodev, + .devo_power = ddi_power, + .devo_quiesce = ddi_quiesce_not_supported, + .devo_cb_ops = &mlxcx_cb_ops +}; + +static struct modldrv mlxcx_modldrv = { + .drv_modops = &mod_driverops, + .drv_linkinfo = "Mellanox Connect-X 4/5/6", + .drv_dev_ops = &mlxcx_dev_ops +}; + +static struct modlinkage mlxcx_modlinkage = { + .ml_rev = MODREV_1, + .ml_linkage = { &mlxcx_modldrv, NULL } +}; + +int +_init(void) +{ + int ret; + + ret = ddi_soft_state_init(&mlxcx_softstate, sizeof (mlxcx_t), 0); + if (ret != 0) { + return (ret); + } + + mac_init_ops(&mlxcx_dev_ops, MLXCX_MODULE_NAME); + + if ((ret = mod_install(&mlxcx_modlinkage)) != DDI_SUCCESS) { + mac_fini_ops(&mlxcx_dev_ops); + ddi_soft_state_fini(&mlxcx_softstate); + return (ret); + } + + return (DDI_SUCCESS); +} + +int +_info(struct modinfo *modinfop) +{ + return (mod_info(&mlxcx_modlinkage, modinfop)); +} + +int +_fini(void) +{ + int ret; + + if ((ret = mod_remove(&mlxcx_modlinkage)) != DDI_SUCCESS) { + return (ret); + } + + mac_fini_ops(&mlxcx_dev_ops); + + ddi_soft_state_fini(&mlxcx_softstate); + + return (DDI_SUCCESS); +} diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.conf b/usr/src/uts/common/io/mlxcx/mlxcx.conf new file mode 100644 index 0000000000..3569c4e5f5 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx.conf @@ -0,0 +1,101 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018, Joyent, Inc. +# Copyright 2020, The University of Queensland +# + +# +# Driver.conf file for Mellanox Connect-X 4/5/6. +# See mlxcx(7D) for valid options. +# + +# +# Sizing of event and completion queues. +# +# The number of entries on each queue will be (1 << *_size_shift) -- so +# a value of 9 would mean 512 entries. +# +#eq_size_shift = 9; +#cq_size_shift = 10; + +# +# Sizing of send and receive queues. +# +# Note that this determines the size of the RX and TX rings that mlxcx will +# advertise to MAC. It also determines how many packet buffers we will allocate +# when starting the interface. +# +#sq_size_shift = 11; +#rq_size_shift = 10; + +# +# Number and configuration of TX groups and rings. +# +#tx_ngroups = 1; +#tx_nrings_per_group = 64; + +# +# Number and configuration of RX groups and rings. +# +#rx_ngroups_large = 2; +#rx_nrings_per_large_group = 16; +#rx_ngroups_small = 256; +#rx_nrings_per_small_group = 4; + +# +# Number of flow table entries allocated to root flow tables. +# +# This places an upper ceiling on how many MAC addresses can be filtered into +# groups across the whole NIC. If you have a lot of VNICs you might want to +# raise this (and probably also rx_ngroups_small). +# +#ftbl_root_size_shift = 12; + +# +# Number of flow table entries allocated to each L1 VLAN filtering table. +# +# This places a limit on the number of VLANs that one MAC address can be +# associated with before falling back to software classification. Two entries +# are always reserved for the non-VLAN catch-all and promisc entries. +# +# Note: illumos MAC today only supports giving a single VLAN per MAC address +# to hardware drivers anyway, so setting this higher is pointless until that +# changes. +# +#ftbl_vlan_size_shift = 4; + +# +# Interrupt and completion moderation. +# +#cqemod_period_usec = 50; +#cqemod_count = <80% of cq_size>; +#intrmod_period_usec = 10; + +# +# Minimum packet size before we use a ddi_dma_bind_addr() rather than bcopy() +# of the packet data. DMA binds are expensive and involve taking locks in the +# PCI nexus driver, so it's seldom worth doing them for small packets. +# +#tx_bind_threshold = 2048; + +# +# Interval between periodic double-checks of queue status against hardware +# state. This is used to detect hardware stalls or errors, as well as guard +# against driver bugs. +# +# If set to too high a frequency, checks may impact NIC performance. Can be +# set to zero to disable periodic checking entirely. +# +#eq_check_interval_sec = 30; +#cq_check_interval_sec = 300; +#wq_check_interval_sec = 300; diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.h b/usr/src/uts/common/io/mlxcx/mlxcx.h new file mode 100644 index 0000000000..3b58989961 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx.h @@ -0,0 +1,1298 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020, The University of Queensland + * Copyright (c) 2018, Joyent, Inc. + */ + +/* + * Mellanox Connect-X 4/5/6 driver. + * + * More details in mlxcx.c + */ + +#ifndef _MLXCX_H +#define _MLXCX_H + +/* + * mlxcx(7D) defintions + */ + +#include <sys/ddi.h> +#include <sys/sunddi.h> +#include <sys/ddifm.h> +#include <sys/id_space.h> +#include <sys/list.h> +#include <sys/stddef.h> +#include <sys/stream.h> +#include <sys/strsun.h> +#include <sys/mac_provider.h> +#include <sys/mac_ether.h> +#include <sys/cpuvar.h> +#include <sys/ethernet.h> + +#include <inet/ip.h> +#include <inet/ip6.h> + +#include <sys/ddifm.h> +#include <sys/fm/protocol.h> +#include <sys/fm/util.h> +#include <sys/fm/io/ddi.h> + +#include <mlxcx_reg.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Get access to the first PCI BAR. + */ +#define MLXCX_REG_NUMBER 1 + +/* + * The command queue is supposed to be a page, which is 4k. + */ +#define MLXCX_CMD_DMA_PAGE_SIZE 4096 + +/* + * Queues can allocate in units of this much memory. + */ +#define MLXCX_QUEUE_DMA_PAGE_SIZE 4096 + +/* + * We advertise two sizes of groups to MAC -- a certain number of "large" + * groups (including the default group, which is sized to at least ncpus) + * followed by a certain number of "small" groups. + * + * This allows us to have a larger amount of classification resources available + * for zones/VMs without resorting to software classification. + */ +#define MLXCX_RX_NGROUPS_LARGE_DFLT 2 +#define MLXCX_RX_NRINGS_PER_LARGE_GROUP_DFLT 16 +#define MLXCX_RX_NGROUPS_SMALL_DFLT 256 +#define MLXCX_RX_NRINGS_PER_SMALL_GROUP_DFLT 4 + +#define MLXCX_TX_NGROUPS_DFLT 1 +#define MLXCX_TX_NRINGS_PER_GROUP_DFLT 64 + +/* + * Queues will be sized to (1 << *Q_SIZE_SHIFT) entries long. + */ +#define MLXCX_EQ_SIZE_SHIFT_DFLT 9 +#define MLXCX_CQ_SIZE_SHIFT_DFLT 10 + +/* + * Default to making SQs bigger than RQs for 9k MTU, since most packets will + * spill over into more than one slot. RQ WQEs are always 1 slot. + */ +#define MLXCX_SQ_SIZE_SHIFT_DFLT 11 +#define MLXCX_RQ_SIZE_SHIFT_DFLT 10 + +#define MLXCX_CQ_HWM_GAP 16 +#define MLXCX_CQ_LWM_GAP 24 + +#define MLXCX_RQ_REFILL_STEP 64 + +/* + * CQ event moderation + */ +#define MLXCX_CQEMOD_PERIOD_USEC_DFLT 50 +#define MLXCX_CQEMOD_COUNT_DFLT \ + (8 * ((1 << MLXCX_CQ_SIZE_SHIFT_DFLT) / 10)) + +/* + * EQ interrupt moderation + */ +#define MLXCX_INTRMOD_PERIOD_USEC_DFLT 10 + +/* Size of root flow tables */ +#define MLXCX_FTBL_ROOT_SIZE_SHIFT_DFLT 12 + +/* Size of 2nd level flow tables for VLAN filtering */ +#define MLXCX_FTBL_VLAN_SIZE_SHIFT_DFLT 4 + +/* + * How big does an mblk have to be before we dma_bind() it instead of + * bcopying? + */ +#define MLXCX_TX_BIND_THRESHOLD_DFLT 2048 + +/* + * How often to check the status of completion queues for overflow and + * other problems. + */ +#define MLXCX_WQ_CHECK_INTERVAL_SEC_DFLT 300 +#define MLXCX_CQ_CHECK_INTERVAL_SEC_DFLT 300 +#define MLXCX_EQ_CHECK_INTERVAL_SEC_DFLT 30 + +#define MLXCX_DOORBELL_TRIES_DFLT 3 +extern uint_t mlxcx_doorbell_tries; + +#define MLXCX_STUCK_INTR_COUNT_DFLT 128 +extern uint_t mlxcx_stuck_intr_count; + +#define MLXCX_BUF_BIND_MAX_ATTEMTPS 50 + +#define MLXCX_MTU_OFFSET \ + (sizeof (struct ether_vlan_header) + ETHERFCSL) + +/* + * This is the current version of the command structure that the driver expects + * to be found in the ISS. + */ +#define MLXCX_CMD_REVISION 5 + +#ifdef DEBUG +#define MLXCX_DMA_SYNC(dma, flag) VERIFY0(ddi_dma_sync( \ + (dma).mxdb_dma_handle, 0, 0, \ + (flag))) +#else +#define MLXCX_DMA_SYNC(dma, flag) (void) ddi_dma_sync( \ + (dma).mxdb_dma_handle, 0, 0, \ + (flag)) +#endif + +#define MLXCX_FM_SERVICE_MLXCX "mlxcx" + +/* + * This macro defines the expected value of the 'Interface Step Sequence ID' + * (issi) which represents the version of the start up and tear down sequence. + * We must check that hardware supports this and tell it which version we're + * using as well. + */ +#define MLXCX_CURRENT_ISSI 1 + +/* + * This is the size of a page that the hardware expects from us when + * manipulating pages. + */ +#define MLXCX_HW_PAGE_SIZE 4096 + +/* + * This is a special lkey value used to terminate a list of scatter pointers. + */ +#define MLXCX_NULL_LKEY 0x100 + +/* + * Forwards + */ +struct mlxcx; +typedef struct mlxcx mlxcx_t; + +typedef enum { + MLXCX_DMABUF_HDL_ALLOC = 1 << 0, + MLXCX_DMABUF_MEM_ALLOC = 1 << 1, + MLXCX_DMABUF_BOUND = 1 << 2, + MLXCX_DMABUF_FOREIGN = 1 << 3, +} mlxcx_dma_buffer_flags_t; + +typedef struct mlxcx_dma_buffer { + mlxcx_dma_buffer_flags_t mxdb_flags; + caddr_t mxdb_va; /* Buffer VA */ + size_t mxdb_len; /* Buffer logical len */ + ddi_acc_handle_t mxdb_acc_handle; + ddi_dma_handle_t mxdb_dma_handle; + uint_t mxdb_ncookies; +} mlxcx_dma_buffer_t; + +typedef struct mlxcx_dev_page { + list_node_t mxdp_list; + avl_node_t mxdp_tree; + uintptr_t mxdp_pa; + mlxcx_dma_buffer_t mxdp_dma; +} mlxcx_dev_page_t; + +/* + * Data structure to keep track of all information related to the command queue. + */ +typedef enum { + MLXCX_CMD_QUEUE_S_IDLE = 1, + MLXCX_CMD_QUEUE_S_BUSY, + MLXCX_CMD_QUEUE_S_BROKEN +} mlxcx_cmd_queue_status_t; + +typedef struct mlxcx_cmd_queue { + kmutex_t mcmd_lock; + kcondvar_t mcmd_cv; + mlxcx_dma_buffer_t mcmd_dma; + mlxcx_cmd_ent_t *mcmd_ent; + + uint8_t mcmd_size_l2; + uint8_t mcmd_stride_l2; + + mlxcx_cmd_queue_status_t mcmd_status; + + ddi_taskq_t *mcmd_taskq; + id_space_t *mcmd_tokens; +} mlxcx_cmd_queue_t; + +typedef struct mlxcd_cmd_mbox { + list_node_t mlbox_node; + mlxcx_dma_buffer_t mlbox_dma; + mlxcx_cmd_mailbox_t *mlbox_data; +} mlxcx_cmd_mbox_t; + +typedef enum { + MLXCX_EQ_ALLOC = 1 << 0, /* dma mem alloc'd, size set */ + MLXCX_EQ_CREATED = 1 << 1, /* CREATE_EQ sent to hw */ + MLXCX_EQ_DESTROYED = 1 << 2, /* DESTROY_EQ sent to hw */ + MLXCX_EQ_ARMED = 1 << 3, /* Armed through the UAR */ + MLXCX_EQ_POLLING = 1 << 4, /* Currently being polled */ +} mlxcx_eventq_state_t; + +typedef struct mlxcx_bf { + kmutex_t mbf_mtx; + uint_t mbf_cnt; + uint_t mbf_even; + uint_t mbf_odd; +} mlxcx_bf_t; + +typedef struct mlxcx_uar { + boolean_t mlu_allocated; + uint_t mlu_num; + uint_t mlu_base; + + volatile uint_t mlu_bfcnt; + mlxcx_bf_t mlu_bf[MLXCX_BF_PER_UAR]; +} mlxcx_uar_t; + +typedef struct mlxcx_pd { + boolean_t mlpd_allocated; + uint32_t mlpd_num; +} mlxcx_pd_t; + +typedef struct mlxcx_tdom { + boolean_t mltd_allocated; + uint32_t mltd_num; +} mlxcx_tdom_t; + +typedef enum { + MLXCX_PORT_VPORT_PROMISC = 1 << 0, +} mlxcx_port_flags_t; + +typedef struct mlxcx_flow_table mlxcx_flow_table_t; +typedef struct mlxcx_flow_group mlxcx_flow_group_t; + +typedef struct { + uint64_t mlps_rx_drops; +} mlxcx_port_stats_t; + +typedef enum { + MLXCX_PORT_INIT = 1 << 0 +} mlxcx_port_init_t; + +typedef struct mlxcx_port { + kmutex_t mlp_mtx; + mlxcx_port_init_t mlp_init; + mlxcx_t *mlp_mlx; + /* + * The mlp_num we have here starts at zero (it's an index), but the + * numbering we have to use for register access starts at 1. We + * currently write mlp_num into the other_vport fields in mlxcx_cmd.c + * (where 0 is a magic number meaning "my vport") so if we ever add + * support for virtualisation features and deal with more than one + * vport, we will probably have to change this. + */ + uint_t mlp_num; + mlxcx_port_flags_t mlp_flags; + uint64_t mlp_guid; + uint8_t mlp_mac_address[ETHERADDRL]; + + uint_t mlp_mtu; + uint_t mlp_max_mtu; + + mlxcx_port_status_t mlp_admin_status; + mlxcx_port_status_t mlp_oper_status; + + boolean_t mlp_autoneg; + mlxcx_eth_proto_t mlp_max_proto; + mlxcx_eth_proto_t mlp_admin_proto; + mlxcx_eth_proto_t mlp_oper_proto; + + mlxcx_eth_inline_mode_t mlp_wqe_min_inline; + + /* Root flow tables */ + mlxcx_flow_table_t *mlp_rx_flow; + mlxcx_flow_table_t *mlp_tx_flow; + + mlxcx_flow_group_t *mlp_promisc; + mlxcx_flow_group_t *mlp_bcast; + mlxcx_flow_group_t *mlp_umcast; + + avl_tree_t mlp_dmac_fe; + + mlxcx_port_stats_t mlp_stats; + + mlxcx_module_status_t mlp_last_modstate; + mlxcx_module_error_type_t mlp_last_moderr; +} mlxcx_port_t; + +typedef enum { + MLXCX_EQ_TYPE_ANY, + MLXCX_EQ_TYPE_RX, + MLXCX_EQ_TYPE_TX +} mlxcx_eventq_type_t; + +typedef struct mlxcx_event_queue { + kmutex_t mleq_mtx; + mlxcx_t *mleq_mlx; + mlxcx_eventq_state_t mleq_state; + mlxcx_eventq_type_t mleq_type; + + mlxcx_dma_buffer_t mleq_dma; + + size_t mleq_entshift; + size_t mleq_nents; + mlxcx_eventq_ent_t *mleq_ent; + uint32_t mleq_cc; /* consumer counter */ + uint32_t mleq_cc_armed; + + uint32_t mleq_events; + + uint32_t mleq_badintrs; + + /* Hardware eq number */ + uint_t mleq_num; + /* Index into the mlxcx_t's interrupts array */ + uint_t mleq_intr_index; + + /* UAR region that has this EQ's doorbell in it */ + mlxcx_uar_t *mleq_uar; + + /* Tree of CQn => mlxcx_completion_queue_t */ + avl_tree_t mleq_cqs; + + uint32_t mleq_check_disarm_cc; + uint_t mleq_check_disarm_cnt; +} mlxcx_event_queue_t; + +typedef enum { + MLXCX_TIS_CREATED = 1 << 0, + MLXCX_TIS_DESTROYED = 1 << 1, +} mlxcx_tis_state_t; + +typedef struct mlxcx_tis { + mlxcx_tis_state_t mltis_state; + list_node_t mltis_entry; + uint_t mltis_num; + mlxcx_tdom_t *mltis_tdom; +} mlxcx_tis_t; + +typedef enum { + MLXCX_BUFFER_INIT, + MLXCX_BUFFER_FREE, + MLXCX_BUFFER_ON_WQ, + MLXCX_BUFFER_ON_LOAN, + MLXCX_BUFFER_ON_CHAIN, +} mlxcx_buffer_state_t; + +typedef struct mlxcx_buf_shard { + list_node_t mlbs_entry; + kmutex_t mlbs_mtx; + list_t mlbs_busy; + list_t mlbs_free; + kcondvar_t mlbs_free_nonempty; +} mlxcx_buf_shard_t; + +typedef struct mlxcx_buffer { + mlxcx_buf_shard_t *mlb_shard; + list_node_t mlb_entry; + list_node_t mlb_cq_entry; + + struct mlxcx_buffer *mlb_tx_head; /* head of tx chain */ + list_t mlb_tx_chain; + list_node_t mlb_tx_chain_entry; + + boolean_t mlb_foreign; + size_t mlb_used; + mblk_t *mlb_tx_mp; + + mlxcx_t *mlb_mlx; + mlxcx_buffer_state_t mlb_state; + uint_t mlb_wqe_index; + mlxcx_dma_buffer_t mlb_dma; + mblk_t *mlb_mp; + frtn_t mlb_frtn; +} mlxcx_buffer_t; + +typedef enum { + MLXCX_CQ_ALLOC = 1 << 0, + MLXCX_CQ_CREATED = 1 << 1, + MLXCX_CQ_DESTROYED = 1 << 2, + MLXCX_CQ_EQAVL = 1 << 3, + MLXCX_CQ_BLOCKED_MAC = 1 << 4, + MLXCX_CQ_TEARDOWN = 1 << 5, + MLXCX_CQ_POLLING = 1 << 6, + MLXCX_CQ_ARMED = 1 << 7, +} mlxcx_completionq_state_t; + +typedef struct mlxcx_work_queue mlxcx_work_queue_t; + +typedef struct mlxcx_completion_queue { + kmutex_t mlcq_mtx; + mlxcx_t *mlcq_mlx; + mlxcx_completionq_state_t mlcq_state; + + mlxcx_port_stats_t *mlcq_stats; + + list_node_t mlcq_entry; + avl_node_t mlcq_eq_entry; + + uint_t mlcq_num; + + mlxcx_work_queue_t *mlcq_wq; + mlxcx_event_queue_t *mlcq_eq; + + /* UAR region that has this CQ's UAR doorbell in it */ + mlxcx_uar_t *mlcq_uar; + + mlxcx_dma_buffer_t mlcq_dma; + + size_t mlcq_entshift; + size_t mlcq_nents; + mlxcx_completionq_ent_t *mlcq_ent; + uint32_t mlcq_cc; /* consumer counter */ + uint32_t mlcq_cc_armed; /* cc at last arm */ + uint32_t mlcq_ec; /* event counter */ + uint32_t mlcq_ec_armed; /* ec at last arm */ + + mlxcx_dma_buffer_t mlcq_doorbell_dma; + mlxcx_completionq_doorbell_t *mlcq_doorbell; + + uint64_t mlcq_bufcnt; + size_t mlcq_bufhwm; + size_t mlcq_buflwm; + list_t mlcq_buffers; + kmutex_t mlcq_bufbmtx; + list_t mlcq_buffers_b; + + uint_t mlcq_check_disarm_cnt; + uint64_t mlcq_check_disarm_cc; + + uint_t mlcq_cqemod_period_usec; + uint_t mlcq_cqemod_count; + + mac_ring_handle_t mlcq_mac_hdl; + uint64_t mlcq_mac_gen; + + boolean_t mlcq_fm_repd_qstate; +} mlxcx_completion_queue_t; + +typedef enum { + MLXCX_WQ_ALLOC = 1 << 0, + MLXCX_WQ_CREATED = 1 << 1, + MLXCX_WQ_STARTED = 1 << 2, + MLXCX_WQ_DESTROYED = 1 << 3, + MLXCX_WQ_TEARDOWN = 1 << 4, + MLXCX_WQ_BUFFERS = 1 << 5, +} mlxcx_workq_state_t; + +typedef enum { + MLXCX_WQ_TYPE_SENDQ = 1, + MLXCX_WQ_TYPE_RECVQ +} mlxcx_workq_type_t; + +typedef struct mlxcx_ring_group mlxcx_ring_group_t; + +struct mlxcx_work_queue { + kmutex_t mlwq_mtx; + mlxcx_t *mlwq_mlx; + mlxcx_workq_type_t mlwq_type; + mlxcx_workq_state_t mlwq_state; + + list_node_t mlwq_entry; + list_node_t mlwq_group_entry; + + mlxcx_ring_group_t *mlwq_group; + + uint_t mlwq_num; + + mlxcx_completion_queue_t *mlwq_cq; + mlxcx_pd_t *mlwq_pd; + + /* Required for send queues */ + mlxcx_tis_t *mlwq_tis; + + /* UAR region that has this WQ's blueflame buffers in it */ + mlxcx_uar_t *mlwq_uar; + + mlxcx_dma_buffer_t mlwq_dma; + + mlxcx_eth_inline_mode_t mlwq_inline_mode; + size_t mlwq_entshift; + size_t mlwq_nents; + /* Discriminate based on mwq_type */ + union { + mlxcx_sendq_ent_t *mlwq_send_ent; + mlxcx_sendq_extra_ent_t *mlwq_send_extra_ent; + mlxcx_recvq_ent_t *mlwq_recv_ent; + mlxcx_sendq_bf_t *mlwq_bf_ent; + }; + uint64_t mlwq_pc; /* producer counter */ + + mlxcx_dma_buffer_t mlwq_doorbell_dma; + mlxcx_workq_doorbell_t *mlwq_doorbell; + + mlxcx_buf_shard_t *mlwq_bufs; + mlxcx_buf_shard_t *mlwq_foreign_bufs; + + boolean_t mlwq_fm_repd_qstate; +}; + +#define MLXCX_RQT_MAX_SIZE 64 + +typedef enum { + MLXCX_RQT_CREATED = 1 << 0, + MLXCX_RQT_DESTROYED = 1 << 1, + MLXCX_RQT_DIRTY = 1 << 2, +} mlxcx_rqtable_state_t; + +typedef struct mlxcx_rqtable { + mlxcx_rqtable_state_t mlrqt_state; + list_node_t mlrqt_entry; + uint_t mlrqt_num; + + size_t mlrqt_max; + size_t mlrqt_used; + + size_t mlrqt_rq_size; + mlxcx_work_queue_t **mlrqt_rq; +} mlxcx_rqtable_t; + +typedef enum { + MLXCX_TIR_CREATED = 1 << 0, + MLXCX_TIR_DESTROYED = 1 << 1, +} mlxcx_tir_state_t; + +typedef struct mlxcx_tir { + mlxcx_tir_state_t mltir_state; + list_node_t mltir_entry; + uint_t mltir_num; + mlxcx_tdom_t *mltir_tdom; + mlxcx_tir_type_t mltir_type; + union { + mlxcx_rqtable_t *mltir_rqtable; + mlxcx_work_queue_t *mltir_rq; + }; + mlxcx_tir_hash_fn_t mltir_hash_fn; + uint8_t mltir_toeplitz_key[40]; + mlxcx_tir_rx_hash_l3_type_t mltir_l3_type; + mlxcx_tir_rx_hash_l4_type_t mltir_l4_type; + mlxcx_tir_rx_hash_fields_t mltir_hash_fields; +} mlxcx_tir_t; + +typedef enum { + MLXCX_FLOW_GROUP_CREATED = 1 << 0, + MLXCX_FLOW_GROUP_BUSY = 1 << 1, + MLXCX_FLOW_GROUP_DESTROYED = 1 << 2, +} mlxcx_flow_group_state_t; + +typedef enum { + MLXCX_FLOW_MATCH_SMAC = 1 << 0, + MLXCX_FLOW_MATCH_DMAC = 1 << 1, + MLXCX_FLOW_MATCH_VLAN = 1 << 2, + MLXCX_FLOW_MATCH_VID = 1 << 3, + MLXCX_FLOW_MATCH_IP_VER = 1 << 4, + MLXCX_FLOW_MATCH_SRCIP = 1 << 5, + MLXCX_FLOW_MATCH_DSTIP = 1 << 6, + MLXCX_FLOW_MATCH_IP_PROTO = 1 << 7, + MLXCX_FLOW_MATCH_SQN = 1 << 8, + MLXCX_FLOW_MATCH_VXLAN = 1 << 9, +} mlxcx_flow_mask_t; + +struct mlxcx_flow_group { + list_node_t mlfg_entry; + list_node_t mlfg_role_entry; + mlxcx_flow_group_state_t mlfg_state; + mlxcx_flow_table_t *mlfg_table; + uint_t mlfg_num; + size_t mlfg_start_idx; + size_t mlfg_size; + size_t mlfg_avail; + list_t mlfg_entries; + mlxcx_flow_mask_t mlfg_mask; +}; + +typedef enum { + MLXCX_FLOW_ENTRY_RESERVED = 1 << 0, + MLXCX_FLOW_ENTRY_CREATED = 1 << 1, + MLXCX_FLOW_ENTRY_DELETED = 1 << 2, + MLXCX_FLOW_ENTRY_DIRTY = 1 << 3, +} mlxcx_flow_entry_state_t; + +typedef struct { + mlxcx_tir_t *mlfed_tir; + mlxcx_flow_table_t *mlfed_flow; +} mlxcx_flow_entry_dest_t; + +typedef struct mlxcx_flow_entry { + list_node_t mlfe_group_entry; + avl_node_t mlfe_dmac_entry; + mlxcx_flow_entry_state_t mlfe_state; + mlxcx_flow_table_t *mlfe_table; + mlxcx_flow_group_t *mlfe_group; + uint_t mlfe_index; + + mlxcx_flow_action_t mlfe_action; + + /* Criteria for match */ + uint8_t mlfe_smac[ETHERADDRL]; + uint8_t mlfe_dmac[ETHERADDRL]; + + mlxcx_vlan_type_t mlfe_vlan_type; + uint16_t mlfe_vid; + + uint_t mlfe_ip_version; + uint8_t mlfe_srcip[IPV6_ADDR_LEN]; + uint8_t mlfe_dstip[IPV6_ADDR_LEN]; + + uint_t mlfe_ip_proto; + uint16_t mlfe_sport; + uint16_t mlfe_dport; + + uint32_t mlfe_sqn; + uint32_t mlfe_vxlan_vni; + + /* Destinations */ + size_t mlfe_ndest; + mlxcx_flow_entry_dest_t mlfe_dest[MLXCX_FLOW_MAX_DESTINATIONS]; + + /* + * mlxcx_group_mac_ts joining this entry to N ring groups + * only used by FEs on the root rx flow table + */ + list_t mlfe_ring_groups; +} mlxcx_flow_entry_t; + +typedef enum { + MLXCX_FLOW_TABLE_CREATED = 1 << 0, + MLXCX_FLOW_TABLE_DESTROYED = 1 << 1, + MLXCX_FLOW_TABLE_ROOT = 1 << 2 +} mlxcx_flow_table_state_t; + +struct mlxcx_flow_table { + kmutex_t mlft_mtx; + mlxcx_flow_table_state_t mlft_state; + uint_t mlft_level; + uint_t mlft_num; + mlxcx_flow_table_type_t mlft_type; + + mlxcx_port_t *mlft_port; + + size_t mlft_entshift; + size_t mlft_nents; + + size_t mlft_entsize; + mlxcx_flow_entry_t *mlft_ent; + + /* First entry not yet claimed by a group */ + size_t mlft_next_ent; + + list_t mlft_groups; +}; + +typedef enum { + MLXCX_GROUP_RX, + MLXCX_GROUP_TX +} mlxcx_group_type_t; + +typedef enum { + MLXCX_GROUP_INIT = 1 << 0, + MLXCX_GROUP_WQS = 1 << 1, + MLXCX_GROUP_TIRTIS = 1 << 2, + MLXCX_GROUP_FLOWS = 1 << 3, + MLXCX_GROUP_RUNNING = 1 << 4, + MLXCX_GROUP_RQT = 1 << 5, +} mlxcx_group_state_t; + +#define MLXCX_RX_HASH_FT_SIZE_SHIFT 4 + +typedef enum { + MLXCX_TIR_ROLE_IPv4 = 0, + MLXCX_TIR_ROLE_IPv6, + MLXCX_TIR_ROLE_TCPv4, + MLXCX_TIR_ROLE_TCPv6, + MLXCX_TIR_ROLE_UDPv4, + MLXCX_TIR_ROLE_UDPv6, + MLXCX_TIR_ROLE_OTHER, + + MLXCX_TIRS_PER_GROUP +} mlxcx_tir_role_t; + +typedef struct { + avl_node_t mlgm_group_entry; + list_node_t mlgm_fe_entry; + mlxcx_ring_group_t *mlgm_group; + uint8_t mlgm_mac[6]; + mlxcx_flow_entry_t *mlgm_fe; +} mlxcx_group_mac_t; + +typedef struct { + list_node_t mlgv_entry; + boolean_t mlgv_tagged; + uint16_t mlgv_vid; + mlxcx_flow_entry_t *mlgv_fe; +} mlxcx_group_vlan_t; + +struct mlxcx_ring_group { + kmutex_t mlg_mtx; + mlxcx_t *mlg_mlx; + mlxcx_group_state_t mlg_state; + mlxcx_group_type_t mlg_type; + + mac_group_handle_t mlg_mac_hdl; + + union { + mlxcx_tis_t mlg_tis; + mlxcx_tir_t mlg_tir[MLXCX_TIRS_PER_GROUP]; + }; + mlxcx_port_t *mlg_port; + + size_t mlg_nwqs; + size_t mlg_wqs_size; + mlxcx_work_queue_t *mlg_wqs; + + mlxcx_rqtable_t *mlg_rqt; + + /* + * Flow table for matching VLAN IDs + */ + mlxcx_flow_table_t *mlg_rx_vlan_ft; + mlxcx_flow_group_t *mlg_rx_vlan_fg; + mlxcx_flow_group_t *mlg_rx_vlan_def_fg; + mlxcx_flow_group_t *mlg_rx_vlan_promisc_fg; + list_t mlg_rx_vlans; + + /* + * Flow table for separating out by protocol before hashing + */ + mlxcx_flow_table_t *mlg_rx_hash_ft; + + /* + * Links to flow entries on the root flow table which are pointing to + * our rx_vlan_ft. + */ + avl_tree_t mlg_rx_macs; +}; + +typedef enum mlxcx_cmd_state { + MLXCX_CMD_S_DONE = 1 << 0, + MLXCX_CMD_S_ERROR = 1 << 1 +} mlxcx_cmd_state_t; + +typedef struct mlxcx_cmd { + struct mlxcx *mlcmd_mlxp; + kmutex_t mlcmd_lock; + kcondvar_t mlcmd_cv; + + uint8_t mlcmd_token; + mlxcx_cmd_op_t mlcmd_op; + + /* + * Command data and extended mailboxes for responses. + */ + const void *mlcmd_in; + uint32_t mlcmd_inlen; + void *mlcmd_out; + uint32_t mlcmd_outlen; + list_t mlcmd_mbox_in; + uint8_t mlcmd_nboxes_in; + list_t mlcmd_mbox_out; + uint8_t mlcmd_nboxes_out; + /* + * Status information. + */ + mlxcx_cmd_state_t mlcmd_state; + uint8_t mlcmd_status; +} mlxcx_cmd_t; + +/* + * Our view of capabilities. + */ +typedef struct mlxcx_hca_cap { + mlxcx_hca_cap_mode_t mhc_mode; + mlxcx_hca_cap_type_t mhc_type; + union { + uint8_t mhc_bulk[MLXCX_HCA_CAP_SIZE]; + mlxcx_hca_cap_general_caps_t mhc_general; + mlxcx_hca_cap_eth_caps_t mhc_eth; + mlxcx_hca_cap_flow_caps_t mhc_flow; + }; +} mlxcx_hca_cap_t; + +typedef struct { + /* Cooked values */ + boolean_t mlc_checksum; + boolean_t mlc_lso; + boolean_t mlc_vxlan; + size_t mlc_max_lso_size; + size_t mlc_max_rqt_size; + + size_t mlc_max_rx_ft_shift; + size_t mlc_max_rx_fe_dest; + size_t mlc_max_rx_flows; + + size_t mlc_max_tir; + + /* Raw caps data */ + mlxcx_hca_cap_t mlc_hca_cur; + mlxcx_hca_cap_t mlc_hca_max; + mlxcx_hca_cap_t mlc_ether_cur; + mlxcx_hca_cap_t mlc_ether_max; + mlxcx_hca_cap_t mlc_nic_flow_cur; + mlxcx_hca_cap_t mlc_nic_flow_max; +} mlxcx_caps_t; + +typedef struct { + uint_t mldp_eq_size_shift; + uint_t mldp_cq_size_shift; + uint_t mldp_rq_size_shift; + uint_t mldp_sq_size_shift; + uint_t mldp_cqemod_period_usec; + uint_t mldp_cqemod_count; + uint_t mldp_intrmod_period_usec; + uint_t mldp_rx_ngroups_large; + uint_t mldp_rx_ngroups_small; + uint_t mldp_rx_nrings_per_large_group; + uint_t mldp_rx_nrings_per_small_group; + uint_t mldp_tx_ngroups; + uint_t mldp_tx_nrings_per_group; + uint_t mldp_ftbl_root_size_shift; + size_t mldp_tx_bind_threshold; + uint_t mldp_ftbl_vlan_size_shift; + uint64_t mldp_eq_check_interval_sec; + uint64_t mldp_cq_check_interval_sec; + uint64_t mldp_wq_check_interval_sec; +} mlxcx_drv_props_t; + +typedef enum { + MLXCX_ATTACH_FM = 1 << 0, + MLXCX_ATTACH_PCI_CONFIG = 1 << 1, + MLXCX_ATTACH_REGS = 1 << 2, + MLXCX_ATTACH_CMD = 1 << 3, + MLXCX_ATTACH_ENABLE_HCA = 1 << 4, + MLXCX_ATTACH_PAGE_LIST = 1 << 5, + MLXCX_ATTACH_INIT_HCA = 1 << 6, + MLXCX_ATTACH_UAR_PD_TD = 1 << 7, + MLXCX_ATTACH_INTRS = 1 << 8, + MLXCX_ATTACH_PORTS = 1 << 9, + MLXCX_ATTACH_MAC_HDL = 1 << 10, + MLXCX_ATTACH_CQS = 1 << 11, + MLXCX_ATTACH_WQS = 1 << 12, + MLXCX_ATTACH_GROUPS = 1 << 13, + MLXCX_ATTACH_BUFS = 1 << 14, + MLXCX_ATTACH_CAPS = 1 << 15, + MLXCX_ATTACH_CHKTIMERS = 1 << 16, +} mlxcx_attach_progress_t; + +struct mlxcx { + /* entry on the mlxcx_glist */ + list_node_t mlx_gentry; + + dev_info_t *mlx_dip; + int mlx_inst; + mlxcx_attach_progress_t mlx_attach; + + mlxcx_drv_props_t mlx_props; + + /* + * Misc. data + */ + uint16_t mlx_fw_maj; + uint16_t mlx_fw_min; + uint16_t mlx_fw_rev; + uint16_t mlx_cmd_rev; + + /* + * Various capabilities of hardware. + */ + mlxcx_caps_t *mlx_caps; + + uint_t mlx_max_sdu; + uint_t mlx_sdu; + + /* + * FM State + */ + int mlx_fm_caps; + + /* + * PCI Data + */ + ddi_acc_handle_t mlx_cfg_handle; + ddi_acc_handle_t mlx_regs_handle; + caddr_t mlx_regs_base; + + /* + * MAC handle + */ + mac_handle_t mlx_mac_hdl; + + /* + * Main command queue for issuing general FW control commands. + */ + mlxcx_cmd_queue_t mlx_cmd; + + /* + * Interrupts + */ + uint_t mlx_intr_pri; + uint_t mlx_intr_type; /* always MSI-X */ + int mlx_intr_count; + size_t mlx_intr_size; /* allocation size */ + ddi_intr_handle_t *mlx_intr_handles; + + /* + * Basic firmware resources which we use for a variety of things. + * The UAR is a reference to a page where CQ and EQ doorbells are + * located. It also holds all the BlueFlame stuff (which we don't + * use). + */ + mlxcx_uar_t mlx_uar; + /* + * The PD (Protection Domain) and TDOM (Transport Domain) are opaque + * entities to us (they're Infiniband constructs we don't actually care + * about) -- we just allocate them and shove their ID numbers in + * whenever we're asked for one. + * + * The "reserved" LKEY is what we should put in queue entries that + * have references to memory to indicate that they're using linear + * addresses (comes from the QUERY_SPECIAL_CONTEXTS cmd). + */ + mlxcx_pd_t mlx_pd; + mlxcx_tdom_t mlx_tdom; + uint_t mlx_rsvd_lkey; + + /* + * Our event queues. These are 1:1 with interrupts. + */ + size_t mlx_eqs_size; /* allocation size */ + mlxcx_event_queue_t *mlx_eqs; + + /* + * Page list. These represent the set of 4k pages we've given to + * hardware. + * + * We can add to this list at the request of hardware from interrupt + * context (the PAGE_REQUEST event), so it's protected by pagemtx. + */ + kmutex_t mlx_pagemtx; + uint_t mlx_npages; + avl_tree_t mlx_pages; + + /* + * Port state + */ + uint_t mlx_nports; + size_t mlx_ports_size; + mlxcx_port_t *mlx_ports; + + /* + * Completion queues (CQs). These are also indexed off the + * event_queue_ts that they each report to. + */ + list_t mlx_cqs; + + uint_t mlx_next_eq; + + /* + * Work queues (WQs). + */ + list_t mlx_wqs; + + /* + * Ring groups + */ + size_t mlx_rx_ngroups; + size_t mlx_rx_groups_size; + mlxcx_ring_group_t *mlx_rx_groups; + + size_t mlx_tx_ngroups; + size_t mlx_tx_groups_size; + mlxcx_ring_group_t *mlx_tx_groups; + + kmem_cache_t *mlx_bufs_cache; + list_t mlx_buf_shards; + + ddi_periodic_t mlx_eq_checktimer; + ddi_periodic_t mlx_cq_checktimer; + ddi_periodic_t mlx_wq_checktimer; +}; + +/* + * Register access + */ +extern uint16_t mlxcx_get16(mlxcx_t *, uintptr_t); +extern uint32_t mlxcx_get32(mlxcx_t *, uintptr_t); +extern uint64_t mlxcx_get64(mlxcx_t *, uintptr_t); + +extern void mlxcx_put32(mlxcx_t *, uintptr_t, uint32_t); +extern void mlxcx_put64(mlxcx_t *, uintptr_t, uint64_t); + +extern void mlxcx_uar_put32(mlxcx_t *, mlxcx_uar_t *, uintptr_t, uint32_t); +extern void mlxcx_uar_put64(mlxcx_t *, mlxcx_uar_t *, uintptr_t, uint64_t); + +/* + * Logging functions. + */ +extern void mlxcx_warn(mlxcx_t *, const char *, ...); +extern void mlxcx_note(mlxcx_t *, const char *, ...); +extern void mlxcx_panic(mlxcx_t *, const char *, ...); + +extern void mlxcx_fm_ereport(mlxcx_t *, const char *); + +extern void mlxcx_check_sq(mlxcx_t *, mlxcx_work_queue_t *); +extern void mlxcx_check_rq(mlxcx_t *, mlxcx_work_queue_t *); + +/* + * DMA Functions + */ +extern void mlxcx_dma_free(mlxcx_dma_buffer_t *); +extern boolean_t mlxcx_dma_alloc(mlxcx_t *, mlxcx_dma_buffer_t *, + ddi_dma_attr_t *, ddi_device_acc_attr_t *, boolean_t, size_t, boolean_t); +extern boolean_t mlxcx_dma_init(mlxcx_t *, mlxcx_dma_buffer_t *, + ddi_dma_attr_t *, boolean_t); +extern boolean_t mlxcx_dma_bind_mblk(mlxcx_t *, mlxcx_dma_buffer_t *, + const mblk_t *, size_t, boolean_t); +extern boolean_t mlxcx_dma_alloc_offset(mlxcx_t *, mlxcx_dma_buffer_t *, + ddi_dma_attr_t *, ddi_device_acc_attr_t *, boolean_t, + size_t, size_t, boolean_t); +extern void mlxcx_dma_unbind(mlxcx_t *, mlxcx_dma_buffer_t *); +extern void mlxcx_dma_acc_attr(mlxcx_t *, ddi_device_acc_attr_t *); +extern void mlxcx_dma_page_attr(mlxcx_t *, ddi_dma_attr_t *); +extern void mlxcx_dma_queue_attr(mlxcx_t *, ddi_dma_attr_t *); +extern void mlxcx_dma_qdbell_attr(mlxcx_t *, ddi_dma_attr_t *); +extern void mlxcx_dma_buf_attr(mlxcx_t *, ddi_dma_attr_t *); + +extern boolean_t mlxcx_give_pages(mlxcx_t *, int32_t); + +static inline const ddi_dma_cookie_t * +mlxcx_dma_cookie_iter(const mlxcx_dma_buffer_t *db, + const ddi_dma_cookie_t *prev) +{ + ASSERT(db->mxdb_flags & MLXCX_DMABUF_BOUND); + return (ddi_dma_cookie_iter(db->mxdb_dma_handle, prev)); +} + +static inline const ddi_dma_cookie_t * +mlxcx_dma_cookie_one(const mlxcx_dma_buffer_t *db) +{ + ASSERT(db->mxdb_flags & MLXCX_DMABUF_BOUND); + return (ddi_dma_cookie_one(db->mxdb_dma_handle)); +} + +/* + * From mlxcx_intr.c + */ +extern boolean_t mlxcx_intr_setup(mlxcx_t *); +extern void mlxcx_intr_teardown(mlxcx_t *); +extern void mlxcx_arm_eq(mlxcx_t *, mlxcx_event_queue_t *); +extern void mlxcx_arm_cq(mlxcx_t *, mlxcx_completion_queue_t *); + +extern mblk_t *mlxcx_rx_poll(mlxcx_t *, mlxcx_completion_queue_t *, size_t); + +/* + * From mlxcx_gld.c + */ +extern boolean_t mlxcx_register_mac(mlxcx_t *); + +/* + * From mlxcx_ring.c + */ +extern boolean_t mlxcx_cq_alloc_dma(mlxcx_t *, mlxcx_completion_queue_t *); +extern void mlxcx_cq_rele_dma(mlxcx_t *, mlxcx_completion_queue_t *); +extern boolean_t mlxcx_wq_alloc_dma(mlxcx_t *, mlxcx_work_queue_t *); +extern void mlxcx_wq_rele_dma(mlxcx_t *, mlxcx_work_queue_t *); + +extern boolean_t mlxcx_buf_create(mlxcx_t *, mlxcx_buf_shard_t *, + mlxcx_buffer_t **); +extern boolean_t mlxcx_buf_create_foreign(mlxcx_t *, mlxcx_buf_shard_t *, + mlxcx_buffer_t **); +extern void mlxcx_buf_take(mlxcx_t *, mlxcx_work_queue_t *, mlxcx_buffer_t **); +extern size_t mlxcx_buf_take_n(mlxcx_t *, mlxcx_work_queue_t *, + mlxcx_buffer_t **, size_t); +extern boolean_t mlxcx_buf_loan(mlxcx_t *, mlxcx_buffer_t *); +extern void mlxcx_buf_return(mlxcx_t *, mlxcx_buffer_t *); +extern void mlxcx_buf_return_chain(mlxcx_t *, mlxcx_buffer_t *, boolean_t); +extern void mlxcx_buf_destroy(mlxcx_t *, mlxcx_buffer_t *); + +extern boolean_t mlxcx_buf_bind_or_copy(mlxcx_t *, mlxcx_work_queue_t *, + mblk_t *, size_t, mlxcx_buffer_t **); + +extern boolean_t mlxcx_rx_group_setup(mlxcx_t *, mlxcx_ring_group_t *); +extern boolean_t mlxcx_tx_group_setup(mlxcx_t *, mlxcx_ring_group_t *); + +extern boolean_t mlxcx_rx_group_start(mlxcx_t *, mlxcx_ring_group_t *); +extern boolean_t mlxcx_tx_ring_start(mlxcx_t *, mlxcx_ring_group_t *, + mlxcx_work_queue_t *); +extern boolean_t mlxcx_rx_ring_start(mlxcx_t *, mlxcx_ring_group_t *, + mlxcx_work_queue_t *); + +extern boolean_t mlxcx_rq_add_buffer(mlxcx_t *, mlxcx_work_queue_t *, + mlxcx_buffer_t *); +extern boolean_t mlxcx_rq_add_buffers(mlxcx_t *, mlxcx_work_queue_t *, + mlxcx_buffer_t **, size_t); +extern boolean_t mlxcx_sq_add_buffer(mlxcx_t *, mlxcx_work_queue_t *, + uint8_t *, size_t, uint32_t, mlxcx_buffer_t *); +extern boolean_t mlxcx_sq_add_nop(mlxcx_t *, mlxcx_work_queue_t *); +extern void mlxcx_rq_refill(mlxcx_t *, mlxcx_work_queue_t *); + +extern void mlxcx_teardown_groups(mlxcx_t *); +extern void mlxcx_wq_teardown(mlxcx_t *, mlxcx_work_queue_t *); +extern void mlxcx_cq_teardown(mlxcx_t *, mlxcx_completion_queue_t *); +extern void mlxcx_teardown_rx_group(mlxcx_t *, mlxcx_ring_group_t *); +extern void mlxcx_teardown_tx_group(mlxcx_t *, mlxcx_ring_group_t *); + +extern void mlxcx_tx_completion(mlxcx_t *, mlxcx_completion_queue_t *, + mlxcx_completionq_ent_t *, mlxcx_buffer_t *); +extern mblk_t *mlxcx_rx_completion(mlxcx_t *, mlxcx_completion_queue_t *, + mlxcx_completionq_ent_t *, mlxcx_buffer_t *); + +extern mlxcx_buf_shard_t *mlxcx_mlbs_create(mlxcx_t *); + +/* + * Flow mgmt + */ +extern boolean_t mlxcx_add_umcast_entry(mlxcx_t *, mlxcx_port_t *, + mlxcx_ring_group_t *, const uint8_t *); +extern boolean_t mlxcx_remove_umcast_entry(mlxcx_t *, mlxcx_port_t *, + mlxcx_ring_group_t *, const uint8_t *); +extern void mlxcx_remove_all_umcast_entries(mlxcx_t *, mlxcx_port_t *, + mlxcx_ring_group_t *); +extern boolean_t mlxcx_setup_flow_group(mlxcx_t *, mlxcx_flow_table_t *, + mlxcx_flow_group_t *); +extern void mlxcx_teardown_flow_table(mlxcx_t *, mlxcx_flow_table_t *); + +extern void mlxcx_remove_all_vlan_entries(mlxcx_t *, mlxcx_ring_group_t *); +extern boolean_t mlxcx_remove_vlan_entry(mlxcx_t *, mlxcx_ring_group_t *, + boolean_t, uint16_t); +extern boolean_t mlxcx_add_vlan_entry(mlxcx_t *, mlxcx_ring_group_t *, + boolean_t, uint16_t); + +/* + * Command functions + */ +extern boolean_t mlxcx_cmd_queue_init(mlxcx_t *); +extern void mlxcx_cmd_queue_fini(mlxcx_t *); + +extern boolean_t mlxcx_cmd_enable_hca(mlxcx_t *); +extern boolean_t mlxcx_cmd_disable_hca(mlxcx_t *); + +extern boolean_t mlxcx_cmd_query_issi(mlxcx_t *, uint_t *); +extern boolean_t mlxcx_cmd_set_issi(mlxcx_t *, uint16_t); + +extern boolean_t mlxcx_cmd_query_pages(mlxcx_t *, uint_t, int32_t *); +extern boolean_t mlxcx_cmd_give_pages(mlxcx_t *, uint_t, int32_t, + mlxcx_dev_page_t **); +extern boolean_t mlxcx_cmd_return_pages(mlxcx_t *, int32_t, uint64_t *, + int32_t *); + +extern boolean_t mlxcx_cmd_query_hca_cap(mlxcx_t *, mlxcx_hca_cap_type_t, + mlxcx_hca_cap_mode_t, mlxcx_hca_cap_t *); + +extern boolean_t mlxcx_cmd_set_driver_version(mlxcx_t *, const char *); + +extern boolean_t mlxcx_cmd_init_hca(mlxcx_t *); +extern boolean_t mlxcx_cmd_teardown_hca(mlxcx_t *); + +extern boolean_t mlxcx_cmd_alloc_uar(mlxcx_t *, mlxcx_uar_t *); +extern boolean_t mlxcx_cmd_dealloc_uar(mlxcx_t *, mlxcx_uar_t *); + +extern boolean_t mlxcx_cmd_alloc_pd(mlxcx_t *, mlxcx_pd_t *); +extern boolean_t mlxcx_cmd_dealloc_pd(mlxcx_t *, mlxcx_pd_t *); + +extern boolean_t mlxcx_cmd_alloc_tdom(mlxcx_t *, mlxcx_tdom_t *); +extern boolean_t mlxcx_cmd_dealloc_tdom(mlxcx_t *, mlxcx_tdom_t *); + +extern boolean_t mlxcx_cmd_create_eq(mlxcx_t *, mlxcx_event_queue_t *); +extern boolean_t mlxcx_cmd_destroy_eq(mlxcx_t *, mlxcx_event_queue_t *); +extern boolean_t mlxcx_cmd_query_eq(mlxcx_t *, mlxcx_event_queue_t *, + mlxcx_eventq_ctx_t *); + +extern boolean_t mlxcx_cmd_create_cq(mlxcx_t *, mlxcx_completion_queue_t *); +extern boolean_t mlxcx_cmd_destroy_cq(mlxcx_t *, mlxcx_completion_queue_t *); +extern boolean_t mlxcx_cmd_query_cq(mlxcx_t *, mlxcx_completion_queue_t *, + mlxcx_completionq_ctx_t *); + +extern boolean_t mlxcx_cmd_create_rq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_start_rq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_stop_rq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_destroy_rq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_query_rq(mlxcx_t *, mlxcx_work_queue_t *, + mlxcx_rq_ctx_t *); + +extern boolean_t mlxcx_cmd_create_tir(mlxcx_t *, mlxcx_tir_t *); +extern boolean_t mlxcx_cmd_destroy_tir(mlxcx_t *, mlxcx_tir_t *); + +extern boolean_t mlxcx_cmd_create_sq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_start_sq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_stop_sq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_destroy_sq(mlxcx_t *, mlxcx_work_queue_t *); +extern boolean_t mlxcx_cmd_query_sq(mlxcx_t *, mlxcx_work_queue_t *, + mlxcx_sq_ctx_t *); + +extern boolean_t mlxcx_cmd_create_tis(mlxcx_t *, mlxcx_tis_t *); +extern boolean_t mlxcx_cmd_destroy_tis(mlxcx_t *, mlxcx_tis_t *); + +extern boolean_t mlxcx_cmd_query_nic_vport_ctx(mlxcx_t *, mlxcx_port_t *); +extern boolean_t mlxcx_cmd_query_special_ctxs(mlxcx_t *); + +extern boolean_t mlxcx_cmd_modify_nic_vport_ctx(mlxcx_t *, mlxcx_port_t *, + mlxcx_modify_nic_vport_ctx_fields_t); + +extern boolean_t mlxcx_cmd_create_flow_table(mlxcx_t *, mlxcx_flow_table_t *); +extern boolean_t mlxcx_cmd_destroy_flow_table(mlxcx_t *, mlxcx_flow_table_t *); +extern boolean_t mlxcx_cmd_set_flow_table_root(mlxcx_t *, mlxcx_flow_table_t *); + +extern boolean_t mlxcx_cmd_create_flow_group(mlxcx_t *, mlxcx_flow_group_t *); +extern boolean_t mlxcx_cmd_set_flow_table_entry(mlxcx_t *, + mlxcx_flow_entry_t *); +extern boolean_t mlxcx_cmd_delete_flow_table_entry(mlxcx_t *, + mlxcx_flow_entry_t *); +extern boolean_t mlxcx_cmd_destroy_flow_group(mlxcx_t *, mlxcx_flow_group_t *); + +extern boolean_t mlxcx_cmd_access_register(mlxcx_t *, mlxcx_cmd_reg_opmod_t, + mlxcx_register_id_t, mlxcx_register_data_t *); +extern boolean_t mlxcx_cmd_query_port_mtu(mlxcx_t *, mlxcx_port_t *); +extern boolean_t mlxcx_cmd_query_port_status(mlxcx_t *, mlxcx_port_t *); +extern boolean_t mlxcx_cmd_query_port_speed(mlxcx_t *, mlxcx_port_t *); + +extern boolean_t mlxcx_cmd_set_port_mtu(mlxcx_t *, mlxcx_port_t *); + +extern boolean_t mlxcx_cmd_create_rqt(mlxcx_t *, mlxcx_rqtable_t *); +extern boolean_t mlxcx_cmd_destroy_rqt(mlxcx_t *, mlxcx_rqtable_t *); + +extern boolean_t mlxcx_cmd_set_int_mod(mlxcx_t *, uint_t, uint_t); + +extern boolean_t mlxcx_cmd_query_module_status(mlxcx_t *, uint_t, + mlxcx_module_status_t *, mlxcx_module_error_type_t *); +extern boolean_t mlxcx_cmd_set_port_led(mlxcx_t *, mlxcx_port_t *, uint16_t); + +/* Comparator for avl_ts */ +extern int mlxcx_cq_compare(const void *, const void *); +extern int mlxcx_dmac_fe_compare(const void *, const void *); +extern int mlxcx_grmac_compare(const void *, const void *); +extern int mlxcx_page_compare(const void *, const void *); + +extern void mlxcx_update_link_state(mlxcx_t *, mlxcx_port_t *); + +extern void mlxcx_eth_proto_to_string(mlxcx_eth_proto_t, char *, size_t); +extern const char *mlxcx_port_status_string(mlxcx_port_status_t); + +extern const char *mlxcx_event_name(mlxcx_event_t); + +#ifdef __cplusplus +} +#endif + +#endif /* _MLXCX_H */ diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c new file mode 100644 index 0000000000..30fb7ca8ef --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c @@ -0,0 +1,3542 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020, The University of Queensland + * Copyright (c) 2018, Joyent, Inc. + */ + +/* + * Controls the management of commands that are issues to and from the HCA + * command queue. + */ + +#include <mlxcx.h> + +#include <sys/debug.h> +#include <sys/sysmacros.h> + +/* + * When we start up the command queue, it will undergo some internal + * initialization after we set the command queue address. These values allow us + * to control how much time we should wait for that to occur. + */ +clock_t mlxcx_cmd_init_delay = 1000 * 10; /* 10 ms in us */ +uint_t mlxcx_cmd_init_trys = 100; /* Wait at most 1s */ + +clock_t mlxcx_cmd_delay = 1000 * 1; /* 1 ms in us */ +uint_t mlxcx_cmd_tries = 5000; /* Wait at most 1s */ + +/* + * This macro is used to identify that we care about our own function that we're + * communicating with. We always use this function. + */ +#define MLXCX_FUNCTION_SELF (to_be16(0)) + +static const char * +mlxcx_cmd_response_string(mlxcx_cmd_ret_t ret) +{ + switch (ret) { + case MLXCX_CMD_R_OK: + return ("MLXCX_CMD_R_OK"); + case MLXCX_CMD_R_INTERNAL_ERR: + return ("MLXCX_CMD_R_INTERNAL_ERR"); + case MLXCX_CMD_R_BAD_OP: + return ("MLXCX_CMD_R_BAD_OP"); + case MLXCX_CMD_R_BAD_PARAM: + return ("MLXCX_CMD_R_BAD_PARAM"); + case MLXCX_CMD_R_BAD_SYS_STATE: + return ("MLXCX_CMD_R_BAD_SYS_STATE"); + case MLXCX_CMD_R_BAD_RESOURCE: + return ("MLXCX_CMD_R_BAD_RESOURCE"); + case MLXCX_CMD_R_RESOURCE_BUSY: + return ("MLXCX_CMD_R_RESOURCE_BUSY"); + case MLXCX_CMD_R_EXCEED_LIM: + return ("MLXCX_CMD_R_EXCEED_LIM"); + case MLXCX_CMD_R_BAD_RES_STATE: + return ("MLXCX_CMD_R_BAD_RES_STATE"); + case MLXCX_CMD_R_BAD_INDEX: + return ("MLXCX_CMD_R_BAD_INDEX"); + case MLXCX_CMD_R_NO_RESOURCES: + return ("MLXCX_CMD_R_NO_RESOURCES"); + case MLXCX_CMD_R_BAD_INPUT_LEN: + return ("MLXCX_CMD_R_BAD_INPUT_LEN"); + case MLXCX_CMD_R_BAD_OUTPUT_LEN: + return ("MLXCX_CMD_R_BAD_OUTPUT_LEN"); + case MLXCX_CMD_R_BAD_RESOURCE_STATE: + return ("MLXCX_CMD_R_BAD_RESOURCE_STATE"); + case MLXCX_CMD_R_BAD_PKT: + return ("MLXCX_CMD_R_BAD_PKT"); + case MLXCX_CMD_R_BAD_SIZE: + return ("MLXCX_CMD_R_BAD_SIZE"); + default: + return ("Unknown command"); + } +} + +static const char * +mlxcx_cmd_opcode_string(mlxcx_cmd_op_t op) +{ + switch (op) { + case MLXCX_OP_QUERY_HCA_CAP: + return ("MLXCX_OP_QUERY_HCA_CAP"); + case MLXCX_OP_QUERY_ADAPTER: + return ("MLXCX_OP_QUERY_ADAPTER"); + case MLXCX_OP_INIT_HCA: + return ("MLXCX_OP_INIT_HCA"); + case MLXCX_OP_TEARDOWN_HCA: + return ("MLXCX_OP_TEARDOWN_HCA"); + case MLXCX_OP_ENABLE_HCA: + return ("MLXCX_OP_ENABLE_HCA"); + case MLXCX_OP_DISABLE_HCA: + return ("MLXCX_OP_DISABLE_HCA"); + case MLXCX_OP_QUERY_PAGES: + return ("MLXCX_OP_QUERY_PAGES"); + case MLXCX_OP_MANAGE_PAGES: + return ("MLXCX_OP_MANAGE_PAGES"); + case MLXCX_OP_SET_HCA_CAP: + return ("MLXCX_OP_SET_HCA_CAP"); + case MLXCX_OP_QUERY_ISSI: + return ("MLXCX_OP_QUERY_ISSI"); + case MLXCX_OP_SET_ISSI: + return ("MLXCX_OP_SET_ISSI"); + case MLXCX_OP_SET_DRIVER_VERSION: + return ("MLXCX_OP_SET_DRIVER_VERSION"); + case MLXCX_OP_QUERY_OTHER_HCA_CAP: + return ("MLXCX_OP_QUERY_OTHER_HCA_CAP"); + case MLXCX_OP_MODIFY_OTHER_HCA_CAP: + return ("MLXCX_OP_MODIFY_OTHER_HCA_CAP"); + case MLXCX_OP_SET_TUNNELED_OPERATIONS: + return ("MLXCX_OP_SET_TUNNELED_OPERATIONS"); + case MLXCX_OP_CREATE_MKEY: + return ("MLXCX_OP_CREATE_MKEY"); + case MLXCX_OP_QUERY_MKEY: + return ("MLXCX_OP_QUERY_MKEY"); + case MLXCX_OP_DESTROY_MKEY: + return ("MLXCX_OP_DESTROY_MKEY"); + case MLXCX_OP_QUERY_SPECIAL_CONTEXTS: + return ("MLXCX_OP_QUERY_SPECIAL_CONTEXTS"); + case MLXCX_OP_PAGE_FAULT_RESUME: + return ("MLXCX_OP_PAGE_FAULT_RESUME"); + case MLXCX_OP_CREATE_EQ: + return ("MLXCX_OP_CREATE_EQ"); + case MLXCX_OP_DESTROY_EQ: + return ("MLXCX_OP_DESTROY_EQ"); + case MLXCX_OP_QUERY_EQ: + return ("MLXCX_OP_QUERY_EQ"); + case MLXCX_OP_GEN_EQE: + return ("MLXCX_OP_GEN_EQE"); + case MLXCX_OP_CREATE_CQ: + return ("MLXCX_OP_CREATE_CQ"); + case MLXCX_OP_DESTROY_CQ: + return ("MLXCX_OP_DESTROY_CQ"); + case MLXCX_OP_QUERY_CQ: + return ("MLXCX_OP_QUERY_CQ"); + case MLXCX_OP_MODIFY_CQ: + return ("MLXCX_OP_MODIFY_CQ"); + case MLXCX_OP_CREATE_QP: + return ("MLXCX_OP_CREATE_QP"); + case MLXCX_OP_DESTROY_QP: + return ("MLXCX_OP_DESTROY_QP"); + case MLXCX_OP_RST2INIT_QP: + return ("MLXCX_OP_RST2INIT_QP"); + case MLXCX_OP_INIT2RTR_QP: + return ("MLXCX_OP_INIT2RTR_QP"); + case MLXCX_OP_RTR2RTS_QP: + return ("MLXCX_OP_RTR2RTS_QP"); + case MLXCX_OP_RTS2RTS_QP: + return ("MLXCX_OP_RTS2RTS_QP"); + case MLXCX_OP_SQERR2RTS_QP: + return ("MLXCX_OP_SQERR2RTS_QP"); + case MLXCX_OP__2ERR_QP: + return ("MLXCX_OP__2ERR_QP"); + case MLXCX_OP__2RST_QP: + return ("MLXCX_OP__2RST_QP"); + case MLXCX_OP_QUERY_QP: + return ("MLXCX_OP_QUERY_QP"); + case MLXCX_OP_SQD_RTS_QP: + return ("MLXCX_OP_SQD_RTS_QP"); + case MLXCX_OP_INIT2INIT_QP: + return ("MLXCX_OP_INIT2INIT_QP"); + case MLXCX_OP_CREATE_PSV: + return ("MLXCX_OP_CREATE_PSV"); + case MLXCX_OP_DESTROY_PSV: + return ("MLXCX_OP_DESTROY_PSV"); + case MLXCX_OP_CREATE_SRQ: + return ("MLXCX_OP_CREATE_SRQ"); + case MLXCX_OP_DESTROY_SRQ: + return ("MLXCX_OP_DESTROY_SRQ"); + case MLXCX_OP_QUERY_SRQ: + return ("MLXCX_OP_QUERY_SRQ"); + case MLXCX_OP_ARM_RQ: + return ("MLXCX_OP_ARM_RQ"); + case MLXCX_OP_CREATE_XRC_SRQ: + return ("MLXCX_OP_CREATE_XRC_SRQ"); + case MLXCX_OP_DESTROY_XRC_SRQ: + return ("MLXCX_OP_DESTROY_XRC_SRQ"); + case MLXCX_OP_QUERY_XRC_SRQ: + return ("MLXCX_OP_QUERY_XRC_SRQ"); + case MLXCX_OP_ARM_XRC_SRQ: + return ("MLXCX_OP_ARM_XRC_SRQ"); + case MLXCX_OP_CREATE_DCT: + return ("MLXCX_OP_CREATE_DCT"); + case MLXCX_OP_DESTROY_DCT: + return ("MLXCX_OP_DESTROY_DCT"); + case MLXCX_OP_DRAIN_DCT: + return ("MLXCX_OP_DRAIN_DCT"); + case MLXCX_OP_QUERY_DCT: + return ("MLXCX_OP_QUERY_DCT"); + case MLXCX_OP_ARM_DCT_FOR_KEY_VIOLATION: + return ("MLXCX_OP_ARM_DCT_FOR_KEY_VIOLATION"); + case MLXCX_OP_CREATE_XRQ: + return ("MLXCX_OP_CREATE_XRQ"); + case MLXCX_OP_DESTROY_XRQ: + return ("MLXCX_OP_DESTROY_XRQ"); + case MLXCX_OP_QUERY_XRQ: + return ("MLXCX_OP_QUERY_XRQ"); + case MLXCX_OP_CREATE_NVMF_BACKEND_CONTROLLER: + return ("MLXCX_OP_CREATE_NVMF_BACKEND_CONTROLLER"); + case MLXCX_OP_DESTROY_NVMF_BACKEND_CONTROLLER: + return ("MLXCX_OP_DESTROY_NVMF_BACKEND_CONTROLLER"); + case MLXCX_OP_QUERY_NVMF_BACKEND_CONTROLLER: + return ("MLXCX_OP_QUERY_NVMF_BACKEND_CONTROLLER"); + case MLXCX_OP_ATTACH_NVMF_NAMESPACE: + return ("MLXCX_OP_ATTACH_NVMF_NAMESPACE"); + case MLXCX_OP_DETACH_NVMF_NAMESPACE: + return ("MLXCX_OP_DETACH_NVMF_NAMESPACE"); + case MLXCX_OP_QUERY_XRQ_DC_PARAMS_ENTRY: + return ("MLXCX_OP_QUERY_XRQ_DC_PARAMS_ENTRY"); + case MLXCX_OP_SET_XRQ_DC_PARAMS_ENTRY: + return ("MLXCX_OP_SET_XRQ_DC_PARAMS_ENTRY"); + case MLXCX_OP_QUERY_XRQ_ERROR_PARAMS: + return ("MLXCX_OP_QUERY_XRQ_ERROR_PARAMS"); + case MLXCX_OP_QUERY_VPORT_STATE: + return ("MLXCX_OP_QUERY_VPORT_STATE"); + case MLXCX_OP_MODIFY_VPORT_STATE: + return ("MLXCX_OP_MODIFY_VPORT_STATE"); + case MLXCX_OP_QUERY_ESW_VPORT_CONTEXT: + return ("MLXCX_OP_QUERY_ESW_VPORT_CONTEXT"); + case MLXCX_OP_MODIFY_ESW_VPORT_CONTEXT: + return ("MLXCX_OP_MODIFY_ESW_VPORT_CONTEXT"); + case MLXCX_OP_QUERY_NIC_VPORT_CONTEXT: + return ("MLXCX_OP_QUERY_NIC_VPORT_CONTEXT"); + case MLXCX_OP_MODIFY_NIC_VPORT_CONTEXT: + return ("MLXCX_OP_MODIFY_NIC_VPORT_CONTEXT"); + case MLXCX_OP_QUERY_ROCE_ADDRESS: + return ("MLXCX_OP_QUERY_ROCE_ADDRESS"); + case MLXCX_OP_SET_ROCE_ADDRESS: + return ("MLXCX_OP_SET_ROCE_ADDRESS"); + case MLXCX_OP_QUERY_HCA_VPORT_CONTEXT: + return ("MLXCX_OP_QUERY_HCA_VPORT_CONTEXT"); + case MLXCX_OP_MODIFY_HCA_VPORT_CONTEXT: + return ("MLXCX_OP_MODIFY_HCA_VPORT_CONTEXT"); + case MLXCX_OP_QUERY_HCA_VPORT_GID: + return ("MLXCX_OP_QUERY_HCA_VPORT_GID"); + case MLXCX_OP_QUERY_HCA_VPORT_PKEY: + return ("MLXCX_OP_QUERY_HCA_VPORT_PKEY"); + case MLXCX_OP_QUERY_VPORT_COUNTER: + return ("MLXCX_OP_QUERY_VPORT_COUNTER"); + case MLXCX_OP_ALLOC_Q_COUNTER: + return ("MLXCX_OP_ALLOC_Q_COUNTER"); + case MLXCX_OP_DEALLOC_Q_COUNTER: + return ("MLXCX_OP_DEALLOC_Q_COUNTER"); + case MLXCX_OP_QUERY_Q_COUNTER: + return ("MLXCX_OP_QUERY_Q_COUNTER"); + case MLXCX_OP_SET_PP_RATE_LIMIT: + return ("MLXCX_OP_SET_PP_RATE_LIMIT"); + case MLXCX_OP_QUERY_PP_RATE_LIMIT: + return ("MLXCX_OP_QUERY_PP_RATE_LIMIT"); + case MLXCX_OP_ALLOC_PD: + return ("MLXCX_OP_ALLOC_PD"); + case MLXCX_OP_DEALLOC_PD: + return ("MLXCX_OP_DEALLOC_PD"); + case MLXCX_OP_ALLOC_UAR: + return ("MLXCX_OP_ALLOC_UAR"); + case MLXCX_OP_DEALLOC_UAR: + return ("MLXCX_OP_DEALLOC_UAR"); + case MLXCX_OP_CONFIG_INT_MODERATION: + return ("MLXCX_OP_CONFIG_INT_MODERATION"); + case MLXCX_OP_ACCESS_REG: + return ("MLXCX_OP_ACCESS_REG"); + case MLXCX_OP_ATTACH_TO_MCG: + return ("MLXCX_OP_ATTACH_TO_MCG"); + case MLXCX_OP_DETACH_FROM_MCG: + return ("MLXCX_OP_DETACH_FROM_MCG"); + case MLXCX_OP_MAD_IFC: + return ("MLXCX_OP_MAD_IFC"); + case MLXCX_OP_QUERY_MAD_DEMUX: + return ("MLXCX_OP_QUERY_MAD_DEMUX"); + case MLXCX_OP_SET_MAD_DEMUX: + return ("MLXCX_OP_SET_MAD_DEMUX"); + case MLXCX_OP_NOP: + return ("MLXCX_OP_NOP"); + case MLXCX_OP_ALLOC_XRCD: + return ("MLXCX_OP_ALLOC_XRCD"); + case MLXCX_OP_DEALLOC_XRCD: + return ("MLXCX_OP_DEALLOC_XRCD"); + case MLXCX_OP_ALLOC_TRANSPORT_DOMAIN: + return ("MLXCX_OP_ALLOC_TRANSPORT_DOMAIN"); + case MLXCX_OP_DEALLOC_TRANSPORT_DOMAIN: + return ("MLXCX_OP_DEALLOC_TRANSPORT_DOMAIN"); + case MLXCX_OP_QUERY_CONG_STATUS: + return ("MLXCX_OP_QUERY_CONG_STATUS"); + case MLXCX_OP_MODIFY_CONG_STATUS: + return ("MLXCX_OP_MODIFY_CONG_STATUS"); + case MLXCX_OP_QUERY_CONG_PARAMS: + return ("MLXCX_OP_QUERY_CONG_PARAMS"); + case MLXCX_OP_MODIFY_CONG_PARAMS: + return ("MLXCX_OP_MODIFY_CONG_PARAMS"); + case MLXCX_OP_QUERY_CONG_STATISTICS: + return ("MLXCX_OP_QUERY_CONG_STATISTICS"); + case MLXCX_OP_ADD_VXLAN_UDP_DPORT: + return ("MLXCX_OP_ADD_VXLAN_UDP_DPORT"); + case MLXCX_OP_DELETE_VXLAN_UDP_DPORT: + return ("MLXCX_OP_DELETE_VXLAN_UDP_DPORT"); + case MLXCX_OP_SET_L2_TABLE_ENTRY: + return ("MLXCX_OP_SET_L2_TABLE_ENTRY"); + case MLXCX_OP_QUERY_L2_TABLE_ENTRY: + return ("MLXCX_OP_QUERY_L2_TABLE_ENTRY"); + case MLXCX_OP_DELETE_L2_TABLE_ENTRY: + return ("MLXCX_OP_DELETE_L2_TABLE_ENTRY"); + case MLXCX_OP_SET_WOL_ROL: + return ("MLXCX_OP_SET_WOL_ROL"); + case MLXCX_OP_QUERY_WOL_ROL: + return ("MLXCX_OP_QUERY_WOL_ROL"); + case MLXCX_OP_CREATE_TIR: + return ("MLXCX_OP_CREATE_TIR"); + case MLXCX_OP_MODIFY_TIR: + return ("MLXCX_OP_MODIFY_TIR"); + case MLXCX_OP_DESTROY_TIR: + return ("MLXCX_OP_DESTROY_TIR"); + case MLXCX_OP_QUERY_TIR: + return ("MLXCX_OP_QUERY_TIR"); + case MLXCX_OP_CREATE_SQ: + return ("MLXCX_OP_CREATE_SQ"); + case MLXCX_OP_MODIFY_SQ: + return ("MLXCX_OP_MODIFY_SQ"); + case MLXCX_OP_DESTROY_SQ: + return ("MLXCX_OP_DESTROY_SQ"); + case MLXCX_OP_QUERY_SQ: + return ("MLXCX_OP_QUERY_SQ"); + case MLXCX_OP_CREATE_RQ: + return ("MLXCX_OP_CREATE_RQ"); + case MLXCX_OP_MODIFY_RQ: + return ("MLXCX_OP_MODIFY_RQ"); + case MLXCX_OP_DESTROY_RQ: + return ("MLXCX_OP_DESTROY_RQ"); + case MLXCX_OP_QUERY_RQ: + return ("MLXCX_OP_QUERY_RQ"); + case MLXCX_OP_CREATE_RMP: + return ("MLXCX_OP_CREATE_RMP"); + case MLXCX_OP_MODIFY_RMP: + return ("MLXCX_OP_MODIFY_RMP"); + case MLXCX_OP_DESTROY_RMP: + return ("MLXCX_OP_DESTROY_RMP"); + case MLXCX_OP_QUERY_RMP: + return ("MLXCX_OP_QUERY_RMP"); + case MLXCX_OP_CREATE_TIS: + return ("MLXCX_OP_CREATE_TIS"); + case MLXCX_OP_MODIFY_TIS: + return ("MLXCX_OP_MODIFY_TIS"); + case MLXCX_OP_DESTROY_TIS: + return ("MLXCX_OP_DESTROY_TIS"); + case MLXCX_OP_QUERY_TIS: + return ("MLXCX_OP_QUERY_TIS"); + case MLXCX_OP_CREATE_RQT: + return ("MLXCX_OP_CREATE_RQT"); + case MLXCX_OP_MODIFY_RQT: + return ("MLXCX_OP_MODIFY_RQT"); + case MLXCX_OP_DESTROY_RQT: + return ("MLXCX_OP_DESTROY_RQT"); + case MLXCX_OP_QUERY_RQT: + return ("MLXCX_OP_QUERY_RQT"); + case MLXCX_OP_SET_FLOW_TABLE_ROOT: + return ("MLXCX_OP_SET_FLOW_TABLE_ROOT"); + case MLXCX_OP_CREATE_FLOW_TABLE: + return ("MLXCX_OP_CREATE_FLOW_TABLE"); + case MLXCX_OP_DESTROY_FLOW_TABLE: + return ("MLXCX_OP_DESTROY_FLOW_TABLE"); + case MLXCX_OP_QUERY_FLOW_TABLE: + return ("MLXCX_OP_QUERY_FLOW_TABLE"); + case MLXCX_OP_CREATE_FLOW_GROUP: + return ("MLXCX_OP_CREATE_FLOW_GROUP"); + case MLXCX_OP_DESTROY_FLOW_GROUP: + return ("MLXCX_OP_DESTROY_FLOW_GROUP"); + case MLXCX_OP_QUERY_FLOW_GROUP: + return ("MLXCX_OP_QUERY_FLOW_GROUP"); + case MLXCX_OP_SET_FLOW_TABLE_ENTRY: + return ("MLXCX_OP_SET_FLOW_TABLE_ENTRY"); + case MLXCX_OP_QUERY_FLOW_TABLE_ENTRY: + return ("MLXCX_OP_QUERY_FLOW_TABLE_ENTRY"); + case MLXCX_OP_DELETE_FLOW_TABLE_ENTRY: + return ("MLXCX_OP_DELETE_FLOW_TABLE_ENTRY"); + case MLXCX_OP_ALLOC_FLOW_COUNTER: + return ("MLXCX_OP_ALLOC_FLOW_COUNTER"); + case MLXCX_OP_DEALLOC_FLOW_COUNTER: + return ("MLXCX_OP_DEALLOC_FLOW_COUNTER"); + case MLXCX_OP_QUERY_FLOW_COUNTER: + return ("MLXCX_OP_QUERY_FLOW_COUNTER"); + case MLXCX_OP_MODIFY_FLOW_TABLE: + return ("MLXCX_OP_MODIFY_FLOW_TABLE"); + case MLXCX_OP_ALLOC_ENCAP_HEADER: + return ("MLXCX_OP_ALLOC_ENCAP_HEADER"); + case MLXCX_OP_DEALLOC_ENCAP_HEADER: + return ("MLXCX_OP_DEALLOC_ENCAP_HEADER"); + case MLXCX_OP_QUERY_ENCAP_HEADER: + return ("MLXCX_OP_QUERY_ENCAP_HEADER"); + default: + return ("Unknown Opcode"); + } +} + +const char * +mlxcx_port_status_string(mlxcx_port_status_t st) +{ + switch (st) { + case MLXCX_PORT_STATUS_UP: + return ("UP"); + case MLXCX_PORT_STATUS_DOWN: + return ("DOWN"); + case MLXCX_PORT_STATUS_UP_ONCE: + return ("UP_ONCE"); + case MLXCX_PORT_STATUS_DISABLED: + return ("DISABLED"); + default: + return ("UNKNOWN"); + } +} + +void +mlxcx_eth_proto_to_string(mlxcx_eth_proto_t p, char *buf, size_t size) +{ + if (p & MLXCX_PROTO_SGMII) + (void) strlcat(buf, "SGMII|", size); + if (p & MLXCX_PROTO_1000BASE_KX) + (void) strlcat(buf, "1000BASE_KX|", size); + if (p & MLXCX_PROTO_10GBASE_CX4) + (void) strlcat(buf, "10GBASE_CX4|", size); + if (p & MLXCX_PROTO_10GBASE_KX4) + (void) strlcat(buf, "10GBASE_KX4|", size); + if (p & MLXCX_PROTO_10GBASE_KR) + (void) strlcat(buf, "10GBASE_KR|", size); + if (p & MLXCX_PROTO_40GBASE_CR4) + (void) strlcat(buf, "40GBASE_CR4|", size); + if (p & MLXCX_PROTO_40GBASE_KR4) + (void) strlcat(buf, "40GBASE_KR4|", size); + if (p & MLXCX_PROTO_SGMII_100BASE) + (void) strlcat(buf, "SGMII_100BASE|", size); + if (p & MLXCX_PROTO_10GBASE_CR) + (void) strlcat(buf, "10GBASE_CR|", size); + if (p & MLXCX_PROTO_10GBASE_SR) + (void) strlcat(buf, "10GBASE_SR|", size); + if (p & MLXCX_PROTO_10GBASE_ER_LR) + (void) strlcat(buf, "10GBASE_ER_LR|", size); + if (p & MLXCX_PROTO_40GBASE_SR4) + (void) strlcat(buf, "40GBASE_SR4|", size); + if (p & MLXCX_PROTO_40GBASE_LR4_ER4) + (void) strlcat(buf, "40GBASE_LR4_ER4|", size); + if (p & MLXCX_PROTO_50GBASE_SR2) + (void) strlcat(buf, "50GBASE_SR2|", size); + if (p & MLXCX_PROTO_100GBASE_CR4) + (void) strlcat(buf, "100GBASE_CR4|", size); + if (p & MLXCX_PROTO_100GBASE_SR4) + (void) strlcat(buf, "100GBASE_SR4|", size); + if (p & MLXCX_PROTO_100GBASE_KR4) + (void) strlcat(buf, "100GBASE_KR4|", size); + if (p & MLXCX_PROTO_25GBASE_CR) + (void) strlcat(buf, "25GBASE_CR|", size); + if (p & MLXCX_PROTO_25GBASE_KR) + (void) strlcat(buf, "25GBASE_KR|", size); + if (p & MLXCX_PROTO_25GBASE_SR) + (void) strlcat(buf, "25GBASE_SR|", size); + if (p & MLXCX_PROTO_50GBASE_CR2) + (void) strlcat(buf, "50GBASE_CR2|", size); + /* Chop off the trailing '|' */ + if (strlen(buf) > 0) + buf[strlen(buf) - 1] = '\0'; +} + +void +mlxcx_cmd_queue_fini(mlxcx_t *mlxp) +{ + mlxcx_cmd_queue_t *cmd = &mlxp->mlx_cmd; + + mutex_enter(&cmd->mcmd_lock); + VERIFY3S(cmd->mcmd_status, ==, MLXCX_CMD_QUEUE_S_IDLE); + mutex_exit(&cmd->mcmd_lock); + + if (cmd->mcmd_tokens != NULL) { + id_space_destroy(cmd->mcmd_tokens); + cmd->mcmd_tokens = NULL; + } + + if (cmd->mcmd_taskq != NULL) { + ddi_taskq_destroy(cmd->mcmd_taskq); + cmd->mcmd_taskq = NULL; + } + + cv_destroy(&cmd->mcmd_cv); + mutex_destroy(&cmd->mcmd_lock); + + cmd->mcmd_ent = NULL; + mlxcx_dma_free(&cmd->mcmd_dma); +} + +boolean_t +mlxcx_cmd_queue_init(mlxcx_t *mlxp) +{ + uint32_t tmp, cmd_low, cmd_high, i; + mlxcx_cmd_queue_t *cmd = &mlxp->mlx_cmd; + char buf[64]; + const ddi_dma_cookie_t *ck; + + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + + tmp = mlxcx_get32(mlxp, MLXCX_ISS_FIRMWARE); + mlxp->mlx_fw_maj = MLXCX_ISS_FW_MAJOR(tmp); + mlxp->mlx_fw_min = MLXCX_ISS_FW_MINOR(tmp); + + tmp = mlxcx_get32(mlxp, MLXCX_ISS_FW_CMD); + mlxp->mlx_fw_rev = MLXCX_ISS_FW_REV(tmp); + mlxp->mlx_cmd_rev = MLXCX_ISS_CMD_REV(tmp); + + if (mlxp->mlx_cmd_rev != MLXCX_CMD_REVISION) { + mlxcx_warn(mlxp, "found unsupported command revision: %u, " + "expected %u", mlxp->mlx_cmd_rev, MLXCX_CMD_REVISION); + return (B_FALSE); + } + + cmd_low = mlxcx_get32(mlxp, MLXCX_ISS_CMD_LOW); + cmd->mcmd_size_l2 = MLXCX_ISS_CMDQ_SIZE(cmd_low); + cmd->mcmd_stride_l2 = MLXCX_ISS_CMDQ_STRIDE(cmd_low); + + mutex_init(&cmd->mcmd_lock, NULL, MUTEX_DRIVER, NULL); + cv_init(&cmd->mcmd_cv, NULL, CV_DRIVER, NULL); + cmd->mcmd_status = MLXCX_CMD_QUEUE_S_IDLE; + + (void) snprintf(buf, sizeof (buf), "mlxcx_tokens_%d", mlxp->mlx_inst); + if ((cmd->mcmd_tokens = id_space_create(buf, 1, UINT8_MAX)) == NULL) { + mlxcx_warn(mlxp, "failed to allocate token id space"); + mlxcx_cmd_queue_fini(mlxp); + return (B_FALSE); + } + + (void) snprintf(buf, sizeof (buf), "mlxcx_cmdq_%d", mlxp->mlx_inst); + if ((cmd->mcmd_taskq = ddi_taskq_create(mlxp->mlx_dip, buf, 1, + TASKQ_DEFAULTPRI, 0)) == NULL) { + mlxcx_warn(mlxp, "failed to create command queue task queue"); + mlxcx_cmd_queue_fini(mlxp); + return (B_FALSE); + } + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_page_attr(mlxp, &attr); + + if (!mlxcx_dma_alloc(mlxp, &cmd->mcmd_dma, &attr, &acc, B_TRUE, + MLXCX_CMD_DMA_PAGE_SIZE, B_TRUE)) { + mlxcx_warn(mlxp, "failed to allocate command dma buffer"); + mlxcx_cmd_queue_fini(mlxp); + return (B_FALSE); + } + + ck = mlxcx_dma_cookie_one(&cmd->mcmd_dma); + cmd_high = (uint32_t)(ck->dmac_laddress >> 32); + cmd_low = (uint32_t)(ck->dmac_laddress & UINT32_MAX); + + mlxcx_put32(mlxp, MLXCX_ISS_CMD_HIGH, cmd_high); + mlxcx_put32(mlxp, MLXCX_ISS_CMD_LOW, cmd_low); + + /* + * Before this is ready, the initializing bit must become zero. + */ + for (i = 0; i < mlxcx_cmd_init_trys; i++) { + uint32_t init = mlxcx_get32(mlxp, MLXCX_ISS_INIT); + + if (MLXCX_ISS_INITIALIZING(init) == 0) + break; + delay(drv_usectohz(mlxcx_cmd_init_delay)); + } + if (i == mlxcx_cmd_init_trys) { + mlxcx_warn(mlxp, "timed out initializing command queue"); + mlxcx_cmd_queue_fini(mlxp); + return (B_FALSE); + } + + cmd->mcmd_ent = (void *)cmd->mcmd_dma.mxdb_va; + + return (B_TRUE); +} + +static void +mlxcx_cmd_in_header_init(mlxcx_cmd_t *cmd, mlxcx_cmd_in_t *in, + mlxcx_cmd_op_t op, uint16_t mod) +{ + ASSERT3U(op, <=, UINT16_MAX); + in->mci_opcode = to_be16(op); + in->mci_op_mod = to_be16(mod); + cmd->mlcmd_op = op; +} + +static boolean_t +mlxcx_cmd_mbox_alloc(mlxcx_t *mlxp, list_t *listp, uint8_t nblocks) +{ + uint8_t i; + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_page_attr(mlxp, &attr); + + for (i = 0; i < nblocks; i++) { + mlxcx_cmd_mbox_t *mbox; + + mbox = kmem_zalloc(sizeof (*mbox), KM_SLEEP); + if (!mlxcx_dma_alloc(mlxp, &mbox->mlbox_dma, &attr, &acc, + B_TRUE, sizeof (mlxcx_cmd_mailbox_t), B_TRUE)) { + mlxcx_warn(mlxp, "failed to allocate mailbox dma " + "buffer"); + kmem_free(mbox, sizeof (*mbox)); + /* + * mlxcx_cmd_fini will clean up any mboxes that we + * already placed onto listp. + */ + return (B_FALSE); + } + mbox->mlbox_data = (void *)mbox->mlbox_dma.mxdb_va; + list_insert_tail(listp, mbox); + } + + return (B_TRUE); +} + +static void +mlxcx_cmd_mbox_free(mlxcx_cmd_mbox_t *mbox) +{ + mlxcx_dma_free(&mbox->mlbox_dma); + kmem_free(mbox, sizeof (mlxcx_cmd_mbox_t)); +} + +static void +mlxcx_cmd_fini(mlxcx_t *mlxp, mlxcx_cmd_t *cmd) +{ + mlxcx_cmd_mbox_t *mbox; + + while ((mbox = list_remove_head(&cmd->mlcmd_mbox_out)) != NULL) { + mlxcx_cmd_mbox_free(mbox); + } + list_destroy(&cmd->mlcmd_mbox_out); + while ((mbox = list_remove_head(&cmd->mlcmd_mbox_in)) != NULL) { + mlxcx_cmd_mbox_free(mbox); + } + list_destroy(&cmd->mlcmd_mbox_in); + id_free(mlxp->mlx_cmd.mcmd_tokens, cmd->mlcmd_token); + cv_destroy(&cmd->mlcmd_cv); + mutex_destroy(&cmd->mlcmd_lock); +} + +static void +mlxcx_cmd_init(mlxcx_t *mlxp, mlxcx_cmd_t *cmd) +{ + bzero(cmd, sizeof (*cmd)); + mutex_init(&cmd->mlcmd_lock, NULL, MUTEX_DRIVER, NULL); + cv_init(&cmd->mlcmd_cv, NULL, CV_DRIVER, NULL); + cmd->mlcmd_token = id_alloc(mlxp->mlx_cmd.mcmd_tokens); + list_create(&cmd->mlcmd_mbox_in, sizeof (mlxcx_cmd_mbox_t), + offsetof(mlxcx_cmd_mbox_t, mlbox_node)); + list_create(&cmd->mlcmd_mbox_out, sizeof (mlxcx_cmd_mbox_t), + offsetof(mlxcx_cmd_mbox_t, mlbox_node)); +} + +static void +mlxcx_cmd_prep_input(mlxcx_cmd_ent_t *ent, mlxcx_cmd_t *cmd) +{ + uint32_t rem = cmd->mlcmd_inlen; + uint8_t i; + const void *in = cmd->mlcmd_in; + uint32_t copy; + mlxcx_cmd_mbox_t *mbox; + const ddi_dma_cookie_t *ck; + + copy = MIN(MLXCX_CMD_INLINE_INPUT_LEN, rem); + bcopy(in, ent->mce_input, copy); + + rem -= copy; + in += copy; + + if (rem == 0) { + ent->mce_in_mbox = to_be64(0); + VERIFY3U(cmd->mlcmd_nboxes_in, ==, 0); + return; + } + + mbox = list_head(&cmd->mlcmd_mbox_in); + ck = mlxcx_dma_cookie_one(&mbox->mlbox_dma); + ent->mce_in_mbox = to_be64(ck->dmac_laddress); + for (i = 0; mbox != NULL; + mbox = list_next(&cmd->mlcmd_mbox_in, mbox), i++) { + mlxcx_cmd_mbox_t *next; + mlxcx_cmd_mailbox_t *mp = mbox->mlbox_data; + + copy = MIN(MLXCX_CMD_MAILBOX_LEN, rem); + bcopy(in, mp->mlxb_data, copy); + rem -= copy; + in += copy; + + mp->mlxb_token = cmd->mlcmd_token; + mp->mlxb_blockno = to_be32(i); + + next = list_next(&cmd->mlcmd_mbox_in, mbox); + if (next == NULL) { + mp->mlxb_nextp = to_be64(0); + } else { + ck = mlxcx_dma_cookie_one(&next->mlbox_dma); + mp->mlxb_nextp = to_be64(ck->dmac_laddress); + } + MLXCX_DMA_SYNC(mbox->mlbox_dma, DDI_DMA_SYNC_FORDEV); + } + VERIFY3U(i, ==, cmd->mlcmd_nboxes_in); + VERIFY0(rem); +} + +static void +mlxcx_cmd_prep_output(mlxcx_cmd_ent_t *ent, mlxcx_cmd_t *cmd) +{ + uint8_t i; + mlxcx_cmd_mbox_t *mbox; + const ddi_dma_cookie_t *ck; + + if (cmd->mlcmd_nboxes_out == 0) { + ent->mce_out_mbox = to_be64(0); + return; + } + + mbox = list_head(&cmd->mlcmd_mbox_out); + ck = mlxcx_dma_cookie_one(&mbox->mlbox_dma); + ent->mce_out_mbox = to_be64(ck->dmac_laddress); + for (i = 0, mbox = list_head(&cmd->mlcmd_mbox_out); mbox != NULL; + mbox = list_next(&cmd->mlcmd_mbox_out, mbox), i++) { + mlxcx_cmd_mbox_t *next; + mlxcx_cmd_mailbox_t *mp = mbox->mlbox_data; + + mp->mlxb_token = cmd->mlcmd_token; + mp->mlxb_blockno = to_be32(i); + + next = list_next(&cmd->mlcmd_mbox_out, mbox); + if (next == NULL) { + mp->mlxb_nextp = to_be64(0); + } else { + ck = mlxcx_dma_cookie_one(&next->mlbox_dma); + mp->mlxb_nextp = to_be64(ck->dmac_laddress); + } + MLXCX_DMA_SYNC(mbox->mlbox_dma, DDI_DMA_SYNC_FORDEV); + } + VERIFY3U(i, ==, cmd->mlcmd_nboxes_out); +} + +static void +mlxcx_cmd_copy_output(mlxcx_cmd_ent_t *ent, mlxcx_cmd_t *cmd) +{ + void *out = cmd->mlcmd_out; + uint32_t rem = cmd->mlcmd_outlen; + uint32_t copy; + mlxcx_cmd_mbox_t *mbox; + + copy = MIN(rem, MLXCX_CMD_INLINE_OUTPUT_LEN); + bcopy(ent->mce_output, out, copy); + out += copy; + rem -= copy; + + if (rem == 0) { + VERIFY0(cmd->mlcmd_nboxes_out); + return; + } + + for (mbox = list_head(&cmd->mlcmd_mbox_out); mbox != NULL; + mbox = list_next(&cmd->mlcmd_mbox_out, mbox)) { + MLXCX_DMA_SYNC(mbox->mlbox_dma, DDI_DMA_SYNC_FORKERNEL); + copy = MIN(MLXCX_CMD_MAILBOX_LEN, rem); + bcopy(mbox->mlbox_data->mlxb_data, out, copy); + out += copy; + rem -= copy; + } + VERIFY0(rem); +} + +static void +mlxcx_cmd_taskq(void *arg) +{ + mlxcx_cmd_t *cmd = arg; + mlxcx_t *mlxp = cmd->mlcmd_mlxp; + mlxcx_cmd_queue_t *cmdq = &mlxp->mlx_cmd; + mlxcx_cmd_ent_t *ent; + uint_t poll; + + ASSERT3S(cmd->mlcmd_op, !=, 0); + + mutex_enter(&cmdq->mcmd_lock); + while (cmdq->mcmd_status == MLXCX_CMD_QUEUE_S_BUSY) { + cv_wait(&cmdq->mcmd_cv, &cmdq->mcmd_lock); + } + + if (cmdq->mcmd_status != MLXCX_CMD_QUEUE_S_IDLE) { + mutex_exit(&cmdq->mcmd_lock); + + mutex_enter(&cmd->mlcmd_lock); + cmd->mlcmd_state = MLXCX_CMD_S_ERROR; + cv_broadcast(&cmd->mlcmd_cv); + mutex_exit(&cmd->mlcmd_lock); + return; + } + + cmdq->mcmd_status = MLXCX_CMD_QUEUE_S_BUSY; + ent = cmdq->mcmd_ent; + mutex_exit(&cmdq->mcmd_lock); + + /* + * Command queue is currently ours as we set busy. + */ + bzero(ent, sizeof (*ent)); + ent->mce_type = MLXCX_CMD_TRANSPORT_PCI; + ent->mce_in_length = to_be32(cmd->mlcmd_inlen); + ent->mce_out_length = to_be32(cmd->mlcmd_outlen); + ent->mce_token = cmd->mlcmd_token; + ent->mce_sig = 0; + ent->mce_status = MLXCX_CMD_HW_OWNED; + mlxcx_cmd_prep_input(ent, cmd); + mlxcx_cmd_prep_output(ent, cmd); + MLXCX_DMA_SYNC(cmdq->mcmd_dma, DDI_DMA_SYNC_FORDEV); + + /* This assumes we only ever use the first command */ + mlxcx_put32(mlxp, MLXCX_ISS_CMD_DOORBELL, 1); + + for (poll = 0; poll < mlxcx_cmd_tries; poll++) { + delay(drv_usectohz(mlxcx_cmd_delay)); + MLXCX_DMA_SYNC(cmdq->mcmd_dma, DDI_DMA_SYNC_FORKERNEL); + if ((ent->mce_status & MLXCX_CMD_HW_OWNED) == 0) + break; + } + + /* + * Command is done (or timed out). Save relevant data. Once we broadcast + * on the CV and drop the lock, we must not touch the cmd again. + */ + mutex_enter(&cmd->mlcmd_lock); + + if (poll == mlxcx_cmd_tries) { + cmd->mlcmd_status = MLXCX_CMD_R_TIMEOUT; + cmd->mlcmd_state = MLXCX_CMD_S_ERROR; + mlxcx_fm_ereport(mlxp, DDI_FM_DEVICE_NO_RESPONSE); + } else { + cmd->mlcmd_status = MLXCX_CMD_STATUS(ent->mce_status); + cmd->mlcmd_state = MLXCX_CMD_S_DONE; + if (cmd->mlcmd_status == 0) { + mlxcx_cmd_copy_output(ent, cmd); + } + } + cv_broadcast(&cmd->mlcmd_cv); + mutex_exit(&cmd->mlcmd_lock); + + mutex_enter(&cmdq->mcmd_lock); + cmdq->mcmd_status = MLXCX_CMD_QUEUE_S_IDLE; + cv_broadcast(&cmdq->mcmd_cv); + mutex_exit(&cmdq->mcmd_lock); +} + +static boolean_t +mlxcx_cmd_send(mlxcx_t *mlxp, mlxcx_cmd_t *cmd, const void *in, uint32_t inlen, + void *out, uint32_t outlen) +{ + if (inlen > MLXCX_CMD_INLINE_INPUT_LEN) { + uint32_t need = inlen - MLXCX_CMD_INLINE_INPUT_LEN; + uint8_t nblocks; + + if (need / MLXCX_CMD_MAILBOX_LEN + 1 > UINT8_MAX) { + mlxcx_warn(mlxp, "requested too many input blocks for " + "%u byte input len", inlen); + return (B_FALSE); + } + + nblocks = need / MLXCX_CMD_MAILBOX_LEN + 1; + if (!mlxcx_cmd_mbox_alloc(mlxp, &cmd->mlcmd_mbox_in, nblocks)) { + mlxcx_warn(mlxp, "failed to allocate %u blocks of " + "input mailbox", nblocks); + return (B_FALSE); + } + cmd->mlcmd_nboxes_in = nblocks; + } + + if (outlen > MLXCX_CMD_INLINE_OUTPUT_LEN) { + uint32_t need = outlen - MLXCX_CMD_INLINE_OUTPUT_LEN; + uint8_t nblocks; + + if (need / MLXCX_CMD_MAILBOX_LEN + 1 > UINT8_MAX) { + mlxcx_warn(mlxp, "requested too many output blocks for " + "%u byte output len", outlen); + return (B_FALSE); + } + + nblocks = need / MLXCX_CMD_MAILBOX_LEN + 1; + if (!mlxcx_cmd_mbox_alloc(mlxp, &cmd->mlcmd_mbox_out, + nblocks)) { + mlxcx_warn(mlxp, "failed to allocate %u blocks of " + "output mailbox", nblocks); + return (B_FALSE); + } + cmd->mlcmd_nboxes_out = nblocks; + } + + cmd->mlcmd_in = in; + cmd->mlcmd_inlen = inlen; + cmd->mlcmd_out = out; + cmd->mlcmd_outlen = outlen; + cmd->mlcmd_mlxp = mlxp; + + /* + * Now that all allocations have been done, all that remains is for us + * to dispatch the request to process this to the taskq for it to be + * processed. + */ + if (ddi_taskq_dispatch(mlxp->mlx_cmd.mcmd_taskq, mlxcx_cmd_taskq, cmd, + DDI_SLEEP) != DDI_SUCCESS) { + mlxcx_warn(mlxp, "failed to submit command to taskq"); + return (B_FALSE); + } + + return (B_TRUE); +} + +static void +mlxcx_cmd_wait(mlxcx_cmd_t *cmd) +{ + mutex_enter(&cmd->mlcmd_lock); + while (cmd->mlcmd_state == 0) { + cv_wait(&cmd->mlcmd_cv, &cmd->mlcmd_lock); + } + mutex_exit(&cmd->mlcmd_lock); +} + +static boolean_t +mlxcx_cmd_evaluate(mlxcx_t *mlxp, mlxcx_cmd_t *cmd) +{ + mlxcx_cmd_out_t *out; + + if ((cmd->mlcmd_state & MLXCX_CMD_S_ERROR) != 0) { + mlxcx_warn(mlxp, "command %s (0x%x) failed due to an internal " + "driver error", + mlxcx_cmd_opcode_string(cmd->mlcmd_op), + cmd->mlcmd_op); + return (B_FALSE); + } + + if (cmd->mlcmd_status != 0) { + mlxcx_warn(mlxp, "command %s (0x%x) failed with command queue " + "error 0x%x", + mlxcx_cmd_opcode_string(cmd->mlcmd_op), + cmd->mlcmd_op, cmd->mlcmd_status); + return (B_FALSE); + } + + out = cmd->mlcmd_out; + if (out->mco_status != MLXCX_CMD_R_OK) { + mlxcx_warn(mlxp, "command %s 0x%x failed with status code %s " + "(0x%x)", mlxcx_cmd_opcode_string(cmd->mlcmd_op), + cmd->mlcmd_op, mlxcx_cmd_response_string(out->mco_status), + out->mco_status); + return (B_FALSE); + } + + return (B_TRUE); +} + +boolean_t +mlxcx_cmd_disable_hca(mlxcx_t *mlxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_disable_hca_in_t in; + mlxcx_cmd_disable_hca_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_disable_hca_head, + MLXCX_OP_DISABLE_HCA, 0); + in.mlxi_disable_hca_func = MLXCX_FUNCTION_SELF; + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_enable_hca(mlxcx_t *mlxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_enable_hca_in_t in; + mlxcx_cmd_enable_hca_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_enable_hca_head, + MLXCX_OP_ENABLE_HCA, 0); + in.mlxi_enable_hca_func = MLXCX_FUNCTION_SELF; + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_issi(mlxcx_t *mlxp, uint32_t *issip) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_issi_in_t in; + mlxcx_cmd_query_issi_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_issi_head, + MLXCX_OP_QUERY_ISSI, 0); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + *issip = out.mlxo_supported_issi; + } else if (cmd.mlcmd_status == 0 && + out.mlxo_query_issi_head.mco_status == MLXCX_CMD_R_BAD_OP) { + /* + * The PRM says that if we get a bad operation, that means this + * command isn't supported so it only supports version 1 of the + * ISSI, which means bit zero should be set. + */ + ret = B_TRUE; + *issip = 1; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_set_issi(mlxcx_t *mlxp, uint16_t issi) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_set_issi_in_t in; + mlxcx_cmd_set_issi_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_set_issi_head, + MLXCX_OP_SET_ISSI, 0); + in.mlxi_set_issi_current = to_be16(issi); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_pages(mlxcx_t *mlxp, uint_t type, int32_t *npages) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_pages_in_t in; + mlxcx_cmd_query_pages_out_t out; + boolean_t ret; + + switch (type) { + case MLXCX_QUERY_PAGES_OPMOD_BOOT: + case MLXCX_QUERY_PAGES_OPMOD_INIT: + case MLXCX_QUERY_PAGES_OPMOD_REGULAR: + break; + default: + mlxcx_warn(mlxp, "!passed invalid type to query pages: %u", + type); + return (B_FALSE); + } + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_pages_head, + MLXCX_OP_QUERY_PAGES, type); + in.mlxi_query_pages_func = MLXCX_FUNCTION_SELF; + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + *npages = from_be32(out.mlxo_query_pages_npages); + } + mlxcx_cmd_fini(mlxp, &cmd); + + return (ret); +} + +boolean_t +mlxcx_cmd_give_pages(mlxcx_t *mlxp, uint_t type, int32_t npages, + mlxcx_dev_page_t **pages) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_manage_pages_in_t in; + mlxcx_cmd_manage_pages_out_t out; + size_t insize, outsize; + boolean_t ret; + uint32_t i; + uint64_t pa; + const ddi_dma_cookie_t *ck; + + switch (type) { + case MLXCX_MANAGE_PAGES_OPMOD_ALLOC_FAIL: + if (npages != 0) { + mlxcx_warn(mlxp, "passed non-zero number of pages (%d) " + "but asked to fail page allocation", npages); + return (B_FALSE); + } + break; + case MLXCX_MANAGE_PAGES_OPMOD_GIVE_PAGES: + if (npages <= 0 || npages > MLXCX_MANAGE_PAGES_MAX_PAGES) { + mlxcx_warn(mlxp, "passed invalid number of pages (%d) " + "to give pages", npages); + return (B_FALSE); + } + break; + default: + mlxcx_warn(mlxp, "!passed invalid type to give pages: %u", + type); + return (B_FALSE); + } + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + insize = offsetof(mlxcx_cmd_manage_pages_in_t, mlxi_manage_pages_pas) + + npages * sizeof (uint64_t); + outsize = offsetof(mlxcx_cmd_manage_pages_out_t, mlxo_manage_pages_pas); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_manage_pages_head, + MLXCX_OP_MANAGE_PAGES, type); + in.mlxi_manage_pages_func = MLXCX_FUNCTION_SELF; + in.mlxi_manage_pages_npages = to_be32(npages); + for (i = 0; i < npages; i++) { + ck = mlxcx_dma_cookie_one(&pages[i]->mxdp_dma); + pa = ck->dmac_laddress; + ASSERT3U(pa & 0xfff, ==, 0); + ASSERT3U(ck->dmac_size, ==, MLXCX_HW_PAGE_SIZE); + in.mlxi_manage_pages_pas[i] = to_be64(pa); + } + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, outsize)) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + + return (ret); +} + +boolean_t +mlxcx_cmd_return_pages(mlxcx_t *mlxp, int32_t nreq, uint64_t *pas, + int32_t *nret) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_manage_pages_in_t in; + mlxcx_cmd_manage_pages_out_t out; + size_t insize, outsize; + boolean_t ret; + uint32_t i; + + if (nreq <= 0) { + mlxcx_warn(mlxp, "passed invalid number of pages (%d) " + "to return pages", nreq); + return (B_FALSE); + } + VERIFY3S(nreq, <=, MLXCX_MANAGE_PAGES_MAX_PAGES); + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + insize = offsetof(mlxcx_cmd_manage_pages_in_t, mlxi_manage_pages_pas); + outsize = offsetof(mlxcx_cmd_manage_pages_out_t, + mlxo_manage_pages_pas) + nreq * sizeof (uint64_t); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_manage_pages_head, + MLXCX_OP_MANAGE_PAGES, MLXCX_MANAGE_PAGES_OPMOD_RETURN_PAGES); + in.mlxi_manage_pages_func = MLXCX_FUNCTION_SELF; + in.mlxi_manage_pages_npages = to_be32(nreq); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, outsize)) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + *nret = from_be32(out.mlxo_manage_pages_npages); + for (i = 0; i < *nret; i++) { + pas[i] = from_be64(out.mlxo_manage_pages_pas[i]); + } + } + mlxcx_cmd_fini(mlxp, &cmd); + + return (ret); +} + +boolean_t +mlxcx_cmd_query_hca_cap(mlxcx_t *mlxp, mlxcx_hca_cap_type_t type, + mlxcx_hca_cap_mode_t mode, mlxcx_hca_cap_t *capp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_hca_cap_in_t in; + mlxcx_cmd_query_hca_cap_out_t *out; + boolean_t ret; + uint16_t opmode; + + bzero(&in, sizeof (in)); + out = kmem_zalloc(sizeof (mlxcx_cmd_query_hca_cap_out_t), KM_SLEEP); + mlxcx_cmd_init(mlxp, &cmd); + + opmode = type << 1 | mode; + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_hca_cap_head, + MLXCX_OP_QUERY_HCA_CAP, opmode); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), out, sizeof (*out))) { + mlxcx_cmd_fini(mlxp, &cmd); + kmem_free(out, sizeof (mlxcx_cmd_query_hca_cap_out_t)); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + capp->mhc_mode = mode; + capp->mhc_type = type; + ASSERT3U(sizeof (out->mlxo_query_hca_cap_data), ==, + sizeof (capp->mhc_bulk)); + bcopy(out->mlxo_query_hca_cap_data, capp->mhc_bulk, + sizeof (capp->mhc_bulk)); + } + mlxcx_cmd_fini(mlxp, &cmd); + + kmem_free(out, sizeof (mlxcx_cmd_query_hca_cap_out_t)); + return (B_TRUE); +} + +boolean_t +mlxcx_cmd_init_hca(mlxcx_t *mlxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_init_hca_in_t in; + mlxcx_cmd_init_hca_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_init_hca_head, + MLXCX_OP_INIT_HCA, 0); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_set_driver_version(mlxcx_t *mlxp, const char *version) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_set_driver_version_in_t in; + mlxcx_cmd_set_driver_version_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_set_driver_version_head, + MLXCX_OP_SET_DRIVER_VERSION, 0); + VERIFY3U(strlcpy(in.mlxi_set_driver_version_version, version, + sizeof (in.mlxi_set_driver_version_version)), <=, + sizeof (in.mlxi_set_driver_version_version)); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_alloc_uar(mlxcx_t *mlxp, mlxcx_uar_t *mlup) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_alloc_uar_in_t in; + mlxcx_cmd_alloc_uar_out_t out; + boolean_t ret; + size_t i; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_alloc_uar_head, + MLXCX_OP_ALLOC_UAR, 0); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlup->mlu_allocated = B_TRUE; + mlup->mlu_num = from_be24(out.mlxo_alloc_uar_uar); + VERIFY3U(mlup->mlu_num, >, 0); + mlup->mlu_base = mlup->mlu_num * MLXCX_HW_PAGE_SIZE; + + for (i = 0; i < MLXCX_BF_PER_UAR; ++i) { + mlup->mlu_bf[i].mbf_even = mlup->mlu_base + + MLXCX_BF_BASE + MLXCX_BF_SIZE * 2 * i; + mlup->mlu_bf[i].mbf_odd = mlup->mlu_bf[i].mbf_even + + MLXCX_BF_SIZE; + } + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_dealloc_uar(mlxcx_t *mlxp, mlxcx_uar_t *mlup) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_dealloc_uar_in_t in; + mlxcx_cmd_dealloc_uar_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_dealloc_uar_head, + MLXCX_OP_DEALLOC_UAR, 0); + VERIFY(mlup->mlu_allocated); + in.mlxi_dealloc_uar_uar = to_be24(mlup->mlu_num); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlup->mlu_allocated = B_FALSE; + mlup->mlu_num = 0; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_alloc_pd(mlxcx_t *mlxp, mlxcx_pd_t *mlpd) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_alloc_pd_in_t in; + mlxcx_cmd_alloc_pd_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_alloc_pd_head, + MLXCX_OP_ALLOC_PD, 0); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlpd->mlpd_allocated = B_TRUE; + mlpd->mlpd_num = from_be24(out.mlxo_alloc_pd_pdn); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_dealloc_pd(mlxcx_t *mlxp, mlxcx_pd_t *mlpd) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_dealloc_pd_in_t in; + mlxcx_cmd_dealloc_pd_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_dealloc_pd_head, + MLXCX_OP_DEALLOC_PD, 0); + VERIFY(mlpd->mlpd_allocated); + in.mlxi_dealloc_pd_pdn = to_be24(mlpd->mlpd_num); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlpd->mlpd_allocated = B_FALSE; + mlpd->mlpd_num = 0; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_alloc_tdom(mlxcx_t *mlxp, mlxcx_tdom_t *mltd) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_alloc_tdom_in_t in; + mlxcx_cmd_alloc_tdom_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_alloc_tdom_head, + MLXCX_OP_ALLOC_TRANSPORT_DOMAIN, 0); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mltd->mltd_allocated = B_TRUE; + mltd->mltd_num = from_be24(out.mlxo_alloc_tdom_tdomn); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_dealloc_tdom(mlxcx_t *mlxp, mlxcx_tdom_t *mltd) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_dealloc_tdom_in_t in; + mlxcx_cmd_dealloc_tdom_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_dealloc_tdom_head, + MLXCX_OP_DEALLOC_TRANSPORT_DOMAIN, 0); + VERIFY(mltd->mltd_allocated); + in.mlxi_dealloc_tdom_tdomn = to_be24(mltd->mltd_num); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mltd->mltd_allocated = B_FALSE; + mltd->mltd_num = 0; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_teardown_hca(mlxcx_t *mlxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_teardown_hca_in_t in; + mlxcx_cmd_teardown_hca_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_teardown_hca_head, + MLXCX_OP_TEARDOWN_HCA, 0); + in.mlxi_teardown_hca_profile = to_be16(MLXCX_TEARDOWN_HCA_GRACEFUL); + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_nic_vport_ctx(mlxcx_t *mlxp, mlxcx_port_t *mlp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_nic_vport_ctx_in_t in; + mlxcx_cmd_query_nic_vport_ctx_out_t out; + boolean_t ret; + const mlxcx_nic_vport_ctx_t *ctx; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlp->mlp_mtx)); + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_nic_vport_ctx_head, + MLXCX_OP_QUERY_NIC_VPORT_CONTEXT, MLXCX_VPORT_TYPE_VNIC); + + in.mlxi_query_nic_vport_ctx_vport_number = to_be16(mlp->mlp_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + ctx = &out.mlxo_query_nic_vport_ctx_context; + mlp->mlp_guid = from_be64(ctx->mlnvc_port_guid); + mlp->mlp_mtu = from_be16(ctx->mlnvc_mtu); + bcopy(ctx->mlnvc_permanent_address, mlp->mlp_mac_address, + sizeof (mlp->mlp_mac_address)); + mlp->mlp_wqe_min_inline = get_bits64(ctx->mlnvc_flags, + MLXCX_VPORT_CTX_MIN_WQE_INLINE); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +static const char * +mlxcx_reg_name(mlxcx_register_id_t rid) +{ + switch (rid) { + case MLXCX_REG_PMTU: + return ("PMTU"); + case MLXCX_REG_PAOS: + return ("PAOS"); + case MLXCX_REG_PTYS: + return ("PTYS"); + case MLXCX_REG_MSGI: + return ("MSGI"); + case MLXCX_REG_PMAOS: + return ("PMAOS"); + case MLXCX_REG_MLCR: + return ("MLCR"); + case MLXCX_REG_MCIA: + return ("MCIA"); + case MLXCX_REG_PPCNT: + return ("PPCNT"); + default: + return ("???"); + } +} + +boolean_t +mlxcx_cmd_access_register(mlxcx_t *mlxp, mlxcx_cmd_reg_opmod_t opmod, + mlxcx_register_id_t rid, mlxcx_register_data_t *data) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_access_register_in_t in; + mlxcx_cmd_access_register_out_t out; + boolean_t ret; + size_t dsize, insize, outsize; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_access_register_head, + MLXCX_OP_ACCESS_REG, opmod); + + in.mlxi_access_register_register_id = to_be16(rid); + + switch (rid) { + case MLXCX_REG_PMTU: + dsize = sizeof (mlxcx_reg_pmtu_t); + break; + case MLXCX_REG_PAOS: + dsize = sizeof (mlxcx_reg_paos_t); + break; + case MLXCX_REG_PTYS: + dsize = sizeof (mlxcx_reg_ptys_t); + break; + case MLXCX_REG_MLCR: + dsize = sizeof (mlxcx_reg_mlcr_t); + break; + case MLXCX_REG_PMAOS: + dsize = sizeof (mlxcx_reg_pmaos_t); + break; + case MLXCX_REG_MCIA: + dsize = sizeof (mlxcx_reg_mcia_t); + break; + case MLXCX_REG_PPCNT: + dsize = sizeof (mlxcx_reg_ppcnt_t); + break; + default: + dsize = 0; + VERIFY(0); + return (B_FALSE); + } + insize = dsize + offsetof(mlxcx_cmd_access_register_in_t, + mlxi_access_register_data); + outsize = dsize + offsetof(mlxcx_cmd_access_register_out_t, + mlxo_access_register_data); + + bcopy(data, &in.mlxi_access_register_data, dsize); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, outsize)) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + bcopy(&out.mlxo_access_register_data, data, dsize); + } else { + mlxcx_warn(mlxp, "failed OP_ACCESS_REG was for register " + "%04x (%s)", rid, mlxcx_reg_name(rid)); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_port_mtu(mlxcx_t *mlxp, mlxcx_port_t *mlp) +{ + mlxcx_register_data_t data; + boolean_t ret; + + /* + * Since we modify the port here we require that the caller is holding + * the port mutex. + */ + ASSERT(mutex_owned(&mlp->mlp_mtx)); + bzero(&data, sizeof (data)); + data.mlrd_pmtu.mlrd_pmtu_local_port = mlp->mlp_num + 1; + + ret = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_PMTU, &data); + + if (ret) { + mlp->mlp_mtu = from_be16(data.mlrd_pmtu.mlrd_pmtu_admin_mtu); + mlp->mlp_max_mtu = from_be16(data.mlrd_pmtu.mlrd_pmtu_max_mtu); + } + + return (ret); +} + +boolean_t +mlxcx_cmd_query_module_status(mlxcx_t *mlxp, uint_t id, + mlxcx_module_status_t *pstatus, mlxcx_module_error_type_t *perr) +{ + mlxcx_register_data_t data; + boolean_t ret; + + bzero(&data, sizeof (data)); + ASSERT3U(id, <, 0xff); + data.mlrd_pmaos.mlrd_pmaos_module = (uint8_t)id; + + ret = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_PMAOS, &data); + + if (ret) { + if (pstatus != NULL) + *pstatus = data.mlrd_pmaos.mlrd_pmaos_oper_status; + if (perr != NULL) + *perr = data.mlrd_pmaos.mlrd_pmaos_error_type; + } + + return (ret); +} + +boolean_t +mlxcx_cmd_set_port_mtu(mlxcx_t *mlxp, mlxcx_port_t *mlp) +{ + mlxcx_register_data_t data; + boolean_t ret; + + ASSERT(mutex_owned(&mlp->mlp_mtx)); + bzero(&data, sizeof (data)); + data.mlrd_pmtu.mlrd_pmtu_local_port = mlp->mlp_num + 1; + data.mlrd_pmtu.mlrd_pmtu_admin_mtu = to_be16(mlp->mlp_mtu); + + ret = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_WRITE, + MLXCX_REG_PMTU, &data); + + return (ret); +} + +boolean_t +mlxcx_cmd_set_port_led(mlxcx_t *mlxp, mlxcx_port_t *mlp, uint16_t sec) +{ + mlxcx_register_data_t data; + boolean_t ret; + + ASSERT(mutex_owned(&mlp->mlp_mtx)); + bzero(&data, sizeof (data)); + data.mlrd_mlcr.mlrd_mlcr_local_port = mlp->mlp_num + 1; + set_bits8(&data.mlrd_mlcr.mlrd_mlcr_flags, MLXCX_MLCR_LED_TYPE, + MLXCX_LED_TYPE_PORT); + data.mlrd_mlcr.mlrd_mlcr_beacon_duration = to_be16(sec); + + ret = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_WRITE, + MLXCX_REG_MLCR, &data); + + return (ret); +} + +boolean_t +mlxcx_cmd_query_port_status(mlxcx_t *mlxp, mlxcx_port_t *mlp) +{ + mlxcx_register_data_t data; + boolean_t ret; + + ASSERT(mutex_owned(&mlp->mlp_mtx)); + bzero(&data, sizeof (data)); + data.mlrd_paos.mlrd_paos_local_port = mlp->mlp_num + 1; + + ret = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_PAOS, &data); + + if (ret) { + mlp->mlp_admin_status = data.mlrd_paos.mlrd_paos_admin_status; + mlp->mlp_oper_status = data.mlrd_paos.mlrd_paos_oper_status; + } + + return (ret); +} + +boolean_t +mlxcx_cmd_query_port_speed(mlxcx_t *mlxp, mlxcx_port_t *mlp) +{ + mlxcx_register_data_t data; + boolean_t ret; + + ASSERT(mutex_owned(&mlp->mlp_mtx)); + bzero(&data, sizeof (data)); + data.mlrd_ptys.mlrd_ptys_local_port = mlp->mlp_num + 1; + set_bit8(&data.mlrd_ptys.mlrd_ptys_proto_mask, + MLXCX_PTYS_PROTO_MASK_ETH); + + ret = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_PTYS, &data); + + if (ret) { + if (get_bit8(data.mlrd_ptys.mlrd_ptys_autoneg_flags, + MLXCX_AUTONEG_DISABLE)) { + mlp->mlp_autoneg = B_FALSE; + } else { + mlp->mlp_autoneg = B_TRUE; + } + mlp->mlp_max_proto = + from_bits32(data.mlrd_ptys.mlrd_ptys_proto_cap); + mlp->mlp_admin_proto = + from_bits32(data.mlrd_ptys.mlrd_ptys_proto_admin); + mlp->mlp_oper_proto = + from_bits32(data.mlrd_ptys.mlrd_ptys_proto_oper); + } + + return (ret); +} + +boolean_t +mlxcx_cmd_modify_nic_vport_ctx(mlxcx_t *mlxp, mlxcx_port_t *mlp, + mlxcx_modify_nic_vport_ctx_fields_t fields) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_modify_nic_vport_ctx_in_t in; + mlxcx_cmd_modify_nic_vport_ctx_out_t out; + boolean_t ret; + mlxcx_nic_vport_ctx_t *ctx; + + ASSERT(mutex_owned(&mlp->mlp_mtx)); + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_modify_nic_vport_ctx_head, + MLXCX_OP_MODIFY_NIC_VPORT_CONTEXT, MLXCX_VPORT_TYPE_VNIC); + + in.mlxi_modify_nic_vport_ctx_vport_number = to_be16(mlp->mlp_num); + in.mlxi_modify_nic_vport_ctx_field_select = to_be32(fields); + + ctx = &in.mlxi_modify_nic_vport_ctx_context; + if (fields & MLXCX_MODIFY_NIC_VPORT_CTX_PROMISC) { + set_bit16(&ctx->mlnvc_promisc_list_type, + MLXCX_VPORT_PROMISC_ALL); + } + if (fields & MLXCX_MODIFY_NIC_VPORT_CTX_MTU) { + ctx->mlnvc_mtu = to_be16(mlp->mlp_mtu); + } + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + if (fields & MLXCX_MODIFY_NIC_VPORT_CTX_PROMISC) { + mlp->mlp_flags |= MLXCX_PORT_VPORT_PROMISC; + } + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_eq(mlxcx_t *mlxp, mlxcx_event_queue_t *mleq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_eq_in_t in; + mlxcx_cmd_create_eq_out_t out; + boolean_t ret; + mlxcx_eventq_ctx_t *ctx; + size_t rem, insize; + const ddi_dma_cookie_t *c; + uint64_t pa, npages; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mleq->mleq_mtx)); + VERIFY(mleq->mleq_state & MLXCX_EQ_ALLOC); + VERIFY0(mleq->mleq_state & MLXCX_EQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_eq_head, + MLXCX_OP_CREATE_EQ, 0); + + ctx = &in.mlxi_create_eq_context; + ctx->mleqc_uar_page = to_be24(mleq->mleq_uar->mlu_num); + ctx->mleqc_log_eq_size = mleq->mleq_entshift; + ctx->mleqc_intr = mleq->mleq_intr_index; + + in.mlxi_create_eq_event_bitmask = to_be64(mleq->mleq_events); + + npages = 0; + c = NULL; + while ((c = mlxcx_dma_cookie_iter(&mleq->mleq_dma, c)) != NULL) { + pa = c->dmac_laddress; + rem = c->dmac_size; + while (rem > 0) { + ASSERT3U(pa & 0xfff, ==, 0); + ASSERT3U(rem, >=, MLXCX_HW_PAGE_SIZE); + in.mlxi_create_eq_pas[npages++] = to_be64(pa); + rem -= MLXCX_HW_PAGE_SIZE; + pa += MLXCX_HW_PAGE_SIZE; + } + } + ASSERT3U(npages, <=, MLXCX_CREATE_QUEUE_MAX_PAGES); + + insize = offsetof(mlxcx_cmd_create_eq_in_t, mlxi_create_eq_pas) + + sizeof (uint64_t) * npages; + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mleq->mleq_state |= MLXCX_EQ_CREATED; + mleq->mleq_num = out.mlxo_create_eq_eqn; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_eq(mlxcx_t *mlxp, mlxcx_event_queue_t *mleq, + mlxcx_eventq_ctx_t *ctxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_eq_in_t in; + mlxcx_cmd_query_eq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mleq->mleq_mtx)); + VERIFY(mleq->mleq_state & MLXCX_EQ_ALLOC); + VERIFY(mleq->mleq_state & MLXCX_EQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_eq_head, + MLXCX_OP_QUERY_EQ, 0); + + in.mlxi_query_eq_eqn = mleq->mleq_num; + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + bcopy(&out.mlxo_query_eq_context, ctxp, + sizeof (mlxcx_eventq_ctx_t)); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_eq(mlxcx_t *mlxp, mlxcx_event_queue_t *mleq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_eq_in_t in; + mlxcx_cmd_destroy_eq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mleq->mleq_mtx)); + VERIFY(mleq->mleq_state & MLXCX_EQ_ALLOC); + VERIFY(mleq->mleq_state & MLXCX_EQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_eq_head, + MLXCX_OP_DESTROY_EQ, 0); + + in.mlxi_destroy_eq_eqn = mleq->mleq_num; + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mleq->mleq_state |= MLXCX_EQ_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_special_ctxs(mlxcx_t *mlxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_special_ctxs_in_t in; + mlxcx_cmd_query_special_ctxs_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_special_ctxs_head, + MLXCX_OP_QUERY_SPECIAL_CONTEXTS, 0); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlxp->mlx_rsvd_lkey = from_be32( + out.mlxo_query_special_ctxs_resd_lkey); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_cq(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_cq_in_t in; + mlxcx_cmd_create_cq_out_t out; + boolean_t ret; + mlxcx_completionq_ctx_t *ctx; + size_t rem, insize; + const ddi_dma_cookie_t *c; + uint64_t pa, npages; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + VERIFY(mlcq->mlcq_state & MLXCX_CQ_ALLOC); + VERIFY0(mlcq->mlcq_state & MLXCX_CQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_cq_head, + MLXCX_OP_CREATE_CQ, 0); + + ctx = &in.mlxi_create_cq_context; + ctx->mlcqc_uar_page = to_be24(mlcq->mlcq_uar->mlu_num); + ctx->mlcqc_log_cq_size = mlcq->mlcq_entshift; + ctx->mlcqc_eqn = mlcq->mlcq_eq->mleq_num; + ctx->mlcqc_cq_period = to_be16(mlcq->mlcq_cqemod_period_usec); + ctx->mlcqc_cq_max_count = to_be16(mlcq->mlcq_cqemod_count); + + c = mlxcx_dma_cookie_one(&mlcq->mlcq_doorbell_dma); + ctx->mlcqc_dbr_addr = to_be64(c->dmac_laddress); + ASSERT3U(c->dmac_size, >=, sizeof (mlxcx_completionq_doorbell_t)); + + npages = 0; + c = NULL; + while ((c = mlxcx_dma_cookie_iter(&mlcq->mlcq_dma, c)) != NULL) { + pa = c->dmac_laddress; + rem = c->dmac_size; + while (rem > 0) { + ASSERT3U(pa & 0xfff, ==, 0); + ASSERT3U(rem, >=, MLXCX_HW_PAGE_SIZE); + in.mlxi_create_cq_pas[npages++] = to_be64(pa); + rem -= MLXCX_HW_PAGE_SIZE; + pa += MLXCX_HW_PAGE_SIZE; + } + } + ASSERT3U(npages, <=, MLXCX_CREATE_QUEUE_MAX_PAGES); + + insize = offsetof(mlxcx_cmd_create_cq_in_t, mlxi_create_cq_pas) + + sizeof (uint64_t) * npages; + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlcq->mlcq_state |= MLXCX_CQ_CREATED; + mlcq->mlcq_num = from_be24(out.mlxo_create_cq_cqn); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_rq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq, + mlxcx_rq_ctx_t *ctxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_rq_in_t in; + mlxcx_cmd_query_rq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + ASSERT3S(mlwq->mlwq_type, ==, MLXCX_WQ_TYPE_RECVQ); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_rq_head, + MLXCX_OP_QUERY_RQ, 0); + + in.mlxi_query_rq_rqn = to_be24(mlwq->mlwq_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + bcopy(&out.mlxo_query_rq_context, ctxp, + sizeof (mlxcx_rq_ctx_t)); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_sq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq, + mlxcx_sq_ctx_t *ctxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_sq_in_t in; + mlxcx_cmd_query_sq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + ASSERT3S(mlwq->mlwq_type, ==, MLXCX_WQ_TYPE_SENDQ); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_sq_head, + MLXCX_OP_QUERY_SQ, 0); + + in.mlxi_query_sq_sqn = to_be24(mlwq->mlwq_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + bcopy(&out.mlxo_query_sq_context, ctxp, + sizeof (mlxcx_sq_ctx_t)); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_query_cq(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq, + mlxcx_completionq_ctx_t *ctxp) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_query_cq_in_t in; + mlxcx_cmd_query_cq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + VERIFY(mlcq->mlcq_state & MLXCX_CQ_ALLOC); + VERIFY(mlcq->mlcq_state & MLXCX_CQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_query_cq_head, + MLXCX_OP_QUERY_CQ, 0); + + in.mlxi_query_cq_cqn = to_be24(mlcq->mlcq_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + bcopy(&out.mlxo_query_cq_context, ctxp, + sizeof (mlxcx_completionq_ctx_t)); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_cq(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_cq_in_t in; + mlxcx_cmd_destroy_cq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + VERIFY(mlcq->mlcq_state & MLXCX_CQ_ALLOC); + VERIFY(mlcq->mlcq_state & MLXCX_CQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_cq_head, + MLXCX_OP_DESTROY_CQ, 0); + + in.mlxi_destroy_cq_cqn = to_be24(mlcq->mlcq_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlcq->mlcq_state |= MLXCX_CQ_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_rq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_rq_in_t in; + mlxcx_cmd_create_rq_out_t out; + boolean_t ret; + mlxcx_rq_ctx_t *ctx; + size_t rem, insize; + const ddi_dma_cookie_t *c; + uint64_t pa, npages; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY3U(mlwq->mlwq_type, ==, MLXCX_WQ_TYPE_RECVQ); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY0(mlwq->mlwq_state & MLXCX_WQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_rq_head, + MLXCX_OP_CREATE_RQ, 0); + + ctx = &in.mlxi_create_rq_context; + + set_bit32(&ctx->mlrqc_flags, MLXCX_RQ_FLAGS_RLKEY); + set_bit32(&ctx->mlrqc_flags, MLXCX_RQ_FLAGS_FLUSH_IN_ERROR); + set_bit32(&ctx->mlrqc_flags, MLXCX_RQ_FLAGS_VLAN_STRIP_DISABLE); + ctx->mlrqc_cqn = to_be24(mlwq->mlwq_cq->mlcq_num); + + set_bits32(&ctx->mlrqc_wq.mlwqc_flags, MLXCX_WORKQ_CTX_TYPE, + MLXCX_WORKQ_TYPE_CYCLIC); + ctx->mlrqc_wq.mlwqc_pd = to_be24(mlwq->mlwq_pd->mlpd_num); + ctx->mlrqc_wq.mlwqc_log_wq_sz = mlwq->mlwq_entshift; + ctx->mlrqc_wq.mlwqc_log_wq_stride = MLXCX_RECVQ_STRIDE_SHIFT; + + c = mlxcx_dma_cookie_one(&mlwq->mlwq_doorbell_dma); + ctx->mlrqc_wq.mlwqc_dbr_addr = to_be64(c->dmac_laddress); + ASSERT3U(c->dmac_size, >=, sizeof (mlxcx_workq_doorbell_t)); + + npages = 0; + c = NULL; + while ((c = mlxcx_dma_cookie_iter(&mlwq->mlwq_dma, c)) != NULL) { + pa = c->dmac_laddress; + rem = c->dmac_size; + while (rem > 0) { + ASSERT3U(pa & 0xfff, ==, 0); + ASSERT3U(rem, >=, MLXCX_HW_PAGE_SIZE); + ctx->mlrqc_wq.mlwqc_pas[npages++] = to_be64(pa); + rem -= MLXCX_HW_PAGE_SIZE; + pa += MLXCX_HW_PAGE_SIZE; + } + } + ASSERT3U(npages, <=, MLXCX_WORKQ_CTX_MAX_ADDRESSES); + + insize = offsetof(mlxcx_cmd_create_rq_in_t, mlxi_create_rq_context) + + offsetof(mlxcx_rq_ctx_t, mlrqc_wq) + + offsetof(mlxcx_workq_ctx_t, mlwqc_pas) + + sizeof (uint64_t) * npages; + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state |= MLXCX_WQ_CREATED; + mlwq->mlwq_num = from_be24(out.mlxo_create_rq_rqn); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_start_rq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_modify_rq_in_t in; + mlxcx_cmd_modify_rq_out_t out; + boolean_t ret; + ddi_fm_error_t err; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + VERIFY0(mlwq->mlwq_state & MLXCX_WQ_STARTED); + + /* + * Before starting the queue, we have to be sure that it is + * empty and the doorbell and counters are set to 0. + */ + ASSERT(mutex_owned(&mlwq->mlwq_cq->mlcq_mtx)); + ASSERT(list_is_empty(&mlwq->mlwq_cq->mlcq_buffers)); + ASSERT(list_is_empty(&mlwq->mlwq_cq->mlcq_buffers_b)); + + mlwq->mlwq_doorbell->mlwqd_recv_counter = to_be16(0); + MLXCX_DMA_SYNC(mlwq->mlwq_doorbell_dma, DDI_DMA_SYNC_FORDEV); + ddi_fm_dma_err_get(mlwq->mlwq_doorbell_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) + return (B_FALSE); + mlwq->mlwq_pc = 0; + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_modify_rq_head, + MLXCX_OP_MODIFY_RQ, 0); + + in.mlxi_modify_rq_rqn = to_be24(mlwq->mlwq_num); + + /* From state */ + set_bits8(&in.mlxi_modify_rq_state, MLXCX_CMD_MODIFY_RQ_STATE, + MLXCX_RQ_STATE_RST); + /* To state */ + set_bits32(&in.mlxi_modify_rq_context.mlrqc_flags, MLXCX_RQ_STATE, + MLXCX_RQ_STATE_RDY); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state |= MLXCX_WQ_STARTED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_stop_rq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_modify_rq_in_t in; + mlxcx_cmd_modify_rq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_STARTED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_modify_rq_head, + MLXCX_OP_MODIFY_RQ, 0); + + in.mlxi_modify_rq_rqn = to_be24(mlwq->mlwq_num); + + /* From state */ + set_bits8(&in.mlxi_modify_rq_state, MLXCX_CMD_MODIFY_RQ_STATE, + MLXCX_RQ_STATE_RDY); + /* To state */ + set_bits32(&in.mlxi_modify_rq_context.mlrqc_flags, MLXCX_RQ_STATE, + MLXCX_RQ_STATE_RST); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state &= ~MLXCX_WQ_STARTED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_rq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_rq_in_t in; + mlxcx_cmd_destroy_rq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + VERIFY0(mlwq->mlwq_state & MLXCX_WQ_STARTED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_rq_head, + MLXCX_OP_DESTROY_RQ, 0); + + in.mlxi_destroy_rq_rqn = to_be24(mlwq->mlwq_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state |= MLXCX_WQ_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_tir(mlxcx_t *mlxp, mlxcx_tir_t *mltir) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_tir_in_t in; + mlxcx_cmd_create_tir_out_t out; + mlxcx_tir_ctx_t *ctx; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + VERIFY0(mltir->mltir_state & MLXCX_TIR_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_tir_head, + MLXCX_OP_CREATE_TIR, 0); + + ctx = &in.mlxi_create_tir_context; + ctx->mltirc_transport_domain = to_be24(mltir->mltir_tdom->mltd_num); + set_bits8(&ctx->mltirc_disp_type, MLXCX_TIR_CTX_DISP_TYPE, + mltir->mltir_type); + switch (mltir->mltir_type) { + case MLXCX_TIR_INDIRECT: + VERIFY(mltir->mltir_rqtable != NULL); + VERIFY(mltir->mltir_rqtable->mlrqt_state & MLXCX_RQT_CREATED); + ctx->mltirc_indirect_table = + to_be24(mltir->mltir_rqtable->mlrqt_num); + set_bits8(&ctx->mltirc_hash_lb, MLXCX_TIR_RX_HASH_FN, + mltir->mltir_hash_fn); + bcopy(mltir->mltir_toeplitz_key, + ctx->mltirc_rx_hash_toeplitz_key, + sizeof (ctx->mltirc_rx_hash_toeplitz_key)); + set_bits32(&ctx->mltirc_rx_hash_fields_outer, + MLXCX_RX_HASH_L3_TYPE, mltir->mltir_l3_type); + set_bits32(&ctx->mltirc_rx_hash_fields_outer, + MLXCX_RX_HASH_L4_TYPE, mltir->mltir_l4_type); + set_bits32(&ctx->mltirc_rx_hash_fields_outer, + MLXCX_RX_HASH_FIELDS, mltir->mltir_hash_fields); + break; + case MLXCX_TIR_DIRECT: + VERIFY(mltir->mltir_rq != NULL); + VERIFY(mltir->mltir_rq->mlwq_state & MLXCX_WQ_CREATED); + ctx->mltirc_inline_rqn = to_be24(mltir->mltir_rq->mlwq_num); + break; + default: + VERIFY(0); + } + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mltir->mltir_state |= MLXCX_TIR_CREATED; + mltir->mltir_num = from_be24(out.mlxo_create_tir_tirn); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_tir(mlxcx_t *mlxp, mlxcx_tir_t *mltir) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_tir_in_t in; + mlxcx_cmd_destroy_tir_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + VERIFY(mltir->mltir_state & MLXCX_TIR_CREATED); + VERIFY0(mltir->mltir_state & MLXCX_TIR_DESTROYED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_tir_head, + MLXCX_OP_DESTROY_TIR, 0); + + in.mlxi_destroy_tir_tirn = to_be24(mltir->mltir_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mltir->mltir_state |= MLXCX_TIR_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_tis(mlxcx_t *mlxp, mlxcx_tis_t *mltis) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_tis_in_t in; + mlxcx_cmd_create_tis_out_t out; + mlxcx_tis_ctx_t *ctx; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + VERIFY0(mltis->mltis_state & MLXCX_TIS_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_tis_head, + MLXCX_OP_CREATE_TIS, 0); + + ctx = &in.mlxi_create_tis_context; + ctx->mltisc_transport_domain = to_be24(mltis->mltis_tdom->mltd_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mltis->mltis_state |= MLXCX_TIS_CREATED; + mltis->mltis_num = from_be24(out.mlxo_create_tis_tisn); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_tis(mlxcx_t *mlxp, mlxcx_tis_t *mltis) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_tis_in_t in; + mlxcx_cmd_destroy_tis_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + VERIFY(mltis->mltis_state & MLXCX_TIR_CREATED); + VERIFY0(mltis->mltis_state & MLXCX_TIR_DESTROYED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_tis_head, + MLXCX_OP_DESTROY_TIS, 0); + + in.mlxi_destroy_tis_tisn = to_be24(mltis->mltis_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mltis->mltis_state |= MLXCX_TIS_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_flow_table(mlxcx_t *mlxp, mlxcx_flow_table_t *mlft) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_flow_table_in_t in; + mlxcx_cmd_create_flow_table_out_t out; + mlxcx_flow_table_ctx_t *ctx; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlft->mlft_mtx)); + VERIFY0(mlft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_flow_table_head, + MLXCX_OP_CREATE_FLOW_TABLE, 0); + + in.mlxi_create_flow_table_vport_number = + to_be16(mlft->mlft_port->mlp_num); + in.mlxi_create_flow_table_table_type = mlft->mlft_type; + ctx = &in.mlxi_create_flow_table_context; + ctx->mlftc_log_size = mlft->mlft_entshift; + ctx->mlftc_level = mlft->mlft_level; + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlft->mlft_num = from_be24(out.mlxo_create_flow_table_table_id); + mlft->mlft_state |= MLXCX_FLOW_TABLE_CREATED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_flow_table(mlxcx_t *mlxp, mlxcx_flow_table_t *mlft) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_flow_table_in_t in; + mlxcx_cmd_destroy_flow_table_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlft->mlft_mtx)); + VERIFY(mlft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + VERIFY0(mlft->mlft_state & MLXCX_FLOW_TABLE_DESTROYED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_flow_table_head, + MLXCX_OP_DESTROY_FLOW_TABLE, 0); + + in.mlxi_destroy_flow_table_vport_number = + to_be16(mlft->mlft_port->mlp_num); + in.mlxi_destroy_flow_table_table_type = mlft->mlft_type; + in.mlxi_destroy_flow_table_table_id = to_be24(mlft->mlft_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlft->mlft_state |= MLXCX_FLOW_TABLE_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_set_flow_table_root(mlxcx_t *mlxp, mlxcx_flow_table_t *mlft) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_set_flow_table_root_in_t in; + mlxcx_cmd_set_flow_table_root_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlft->mlft_mtx)); + VERIFY(mlft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + VERIFY0(mlft->mlft_state & MLXCX_FLOW_TABLE_DESTROYED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_set_flow_table_root_head, + MLXCX_OP_SET_FLOW_TABLE_ROOT, 0); + + in.mlxi_set_flow_table_root_vport_number = + to_be16(mlft->mlft_port->mlp_num); + in.mlxi_set_flow_table_root_table_type = mlft->mlft_type; + in.mlxi_set_flow_table_root_table_id = to_be24(mlft->mlft_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlft->mlft_state |= MLXCX_FLOW_TABLE_ROOT; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_flow_group(mlxcx_t *mlxp, mlxcx_flow_group_t *mlfg) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_flow_group_in_t in; + mlxcx_cmd_create_flow_group_out_t out; + boolean_t ret; + const mlxcx_flow_table_t *mlft; + mlxcx_flow_header_match_t *hdrs; + mlxcx_flow_params_match_t *params; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlft = mlfg->mlfg_table; + ASSERT(mutex_owned(&mlft->mlft_mtx)); + VERIFY(mlft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + VERIFY0(mlft->mlft_state & MLXCX_FLOW_TABLE_DESTROYED); + VERIFY0(mlfg->mlfg_state & MLXCX_FLOW_GROUP_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_flow_group_head, + MLXCX_OP_CREATE_FLOW_GROUP, 0); + + in.mlxi_create_flow_group_vport_number = + to_be16(mlft->mlft_port->mlp_num); + in.mlxi_create_flow_group_table_type = mlft->mlft_type; + in.mlxi_create_flow_group_table_id = to_be24(mlft->mlft_num); + in.mlxi_create_flow_group_start_flow_index = + to_be32(mlfg->mlfg_start_idx); + in.mlxi_create_flow_group_end_flow_index = + to_be32(mlfg->mlfg_start_idx + (mlfg->mlfg_size - 1)); + + hdrs = &in.mlxi_create_flow_group_match_criteria.mlfm_outer_headers; + params = &in.mlxi_create_flow_group_match_criteria.mlfm_misc_parameters; + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_SMAC) { + in.mlxi_create_flow_group_match_criteria_en |= + MLXCX_FLOW_GROUP_MATCH_OUTER_HDRS; + (void) memset(&hdrs->mlfh_smac, 0xff, sizeof (hdrs->mlfh_smac)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_DMAC) { + in.mlxi_create_flow_group_match_criteria_en |= + MLXCX_FLOW_GROUP_MATCH_OUTER_HDRS; + (void) memset(&hdrs->mlfh_dmac, 0xff, sizeof (hdrs->mlfh_dmac)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VLAN) { + in.mlxi_create_flow_group_match_criteria_en |= + MLXCX_FLOW_GROUP_MATCH_OUTER_HDRS; + set_bit24(&hdrs->mlfh_tcp_ip_flags, MLXCX_FLOW_HDR_CVLAN_TAG); + set_bit24(&hdrs->mlfh_tcp_ip_flags, MLXCX_FLOW_HDR_SVLAN_TAG); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VID) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VLAN); + set_bits16(&hdrs->mlfh_first_vid_flags, + MLXCX_FLOW_HDR_FIRST_VID, UINT16_MAX); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER) { + in.mlxi_create_flow_group_match_criteria_en |= + MLXCX_FLOW_GROUP_MATCH_OUTER_HDRS; + set_bits24(&hdrs->mlfh_tcp_ip_flags, MLXCX_FLOW_HDR_IP_VERSION, + UINT32_MAX); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_SRCIP) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER); + (void) memset(&hdrs->mlfh_src_ip, 0xff, + sizeof (hdrs->mlfh_src_ip)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_DSTIP) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER); + (void) memset(&hdrs->mlfh_src_ip, 0xff, + sizeof (hdrs->mlfh_dst_ip)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_PROTO) { + in.mlxi_create_flow_group_match_criteria_en |= + MLXCX_FLOW_GROUP_MATCH_OUTER_HDRS; + hdrs->mlfh_ip_protocol = UINT8_MAX; + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_SRCIP) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER); + (void) memset(&hdrs->mlfh_src_ip, 0xff, + sizeof (hdrs->mlfh_src_ip)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_DSTIP) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER); + (void) memset(&hdrs->mlfh_src_ip, 0xff, + sizeof (hdrs->mlfh_dst_ip)); + } + + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_SQN) { + in.mlxi_create_flow_group_match_criteria_en |= + MLXCX_FLOW_GROUP_MATCH_MISC_PARAMS; + params->mlfp_source_sqn = to_be24(UINT32_MAX); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VXLAN) { + in.mlxi_create_flow_group_match_criteria_en |= + MLXCX_FLOW_GROUP_MATCH_MISC_PARAMS; + params->mlfp_vxlan_vni = to_be24(UINT32_MAX); + } + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlfg->mlfg_state |= MLXCX_FLOW_GROUP_CREATED; + mlfg->mlfg_num = from_be24(out.mlxo_create_flow_group_group_id); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_flow_group(mlxcx_t *mlxp, mlxcx_flow_group_t *mlfg) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_flow_group_in_t in; + mlxcx_cmd_destroy_flow_group_out_t out; + boolean_t ret; + const mlxcx_flow_table_t *mlft; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlft = mlfg->mlfg_table; + ASSERT(mutex_owned(&mlft->mlft_mtx)); + VERIFY(mlft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + VERIFY0(mlft->mlft_state & MLXCX_FLOW_TABLE_DESTROYED); + VERIFY(mlfg->mlfg_state & MLXCX_FLOW_GROUP_CREATED); + VERIFY0(mlfg->mlfg_state & MLXCX_FLOW_GROUP_DESTROYED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_flow_group_head, + MLXCX_OP_DESTROY_FLOW_GROUP, 0); + + in.mlxi_destroy_flow_group_vport_number = + to_be16(mlft->mlft_port->mlp_num); + in.mlxi_destroy_flow_group_table_type = mlft->mlft_type; + in.mlxi_destroy_flow_group_table_id = to_be24(mlft->mlft_num); + in.mlxi_destroy_flow_group_group_id = to_be32(mlfg->mlfg_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlfg->mlfg_state |= MLXCX_FLOW_GROUP_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_set_flow_table_entry(mlxcx_t *mlxp, mlxcx_flow_entry_t *mlfe) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_set_flow_table_entry_in_t in; + mlxcx_cmd_set_flow_table_entry_out_t out; + boolean_t ret; + size_t insize; + mlxcx_flow_entry_ctx_t *ctx; + const mlxcx_flow_table_t *mlft; + mlxcx_flow_group_t *mlfg; + mlxcx_flow_dest_t *d; + uint_t i; + mlxcx_flow_header_match_t *hdrs; + mlxcx_flow_params_match_t *params; + mlxcx_cmd_set_flow_table_entry_opmod_t opmod; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlft = mlfe->mlfe_table; + ASSERT(mutex_owned(&mlft->mlft_mtx)); + VERIFY(mlft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + VERIFY0(mlft->mlft_state & MLXCX_FLOW_TABLE_DESTROYED); + + mlfg = mlfe->mlfe_group; + VERIFY(mlfg->mlfg_state & MLXCX_FLOW_GROUP_CREATED); + VERIFY0(mlfg->mlfg_state & MLXCX_FLOW_GROUP_DESTROYED); + + opmod = MLXCX_CMD_FLOW_ENTRY_SET_NEW; + if (mlfe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + ASSERT(mlfe->mlfe_state & MLXCX_FLOW_ENTRY_DIRTY); + opmod = MLXCX_CMD_FLOW_ENTRY_MODIFY; + } + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_set_flow_table_entry_head, + MLXCX_OP_SET_FLOW_TABLE_ENTRY, opmod); + + in.mlxi_set_flow_table_entry_vport_number = + to_be16(mlft->mlft_port->mlp_num); + in.mlxi_set_flow_table_entry_table_type = mlft->mlft_type; + in.mlxi_set_flow_table_entry_table_id = to_be24(mlft->mlft_num); + in.mlxi_set_flow_table_entry_flow_index = to_be32(mlfe->mlfe_index); + + if (mlfe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + set_bit8(&in.mlxi_set_flow_table_entry_modify_bitmask, + MLXCX_CMD_FLOW_ENTRY_SET_ACTION); + set_bit8(&in.mlxi_set_flow_table_entry_modify_bitmask, + MLXCX_CMD_FLOW_ENTRY_SET_DESTINATION); + } + + ctx = &in.mlxi_set_flow_table_entry_context; + ctx->mlfec_group_id = to_be32(mlfg->mlfg_num); + + insize = offsetof(mlxcx_cmd_set_flow_table_entry_in_t, + mlxi_set_flow_table_entry_context) + + offsetof(mlxcx_flow_entry_ctx_t, mlfec_destination); + + ctx->mlfec_action = to_be16(mlfe->mlfe_action); + + switch (mlfe->mlfe_action) { + case MLXCX_FLOW_ACTION_ALLOW: + case MLXCX_FLOW_ACTION_DROP: + break; + case MLXCX_FLOW_ACTION_FORWARD: + ASSERT3U(mlfe->mlfe_ndest, <=, MLXCX_FLOW_MAX_DESTINATIONS); + ASSERT3U(mlfe->mlfe_ndest, <=, + mlxp->mlx_caps->mlc_max_rx_fe_dest); + ctx->mlfec_destination_list_size = to_be24(mlfe->mlfe_ndest); + for (i = 0; i < mlfe->mlfe_ndest; ++i) { + insize += sizeof (mlxcx_flow_dest_t); + d = &ctx->mlfec_destination[i]; + if (mlfe->mlfe_dest[i].mlfed_tir != NULL) { + d->mlfd_destination_type = MLXCX_FLOW_DEST_TIR; + d->mlfd_destination_id = to_be24( + mlfe->mlfe_dest[i].mlfed_tir->mltir_num); + } else if (mlfe->mlfe_dest[i].mlfed_flow != NULL) { + d->mlfd_destination_type = + MLXCX_FLOW_DEST_FLOW_TABLE; + d->mlfd_destination_id = to_be24( + mlfe->mlfe_dest[i].mlfed_flow->mlft_num); + } else { + /* Invalid flow entry destination */ + VERIFY(0); + } + } + break; + case MLXCX_FLOW_ACTION_COUNT: + /* We don't support count actions yet. */ + VERIFY(0); + break; + case MLXCX_FLOW_ACTION_ENCAP: + case MLXCX_FLOW_ACTION_DECAP: + /* We don't support encap/decap actions yet. */ + VERIFY(0); + break; + } + + hdrs = &ctx->mlfec_match_value.mlfm_outer_headers; + params = &ctx->mlfec_match_value.mlfm_misc_parameters; + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_SMAC) { + bcopy(mlfe->mlfe_smac, hdrs->mlfh_smac, + sizeof (hdrs->mlfh_smac)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_DMAC) { + bcopy(mlfe->mlfe_dmac, hdrs->mlfh_dmac, + sizeof (hdrs->mlfh_dmac)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VLAN) { + switch (mlfe->mlfe_vlan_type) { + case MLXCX_VLAN_TYPE_CVLAN: + set_bit24(&hdrs->mlfh_tcp_ip_flags, + MLXCX_FLOW_HDR_CVLAN_TAG); + break; + case MLXCX_VLAN_TYPE_SVLAN: + set_bit24(&hdrs->mlfh_tcp_ip_flags, + MLXCX_FLOW_HDR_SVLAN_TAG); + break; + default: + break; + } + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VID) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VLAN); + set_bits16(&hdrs->mlfh_first_vid_flags, + MLXCX_FLOW_HDR_FIRST_VID, mlfe->mlfe_vid); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER) { + set_bits24(&hdrs->mlfh_tcp_ip_flags, MLXCX_FLOW_HDR_IP_VERSION, + mlfe->mlfe_ip_version); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_SRCIP) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER); + bcopy(mlfe->mlfe_srcip, hdrs->mlfh_src_ip, + sizeof (hdrs->mlfh_src_ip)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_DSTIP) { + ASSERT(mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_VER); + bcopy(mlfe->mlfe_dstip, hdrs->mlfh_src_ip, + sizeof (hdrs->mlfh_dst_ip)); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_IP_PROTO) { + hdrs->mlfh_ip_protocol = mlfe->mlfe_ip_proto; + } + + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_SQN) { + params->mlfp_source_sqn = to_be24(mlfe->mlfe_sqn); + } + if (mlfg->mlfg_mask & MLXCX_FLOW_MATCH_VXLAN) { + params->mlfp_vxlan_vni = to_be24(mlfe->mlfe_vxlan_vni); + } + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlfe->mlfe_state |= MLXCX_FLOW_ENTRY_CREATED; + mlfe->mlfe_state &= ~MLXCX_FLOW_ENTRY_DIRTY; + mlfg->mlfg_state |= MLXCX_FLOW_GROUP_BUSY; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_delete_flow_table_entry(mlxcx_t *mlxp, mlxcx_flow_entry_t *mlfe) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_delete_flow_table_entry_in_t in; + mlxcx_cmd_delete_flow_table_entry_out_t out; + boolean_t ret; + const mlxcx_flow_table_t *mlft; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlft = mlfe->mlfe_table; + ASSERT(mutex_owned(&mlft->mlft_mtx)); + VERIFY(mlft->mlft_state & MLXCX_FLOW_TABLE_CREATED); + VERIFY0(mlft->mlft_state & MLXCX_FLOW_TABLE_DESTROYED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_delete_flow_table_entry_head, + MLXCX_OP_DELETE_FLOW_TABLE_ENTRY, 0); + + in.mlxi_delete_flow_table_entry_vport_number = + to_be16(mlft->mlft_port->mlp_num); + in.mlxi_delete_flow_table_entry_table_type = mlft->mlft_type; + in.mlxi_delete_flow_table_entry_table_id = to_be24(mlft->mlft_num); + in.mlxi_delete_flow_table_entry_flow_index = to_be32(mlfe->mlfe_index); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + /* + * Note that flow entries have a different lifecycle to most + * other things we create -- we have to be able to re-use them + * after they have been deleted, since they exist at a fixed + * position in their flow table. + * + * So we clear the CREATED bit here for them to let us call + * create_flow_table_entry() on the same entry again later. + */ + mlfe->mlfe_state &= ~MLXCX_FLOW_ENTRY_CREATED; + mlfe->mlfe_state |= MLXCX_FLOW_ENTRY_DELETED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_sq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_sq_in_t in; + mlxcx_cmd_create_sq_out_t out; + boolean_t ret; + mlxcx_sq_ctx_t *ctx; + size_t rem, insize; + const ddi_dma_cookie_t *c; + uint64_t pa, npages; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY3U(mlwq->mlwq_type, ==, MLXCX_WQ_TYPE_SENDQ); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY0(mlwq->mlwq_state & MLXCX_WQ_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_sq_head, + MLXCX_OP_CREATE_SQ, 0); + + ctx = &in.mlxi_create_sq_context; + + set_bit32(&ctx->mlsqc_flags, MLXCX_SQ_FLAGS_RLKEY); + set_bit32(&ctx->mlsqc_flags, MLXCX_SQ_FLAGS_FLUSH_IN_ERROR); + set_bits32(&ctx->mlsqc_flags, MLXCX_SQ_MIN_WQE_INLINE, + mlwq->mlwq_inline_mode); + ctx->mlsqc_cqn = to_be24(mlwq->mlwq_cq->mlcq_num); + + VERIFY(mlwq->mlwq_tis != NULL); + ctx->mlsqc_tis_lst_sz = to_be16(1); + ctx->mlsqc_tis_num = to_be24(mlwq->mlwq_tis->mltis_num); + + set_bits32(&ctx->mlsqc_wq.mlwqc_flags, MLXCX_WORKQ_CTX_TYPE, + MLXCX_WORKQ_TYPE_CYCLIC); + ctx->mlsqc_wq.mlwqc_pd = to_be24(mlwq->mlwq_pd->mlpd_num); + ctx->mlsqc_wq.mlwqc_uar_page = to_be24(mlwq->mlwq_uar->mlu_num); + ctx->mlsqc_wq.mlwqc_log_wq_sz = mlwq->mlwq_entshift; + ctx->mlsqc_wq.mlwqc_log_wq_stride = MLXCX_SENDQ_STRIDE_SHIFT; + + c = mlxcx_dma_cookie_one(&mlwq->mlwq_doorbell_dma); + ctx->mlsqc_wq.mlwqc_dbr_addr = to_be64(c->dmac_laddress); + ASSERT3U(c->dmac_size, >=, sizeof (mlxcx_workq_doorbell_t)); + + npages = 0; + c = NULL; + while ((c = mlxcx_dma_cookie_iter(&mlwq->mlwq_dma, c)) != NULL) { + pa = c->dmac_laddress; + rem = c->dmac_size; + while (rem > 0) { + ASSERT3U(pa & 0xfff, ==, 0); + ASSERT3U(rem, >=, MLXCX_HW_PAGE_SIZE); + ctx->mlsqc_wq.mlwqc_pas[npages++] = to_be64(pa); + rem -= MLXCX_HW_PAGE_SIZE; + pa += MLXCX_HW_PAGE_SIZE; + } + } + ASSERT3U(npages, <=, MLXCX_WORKQ_CTX_MAX_ADDRESSES); + + insize = offsetof(mlxcx_cmd_create_sq_in_t, mlxi_create_sq_context) + + offsetof(mlxcx_sq_ctx_t, mlsqc_wq) + + offsetof(mlxcx_workq_ctx_t, mlwqc_pas) + + sizeof (uint64_t) * npages; + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, insize, &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state |= MLXCX_WQ_CREATED; + mlwq->mlwq_num = from_be24(out.mlxo_create_sq_sqn); + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_start_sq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_modify_sq_in_t in; + mlxcx_cmd_modify_sq_out_t out; + boolean_t ret; + ddi_fm_error_t err; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + ASSERT(mlwq->mlwq_cq != NULL); + + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + VERIFY0(mlwq->mlwq_state & MLXCX_WQ_STARTED); + + /* + * Before starting the queue, we have to be sure that it is + * empty and the doorbell and counters are set to 0. + */ + ASSERT(mutex_owned(&mlwq->mlwq_cq->mlcq_mtx)); + ASSERT(list_is_empty(&mlwq->mlwq_cq->mlcq_buffers)); + ASSERT(list_is_empty(&mlwq->mlwq_cq->mlcq_buffers_b)); + + mlwq->mlwq_doorbell->mlwqd_recv_counter = to_be16(0); + MLXCX_DMA_SYNC(mlwq->mlwq_doorbell_dma, DDI_DMA_SYNC_FORDEV); + ddi_fm_dma_err_get(mlwq->mlwq_doorbell_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) + return (B_FALSE); + mlwq->mlwq_pc = 0; + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_modify_sq_head, + MLXCX_OP_MODIFY_SQ, 0); + + in.mlxi_modify_sq_sqn = to_be24(mlwq->mlwq_num); + + /* From state */ + set_bits8(&in.mlxi_modify_sq_state, MLXCX_CMD_MODIFY_SQ_STATE, + MLXCX_SQ_STATE_RST); + /* To state */ + set_bits32(&in.mlxi_modify_sq_context.mlsqc_flags, MLXCX_SQ_STATE, + MLXCX_SQ_STATE_RDY); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state |= MLXCX_WQ_STARTED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_stop_sq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_modify_sq_in_t in; + mlxcx_cmd_modify_sq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_STARTED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_modify_sq_head, + MLXCX_OP_MODIFY_SQ, 0); + + in.mlxi_modify_sq_sqn = to_be24(mlwq->mlwq_num); + + /* From state */ + set_bits8(&in.mlxi_modify_sq_state, MLXCX_CMD_MODIFY_SQ_STATE, + MLXCX_SQ_STATE_RDY); + /* To state */ + set_bits32(&in.mlxi_modify_sq_context.mlsqc_flags, MLXCX_SQ_STATE, + MLXCX_SQ_STATE_RST); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state &= ~MLXCX_WQ_STARTED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_sq(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_sq_in_t in; + mlxcx_cmd_destroy_sq_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + VERIFY(mlwq->mlwq_state & MLXCX_WQ_CREATED); + VERIFY0(mlwq->mlwq_state & MLXCX_WQ_STARTED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_sq_head, + MLXCX_OP_DESTROY_SQ, 0); + + in.mlxi_destroy_sq_sqn = to_be24(mlwq->mlwq_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlwq->mlwq_state |= MLXCX_WQ_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_create_rqt(mlxcx_t *mlxp, mlxcx_rqtable_t *mlrqt) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_create_rqt_in_t in; + mlxcx_cmd_create_rqt_out_t out; + mlxcx_rqtable_ctx_t *ctx; + boolean_t ret; + uint_t i; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + VERIFY0(mlrqt->mlrqt_state & MLXCX_RQT_CREATED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_create_rqt_head, + MLXCX_OP_CREATE_RQT, 0); + + ctx = &in.mlxi_create_rqt_context; + ASSERT3U(mlrqt->mlrqt_max, <=, MLXCX_RQT_MAX_RQ_REFS); + ASSERT3U(mlrqt->mlrqt_max, <=, mlxp->mlx_caps->mlc_max_rqt_size); + ctx->mlrqtc_max_size = to_be16(mlrqt->mlrqt_max); + ctx->mlrqtc_actual_size = to_be16(mlrqt->mlrqt_used); + for (i = 0; i < mlrqt->mlrqt_used; ++i) { + ctx->mlrqtc_rqref[i].mlrqtr_rqn = to_be24( + mlrqt->mlrqt_rq[i]->mlwq_num); + } + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlrqt->mlrqt_num = from_be24(out.mlxo_create_rqt_rqtn); + mlrqt->mlrqt_state |= MLXCX_RQT_CREATED; + mlrqt->mlrqt_state &= ~MLXCX_RQT_DIRTY; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_destroy_rqt(mlxcx_t *mlxp, mlxcx_rqtable_t *mlrqt) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_destroy_rqt_in_t in; + mlxcx_cmd_destroy_rqt_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + VERIFY(mlrqt->mlrqt_state & MLXCX_RQT_CREATED); + VERIFY0(mlrqt->mlrqt_state & MLXCX_RQT_DESTROYED); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_destroy_rqt_head, + MLXCX_OP_DESTROY_RQT, 0); + + in.mlxi_destroy_rqt_rqtn = to_be24(mlrqt->mlrqt_num); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + if (ret) { + mlrqt->mlrqt_state |= MLXCX_RQT_DESTROYED; + } + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +boolean_t +mlxcx_cmd_set_int_mod(mlxcx_t *mlxp, uint_t intr, uint_t min_delay) +{ + mlxcx_cmd_t cmd; + mlxcx_cmd_config_int_mod_in_t in; + mlxcx_cmd_config_int_mod_out_t out; + boolean_t ret; + + bzero(&in, sizeof (in)); + bzero(&out, sizeof (out)); + + mlxcx_cmd_init(mlxp, &cmd); + mlxcx_cmd_in_header_init(&cmd, &in.mlxi_config_int_mod_head, + MLXCX_OP_CONFIG_INT_MODERATION, MLXCX_CMD_CONFIG_INT_MOD_WRITE); + + in.mlxi_config_int_mod_int_vector = to_be16(intr); + in.mlxi_config_int_mod_min_delay = to_be16(min_delay); + + if (!mlxcx_cmd_send(mlxp, &cmd, &in, sizeof (in), &out, sizeof (out))) { + mlxcx_cmd_fini(mlxp, &cmd); + return (B_FALSE); + } + mlxcx_cmd_wait(&cmd); + + ret = mlxcx_cmd_evaluate(mlxp, &cmd); + mlxcx_cmd_fini(mlxp, &cmd); + return (ret); +} + +/* + * CTASSERTs here are for the structs in mlxcx_reg.h, to check they match + * against offsets from the PRM. + * + * They're not in the header file, to avoid them being used by multiple .c + * files. + */ + +CTASSERT(offsetof(mlxcx_eventq_ent_t, mleqe_unknown_data) == 0x20); +CTASSERT(offsetof(mlxcx_eventq_ent_t, mleqe_signature) == 0x3c + 2); +CTASSERT(sizeof (mlxcx_eventq_ent_t) == 64); + +CTASSERT(offsetof(mlxcx_completionq_error_ent_t, mlcqee_byte_cnt) == 0x2C); +CTASSERT(offsetof(mlxcx_completionq_error_ent_t, mlcqee_wqe_opcode) == 0x38); + +CTASSERT(sizeof (mlxcx_completionq_error_ent_t) == + sizeof (mlxcx_completionq_ent_t)); +CTASSERT(sizeof (mlxcx_wqe_control_seg_t) == (1 << 4)); + +CTASSERT(offsetof(mlxcx_wqe_eth_seg_t, mles_inline_headers) == 0x0e); +CTASSERT(sizeof (mlxcx_wqe_eth_seg_t) == (1 << 5)); + +CTASSERT(sizeof (mlxcx_wqe_data_seg_t) == (1 << 4)); + +CTASSERT(sizeof (mlxcx_sendq_ent_t) == (1 << MLXCX_SENDQ_STRIDE_SHIFT)); + +CTASSERT(sizeof (mlxcx_sendq_bf_t) == (1 << MLXCX_SENDQ_STRIDE_SHIFT)); + +CTASSERT(sizeof (mlxcx_sendq_extra_ent_t) == (1 << MLXCX_SENDQ_STRIDE_SHIFT)); + +CTASSERT(sizeof (mlxcx_recvq_ent_t) == (1 << MLXCX_RECVQ_STRIDE_SHIFT)); + +CTASSERT(offsetof(mlxcx_workq_ctx_t, mlwqc_dbr_addr) == 0x10); +CTASSERT(offsetof(mlxcx_workq_ctx_t, mlwqc_pas) == 0xc0); + +CTASSERT(offsetof(mlxcx_rq_ctx_t, mlrqc_cqn) == 0x09); +CTASSERT(offsetof(mlxcx_rq_ctx_t, mlrqc_wq) == 0x30); + +CTASSERT(offsetof(mlxcx_sq_ctx_t, mlsqc_cqn) == 0x09); +CTASSERT(offsetof(mlxcx_sq_ctx_t, mlsqc_tis_lst_sz) == 0x20); +CTASSERT(offsetof(mlxcx_sq_ctx_t, mlsqc_tis_num) == 0x2d); +CTASSERT(offsetof(mlxcx_sq_ctx_t, mlsqc_wq) == 0x30); + +CTASSERT(sizeof (mlxcx_tis_ctx_t) == 0xa0); +CTASSERT(offsetof(mlxcx_tis_ctx_t, mltisc_transport_domain) == 0x25); + +CTASSERT(offsetof(mlxcx_rqtable_ctx_t, mlrqtc_max_size) == 0x16); +CTASSERT(offsetof(mlxcx_rqtable_ctx_t, mlrqtc_rqref) == 0xF0); + +CTASSERT(offsetof(mlxcx_cmd_create_eq_in_t, mlxi_create_eq_event_bitmask) == + 0x58); +CTASSERT(offsetof(mlxcx_cmd_create_eq_in_t, mlxi_create_eq_pas) == 0x110); +CTASSERT(offsetof(mlxcx_cmd_create_eq_in_t, mlxi_create_eq_context) == 0x10); + +CTASSERT(offsetof(mlxcx_cmd_create_tir_in_t, mlxi_create_tir_context) == 0x20); + +CTASSERT(offsetof(mlxcx_cmd_create_tis_in_t, mlxi_create_tis_context) == 0x20); + +CTASSERT(offsetof(mlxcx_cmd_query_special_ctxs_out_t, + mlxo_query_special_ctxs_resd_lkey) == 0x0c); + +CTASSERT(offsetof(mlxcx_cmd_query_cq_out_t, mlxo_query_cq_context) == 0x10); +CTASSERT(offsetof(mlxcx_cmd_query_cq_out_t, mlxo_query_cq_pas) == 0x110); + +CTASSERT(offsetof(mlxcx_cmd_query_rq_out_t, mlxo_query_rq_context) == 0x20); + +CTASSERT(offsetof(mlxcx_cmd_create_sq_in_t, mlxi_create_sq_context) == 0x20); + +CTASSERT(offsetof(mlxcx_cmd_modify_sq_in_t, mlxi_modify_sq_context) == 0x20); + +CTASSERT(offsetof(mlxcx_cmd_query_sq_out_t, mlxo_query_sq_context) == 0x20); + +CTASSERT(offsetof(mlxcx_cmd_create_rqt_in_t, mlxi_create_rqt_context) == 0x20); + +CTASSERT(offsetof(mlxcx_reg_pmtu_t, mlrd_pmtu_oper_mtu) == 0x0C); + +CTASSERT(sizeof (mlxcx_reg_ptys_t) == 64); +CTASSERT(offsetof(mlxcx_reg_ptys_t, mlrd_ptys_proto_cap) == 0x0c); +CTASSERT(offsetof(mlxcx_reg_ptys_t, mlrd_ptys_proto_admin) == 0x18); +CTASSERT(offsetof(mlxcx_reg_ptys_t, mlrd_ptys_proto_partner_advert) == 0x30); + +CTASSERT(offsetof(mlxcx_reg_mcia_t, mlrd_mcia_data) == 0x10); + +CTASSERT(offsetof(mlxcx_ppcnt_ieee_802_3_t, + mlppc_ieee_802_3_in_range_len_err) == 0x50); +CTASSERT(offsetof(mlxcx_ppcnt_ieee_802_3_t, + mlppc_ieee_802_3_pause_tx) == 0x90); + +CTASSERT(sizeof (mlxcx_reg_ppcnt_t) == 256); +CTASSERT(offsetof(mlxcx_reg_ppcnt_t, mlrd_ppcnt_data) == 0x08); + +CTASSERT(offsetof(mlxcx_cmd_access_register_in_t, + mlxi_access_register_argument) == 0x0C); +CTASSERT(offsetof(mlxcx_cmd_access_register_in_t, + mlxi_access_register_data) == 0x10); + +CTASSERT(offsetof(mlxcx_cmd_access_register_out_t, + mlxo_access_register_data) == 0x10); diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_dma.c b/usr/src/uts/common/io/mlxcx/mlxcx_dma.c new file mode 100644 index 0000000000..79b9bb3746 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_dma.c @@ -0,0 +1,460 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020, The University of Queensland + * Copyright (c) 2018, Joyent, Inc. + */ + +/* + * DMA allocation and tear down routines. + */ + +#include <mlxcx.h> + +void +mlxcx_dma_acc_attr(mlxcx_t *mlxp, ddi_device_acc_attr_t *accp) +{ + bzero(accp, sizeof (*accp)); + accp->devacc_attr_version = DDI_DEVICE_ATTR_V0; + accp->devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; + accp->devacc_attr_dataorder = DDI_STRICTORDER_ACC; + + if (DDI_FM_DMA_ERR_CAP(mlxp->mlx_fm_caps)) { + accp->devacc_attr_access = DDI_FLAGERR_ACC; + } else { + accp->devacc_attr_access = DDI_DEFAULT_ACC; + } +} + +void +mlxcx_dma_page_attr(mlxcx_t *mlxp, ddi_dma_attr_t *attrp) +{ + bzero(attrp, sizeof (*attrp)); + attrp->dma_attr_version = DMA_ATTR_V0; + + /* + * This is a 64-bit PCIe device. We can use the entire address space. + */ + attrp->dma_attr_addr_lo = 0x0; + attrp->dma_attr_addr_hi = UINT64_MAX; + + /* + * The count max indicates the total amount that can fit into one + * cookie. Because we're creating a single page for tracking purposes, + * this can be a page in size. The alignment and segment are related to + * this same requirement. The alignment needs to be page aligned and the + * segment is the boundary that this can't cross, aka a 4k page. + */ + attrp->dma_attr_count_max = MLXCX_CMD_DMA_PAGE_SIZE - 1; + attrp->dma_attr_align = MLXCX_CMD_DMA_PAGE_SIZE; + attrp->dma_attr_seg = MLXCX_CMD_DMA_PAGE_SIZE - 1; + + attrp->dma_attr_burstsizes = 0xfff; + + /* + * The minimum and and maximum sizes that we can send. We cap this based + * on the use of this, which is a page size. + */ + attrp->dma_attr_minxfer = 0x1; + attrp->dma_attr_maxxfer = MLXCX_CMD_DMA_PAGE_SIZE; + + /* + * This is supposed to be used for static data structures, therefore we + * keep this just to a page. + */ + attrp->dma_attr_sgllen = 1; + + /* + * The granularity describe the addressing graularity. That is, the + * hardware can ask for chunks in this units of bytes. + */ + attrp->dma_attr_granular = MLXCX_CMD_DMA_PAGE_SIZE; + + if (DDI_FM_DMA_ERR_CAP(mlxp->mlx_fm_caps)) { + attrp->dma_attr_flags = DDI_DMA_FLAGERR; + } else { + attrp->dma_attr_flags = 0; + } +} + +/* + * DMA attributes for queue memory (EQ, CQ, WQ etc) + * + * These have to allocate in units of whole pages, but can be multiple + * pages and don't have to be physically contiguous. + */ +void +mlxcx_dma_queue_attr(mlxcx_t *mlxp, ddi_dma_attr_t *attrp) +{ + bzero(attrp, sizeof (*attrp)); + attrp->dma_attr_version = DMA_ATTR_V0; + + /* + * This is a 64-bit PCIe device. We can use the entire address space. + */ + attrp->dma_attr_addr_lo = 0x0; + attrp->dma_attr_addr_hi = UINT64_MAX; + + attrp->dma_attr_count_max = MLXCX_QUEUE_DMA_PAGE_SIZE - 1; + + attrp->dma_attr_align = MLXCX_QUEUE_DMA_PAGE_SIZE; + + attrp->dma_attr_burstsizes = 0xfff; + + /* + * The minimum and and maximum sizes that we can send. We cap this based + * on the use of this, which is a page size. + */ + attrp->dma_attr_minxfer = MLXCX_QUEUE_DMA_PAGE_SIZE; + attrp->dma_attr_maxxfer = UINT32_MAX; + + attrp->dma_attr_seg = UINT64_MAX; + + attrp->dma_attr_granular = MLXCX_QUEUE_DMA_PAGE_SIZE; + + /* But we can have more than one. */ + attrp->dma_attr_sgllen = MLXCX_CREATE_QUEUE_MAX_PAGES; + + if (DDI_FM_DMA_ERR_CAP(mlxp->mlx_fm_caps)) { + attrp->dma_attr_flags = DDI_DMA_FLAGERR; + } else { + attrp->dma_attr_flags = 0; + } +} + +/* + * DMA attributes for packet buffers + */ +void +mlxcx_dma_buf_attr(mlxcx_t *mlxp, ddi_dma_attr_t *attrp) +{ + bzero(attrp, sizeof (*attrp)); + attrp->dma_attr_version = DMA_ATTR_V0; + + /* + * This is a 64-bit PCIe device. We can use the entire address space. + */ + attrp->dma_attr_addr_lo = 0x0; + attrp->dma_attr_addr_hi = UINT64_MAX; + + /* + * Each scatter pointer has a 32-bit length field. + */ + attrp->dma_attr_count_max = UINT32_MAX; + + /* + * The PRM gives us no alignment requirements for scatter pointers, + * but it implies that units < 16bytes are a bad idea. + */ + attrp->dma_attr_align = 16; + attrp->dma_attr_granular = 1; + + attrp->dma_attr_burstsizes = 0xfff; + + attrp->dma_attr_minxfer = 1; + attrp->dma_attr_maxxfer = UINT64_MAX; + + attrp->dma_attr_seg = UINT64_MAX; + + /* + * We choose how many scatter pointers we're allowed per packet when + * we set the recv queue stride. This macro is from mlxcx_reg.h where + * we fix that for all of our receive queues. + */ + attrp->dma_attr_sgllen = MLXCX_RECVQ_MAX_PTRS; + + if (DDI_FM_DMA_ERR_CAP(mlxp->mlx_fm_caps)) { + attrp->dma_attr_flags = DDI_DMA_FLAGERR; + } else { + attrp->dma_attr_flags = 0; + } +} + +/* + * DMA attributes for queue doorbells + */ +void +mlxcx_dma_qdbell_attr(mlxcx_t *mlxp, ddi_dma_attr_t *attrp) +{ + bzero(attrp, sizeof (*attrp)); + attrp->dma_attr_version = DMA_ATTR_V0; + + /* + * This is a 64-bit PCIe device. We can use the entire address space. + */ + attrp->dma_attr_addr_lo = 0x0; + attrp->dma_attr_addr_hi = UINT64_MAX; + + /* + * Queue doorbells are always exactly 16 bytes in length, but + * the ddi_dma functions don't like such small values of count_max. + * + * We tell some lies here. + */ + attrp->dma_attr_count_max = MLXCX_QUEUE_DMA_PAGE_SIZE - 1; + attrp->dma_attr_align = 8; + attrp->dma_attr_burstsizes = 0x8; + attrp->dma_attr_minxfer = 1; + attrp->dma_attr_maxxfer = UINT16_MAX; + attrp->dma_attr_seg = MLXCX_QUEUE_DMA_PAGE_SIZE - 1; + attrp->dma_attr_granular = 1; + attrp->dma_attr_sgllen = 1; + + if (DDI_FM_DMA_ERR_CAP(mlxp->mlx_fm_caps)) { + attrp->dma_attr_flags = DDI_DMA_FLAGERR; + } else { + attrp->dma_attr_flags = 0; + } +} + +void +mlxcx_dma_free(mlxcx_dma_buffer_t *mxdb) +{ + int ret; + + if (mxdb->mxdb_flags & MLXCX_DMABUF_BOUND) { + VERIFY(mxdb->mxdb_dma_handle != NULL); + ret = ddi_dma_unbind_handle(mxdb->mxdb_dma_handle); + VERIFY3S(ret, ==, DDI_SUCCESS); + mxdb->mxdb_flags &= ~MLXCX_DMABUF_BOUND; + mxdb->mxdb_ncookies = 0; + } + + if (mxdb->mxdb_flags & MLXCX_DMABUF_MEM_ALLOC) { + ddi_dma_mem_free(&mxdb->mxdb_acc_handle); + mxdb->mxdb_acc_handle = NULL; + mxdb->mxdb_va = NULL; + mxdb->mxdb_len = 0; + mxdb->mxdb_flags &= ~MLXCX_DMABUF_MEM_ALLOC; + } + + if (mxdb->mxdb_flags & MLXCX_DMABUF_FOREIGN) { + /* The mblk will be freed separately */ + mxdb->mxdb_va = NULL; + mxdb->mxdb_len = 0; + mxdb->mxdb_flags &= ~MLXCX_DMABUF_FOREIGN; + } + + if (mxdb->mxdb_flags & MLXCX_DMABUF_HDL_ALLOC) { + ddi_dma_free_handle(&mxdb->mxdb_dma_handle); + mxdb->mxdb_dma_handle = NULL; + mxdb->mxdb_flags &= ~MLXCX_DMABUF_HDL_ALLOC; + } + + ASSERT3U(mxdb->mxdb_flags, ==, 0); + ASSERT3P(mxdb->mxdb_dma_handle, ==, NULL); + ASSERT3P(mxdb->mxdb_va, ==, NULL); + ASSERT3U(mxdb->mxdb_len, ==, 0); + ASSERT3U(mxdb->mxdb_ncookies, ==, 0); +} + +void +mlxcx_dma_unbind(mlxcx_t *mlxp, mlxcx_dma_buffer_t *mxdb) +{ + int ret; + + ASSERT(mxdb->mxdb_flags & MLXCX_DMABUF_HDL_ALLOC); + ASSERT(mxdb->mxdb_flags & MLXCX_DMABUF_BOUND); + + if (mxdb->mxdb_flags & MLXCX_DMABUF_FOREIGN) { + /* The mblk will be freed separately */ + mxdb->mxdb_va = NULL; + mxdb->mxdb_len = 0; + mxdb->mxdb_flags &= ~MLXCX_DMABUF_FOREIGN; + } + + ret = ddi_dma_unbind_handle(mxdb->mxdb_dma_handle); + VERIFY3S(ret, ==, DDI_SUCCESS); + mxdb->mxdb_flags &= ~MLXCX_DMABUF_BOUND; + mxdb->mxdb_ncookies = 0; +} + +boolean_t +mlxcx_dma_init(mlxcx_t *mlxp, mlxcx_dma_buffer_t *mxdb, + ddi_dma_attr_t *attrp, boolean_t wait) +{ + int ret; + int (*memcb)(caddr_t); + + if (wait == B_TRUE) { + memcb = DDI_DMA_SLEEP; + } else { + memcb = DDI_DMA_DONTWAIT; + } + + ASSERT3S(mxdb->mxdb_flags, ==, 0); + + ret = ddi_dma_alloc_handle(mlxp->mlx_dip, attrp, memcb, NULL, + &mxdb->mxdb_dma_handle); + if (ret != 0) { + mlxcx_warn(mlxp, "!failed to allocate DMA handle: %d", ret); + mxdb->mxdb_dma_handle = NULL; + return (B_FALSE); + } + mxdb->mxdb_flags |= MLXCX_DMABUF_HDL_ALLOC; + + return (B_TRUE); +} + +boolean_t +mlxcx_dma_bind_mblk(mlxcx_t *mlxp, mlxcx_dma_buffer_t *mxdb, + const mblk_t *mp, size_t off, boolean_t wait) +{ + int ret; + uint_t flags = DDI_DMA_STREAMING; + int (*memcb)(caddr_t); + + if (wait == B_TRUE) { + memcb = DDI_DMA_SLEEP; + } else { + memcb = DDI_DMA_DONTWAIT; + } + + ASSERT(mxdb->mxdb_flags & MLXCX_DMABUF_HDL_ALLOC); + ASSERT0(mxdb->mxdb_flags & + (MLXCX_DMABUF_FOREIGN | MLXCX_DMABUF_MEM_ALLOC)); + ASSERT0(mxdb->mxdb_flags & MLXCX_DMABUF_BOUND); + + ASSERT3U(off, <=, MBLKL(mp)); + mxdb->mxdb_va = (caddr_t)(mp->b_rptr + off); + mxdb->mxdb_len = MBLKL(mp) - off; + mxdb->mxdb_flags |= MLXCX_DMABUF_FOREIGN; + + ret = ddi_dma_addr_bind_handle(mxdb->mxdb_dma_handle, NULL, + mxdb->mxdb_va, mxdb->mxdb_len, DDI_DMA_WRITE | flags, memcb, NULL, + NULL, NULL); + if (ret != DDI_DMA_MAPPED) { + mxdb->mxdb_va = NULL; + mxdb->mxdb_len = 0; + mxdb->mxdb_flags &= ~MLXCX_DMABUF_FOREIGN; + return (B_FALSE); + } + mxdb->mxdb_flags |= MLXCX_DMABUF_BOUND; + mxdb->mxdb_ncookies = ddi_dma_ncookies(mxdb->mxdb_dma_handle); + + return (B_TRUE); +} + +boolean_t +mlxcx_dma_alloc(mlxcx_t *mlxp, mlxcx_dma_buffer_t *mxdb, + ddi_dma_attr_t *attrp, ddi_device_acc_attr_t *accp, boolean_t zero, + size_t size, boolean_t wait) +{ + int ret; + uint_t flags = DDI_DMA_CONSISTENT; + size_t len; + int (*memcb)(caddr_t); + + if (wait == B_TRUE) { + memcb = DDI_DMA_SLEEP; + } else { + memcb = DDI_DMA_DONTWAIT; + } + + ASSERT3U(mxdb->mxdb_flags, ==, 0); + + ret = ddi_dma_alloc_handle(mlxp->mlx_dip, attrp, memcb, NULL, + &mxdb->mxdb_dma_handle); + if (ret != 0) { + mlxcx_warn(mlxp, "!failed to allocate DMA handle: %d", ret); + mxdb->mxdb_dma_handle = NULL; + return (B_FALSE); + } + mxdb->mxdb_flags |= MLXCX_DMABUF_HDL_ALLOC; + + ret = ddi_dma_mem_alloc(mxdb->mxdb_dma_handle, size, accp, flags, memcb, + NULL, &mxdb->mxdb_va, &len, &mxdb->mxdb_acc_handle); + if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "!failed to allocate DMA memory: %d", ret); + mxdb->mxdb_va = NULL; + mxdb->mxdb_acc_handle = NULL; + mlxcx_dma_free(mxdb); + return (B_FALSE); + } + mxdb->mxdb_len = size; + mxdb->mxdb_flags |= MLXCX_DMABUF_MEM_ALLOC; + + if (zero == B_TRUE) + bzero(mxdb->mxdb_va, len); + + ret = ddi_dma_addr_bind_handle(mxdb->mxdb_dma_handle, NULL, + mxdb->mxdb_va, len, DDI_DMA_RDWR | flags, memcb, NULL, NULL, + NULL); + if (ret != 0) { + mlxcx_warn(mlxp, "!failed to bind DMA memory: %d", ret); + mlxcx_dma_free(mxdb); + return (B_FALSE); + } + mxdb->mxdb_flags |= MLXCX_DMABUF_BOUND; + mxdb->mxdb_ncookies = ddi_dma_ncookies(mxdb->mxdb_dma_handle); + + return (B_TRUE); +} + +boolean_t +mlxcx_dma_alloc_offset(mlxcx_t *mlxp, mlxcx_dma_buffer_t *mxdb, + ddi_dma_attr_t *attrp, ddi_device_acc_attr_t *accp, boolean_t zero, + size_t size, size_t offset, boolean_t wait) +{ + int ret; + uint_t flags = DDI_DMA_STREAMING; + size_t len; + int (*memcb)(caddr_t); + + if (wait == B_TRUE) { + memcb = DDI_DMA_SLEEP; + } else { + memcb = DDI_DMA_DONTWAIT; + } + + ASSERT3U(mxdb->mxdb_flags, ==, 0); + + ret = ddi_dma_alloc_handle(mlxp->mlx_dip, attrp, memcb, NULL, + &mxdb->mxdb_dma_handle); + if (ret != 0) { + mlxcx_warn(mlxp, "!failed to allocate DMA handle: %d", ret); + mxdb->mxdb_dma_handle = NULL; + return (B_FALSE); + } + mxdb->mxdb_flags |= MLXCX_DMABUF_HDL_ALLOC; + + ret = ddi_dma_mem_alloc(mxdb->mxdb_dma_handle, size + offset, accp, + flags, memcb, NULL, &mxdb->mxdb_va, &len, &mxdb->mxdb_acc_handle); + if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "!failed to allocate DMA memory: %d", ret); + mxdb->mxdb_va = NULL; + mxdb->mxdb_acc_handle = NULL; + mlxcx_dma_free(mxdb); + return (B_FALSE); + } + + if (zero == B_TRUE) + bzero(mxdb->mxdb_va, len); + + mxdb->mxdb_va += offset; + len -= offset; + mxdb->mxdb_len = len; + mxdb->mxdb_flags |= MLXCX_DMABUF_MEM_ALLOC; + + ret = ddi_dma_addr_bind_handle(mxdb->mxdb_dma_handle, NULL, + mxdb->mxdb_va, len, DDI_DMA_RDWR | flags, memcb, NULL, NULL, + NULL); + if (ret != 0) { + mlxcx_warn(mlxp, "!failed to bind DMA memory: %d", ret); + mlxcx_dma_free(mxdb); + return (B_FALSE); + } + mxdb->mxdb_flags |= MLXCX_DMABUF_BOUND; + mxdb->mxdb_ncookies = ddi_dma_ncookies(mxdb->mxdb_dma_handle); + + return (B_TRUE); +} diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_endint.h b/usr/src/uts/common/io/mlxcx/mlxcx_endint.h new file mode 100644 index 0000000000..4ad69173c0 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_endint.h @@ -0,0 +1,305 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020, The University of Queensland + */ + +#ifndef _MLXCX_ENDINT_H +#define _MLXCX_ENDINT_H + +#include <sys/types.h> +#include <sys/byteorder.h> + +/* + * The inlines and structs in this file are used by mlxcx to ensure endian + * safety when dealing with memory-mapped structures from the device, and + * also simpler use of 24-bit integers (which Mellanox loves). + * + * By declaring all of these values in the memory-mapped structures as structs + * (e.g. uint32be_t) rather than bare integers (uint32_t) we ensure that the + * compiler will not allow them to be silently converted to integers and used + * without doing the necessary byte-swapping work. + * + * The uintXbe_t structs are designed to be used inside a #pragma pack(1) + * context only and we don't try to fix up their alignment. + * + * Also present in here are a number of bitsX_t types which can be used to + * gain a little bit of type safety when dealing with endian-swapped bitfields. + */ + +#pragma pack(1) +typedef struct { uint16_t be_val; } uint16be_t; +typedef struct { uint8_t be_val[3]; } uint24be_t; +typedef struct { uint32_t be_val; } uint32be_t; +typedef struct { uint64_t be_val; } uint64be_t; +#pragma pack() + +static inline uint16_t +from_be16(uint16be_t v) +{ + return (BE_16(v.be_val)); +} + +static inline uint32_t +from_be24(uint24be_t v) +{ + return (((uint32_t)v.be_val[0] << 16) | + ((uint32_t)v.be_val[1] << 8) | + ((uint32_t)v.be_val[2])); +} + +static inline uint32_t +from_be32(uint32be_t v) +{ + return (BE_32(v.be_val)); +} + +static inline uint64_t +from_be64(uint64be_t v) +{ + return (BE_64(v.be_val)); +} + +static inline uint16be_t +to_be16(uint16_t v) +{ + /* CSTYLED */ + return ((uint16be_t){ .be_val = BE_16(v) }); +} + +static inline uint24be_t +to_be24(uint32_t v) +{ + /* CSTYLED */ + return ((uint24be_t){ .be_val = { + (v & 0xFF0000) >> 16, + (v & 0x00FF00) >> 8, + (v & 0x0000FF) + }}); +} + +static inline uint32be_t +to_be32(uint32_t v) +{ + /* CSTYLED */ + return ((uint32be_t){ .be_val = BE_32(v) }); +} + +static inline uint64be_t +to_be64(uint64_t v) +{ + /* CSTYLED */ + return ((uint64be_t){ .be_val = BE_64(v) }); +} + +#pragma pack(1) +typedef struct { uint8_t bit_val; } bits8_t; +typedef struct { uint16_t bit_val; } bits16_t; +typedef struct { uint32_t bit_val; } bits32_t; +typedef struct { uint24be_t bit_val; } bits24_t; +typedef struct { uint64_t bit_val; } bits64_t; +typedef struct { uint64_t bit_shift; uint64_t bit_mask; } bitdef_t; +#pragma pack() + +static inline uint8_t +get_bits8(bits8_t v, bitdef_t d) +{ + return ((v.bit_val & d.bit_mask) >> d.bit_shift); +} +static inline void +set_bits8(bits8_t *v, bitdef_t d, uint8_t val) +{ + v->bit_val &= ~d.bit_mask; + v->bit_val |= (val << d.bit_shift) & d.bit_mask; +} +static inline uint8_t +get_bit8(bits8_t v, uint8_t mask) +{ + return ((v.bit_val & mask) != 0); +} +static inline void +set_bit8(bits8_t *v, uint8_t mask) +{ + v->bit_val |= mask; +} +static inline void +clear_bit8(bits8_t *v, uint8_t mask) +{ + v->bit_val &= ~mask; +} +static inline bits8_t +new_bits8(void) +{ + /* CSTYLED */ + return ((bits8_t){ .bit_val = 0 }); +} +static inline uint8_t +from_bits8(bits8_t v) +{ + return (v.bit_val); +} + +static inline uint16_t +get_bits16(bits16_t v, bitdef_t d) +{ + return ((BE_16(v.bit_val) & d.bit_mask) >> d.bit_shift); +} +static inline void +set_bits16(bits16_t *v, bitdef_t d, uint16_t val) +{ + v->bit_val &= BE_16(~d.bit_mask); + v->bit_val |= BE_16((val << d.bit_shift) & d.bit_mask); +} +static inline uint16_t +get_bit16(bits16_t v, uint16_t mask) +{ + return ((BE_16(v.bit_val) & mask) != 0); +} +static inline void +set_bit16(bits16_t *v, uint16_t mask) +{ + v->bit_val |= BE_16(mask); +} +static inline void +clear_bit16(bits16_t *v, uint16_t mask) +{ + v->bit_val &= BE_16(~mask); +} +static inline bits16_t +new_bits16(void) +{ + /* CSTYLED */ + return ((bits16_t){ .bit_val = 0 }); +} +static inline uint16_t +from_bits16(bits16_t v) +{ + return (BE_16(v.bit_val)); +} + +static inline uint32_t +get_bits32(bits32_t v, bitdef_t d) +{ + return ((BE_32(v.bit_val) & d.bit_mask) >> d.bit_shift); +} +static inline void +set_bits32(bits32_t *v, bitdef_t d, uint32_t val) +{ + v->bit_val &= BE_32(~d.bit_mask); + v->bit_val |= BE_32((val << d.bit_shift) & d.bit_mask); +} +static inline uint32_t +get_bit32(bits32_t v, uint32_t mask) +{ + return ((BE_32(v.bit_val) & mask) != 0); +} +static inline void +set_bit32(bits32_t *v, uint32_t mask) +{ + v->bit_val |= BE_32(mask); +} +static inline void +clear_bit32(bits32_t *v, uint32_t mask) +{ + v->bit_val &= BE_32(~mask); +} +static inline bits32_t +new_bits32(void) +{ + /* CSTYLED */ + return ((bits32_t){ .bit_val = 0 }); +} +static inline uint32_t +from_bits32(bits32_t v) +{ + return (BE_32(v.bit_val)); +} + +static inline uint32_t +get_bits24(bits24_t v, bitdef_t d) +{ + return ((from_be24(v.bit_val) & d.bit_mask) >> d.bit_shift); +} +static inline void +set_bits24(bits24_t *v, bitdef_t d, uint32_t val) +{ + uint32_t vv = from_be24(v->bit_val); + vv &= ~d.bit_mask; + vv |= (val << d.bit_shift) & d.bit_mask; + v->bit_val = to_be24(vv); +} +static inline uint32_t +get_bit24(bits24_t v, uint32_t mask) +{ + return ((from_be24(v.bit_val) & mask) != 0); +} +static inline void +set_bit24(bits24_t *v, uint32_t mask) +{ + v->bit_val = to_be24(from_be24(v->bit_val) | mask); +} +static inline void +clear_bit24(bits24_t *v, uint32_t mask) +{ + v->bit_val = to_be24(from_be24(v->bit_val) & ~mask); +} +static inline bits24_t +new_bits24(void) +{ + /* CSTYLED */ + return ((bits24_t){ .bit_val = to_be24(0) }); +} +static inline uint32_t +from_bits24(bits24_t v) +{ + return (from_be24(v.bit_val)); +} + +static inline uint64_t +get_bits64(bits64_t v, bitdef_t d) +{ + return ((BE_64(v.bit_val) & d.bit_mask) >> d.bit_shift); +} +static inline void +set_bits64(bits64_t *v, bitdef_t d, uint64_t val) +{ + v->bit_val &= BE_64(~d.bit_mask); + v->bit_val |= BE_64((val << d.bit_shift) & d.bit_mask); +} +static inline uint64_t +get_bit64(bits64_t v, uint64_t mask) +{ + return ((BE_64(v.bit_val) & mask) != 0); +} +static inline void +set_bit64(bits64_t *v, uint64_t mask) +{ + v->bit_val |= BE_64(mask); +} +static inline void +clear_bit64(bits64_t *v, uint64_t mask) +{ + v->bit_val &= BE_64(~mask); +} +static inline bits64_t +new_bits64(void) +{ + /* CSTYLED */ + return ((bits64_t){ .bit_val = 0 }); +} +static inline uint64_t +from_bits64(bits64_t v) +{ + return (BE_64(v.bit_val)); +} + +#endif /* _MLXCX_ENDINT_H */ diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_gld.c b/usr/src/uts/common/io/mlxcx/mlxcx_gld.c new file mode 100644 index 0000000000..871c4f30b3 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_gld.c @@ -0,0 +1,1254 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2020, the University of Queensland + */ + +/* + * Mellanox Connect-X 4/5/6 driver. + */ + +#include <sys/modctl.h> +#include <sys/conf.h> +#include <sys/devops.h> +#include <sys/sysmacros.h> +#include <sys/vlan.h> + +#include <sys/pattr.h> +#include <sys/dlpi.h> + +#include <sys/mac_provider.h> + +/* Need these for mac_vlan_header_info() */ +#include <sys/mac_client.h> +#include <sys/mac_client_priv.h> + +#include <mlxcx.h> + +static char *mlxcx_priv_props[] = { + NULL +}; + +#define MBITS 1000000ULL +#define GBITS (1000ULL * MBITS) + +static uint64_t +mlxcx_speed_to_bits(mlxcx_eth_proto_t v) +{ + switch (v) { + case MLXCX_PROTO_SGMII_100BASE: + return (100ULL * MBITS); + case MLXCX_PROTO_SGMII: + case MLXCX_PROTO_1000BASE_KX: + return (1000ULL * MBITS); + case MLXCX_PROTO_10GBASE_CX4: + case MLXCX_PROTO_10GBASE_KX4: + case MLXCX_PROTO_10GBASE_KR: + case MLXCX_PROTO_10GBASE_CR: + case MLXCX_PROTO_10GBASE_SR: + case MLXCX_PROTO_10GBASE_ER_LR: + return (10ULL * GBITS); + case MLXCX_PROTO_40GBASE_CR4: + case MLXCX_PROTO_40GBASE_KR4: + case MLXCX_PROTO_40GBASE_SR4: + case MLXCX_PROTO_40GBASE_LR4_ER4: + return (40ULL * GBITS); + case MLXCX_PROTO_25GBASE_CR: + case MLXCX_PROTO_25GBASE_KR: + case MLXCX_PROTO_25GBASE_SR: + return (25ULL * GBITS); + case MLXCX_PROTO_50GBASE_SR2: + case MLXCX_PROTO_50GBASE_CR2: + case MLXCX_PROTO_50GBASE_KR2: + return (50ULL * GBITS); + case MLXCX_PROTO_100GBASE_CR4: + case MLXCX_PROTO_100GBASE_SR4: + case MLXCX_PROTO_100GBASE_KR4: + return (100ULL * GBITS); + default: + return (0); + } +} + +static int +mlxcx_mac_stat_rfc_2863(mlxcx_t *mlxp, mlxcx_port_t *port, uint_t stat, + uint64_t *val) +{ + int ret = 0; + boolean_t ok; + mlxcx_register_data_t data; + mlxcx_ppcnt_rfc_2863_t *st; + + ASSERT(mutex_owned(&port->mlp_mtx)); + + bzero(&data, sizeof (data)); + data.mlrd_ppcnt.mlrd_ppcnt_local_port = port->mlp_num + 1; + data.mlrd_ppcnt.mlrd_ppcnt_grp = MLXCX_PPCNT_GRP_RFC_2863; + data.mlrd_ppcnt.mlrd_ppcnt_clear = MLXCX_PPCNT_NO_CLEAR; + + ok = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_PPCNT, &data); + if (!ok) + return (EIO); + st = &data.mlrd_ppcnt.mlrd_ppcnt_rfc_2863; + + switch (stat) { + case MAC_STAT_RBYTES: + *val = from_be64(st->mlppc_rfc_2863_in_octets); + break; + case MAC_STAT_MULTIRCV: + *val = from_be64(st->mlppc_rfc_2863_in_mcast_pkts); + break; + case MAC_STAT_BRDCSTRCV: + *val = from_be64(st->mlppc_rfc_2863_in_bcast_pkts); + break; + case MAC_STAT_MULTIXMT: + *val = from_be64(st->mlppc_rfc_2863_out_mcast_pkts); + break; + case MAC_STAT_BRDCSTXMT: + *val = from_be64(st->mlppc_rfc_2863_out_bcast_pkts); + break; + case MAC_STAT_IERRORS: + *val = from_be64(st->mlppc_rfc_2863_in_errors); + break; + case MAC_STAT_UNKNOWNS: + *val = from_be64(st->mlppc_rfc_2863_in_unknown_protos); + break; + case MAC_STAT_OERRORS: + *val = from_be64(st->mlppc_rfc_2863_out_errors); + break; + case MAC_STAT_OBYTES: + *val = from_be64(st->mlppc_rfc_2863_out_octets); + break; + default: + ret = ENOTSUP; + } + + return (ret); +} + +static int +mlxcx_mac_stat_ieee_802_3(mlxcx_t *mlxp, mlxcx_port_t *port, uint_t stat, + uint64_t *val) +{ + int ret = 0; + boolean_t ok; + mlxcx_register_data_t data; + mlxcx_ppcnt_ieee_802_3_t *st; + + ASSERT(mutex_owned(&port->mlp_mtx)); + + bzero(&data, sizeof (data)); + data.mlrd_ppcnt.mlrd_ppcnt_local_port = port->mlp_num + 1; + data.mlrd_ppcnt.mlrd_ppcnt_grp = MLXCX_PPCNT_GRP_IEEE_802_3; + data.mlrd_ppcnt.mlrd_ppcnt_clear = MLXCX_PPCNT_NO_CLEAR; + + ok = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_PPCNT, &data); + if (!ok) + return (EIO); + st = &data.mlrd_ppcnt.mlrd_ppcnt_ieee_802_3; + + switch (stat) { + case MAC_STAT_IPACKETS: + *val = from_be64(st->mlppc_ieee_802_3_frames_rx); + break; + case MAC_STAT_OPACKETS: + *val = from_be64(st->mlppc_ieee_802_3_frames_tx); + break; + case ETHER_STAT_ALIGN_ERRORS: + *val = from_be64(st->mlppc_ieee_802_3_align_err); + break; + case ETHER_STAT_FCS_ERRORS: + *val = from_be64(st->mlppc_ieee_802_3_fcs_err); + break; + case ETHER_STAT_TOOLONG_ERRORS: + *val = from_be64(st->mlppc_ieee_802_3_frame_too_long_err); + break; + default: + ret = ENOTSUP; + } + + return (ret); +} + +static int +mlxcx_mac_stat(void *arg, uint_t stat, uint64_t *val) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_port_t *port = &mlxp->mlx_ports[0]; + int ret = 0; + + mutex_enter(&port->mlp_mtx); + + switch (stat) { + case MAC_STAT_IFSPEED: + *val = mlxcx_speed_to_bits(port->mlp_oper_proto); + break; + case ETHER_STAT_LINK_DUPLEX: + *val = LINK_DUPLEX_FULL; + break; + case MAC_STAT_RBYTES: + case MAC_STAT_MULTIRCV: + case MAC_STAT_BRDCSTRCV: + case MAC_STAT_MULTIXMT: + case MAC_STAT_BRDCSTXMT: + case MAC_STAT_IERRORS: + case MAC_STAT_UNKNOWNS: + case MAC_STAT_OERRORS: + case MAC_STAT_OBYTES: + ret = mlxcx_mac_stat_rfc_2863(mlxp, port, stat, val); + break; + case MAC_STAT_IPACKETS: + case MAC_STAT_OPACKETS: + case ETHER_STAT_ALIGN_ERRORS: + case ETHER_STAT_FCS_ERRORS: + case ETHER_STAT_TOOLONG_ERRORS: + ret = mlxcx_mac_stat_ieee_802_3(mlxp, port, stat, val); + break; + case MAC_STAT_NORCVBUF: + *val = port->mlp_stats.mlps_rx_drops; + break; + default: + ret = ENOTSUP; + } + + mutex_exit(&port->mlp_mtx); + + return (ret); +} + +static int +mlxcx_mac_led_set(void *arg, mac_led_mode_t mode, uint_t flags) +{ + mlxcx_t *mlxp = arg; + mlxcx_port_t *port = &mlxp->mlx_ports[0]; + int ret = 0; + + if (flags != 0) { + return (EINVAL); + } + + mutex_enter(&port->mlp_mtx); + + switch (mode) { + case MAC_LED_DEFAULT: + case MAC_LED_OFF: + if (!mlxcx_cmd_set_port_led(mlxp, port, 0)) { + ret = EIO; + break; + } + break; + case MAC_LED_IDENT: + if (!mlxcx_cmd_set_port_led(mlxp, port, UINT16_MAX)) { + ret = EIO; + break; + } + break; + default: + ret = ENOTSUP; + } + + mutex_exit(&port->mlp_mtx); + + return (ret); +} + +static int +mlxcx_mac_txr_info(void *arg, uint_t id, mac_transceiver_info_t *infop) +{ + mlxcx_t *mlxp = arg; + mlxcx_module_status_t st; + + if (!mlxcx_cmd_query_module_status(mlxp, id, &st, NULL)) + return (EIO); + + if (st != MLXCX_MODULE_UNPLUGGED) + mac_transceiver_info_set_present(infop, B_TRUE); + + if (st == MLXCX_MODULE_PLUGGED) + mac_transceiver_info_set_usable(infop, B_TRUE); + + return (0); +} + +static int +mlxcx_mac_txr_read(void *arg, uint_t id, uint_t page, void *vbuf, + size_t nbytes, off_t offset, size_t *nread) +{ + mlxcx_t *mlxp = arg; + mlxcx_register_data_t data; + uint8_t *buf = vbuf; + boolean_t ok; + size_t take, done = 0; + uint8_t i2c_addr; + + if (id != 0 || vbuf == NULL || nbytes == 0 || nread == NULL) + return (EINVAL); + + if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) + return (EINVAL); + + /* + * The PRM is really not very clear about any of this, but it seems + * that the i2c_device_addr field in MCIA is the SFP+ spec "page" + * number shifted right by 1 bit. They're written in the SFF spec + * like "1010000X" so Mellanox just dropped the X. + * + * This means that if we want page 0xA0, we put 0x50 in the + * i2c_device_addr field. + * + * The "page_number" field in MCIA means something else. Don't ask me + * what. FreeBSD leaves it as zero, so we will too! + */ + i2c_addr = page >> 1; + + while (done < nbytes) { + take = nbytes - done; + if (take > sizeof (data.mlrd_mcia.mlrd_mcia_data)) + take = sizeof (data.mlrd_mcia.mlrd_mcia_data); + + bzero(&data, sizeof (data)); + ASSERT3U(id, <=, 0xff); + data.mlrd_mcia.mlrd_mcia_module = (uint8_t)id; + data.mlrd_mcia.mlrd_mcia_i2c_device_addr = i2c_addr; + data.mlrd_mcia.mlrd_mcia_device_addr = to_be16(offset); + data.mlrd_mcia.mlrd_mcia_size = to_be16(take); + + ok = mlxcx_cmd_access_register(mlxp, + MLXCX_CMD_ACCESS_REGISTER_READ, MLXCX_REG_MCIA, &data); + if (!ok) { + *nread = 0; + return (EIO); + } + + if (data.mlrd_mcia.mlrd_mcia_status != MLXCX_MCIA_STATUS_OK) { + *nread = 0; + return (EIO); + } + + bcopy(data.mlrd_mcia.mlrd_mcia_data, &buf[done], take); + + done += take; + offset += take; + } + *nread = done; + return (0); +} + +static int +mlxcx_mac_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) +{ + mlxcx_work_queue_t *wq = (mlxcx_work_queue_t *)rh; + (void) wq; + + /* + * We should add support for using hw flow counters and such to + * get per-ring statistics. Not done yet though! + */ + + switch (stat) { + default: + *val = 0; + return (ENOTSUP); + } + + return (0); +} + +static int +mlxcx_mac_start(void *arg) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + (void) mlxp; + return (0); +} + +static void +mlxcx_mac_stop(void *arg) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + (void) mlxp; +} + +static mblk_t * +mlxcx_mac_ring_tx(void *arg, mblk_t *mp) +{ + mlxcx_work_queue_t *sq = (mlxcx_work_queue_t *)arg; + mlxcx_t *mlxp = sq->mlwq_mlx; + mlxcx_completion_queue_t *cq; + mlxcx_buffer_t *b; + mac_header_info_t mhi; + mblk_t *kmp, *nmp; + uint8_t inline_hdrs[MLXCX_MAX_INLINE_HEADERLEN]; + size_t inline_hdrlen, rem, off; + uint32_t chkflags = 0; + boolean_t ok; + size_t take = 0; + + VERIFY(mp->b_next == NULL); + + mac_hcksum_get(mp, NULL, NULL, NULL, NULL, &chkflags); + + if (mac_vlan_header_info(mlxp->mlx_mac_hdl, mp, &mhi) != 0) { + /* + * We got given a frame without a valid L2 header on it. We + * can't really transmit that (mlx parts don't like it), so + * we will just drop it on the floor. + */ + freemsg(mp); + return (NULL); + } + + inline_hdrlen = rem = mhi.mhi_hdrsize; + + kmp = mp; + off = 0; + while (rem > 0) { + const ptrdiff_t sz = MBLKL(kmp); + ASSERT3S(sz, >=, 0); + ASSERT3U(sz, <=, SIZE_MAX); + take = sz; + if (take > rem) + take = rem; + bcopy(kmp->b_rptr, inline_hdrs + off, take); + rem -= take; + off += take; + if (take == sz) { + take = 0; + kmp = kmp->b_cont; + } + } + + if (!mlxcx_buf_bind_or_copy(mlxp, sq, kmp, take, &b)) { + /* + * Something went really wrong, and we probably will never be + * able to TX again (all our buffers are broken and DMA is + * failing). Drop the packet on the floor -- FMA should be + * reporting this error elsewhere. + */ + freemsg(mp); + return (NULL); + } + + mutex_enter(&sq->mlwq_mtx); + VERIFY3U(sq->mlwq_inline_mode, <=, MLXCX_ETH_INLINE_L2); + cq = sq->mlwq_cq; + + /* + * state is a single int, so read-only access without the CQ lock + * should be fine. + */ + if (cq->mlcq_state & MLXCX_CQ_TEARDOWN) { + mutex_exit(&sq->mlwq_mtx); + mlxcx_buf_return_chain(mlxp, b, B_FALSE); + return (NULL); + } + + if (sq->mlwq_state & MLXCX_WQ_TEARDOWN) { + mutex_exit(&sq->mlwq_mtx); + mlxcx_buf_return_chain(mlxp, b, B_FALSE); + return (NULL); + } + + /* + * Similar logic here: bufcnt is only manipulated atomically, and + * bufhwm is set at startup. + */ + if (cq->mlcq_bufcnt >= cq->mlcq_bufhwm) { + atomic_or_uint(&cq->mlcq_state, MLXCX_CQ_BLOCKED_MAC); + mutex_exit(&sq->mlwq_mtx); + mlxcx_buf_return_chain(mlxp, b, B_TRUE); + return (mp); + } + + ok = mlxcx_sq_add_buffer(mlxp, sq, inline_hdrs, inline_hdrlen, + chkflags, b); + if (!ok) { + atomic_or_uint(&cq->mlcq_state, MLXCX_CQ_BLOCKED_MAC); + mutex_exit(&sq->mlwq_mtx); + mlxcx_buf_return_chain(mlxp, b, B_TRUE); + return (mp); + } + + /* + * Now that we've successfully enqueued the rest of the packet, + * free any mblks that we cut off while inlining headers. + */ + for (; mp != kmp; mp = nmp) { + nmp = mp->b_cont; + freeb(mp); + } + + mutex_exit(&sq->mlwq_mtx); + + return (NULL); +} + +static int +mlxcx_mac_setpromisc(void *arg, boolean_t on) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_port_t *port = &mlxp->mlx_ports[0]; + mlxcx_flow_group_t *fg; + mlxcx_flow_entry_t *fe; + mlxcx_flow_table_t *ft; + mlxcx_ring_group_t *g; + int ret = 0; + uint_t idx; + + mutex_enter(&port->mlp_mtx); + + /* + * First, do the top-level flow entry on the root flow table for + * the port. This catches all traffic that doesn't match any MAC + * MAC filters. + */ + ft = port->mlp_rx_flow; + mutex_enter(&ft->mlft_mtx); + fg = port->mlp_promisc; + fe = list_head(&fg->mlfg_entries); + if (on && !(fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED)) { + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + ret = EIO; + } + } else if (!on && (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED)) { + if (!mlxcx_cmd_delete_flow_table_entry(mlxp, fe)) { + ret = EIO; + } + } + mutex_exit(&ft->mlft_mtx); + + /* + * If we failed to change the top-level entry, don't bother with + * trying the per-group ones. + */ + if (ret != 0) { + mutex_exit(&port->mlp_mtx); + return (ret); + } + + /* + * Then, do the per-rx-group flow entries which catch traffic that + * matched a MAC filter but failed to match a VLAN filter. + */ + for (idx = 0; idx < mlxp->mlx_rx_ngroups; ++idx) { + g = &mlxp->mlx_rx_groups[idx]; + + mutex_enter(&g->mlg_mtx); + + ft = g->mlg_rx_vlan_ft; + mutex_enter(&ft->mlft_mtx); + + fg = g->mlg_rx_vlan_promisc_fg; + fe = list_head(&fg->mlfg_entries); + if (on && !(fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED)) { + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + ret = EIO; + } + } else if (!on && (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED)) { + if (!mlxcx_cmd_delete_flow_table_entry(mlxp, fe)) { + ret = EIO; + } + } + + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + } + + mutex_exit(&port->mlp_mtx); + return (ret); +} + +static int +mlxcx_mac_multicast(void *arg, boolean_t add, const uint8_t *addr) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_port_t *port = &mlxp->mlx_ports[0]; + mlxcx_ring_group_t *g = &mlxp->mlx_rx_groups[0]; + int ret = 0; + + mutex_enter(&port->mlp_mtx); + mutex_enter(&g->mlg_mtx); + if (add) { + if (!mlxcx_add_umcast_entry(mlxp, port, g, addr)) { + ret = EIO; + } + } else { + if (!mlxcx_remove_umcast_entry(mlxp, port, g, addr)) { + ret = EIO; + } + } + mutex_exit(&g->mlg_mtx); + mutex_exit(&port->mlp_mtx); + return (ret); +} + +static int +mlxcx_group_add_mac(void *arg, const uint8_t *mac_addr) +{ + mlxcx_ring_group_t *g = arg; + mlxcx_t *mlxp = g->mlg_mlx; + mlxcx_port_t *port = g->mlg_port; + int ret = 0; + + mutex_enter(&port->mlp_mtx); + mutex_enter(&g->mlg_mtx); + if (!mlxcx_add_umcast_entry(mlxp, port, g, mac_addr)) { + ret = EIO; + } + mutex_exit(&g->mlg_mtx); + mutex_exit(&port->mlp_mtx); + + return (ret); +} + +/* + * Support for VLAN steering into groups is not yet available in upstream + * illumos. + */ +#if defined(MAC_VLAN_UNTAGGED) + +static int +mlxcx_group_add_vlan(mac_group_driver_t gh, uint16_t vid) +{ + mlxcx_ring_group_t *g = (mlxcx_ring_group_t *)gh; + mlxcx_t *mlxp = g->mlg_mlx; + int ret = 0; + boolean_t tagged = B_TRUE; + + if (vid == MAC_VLAN_UNTAGGED) { + vid = 0; + tagged = B_FALSE; + } + + mutex_enter(&g->mlg_mtx); + if (!mlxcx_add_vlan_entry(mlxp, g, tagged, vid)) { + ret = EIO; + } + mutex_exit(&g->mlg_mtx); + + return (ret); +} + +static int +mlxcx_group_remove_vlan(mac_group_driver_t gh, uint16_t vid) +{ + mlxcx_ring_group_t *g = (mlxcx_ring_group_t *)gh; + mlxcx_t *mlxp = g->mlg_mlx; + int ret = 0; + boolean_t tagged = B_TRUE; + + if (vid == MAC_VLAN_UNTAGGED) { + vid = 0; + tagged = B_FALSE; + } + + mutex_enter(&g->mlg_mtx); + if (!mlxcx_remove_vlan_entry(mlxp, g, tagged, vid)) { + ret = EIO; + } + mutex_exit(&g->mlg_mtx); + + return (ret); +} + +#endif /* MAC_VLAN_UNTAGGED */ + +static int +mlxcx_group_remove_mac(void *arg, const uint8_t *mac_addr) +{ + mlxcx_ring_group_t *g = arg; + mlxcx_t *mlxp = g->mlg_mlx; + mlxcx_port_t *port = g->mlg_port; + int ret = 0; + + mutex_enter(&port->mlp_mtx); + mutex_enter(&g->mlg_mtx); + if (!mlxcx_remove_umcast_entry(mlxp, port, g, mac_addr)) { + ret = EIO; + } + mutex_exit(&g->mlg_mtx); + mutex_exit(&port->mlp_mtx); + + return (ret); +} + +static int +mlxcx_mac_ring_start(mac_ring_driver_t rh, uint64_t gen_num) +{ + mlxcx_work_queue_t *wq = (mlxcx_work_queue_t *)rh; + mlxcx_completion_queue_t *cq = wq->mlwq_cq; + mlxcx_ring_group_t *g = wq->mlwq_group; + mlxcx_t *mlxp = wq->mlwq_mlx; + + ASSERT(cq != NULL); + ASSERT(g != NULL); + + ASSERT(wq->mlwq_type == MLXCX_WQ_TYPE_SENDQ || + wq->mlwq_type == MLXCX_WQ_TYPE_RECVQ); + if (wq->mlwq_type == MLXCX_WQ_TYPE_SENDQ && + !mlxcx_tx_ring_start(mlxp, g, wq)) + return (EIO); + if (wq->mlwq_type == MLXCX_WQ_TYPE_RECVQ && + !mlxcx_rx_ring_start(mlxp, g, wq)) + return (EIO); + + mutex_enter(&cq->mlcq_mtx); + cq->mlcq_mac_gen = gen_num; + mutex_exit(&cq->mlcq_mtx); + + return (0); +} + +static void +mlxcx_mac_ring_stop(mac_ring_driver_t rh) +{ + mlxcx_work_queue_t *wq = (mlxcx_work_queue_t *)rh; + mlxcx_completion_queue_t *cq = wq->mlwq_cq; + mlxcx_t *mlxp = wq->mlwq_mlx; + mlxcx_buf_shard_t *s; + mlxcx_buffer_t *buf; + + mutex_enter(&cq->mlcq_mtx); + mutex_enter(&wq->mlwq_mtx); + if (wq->mlwq_state & MLXCX_WQ_STARTED) { + if (wq->mlwq_type == MLXCX_WQ_TYPE_RECVQ && + !mlxcx_cmd_stop_rq(mlxp, wq)) { + mutex_exit(&wq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + return; + } + if (wq->mlwq_type == MLXCX_WQ_TYPE_SENDQ && + !mlxcx_cmd_stop_sq(mlxp, wq)) { + mutex_exit(&wq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + return; + } + } + ASSERT0(wq->mlwq_state & MLXCX_WQ_STARTED); + + if (wq->mlwq_state & MLXCX_WQ_BUFFERS) { + /* Return any outstanding buffers to the free pool. */ + while ((buf = list_remove_head(&cq->mlcq_buffers)) != NULL) { + mlxcx_buf_return_chain(mlxp, buf, B_FALSE); + } + mutex_enter(&cq->mlcq_bufbmtx); + while ((buf = list_remove_head(&cq->mlcq_buffers_b)) != NULL) { + mlxcx_buf_return_chain(mlxp, buf, B_FALSE); + } + mutex_exit(&cq->mlcq_bufbmtx); + cq->mlcq_bufcnt = 0; + + s = wq->mlwq_bufs; + mutex_enter(&s->mlbs_mtx); + while (!list_is_empty(&s->mlbs_busy)) + cv_wait(&s->mlbs_free_nonempty, &s->mlbs_mtx); + while ((buf = list_head(&s->mlbs_free)) != NULL) { + mlxcx_buf_destroy(mlxp, buf); + } + mutex_exit(&s->mlbs_mtx); + + s = wq->mlwq_foreign_bufs; + if (s != NULL) { + mutex_enter(&s->mlbs_mtx); + while (!list_is_empty(&s->mlbs_busy)) + cv_wait(&s->mlbs_free_nonempty, &s->mlbs_mtx); + while ((buf = list_head(&s->mlbs_free)) != NULL) { + mlxcx_buf_destroy(mlxp, buf); + } + mutex_exit(&s->mlbs_mtx); + } + + wq->mlwq_state &= ~MLXCX_WQ_BUFFERS; + } + ASSERT0(wq->mlwq_state & MLXCX_WQ_BUFFERS); + + mutex_exit(&wq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); +} + +static int +mlxcx_mac_group_start(mac_group_driver_t gh) +{ + mlxcx_ring_group_t *g = (mlxcx_ring_group_t *)gh; + mlxcx_t *mlxp = g->mlg_mlx; + + VERIFY3S(g->mlg_type, ==, MLXCX_GROUP_RX); + ASSERT(mlxp != NULL); + + if (g->mlg_state & MLXCX_GROUP_RUNNING) + return (0); + + if (!mlxcx_rx_group_start(mlxp, g)) + return (EIO); + + return (0); +} + +static void +mlxcx_mac_fill_tx_ring(void *arg, mac_ring_type_t rtype, const int group_index, + const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_ring_group_t *g; + mlxcx_work_queue_t *wq; + mac_intr_t *mintr = &infop->mri_intr; + + if (rtype != MAC_RING_TYPE_TX) + return; + ASSERT3S(group_index, ==, -1); + + g = &mlxp->mlx_tx_groups[0]; + ASSERT(g->mlg_state & MLXCX_GROUP_INIT); + mutex_enter(&g->mlg_mtx); + + ASSERT3S(ring_index, >=, 0); + ASSERT3S(ring_index, <, g->mlg_nwqs); + + wq = &g->mlg_wqs[ring_index]; + + wq->mlwq_cq->mlcq_mac_hdl = rh; + + infop->mri_driver = (mac_ring_driver_t)wq; + infop->mri_start = mlxcx_mac_ring_start; + infop->mri_stop = mlxcx_mac_ring_stop; + infop->mri_tx = mlxcx_mac_ring_tx; + infop->mri_stat = mlxcx_mac_ring_stat; + + mintr->mi_ddi_handle = mlxp->mlx_intr_handles[ + wq->mlwq_cq->mlcq_eq->mleq_intr_index]; + + mutex_exit(&g->mlg_mtx); +} + +static int +mlxcx_mac_ring_intr_enable(mac_intr_handle_t intrh) +{ + mlxcx_completion_queue_t *cq = (mlxcx_completion_queue_t *)intrh; + mlxcx_event_queue_t *eq = cq->mlcq_eq; + mlxcx_t *mlxp = cq->mlcq_mlx; + + /* + * We are going to call mlxcx_arm_cq() here, so we take the EQ lock + * as well as the CQ one to make sure we don't race against + * mlxcx_intr_n(). + */ + mutex_enter(&eq->mleq_mtx); + mutex_enter(&cq->mlcq_mtx); + if (cq->mlcq_state & MLXCX_CQ_POLLING) { + cq->mlcq_state &= ~MLXCX_CQ_POLLING; + if (!(cq->mlcq_state & MLXCX_CQ_ARMED)) + mlxcx_arm_cq(mlxp, cq); + } + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&eq->mleq_mtx); + + return (0); +} + +static int +mlxcx_mac_ring_intr_disable(mac_intr_handle_t intrh) +{ + mlxcx_completion_queue_t *cq = (mlxcx_completion_queue_t *)intrh; + + atomic_or_uint(&cq->mlcq_state, MLXCX_CQ_POLLING); + mutex_enter(&cq->mlcq_mtx); + VERIFY(cq->mlcq_state & MLXCX_CQ_POLLING); + mutex_exit(&cq->mlcq_mtx); + + return (0); +} + +static mblk_t * +mlxcx_mac_ring_rx_poll(void *arg, int poll_bytes) +{ + mlxcx_work_queue_t *wq = (mlxcx_work_queue_t *)arg; + mlxcx_completion_queue_t *cq = wq->mlwq_cq; + mlxcx_t *mlxp = wq->mlwq_mlx; + mblk_t *mp; + + ASSERT(cq != NULL); + ASSERT3S(poll_bytes, >, 0); + if (poll_bytes == 0) + return (NULL); + + mutex_enter(&cq->mlcq_mtx); + mp = mlxcx_rx_poll(mlxp, cq, poll_bytes); + mutex_exit(&cq->mlcq_mtx); + + return (mp); +} + +static void +mlxcx_mac_fill_rx_ring(void *arg, mac_ring_type_t rtype, const int group_index, + const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_ring_group_t *g; + mlxcx_work_queue_t *wq; + mac_intr_t *mintr = &infop->mri_intr; + + if (rtype != MAC_RING_TYPE_RX) + return; + ASSERT3S(group_index, >=, 0); + ASSERT3S(group_index, <, mlxp->mlx_rx_ngroups); + + g = &mlxp->mlx_rx_groups[group_index]; + ASSERT(g->mlg_state & MLXCX_GROUP_INIT); + mutex_enter(&g->mlg_mtx); + + ASSERT3S(ring_index, >=, 0); + ASSERT3S(ring_index, <, g->mlg_nwqs); + + ASSERT(g->mlg_state & MLXCX_GROUP_WQS); + wq = &g->mlg_wqs[ring_index]; + + wq->mlwq_cq->mlcq_mac_hdl = rh; + + infop->mri_driver = (mac_ring_driver_t)wq; + infop->mri_start = mlxcx_mac_ring_start; + infop->mri_stop = mlxcx_mac_ring_stop; + infop->mri_poll = mlxcx_mac_ring_rx_poll; + infop->mri_stat = mlxcx_mac_ring_stat; + + mintr->mi_handle = (mac_intr_handle_t)wq->mlwq_cq; + mintr->mi_enable = mlxcx_mac_ring_intr_enable; + mintr->mi_disable = mlxcx_mac_ring_intr_disable; + + mintr->mi_ddi_handle = mlxp->mlx_intr_handles[ + wq->mlwq_cq->mlcq_eq->mleq_intr_index]; + + mutex_exit(&g->mlg_mtx); +} + +static void +mlxcx_mac_fill_rx_group(void *arg, mac_ring_type_t rtype, const int index, + mac_group_info_t *infop, mac_group_handle_t gh) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_ring_group_t *g; + + if (rtype != MAC_RING_TYPE_RX) + return; + + ASSERT3S(index, >=, 0); + ASSERT3S(index, <, mlxp->mlx_rx_ngroups); + g = &mlxp->mlx_rx_groups[index]; + ASSERT(g->mlg_state & MLXCX_GROUP_INIT); + + g->mlg_mac_hdl = gh; + + infop->mgi_driver = (mac_group_driver_t)g; + infop->mgi_start = mlxcx_mac_group_start; + infop->mgi_stop = NULL; + infop->mgi_addmac = mlxcx_group_add_mac; + infop->mgi_remmac = mlxcx_group_remove_mac; +#if defined(MAC_VLAN_UNTAGGED) + infop->mgi_addvlan = mlxcx_group_add_vlan; + infop->mgi_remvlan = mlxcx_group_remove_vlan; +#endif /* MAC_VLAN_UNTAGGED */ + + infop->mgi_count = g->mlg_nwqs; +} + +static boolean_t +mlxcx_mac_getcapab(void *arg, mac_capab_t cap, void *cap_data) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mac_capab_rings_t *cap_rings; + mac_capab_led_t *cap_leds; + mac_capab_transceiver_t *cap_txr; + uint_t i, n = 0; + + switch (cap) { + + case MAC_CAPAB_RINGS: + cap_rings = cap_data; + cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; + switch (cap_rings->mr_type) { + case MAC_RING_TYPE_TX: + cap_rings->mr_gnum = 0; + cap_rings->mr_rnum = mlxp->mlx_tx_groups[0].mlg_nwqs; + cap_rings->mr_rget = mlxcx_mac_fill_tx_ring; + cap_rings->mr_gget = NULL; + cap_rings->mr_gaddring = NULL; + cap_rings->mr_gremring = NULL; + break; + case MAC_RING_TYPE_RX: + cap_rings->mr_gnum = mlxp->mlx_rx_ngroups; + for (i = 0; i < mlxp->mlx_rx_ngroups; ++i) + n += mlxp->mlx_rx_groups[i].mlg_nwqs; + cap_rings->mr_rnum = n; + cap_rings->mr_rget = mlxcx_mac_fill_rx_ring; + cap_rings->mr_gget = mlxcx_mac_fill_rx_group; + cap_rings->mr_gaddring = NULL; + cap_rings->mr_gremring = NULL; + break; + default: + return (B_FALSE); + } + break; + + case MAC_CAPAB_HCKSUM: + if (mlxp->mlx_caps->mlc_checksum) { + *(uint32_t *)cap_data = HCKSUM_INET_FULL_V4 | + HCKSUM_INET_FULL_V6 | HCKSUM_IPHDRCKSUM; + } + break; + + case MAC_CAPAB_LED: + cap_leds = cap_data; + + cap_leds->mcl_flags = 0; + cap_leds->mcl_modes = MAC_LED_DEFAULT | MAC_LED_OFF | + MAC_LED_IDENT; + cap_leds->mcl_set = mlxcx_mac_led_set; + break; + + case MAC_CAPAB_TRANSCEIVER: + cap_txr = cap_data; + + cap_txr->mct_flags = 0; + cap_txr->mct_ntransceivers = 1; + cap_txr->mct_info = mlxcx_mac_txr_info; + cap_txr->mct_read = mlxcx_mac_txr_read; + break; + + default: + return (B_FALSE); + } + + return (B_TRUE); +} + +static void +mlxcx_mac_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, + mac_prop_info_handle_t prh) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_port_t *port = &mlxp->mlx_ports[0]; + + mutex_enter(&port->mlp_mtx); + + switch (pr_num) { + case MAC_PROP_DUPLEX: + case MAC_PROP_SPEED: + mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); + break; + case MAC_PROP_MTU: + mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); + mac_prop_info_set_range_uint32(prh, MLXCX_MTU_OFFSET, + port->mlp_max_mtu); + mac_prop_info_set_default_uint32(prh, + port->mlp_mtu - MLXCX_MTU_OFFSET); + break; + case MAC_PROP_AUTONEG: + mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); + mac_prop_info_set_default_uint8(prh, 1); + break; + default: + break; + } + + mutex_exit(&port->mlp_mtx); +} + +static int +mlxcx_mac_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, + uint_t pr_valsize, const void *pr_val) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_port_t *port = &mlxp->mlx_ports[0]; + int ret = 0; + uint32_t new_mtu, new_hw_mtu, old_mtu; + mlxcx_buf_shard_t *sh; + boolean_t allocd = B_FALSE; + + mutex_enter(&port->mlp_mtx); + + switch (pr_num) { + case MAC_PROP_MTU: + bcopy(pr_val, &new_mtu, sizeof (new_mtu)); + new_hw_mtu = new_mtu + MLXCX_MTU_OFFSET; + if (new_hw_mtu == port->mlp_mtu) + break; + if (new_hw_mtu > port->mlp_max_mtu) { + ret = EINVAL; + break; + } + sh = list_head(&mlxp->mlx_buf_shards); + for (; sh != NULL; sh = list_next(&mlxp->mlx_buf_shards, sh)) { + mutex_enter(&sh->mlbs_mtx); + if (!list_is_empty(&sh->mlbs_free) || + !list_is_empty(&sh->mlbs_busy)) { + allocd = B_TRUE; + mutex_exit(&sh->mlbs_mtx); + break; + } + mutex_exit(&sh->mlbs_mtx); + } + if (allocd) { + ret = EBUSY; + break; + } + old_mtu = port->mlp_mtu; + ret = mac_maxsdu_update(mlxp->mlx_mac_hdl, new_mtu); + if (ret != 0) + break; + port->mlp_mtu = new_hw_mtu; + if (!mlxcx_cmd_modify_nic_vport_ctx(mlxp, port, + MLXCX_MODIFY_NIC_VPORT_CTX_MTU)) { + port->mlp_mtu = old_mtu; + (void) mac_maxsdu_update(mlxp->mlx_mac_hdl, old_mtu); + ret = EIO; + break; + } + if (!mlxcx_cmd_set_port_mtu(mlxp, port)) { + port->mlp_mtu = old_mtu; + (void) mac_maxsdu_update(mlxp->mlx_mac_hdl, old_mtu); + ret = EIO; + break; + } + break; + default: + ret = ENOTSUP; + break; + } + + mutex_exit(&port->mlp_mtx); + + return (ret); +} + +static int +mlxcx_mac_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, + uint_t pr_valsize, void *pr_val) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_port_t *port = &mlxp->mlx_ports[0]; + uint64_t speed; + int ret = 0; + + mutex_enter(&port->mlp_mtx); + + switch (pr_num) { + case MAC_PROP_DUPLEX: + if (pr_valsize < sizeof (link_duplex_t)) { + ret = EOVERFLOW; + break; + } + /* connectx parts only support full duplex */ + *(link_duplex_t *)pr_val = LINK_DUPLEX_FULL; + break; + case MAC_PROP_SPEED: + if (pr_valsize < sizeof (uint64_t)) { + ret = EOVERFLOW; + break; + } + speed = mlxcx_speed_to_bits(port->mlp_oper_proto); + bcopy(&speed, pr_val, sizeof (speed)); + break; + case MAC_PROP_STATUS: + if (pr_valsize < sizeof (link_state_t)) { + ret = EOVERFLOW; + break; + } + switch (port->mlp_oper_status) { + case MLXCX_PORT_STATUS_UP: + case MLXCX_PORT_STATUS_UP_ONCE: + *(link_state_t *)pr_val = LINK_STATE_UP; + break; + case MLXCX_PORT_STATUS_DOWN: + *(link_state_t *)pr_val = LINK_STATE_DOWN; + break; + default: + *(link_state_t *)pr_val = LINK_STATE_UNKNOWN; + } + break; + case MAC_PROP_AUTONEG: + if (pr_valsize < sizeof (uint8_t)) { + ret = EOVERFLOW; + break; + } + *(uint8_t *)pr_val = port->mlp_autoneg; + break; + case MAC_PROP_MTU: + if (pr_valsize < sizeof (uint32_t)) { + ret = EOVERFLOW; + break; + } + *(uint32_t *)pr_val = port->mlp_mtu - MLXCX_MTU_OFFSET; + break; + default: + ret = ENOTSUP; + break; + } + + mutex_exit(&port->mlp_mtx); + + return (ret); +} + +#define MLXCX_MAC_CALLBACK_FLAGS \ + (MC_GETCAPAB | MC_GETPROP | MC_PROPINFO | MC_SETPROP) + +static mac_callbacks_t mlxcx_mac_callbacks = { + .mc_callbacks = MLXCX_MAC_CALLBACK_FLAGS, + .mc_getstat = mlxcx_mac_stat, + .mc_start = mlxcx_mac_start, + .mc_stop = mlxcx_mac_stop, + .mc_setpromisc = mlxcx_mac_setpromisc, + .mc_multicst = mlxcx_mac_multicast, + .mc_ioctl = NULL, + .mc_getcapab = mlxcx_mac_getcapab, + .mc_setprop = mlxcx_mac_setprop, + .mc_getprop = mlxcx_mac_getprop, + .mc_propinfo = mlxcx_mac_propinfo, + .mc_tx = NULL, + .mc_unicst = NULL, +}; + +boolean_t +mlxcx_register_mac(mlxcx_t *mlxp) +{ + mac_register_t *mac = mac_alloc(MAC_VERSION); + mlxcx_port_t *port; + int ret; + + if (mac == NULL) + return (B_FALSE); + + VERIFY3U(mlxp->mlx_nports, ==, 1); + port = &mlxp->mlx_ports[0]; + + mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER; + mac->m_driver = mlxp; + mac->m_dip = mlxp->mlx_dip; + mac->m_src_addr = port->mlp_mac_address; + mac->m_callbacks = &mlxcx_mac_callbacks; + mac->m_min_sdu = MLXCX_MTU_OFFSET; + mac->m_max_sdu = port->mlp_mtu - MLXCX_MTU_OFFSET; + mac->m_margin = VLAN_TAGSZ; + mac->m_priv_props = mlxcx_priv_props; + mac->m_v12n = MAC_VIRT_LEVEL1; + + ret = mac_register(mac, &mlxp->mlx_mac_hdl); + if (ret != 0) { + mlxcx_warn(mlxp, "mac_register() returned %d", ret); + } + mac_free(mac); + + mlxcx_update_link_state(mlxp, port); + + return (ret == 0); +} diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_intr.c b/usr/src/uts/common/io/mlxcx/mlxcx_intr.c new file mode 100644 index 0000000000..0516f86d6b --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_intr.c @@ -0,0 +1,1010 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2020, the University of Queensland + */ + +/* + * Mellanox Connect-X 4/5/6 driver. + */ + +#include <sys/modctl.h> +#include <sys/conf.h> +#include <sys/devops.h> +#include <sys/sysmacros.h> + +#include <sys/mac_provider.h> + +#include <mlxcx.h> + +void +mlxcx_intr_teardown(mlxcx_t *mlxp) +{ + int i; + int ret; + + for (i = 0; i < mlxp->mlx_intr_count; ++i) { + mlxcx_event_queue_t *mleq = &mlxp->mlx_eqs[i]; + mutex_enter(&mleq->mleq_mtx); + VERIFY0(mleq->mleq_state & MLXCX_EQ_ALLOC); + if (mleq->mleq_state & MLXCX_EQ_CREATED) + VERIFY(mleq->mleq_state & MLXCX_EQ_DESTROYED); + if (i != 0) { + VERIFY(avl_is_empty(&mleq->mleq_cqs)); + avl_destroy(&mleq->mleq_cqs); + } + mutex_exit(&mleq->mleq_mtx); + (void) ddi_intr_disable(mlxp->mlx_intr_handles[i]); + (void) ddi_intr_remove_handler(mlxp->mlx_intr_handles[i]); + ret = ddi_intr_free(mlxp->mlx_intr_handles[i]); + if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "failed to free interrupt %d: %d", + i, ret); + } + mutex_destroy(&mleq->mleq_mtx); + } + kmem_free(mlxp->mlx_intr_handles, mlxp->mlx_intr_size); + kmem_free(mlxp->mlx_eqs, mlxp->mlx_eqs_size); + mlxp->mlx_intr_handles = NULL; + mlxp->mlx_eqs = NULL; +} + +/* + * Get the next SW-owned entry on the event queue, or NULL if we reach the end. + */ +static mlxcx_eventq_ent_t * +mlxcx_eq_next(mlxcx_event_queue_t *mleq) +{ + mlxcx_eventq_ent_t *ent; + ddi_fm_error_t err; + uint_t ci; + const uint_t swowner = ((mleq->mleq_cc >> mleq->mleq_entshift) & 1); + + ASSERT(mutex_owned(&mleq->mleq_mtx)); + ASSERT(mleq->mleq_state & MLXCX_EQ_CREATED); + ASSERT0(mleq->mleq_state & MLXCX_EQ_DESTROYED); + + /* mleq_nents is always a power of 2 */ + ci = mleq->mleq_cc & (mleq->mleq_nents - 1); + + ent = &mleq->mleq_ent[ci]; + VERIFY0(ddi_dma_sync(mleq->mleq_dma.mxdb_dma_handle, + (uintptr_t)ent - (uintptr_t)mleq->mleq_ent, + sizeof (mlxcx_eventq_ent_t), DDI_DMA_SYNC_FORCPU)); + ddi_fm_dma_err_get(mleq->mleq_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status == DDI_FM_OK && (ent->mleqe_owner & 1) == swowner) { + /* The PRM says we have to membar here, so we're doing it */ + membar_consumer(); + ++mleq->mleq_cc; + return (ent); + } + /* + * In the case of a DMA error, we should re-arm this EQ and then come + * back and try again when the device wakes us back up. + * + * Hopefully the fault will be gone by then. + */ + ddi_fm_dma_err_clear(mleq->mleq_dma.mxdb_dma_handle, DDI_FME_VERSION); + + return (NULL); +} + +void +mlxcx_arm_eq(mlxcx_t *mlxp, mlxcx_event_queue_t *mleq) +{ + uint_t try = 0; + ddi_fm_error_t err; + bits32_t v = new_bits32(); + + ASSERT(mutex_owned(&mleq->mleq_mtx)); + ASSERT(mleq->mleq_state & MLXCX_EQ_CREATED); + ASSERT0(mleq->mleq_state & MLXCX_EQ_DESTROYED); + ASSERT0(mleq->mleq_state & MLXCX_EQ_ARMED); + ASSERT0(mleq->mleq_state & MLXCX_EQ_POLLING); + + mleq->mleq_state |= MLXCX_EQ_ARMED; + mleq->mleq_cc_armed = mleq->mleq_cc; + + set_bits32(&v, MLXCX_EQ_ARM_EQN, mleq->mleq_num); + set_bits32(&v, MLXCX_EQ_ARM_CI, mleq->mleq_cc); + +retry: + mlxcx_uar_put32(mlxp, mleq->mleq_uar, MLXCX_UAR_EQ_ARM, + from_bits32(v)); + ddi_fm_acc_err_get(mlxp->mlx_regs_handle, &err, + DDI_FME_VERSION); + if (err.fme_status == DDI_FM_OK) + return; + if (try++ < mlxcx_doorbell_tries) { + ddi_fm_acc_err_clear(mlxp->mlx_regs_handle, DDI_FME_VERSION); + goto retry; + } + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_LOST); +} + +static void +mlxcx_update_eq(mlxcx_t *mlxp, mlxcx_event_queue_t *mleq) +{ + bits32_t v = new_bits32(); + ddi_fm_error_t err; + + ASSERT(mutex_owned(&mleq->mleq_mtx)); + ASSERT(mleq->mleq_state & MLXCX_EQ_CREATED); + ASSERT0(mleq->mleq_state & MLXCX_EQ_DESTROYED); + ASSERT0(mleq->mleq_state & MLXCX_EQ_ARMED); + + set_bits32(&v, MLXCX_EQ_ARM_EQN, mleq->mleq_num); + set_bits32(&v, MLXCX_EQ_ARM_CI, mleq->mleq_cc); + + mlxcx_uar_put32(mlxp, mleq->mleq_uar, MLXCX_UAR_EQ_NOARM, + from_bits32(v)); + ddi_fm_acc_err_get(mlxp->mlx_regs_handle, &err, + DDI_FME_VERSION); + ddi_fm_acc_err_clear(mlxp->mlx_regs_handle, DDI_FME_VERSION); + /* + * Ignore the error, if it's still happening when we try to re-arm the + * EQ, we will note the impact then. + */ +} + +static mlxcx_completionq_ent_t * +mlxcx_cq_next(mlxcx_completion_queue_t *mlcq) +{ + mlxcx_completionq_ent_t *ent; + ddi_fm_error_t err; + uint_t ci; + const uint_t swowner = ((mlcq->mlcq_cc >> mlcq->mlcq_entshift) & 1); + + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + ASSERT(mlcq->mlcq_state & MLXCX_CQ_CREATED); + ASSERT0(mlcq->mlcq_state & MLXCX_CQ_DESTROYED); + + /* mlcq_nents is always a power of 2 */ + ci = mlcq->mlcq_cc & (mlcq->mlcq_nents - 1); + + ent = &mlcq->mlcq_ent[ci]; + VERIFY0(ddi_dma_sync(mlcq->mlcq_dma.mxdb_dma_handle, + (uintptr_t)ent - (uintptr_t)mlcq->mlcq_ent, + sizeof (mlxcx_completionq_ent_t), DDI_DMA_SYNC_FORCPU)); + ddi_fm_dma_err_get(mlcq->mlcq_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status == DDI_FM_OK && (ent->mlcqe_owner & 1) == swowner) { + /* The PRM says we have to membar here, so we're doing it */ + membar_consumer(); + ++mlcq->mlcq_cc; + return (ent); + } + ddi_fm_dma_err_clear(mlcq->mlcq_dma.mxdb_dma_handle, DDI_FME_VERSION); + + return (NULL); +} + +void +mlxcx_arm_cq(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq) +{ + bits32_t dbval = new_bits32(); + uint64_t udbval; + ddi_fm_error_t err; + uint_t try = 0; + + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + ASSERT(mlcq->mlcq_state & MLXCX_CQ_CREATED); + ASSERT0(mlcq->mlcq_state & MLXCX_CQ_DESTROYED); + + if (mlcq->mlcq_state & MLXCX_CQ_ARMED) + ASSERT3U(mlcq->mlcq_ec, >, mlcq->mlcq_ec_armed); + + if (mlcq->mlcq_state & MLXCX_CQ_TEARDOWN) + return; + + mlcq->mlcq_state |= MLXCX_CQ_ARMED; + mlcq->mlcq_cc_armed = mlcq->mlcq_cc; + mlcq->mlcq_ec_armed = mlcq->mlcq_ec; + + set_bits32(&dbval, MLXCX_CQ_ARM_SEQ, mlcq->mlcq_ec); + set_bits32(&dbval, MLXCX_CQ_ARM_CI, mlcq->mlcq_cc); + + udbval = (uint64_t)from_bits32(dbval) << 32; + udbval |= mlcq->mlcq_num & 0xffffff; + + mlcq->mlcq_doorbell->mlcqd_update_ci = to_be24(mlcq->mlcq_cc); + mlcq->mlcq_doorbell->mlcqd_arm_ci = dbval; + +retry: + MLXCX_DMA_SYNC(mlcq->mlcq_doorbell_dma, DDI_DMA_SYNC_FORDEV); + ddi_fm_dma_err_get(mlcq->mlcq_doorbell_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + if (try++ < mlxcx_doorbell_tries) { + ddi_fm_dma_err_clear( + mlcq->mlcq_doorbell_dma.mxdb_dma_handle, + DDI_FME_VERSION); + goto retry; + } else { + goto err; + } + } + + mlxcx_uar_put64(mlxp, mlcq->mlcq_uar, MLXCX_UAR_CQ_ARM, udbval); + ddi_fm_acc_err_get(mlxp->mlx_regs_handle, &err, + DDI_FME_VERSION); + if (err.fme_status == DDI_FM_OK) + return; + if (try++ < mlxcx_doorbell_tries) { + ddi_fm_acc_err_clear(mlxp->mlx_regs_handle, DDI_FME_VERSION); + goto retry; + } + +err: + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_LOST); +} + +const char * +mlxcx_event_name(mlxcx_event_t evt) +{ + switch (evt) { + case MLXCX_EVENT_COMPLETION: + return ("COMPLETION"); + case MLXCX_EVENT_PATH_MIGRATED: + return ("PATH_MIGRATED"); + case MLXCX_EVENT_COMM_ESTABLISH: + return ("COMM_ESTABLISH"); + case MLXCX_EVENT_SENDQ_DRAIN: + return ("SENDQ_DRAIN"); + case MLXCX_EVENT_LAST_WQE: + return ("LAST_WQE"); + case MLXCX_EVENT_SRQ_LIMIT: + return ("SRQ_LIMIT"); + case MLXCX_EVENT_DCT_ALL_CLOSED: + return ("DCT_ALL_CLOSED"); + case MLXCX_EVENT_DCT_ACCKEY_VIOL: + return ("DCT_ACCKEY_VIOL"); + case MLXCX_EVENT_CQ_ERROR: + return ("CQ_ERROR"); + case MLXCX_EVENT_WQ_CATASTROPHE: + return ("WQ_CATASTROPHE"); + case MLXCX_EVENT_PATH_MIGRATE_FAIL: + return ("PATH_MIGRATE_FAIL"); + case MLXCX_EVENT_PAGE_FAULT: + return ("PAGE_FAULT"); + case MLXCX_EVENT_WQ_INVALID_REQ: + return ("WQ_INVALID_REQ"); + case MLXCX_EVENT_WQ_ACCESS_VIOL: + return ("WQ_ACCESS_VIOL"); + case MLXCX_EVENT_SRQ_CATASTROPHE: + return ("SRQ_CATASTROPHE"); + case MLXCX_EVENT_INTERNAL_ERROR: + return ("INTERNAL_ERROR"); + case MLXCX_EVENT_PORT_STATE: + return ("PORT_STATE"); + case MLXCX_EVENT_GPIO: + return ("GPIO"); + case MLXCX_EVENT_PORT_MODULE: + return ("PORT_MODULE"); + case MLXCX_EVENT_TEMP_WARNING: + return ("TEMP_WARNING"); + case MLXCX_EVENT_REMOTE_CONFIG: + return ("REMOTE_CONFIG"); + case MLXCX_EVENT_DCBX_CHANGE: + return ("DCBX_CHANGE"); + case MLXCX_EVENT_DOORBELL_CONGEST: + return ("DOORBELL_CONGEST"); + case MLXCX_EVENT_STALL_VL: + return ("STALL_VL"); + case MLXCX_EVENT_CMD_COMPLETION: + return ("CMD_COMPLETION"); + case MLXCX_EVENT_PAGE_REQUEST: + return ("PAGE_REQUEST"); + case MLXCX_EVENT_NIC_VPORT: + return ("NIC_VPORT"); + case MLXCX_EVENT_EC_PARAMS_CHANGE: + return ("EC_PARAMS_CHANGE"); + case MLXCX_EVENT_XRQ_ERROR: + return ("XRQ_ERROR"); + } + return ("UNKNOWN"); +} + +/* Should be called only when link state has changed. */ +void +mlxcx_update_link_state(mlxcx_t *mlxp, mlxcx_port_t *port) +{ + link_state_t ls; + + mutex_enter(&port->mlp_mtx); + (void) mlxcx_cmd_query_port_status(mlxp, port); + (void) mlxcx_cmd_query_port_speed(mlxp, port); + + switch (port->mlp_oper_status) { + case MLXCX_PORT_STATUS_UP: + case MLXCX_PORT_STATUS_UP_ONCE: + ls = LINK_STATE_UP; + break; + case MLXCX_PORT_STATUS_DOWN: + ls = LINK_STATE_DOWN; + break; + default: + ls = LINK_STATE_UNKNOWN; + } + mac_link_update(mlxp->mlx_mac_hdl, ls); + + mutex_exit(&port->mlp_mtx); +} + +static void +mlxcx_give_pages_once(mlxcx_t *mlxp, size_t npages) +{ + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + mlxcx_dev_page_t *mdp; + int32_t togive; + mlxcx_dev_page_t *pages[MLXCX_MANAGE_PAGES_MAX_PAGES]; + uint_t i; + const ddi_dma_cookie_t *ck; + + togive = MIN(npages, MLXCX_MANAGE_PAGES_MAX_PAGES); + + for (i = 0; i < togive; i++) { + mdp = kmem_zalloc(sizeof (mlxcx_dev_page_t), KM_SLEEP); + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_page_attr(mlxp, &attr); + if (!mlxcx_dma_alloc(mlxp, &mdp->mxdp_dma, &attr, &acc, + B_TRUE, MLXCX_HW_PAGE_SIZE, B_TRUE)) { + mlxcx_warn(mlxp, "failed to allocate 4k page %u/%u", i, + togive); + goto cleanup_npages; + } + ck = mlxcx_dma_cookie_one(&mdp->mxdp_dma); + mdp->mxdp_pa = ck->dmac_laddress; + pages[i] = mdp; + } + + mutex_enter(&mlxp->mlx_pagemtx); + + if (!mlxcx_cmd_give_pages(mlxp, + MLXCX_MANAGE_PAGES_OPMOD_GIVE_PAGES, togive, pages)) { + mlxcx_warn(mlxp, "!hardware refused our gift of %u " + "pages!", togive); + goto cleanup_npages; + } + + for (i = 0; i < togive; i++) { + avl_add(&mlxp->mlx_pages, pages[i]); + } + mlxp->mlx_npages += togive; + mutex_exit(&mlxp->mlx_pagemtx); + + return; + +cleanup_npages: + for (i = 0; i < togive; i++) { + mdp = pages[i]; + mlxcx_dma_free(&mdp->mxdp_dma); + kmem_free(mdp, sizeof (mlxcx_dev_page_t)); + } + /* Tell the hardware we had an allocation failure. */ + (void) mlxcx_cmd_give_pages(mlxp, MLXCX_MANAGE_PAGES_OPMOD_ALLOC_FAIL, + 0, NULL); + mutex_exit(&mlxp->mlx_pagemtx); +} + +static void +mlxcx_take_pages_once(mlxcx_t *mlxp, size_t npages) +{ + uint_t i; + int32_t req, ret; + uint64_t pas[MLXCX_MANAGE_PAGES_MAX_PAGES]; + mlxcx_dev_page_t *mdp, probe; + + mutex_enter(&mlxp->mlx_pagemtx); + + ASSERT0(avl_is_empty(&mlxp->mlx_pages)); + req = MIN(npages, MLXCX_MANAGE_PAGES_MAX_PAGES); + + if (!mlxcx_cmd_return_pages(mlxp, req, pas, &ret)) { + return; + } + + for (i = 0; i < ret; i++) { + bzero(&probe, sizeof (probe)); + probe.mxdp_pa = pas[i]; + + mdp = avl_find(&mlxp->mlx_pages, &probe, NULL); + + if (mdp != NULL) { + avl_remove(&mlxp->mlx_pages, mdp); + mlxp->mlx_npages--; + mlxcx_dma_free(&mdp->mxdp_dma); + kmem_free(mdp, sizeof (mlxcx_dev_page_t)); + } else { + mlxcx_warn(mlxp, "hardware returned a page " + "with PA 0x%" PRIx64 " but we have no " + "record of giving out such a page", pas[i]); + } + } + + mutex_exit(&mlxp->mlx_pagemtx); +} + +static const char * +mlxcx_module_error_string(mlxcx_module_error_type_t err) +{ + switch (err) { + case MLXCX_MODULE_ERR_POWER_BUDGET: + return ("POWER_BUDGET"); + case MLXCX_MODULE_ERR_LONG_RANGE: + return ("LONG_RANGE"); + case MLXCX_MODULE_ERR_BUS_STUCK: + return ("BUS_STUCK"); + case MLXCX_MODULE_ERR_NO_EEPROM: + return ("NO_EEPROM"); + case MLXCX_MODULE_ERR_ENFORCEMENT: + return ("ENFORCEMENT"); + case MLXCX_MODULE_ERR_UNKNOWN_IDENT: + return ("UNKNOWN_IDENT"); + case MLXCX_MODULE_ERR_HIGH_TEMP: + return ("HIGH_TEMP"); + case MLXCX_MODULE_ERR_CABLE_SHORTED: + return ("CABLE_SHORTED"); + default: + return ("UNKNOWN"); + } +} + +static void +mlxcx_report_module_error(mlxcx_t *mlxp, mlxcx_evdata_port_mod_t *evd) +{ + uint64_t ena; + char buf[FM_MAX_CLASS]; + const char *lename; + const char *ename; + const char *stname; + uint_t eno = 0; + mlxcx_module_status_t state = evd->mled_port_mod_module_status; + + switch (state) { + case MLXCX_MODULE_ERROR: + stname = "error"; + eno = evd->mled_port_mod_error_type; + lename = mlxcx_module_error_string(eno); + switch (eno) { + case MLXCX_MODULE_ERR_ENFORCEMENT: + ename = DDI_FM_TXR_ERROR_WHITELIST; + break; + case MLXCX_MODULE_ERR_UNKNOWN_IDENT: + case MLXCX_MODULE_ERR_NO_EEPROM: + ename = DDI_FM_TXR_ERROR_NOTSUPP; + break; + case MLXCX_MODULE_ERR_HIGH_TEMP: + ename = DDI_FM_TXR_ERROR_OVERTEMP; + break; + case MLXCX_MODULE_ERR_POWER_BUDGET: + case MLXCX_MODULE_ERR_LONG_RANGE: + case MLXCX_MODULE_ERR_CABLE_SHORTED: + ename = DDI_FM_TXR_ERROR_HWFAIL; + break; + case MLXCX_MODULE_ERR_BUS_STUCK: + default: + ename = DDI_FM_TXR_ERROR_UNKNOWN; + } + break; + default: + return; + } + + (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", + DDI_FM_NIC, DDI_FM_TXR_ERROR); + ena = fm_ena_generate(0, FM_ENA_FMT1); + if (!DDI_FM_EREPORT_CAP(mlxp->mlx_fm_caps)) + return; + + ddi_fm_ereport_post(mlxp->mlx_dip, buf, ena, DDI_NOSLEEP, + /* compulsory FM props */ + FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, + /* generic NIC txr error event props */ + "error", DATA_TYPE_STRING, ename, + "port_index", DATA_TYPE_UINT8, 0, + "txr_index", DATA_TYPE_UINT8, evd->mled_port_mod_module, + /* local props */ + "mlxcx_state", DATA_TYPE_STRING, stname, + "mlxcx_error", DATA_TYPE_STRING, lename, + "mlxcx_error_num", DATA_TYPE_UINT8, eno, + NULL); + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_LOST); +} + +static uint_t +mlxcx_intr_0(caddr_t arg, caddr_t arg2) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_event_queue_t *mleq = (mlxcx_event_queue_t *)arg2; + mlxcx_eventq_ent_t *ent; + mlxcx_port_t *port; + uint_t portn; + int32_t npages = 0; + + mutex_enter(&mleq->mleq_mtx); + + if (!(mleq->mleq_state & MLXCX_EQ_ALLOC) || + !(mleq->mleq_state & MLXCX_EQ_CREATED) || + (mleq->mleq_state & MLXCX_EQ_DESTROYED)) { + mlxcx_warn(mlxp, "int0 on bad eq state"); + mutex_exit(&mleq->mleq_mtx); + return (DDI_INTR_UNCLAIMED); + } + + ent = mlxcx_eq_next(mleq); + if (ent == NULL) { + mlxcx_warn(mlxp, "spurious int 0?"); + mutex_exit(&mleq->mleq_mtx); + return (DDI_INTR_UNCLAIMED); + } + + ASSERT(mleq->mleq_state & MLXCX_EQ_ARMED); + mleq->mleq_state &= ~MLXCX_EQ_ARMED; + + for (; ent != NULL; ent = mlxcx_eq_next(mleq)) { + switch (ent->mleqe_event_type) { + case MLXCX_EVENT_PAGE_REQUEST: + VERIFY3U(from_be16(ent->mleqe_page_request. + mled_page_request_function_id), ==, 0); + npages += (int32_t)from_be32(ent->mleqe_page_request. + mled_page_request_num_pages); + break; + case MLXCX_EVENT_PORT_STATE: + portn = get_bits8( + ent->mleqe_port_state.mled_port_state_port_num, + MLXCX_EVENT_PORT_NUM) - 1; + if (portn >= mlxp->mlx_nports) + break; + port = &mlxp->mlx_ports[portn]; + mlxcx_update_link_state(mlxp, port); + break; + case MLXCX_EVENT_PORT_MODULE: + mlxcx_report_module_error(mlxp, &ent->mleqe_port_mod); + break; + default: + mlxcx_warn(mlxp, "unhandled event 0x%x on int0", + ent->mleqe_event_type); + } + } + + if (npages > 0) { + mlxcx_give_pages_once(mlxp, npages); + } else if (npages < 0) { + mlxcx_take_pages_once(mlxp, -1 * npages); + } + + mlxcx_arm_eq(mlxp, mleq); + mutex_exit(&mleq->mleq_mtx); + + return (DDI_INTR_CLAIMED); +} + +mblk_t * +mlxcx_rx_poll(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq, size_t bytelim) +{ + mlxcx_buffer_t *buf; + mblk_t *mp, *cmp, *nmp; + mlxcx_completionq_ent_t *cent; + size_t bytes = 0; + boolean_t found; + + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + + ASSERT(mlcq->mlcq_wq != NULL); + ASSERT3U(mlcq->mlcq_wq->mlwq_type, ==, MLXCX_WQ_TYPE_RECVQ); + + if (!(mlcq->mlcq_state & MLXCX_CQ_ALLOC) || + !(mlcq->mlcq_state & MLXCX_CQ_CREATED) || + (mlcq->mlcq_state & MLXCX_CQ_DESTROYED) || + (mlcq->mlcq_state & MLXCX_CQ_TEARDOWN)) { + return (NULL); + } + + ASSERT(mlcq->mlcq_state & MLXCX_CQ_POLLING); + + nmp = cmp = mp = NULL; + + cent = mlxcx_cq_next(mlcq); + for (; cent != NULL; cent = mlxcx_cq_next(mlcq)) { + /* + * Teardown and ring stop can atomic_or this flag + * into our state if they want us to stop early. + */ + if (mlcq->mlcq_state & MLXCX_CQ_TEARDOWN) + break; + + if (cent->mlcqe_opcode == MLXCX_CQE_OP_REQ && + cent->mlcqe_send_wqe_opcode == MLXCX_WQE_OP_NOP) { + /* NOP */ + goto nextcq; + } + + buf = list_head(&mlcq->mlcq_buffers); + found = B_FALSE; + while (buf != NULL) { + if ((buf->mlb_wqe_index & UINT16_MAX) == + from_be16(cent->mlcqe_wqe_counter)) { + found = B_TRUE; + break; + } + buf = list_next(&mlcq->mlcq_buffers, buf); + } + if (!found) { + buf = list_head(&mlcq->mlcq_buffers); + mlxcx_warn(mlxp, "got completion on CQ %x but " + "no buffer matching wqe found: %x (first " + "buffer counter = %x)", mlcq->mlcq_num, + from_be16(cent->mlcqe_wqe_counter), + buf == NULL ? UINT32_MAX : buf->mlb_wqe_index); + mlxcx_fm_ereport(mlxp, DDI_FM_DEVICE_INVAL_STATE); + goto nextcq; + } + list_remove(&mlcq->mlcq_buffers, buf); + atomic_dec_64(&mlcq->mlcq_bufcnt); + + nmp = mlxcx_rx_completion(mlxp, mlcq, cent, buf); + if (nmp != NULL) { + bytes += from_be32(cent->mlcqe_byte_cnt); + if (cmp != NULL) { + cmp->b_next = nmp; + cmp = nmp; + } else { + mp = cmp = nmp; + } + } +nextcq: + mlcq->mlcq_doorbell->mlcqd_update_ci = to_be24(mlcq->mlcq_cc); + + if (bytelim != 0 && bytes > bytelim) + break; + } + + return (mp); +} + +static uint_t +mlxcx_intr_n(caddr_t arg, caddr_t arg2) +{ + mlxcx_t *mlxp = (mlxcx_t *)arg; + mlxcx_event_queue_t *mleq = (mlxcx_event_queue_t *)arg2; + mlxcx_eventq_ent_t *ent; + mlxcx_completionq_ent_t *cent; + mlxcx_completion_queue_t *mlcq, probe; + mlxcx_buffer_t *buf; + mblk_t *mp, *cmp, *nmp; + boolean_t found, tellmac = B_FALSE, added; + + mutex_enter(&mleq->mleq_mtx); + + if (!(mleq->mleq_state & MLXCX_EQ_ALLOC) || + !(mleq->mleq_state & MLXCX_EQ_CREATED) || + (mleq->mleq_state & MLXCX_EQ_DESTROYED)) { + mutex_exit(&mleq->mleq_mtx); + return (DDI_INTR_CLAIMED); + } + + ent = mlxcx_eq_next(mleq); + if (ent == NULL) { + if (++mleq->mleq_badintrs > mlxcx_stuck_intr_count) { + mlxcx_fm_ereport(mlxp, DDI_FM_DEVICE_BADINT_LIMIT); + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_LOST); + (void) ddi_intr_disable(mlxp->mlx_intr_handles[ + mleq->mleq_intr_index]); + } + mutex_exit(&mleq->mleq_mtx); + return (DDI_INTR_CLAIMED); + } + mleq->mleq_badintrs = 0; + + ASSERT(mleq->mleq_state & MLXCX_EQ_ARMED); + mleq->mleq_state &= ~MLXCX_EQ_ARMED; + + for (; ent != NULL; ent = mlxcx_eq_next(mleq)) { + if (ent->mleqe_event_type != MLXCX_EVENT_COMPLETION) { + mlxcx_fm_ereport(mlxp, DDI_FM_DEVICE_INVAL_STATE); + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_LOST); + (void) ddi_intr_disable(mlxp->mlx_intr_handles[ + mleq->mleq_intr_index]); + mutex_exit(&mleq->mleq_mtx); + return (DDI_INTR_CLAIMED); + } + ASSERT3U(ent->mleqe_event_type, ==, MLXCX_EVENT_COMPLETION); + + probe.mlcq_num = + from_be24(ent->mleqe_completion.mled_completion_cqn); + mlcq = avl_find(&mleq->mleq_cqs, &probe, NULL); + + if (mlcq == NULL) + continue; + + /* + * The polling function might have the mutex and stop us from + * getting the lock here, so we increment the event counter + * atomically from outside. + * + * This way at the end of polling when we go back to interrupts + * from this CQ, the event counter is still correct. + * + * Note that mlxcx_mac_ring_intr_enable() takes the EQ lock so + * as to avoid any possibility of racing against us here, so we + * only have to consider mlxcx_rx_poll(). + */ + atomic_inc_32(&mlcq->mlcq_ec); + atomic_and_uint(&mlcq->mlcq_state, ~MLXCX_CQ_ARMED); + + if (mutex_tryenter(&mlcq->mlcq_mtx) == 0) { + /* + * If we failed to take the mutex because the polling + * function has it, just move on. We don't want to + * block other CQs behind this one. + */ + if (mlcq->mlcq_state & MLXCX_CQ_POLLING) + continue; + /* Otherwise we will wait. */ + mutex_enter(&mlcq->mlcq_mtx); + } + + if (!(mlcq->mlcq_state & MLXCX_CQ_ALLOC) || + !(mlcq->mlcq_state & MLXCX_CQ_CREATED) || + (mlcq->mlcq_state & MLXCX_CQ_DESTROYED) || + (mlcq->mlcq_state & MLXCX_CQ_TEARDOWN) || + (mlcq->mlcq_state & MLXCX_CQ_POLLING)) { + mutex_exit(&mlcq->mlcq_mtx); + continue; + } + + nmp = cmp = mp = NULL; + tellmac = B_FALSE; + + cent = mlxcx_cq_next(mlcq); + for (; cent != NULL; cent = mlxcx_cq_next(mlcq)) { + /* + * Teardown and ring stop can atomic_or this flag + * into our state if they want us to stop early. + */ + if (mlcq->mlcq_state & MLXCX_CQ_TEARDOWN) + break; + if (mlcq->mlcq_state & MLXCX_CQ_POLLING) + break; + + if (cent->mlcqe_opcode == MLXCX_CQE_OP_REQ && + cent->mlcqe_send_wqe_opcode == MLXCX_WQE_OP_NOP) { + /* NOP */ + goto nextcq; + } + +lookagain: + /* + * Generally the buffer we're looking for will be + * at the front of the list, so this loop won't + * need to look far. + */ + buf = list_head(&mlcq->mlcq_buffers); + found = B_FALSE; + while (buf != NULL) { + if ((buf->mlb_wqe_index & UINT16_MAX) == + from_be16(cent->mlcqe_wqe_counter)) { + found = B_TRUE; + break; + } + buf = list_next(&mlcq->mlcq_buffers, buf); + } + if (!found) { + /* + * If there's any buffers waiting on the + * buffers_b list, then merge those into + * the main list and have another look. + * + * The wq enqueue routines push new buffers + * into buffers_b so that they can avoid + * taking the mlcq_mtx and blocking us for + * every single packet. + */ + added = B_FALSE; + mutex_enter(&mlcq->mlcq_bufbmtx); + if (!list_is_empty(&mlcq->mlcq_buffers_b)) { + list_move_tail(&mlcq->mlcq_buffers, + &mlcq->mlcq_buffers_b); + added = B_TRUE; + } + mutex_exit(&mlcq->mlcq_bufbmtx); + if (added) + goto lookagain; + } + if (!found) { + buf = list_head(&mlcq->mlcq_buffers); + mlxcx_warn(mlxp, "got completion on CQ %x but " + "no buffer matching wqe found: %x (first " + "buffer counter = %x)", mlcq->mlcq_num, + from_be16(cent->mlcqe_wqe_counter), + buf == NULL ? UINT32_MAX : + buf->mlb_wqe_index); + mlxcx_fm_ereport(mlxp, + DDI_FM_DEVICE_INVAL_STATE); + goto nextcq; + } + list_remove(&mlcq->mlcq_buffers, buf); + atomic_dec_64(&mlcq->mlcq_bufcnt); + + switch (mlcq->mlcq_wq->mlwq_type) { + case MLXCX_WQ_TYPE_SENDQ: + mlxcx_tx_completion(mlxp, mlcq, cent, buf); + break; + case MLXCX_WQ_TYPE_RECVQ: + nmp = mlxcx_rx_completion(mlxp, mlcq, cent, + buf); + if (nmp != NULL) { + if (cmp != NULL) { + cmp->b_next = nmp; + cmp = nmp; + } else { + mp = cmp = nmp; + } + } + break; + } + +nextcq: + /* + * Update the "doorbell" consumer counter for the queue + * every time. Unlike a UAR write, this is relatively + * cheap and doesn't require us to go out on the bus + * straight away (since it's our memory). + */ + mlcq->mlcq_doorbell->mlcqd_update_ci = + to_be24(mlcq->mlcq_cc); + + if ((mlcq->mlcq_state & MLXCX_CQ_BLOCKED_MAC) && + mlcq->mlcq_bufcnt < mlcq->mlcq_buflwm) { + mlcq->mlcq_state &= ~MLXCX_CQ_BLOCKED_MAC; + tellmac = B_TRUE; + } + } + + mlxcx_arm_cq(mlxp, mlcq); + mutex_exit(&mlcq->mlcq_mtx); + + if (tellmac) { + mac_tx_ring_update(mlxp->mlx_mac_hdl, + mlcq->mlcq_mac_hdl); + } + if (mp != NULL) { + mac_rx_ring(mlxp->mlx_mac_hdl, mlcq->mlcq_mac_hdl, + mp, mlcq->mlcq_mac_gen); + } + + /* + * Updating the consumer counter for an EQ requires a write + * to the UAR, which is possibly expensive. + * + * Try to do it only often enough to stop us wrapping around. + */ + if ((mleq->mleq_cc & 0x7) == 0) + mlxcx_update_eq(mlxp, mleq); + } + + mlxcx_arm_eq(mlxp, mleq); + mutex_exit(&mleq->mleq_mtx); + + return (DDI_INTR_CLAIMED); +} + +boolean_t +mlxcx_intr_setup(mlxcx_t *mlxp) +{ + dev_info_t *dip = mlxp->mlx_dip; + int ret; + int nintrs = 0; + int navail = 0; + int types, i; + mlxcx_eventq_type_t eqt = MLXCX_EQ_TYPE_ANY; + + ret = ddi_intr_get_supported_types(dip, &types); + if (ret != DDI_SUCCESS) { + return (B_FALSE); + } + + if (!(types & DDI_INTR_TYPE_MSIX)) { + mlxcx_warn(mlxp, "MSI-X interrupts not available, but mlxcx " + "requires MSI-X"); + return (B_FALSE); + } + + ret = ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_MSIX, &nintrs); + if (ret != DDI_SUCCESS) { + return (B_FALSE); + } + if (nintrs < 2) { + mlxcx_warn(mlxp, "%d MSI-X interrupts available, but mlxcx " + "requires 2", nintrs); + return (B_FALSE); + } + + ret = ddi_intr_get_navail(dip, DDI_INTR_TYPE_MSIX, &navail); + if (navail < 2) { + mlxcx_warn(mlxp, "%d MSI-X interrupts available, but mlxcx " + "requires 2", navail); + return (B_FALSE); + } + + mlxp->mlx_intr_size = navail * sizeof (ddi_intr_handle_t); + mlxp->mlx_intr_handles = kmem_alloc(mlxp->mlx_intr_size, KM_SLEEP); + + ret = ddi_intr_alloc(dip, mlxp->mlx_intr_handles, DDI_INTR_TYPE_MSIX, + 0, navail, &mlxp->mlx_intr_count, DDI_INTR_ALLOC_NORMAL); + if (ret != DDI_SUCCESS) { + mlxcx_intr_teardown(mlxp); + return (B_FALSE); + } + if (mlxp->mlx_intr_count < 2) { + mlxcx_intr_teardown(mlxp); + return (B_FALSE); + } + mlxp->mlx_intr_type = DDI_INTR_TYPE_MSIX; + + ret = ddi_intr_get_pri(mlxp->mlx_intr_handles[0], &mlxp->mlx_intr_pri); + if (ret != DDI_SUCCESS) { + mlxcx_intr_teardown(mlxp); + return (B_FALSE); + } + + mlxp->mlx_eqs_size = mlxp->mlx_intr_count * + sizeof (mlxcx_event_queue_t); + mlxp->mlx_eqs = kmem_zalloc(mlxp->mlx_eqs_size, KM_SLEEP); + + ret = ddi_intr_add_handler(mlxp->mlx_intr_handles[0], mlxcx_intr_0, + (caddr_t)mlxp, (caddr_t)&mlxp->mlx_eqs[0]); + if (ret != DDI_SUCCESS) { + mlxcx_intr_teardown(mlxp); + return (B_FALSE); + } + + /* + * If we have enough interrupts, set their "type" fields so that we + * avoid mixing RX and TX queues on the same EQs. + */ + if (mlxp->mlx_intr_count >= 8) { + eqt = MLXCX_EQ_TYPE_RX; + } + + for (i = 1; i < mlxp->mlx_intr_count; ++i) { + mutex_init(&mlxp->mlx_eqs[i].mleq_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + avl_create(&mlxp->mlx_eqs[i].mleq_cqs, mlxcx_cq_compare, + sizeof (mlxcx_completion_queue_t), + offsetof(mlxcx_completion_queue_t, mlcq_eq_entry)); + mlxp->mlx_eqs[i].mleq_intr_index = i; + + mlxp->mlx_eqs[i].mleq_type = eqt; + /* + * If eqt is still ANY, just leave it set to that + * (no else here). + */ + if (eqt == MLXCX_EQ_TYPE_RX) { + eqt = MLXCX_EQ_TYPE_TX; + } else if (eqt == MLXCX_EQ_TYPE_TX) { + eqt = MLXCX_EQ_TYPE_RX; + } + + ret = ddi_intr_add_handler(mlxp->mlx_intr_handles[i], + mlxcx_intr_n, (caddr_t)mlxp, (caddr_t)&mlxp->mlx_eqs[i]); + if (ret != DDI_SUCCESS) { + mlxcx_intr_teardown(mlxp); + return (B_FALSE); + } + } + + return (B_TRUE); +} diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_reg.h b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h new file mode 100644 index 0000000000..76d0da30e7 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h @@ -0,0 +1,2481 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020, The University of Queensland + * Copyright (c) 2018, Joyent, Inc. + */ + +#ifndef _MLXCX_REG_H +#define _MLXCX_REG_H + +#include <sys/types.h> +#include <sys/byteorder.h> + +#include <mlxcx_endint.h> + +#if !defined(_BIT_FIELDS_HTOL) && !defined(_BIT_FIELDS_LTOH) +#error "Need _BIT_FIELDS_HTOL or _BIT_FIELDS_LTOH" +#endif + +/* + * Register offsets. + */ + +#define MLXCX_ISS_FIRMWARE 0x0000 +#define MLXCX_ISS_FW_MAJOR(x) (((x) & 0xffff)) +#define MLXCX_ISS_FW_MINOR(x) (((x) >> 16) & 0xffff) +#define MLXCX_ISS_FW_CMD 0x0004 +#define MLXCX_ISS_FW_REV(x) (((x) & 0xffff)) +#define MLXCX_ISS_CMD_REV(x) (((x) >> 16) & 0xffff) +#define MLXCX_ISS_CMD_HIGH 0x0010 +#define MLXCX_ISS_CMD_LOW 0x0014 +#define MLXCX_ISS_CMDQ_SIZE(x) (((x) >> 4) & 0xf) +#define MLXCX_ISS_CMDQ_STRIDE(x) ((x) & 0xf) + +#define MLXCX_ISS_CMD_DOORBELL 0x0018 +#define MLXCX_ISS_INIT 0x01fc +#define MLXCX_ISS_INITIALIZING(x) (((x) >> 31) & 0x1) +#define MLXCX_ISS_HEALTH_BUF 0x0200 +#define MLXCX_ISS_NO_DRAM_NIC 0x0240 +#define MLXCX_ISS_TIMER 0x1000 +#define MLXCX_ISS_HEALTH_COUNT 0x1010 +#define MLXCX_ISS_HEALTH_SYND 0x1013 + +#define MLXCX_CMD_INLINE_INPUT_LEN 16 +#define MLXCX_CMD_INLINE_OUTPUT_LEN 16 + +#define MLXCX_CMD_MAILBOX_LEN 512 + +#define MLXCX_CMD_TRANSPORT_PCI 7 +#define MLXCX_CMD_HW_OWNED 0x01 +#define MLXCX_CMD_STATUS(x) ((x) >> 1) + +#define MLXCX_UAR_CQ_ARM 0x0020 +#define MLXCX_UAR_EQ_ARM 0x0040 +#define MLXCX_UAR_EQ_NOARM 0x0048 + +/* Number of blue flame reg pairs per UAR */ +#define MLXCX_BF_PER_UAR 2 +#define MLXCX_BF_PER_UAR_MASK 0x1 +#define MLXCX_BF_SIZE 0x100 +#define MLXCX_BF_BASE 0x0800 + +/* CSTYLED */ +#define MLXCX_EQ_ARM_EQN (bitdef_t){24, 0xff000000} +/* CSTYLED */ +#define MLXCX_EQ_ARM_CI (bitdef_t){0, 0x00ffffff} + +/* + * Hardware structure that is used to represent a command. + */ +#pragma pack(1) +typedef struct { + uint8_t mce_type; + uint8_t mce_rsvd[3]; + uint32be_t mce_in_length; + uint64be_t mce_in_mbox; + uint8_t mce_input[MLXCX_CMD_INLINE_INPUT_LEN]; + uint8_t mce_output[MLXCX_CMD_INLINE_OUTPUT_LEN]; + uint64be_t mce_out_mbox; + uint32be_t mce_out_length; + uint8_t mce_token; + uint8_t mce_sig; + uint8_t mce_rsvd1; + uint8_t mce_status; +} mlxcx_cmd_ent_t; + +typedef struct { + uint8_t mlxb_data[MLXCX_CMD_MAILBOX_LEN]; + uint8_t mlxb_rsvd[48]; + uint64be_t mlxb_nextp; + uint32be_t mlxb_blockno; + uint8_t mlxb_rsvd1; + uint8_t mlxb_token; + uint8_t mlxb_ctrl_sig; + uint8_t mlxb_sig; +} mlxcx_cmd_mailbox_t; + +typedef struct { + uint8_t mled_page_request_rsvd[2]; + uint16be_t mled_page_request_function_id; + uint32be_t mled_page_request_num_pages; +} mlxcx_evdata_page_request_t; + +/* CSTYLED */ +#define MLXCX_EVENT_PORT_NUM (bitdef_t){ .bit_shift = 4, .bit_mask = 0xF0 } + +typedef struct { + uint8_t mled_port_state_rsvd[8]; + bits8_t mled_port_state_port_num; +} mlxcx_evdata_port_state_t; + +typedef enum { + MLXCX_MODULE_INITIALIZING = 0x0, + MLXCX_MODULE_PLUGGED = 0x1, + MLXCX_MODULE_UNPLUGGED = 0x2, + MLXCX_MODULE_ERROR = 0x3 +} mlxcx_module_status_t; + +typedef enum { + MLXCX_MODULE_ERR_POWER_BUDGET = 0x0, + MLXCX_MODULE_ERR_LONG_RANGE = 0x1, + MLXCX_MODULE_ERR_BUS_STUCK = 0x2, + MLXCX_MODULE_ERR_NO_EEPROM = 0x3, + MLXCX_MODULE_ERR_ENFORCEMENT = 0x4, + MLXCX_MODULE_ERR_UNKNOWN_IDENT = 0x5, + MLXCX_MODULE_ERR_HIGH_TEMP = 0x6, + MLXCX_MODULE_ERR_CABLE_SHORTED = 0x7, +} mlxcx_module_error_type_t; + +typedef struct { + uint8_t mled_port_mod_rsvd; + uint8_t mled_port_mod_module; + uint8_t mled_port_mod_rsvd2; + uint8_t mled_port_mod_module_status; + uint8_t mled_port_mod_rsvd3[2]; + uint8_t mled_port_mod_error_type; + uint8_t mled_port_mod_rsvd4; +} mlxcx_evdata_port_mod_t; + +typedef struct { + uint8_t mled_completion_rsvd[25]; + uint24be_t mled_completion_cqn; +} mlxcx_evdata_completion_t; + +typedef enum { + MLXCX_EV_QUEUE_TYPE_QP = 0x0, + MLXCX_EV_QUEUE_TYPE_RQ = 0x1, + MLXCX_EV_QUEUE_TYPE_SQ = 0x2, +} mlxcx_evdata_queue_type_t; + +typedef struct { + uint8_t mled_queue_rsvd[20]; + uint8_t mled_queue_type; + uint8_t mled_queue_rsvd2[4]; + uint24be_t mled_queue_num; +} mlxcx_evdata_queue_t; + +#define MLXCX_EQ_OWNER_INIT 1 + +typedef struct { + uint8_t mleqe_rsvd[1]; + uint8_t mleqe_event_type; + uint8_t mleqe_rsvd2[1]; + uint8_t mleqe_event_sub_type; + uint8_t mleqe_rsvd3[28]; + union { + uint8_t mleqe_unknown_data[28]; + mlxcx_evdata_completion_t mleqe_completion; + mlxcx_evdata_page_request_t mleqe_page_request; + mlxcx_evdata_port_state_t mleqe_port_state; + mlxcx_evdata_port_mod_t mleqe_port_mod; + mlxcx_evdata_queue_t mleqe_queue; + }; + uint8_t mleqe_rsvd4[2]; + uint8_t mleqe_signature; + uint8_t mleqe_owner; +} mlxcx_eventq_ent_t; + +typedef enum { + MLXCX_CQE_L3_HDR_NONE = 0x0, + MLXCX_CQE_L3_HDR_RCV_BUF = 0x1, + MLXCX_CQE_L3_HDR_CQE = 0x2, +} mlxcx_cqe_l3_hdr_placement_t; + +typedef enum { + MLXCX_CQE_CSFLAGS_L4_OK = 1 << 2, + MLXCX_CQE_CSFLAGS_L3_OK = 1 << 1, + MLXCX_CQE_CSFLAGS_L2_OK = 1 << 0, +} mlxcx_cqe_csflags_t; + +typedef enum { + MLXCX_CQE_L4_TYPE_NONE = 0, + MLXCX_CQE_L4_TYPE_TCP = 1, + MLXCX_CQE_L4_TYPE_UDP = 2, + MLXCX_CQE_L4_TYPE_TCP_EMPTY_ACK = 3, + MLXCX_CQE_L4_TYPE_TCP_ACK = 4, +} mlxcx_cqe_l4_hdr_type_t; + +typedef enum { + MLXCX_CQE_L3_TYPE_NONE = 0, + MLXCX_CQE_L3_TYPE_IPv6 = 1, + MLXCX_CQE_L3_TYPE_IPv4 = 2, +} mlxcx_cqe_l3_hdr_type_t; + +typedef enum { + MLXCX_CQE_RX_HASH_NONE = 0, + MLXCX_CQE_RX_HASH_IPv4 = 1, + MLXCX_CQE_RX_HASH_IPv6 = 2, + MLXCX_CQE_RX_HASH_IPSEC_SPI = 3, +} mlxcx_cqe_rx_hash_type_t; +/* BEGIN CSTYLED */ +#define MLXCX_CQE_RX_HASH_IP_SRC (bitdef_t){0, 0x3} +#define MLXCX_CQE_RX_HASH_IP_DEST (bitdef_t){2, (0x3 << 2)} +#define MLXCX_CQE_RX_HASH_L4_SRC (bitdef_t){4, (0x3 << 4)} +#define MLXCX_CQE_RX_HASH_L4_DEST (bitdef_t){6, (0x3 << 6)} +/* END CSTYLED */ + +typedef enum { + MLXCX_CQE_OP_REQ = 0x0, + MLXCX_CQE_OP_RESP_RDMA = 0x1, + MLXCX_CQE_OP_RESP = 0x2, + MLXCX_CQE_OP_RESP_IMMEDIATE = 0x3, + MLXCX_CQE_OP_RESP_INVALIDATE = 0x4, + MLXCX_CQE_OP_RESIZE_CQ = 0x5, + MLXCX_CQE_OP_SIG_ERR = 0x12, + MLXCX_CQE_OP_REQ_ERR = 0xd, + MLXCX_CQE_OP_RESP_ERR = 0xe, + MLXCX_CQE_OP_INVALID = 0xf +} mlxcx_cqe_opcode_t; + +typedef enum { + MLXCX_CQE_FORMAT_BASIC = 0, + MLXCX_CQE_FORMAT_INLINE_32 = 1, + MLXCX_CQE_FORMAT_INLINE_64 = 2, + MLXCX_CQE_FORMAT_COMPRESSED = 3, +} mlxcx_cqe_format_t; + +typedef enum { + MLXCX_CQE_OWNER_INIT = 1 +} mlxcx_cqe_owner_t; + +typedef enum { + MLXCX_VLAN_TYPE_NONE, + MLXCX_VLAN_TYPE_CVLAN, + MLXCX_VLAN_TYPE_SVLAN, +} mlxcx_vlan_type_t; + +typedef enum { + MLXCX_CQ_ERR_LOCAL_LENGTH = 0x1, + MLXCX_CQ_ERR_LOCAL_QP_OP = 0x2, + MLXCX_CQ_ERR_LOCAL_PROTECTION = 0x4, + MLXCX_CQ_ERR_WR_FLUSHED = 0x5, + MLXCX_CQ_ERR_MEM_WINDOW_BIND = 0x6, + MLXCX_CQ_ERR_BAD_RESPONSE = 0x10, + MLXCX_CQ_ERR_LOCAL_ACCESS = 0x11, + MLXCX_CQ_ERR_XPORT_RETRY_CTR = 0x15, + MLXCX_CQ_ERR_RNR_RETRY_CTR = 0x16, + MLXCX_CQ_ERR_ABORTED = 0x22 +} mlxcx_cq_error_syndrome_t; + +typedef struct { + uint8_t mlcqee_rsvd[2]; + uint16be_t mlcqee_wqe_id; + uint8_t mlcqee_rsvd2[29]; + uint24be_t mlcqee_user_index; + uint8_t mlcqee_rsvd3[8]; + uint32be_t mlcqee_byte_cnt; + uint8_t mlcqee_rsvd4[6]; + uint8_t mlcqee_vendor_error_syndrome; + uint8_t mlcqee_syndrome; + uint8_t mlcqee_wqe_opcode; + uint24be_t mlcqee_flow_tag; + uint16be_t mlcqee_wqe_counter; + uint8_t mlcqee_signature; + struct { +#if defined(_BIT_FIELDS_HTOL) + uint8_t mlcqe_opcode:4; + uint8_t mlcqe_rsvd5:3; + uint8_t mlcqe_owner:1; +#elif defined(_BIT_FIELDS_LTOH) + uint8_t mlcqe_owner:1; + uint8_t mlcqe_rsvd5:3; + uint8_t mlcqe_opcode:4; +#endif + }; +} mlxcx_completionq_error_ent_t; + +typedef struct { + uint8_t mlcqe_tunnel_flags; + uint8_t mlcqe_rsvd[3]; + uint8_t mlcqe_lro_flags; + uint8_t mlcqe_lro_min_ttl; + uint16be_t mlcqe_lro_tcp_win; + uint32be_t mlcqe_lro_ack_seq_num; + uint32be_t mlcqe_rx_hash_result; + bits8_t mlcqe_rx_hash_type; + uint8_t mlcqe_ml_path; + uint8_t mlcqe_rsvd2[2]; + uint16be_t mlcqe_checksum; + uint16be_t mlcqe_slid_smac_lo; + struct { +#if defined(_BIT_FIELDS_HTOL) + uint8_t mlcqe_rsvd3:1; + uint8_t mlcqe_force_loopback:1; + uint8_t mlcqe_l3_hdr:2; + uint8_t mlcqe_sl_roce_pktype:4; +#elif defined(_BIT_FIELDS_LTOH) + uint8_t mlcqe_sl_roce_pktype:4; + uint8_t mlcqe_l3_hdr:2; + uint8_t mlcqe_force_loopback:1; + uint8_t mlcqe_rsvd3:1; +#endif + }; + uint24be_t mlcqe_rqpn; + bits8_t mlcqe_csflags; + struct { +#if defined(_BIT_FIELDS_HTOL) + uint8_t mlcqe_ip_frag:1; + uint8_t mlcqe_l4_hdr_type:3; + uint8_t mlcqe_l3_hdr_type:2; + uint8_t mlcqe_ip_ext_opts:1; + uint8_t mlcqe_cv:1; +#elif defined(_BIT_FIELDS_LTOH) + uint8_t mlcqe_cv:1; + uint8_t mlcqe_ip_ext_opts:1; + uint8_t mlcqe_l3_hdr_type:2; + uint8_t mlcqe_l4_hdr_type:3; + uint8_t mlcqe_ip_frag:1; +#endif + }; + uint16be_t mlcqe_up_cfi_vid; + uint8_t mlcqe_lro_num_seg; + uint24be_t mlcqe_user_index; + uint32be_t mlcqe_immediate; + uint8_t mlcqe_rsvd4[4]; + uint32be_t mlcqe_byte_cnt; + union { + struct { + uint32be_t mlcqe_lro_timestamp_value; + uint32be_t mlcqe_lro_timestamp_echo; + }; + uint64be_t mlcqe_timestamp; + }; + union { + uint8_t mlcqe_rx_drop_counter; + uint8_t mlcqe_send_wqe_opcode; + }; + uint24be_t mlcqe_flow_tag; + uint16be_t mlcqe_wqe_counter; + uint8_t mlcqe_signature; + struct { +#if defined(_BIT_FIELDS_HTOL) + uint8_t mlcqe_opcode:4; + uint8_t mlcqe_format:2; + uint8_t mlcqe_se:1; + uint8_t mlcqe_owner:1; +#elif defined(_BIT_FIELDS_LTOH) + uint8_t mlcqe_owner:1; + uint8_t mlcqe_se:1; + uint8_t mlcqe_format:2; + uint8_t mlcqe_opcode:4; +#endif + }; +} mlxcx_completionq_ent_t; + +typedef struct { + uint8_t mlcqe_data[64]; + mlxcx_completionq_ent_t mlcqe_ent; +} mlxcx_completionq_ent128_t; + +typedef enum { + MLXCX_WQE_OP_NOP = 0x00, + MLXCX_WQE_OP_SEND_INVALIDATE = 0x01, + MLXCX_WQE_OP_RDMA_W = 0x08, + MLXCX_WQE_OP_RDMA_W_IMMEDIATE = 0x09, + MLXCX_WQE_OP_SEND = 0x0A, + MLXCX_WQE_OP_SEND_IMMEDIATE = 0x0B, + MLXCX_WQE_OP_LSO = 0x0E, + MLXCX_WQE_OP_WAIT = 0x0F, + MLXCX_WQE_OP_RDMA_R = 0x10, +} mlxcx_wqe_opcode_t; + +#define MLXCX_SQE_MAX_DS ((1 << 6) - 1) +#define MLXCX_SQE_MAX_PTRS 61 + +typedef enum { + MLXCX_SQE_FENCE_NONE = 0x0, + MLXCX_SQE_FENCE_WAIT_OTHERS = 0x1, + MLXCX_SQE_FENCE_START = 0x2, + MLXCX_SQE_FENCE_STRONG_ORDER = 0x3, + MLXCX_SQE_FENCE_START_WAIT = 0x4 +} mlxcx_sqe_fence_mode_t; + +typedef enum { + MLXCX_SQE_CQE_ON_EACH_ERROR = 0x0, + MLXCX_SQE_CQE_ON_FIRST_ERROR = 0x1, + MLXCX_SQE_CQE_ALWAYS = 0x2, + MLXCX_SQE_CQE_ALWAYS_PLUS_EQE = 0x3 +} mlxcx_sqe_completion_mode_t; + +#define MLXCX_SQE_SOLICITED (1 << 1) +/* CSTYLED */ +#define MLXCX_SQE_FENCE_MODE (bitdef_t){5, 0xe0} +/* CSTYLED */ +#define MLXCX_SQE_COMPLETION_MODE (bitdef_t){2, 0x0c} + +typedef struct { + uint8_t mlcs_opcode_mod; + uint16be_t mlcs_wqe_index; + uint8_t mlcs_opcode; + uint24be_t mlcs_qp_or_sq; + uint8_t mlcs_ds; + uint8_t mlcs_signature; + uint8_t mlcs_rsvd2[2]; + bits8_t mlcs_flags; + uint32be_t mlcs_immediate; +} mlxcx_wqe_control_seg_t; + +typedef enum { + MLXCX_SQE_ETH_CSFLAG_L4_CHECKSUM = 1 << 7, + MLXCX_SQE_ETH_CSFLAG_L3_CHECKSUM = 1 << 6, + MLXCX_SQE_ETH_CSFLAG_L4_INNER_CHECKSUM = 1 << 5, + MLXCX_SQE_ETH_CSFLAG_L3_INNER_CHECKSUM = 1 << 4, +} mlxcx_wqe_eth_flags_t; + +/* CSTYLED */ +#define MLXCX_SQE_ETH_INLINE_HDR_SZ (bitdef_t){0, 0x03ff} +#define MLXCX_SQE_ETH_SZFLAG_VLAN (1 << 15) +#define MLXCX_MAX_INLINE_HEADERLEN 64 + +typedef struct { + uint8_t mles_rsvd[4]; + bits8_t mles_csflags; + uint8_t mles_rsvd2[1]; + uint16_t mles_mss; + uint8_t mles_rsvd3[4]; + bits16_t mles_szflags; + uint8_t mles_inline_headers[18]; +} mlxcx_wqe_eth_seg_t; + +typedef struct { + uint32be_t mlds_byte_count; + uint32be_t mlds_lkey; + uint64be_t mlds_address; +} mlxcx_wqe_data_seg_t; + +#define MLXCX_SENDQ_STRIDE_SHIFT 6 + +typedef struct { + mlxcx_wqe_control_seg_t mlsqe_control; + mlxcx_wqe_eth_seg_t mlsqe_eth; + mlxcx_wqe_data_seg_t mlsqe_data[1]; +} mlxcx_sendq_ent_t; + +typedef struct { + uint64be_t mlsqbf_qwords[8]; +} mlxcx_sendq_bf_t; + +typedef struct { + mlxcx_wqe_data_seg_t mlsqe_data[4]; +} mlxcx_sendq_extra_ent_t; + +#define MLXCX_RECVQ_STRIDE_SHIFT 7 +/* + * Each mlxcx_wqe_data_seg_t is 1<<4 bytes long (there's a CTASSERT to verify + * this in mlxcx_cmd.c), so the number of pointers is 1 << (shift - 4). + */ +#define MLXCX_RECVQ_MAX_PTRS (1 << (MLXCX_RECVQ_STRIDE_SHIFT - 4)) +typedef struct { + mlxcx_wqe_data_seg_t mlrqe_data[MLXCX_RECVQ_MAX_PTRS]; +} mlxcx_recvq_ent_t; + +/* CSTYLED */ +#define MLXCX_CQ_ARM_CI (bitdef_t){ .bit_shift = 0, \ + .bit_mask = 0x00ffffff } +/* CSTYLED */ +#define MLXCX_CQ_ARM_SEQ (bitdef_t){ .bit_shift = 28, \ + .bit_mask = 0x30000000 } +#define MLXCX_CQ_ARM_SOLICITED (1 << 24) + +typedef struct { + uint8_t mlcqd_rsvd; + uint24be_t mlcqd_update_ci; + bits32_t mlcqd_arm_ci; +} mlxcx_completionq_doorbell_t; + +typedef struct { + uint16be_t mlwqd_rsvd; + uint16be_t mlwqd_recv_counter; + uint16be_t mlwqd_rsvd2; + uint16be_t mlwqd_send_counter; +} mlxcx_workq_doorbell_t; + +#define MLXCX_EQ_STATUS_OK (0x0 << 4) +#define MLXCX_EQ_STATUS_WRITE_FAILURE (0xA << 4) + +#define MLXCX_EQ_OI (1 << 1) +#define MLXCX_EQ_EC (1 << 2) + +#define MLXCX_EQ_ST_ARMED 0x9 +#define MLXCX_EQ_ST_FIRED 0xA + +/* CSTYLED */ +#define MLXCX_EQ_LOG_PAGE_SIZE (bitdef_t){ .bit_shift = 24, \ + .bit_mask = 0x1F000000 } + +typedef struct { + uint8_t mleqc_status; + uint8_t mleqc_ecoi; + uint8_t mleqc_state; + uint8_t mleqc_rsvd[7]; + uint16be_t mleqc_page_offset; + uint8_t mleqc_log_eq_size; + uint24be_t mleqc_uar_page; + uint8_t mleqc_rsvd3[7]; + uint8_t mleqc_intr; + uint32be_t mleqc_log_page; + uint8_t mleqc_rsvd4[13]; + uint24be_t mleqc_consumer_counter; + uint8_t mleqc_rsvd5; + uint24be_t mleqc_producer_counter; + uint8_t mleqc_rsvd6[16]; +} mlxcx_eventq_ctx_t; + +typedef enum { + MLXCX_CQC_CQE_SIZE_64 = 0x0, + MLXCX_CQC_CQE_SIZE_128 = 0x1, +} mlxcx_cqc_cqe_sz_t; + +typedef enum { + MLXCX_CQC_STATUS_OK = 0x0, + MLXCX_CQC_STATUS_OVERFLOW = 0x9, + MLXCX_CQC_STATUS_WRITE_FAIL = 0xA, + MLXCX_CQC_STATUS_INVALID = 0xF +} mlxcx_cqc_status_t; + +typedef enum { + MLXCX_CQC_STATE_ARMED_SOLICITED = 0x6, + MLXCX_CQC_STATE_ARMED = 0x9, + MLXCX_CQC_STATE_FIRED = 0xA +} mlxcx_cqc_state_t; + +/* CSTYLED */ +#define MLXCX_CQ_CTX_STATUS (bitdef_t){28, 0xf0000000} +/* CSTYLED */ +#define MLXCX_CQ_CTX_CQE_SZ (bitdef_t){21, 0x00e00000} +/* CSTYLED */ +#define MLXCX_CQ_CTX_PERIOD_MODE (bitdef_t){15, 0x00018000} +/* CSTYLED */ +#define MLXCX_CQ_CTX_MINI_CQE_FORMAT (bitdef_t){12, 0x00003000} +/* CSTYLED */ +#define MLXCX_CQ_CTX_STATE (bitdef_t){8, 0x00000f00} + +typedef struct mlxcx_completionq_ctx { + bits32_t mlcqc_flags; + + uint8_t mlcqc_rsvd4[4]; + + uint8_t mlcqc_rsvd5[2]; + uint16be_t mlcqc_page_offset; + + uint8_t mlcqc_log_cq_size; + uint24be_t mlcqc_uar_page; + + uint16be_t mlcqc_cq_period; + uint16be_t mlcqc_cq_max_count; + + uint8_t mlcqc_rsvd7[3]; + uint8_t mlcqc_eqn; + + uint8_t mlcqc_log_page_size; + uint8_t mlcqc_rsvd8[3]; + + uint8_t mlcqc_rsvd9[4]; + + uint8_t mlcqc_rsvd10; + uint24be_t mlcqc_last_notified_index; + uint8_t mlcqc_rsvd11; + uint24be_t mlcqc_last_solicit_index; + uint8_t mlcqc_rsvd12; + uint24be_t mlcqc_consumer_counter; + uint8_t mlcqc_rsvd13; + uint24be_t mlcqc_producer_counter; + + uint8_t mlcqc_rsvd14[8]; + + uint64be_t mlcqc_dbr_addr; +} mlxcx_completionq_ctx_t; + +typedef enum { + MLXCX_WORKQ_TYPE_LINKED_LIST = 0x0, + MLXCX_WORKQ_TYPE_CYCLIC = 0x1, + MLXCX_WORKQ_TYPE_LINKED_LIST_STRIDING = 0x2, + MLXCX_WORKQ_TYPE_CYCLIC_STRIDING = 0x3 +} mlxcx_workq_ctx_type_t; + +typedef enum { + MLXCX_WORKQ_END_PAD_NONE = 0x0, + MLXCX_WORKQ_END_PAD_ALIGN = 0x1 +} mlxcx_workq_end_padding_t; + +/* CSTYLED */ +#define MLXCX_WORKQ_CTX_TYPE (bitdef_t){ \ + .bit_shift = 28, \ + .bit_mask = 0xf0000000 } +#define MLXCX_WORKQ_CTX_SIGNATURE (1 << 27) +#define MLXCX_WORKQ_CTX_CD_SLAVE (1 << 24) +/* CSTYLED */ +#define MLXCX_WORKQ_CTX_END_PADDING (bitdef_t){ \ + .bit_shift = 25, \ + .bit_mask = 0x06000000 } + +#define MLXCX_WORKQ_CTX_MAX_ADDRESSES 128 + +typedef struct mlxcx_workq_ctx { + bits32_t mlwqc_flags; + uint8_t mlwqc_rsvd[2]; + uint16be_t mlwqc_lwm; + uint8_t mlwqc_rsvd2; + uint24be_t mlwqc_pd; + uint8_t mlwqc_rsvd3; + uint24be_t mlwqc_uar_page; + uint64be_t mlwqc_dbr_addr; + uint32be_t mlwqc_hw_counter; + uint32be_t mlwqc_sw_counter; + uint8_t mlwqc_rsvd4; + uint8_t mlwqc_log_wq_stride; + uint8_t mlwqc_log_wq_pg_sz; + uint8_t mlwqc_log_wq_sz; + uint8_t mlwqc_rsvd5[2]; + bits16_t mlwqc_strides; + uint8_t mlwqc_rsvd6[152]; + uint64be_t mlwqc_pas[MLXCX_WORKQ_CTX_MAX_ADDRESSES]; +} mlxcx_workq_ctx_t; + +#define MLXCX_RQ_FLAGS_RLKEY (1UL << 31) +#define MLXCX_RQ_FLAGS_SCATTER_FCS (1 << 29) +#define MLXCX_RQ_FLAGS_VLAN_STRIP_DISABLE (1 << 28) +#define MLXCX_RQ_FLAGS_FLUSH_IN_ERROR (1 << 18) +/* CSTYLED */ +#define MLXCX_RQ_MEM_RQ_TYPE (bitdef_t){ \ + .bit_shift = 24, \ + .bit_mask = 0x0f000000 } +/* CSTYLED */ +#define MLXCX_RQ_STATE (bitdef_t){ \ + .bit_shift = 20, \ + .bit_mask = 0x00f00000 } + +typedef struct mlxcx_rq_ctx { + bits32_t mlrqc_flags; + uint8_t mlrqc_rsvd; + uint24be_t mlrqc_user_index; + uint8_t mlrqc_rsvd2; + uint24be_t mlrqc_cqn; + uint8_t mlrqc_counter_set_id; + uint8_t mlrqc_rsvd3[4]; + uint24be_t mlrqc_rmpn; + uint8_t mlrqc_rsvd4[28]; + mlxcx_workq_ctx_t mlrqc_wq; +} mlxcx_rq_ctx_t; + +#define MLXCX_SQ_FLAGS_RLKEY (1UL << 31) +#define MLXCX_SQ_FLAGS_CD_MASTER (1 << 30) +#define MLXCX_SQ_FLAGS_FRE (1 << 29) +#define MLXCX_SQ_FLAGS_FLUSH_IN_ERROR (1 << 28) +#define MLXCX_SQ_FLAGS_ALLOW_MULTI_PKT (1 << 27) +#define MLXCX_SQ_FLAGS_REG_UMR (1 << 19) + +typedef enum { + MLXCX_ETH_CAP_INLINE_REQUIRE_L2 = 0, + MLXCX_ETH_CAP_INLINE_VPORT_CTX = 1, + MLXCX_ETH_CAP_INLINE_NOT_REQUIRED = 2 +} mlxcx_eth_cap_inline_mode_t; + +typedef enum { + MLXCX_ETH_INLINE_NONE = 0, + MLXCX_ETH_INLINE_L2 = 1, + MLXCX_ETH_INLINE_L3 = 2, + MLXCX_ETH_INLINE_L4 = 3, + MLXCX_ETH_INLINE_INNER_L2 = 5, + MLXCX_ETH_INLINE_INNER_L3 = 6, + MLXCX_ETH_INLINE_INNER_L4 = 7 +} mlxcx_eth_inline_mode_t; + +/* CSTYLED */ +#define MLXCX_SQ_MIN_WQE_INLINE (bitdef_t){ \ + .bit_shift = 24, \ + .bit_mask = 0x07000000 } +/* CSTYLED */ +#define MLXCX_SQ_STATE (bitdef_t){ \ + .bit_shift = 20, \ + .bit_mask = 0x00f00000 } + +typedef struct mlxcx_sq_ctx { + bits32_t mlsqc_flags; + uint8_t mlsqc_rsvd; + uint24be_t mlsqc_user_index; + uint8_t mlsqc_rsvd2; + uint24be_t mlsqc_cqn; + uint8_t mlsqc_rsvd3[18]; + uint16be_t mlsqc_packet_pacing_rate_limit_index; + uint16be_t mlsqc_tis_lst_sz; + uint8_t mlsqc_rsvd4[11]; + uint24be_t mlsqc_tis_num; + mlxcx_workq_ctx_t mlsqc_wq; +} mlxcx_sq_ctx_t; + +#define MLXCX_NIC_VPORT_CTX_MAX_ADDRESSES 64 + +typedef enum { + MLXCX_VPORT_PROMISC_UCAST = 1 << 15, + MLXCX_VPORT_PROMISC_MCAST = 1 << 14, + MLXCX_VPORT_PROMISC_ALL = 1 << 13 +} mlxcx_nic_vport_ctx_promisc_t; + +#define MLXCX_VPORT_LIST_TYPE_MASK 0x07 +#define MLXCX_VPORT_LIST_TYPE_SHIFT 0 + +/* CSTYLED */ +#define MLXCX_VPORT_CTX_MIN_WQE_INLINE (bitdef_t){56, 0x0700000000000000} + +typedef struct { + bits64_t mlnvc_flags; + uint8_t mlnvc_rsvd[28]; + uint8_t mlnvc_rsvd2[2]; + uint16be_t mlnvc_mtu; + uint64be_t mlnvc_system_image_guid; + uint64be_t mlnvc_port_guid; + uint64be_t mlnvc_node_guid; + uint8_t mlnvc_rsvd3[40]; + uint16be_t mlnvc_qkey_violation_counter; + uint8_t mlnvc_rsvd4[2]; + uint8_t mlnvc_rsvd5[132]; + bits16_t mlnvc_promisc_list_type; + uint16be_t mlnvc_allowed_list_size; + uint8_t mlnvc_rsvd6[2]; + uint8_t mlnvc_permanent_address[6]; + uint8_t mlnvc_rsvd7[4]; + uint64be_t mlnvc_address[MLXCX_NIC_VPORT_CTX_MAX_ADDRESSES]; +} mlxcx_nic_vport_ctx_t; + +typedef struct { + uint8_t mlftc_flags; + uint8_t mlftc_level; + uint8_t mlftc_rsvd; + uint8_t mlftc_log_size; + uint8_t mlftc_rsvd2; + uint24be_t mlftc_table_miss_id; + uint8_t mlftc_rsvd3[4]; + uint8_t mlftc_rsvd4[28]; +} mlxcx_flow_table_ctx_t; + +/* CSTYLED */ +#define MLXCX_FLOW_HDR_FIRST_VID (bitdef_t){0, 0x07ff} +/* CSTYLED */ +#define MLXCX_FLOW_HDR_FIRST_PRIO (bitdef_t){13,0x7000} +#define MLXCX_FLOW_HDR_FIRST_CFI (1 << 12) + +#define MLXCX_FLOW_HDR_IP_DSCP_SHIFT 18 +#define MLXCX_FLOW_HDR_IP_DSCP_MASK 0xfc0000 +#define MLXCX_FLOW_HDR_IP_ECN_SHIFT 16 +#define MLXCX_FLOW_HDR_IP_ECN_MASK 0x030000 +#define MLXCX_FLOW_HDR_CVLAN_TAG (1 << 15) +#define MLXCX_FLOW_HDR_SVLAN_TAG (1 << 14) +#define MLXCX_FLOW_HDR_FRAG (1 << 13) +/* CSTYLED */ +#define MLXCX_FLOW_HDR_IP_VERSION (bitdef_t){ \ + .bit_shift = 9, \ + .bit_mask = 0x001e00 } +/* CSTYLED */ +#define MLXCX_FLOW_HDR_TCP_FLAGS (bitdef_t){ \ + .bit_shift = 0, \ + .bit_mask = 0x0001ff } + +typedef struct { + uint8_t mlfh_smac[6]; + uint16be_t mlfh_ethertype; + uint8_t mlfh_dmac[6]; + bits16_t mlfh_first_vid_flags; + uint8_t mlfh_ip_protocol; + bits24_t mlfh_tcp_ip_flags; + uint16be_t mlfh_tcp_sport; + uint16be_t mlfh_tcp_dport; + uint8_t mlfh_rsvd[3]; + uint8_t mlfh_ip_ttl_hoplimit; + uint16be_t mlfh_udp_sport; + uint16be_t mlfh_udp_dport; + uint8_t mlfh_src_ip[16]; + uint8_t mlfh_dst_ip[16]; +} mlxcx_flow_header_match_t; + +typedef struct { + uint8_t mlfp_rsvd; + uint24be_t mlfp_source_sqn; + uint8_t mlfp_rsvd2[2]; + uint16be_t mlfp_source_port; + bits16_t mlfp_outer_second_vid_flags; + bits16_t mlfp_inner_second_vid_flags; + bits16_t mlfp_vlan_flags; + uint16be_t mlfp_gre_protocol; + uint32be_t mlfp_gre_key; + uint24be_t mlfp_vxlan_vni; + uint8_t mlfp_rsvd3; + uint8_t mlfp_rsvd4[4]; + uint8_t mlfp_rsvd5; + uint24be_t mlfp_outer_ipv6_flow_label; + uint8_t mlfp_rsvd6; + uint24be_t mlfp_inner_ipv6_flow_label; + uint8_t mlfp_rsvd7[28]; +} mlxcx_flow_params_match_t; + +typedef struct { + mlxcx_flow_header_match_t mlfm_outer_headers; + mlxcx_flow_params_match_t mlfm_misc_parameters; + mlxcx_flow_header_match_t mlfm_inner_headers; + uint8_t mlfm_rsvd[320]; +} mlxcx_flow_match_t; + +#define MLXCX_FLOW_MAX_DESTINATIONS 64 +typedef enum { + MLXCX_FLOW_DEST_VPORT = 0x0, + MLXCX_FLOW_DEST_FLOW_TABLE = 0x1, + MLXCX_FLOW_DEST_TIR = 0x2, + MLXCX_FLOW_DEST_QP = 0x3 +} mlxcx_flow_destination_type_t; + +typedef struct { + uint8_t mlfd_destination_type; + uint24be_t mlfd_destination_id; + uint8_t mlfd_rsvd[4]; +} mlxcx_flow_dest_t; + +typedef enum { + MLXCX_FLOW_ACTION_ALLOW = 1 << 0, + MLXCX_FLOW_ACTION_DROP = 1 << 1, + MLXCX_FLOW_ACTION_FORWARD = 1 << 2, + MLXCX_FLOW_ACTION_COUNT = 1 << 3, + MLXCX_FLOW_ACTION_ENCAP = 1 << 4, + MLXCX_FLOW_ACTION_DECAP = 1 << 5 +} mlxcx_flow_action_t; + +typedef struct { + uint8_t mlfec_rsvd[4]; + uint32be_t mlfec_group_id; + uint8_t mlfec_rsvd2; + uint24be_t mlfec_flow_tag; + uint8_t mlfec_rsvd3[2]; + uint16be_t mlfec_action; + uint8_t mlfec_rsvd4; + uint24be_t mlfec_destination_list_size; + uint8_t mlfec_rsvd5; + uint24be_t mlfec_flow_counter_list_size; + uint32be_t mlfec_encap_id; + uint8_t mlfec_rsvd6[36]; + mlxcx_flow_match_t mlfec_match_value; + uint8_t mlfec_rsvd7[192]; + mlxcx_flow_dest_t mlfec_destination[MLXCX_FLOW_MAX_DESTINATIONS]; +} mlxcx_flow_entry_ctx_t; + +/* CSTYLED */ +#define MLXCX_TIR_CTX_DISP_TYPE (bitdef_t){ 4, 0xf0 } +typedef enum { + MLXCX_TIR_DIRECT = 0x0, + MLXCX_TIR_INDIRECT = 0x1, +} mlxcx_tir_type_t; + +/* CSTYLED */ +#define MLXCX_TIR_LRO_TIMEOUT (bitdef_t){ 12, 0x0ffff000 } +/* CSTYLED */ +#define MLXCX_TIR_LRO_ENABLE_MASK (bitdef_t){ 8, 0x00000f00 } +/* CSTYLED */ +#define MLXCX_TIR_LRO_MAX_MSG_SZ (bitdef_t){ 0, 0x000000ff } + +/* CSTYLED */ +#define MLXCX_TIR_RX_HASH_FN (bitdef_t){ 4, 0xf0 } +typedef enum { + MLXCX_TIR_HASH_NONE = 0x0, + MLXCX_TIR_HASH_XOR8 = 0x1, + MLXCX_TIR_HASH_TOEPLITZ = 0x2 +} mlxcx_tir_hash_fn_t; +#define MLXCX_TIR_LB_UNICAST (1 << 24) +#define MLXCX_TIR_LB_MULTICAST (1 << 25) + +/* CSTYLED */ +#define MLXCX_RX_HASH_L3_TYPE (bitdef_t){ 31, 0x80000000 } +typedef enum { + MLXCX_RX_HASH_L3_IPv4 = 0, + MLXCX_RX_HASH_L3_IPv6 = 1 +} mlxcx_tir_rx_hash_l3_type_t; +/* CSTYLED */ +#define MLXCX_RX_HASH_L4_TYPE (bitdef_t){ 30, 0x40000000 } +typedef enum { + MLXCX_RX_HASH_L4_TCP = 0, + MLXCX_RX_HASH_L4_UDP = 1 +} mlxcx_tir_rx_hash_l4_type_t; +/* CSTYLED */ +#define MLXCX_RX_HASH_FIELDS (bitdef_t){ 0, 0x3fffffff } +typedef enum { + MLXCX_RX_HASH_SRC_IP = 1 << 0, + MLXCX_RX_HASH_DST_IP = 1 << 1, + MLXCX_RX_HASH_L4_SPORT = 1 << 2, + MLXCX_RX_HASH_L4_DPORT = 1 << 3, + MLXCX_RX_HASH_IPSEC_SPI = 1 << 4 +} mlxcx_tir_rx_hash_fields_t; + +typedef struct { + uint8_t mltirc_rsvd[4]; + bits8_t mltirc_disp_type; + uint8_t mltirc_rsvd2[11]; + bits32_t mltirc_lro; + uint8_t mltirc_rsvd3[9]; + uint24be_t mltirc_inline_rqn; + bits8_t mltirc_flags; + uint24be_t mltirc_indirect_table; + bits8_t mltirc_hash_lb; + uint24be_t mltirc_transport_domain; + uint8_t mltirc_rx_hash_toeplitz_key[40]; + bits32_t mltirc_rx_hash_fields_outer; + bits32_t mltirc_rx_hash_fields_inner; + uint8_t mltirc_rsvd4[152]; +} mlxcx_tir_ctx_t; + +typedef struct { + uint8_t mltisc_rsvd; + uint8_t mltisc_prio_or_sl; + uint8_t mltisc_rsvd2[35]; + uint24be_t mltisc_transport_domain; + uint8_t mltisc_rsvd3[120]; +} mlxcx_tis_ctx_t; + +#define MLXCX_RQT_MAX_RQ_REFS 64 + +typedef struct { + uint8_t mlrqtr_rsvd; + uint24be_t mlrqtr_rqn; +} mlxcx_rqtable_rq_ref_t; + +typedef struct { + uint8_t mlrqtc_rsvd[22]; + uint16be_t mlrqtc_max_size; + uint8_t mlrqtc_rsvd2[2]; + uint16be_t mlrqtc_actual_size; + uint8_t mlrqtc_rsvd3[212]; + mlxcx_rqtable_rq_ref_t mlrqtc_rqref[MLXCX_RQT_MAX_RQ_REFS]; +} mlxcx_rqtable_ctx_t; + +#pragma pack() + +typedef enum { + MLXCX_EVENT_COMPLETION = 0x00, + MLXCX_EVENT_PATH_MIGRATED = 0x01, + MLXCX_EVENT_COMM_ESTABLISH = 0x02, + MLXCX_EVENT_SENDQ_DRAIN = 0x03, + MLXCX_EVENT_LAST_WQE = 0x13, + MLXCX_EVENT_SRQ_LIMIT = 0x14, + MLXCX_EVENT_DCT_ALL_CLOSED = 0x1C, + MLXCX_EVENT_DCT_ACCKEY_VIOL = 0x1D, + MLXCX_EVENT_CQ_ERROR = 0x04, + MLXCX_EVENT_WQ_CATASTROPHE = 0x05, + MLXCX_EVENT_PATH_MIGRATE_FAIL = 0x07, + MLXCX_EVENT_PAGE_FAULT = 0x0C, + MLXCX_EVENT_WQ_INVALID_REQ = 0x10, + MLXCX_EVENT_WQ_ACCESS_VIOL = 0x11, + MLXCX_EVENT_SRQ_CATASTROPHE = 0x12, + MLXCX_EVENT_INTERNAL_ERROR = 0x08, + MLXCX_EVENT_PORT_STATE = 0x09, + MLXCX_EVENT_GPIO = 0x15, + MLXCX_EVENT_PORT_MODULE = 0x16, + MLXCX_EVENT_TEMP_WARNING = 0x17, + MLXCX_EVENT_REMOTE_CONFIG = 0x19, + MLXCX_EVENT_DCBX_CHANGE = 0x1E, + MLXCX_EVENT_DOORBELL_CONGEST = 0x1A, + MLXCX_EVENT_STALL_VL = 0x1B, + MLXCX_EVENT_CMD_COMPLETION = 0x0A, + MLXCX_EVENT_PAGE_REQUEST = 0x0B, + MLXCX_EVENT_NIC_VPORT = 0x0D, + MLXCX_EVENT_EC_PARAMS_CHANGE = 0x0E, + MLXCX_EVENT_XRQ_ERROR = 0x18 +} mlxcx_event_t; + +typedef enum { + MLXCX_CMD_R_OK = 0x00, + MLXCX_CMD_R_INTERNAL_ERR = 0x01, + MLXCX_CMD_R_BAD_OP = 0x02, + MLXCX_CMD_R_BAD_PARAM = 0x03, + MLXCX_CMD_R_BAD_SYS_STATE = 0x04, + MLXCX_CMD_R_BAD_RESOURCE = 0x05, + MLXCX_CMD_R_RESOURCE_BUSY = 0x06, + MLXCX_CMD_R_EXCEED_LIM = 0x08, + MLXCX_CMD_R_BAD_RES_STATE = 0x09, + MLXCX_CMD_R_BAD_INDEX = 0x0a, + MLXCX_CMD_R_NO_RESOURCES = 0x0f, + MLXCX_CMD_R_BAD_INPUT_LEN = 0x50, + MLXCX_CMD_R_BAD_OUTPUT_LEN = 0x51, + MLXCX_CMD_R_BAD_RESOURCE_STATE = 0x10, + MLXCX_CMD_R_BAD_PKT = 0x30, + MLXCX_CMD_R_BAD_SIZE = 0x40, + MLXCX_CMD_R_TIMEOUT = 0xFF +} mlxcx_cmd_ret_t; + +typedef enum { + MLXCX_OP_QUERY_HCA_CAP = 0x100, + MLXCX_OP_QUERY_ADAPTER = 0x101, + MLXCX_OP_INIT_HCA = 0x102, + MLXCX_OP_TEARDOWN_HCA = 0x103, + MLXCX_OP_ENABLE_HCA = 0x104, + MLXCX_OP_DISABLE_HCA = 0x105, + MLXCX_OP_QUERY_PAGES = 0x107, + MLXCX_OP_MANAGE_PAGES = 0x108, + MLXCX_OP_SET_HCA_CAP = 0x109, + MLXCX_OP_QUERY_ISSI = 0x10A, + MLXCX_OP_SET_ISSI = 0x10B, + MLXCX_OP_SET_DRIVER_VERSION = 0x10D, + MLXCX_OP_QUERY_OTHER_HCA_CAP = 0x10E, + MLXCX_OP_MODIFY_OTHER_HCA_CAP = 0x10F, + MLXCX_OP_SET_TUNNELED_OPERATIONS = 0x110, + MLXCX_OP_CREATE_MKEY = 0x200, + MLXCX_OP_QUERY_MKEY = 0x201, + MLXCX_OP_DESTROY_MKEY = 0x202, + MLXCX_OP_QUERY_SPECIAL_CONTEXTS = 0x203, + MLXCX_OP_PAGE_FAULT_RESUME = 0x204, + MLXCX_OP_CREATE_EQ = 0x301, + MLXCX_OP_DESTROY_EQ = 0x302, + MLXCX_OP_QUERY_EQ = 0x303, + MLXCX_OP_GEN_EQE = 0x304, + MLXCX_OP_CREATE_CQ = 0x400, + MLXCX_OP_DESTROY_CQ = 0x401, + MLXCX_OP_QUERY_CQ = 0x402, + MLXCX_OP_MODIFY_CQ = 0x403, + MLXCX_OP_CREATE_QP = 0x500, + MLXCX_OP_DESTROY_QP = 0x501, + MLXCX_OP_RST2INIT_QP = 0x502, + MLXCX_OP_INIT2RTR_QP = 0x503, + MLXCX_OP_RTR2RTS_QP = 0x504, + MLXCX_OP_RTS2RTS_QP = 0x505, + MLXCX_OP_SQERR2RTS_QP = 0x506, + MLXCX_OP__2ERR_QP = 0x507, + MLXCX_OP__2RST_QP = 0x50A, + MLXCX_OP_QUERY_QP = 0x50B, + MLXCX_OP_SQD_RTS_QP = 0x50C, + MLXCX_OP_INIT2INIT_QP = 0x50E, + MLXCX_OP_CREATE_PSV = 0x600, + MLXCX_OP_DESTROY_PSV = 0x601, + MLXCX_OP_CREATE_SRQ = 0x700, + MLXCX_OP_DESTROY_SRQ = 0x701, + MLXCX_OP_QUERY_SRQ = 0x702, + MLXCX_OP_ARM_RQ = 0x703, + MLXCX_OP_CREATE_XRC_SRQ = 0x705, + MLXCX_OP_DESTROY_XRC_SRQ = 0x706, + MLXCX_OP_QUERY_XRC_SRQ = 0x707, + MLXCX_OP_ARM_XRC_SRQ = 0x708, + MLXCX_OP_CREATE_DCT = 0x710, + MLXCX_OP_DESTROY_DCT = 0x711, + MLXCX_OP_DRAIN_DCT = 0x712, + MLXCX_OP_QUERY_DCT = 0x713, + MLXCX_OP_ARM_DCT_FOR_KEY_VIOLATION = 0x714, + MLXCX_OP_CREATE_XRQ = 0x717, + MLXCX_OP_DESTROY_XRQ = 0x718, + MLXCX_OP_QUERY_XRQ = 0x719, + MLXCX_OP_CREATE_NVMF_BACKEND_CONTROLLER = 0x720, + MLXCX_OP_DESTROY_NVMF_BACKEND_CONTROLLER = 0x721, + MLXCX_OP_QUERY_NVMF_BACKEND_CONTROLLER = 0x722, + MLXCX_OP_ATTACH_NVMF_NAMESPACE = 0x723, + MLXCX_OP_DETACH_NVMF_NAMESPACE = 0x724, + MLXCX_OP_QUERY_XRQ_DC_PARAMS_ENTRY = 0x725, + MLXCX_OP_SET_XRQ_DC_PARAMS_ENTRY = 0x726, + MLXCX_OP_QUERY_XRQ_ERROR_PARAMS = 0x727, + MLXCX_OP_QUERY_VPORT_STATE = 0x750, + MLXCX_OP_MODIFY_VPORT_STATE = 0x751, + MLXCX_OP_QUERY_ESW_VPORT_CONTEXT = 0x752, + MLXCX_OP_MODIFY_ESW_VPORT_CONTEXT = 0x753, + MLXCX_OP_QUERY_NIC_VPORT_CONTEXT = 0x754, + MLXCX_OP_MODIFY_NIC_VPORT_CONTEXT = 0x755, + MLXCX_OP_QUERY_ROCE_ADDRESS = 0x760, + MLXCX_OP_SET_ROCE_ADDRESS = 0x761, + MLXCX_OP_QUERY_HCA_VPORT_CONTEXT = 0x762, + MLXCX_OP_MODIFY_HCA_VPORT_CONTEXT = 0x763, + MLXCX_OP_QUERY_HCA_VPORT_GID = 0x764, + MLXCX_OP_QUERY_HCA_VPORT_PKEY = 0x765, + MLXCX_OP_QUERY_VPORT_COUNTER = 0x770, + MLXCX_OP_ALLOC_Q_COUNTER = 0x771, + MLXCX_OP_DEALLOC_Q_COUNTER = 0x772, + MLXCX_OP_QUERY_Q_COUNTER = 0x773, + MLXCX_OP_SET_PP_RATE_LIMIT = 0x780, + MLXCX_OP_QUERY_PP_RATE_LIMIT = 0x781, + MLXCX_OP_ALLOC_PD = 0x800, + MLXCX_OP_DEALLOC_PD = 0x801, + MLXCX_OP_ALLOC_UAR = 0x802, + MLXCX_OP_DEALLOC_UAR = 0x803, + MLXCX_OP_CONFIG_INT_MODERATION = 0x804, + MLXCX_OP_ACCESS_REG = 0x805, + MLXCX_OP_ATTACH_TO_MCG = 0x806, + MLXCX_OP_DETACH_FROM_MCG = 0x807, + MLXCX_OP_MAD_IFC = 0x50D, + MLXCX_OP_QUERY_MAD_DEMUX = 0x80B, + MLXCX_OP_SET_MAD_DEMUX = 0x80C, + MLXCX_OP_NOP = 0x80D, + MLXCX_OP_ALLOC_XRCD = 0x80E, + MLXCX_OP_DEALLOC_XRCD = 0x80F, + MLXCX_OP_ALLOC_TRANSPORT_DOMAIN = 0x816, + MLXCX_OP_DEALLOC_TRANSPORT_DOMAIN = 0x817, + MLXCX_OP_QUERY_CONG_STATUS = 0x822, + MLXCX_OP_MODIFY_CONG_STATUS = 0x823, + MLXCX_OP_QUERY_CONG_PARAMS = 0x824, + MLXCX_OP_MODIFY_CONG_PARAMS = 0x825, + MLXCX_OP_QUERY_CONG_STATISTICS = 0x826, + MLXCX_OP_ADD_VXLAN_UDP_DPORT = 0x827, + MLXCX_OP_DELETE_VXLAN_UDP_DPORT = 0x828, + MLXCX_OP_SET_L2_TABLE_ENTRY = 0x829, + MLXCX_OP_QUERY_L2_TABLE_ENTRY = 0x82A, + MLXCX_OP_DELETE_L2_TABLE_ENTRY = 0x82B, + MLXCX_OP_SET_WOL_ROL = 0x830, + MLXCX_OP_QUERY_WOL_ROL = 0x831, + MLXCX_OP_CREATE_TIR = 0x900, + MLXCX_OP_MODIFY_TIR = 0x901, + MLXCX_OP_DESTROY_TIR = 0x902, + MLXCX_OP_QUERY_TIR = 0x903, + MLXCX_OP_CREATE_SQ = 0x904, + MLXCX_OP_MODIFY_SQ = 0x905, + MLXCX_OP_DESTROY_SQ = 0x906, + MLXCX_OP_QUERY_SQ = 0x907, + MLXCX_OP_CREATE_RQ = 0x908, + MLXCX_OP_MODIFY_RQ = 0x909, + MLXCX_OP_DESTROY_RQ = 0x90A, + MLXCX_OP_QUERY_RQ = 0x90B, + MLXCX_OP_CREATE_RMP = 0x90C, + MLXCX_OP_MODIFY_RMP = 0x90D, + MLXCX_OP_DESTROY_RMP = 0x90E, + MLXCX_OP_QUERY_RMP = 0x90F, + MLXCX_OP_CREATE_TIS = 0x912, + MLXCX_OP_MODIFY_TIS = 0x913, + MLXCX_OP_DESTROY_TIS = 0x914, + MLXCX_OP_QUERY_TIS = 0x915, + MLXCX_OP_CREATE_RQT = 0x916, + MLXCX_OP_MODIFY_RQT = 0x917, + MLXCX_OP_DESTROY_RQT = 0x918, + MLXCX_OP_QUERY_RQT = 0x919, + MLXCX_OP_SET_FLOW_TABLE_ROOT = 0x92f, + MLXCX_OP_CREATE_FLOW_TABLE = 0x930, + MLXCX_OP_DESTROY_FLOW_TABLE = 0x931, + MLXCX_OP_QUERY_FLOW_TABLE = 0x932, + MLXCX_OP_CREATE_FLOW_GROUP = 0x933, + MLXCX_OP_DESTROY_FLOW_GROUP = 0x934, + MLXCX_OP_QUERY_FLOW_GROUP = 0x935, + MLXCX_OP_SET_FLOW_TABLE_ENTRY = 0x936, + MLXCX_OP_QUERY_FLOW_TABLE_ENTRY = 0x937, + MLXCX_OP_DELETE_FLOW_TABLE_ENTRY = 0x938, + MLXCX_OP_ALLOC_FLOW_COUNTER = 0x939, + MLXCX_OP_DEALLOC_FLOW_COUNTER = 0x93a, + MLXCX_OP_QUERY_FLOW_COUNTER = 0x93b, + MLXCX_OP_MODIFY_FLOW_TABLE = 0x93c, + MLXCX_OP_ALLOC_ENCAP_HEADER = 0x93d, + MLXCX_OP_DEALLOC_ENCAP_HEADER = 0x93e, + MLXCX_OP_QUERY_ENCAP_HEADER = 0x93f +} mlxcx_cmd_op_t; + +/* + * Definitions for relevant commands + */ +#pragma pack(1) +typedef struct { + uint16be_t mci_opcode; + uint8_t mci_rsvd[4]; + uint16be_t mci_op_mod; +} mlxcx_cmd_in_t; + +typedef struct { + uint8_t mco_status; + uint8_t mco_rsvd[3]; + uint32be_t mco_syndrome; +} mlxcx_cmd_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_enable_hca_head; + uint8_t mlxi_enable_hca_rsvd[2]; + uint16be_t mlxi_enable_hca_func; + uint8_t mlxi_enable_hca_rsvd1[4]; +} mlxcx_cmd_enable_hca_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_enable_hca_head; + uint8_t mlxo_enable_hca_rsvd[8]; +} mlxcx_cmd_enable_hca_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_disable_hca_head; + uint8_t mlxi_disable_hca_rsvd[2]; + uint16be_t mlxi_disable_hca_func; + uint8_t mlxi_disable_hca_rsvd1[4]; +} mlxcx_cmd_disable_hca_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_disable_hca_head; + uint8_t mlxo_disable_hca_rsvd[8]; +} mlxcx_cmd_disable_hca_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_issi_head; + uint8_t mlxi_query_issi_rsvd[8]; +} mlxcx_cmd_query_issi_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_issi_head; + uint8_t mlxo_query_issi_rsv[2]; + uint16be_t mlxo_query_issi_current; + uint8_t mlxo_query_issi_rsvd1[20]; + /* + * To date we only support version 1 of the ISSI. The last byte has the + * ISSI data that we care about, therefore we phrase the struct this + * way. + */ + uint8_t mlxo_query_issi_rsvd2[79]; + uint8_t mlxo_supported_issi; +} mlxcx_cmd_query_issi_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_set_issi_head; + uint8_t mlxi_set_issi_rsvd[2]; + uint16be_t mlxi_set_issi_current; + uint8_t mlxi_set_iss_rsvd1[4]; +} mlxcx_cmd_set_issi_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_set_issi_head; + uint8_t mlxo_set_issi_rsvd[8]; +} mlxcx_cmd_set_issi_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_init_hca_head; + uint8_t mlxi_init_hca_rsvd[8]; +} mlxcx_cmd_init_hca_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_init_hca_head; + uint8_t mlxo_init_hca_rsvd[8]; +} mlxcx_cmd_init_hca_out_t; + +#define MLXCX_TEARDOWN_HCA_GRACEFUL 0x00 +#define MLXCX_TEARDOWN_HCA_FORCE 0x01 + +typedef struct { + mlxcx_cmd_in_t mlxi_teardown_hca_head; + uint8_t mlxi_teardown_hca_rsvd[2]; + uint16be_t mlxi_teardown_hca_profile; + uint8_t mlxi_teardown_hca_rsvd1[4]; +} mlxcx_cmd_teardown_hca_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_teardown_hca_head; + uint8_t mlxo_teardown_hca_rsvd[7]; + uint8_t mlxo_teardown_hca_state; +} mlxcx_cmd_teardown_hca_out_t; + +#define MLXCX_QUERY_PAGES_OPMOD_BOOT 0x01 +#define MLXCX_QUERY_PAGES_OPMOD_INIT 0x02 +#define MLXCX_QUERY_PAGES_OPMOD_REGULAR 0x03 + +typedef struct { + mlxcx_cmd_in_t mlxi_query_pages_head; + uint8_t mlxi_query_pages_rsvd[2]; + uint16be_t mlxi_query_pages_func; + uint8_t mlxi_query_pages_rsvd1[4]; +} mlxcx_cmd_query_pages_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_pages_head; + uint8_t mlxo_query_pages_rsvd[2]; + uint16be_t mlxo_query_pages_func; + uint32be_t mlxo_query_pages_npages; +} mlxcx_cmd_query_pages_out_t; + +#define MLXCX_MANAGE_PAGES_OPMOD_ALLOC_FAIL 0x00 +#define MLXCX_MANAGE_PAGES_OPMOD_GIVE_PAGES 0x01 +#define MLXCX_MANAGE_PAGES_OPMOD_RETURN_PAGES 0x02 + +/* + * This is an artificial limit that we're imposing on our actions. + */ +#define MLXCX_MANAGE_PAGES_MAX_PAGES 512 + +typedef struct { + mlxcx_cmd_in_t mlxi_manage_pages_head; + uint8_t mlxi_manage_pages_rsvd[2]; + uint16be_t mlxi_manage_pages_func; + uint32be_t mlxi_manage_pages_npages; + uint64be_t mlxi_manage_pages_pas[MLXCX_MANAGE_PAGES_MAX_PAGES]; +} mlxcx_cmd_manage_pages_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_manage_pages_head; + uint32be_t mlxo_manage_pages_npages; + uint8_t mlxo_manage_pages_rsvd[4]; + uint64be_t mlxo_manage_pages_pas[MLXCX_MANAGE_PAGES_MAX_PAGES]; +} mlxcx_cmd_manage_pages_out_t; + +typedef enum { + MLXCX_HCA_CAP_MODE_MAX = 0x0, + MLXCX_HCA_CAP_MODE_CURRENT = 0x1 +} mlxcx_hca_cap_mode_t; + +typedef enum { + MLXCX_HCA_CAP_GENERAL = 0x0, + MLXCX_HCA_CAP_ETHERNET = 0x1, + MLXCX_HCA_CAP_ODP = 0x2, + MLXCX_HCA_CAP_ATOMIC = 0x3, + MLXCX_HCA_CAP_ROCE = 0x4, + MLXCX_HCA_CAP_IPoIB = 0x5, + MLXCX_HCA_CAP_NIC_FLOW = 0x7, + MLXCX_HCA_CAP_ESWITCH_FLOW = 0x8, + MLXCX_HCA_CAP_ESWITCH = 0x9, + MLXCX_HCA_CAP_VECTOR = 0xb, + MLXCX_HCA_CAP_QoS = 0xc, + MLXCX_HCA_CAP_NVMEoF = 0xe +} mlxcx_hca_cap_type_t; + +typedef enum { + MLXCX_CAP_GENERAL_PORT_TYPE_IB = 0x0, + MLXCX_CAP_GENERAL_PORT_TYPE_ETHERNET = 0x1, +} mlxcx_hca_cap_general_port_type_t; + +typedef enum { + MLXCX_CAP_GENERAL_FLAGS_C_ESW_FLOW_TABLE = (1 << 8), + MLXCX_CAP_GENERAL_FLAGS_C_NIC_FLOW_TABLE = (1 << 9), +} mlxcx_hca_cap_general_flags_c_t; + +typedef struct { + uint8_t mlcap_general_access_other_hca_roce; + uint8_t mlcap_general_rsvd[3]; + + uint8_t mlcap_general_rsvd2[12]; + + uint8_t mlcap_general_log_max_srq_sz; + uint8_t mlcap_general_log_max_qp_sz; + uint8_t mlcap_general_rsvd3[1]; + uint8_t mlcap_general_log_max_qp; + + uint8_t mlcap_general_rsvd4[1]; + uint8_t mlcap_general_log_max_srq; + uint8_t mlcap_general_rsvd5[2]; + + uint8_t mlcap_general_rsvd6[1]; + uint8_t mlcap_general_log_max_cq_sz; + uint8_t mlcap_general_rsvd7[1]; + uint8_t mlcap_general_log_max_cq; + + uint8_t mlcap_general_log_max_eq_sz; + uint8_t mlcap_general_log_max_mkey_flags; + uint8_t mlcap_general_rsvd8[1]; + uint8_t mlcap_general_log_max_eq; + + uint8_t mlcap_general_max_indirection; + uint8_t mlcap_general_log_max_mrw_sz_flags; + uint8_t mlcap_general_log_max_bsf_list_size_flags; + uint8_t mlcap_general_log_max_klm_list_size_flags; + + uint8_t mlcap_general_rsvd9[1]; + uint8_t mlcap_general_log_max_ra_req_dc; + uint8_t mlcap_general_rsvd10[1]; + uint8_t mlcap_general_log_max_ra_res_dc; + + uint8_t mlcap_general_rsvd11[1]; + uint8_t mlcap_general_log_max_ra_req_qp; + uint8_t mlcap_general_rsvd12[1]; + uint8_t mlcap_general_log_max_ra_res_qp; + + uint16be_t mlcap_general_flags_a; + uint16be_t mlcap_general_gid_table_size; + + bits16_t mlcap_general_flags_b; + uint16be_t mlcap_general_pkey_table_size; + + bits16_t mlcap_general_flags_c; + struct { +#if defined(_BIT_FIELDS_HTOL) + uint8_t mlcap_general_flags_d:6; + uint8_t mlcap_general_port_type:2; +#elif defined(_BIT_FIELDS_LTOH) + uint8_t mlcap_general_port_type:2; + uint8_t mlcap_general_flags_d:6; +#endif + }; + uint8_t mlcap_general_num_ports; + + struct { +#if defined(_BIT_FIELDS_HTOL) + uint8_t mlcap_general_rsvd13:3; + uint8_t mlcap_general_log_max_msg:5; +#elif defined(_BIT_FIELDS_LTOH) + uint8_t mlcap_general_log_max_msg:5; + uint8_t mlcap_general_rsvd13:3; +#endif + }; + uint8_t mlcap_general_max_tc; + bits16_t mlcap_general_flags_d_wol; + + uint16be_t mlcap_general_state_rate_support; + uint8_t mlcap_general_rsvd14[1]; + struct { +#if defined(_BIT_FIELDS_HTOL) + uint8_t mlcap_general_rsvd15:4; + uint8_t mlcap_general_cqe_version:4; +#elif defined(_BIT_FIELDS_LTOH) + uint8_t mlcap_general_cqe_version:4; + uint8_t mlcap_general_rsvd15:4; +#endif + }; + + uint32be_t mlcap_general_flags_e; + + uint32be_t mlcap_general_flags_f; + + uint8_t mlcap_general_rsvd16[1]; + uint8_t mlcap_general_uar_sz; + uint8_t mlcap_general_cnak; + uint8_t mlcap_general_log_pg_sz; + uint8_t mlcap_general_rsvd17[32]; + bits8_t mlcap_general_log_max_rq_flags; + uint8_t mlcap_general_log_max_sq; + uint8_t mlcap_general_log_max_tir; + uint8_t mlcap_general_log_max_tis; +} mlxcx_hca_cap_general_caps_t; + +typedef enum { + MLXCX_ETH_CAP_TUNNEL_STATELESS_VXLAN = 1 << 0, + MLXCX_ETH_CAP_TUNNEL_STATELESS_GRE = 1 << 1, + MLXCX_ETH_CAP_TUNNEL_LSO_CONST_OUT_IP_ID = 1 << 4, + MLXCX_ETH_CAP_SCATTER_FCS = 1 << 6, + MLXCX_ETH_CAP_REG_UMR_SQ = 1 << 7, + MLXCX_ETH_CAP_SELF_LB_UC = 1 << 21, + MLXCX_ETH_CAP_SELF_LB_MC = 1 << 22, + MLXCX_ETH_CAP_SELF_LB_EN_MODIFIABLE = 1 << 23, + MLXCX_ETH_CAP_WQE_VLAN_INSERT = 1 << 24, + MLXCX_ETH_CAP_LRO_TIME_STAMP = 1 << 27, + MLXCX_ETH_CAP_LRO_PSH_FLAG = 1 << 28, + MLXCX_ETH_CAP_LRO_CAP = 1 << 29, + MLXCX_ETH_CAP_VLAN_STRIP = 1 << 30, + MLXCX_ETH_CAP_CSUM_CAP = 1UL << 31 +} mlxcx_hca_eth_cap_flags_t; + +/* CSTYLED */ +#define MLXCX_ETH_CAP_RSS_IND_TBL_CAP (bitdef_t){8, 0x00000f00} +/* CSTYLED */ +#define MLXCX_ETH_CAP_WQE_INLINE_MODE (bitdef_t){12, 0x00003000} +/* CSTYLED */ +#define MLXCX_ETH_CAP_MULTI_PKT_SEND_WQE (bitdef_t){14, 0x0000c000} +/* CSTYLED */ +#define MLXCX_ETH_CAP_MAX_LSO_CAP (bitdef_t){16, 0x001f0000} +/* CSTYLED */ +#define MLXCX_ETH_CAP_LRO_MAX_MSG_SZ_MODE (bitdef_t){25, 0x06000000} + +typedef struct { + bits32_t mlcap_eth_flags; + uint8_t mlcap_eth_rsvd[6]; + uint16be_t mlcap_eth_lro_min_mss_size; + uint8_t mlcap_eth_rsvd2[36]; + uint32be_t mlcap_eth_lro_timer_supported_periods[4]; +} mlxcx_hca_cap_eth_caps_t; + +typedef enum { + MLXCX_FLOW_CAP_PROPS_DECAP = 1 << 23, + MLXCX_FLOW_CAP_PROPS_ENCAP = 1 << 24, + MLXCX_FLOW_CAP_PROPS_MODIFY_TBL = 1 << 25, + MLXCX_FLOW_CAP_PROPS_MISS_TABLE = 1 << 26, + MLXCX_FLOW_CAP_PROPS_MODIFY_ROOT_TBL = 1 << 27, + MLXCX_FLOW_CAP_PROPS_MODIFY = 1 << 28, + MLXCX_FLOW_CAP_PROPS_COUNTER = 1 << 29, + MLXCX_FLOW_CAP_PROPS_TAG = 1 << 30, + MLXCX_FLOW_CAP_PROPS_SUPPORT = 1UL << 31 +} mlxcx_hca_cap_flow_cap_props_flags_t; + +typedef struct { + bits32_t mlcap_flow_prop_flags; + uint8_t mlcap_flow_prop_log_max_ft_size; + uint8_t mlcap_flow_prop_rsvd[2]; + uint8_t mlcap_flow_prop_max_ft_level; + uint8_t mlcap_flow_prop_rsvd2[7]; + uint8_t mlcap_flow_prop_log_max_ft_num; + uint8_t mlcap_flow_prop_rsvd3[2]; + uint8_t mlcap_flow_prop_log_max_flow_counter; + uint8_t mlcap_flow_prop_log_max_destination; + uint8_t mlcap_flow_prop_rsvd4[3]; + uint8_t mlcap_flow_prop_log_max_flow; + uint8_t mlcap_flow_prop_rsvd5[8]; + bits32_t mlcap_flow_prop_support[4]; + bits32_t mlcap_flow_prop_bitmask[4]; +} mlxcx_hca_cap_flow_cap_props_t; + +typedef struct { + bits32_t mlcap_flow_flags; + uint8_t mlcap_flow_rsvd[60]; + mlxcx_hca_cap_flow_cap_props_t mlcap_flow_nic_rx; + mlxcx_hca_cap_flow_cap_props_t mlcap_flow_nic_rx_rdma; + mlxcx_hca_cap_flow_cap_props_t mlcap_flow_nic_rx_sniffer; + mlxcx_hca_cap_flow_cap_props_t mlcap_flow_nic_tx; + mlxcx_hca_cap_flow_cap_props_t mlcap_flow_nic_tx_rdma; + mlxcx_hca_cap_flow_cap_props_t mlcap_flow_nic_tx_sniffer; +} mlxcx_hca_cap_flow_caps_t; + +/* + * Size of a buffer that is required to hold the output data. + */ +#define MLXCX_HCA_CAP_SIZE 0x1000 + +typedef struct { + mlxcx_cmd_in_t mlxi_query_hca_cap_head; + uint8_t mlxi_query_hca_cap_rsvd[8]; +} mlxcx_cmd_query_hca_cap_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_hca_cap_head; + uint8_t mlxo_query_hca_cap_rsvd[8]; + uint8_t mlxo_query_hca_cap_data[MLXCX_HCA_CAP_SIZE]; +} mlxcx_cmd_query_hca_cap_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_set_driver_version_head; + uint8_t mlxi_set_driver_version_rsvd[8]; + char mlxi_set_driver_version_version[64]; +} mlxcx_cmd_set_driver_version_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_set_driver_version_head; + uint8_t mlxo_set_driver_version_rsvd[8]; +} mlxcx_cmd_set_driver_version_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_alloc_uar_head; + uint8_t mlxi_alloc_uar_rsvd[8]; +} mlxcx_cmd_alloc_uar_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_alloc_uar_head; + uint8_t mlxo_alloc_uar_rsvd; + uint24be_t mlxo_alloc_uar_uar; + uint8_t mlxo_alloc_uar_rsvd2[4]; +} mlxcx_cmd_alloc_uar_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_dealloc_uar_head; + uint8_t mlxi_dealloc_uar_rsvd; + uint24be_t mlxi_dealloc_uar_uar; + uint8_t mlxi_dealloc_uar_rsvd2[4]; +} mlxcx_cmd_dealloc_uar_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_dealloc_uar_head; + uint8_t mlxo_dealloc_uar_rsvd[8]; +} mlxcx_cmd_dealloc_uar_out_t; + +/* + * This is an artificial limit that we're imposing on our actions. + */ +#define MLXCX_CREATE_QUEUE_MAX_PAGES 128 + +typedef struct { + mlxcx_cmd_in_t mlxi_create_eq_head; + uint8_t mlxi_create_eq_rsvd[8]; + mlxcx_eventq_ctx_t mlxi_create_eq_context; + uint8_t mlxi_create_eq_rsvd2[8]; + uint64be_t mlxi_create_eq_event_bitmask; + uint8_t mlxi_create_eq_rsvd3[176]; + uint64be_t mlxi_create_eq_pas[MLXCX_CREATE_QUEUE_MAX_PAGES]; +} mlxcx_cmd_create_eq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_eq_head; + uint8_t mlxo_create_eq_rsvd[3]; + uint8_t mlxo_create_eq_eqn; + uint8_t mlxo_create_eq_rsvd2[4]; +} mlxcx_cmd_create_eq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_eq_head; + uint8_t mlxi_query_eq_rsvd[3]; + uint8_t mlxi_query_eq_eqn; + uint8_t mlxi_query_eq_rsvd2[4]; +} mlxcx_cmd_query_eq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_eq_head; + uint8_t mlxo_query_eq_rsvd[8]; + mlxcx_eventq_ctx_t mlxo_query_eq_context; + uint8_t mlxi_query_eq_rsvd2[8]; + uint64be_t mlxi_query_eq_event_bitmask; + uint8_t mlxi_query_eq_rsvd3[176]; + uint64be_t mlxi_create_eq_pas[MLXCX_CREATE_QUEUE_MAX_PAGES]; +} mlxcx_cmd_query_eq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_eq_head; + uint8_t mlxi_destroy_eq_rsvd[3]; + uint8_t mlxi_destroy_eq_eqn; + uint8_t mlxi_destroy_eq_rsvd2[4]; +} mlxcx_cmd_destroy_eq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_eq_head; + uint8_t mlxo_destroy_eq_rsvd[8]; +} mlxcx_cmd_destroy_eq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_alloc_pd_head; + uint8_t mlxi_alloc_pd_rsvd[8]; +} mlxcx_cmd_alloc_pd_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_alloc_pd_head; + uint8_t mlxo_alloc_pd_rsvd; + uint24be_t mlxo_alloc_pd_pdn; + uint8_t mlxo_alloc_pd_rsvd2[4]; +} mlxcx_cmd_alloc_pd_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_dealloc_pd_head; + uint8_t mlxi_dealloc_pd_rsvd; + uint24be_t mlxi_dealloc_pd_pdn; + uint8_t mlxi_dealloc_pd_rsvd2[4]; +} mlxcx_cmd_dealloc_pd_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_dealloc_pd_head; + uint8_t mlxo_dealloc_pd_rsvd[8]; +} mlxcx_cmd_dealloc_pd_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_alloc_tdom_head; + uint8_t mlxi_alloc_tdom_rsvd[8]; +} mlxcx_cmd_alloc_tdom_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_alloc_tdom_head; + uint8_t mlxo_alloc_tdom_rsvd; + uint24be_t mlxo_alloc_tdom_tdomn; + uint8_t mlxo_alloc_tdom_rsvd2[4]; +} mlxcx_cmd_alloc_tdom_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_dealloc_tdom_head; + uint8_t mlxi_dealloc_tdom_rsvd; + uint24be_t mlxi_dealloc_tdom_tdomn; + uint8_t mlxi_dealloc_tdom_rsvd2[4]; +} mlxcx_cmd_dealloc_tdom_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_dealloc_tdom_head; + uint8_t mlxo_dealloc_tdom_rsvd[8]; +} mlxcx_cmd_dealloc_tdom_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_tir_head; + uint8_t mlxi_create_tir_rsvd[24]; + mlxcx_tir_ctx_t mlxi_create_tir_context; +} mlxcx_cmd_create_tir_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_tir_head; + uint8_t mlxo_create_tir_rsvd; + uint24be_t mlxo_create_tir_tirn; + uint8_t mlxo_create_tir_rsvd2[4]; +} mlxcx_cmd_create_tir_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_tir_head; + uint8_t mlxi_destroy_tir_rsvd; + uint24be_t mlxi_destroy_tir_tirn; + uint8_t mlxi_destroy_tir_rsvd2[4]; +} mlxcx_cmd_destroy_tir_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_tir_head; + uint8_t mlxo_destroy_tir_rsvd[8]; +} mlxcx_cmd_destroy_tir_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_tis_head; + uint8_t mlxi_create_tis_rsvd[24]; + mlxcx_tis_ctx_t mlxi_create_tis_context; +} mlxcx_cmd_create_tis_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_tis_head; + uint8_t mlxo_create_tis_rsvd; + uint24be_t mlxo_create_tis_tisn; + uint8_t mlxo_create_tis_rsvd2[4]; +} mlxcx_cmd_create_tis_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_tis_head; + uint8_t mlxi_destroy_tis_rsvd; + uint24be_t mlxi_destroy_tis_tisn; + uint8_t mlxi_destroy_tis_rsvd2[4]; +} mlxcx_cmd_destroy_tis_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_tis_head; + uint8_t mlxo_destroy_tis_rsvd[8]; +} mlxcx_cmd_destroy_tis_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_special_ctxs_head; + uint8_t mlxi_query_special_ctxs_rsvd[8]; +} mlxcx_cmd_query_special_ctxs_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_special_ctxs_head; + uint8_t mlxo_query_special_ctxs_rsvd[4]; + uint32be_t mlxo_query_special_ctxs_resd_lkey; + uint32be_t mlxo_query_special_ctxs_null_mkey; + uint8_t mlxo_query_special_ctxs_rsvd2[12]; +} mlxcx_cmd_query_special_ctxs_out_t; + +typedef enum { + MLXCX_VPORT_TYPE_VNIC = 0x0, + MLXCX_VPORT_TYPE_ESWITCH = 0x1, + MLXCX_VPORT_TYPE_UPLINK = 0x2, +} mlxcx_cmd_vport_op_mod_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_nic_vport_ctx_head; + uint8_t mlxi_query_nic_vport_ctx_other_vport; + uint8_t mlxi_query_nic_vport_ctx_rsvd[1]; + uint16be_t mlxi_query_nic_vport_ctx_vport_number; + uint8_t mlxi_query_nic_vport_ctx_allowed_list_type; + uint8_t mlxi_query_nic_vport_ctx_rsvd2[3]; +} mlxcx_cmd_query_nic_vport_ctx_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_nic_vport_ctx_head; + uint8_t mlxo_query_nic_vport_ctx_rsvd[8]; + mlxcx_nic_vport_ctx_t mlxo_query_nic_vport_ctx_context; +} mlxcx_cmd_query_nic_vport_ctx_out_t; + +typedef enum { + MLXCX_MODIFY_NIC_VPORT_CTX_ROCE_EN = 1 << 1, + MLXCX_MODIFY_NIC_VPORT_CTX_ADDR_LIST = 1 << 2, + MLXCX_MODIFY_NIC_VPORT_CTX_PERM_ADDR = 1 << 3, + MLXCX_MODIFY_NIC_VPORT_CTX_PROMISC = 1 << 4, + MLXCX_MODIFY_NIC_VPORT_CTX_EVENT = 1 << 5, + MLXCX_MODIFY_NIC_VPORT_CTX_MTU = 1 << 6, + MLXCX_MODIFY_NIC_VPORT_CTX_WQE_INLINE = 1 << 7, + MLXCX_MODIFY_NIC_VPORT_CTX_PORT_GUID = 1 << 8, + MLXCX_MODIFY_NIC_VPORT_CTX_NODE_GUID = 1 << 9, +} mlxcx_modify_nic_vport_ctx_fields_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_modify_nic_vport_ctx_head; + uint8_t mlxi_modify_nic_vport_ctx_other_vport; + uint8_t mlxi_modify_nic_vport_ctx_rsvd[1]; + uint16be_t mlxi_modify_nic_vport_ctx_vport_number; + uint32be_t mlxi_modify_nic_vport_ctx_field_select; + uint8_t mlxi_modify_nic_vport_ctx_rsvd2[240]; + mlxcx_nic_vport_ctx_t mlxi_modify_nic_vport_ctx_context; +} mlxcx_cmd_modify_nic_vport_ctx_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_modify_nic_vport_ctx_head; + uint8_t mlxo_modify_nic_vport_ctx_rsvd[8]; +} mlxcx_cmd_modify_nic_vport_ctx_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_vport_state_head; + uint8_t mlxi_query_vport_state_other_vport; + uint8_t mlxi_query_vport_state_rsvd[1]; + uint16be_t mlxi_query_vport_state_vport_number; + uint8_t mlxi_query_vport_state_rsvd2[4]; +} mlxcx_cmd_query_vport_state_in_t; + +/* CSTYLED */ +#define MLXCX_VPORT_ADMIN_STATE (bitdef_t){4, 0xF0} +/* CSTYLED */ +#define MLXCX_VPORT_OPER_STATE (bitdef_t){0, 0x0F} + +typedef enum { + MLXCX_VPORT_OPER_STATE_DOWN = 0x0, + MLXCX_VPORT_OPER_STATE_UP = 0x1, +} mlxcx_vport_oper_state_t; + +typedef enum { + MLXCX_VPORT_ADMIN_STATE_DOWN = 0x0, + MLXCX_VPORT_ADMIN_STATE_UP = 0x1, + MLXCX_VPORT_ADMIN_STATE_FOLLOW = 0x2, +} mlxcx_vport_admin_state_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_vport_state_head; + uint8_t mlxo_query_vport_state_rsvd[4]; + uint16be_t mlxo_query_vport_state_max_tx_speed; + uint8_t mlxo_query_vport_state_rsvd2[1]; + uint8_t mlxo_query_vport_state_state; +} mlxcx_cmd_query_vport_state_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_cq_head; + uint8_t mlxi_create_cq_rsvd[8]; + mlxcx_completionq_ctx_t mlxi_create_cq_context; + uint8_t mlxi_create_cq_rsvd2[192]; + uint64be_t mlxi_create_cq_pas[MLXCX_CREATE_QUEUE_MAX_PAGES]; +} mlxcx_cmd_create_cq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_cq_head; + uint8_t mlxo_create_cq_rsvd; + uint24be_t mlxo_create_cq_cqn; + uint8_t mlxo_create_cq_rsvd2[4]; +} mlxcx_cmd_create_cq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_cq_head; + uint8_t mlxi_destroy_cq_rsvd; + uint24be_t mlxi_destroy_cq_cqn; + uint8_t mlxi_destroy_cq_rsvd2[4]; +} mlxcx_cmd_destroy_cq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_cq_head; + uint8_t mlxo_destroy_cq_rsvd[8]; +} mlxcx_cmd_destroy_cq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_cq_head; + uint8_t mlxi_query_cq_rsvd; + uint24be_t mlxi_query_cq_cqn; + uint8_t mlxi_query_cq_rsvd2[4]; +} mlxcx_cmd_query_cq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_cq_head; + uint8_t mlxo_query_cq_rsvd[8]; + mlxcx_completionq_ctx_t mlxo_query_cq_context; + uint8_t mlxo_query_cq_rsvd2[192]; + uint64be_t mlxo_query_cq_pas[MLXCX_CREATE_QUEUE_MAX_PAGES]; +} mlxcx_cmd_query_cq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_rq_head; + uint8_t mlxi_create_rq_rsvd[24]; + mlxcx_rq_ctx_t mlxi_create_rq_context; +} mlxcx_cmd_create_rq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_rq_head; + uint8_t mlxo_create_rq_rsvd; + uint24be_t mlxo_create_rq_rqn; + uint8_t mlxo_create_rq_rsvd2[4]; +} mlxcx_cmd_create_rq_out_t; + +/* CSTYLED */ +#define MLXCX_CMD_MODIFY_RQ_STATE (bitdef_t){ \ + .bit_shift = 4, .bit_mask = 0xF0 } + +typedef enum { + MLXCX_MODIFY_RQ_SCATTER_FCS = 1 << 2, + MLXCX_MODIFY_RQ_VSD = 1 << 1, + MLXCX_MODIFY_RQ_COUNTER_SET_ID = 1 << 3, + MLXCX_MODIFY_RQ_LWM = 1 << 0 +} mlxcx_cmd_modify_rq_bitmask_t; + +typedef enum { + MLXCX_RQ_STATE_RST = 0x0, + MLXCX_RQ_STATE_RDY = 0x1, + MLXCX_RQ_STATE_ERR = 0x3 +} mlxcx_rq_state_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_modify_rq_head; + bits8_t mlxi_modify_rq_state; + uint24be_t mlxi_modify_rq_rqn; + uint8_t mlxi_modify_rq_rsvd[4]; + uint64be_t mlxi_modify_rq_bitmask; + uint8_t mlxi_modify_rq_rsvd2[8]; + mlxcx_rq_ctx_t mlxi_modify_rq_context; +} mlxcx_cmd_modify_rq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_modify_rq_head; + uint8_t mlxo_modify_rq_rsvd[8]; +} mlxcx_cmd_modify_rq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_rq_head; + uint8_t mlxi_query_rq_rsvd; + uint24be_t mlxi_query_rq_rqn; + uint8_t mlxi_query_rq_rsvd2[4]; +} mlxcx_cmd_query_rq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_rq_head; + uint8_t mlxo_query_rq_rsvd[24]; + mlxcx_rq_ctx_t mlxo_query_rq_context; +} mlxcx_cmd_query_rq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_rq_head; + uint8_t mlxi_destroy_rq_rsvd; + uint24be_t mlxi_destroy_rq_rqn; + uint8_t mlxi_destroy_rq_rsvd2[4]; +} mlxcx_cmd_destroy_rq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_rq_head; + uint8_t mlxo_destroy_rq_rsvd[8]; +} mlxcx_cmd_destroy_rq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_sq_head; + uint8_t mlxi_create_sq_rsvd[24]; + mlxcx_sq_ctx_t mlxi_create_sq_context; +} mlxcx_cmd_create_sq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_sq_head; + uint8_t mlxo_create_sq_rsvd; + uint24be_t mlxo_create_sq_sqn; + uint8_t mlxo_create_sq_rsvd2[4]; +} mlxcx_cmd_create_sq_out_t; + +/* CSTYLED */ +#define MLXCX_CMD_MODIFY_SQ_STATE (bitdef_t){ \ + .bit_shift = 4, .bit_mask = 0xF0 } + +typedef enum { + MLXCX_MODIFY_SQ_PACKET_PACING_INDEX = 1 << 0, +} mlxcx_cmd_modify_sq_bitmask_t; + +typedef enum { + MLXCX_SQ_STATE_RST = 0x0, + MLXCX_SQ_STATE_RDY = 0x1, + MLXCX_SQ_STATE_ERR = 0x3 +} mlxcx_sq_state_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_modify_sq_head; + bits8_t mlxi_modify_sq_state; + uint24be_t mlxi_modify_sq_sqn; + uint8_t mlxi_modify_sq_rsvd[4]; + uint64be_t mlxi_modify_sq_bitmask; + uint8_t mlxi_modify_sq_rsvd2[8]; + mlxcx_sq_ctx_t mlxi_modify_sq_context; +} mlxcx_cmd_modify_sq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_modify_sq_head; + uint8_t mlxo_modify_sq_rsvd[8]; +} mlxcx_cmd_modify_sq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_query_sq_head; + uint8_t mlxi_query_sq_rsvd; + uint24be_t mlxi_query_sq_sqn; + uint8_t mlxi_query_sq_rsvd2[4]; +} mlxcx_cmd_query_sq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_query_sq_head; + uint8_t mlxo_query_sq_rsvd[24]; + mlxcx_sq_ctx_t mlxo_query_sq_context; +} mlxcx_cmd_query_sq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_sq_head; + uint8_t mlxi_destroy_sq_rsvd; + uint24be_t mlxi_destroy_sq_sqn; + uint8_t mlxi_destroy_sq_rsvd2[4]; +} mlxcx_cmd_destroy_sq_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_sq_head; + uint8_t mlxo_destroy_sq_rsvd[8]; +} mlxcx_cmd_destroy_sq_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_rqt_head; + uint8_t mlxi_create_rqt_rsvd[24]; + mlxcx_rqtable_ctx_t mlxi_create_rqt_context; +} mlxcx_cmd_create_rqt_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_rqt_head; + uint8_t mlxo_create_rqt_rsvd; + uint24be_t mlxo_create_rqt_rqtn; + uint8_t mlxo_create_rqt_rsvd2[4]; +} mlxcx_cmd_create_rqt_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_rqt_head; + uint8_t mlxi_destroy_rqt_rsvd; + uint24be_t mlxi_destroy_rqt_rqtn; + uint8_t mlxi_destroy_rqt_rsvd2[4]; +} mlxcx_cmd_destroy_rqt_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_rqt_head; + uint8_t mlxo_destroy_rqt_rsvd[8]; +} mlxcx_cmd_destroy_rqt_out_t; + +typedef enum { + MLXCX_FLOW_TABLE_NIC_RX = 0x0, + MLXCX_FLOW_TABLE_NIC_TX = 0x1, + MLXCX_FLOW_TABLE_ESW_OUT = 0x2, + MLXCX_FLOW_TABLE_ESW_IN = 0x3, + MLXCX_FLOW_TABLE_ESW_FDB = 0x4, + MLXCX_FLOW_TABLE_NIC_RX_SNIFF = 0x5, + MLXCX_FLOW_TABLE_NIC_TX_SNIFF = 0x6, + MLXCX_FLOW_TABLE_NIC_RX_RDMA = 0x7, + MLXCX_FLOW_TABLE_NIC_TX_RDMA = 0x8 +} mlxcx_flow_table_type_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_flow_table_head; + uint8_t mlxi_create_flow_table_other_vport; + uint8_t mlxi_create_flow_table_rsvd; + uint16be_t mlxi_create_flow_table_vport_number; + uint8_t mlxi_create_flow_table_rsvd2[4]; + uint8_t mlxi_create_flow_table_table_type; + uint8_t mlxi_create_flow_table_rsvd3[7]; + mlxcx_flow_table_ctx_t mlxi_create_flow_table_context; +} mlxcx_cmd_create_flow_table_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_flow_table_head; + uint8_t mlxo_create_flow_table_rsvd; + uint24be_t mlxo_create_flow_table_table_id; + uint8_t mlxo_create_flow_table_rsvd2[4]; +} mlxcx_cmd_create_flow_table_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_flow_table_head; + uint8_t mlxi_destroy_flow_table_other_vport; + uint8_t mlxi_destroy_flow_table_rsvd; + uint16be_t mlxi_destroy_flow_table_vport_number; + uint8_t mlxi_destroy_flow_table_rsvd2[4]; + uint8_t mlxi_destroy_flow_table_table_type; + uint8_t mlxi_destroy_flow_table_rsvd3[4]; + uint24be_t mlxi_destroy_flow_table_table_id; + uint8_t mlxi_destroy_flow_table_rsvd4[4]; +} mlxcx_cmd_destroy_flow_table_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_flow_table_head; + uint8_t mlxo_destroy_flow_table_rsvd[8]; +} mlxcx_cmd_destroy_flow_table_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_set_flow_table_root_head; + uint8_t mlxi_set_flow_table_root_other_vport; + uint8_t mlxi_set_flow_table_root_rsvd; + uint16be_t mlxi_set_flow_table_root_vport_number; + uint8_t mlxi_set_flow_table_root_rsvd2[4]; + uint8_t mlxi_set_flow_table_root_table_type; + uint8_t mlxi_set_flow_table_root_rsvd3[4]; + uint24be_t mlxi_set_flow_table_root_table_id; + uint8_t mlxi_set_flow_table_root_rsvd4[4]; +} mlxcx_cmd_set_flow_table_root_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_set_flow_table_root_head; + uint8_t mlxo_set_flow_table_root_rsvd[8]; +} mlxcx_cmd_set_flow_table_root_out_t; + +typedef enum { + MLXCX_FLOW_GROUP_MATCH_OUTER_HDRS = 1 << 0, + MLXCX_FLOW_GROUP_MATCH_MISC_PARAMS = 1 << 1, + MLXCX_FLOW_GROUP_MATCH_INNER_HDRS = 1 << 2, +} mlxcx_flow_group_match_criteria_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_create_flow_group_head; + uint8_t mlxi_create_flow_group_other_vport; + uint8_t mlxi_create_flow_group_rsvd; + uint16be_t mlxi_create_flow_group_vport_number; + uint8_t mlxi_create_flow_group_rsvd2[4]; + uint8_t mlxi_create_flow_group_table_type; + uint8_t mlxi_create_flow_group_rsvd3[4]; + uint24be_t mlxi_create_flow_group_table_id; + uint8_t mlxi_create_flow_group_rsvd4[4]; + uint32be_t mlxi_create_flow_group_start_flow_index; + uint8_t mlxi_create_flow_group_rsvd5[4]; + uint32be_t mlxi_create_flow_group_end_flow_index; + uint8_t mlxi_create_flow_group_rsvd6[23]; + uint8_t mlxi_create_flow_group_match_criteria_en; + mlxcx_flow_match_t mlxi_create_flow_group_match_criteria; + uint8_t mlxi_create_flow_group_rsvd7[448]; +} mlxcx_cmd_create_flow_group_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_create_flow_group_head; + uint8_t mlxo_create_flow_group_rsvd; + uint24be_t mlxo_create_flow_group_group_id; + uint8_t mlxo_create_flow_group_rsvd2[4]; +} mlxcx_cmd_create_flow_group_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_destroy_flow_group_head; + uint8_t mlxi_destroy_flow_group_other_vport; + uint8_t mlxi_destroy_flow_group_rsvd; + uint16be_t mlxi_destroy_flow_group_vport_number; + uint8_t mlxi_destroy_flow_group_rsvd2[4]; + uint8_t mlxi_destroy_flow_group_table_type; + uint8_t mlxi_destroy_flow_group_rsvd3[4]; + uint24be_t mlxi_destroy_flow_group_table_id; + uint32be_t mlxi_destroy_flow_group_group_id; + uint8_t mlxi_destroy_flow_group_rsvd4[36]; +} mlxcx_cmd_destroy_flow_group_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_destroy_flow_group_head; + uint8_t mlxo_destroy_flow_group_rsvd[8]; +} mlxcx_cmd_destroy_flow_group_out_t; + +typedef enum { + MLXCX_CMD_FLOW_ENTRY_SET_NEW = 0, + MLXCX_CMD_FLOW_ENTRY_MODIFY = 1, +} mlxcx_cmd_set_flow_table_entry_opmod_t; + +typedef enum { + MLXCX_CMD_FLOW_ENTRY_SET_ACTION = 1 << 0, + MLXCX_CMD_FLOW_ENTRY_SET_FLOW_TAG = 1 << 1, + MLXCX_CMD_FLOW_ENTRY_SET_DESTINATION = 1 << 2, + MLXCX_CMD_FLOW_ENTRY_SET_COUNTERS = 1 << 3, + MLXCX_CMD_FLOW_ENTRY_SET_ENCAP = 1 << 4 +} mlxcx_cmd_set_flow_table_entry_bitmask_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_set_flow_table_entry_head; + uint8_t mlxi_set_flow_table_entry_other_vport; + uint8_t mlxi_set_flow_table_entry_rsvd; + uint16be_t mlxi_set_flow_table_entry_vport_number; + uint8_t mlxi_set_flow_table_entry_rsvd2[4]; + uint8_t mlxi_set_flow_table_entry_table_type; + uint8_t mlxi_set_flow_table_entry_rsvd3[4]; + uint24be_t mlxi_set_flow_table_entry_table_id; + uint8_t mlxi_set_flow_table_entry_rsvd4[3]; + bits8_t mlxi_set_flow_table_entry_modify_bitmask; + uint8_t mlxi_set_flow_table_entry_rsvd5[4]; + uint32be_t mlxi_set_flow_table_entry_flow_index; + uint8_t mlxi_set_flow_table_entry_rsvd6[28]; + mlxcx_flow_entry_ctx_t mlxi_set_flow_table_entry_context; +} mlxcx_cmd_set_flow_table_entry_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_set_flow_table_entry_head; + uint8_t mlxo_set_flow_table_entry_rsvd[8]; +} mlxcx_cmd_set_flow_table_entry_out_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_delete_flow_table_entry_head; + uint8_t mlxi_delete_flow_table_entry_other_vport; + uint8_t mlxi_delete_flow_table_entry_rsvd; + uint16be_t mlxi_delete_flow_table_entry_vport_number; + uint8_t mlxi_delete_flow_table_entry_rsvd2[4]; + uint8_t mlxi_delete_flow_table_entry_table_type; + uint8_t mlxi_delete_flow_table_entry_rsvd3[4]; + uint24be_t mlxi_delete_flow_table_entry_table_id; + uint8_t mlxi_delete_flow_table_entry_rsvd4[8]; + uint32be_t mlxi_delete_flow_table_entry_flow_index; + uint8_t mlxi_delete_flow_table_entry_rsvd5[28]; +} mlxcx_cmd_delete_flow_table_entry_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_delete_flow_table_entry_head; + uint8_t mlxo_delete_flow_table_entry_rsvd[8]; +} mlxcx_cmd_delete_flow_table_entry_out_t; + +typedef enum { + MLXCX_CMD_CONFIG_INT_MOD_READ = 1, + MLXCX_CMD_CONFIG_INT_MOD_WRITE = 0 +} mlxcx_cmd_config_int_mod_opmod_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_config_int_mod_head; + uint16be_t mlxi_config_int_mod_min_delay; + uint16be_t mlxi_config_int_mod_int_vector; + uint8_t mlxi_config_int_mod_rsvd[4]; +} mlxcx_cmd_config_int_mod_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_config_int_mod_head; + uint16be_t mlxo_config_int_mod_min_delay; + uint16be_t mlxo_config_int_mod_int_vector; + uint8_t mlxo_config_int_mod_rsvd[4]; +} mlxcx_cmd_config_int_mod_out_t; + +typedef struct { + uint8_t mlrd_pmtu_rsvd; + uint8_t mlrd_pmtu_local_port; + uint8_t mlrd_pmtu_rsvd2[2]; + + uint16be_t mlrd_pmtu_max_mtu; + uint8_t mlrd_pmtu_rsvd3[2]; + + uint16be_t mlrd_pmtu_admin_mtu; + uint8_t mlrd_pmtu_rsvd4[2]; + + uint16be_t mlrd_pmtu_oper_mtu; + uint8_t mlrd_pmtu_rsvd5[2]; +} mlxcx_reg_pmtu_t; + +typedef enum { + MLXCX_PORT_STATUS_UP = 1, + MLXCX_PORT_STATUS_DOWN = 2, + MLXCX_PORT_STATUS_UP_ONCE = 3, + MLXCX_PORT_STATUS_DISABLED = 4, +} mlxcx_port_status_t; + +typedef enum { + MLXCX_PAOS_ADMIN_ST_EN = 1UL << 31, +} mlxcx_paos_flags_t; + +typedef struct { + uint8_t mlrd_paos_swid; + uint8_t mlrd_paos_local_port; + uint8_t mlrd_paos_admin_status; + uint8_t mlrd_paos_oper_status; + bits32_t mlrd_paos_flags; + uint8_t mlrd_paos_rsvd[8]; +} mlxcx_reg_paos_t; + +typedef enum { + MLXCX_PROTO_SGMII = 1 << 0, + MLXCX_PROTO_1000BASE_KX = 1 << 1, + MLXCX_PROTO_10GBASE_CX4 = 1 << 2, + MLXCX_PROTO_10GBASE_KX4 = 1 << 3, + MLXCX_PROTO_10GBASE_KR = 1 << 4, + MLXCX_PROTO_UNKNOWN_1 = 1 << 5, + MLXCX_PROTO_40GBASE_CR4 = 1 << 6, + MLXCX_PROTO_40GBASE_KR4 = 1 << 7, + MLXCX_PROTO_UNKNOWN_2 = 1 << 8, + MLXCX_PROTO_SGMII_100BASE = 1 << 9, + MLXCX_PROTO_UNKNOWN_3 = 1 << 10, + MLXCX_PROTO_UNKNOWN_4 = 1 << 11, + MLXCX_PROTO_10GBASE_CR = 1 << 12, + MLXCX_PROTO_10GBASE_SR = 1 << 13, + MLXCX_PROTO_10GBASE_ER_LR = 1 << 14, + MLXCX_PROTO_40GBASE_SR4 = 1 << 15, + MLXCX_PROTO_40GBASE_LR4_ER4 = 1 << 16, + MLXCX_PROTO_UNKNOWN_5 = 1 << 17, + MLXCX_PROTO_50GBASE_SR2 = 1 << 18, + MLXCX_PROTO_UNKNOWN_6 = 1 << 19, + MLXCX_PROTO_100GBASE_CR4 = 1 << 20, + MLXCX_PROTO_100GBASE_SR4 = 1 << 21, + MLXCX_PROTO_100GBASE_KR4 = 1 << 22, + MLXCX_PROTO_UNKNOWN_7 = 1 << 23, + MLXCX_PROTO_UNKNOWN_8 = 1 << 24, + MLXCX_PROTO_UNKNOWN_9 = 1 << 25, + MLXCX_PROTO_UNKNOWN_10 = 1 << 26, + MLXCX_PROTO_25GBASE_CR = 1 << 27, + MLXCX_PROTO_25GBASE_KR = 1 << 28, + MLXCX_PROTO_25GBASE_SR = 1 << 29, + MLXCX_PROTO_50GBASE_CR2 = 1 << 30, + MLXCX_PROTO_50GBASE_KR2 = 1UL << 31, +} mlxcx_eth_proto_t; + +typedef enum { + MLXCX_AUTONEG_DISABLE_CAP = 1 << 5, + MLXCX_AUTONEG_DISABLE = 1 << 6 +} mlxcx_autoneg_flags_t; + +typedef enum { + MLXCX_PTYS_PROTO_MASK_IB = 1 << 0, + MLXCX_PTYS_PROTO_MASK_ETH = 1 << 2, +} mlxcx_reg_ptys_proto_mask_t; + +typedef struct { + bits8_t mlrd_ptys_autoneg_flags; + uint8_t mlrd_ptys_local_port; + uint8_t mlrd_ptys_rsvd; + bits8_t mlrd_ptys_proto_mask; + + bits8_t mlrd_ptys_autoneg_status; + uint8_t mlrd_ptys_rsvd2; + uint16be_t mlrd_ptys_data_rate_oper; + + uint8_t mlrd_ptys_rsvd3[4]; + + bits32_t mlrd_ptys_proto_cap; + uint8_t mlrd_ptys_rsvd4[8]; + bits32_t mlrd_ptys_proto_admin; + uint8_t mlrd_ptys_rsvd5[8]; + bits32_t mlrd_ptys_proto_oper; + uint8_t mlrd_ptys_rsvd6[8]; + bits32_t mlrd_ptys_proto_partner_advert; + uint8_t mlrd_ptys_rsvd7[12]; +} mlxcx_reg_ptys_t; + +typedef enum { + MLXCX_LED_TYPE_BOTH = 0x0, + MLXCX_LED_TYPE_UID = 0x1, + MLXCX_LED_TYPE_PORT = 0x2, +} mlxcx_led_type_t; + +#define MLXCX_MLCR_INDIVIDUAL_ONLY (1 << 4) +/* CSTYLED */ +#define MLXCX_MLCR_LED_TYPE (bitdef_t){ 0, 0x0F } + +typedef struct { + uint8_t mlrd_mlcr_rsvd; + uint8_t mlrd_mlcr_local_port; + uint8_t mlrd_mlcr_rsvd2; + bits8_t mlrd_mlcr_flags; + uint8_t mlrd_mlcr_rsvd3[2]; + uint16be_t mlrd_mlcr_beacon_duration; + uint8_t mlrd_mlcr_rsvd4[2]; + uint16be_t mlrd_mlcr_beacon_remain; +} mlxcx_reg_mlcr_t; + +typedef struct { + uint8_t mlrd_pmaos_rsvd; + uint8_t mlrd_pmaos_module; + uint8_t mlrd_pmaos_admin_status; + uint8_t mlrd_pmaos_oper_status; + bits8_t mlrd_pmaos_flags; + uint8_t mlrd_pmaos_rsvd2; + uint8_t mlrd_pmaos_error_type; + uint8_t mlrd_pmaos_event_en; + uint8_t mlrd_pmaos_rsvd3[8]; +} mlxcx_reg_pmaos_t; + +typedef enum { + MLXCX_MCIA_STATUS_OK = 0x0, + MLXCX_MCIA_STATUS_NO_EEPROM = 0x1, + MLXCX_MCIA_STATUS_NOT_SUPPORTED = 0x2, + MLXCX_MCIA_STATUS_NOT_CONNECTED = 0x3, + MLXCX_MCIA_STATUS_I2C_ERROR = 0x9, + MLXCX_MCIA_STATUS_DISABLED = 0x10 +} mlxcx_mcia_status_t; + +typedef struct { + bits8_t mlrd_mcia_flags; + uint8_t mlrd_mcia_module; + uint8_t mlrd_mcia_rsvd; + uint8_t mlrd_mcia_status; + uint8_t mlrd_mcia_i2c_device_addr; + uint8_t mlrd_mcia_page_number; + uint16be_t mlrd_mcia_device_addr; + uint8_t mlrd_mcia_rsvd2[2]; + uint16be_t mlrd_mcia_size; + uint8_t mlrd_mcia_rsvd3[4]; + uint8_t mlrd_mcia_data[48]; +} mlxcx_reg_mcia_t; + +typedef struct { + uint64be_t mlppc_ieee_802_3_frames_tx; + uint64be_t mlppc_ieee_802_3_frames_rx; + uint64be_t mlppc_ieee_802_3_fcs_err; + uint64be_t mlppc_ieee_802_3_align_err; + uint64be_t mlppc_ieee_802_3_bytes_tx; + uint64be_t mlppc_ieee_802_3_bytes_rx; + uint64be_t mlppc_ieee_802_3_mcast_tx; + uint64be_t mlppc_ieee_802_3_bcast_tx; + uint64be_t mlppc_ieee_802_3_mcast_rx; + uint64be_t mlppc_ieee_802_3_bcast_rx; + uint64be_t mlppc_ieee_802_3_in_range_len_err; + uint64be_t mlppc_ieee_802_3_out_of_range_len_err; + uint64be_t mlppc_ieee_802_3_frame_too_long_err; + uint64be_t mlppc_ieee_802_3_symbol_err; + uint64be_t mlppc_ieee_802_3_mac_ctrl_tx; + uint64be_t mlppc_ieee_802_3_mac_ctrl_rx; + uint64be_t mlppc_ieee_802_3_unsup_opcodes_rx; + uint64be_t mlppc_ieee_802_3_pause_rx; + uint64be_t mlppc_ieee_802_3_pause_tx; +} mlxcx_ppcnt_ieee_802_3_t; + +typedef struct { + uint64be_t mlppc_rfc_2863_in_octets; + uint64be_t mlppc_rfc_2863_in_ucast_pkts; + uint64be_t mlppc_rfc_2863_in_discards; + uint64be_t mlppc_rfc_2863_in_errors; + uint64be_t mlppc_rfc_2863_in_unknown_protos; + uint64be_t mlppc_rfc_2863_out_octets; + uint64be_t mlppc_rfc_2863_out_ucast_pkts; + uint64be_t mlppc_rfc_2863_out_discards; + uint64be_t mlppc_rfc_2863_out_errors; + uint64be_t mlppc_rfc_2863_in_mcast_pkts; + uint64be_t mlppc_rfc_2863_in_bcast_pkts; + uint64be_t mlppc_rfc_2863_out_mcast_pkts; + uint64be_t mlppc_rfc_2863_out_bcast_pkts; +} mlxcx_ppcnt_rfc_2863_t; + +typedef struct { + uint64be_t mlppc_phy_stats_time_since_last_clear; + uint64be_t mlppc_phy_stats_rx_bits; + uint64be_t mlppc_phy_stats_symbol_errs; + uint64be_t mlppc_phy_stats_corrected_bits; + uint8_t mlppc_phy_stats_rsvd[2]; + uint8_t mlppc_phy_stats_raw_ber_mag; + uint8_t mlppc_phy_stats_raw_ber_coef; + uint8_t mlppc_phy_stats_rsvd2[2]; + uint8_t mlppc_phy_stats_eff_ber_mag; + uint8_t mlppc_phy_stats_eff_ber_coef; +} mlxcx_ppcnt_phy_stats_t; + +typedef enum { + MLXCX_PPCNT_GRP_IEEE_802_3 = 0x0, + MLXCX_PPCNT_GRP_RFC_2863 = 0x1, + MLXCX_PPCNT_GRP_RFC_2819 = 0x2, + MLXCX_PPCNT_GRP_RFC_3635 = 0x3, + MLXCX_PPCNT_GRP_ETH_EXTD = 0x5, + MLXCX_PPCNT_GRP_ETH_DISCARD = 0x6, + MLXCX_PPCNT_GRP_PER_PRIO = 0x10, + MLXCX_PPCNT_GRP_PER_TC = 0x11, + MLXCX_PPCNT_GRP_PER_TC_CONGEST = 0x13, + MLXCX_PPCNT_GRP_PHY_STATS = 0x16 +} mlxcx_ppcnt_grp_t; + +typedef enum { + MLXCX_PPCNT_CLEAR = (1 << 7), + MLXCX_PPCNT_NO_CLEAR = 0 +} mlxcx_ppcnt_clear_t; + +typedef struct { + uint8_t mlrd_ppcnt_swid; + uint8_t mlrd_ppcnt_local_port; + uint8_t mlrd_ppcnt_pnat; + uint8_t mlrd_ppcnt_grp; + uint8_t mlrd_ppcnt_clear; + uint8_t mlrd_ppcnt_rsvd[2]; + uint8_t mlrd_ppcnt_prio_tc; + union { + uint8_t mlrd_ppcnt_data[248]; + mlxcx_ppcnt_ieee_802_3_t mlrd_ppcnt_ieee_802_3; + mlxcx_ppcnt_rfc_2863_t mlrd_ppcnt_rfc_2863; + mlxcx_ppcnt_phy_stats_t mlrd_ppcnt_phy_stats; + }; +} mlxcx_reg_ppcnt_t; + +typedef enum { + MLXCX_REG_PMTU = 0x5003, + MLXCX_REG_PTYS = 0x5004, + MLXCX_REG_PAOS = 0x5006, + MLXCX_REG_PMAOS = 0x5012, + MLXCX_REG_MSGI = 0x9021, + MLXCX_REG_MLCR = 0x902B, + MLXCX_REG_MCIA = 0x9014, + MLXCX_REG_PPCNT = 0x5008, +} mlxcx_register_id_t; + +typedef union { + mlxcx_reg_pmtu_t mlrd_pmtu; + mlxcx_reg_paos_t mlrd_paos; + mlxcx_reg_ptys_t mlrd_ptys; + mlxcx_reg_mlcr_t mlrd_mlcr; + mlxcx_reg_pmaos_t mlrd_pmaos; + mlxcx_reg_mcia_t mlrd_mcia; + mlxcx_reg_ppcnt_t mlrd_ppcnt; +} mlxcx_register_data_t; + +typedef enum { + MLXCX_CMD_ACCESS_REGISTER_READ = 1, + MLXCX_CMD_ACCESS_REGISTER_WRITE = 0 +} mlxcx_cmd_reg_opmod_t; + +typedef struct { + mlxcx_cmd_in_t mlxi_access_register_head; + uint8_t mlxi_access_register_rsvd[2]; + uint16be_t mlxi_access_register_register_id; + uint32be_t mlxi_access_register_argument; + mlxcx_register_data_t mlxi_access_register_data; +} mlxcx_cmd_access_register_in_t; + +typedef struct { + mlxcx_cmd_out_t mlxo_access_register_head; + uint8_t mlxo_access_register_rsvd[8]; + mlxcx_register_data_t mlxo_access_register_data; +} mlxcx_cmd_access_register_out_t; + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* _MLXCX_REG_H */ diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_ring.c b/usr/src/uts/common/io/mlxcx/mlxcx_ring.c new file mode 100644 index 0000000000..8337545b57 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_ring.c @@ -0,0 +1,2264 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020, The University of Queensland + * Copyright (c) 2018, Joyent, Inc. + */ + +/* + * Mellanox Connect-X 4/5/6 driver. + */ + +#include <sys/modctl.h> +#include <sys/conf.h> +#include <sys/devops.h> +#include <sys/sysmacros.h> +#include <sys/atomic.h> +#include <sys/cpuvar.h> + +#include <sys/pattr.h> +#include <sys/dlpi.h> + +#include <sys/mac_provider.h> + +#include <sys/random.h> + +#include <mlxcx.h> + +boolean_t +mlxcx_wq_alloc_dma(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + boolean_t ret; + size_t sz; + + VERIFY0(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + + /* Receive and send queue entries might be different sizes. */ + switch (mlwq->mlwq_type) { + case MLXCX_WQ_TYPE_SENDQ: + mlwq->mlwq_entshift = mlxp->mlx_props.mldp_sq_size_shift; + mlwq->mlwq_nents = (1 << mlwq->mlwq_entshift); + sz = mlwq->mlwq_nents * sizeof (mlxcx_sendq_ent_t); + break; + case MLXCX_WQ_TYPE_RECVQ: + mlwq->mlwq_entshift = mlxp->mlx_props.mldp_rq_size_shift; + mlwq->mlwq_nents = (1 << mlwq->mlwq_entshift); + sz = mlwq->mlwq_nents * sizeof (mlxcx_recvq_ent_t); + break; + default: + VERIFY(0); + return (B_FALSE); + } + ASSERT3U(sz & (MLXCX_HW_PAGE_SIZE - 1), ==, 0); + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_queue_attr(mlxp, &attr); + + ret = mlxcx_dma_alloc(mlxp, &mlwq->mlwq_dma, &attr, &acc, + B_TRUE, sz, B_TRUE); + if (!ret) { + mlxcx_warn(mlxp, "failed to allocate WQ memory"); + return (B_FALSE); + } + + /* + * Just set the first pointer in the union. Yes, this is a strict + * aliasing violation. No, I don't care. + */ + mlwq->mlwq_send_ent = (mlxcx_sendq_ent_t *)mlwq->mlwq_dma.mxdb_va; + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_qdbell_attr(mlxp, &attr); + sz = sizeof (mlxcx_workq_doorbell_t); + ret = mlxcx_dma_alloc(mlxp, &mlwq->mlwq_doorbell_dma, &attr, &acc, + B_TRUE, sz, B_TRUE); + if (!ret) { + mlxcx_warn(mlxp, "failed to allocate WQ doorbell memory"); + mlxcx_dma_free(&mlwq->mlwq_dma); + mlwq->mlwq_send_ent = NULL; + return (B_FALSE); + } + + mlwq->mlwq_doorbell = + (mlxcx_workq_doorbell_t *)mlwq->mlwq_doorbell_dma.mxdb_va; + + mlwq->mlwq_state |= MLXCX_WQ_ALLOC; + + return (B_TRUE); +} + +void +mlxcx_wq_rele_dma(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + VERIFY(mlwq->mlwq_state & MLXCX_WQ_ALLOC); + if (mlwq->mlwq_state & MLXCX_WQ_CREATED) + VERIFY(mlwq->mlwq_state & MLXCX_WQ_DESTROYED); + + mlxcx_dma_free(&mlwq->mlwq_dma); + mlwq->mlwq_send_ent = NULL; + mlxcx_dma_free(&mlwq->mlwq_doorbell_dma); + mlwq->mlwq_doorbell = NULL; + + mlwq->mlwq_state &= ~MLXCX_CQ_ALLOC; +} + +boolean_t +mlxcx_cq_alloc_dma(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq) +{ + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + boolean_t ret; + size_t sz, i; + + VERIFY0(mlcq->mlcq_state & MLXCX_EQ_ALLOC); + + mlcq->mlcq_entshift = mlxp->mlx_props.mldp_cq_size_shift; + mlcq->mlcq_nents = (1 << mlcq->mlcq_entshift); + sz = mlcq->mlcq_nents * sizeof (mlxcx_completionq_ent_t); + ASSERT3U(sz & (MLXCX_HW_PAGE_SIZE - 1), ==, 0); + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_queue_attr(mlxp, &attr); + + ret = mlxcx_dma_alloc(mlxp, &mlcq->mlcq_dma, &attr, &acc, + B_TRUE, sz, B_TRUE); + if (!ret) { + mlxcx_warn(mlxp, "failed to allocate CQ memory"); + return (B_FALSE); + } + + mlcq->mlcq_ent = (mlxcx_completionq_ent_t *)mlcq->mlcq_dma.mxdb_va; + + for (i = 0; i < mlcq->mlcq_nents; ++i) { + mlcq->mlcq_ent[i].mlcqe_opcode = MLXCX_CQE_OP_INVALID; + mlcq->mlcq_ent[i].mlcqe_owner = MLXCX_CQE_OWNER_INIT; + } + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_qdbell_attr(mlxp, &attr); + sz = sizeof (mlxcx_completionq_doorbell_t); + ret = mlxcx_dma_alloc(mlxp, &mlcq->mlcq_doorbell_dma, &attr, &acc, + B_TRUE, sz, B_TRUE); + if (!ret) { + mlxcx_warn(mlxp, "failed to allocate CQ doorbell memory"); + mlxcx_dma_free(&mlcq->mlcq_dma); + mlcq->mlcq_ent = NULL; + return (B_FALSE); + } + + mlcq->mlcq_doorbell = + (mlxcx_completionq_doorbell_t *)mlcq->mlcq_doorbell_dma.mxdb_va; + + mlcq->mlcq_state |= MLXCX_CQ_ALLOC; + + return (B_TRUE); +} + +void +mlxcx_cq_rele_dma(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq) +{ + VERIFY(mlcq->mlcq_state & MLXCX_CQ_ALLOC); + if (mlcq->mlcq_state & MLXCX_CQ_CREATED) + VERIFY(mlcq->mlcq_state & MLXCX_CQ_DESTROYED); + + mlxcx_dma_free(&mlcq->mlcq_dma); + mlcq->mlcq_ent = NULL; + mlxcx_dma_free(&mlcq->mlcq_doorbell_dma); + mlcq->mlcq_doorbell = NULL; + + mlcq->mlcq_state &= ~MLXCX_CQ_ALLOC; +} + +void +mlxcx_wq_teardown(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + mlxcx_completion_queue_t *mlcq; + + /* + * If something is holding the lock on a long operation like a + * refill, setting this flag asks them to exit early if possible. + */ + atomic_or_uint(&mlwq->mlwq_state, MLXCX_WQ_TEARDOWN); + + mutex_enter(&mlwq->mlwq_mtx); + + list_remove(&mlxp->mlx_wqs, mlwq); + + if ((mlwq->mlwq_state & MLXCX_WQ_CREATED) && + !(mlwq->mlwq_state & MLXCX_WQ_DESTROYED)) { + if (mlwq->mlwq_type == MLXCX_WQ_TYPE_RECVQ && + mlwq->mlwq_state & MLXCX_WQ_STARTED && + !mlxcx_cmd_stop_rq(mlxp, mlwq)) { + mlxcx_warn(mlxp, "failed to stop " + "recv queue num %x", mlwq->mlwq_num); + } + if (mlwq->mlwq_type == MLXCX_WQ_TYPE_SENDQ && + mlwq->mlwq_state & MLXCX_WQ_STARTED && + !mlxcx_cmd_stop_sq(mlxp, mlwq)) { + mlxcx_warn(mlxp, "failed to stop " + "send queue num %x", mlwq->mlwq_num); + } + if (mlwq->mlwq_type == MLXCX_WQ_TYPE_RECVQ && + !mlxcx_cmd_destroy_rq(mlxp, mlwq)) { + mlxcx_warn(mlxp, "failed to destroy " + "recv queue num %x", mlwq->mlwq_num); + } + if (mlwq->mlwq_type == MLXCX_WQ_TYPE_SENDQ && + !mlxcx_cmd_destroy_sq(mlxp, mlwq)) { + mlxcx_warn(mlxp, "failed to destroy " + "send queue num %x", mlwq->mlwq_num); + } + } + if (mlwq->mlwq_state & MLXCX_WQ_ALLOC) { + mlxcx_wq_rele_dma(mlxp, mlwq); + } + mlcq = mlwq->mlwq_cq; + + /* These will be released by mlxcx_teardown_bufs() */ + mlwq->mlwq_bufs = NULL; + mlwq->mlwq_foreign_bufs = NULL; + + mutex_exit(&mlwq->mlwq_mtx); + + mutex_enter(&mlcq->mlcq_mtx); + mutex_enter(&mlwq->mlwq_mtx); + ASSERT3P(mlcq->mlcq_wq, ==, mlwq); + mlcq->mlcq_wq = NULL; + mutex_exit(&mlwq->mlwq_mtx); + mutex_exit(&mlcq->mlcq_mtx); + + mutex_destroy(&mlwq->mlwq_mtx); +} + +void +mlxcx_cq_teardown(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq) +{ + mlxcx_event_queue_t *mleq; + mlxcx_buffer_t *b; + + /* + * If something is holding the lock on a long operation like polling + * which we're going to abort anyway, this flag asks them to exit + * early if possible. + */ + atomic_or_uint(&mlcq->mlcq_state, MLXCX_CQ_TEARDOWN); + + mutex_enter(&mlcq->mlcq_mtx); + + list_remove(&mlxp->mlx_cqs, mlcq); + + if ((mlcq->mlcq_state & MLXCX_CQ_CREATED) && + !(mlcq->mlcq_state & MLXCX_CQ_DESTROYED)) { + if (!mlxcx_cmd_destroy_cq(mlxp, mlcq)) { + mlxcx_warn(mlxp, "failed to destroy " + "completion queue num %u", + mlcq->mlcq_num); + } + } + if (mlcq->mlcq_state & MLXCX_CQ_ALLOC) { + mlxcx_cq_rele_dma(mlxp, mlcq); + } + /* + * If we're on an EQ AVL tree, then we need to grab + * the EQ's mutex to take it off. The ISR always takes + * EQ mutex before CQ mutex, so we have to let go of + * the CQ mutex then come back again. + * + * The ISR will bail out if tries to touch this CQ now since + * we added the CQ_DESTROYED flag above. + */ + if (mlcq->mlcq_state & MLXCX_CQ_EQAVL) { + mleq = mlcq->mlcq_eq; + } else { + mleq = NULL; + } + + /* Return any outstanding buffers to the free pool. */ + while ((b = list_remove_head(&mlcq->mlcq_buffers)) != NULL) { + mlxcx_buf_return_chain(mlxp, b, B_FALSE); + } + mutex_enter(&mlcq->mlcq_bufbmtx); + while ((b = list_remove_head(&mlcq->mlcq_buffers_b)) != NULL) { + mlxcx_buf_return_chain(mlxp, b, B_FALSE); + } + mutex_exit(&mlcq->mlcq_bufbmtx); + + /* + * Since the interrupt handlers take the EQ lock before the CQ one, + * we must do the same here. That means letting go of the lock + * for a brief window here (we'll double-check the state when we + * get back in). + */ + mutex_exit(&mlcq->mlcq_mtx); + + if (mleq != NULL) { + mutex_enter(&mleq->mleq_mtx); + mutex_enter(&mlcq->mlcq_mtx); + /* + * Double-check the state, we let go of the + * mutex briefly. + */ + if (mlcq->mlcq_state & MLXCX_CQ_EQAVL) { + avl_remove(&mleq->mleq_cqs, mlcq); + mlcq->mlcq_state &= ~MLXCX_CQ_EQAVL; + } + mutex_exit(&mlcq->mlcq_mtx); + mutex_exit(&mleq->mleq_mtx); + } + + mutex_enter(&mlcq->mlcq_mtx); + ASSERT0(mlcq->mlcq_state & ~(MLXCX_CQ_CREATED | MLXCX_CQ_DESTROYED | + MLXCX_CQ_TEARDOWN | MLXCX_CQ_ARMED)); + mutex_exit(&mlcq->mlcq_mtx); + + mutex_destroy(&mlcq->mlcq_mtx); + mutex_destroy(&mlcq->mlcq_bufbmtx); + list_destroy(&mlcq->mlcq_buffers); + list_destroy(&mlcq->mlcq_buffers_b); + kmem_free(mlcq, sizeof (mlxcx_completion_queue_t)); +} + +static boolean_t +mlxcx_cq_setup(mlxcx_t *mlxp, mlxcx_event_queue_t *eq, + mlxcx_completion_queue_t **cqp) +{ + mlxcx_completion_queue_t *cq; + + cq = kmem_zalloc(sizeof (mlxcx_completion_queue_t), KM_SLEEP); + mutex_init(&cq->mlcq_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + mutex_init(&cq->mlcq_bufbmtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + list_create(&cq->mlcq_buffers, sizeof (mlxcx_buffer_t), + offsetof(mlxcx_buffer_t, mlb_cq_entry)); + list_create(&cq->mlcq_buffers_b, sizeof (mlxcx_buffer_t), + offsetof(mlxcx_buffer_t, mlb_cq_entry)); + + cq->mlcq_mlx = mlxp; + list_insert_tail(&mlxp->mlx_cqs, cq); + + mutex_enter(&cq->mlcq_mtx); + + if (!mlxcx_cq_alloc_dma(mlxp, cq)) { + mutex_exit(&cq->mlcq_mtx); + return (B_FALSE); + } + + cq->mlcq_bufhwm = cq->mlcq_nents - MLXCX_CQ_HWM_GAP; + cq->mlcq_buflwm = cq->mlcq_nents - MLXCX_CQ_LWM_GAP; + + cq->mlcq_uar = &mlxp->mlx_uar; + cq->mlcq_eq = eq; + + cq->mlcq_cqemod_period_usec = mlxp->mlx_props.mldp_cqemod_period_usec; + cq->mlcq_cqemod_count = mlxp->mlx_props.mldp_cqemod_count; + + if (!mlxcx_cmd_create_cq(mlxp, cq)) { + mutex_exit(&cq->mlcq_mtx); + return (B_FALSE); + } + + mutex_exit(&cq->mlcq_mtx); + + mutex_enter(&eq->mleq_mtx); + mutex_enter(&cq->mlcq_mtx); + ASSERT0(cq->mlcq_state & MLXCX_CQ_EQAVL); + avl_add(&eq->mleq_cqs, cq); + cq->mlcq_state |= MLXCX_CQ_EQAVL; + mlxcx_arm_cq(mlxp, cq); + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&eq->mleq_mtx); + + *cqp = cq; + return (B_TRUE); +} + +static boolean_t +mlxcx_rq_setup(mlxcx_t *mlxp, mlxcx_completion_queue_t *cq, + mlxcx_work_queue_t *wq) +{ + mutex_init(&wq->mlwq_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + + list_insert_tail(&mlxp->mlx_wqs, wq); + + mutex_enter(&wq->mlwq_mtx); + + wq->mlwq_mlx = mlxp; + wq->mlwq_type = MLXCX_WQ_TYPE_RECVQ; + wq->mlwq_cq = cq; + wq->mlwq_pd = &mlxp->mlx_pd; + wq->mlwq_uar = &mlxp->mlx_uar; + + wq->mlwq_bufs = mlxcx_mlbs_create(mlxp); + + if (!mlxcx_wq_alloc_dma(mlxp, wq)) { + mutex_exit(&wq->mlwq_mtx); + return (B_FALSE); + } + + if (!mlxcx_cmd_create_rq(mlxp, wq)) { + mutex_exit(&wq->mlwq_mtx); + return (B_FALSE); + } + + mutex_exit(&wq->mlwq_mtx); + + mutex_enter(&cq->mlcq_mtx); + mutex_enter(&wq->mlwq_mtx); + ASSERT3P(cq->mlcq_wq, ==, NULL); + cq->mlcq_wq = wq; + mutex_exit(&wq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + + return (B_TRUE); +} + +static boolean_t +mlxcx_sq_setup(mlxcx_t *mlxp, mlxcx_port_t *port, mlxcx_completion_queue_t *cq, + mlxcx_tis_t *tis, mlxcx_work_queue_t *wq) +{ + mutex_init(&wq->mlwq_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + + list_insert_tail(&mlxp->mlx_wqs, wq); + + mutex_enter(&wq->mlwq_mtx); + + wq->mlwq_mlx = mlxp; + wq->mlwq_type = MLXCX_WQ_TYPE_SENDQ; + wq->mlwq_cq = cq; + wq->mlwq_pd = &mlxp->mlx_pd; + wq->mlwq_uar = &mlxp->mlx_uar; + wq->mlwq_tis = tis; + + wq->mlwq_bufs = mlxcx_mlbs_create(mlxp); + wq->mlwq_foreign_bufs = mlxcx_mlbs_create(mlxp); + + VERIFY3U(port->mlp_wqe_min_inline, <=, MLXCX_ETH_INLINE_L2); + wq->mlwq_inline_mode = MLXCX_ETH_INLINE_L2; + + if (!mlxcx_wq_alloc_dma(mlxp, wq)) { + mutex_exit(&wq->mlwq_mtx); + return (B_FALSE); + } + + if (!mlxcx_cmd_create_sq(mlxp, wq)) { + mutex_exit(&wq->mlwq_mtx); + return (B_FALSE); + } + + mutex_exit(&wq->mlwq_mtx); + + mutex_enter(&cq->mlcq_mtx); + mutex_enter(&wq->mlwq_mtx); + ASSERT3P(cq->mlcq_wq, ==, NULL); + cq->mlcq_wq = wq; + mutex_exit(&wq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + + return (B_TRUE); +} + +void +mlxcx_teardown_rx_group(mlxcx_t *mlxp, mlxcx_ring_group_t *g) +{ + mlxcx_work_queue_t *wq; + mlxcx_completion_queue_t *cq; + mlxcx_flow_entry_t *fe; + mlxcx_flow_group_t *fg; + mlxcx_flow_table_t *ft; + uint_t i; + + mutex_enter(&g->mlg_port->mlp_mtx); + mutex_enter(&g->mlg_mtx); + + if (g->mlg_state & MLXCX_GROUP_FLOWS) { + mlxcx_remove_all_umcast_entries(mlxp, g->mlg_port, g); + + if (g->mlg_rx_vlan_ft != NULL) + mlxcx_remove_all_vlan_entries(mlxp, g); + + if (g == &mlxp->mlx_rx_groups[0]) { + ft = g->mlg_port->mlp_rx_flow; + mutex_enter(&ft->mlft_mtx); + + fg = g->mlg_port->mlp_bcast; + fe = list_head(&fg->mlfg_entries); + if (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + (void) mlxcx_cmd_delete_flow_table_entry( + mlxp, fe); + } + + fg = g->mlg_port->mlp_promisc; + fe = list_head(&fg->mlfg_entries); + if (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + (void) mlxcx_cmd_delete_flow_table_entry( + mlxp, fe); + } + + mutex_exit(&ft->mlft_mtx); + } + + if (g->mlg_rx_vlan_ft != NULL) { + mutex_enter(&g->mlg_rx_vlan_ft->mlft_mtx); + ASSERT(list_is_empty(&g->mlg_rx_vlans)); + fg = g->mlg_rx_vlan_def_fg; + fe = list_head(&fg->mlfg_entries); + if (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + (void) mlxcx_cmd_delete_flow_table_entry( + mlxp, fe); + } + fg = g->mlg_rx_vlan_promisc_fg; + fe = list_head(&fg->mlfg_entries); + if (fe->mlfe_state & MLXCX_FLOW_ENTRY_CREATED) { + (void) mlxcx_cmd_delete_flow_table_entry( + mlxp, fe); + } + mlxcx_teardown_flow_table(mlxp, g->mlg_rx_vlan_ft); + list_destroy(&g->mlg_rx_vlans); + + g->mlg_rx_vlan_ft = NULL; + } + + mutex_enter(&g->mlg_rx_hash_ft->mlft_mtx); + mlxcx_teardown_flow_table(mlxp, g->mlg_rx_hash_ft); + g->mlg_rx_hash_ft = NULL; + + avl_destroy(&g->mlg_rx_macs); + g->mlg_state &= ~MLXCX_GROUP_FLOWS; + } + + if (g->mlg_state & MLXCX_GROUP_RUNNING) { + for (i = 0; i < g->mlg_nwqs; ++i) { + wq = &g->mlg_wqs[i]; + mutex_enter(&wq->mlwq_mtx); + if (wq->mlwq_state & MLXCX_WQ_STARTED && + !mlxcx_cmd_stop_rq(mlxp, wq)) { + mlxcx_warn(mlxp, "failed to stop rq %x", + wq->mlwq_num); + } + mutex_exit(&wq->mlwq_mtx); + } + g->mlg_state &= ~MLXCX_GROUP_RUNNING; + } + + if (g->mlg_state & MLXCX_GROUP_TIRTIS) { + for (i = 0; i < MLXCX_TIRS_PER_GROUP; ++i) { + mlxcx_tir_t *tir = &g->mlg_tir[i]; + if (tir->mltir_state & MLXCX_TIR_CREATED && + !(tir->mltir_state & MLXCX_TIR_DESTROYED)) { + if (!mlxcx_cmd_destroy_tir(mlxp, tir)) { + mlxcx_warn(mlxp, + "failed to destroy tir %u " + "for rx ring", tir->mltir_num); + } + } + } + g->mlg_state &= ~MLXCX_GROUP_TIRTIS; + } + + if (g->mlg_state & MLXCX_GROUP_RQT) { + if (g->mlg_rqt->mlrqt_state & MLXCX_RQT_CREATED && + !(g->mlg_rqt->mlrqt_state & MLXCX_RQT_DESTROYED)) { + if (!mlxcx_cmd_destroy_rqt(mlxp, g->mlg_rqt)) { + mlxcx_warn(mlxp, "failed to destroy rqt %u " + "for rx ring", g->mlg_rqt->mlrqt_num); + } + kmem_free(g->mlg_rqt->mlrqt_rq, + g->mlg_rqt->mlrqt_rq_size); + g->mlg_rqt->mlrqt_rq = NULL; + kmem_free(g->mlg_rqt, sizeof (mlxcx_rqtable_t)); + g->mlg_rqt = NULL; + } + g->mlg_state &= ~MLXCX_GROUP_RQT; + } + + for (i = 0; i < g->mlg_nwqs; ++i) { + wq = &g->mlg_wqs[i]; + cq = wq->mlwq_cq; + mlxcx_wq_teardown(mlxp, wq); + if (cq != NULL) + mlxcx_cq_teardown(mlxp, cq); + } + kmem_free(g->mlg_wqs, g->mlg_wqs_size); + g->mlg_wqs = NULL; + g->mlg_state &= ~MLXCX_GROUP_WQS; + + mutex_exit(&g->mlg_mtx); + mutex_exit(&g->mlg_port->mlp_mtx); + + mutex_destroy(&g->mlg_mtx); + + g->mlg_state &= ~MLXCX_GROUP_INIT; + ASSERT3S(g->mlg_state, ==, 0); +} + +void +mlxcx_teardown_tx_group(mlxcx_t *mlxp, mlxcx_ring_group_t *g) +{ + mlxcx_work_queue_t *wq; + mlxcx_completion_queue_t *cq; + uint_t i; + + mutex_enter(&g->mlg_mtx); + + if (g->mlg_state & MLXCX_GROUP_WQS) { + for (i = 0; i < g->mlg_nwqs; ++i) { + wq = &g->mlg_wqs[i]; + mutex_enter(&wq->mlwq_mtx); + cq = wq->mlwq_cq; + if (wq->mlwq_state & MLXCX_WQ_STARTED && + !mlxcx_cmd_stop_sq(mlxp, wq)) { + mlxcx_warn(mlxp, "failed to stop sq %x", + wq->mlwq_num); + } + mutex_exit(&wq->mlwq_mtx); + mlxcx_wq_teardown(mlxp, wq); + if (cq != NULL) + mlxcx_cq_teardown(mlxp, cq); + } + g->mlg_state &= ~MLXCX_GROUP_RUNNING; + kmem_free(g->mlg_wqs, g->mlg_wqs_size); + g->mlg_wqs = NULL; + g->mlg_state &= ~MLXCX_GROUP_WQS; + } + + if ((g->mlg_state & MLXCX_GROUP_TIRTIS) && + g->mlg_tis.mltis_state & MLXCX_TIS_CREATED && + !(g->mlg_tis.mltis_state & MLXCX_TIS_DESTROYED)) { + if (!mlxcx_cmd_destroy_tis(mlxp, &g->mlg_tis)) { + mlxcx_warn(mlxp, "failed to destroy tis %u for tx ring", + g->mlg_tis.mltis_num); + } + } + g->mlg_state &= ~MLXCX_GROUP_TIRTIS; + + mutex_exit(&g->mlg_mtx); + mutex_destroy(&g->mlg_mtx); + g->mlg_state &= ~MLXCX_GROUP_INIT; + ASSERT3S(g->mlg_state, ==, 0); +} + +void +mlxcx_teardown_groups(mlxcx_t *mlxp) +{ + mlxcx_ring_group_t *g; + uint_t i; + + for (i = 0; i < mlxp->mlx_rx_ngroups; ++i) { + g = &mlxp->mlx_rx_groups[i]; + if (!(g->mlg_state & MLXCX_GROUP_INIT)) + continue; + ASSERT3S(g->mlg_type, ==, MLXCX_GROUP_RX); + mlxcx_teardown_rx_group(mlxp, g); + } + kmem_free(mlxp->mlx_rx_groups, mlxp->mlx_rx_groups_size); + mlxp->mlx_rx_groups = NULL; + + for (i = 0; i < mlxp->mlx_tx_ngroups; ++i) { + g = &mlxp->mlx_tx_groups[i]; + if (!(g->mlg_state & MLXCX_GROUP_INIT)) + continue; + ASSERT3S(g->mlg_type, ==, MLXCX_GROUP_TX); + mlxcx_teardown_tx_group(mlxp, g); + } + kmem_free(mlxp->mlx_tx_groups, mlxp->mlx_tx_groups_size); + mlxp->mlx_tx_groups = NULL; +} + +boolean_t +mlxcx_rx_group_setup(mlxcx_t *mlxp, mlxcx_ring_group_t *g) +{ + mlxcx_event_queue_t *eq; + mlxcx_completion_queue_t *cq; + mlxcx_work_queue_t *rq; + mlxcx_flow_table_t *ft; + mlxcx_flow_group_t *fg; + mlxcx_flow_entry_t *fe; + uint_t i, j; + + ASSERT3S(g->mlg_state, ==, 0); + + mutex_init(&g->mlg_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + mutex_enter(&g->mlg_mtx); + g->mlg_mlx = mlxp; + g->mlg_type = MLXCX_GROUP_RX; + g->mlg_port = &mlxp->mlx_ports[0]; + g->mlg_state |= MLXCX_GROUP_INIT; + + g->mlg_nwqs = mlxp->mlx_props.mldp_rx_nrings_per_small_group; + i = g - &mlxp->mlx_rx_groups[0]; + if (i < mlxp->mlx_props.mldp_rx_ngroups_large) + g->mlg_nwqs = mlxp->mlx_props.mldp_rx_nrings_per_large_group; + + g->mlg_wqs_size = g->mlg_nwqs * sizeof (mlxcx_work_queue_t); + g->mlg_wqs = kmem_zalloc(g->mlg_wqs_size, KM_SLEEP); + g->mlg_state |= MLXCX_GROUP_WQS; + + g->mlg_rqt = kmem_zalloc(sizeof (mlxcx_rqtable_t), KM_SLEEP); + g->mlg_rqt->mlrqt_max = 2; + while (g->mlg_rqt->mlrqt_max < g->mlg_nwqs) + g->mlg_rqt->mlrqt_max <<= 1; + g->mlg_rqt->mlrqt_rq_size = g->mlg_rqt->mlrqt_max * + sizeof (mlxcx_work_queue_t *); + g->mlg_rqt->mlrqt_rq = kmem_zalloc(g->mlg_rqt->mlrqt_rq_size, KM_SLEEP); + g->mlg_state |= MLXCX_GROUP_RQT; + + for (i = 0; i < g->mlg_nwqs; ++i) { + eq = NULL; + while (eq == NULL) { + eq = &mlxp->mlx_eqs[mlxp->mlx_next_eq++]; + if (mlxp->mlx_next_eq >= mlxp->mlx_intr_count) + mlxp->mlx_next_eq = 1; + if (eq->mleq_type != MLXCX_EQ_TYPE_ANY && + eq->mleq_type != MLXCX_EQ_TYPE_RX) { + /* Try the next one */ + eq = NULL; + } + } + + if (!mlxcx_cq_setup(mlxp, eq, &cq)) { + g->mlg_nwqs = i; + break; + } + cq->mlcq_stats = &g->mlg_port->mlp_stats; + + rq = &g->mlg_wqs[i]; + if (!mlxcx_rq_setup(mlxp, cq, rq)) { + g->mlg_nwqs = i; + break; + } + g->mlg_rqt->mlrqt_rq[g->mlg_rqt->mlrqt_used++] = rq; + g->mlg_rqt->mlrqt_state |= MLXCX_RQT_DIRTY; + rq->mlwq_group = g; + } + if (g->mlg_nwqs == 0) { + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + if (!mlxcx_cmd_create_rqt(mlxp, g->mlg_rqt)) { + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + for (i = 0; i < MLXCX_TIRS_PER_GROUP; ++i) { + mlxcx_tir_t *tir = &g->mlg_tir[i]; + tir->mltir_tdom = &mlxp->mlx_tdom; + switch (i) { + case MLXCX_TIR_ROLE_OTHER: + tir->mltir_type = MLXCX_TIR_DIRECT; + tir->mltir_rq = &g->mlg_wqs[0]; + break; + case MLXCX_TIR_ROLE_IPv4: + case MLXCX_TIR_ROLE_IPv6: + case MLXCX_TIR_ROLE_TCPv4: + case MLXCX_TIR_ROLE_TCPv6: + case MLXCX_TIR_ROLE_UDPv4: + case MLXCX_TIR_ROLE_UDPv6: + tir->mltir_type = MLXCX_TIR_INDIRECT; + tir->mltir_rqtable = g->mlg_rqt; + tir->mltir_hash_fn = MLXCX_TIR_HASH_TOEPLITZ; + (void) random_get_pseudo_bytes(tir->mltir_toeplitz_key, + sizeof (tir->mltir_toeplitz_key)); + break; + } + switch (i) { + case MLXCX_TIR_ROLE_OTHER: + break; + case MLXCX_TIR_ROLE_IPv4: + case MLXCX_TIR_ROLE_TCPv4: + case MLXCX_TIR_ROLE_UDPv4: + tir->mltir_l3_type = MLXCX_RX_HASH_L3_IPv4; + tir->mltir_hash_fields = + MLXCX_RX_HASH_SRC_IP | MLXCX_RX_HASH_DST_IP; + break; + case MLXCX_TIR_ROLE_IPv6: + case MLXCX_TIR_ROLE_TCPv6: + case MLXCX_TIR_ROLE_UDPv6: + tir->mltir_l3_type = MLXCX_RX_HASH_L3_IPv6; + tir->mltir_hash_fields = + MLXCX_RX_HASH_SRC_IP | MLXCX_RX_HASH_DST_IP; + break; + } + switch (i) { + case MLXCX_TIR_ROLE_OTHER: + case MLXCX_TIR_ROLE_IPv4: + case MLXCX_TIR_ROLE_IPv6: + break; + case MLXCX_TIR_ROLE_TCPv4: + case MLXCX_TIR_ROLE_TCPv6: + tir->mltir_l4_type = MLXCX_RX_HASH_L4_TCP; + tir->mltir_hash_fields |= + MLXCX_RX_HASH_L4_SPORT | MLXCX_RX_HASH_L4_DPORT; + break; + case MLXCX_TIR_ROLE_UDPv4: + case MLXCX_TIR_ROLE_UDPv6: + tir->mltir_l4_type = MLXCX_RX_HASH_L4_UDP; + tir->mltir_hash_fields |= + MLXCX_RX_HASH_L4_SPORT | MLXCX_RX_HASH_L4_DPORT; + break; + } + + if (!mlxcx_cmd_create_tir(mlxp, tir)) { + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + g->mlg_state |= MLXCX_GROUP_TIRTIS; + } + + /* + * Flow table: our RX hashing breakout table for RSS + */ + + g->mlg_rx_hash_ft = (ft = kmem_zalloc(sizeof (mlxcx_flow_table_t), + KM_SLEEP)); + mutex_init(&ft->mlft_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + avl_create(&g->mlg_rx_macs, mlxcx_grmac_compare, + sizeof (mlxcx_group_mac_t), + offsetof(mlxcx_group_mac_t, mlgm_group_entry)); + g->mlg_state |= MLXCX_GROUP_FLOWS; + + mutex_enter(&ft->mlft_mtx); + + ft->mlft_type = MLXCX_FLOW_TABLE_NIC_RX; + ft->mlft_level = 2; + ft->mlft_port = g->mlg_port; + ft->mlft_entshift = MLXCX_RX_HASH_FT_SIZE_SHIFT; + ft->mlft_nents = (1 << ft->mlft_entshift); + ASSERT3U(ft->mlft_nents, >=, MLXCX_TIRS_PER_GROUP); + ft->mlft_entsize = ft->mlft_nents * sizeof (mlxcx_flow_entry_t); + ft->mlft_ent = kmem_zalloc(ft->mlft_entsize, KM_SLEEP); + list_create(&ft->mlft_groups, sizeof (mlxcx_flow_group_t), + offsetof(mlxcx_flow_group_t, mlfg_entry)); + + for (j = 0; j < ft->mlft_nents; ++j) { + ft->mlft_ent[j].mlfe_table = ft; + ft->mlft_ent[j].mlfe_index = j; + } + + if (!mlxcx_cmd_create_flow_table(mlxp, ft)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_IP_VER | MLXCX_FLOW_MATCH_IP_PROTO; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_ip_version = 6; + fe->mlfe_ip_proto = IPPROTO_UDP; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_tir = + &g->mlg_tir[MLXCX_TIR_ROLE_UDPv6]; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_IP_VER | MLXCX_FLOW_MATCH_IP_PROTO; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_ip_version = 4; + fe->mlfe_ip_proto = IPPROTO_UDP; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_tir = + &g->mlg_tir[MLXCX_TIR_ROLE_UDPv4]; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_IP_VER | MLXCX_FLOW_MATCH_IP_PROTO; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_ip_version = 6; + fe->mlfe_ip_proto = IPPROTO_TCP; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_tir = + &g->mlg_tir[MLXCX_TIR_ROLE_TCPv6]; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_IP_VER | MLXCX_FLOW_MATCH_IP_PROTO; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_ip_version = 4; + fe->mlfe_ip_proto = IPPROTO_TCP; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_tir = + &g->mlg_tir[MLXCX_TIR_ROLE_TCPv4]; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_IP_VER; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_ip_version = 6; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_tir = + &g->mlg_tir[MLXCX_TIR_ROLE_IPv6]; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_IP_VER; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_ip_version = 4; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_tir = + &g->mlg_tir[MLXCX_TIR_ROLE_IPv4]; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_tir = + &g->mlg_tir[MLXCX_TIR_ROLE_OTHER]; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + mutex_exit(&ft->mlft_mtx); + + /* + * Flow table: the VLAN breakout table for doing VLAN filtering after + * we've matched a MAC address. + */ + + g->mlg_rx_vlan_ft = (ft = kmem_zalloc(sizeof (mlxcx_flow_table_t), + KM_SLEEP)); + mutex_init(&ft->mlft_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + list_create(&g->mlg_rx_vlans, sizeof (mlxcx_group_vlan_t), + offsetof(mlxcx_group_vlan_t, mlgv_entry)); + + mutex_enter(&ft->mlft_mtx); + + ft->mlft_type = MLXCX_FLOW_TABLE_NIC_RX; + ft->mlft_level = 1; + ft->mlft_port = g->mlg_port; + ft->mlft_entshift = mlxp->mlx_props.mldp_ftbl_vlan_size_shift; + ft->mlft_nents = (1 << ft->mlft_entshift); + ft->mlft_entsize = ft->mlft_nents * sizeof (mlxcx_flow_entry_t); + ft->mlft_ent = kmem_zalloc(ft->mlft_entsize, KM_SLEEP); + list_create(&ft->mlft_groups, sizeof (mlxcx_flow_group_t), + offsetof(mlxcx_flow_group_t, mlfg_entry)); + + for (j = 0; j < ft->mlft_nents; ++j) { + fe = &ft->mlft_ent[j]; + fe->mlfe_table = ft; + fe->mlfe_index = j; + fe->mlfe_action = MLXCX_FLOW_ACTION_FORWARD; + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_flow = g->mlg_rx_hash_ft; + } + + if (!mlxcx_cmd_create_flow_table(mlxp, ft)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + /* First group is all actual matched VLANs */ + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + g->mlg_rx_vlan_fg = fg; + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = ft->mlft_nents - 2; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_VLAN; + fg->mlfg_mask |= MLXCX_FLOW_MATCH_VID; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + /* + * Then the "default" entry which we enable when we have no VLAN IDs + * added to the group (we start with this enabled). + */ + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + g->mlg_rx_vlan_def_fg = fg; + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + /* + * Finally, the promisc entry which points at the *hash ft* from the + * default group. We only enable this when we have promisc on. + */ + fg = kmem_zalloc(sizeof (mlxcx_flow_group_t), KM_SLEEP); + g->mlg_rx_vlan_promisc_fg = fg; + list_insert_tail(&ft->mlft_groups, fg); + fg->mlfg_table = ft; + fg->mlfg_size = 1; + if (!mlxcx_setup_flow_group(mlxp, ft, fg)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + fe = list_head(&fg->mlfg_entries); + fe->mlfe_ndest = 1; + fe->mlfe_dest[0].mlfed_flow = mlxp->mlx_rx_groups[0].mlg_rx_hash_ft; + + mutex_exit(&ft->mlft_mtx); + + mutex_exit(&g->mlg_mtx); + + return (B_TRUE); +} + +boolean_t +mlxcx_rx_ring_start(mlxcx_t *mlxp, mlxcx_ring_group_t *g, + mlxcx_work_queue_t *rq) +{ + uint_t j; + mlxcx_buffer_t *b; + mlxcx_completion_queue_t *cq; + + mutex_enter(&g->mlg_mtx); + /* + * Sadly, even though MAC has the mgi_start callback, it is not always + * called -- in particular when we are being managed under an aggr, the + * mgi_start callback will only ever be called on the default group. + * + * So instead of asserting about the group state here, we have to + * check it and call group start if needed. + */ + if (!(g->mlg_state & MLXCX_GROUP_RUNNING)) { + mutex_exit(&g->mlg_mtx); + if (!mlxcx_rx_group_start(mlxp, g)) + return (B_FALSE); + mutex_enter(&g->mlg_mtx); + } + ASSERT(g->mlg_state & MLXCX_GROUP_RUNNING); + + cq = rq->mlwq_cq; + ASSERT(cq != NULL); + + mutex_enter(&cq->mlcq_mtx); + mutex_enter(&rq->mlwq_mtx); + + if (rq->mlwq_state & MLXCX_WQ_STARTED) { + mutex_exit(&rq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&g->mlg_mtx); + return (B_TRUE); + } + + if (!mlxcx_cmd_start_rq(mlxp, rq)) { + mutex_exit(&rq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + ASSERT(rq->mlwq_state & MLXCX_WQ_STARTED); + + ASSERT0(rq->mlwq_state & MLXCX_WQ_BUFFERS); + rq->mlwq_state |= MLXCX_WQ_BUFFERS; + + for (j = 0; j < rq->mlwq_nents; ++j) { + if (!mlxcx_buf_create(mlxp, rq->mlwq_bufs, &b)) + break; + mlxcx_buf_return(mlxp, b); + } + for (j = 0; j < rq->mlwq_nents / 2; ++j) { + if (!mlxcx_buf_create(mlxp, rq->mlwq_bufs, &b)) + break; + mlxcx_buf_return(mlxp, b); + } + + mlxcx_rq_refill(mlxp, rq); + + mutex_exit(&rq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&g->mlg_mtx); + + return (B_TRUE); +} + +boolean_t +mlxcx_rx_group_start(mlxcx_t *mlxp, mlxcx_ring_group_t *g) +{ + mlxcx_flow_table_t *ft; + mlxcx_flow_group_t *fg; + mlxcx_flow_entry_t *fe; + + mutex_enter(&g->mlg_mtx); + + if (g->mlg_state & MLXCX_GROUP_RUNNING) { + mutex_exit(&g->mlg_mtx); + return (B_TRUE); + } + + ASSERT0(g->mlg_state & MLXCX_GROUP_RUNNING); + + g->mlg_state |= MLXCX_GROUP_RUNNING; + + if (g == &mlxp->mlx_rx_groups[0]) { + ft = g->mlg_port->mlp_rx_flow; + mutex_enter(&ft->mlft_mtx); + + /* + * Broadcast and promisc entries go directly to group 0's + * RSS hash fanout flow table. They bypass VLAN filtering. + */ + fg = g->mlg_port->mlp_bcast; + fe = list_head(&fg->mlfg_entries); + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_flow = g->mlg_rx_hash_ft; + if (!mlxcx_cmd_set_flow_table_entry(mlxp, fe)) { + mutex_exit(&ft->mlft_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + fg = g->mlg_port->mlp_promisc; + fe = list_head(&fg->mlfg_entries); + fe->mlfe_dest[fe->mlfe_ndest++].mlfed_flow = g->mlg_rx_hash_ft; + /* + * Don't actually set the promisc entry until promisc is + * enabled. + */ + + mutex_exit(&ft->mlft_mtx); + } + + mutex_exit(&g->mlg_mtx); + + return (B_TRUE); +} + +boolean_t +mlxcx_tx_group_setup(mlxcx_t *mlxp, mlxcx_ring_group_t *g) +{ + mlxcx_event_queue_t *eq; + mlxcx_completion_queue_t *cq; + mlxcx_work_queue_t *sq; + uint_t i; + + ASSERT3S(g->mlg_state, ==, 0); + + mutex_init(&g->mlg_mtx, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_intr_pri)); + g->mlg_state |= MLXCX_GROUP_INIT; + mutex_enter(&g->mlg_mtx); + + g->mlg_mlx = mlxp; + g->mlg_type = MLXCX_GROUP_TX; + g->mlg_port = &mlxp->mlx_ports[0]; + + g->mlg_nwqs = mlxp->mlx_props.mldp_tx_nrings_per_group; + g->mlg_wqs_size = g->mlg_nwqs * sizeof (mlxcx_work_queue_t); + g->mlg_wqs = kmem_zalloc(g->mlg_wqs_size, KM_SLEEP); + g->mlg_state |= MLXCX_GROUP_WQS; + + g->mlg_tis.mltis_tdom = &mlxp->mlx_tdom; + + if (!mlxcx_cmd_create_tis(mlxp, &g->mlg_tis)) { + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + + g->mlg_state |= MLXCX_GROUP_TIRTIS; + + for (i = 0; i < g->mlg_nwqs; ++i) { + eq = NULL; + while (eq == NULL) { + eq = &mlxp->mlx_eqs[mlxp->mlx_next_eq++]; + if (mlxp->mlx_next_eq >= mlxp->mlx_intr_count) + mlxp->mlx_next_eq = 1; + if (eq->mleq_type != MLXCX_EQ_TYPE_ANY && + eq->mleq_type != MLXCX_EQ_TYPE_TX) { + /* Try the next one */ + eq = NULL; + } + } + + if (!mlxcx_cq_setup(mlxp, eq, &cq)) + return (B_FALSE); + cq->mlcq_stats = &g->mlg_port->mlp_stats; + + sq = &g->mlg_wqs[i]; + if (!mlxcx_sq_setup(mlxp, g->mlg_port, cq, &g->mlg_tis, sq)) { + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + sq->mlwq_group = g; + } + + mutex_exit(&g->mlg_mtx); + + return (B_TRUE); +} + +boolean_t +mlxcx_tx_ring_start(mlxcx_t *mlxp, mlxcx_ring_group_t *g, + mlxcx_work_queue_t *sq) +{ + uint_t i; + mlxcx_buffer_t *b; + mlxcx_completion_queue_t *cq; + + mutex_enter(&g->mlg_mtx); + + cq = sq->mlwq_cq; + ASSERT(cq != NULL); + + mutex_enter(&cq->mlcq_mtx); + mutex_enter(&sq->mlwq_mtx); + if (sq->mlwq_state & MLXCX_WQ_STARTED) { + mutex_exit(&sq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&g->mlg_mtx); + return (B_TRUE); + } + + ASSERT0(sq->mlwq_state & MLXCX_WQ_BUFFERS); + for (i = 0; i < sq->mlwq_nents; ++i) { + if (!mlxcx_buf_create_foreign(mlxp, sq->mlwq_foreign_bufs, &b)) + break; + mlxcx_buf_return(mlxp, b); + } + for (i = 0; i < sq->mlwq_nents / 2; ++i) { + if (!mlxcx_buf_create_foreign(mlxp, sq->mlwq_foreign_bufs, &b)) + break; + mlxcx_buf_return(mlxp, b); + } + for (i = 0; i < sq->mlwq_nents; ++i) { + if (!mlxcx_buf_create(mlxp, sq->mlwq_bufs, &b)) + break; + mlxcx_buf_return(mlxp, b); + } + sq->mlwq_state |= MLXCX_WQ_BUFFERS; + + if (!mlxcx_cmd_start_sq(mlxp, sq)) { + mutex_exit(&sq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&g->mlg_mtx); + return (B_FALSE); + } + g->mlg_state |= MLXCX_GROUP_RUNNING; + + (void) mlxcx_sq_add_nop(mlxp, sq); + + mutex_exit(&sq->mlwq_mtx); + mutex_exit(&cq->mlcq_mtx); + mutex_exit(&g->mlg_mtx); + + return (B_TRUE); +} + +static boolean_t +mlxcx_sq_ring_dbell(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq, uint_t first) +{ + uint_t idx; + mlxcx_bf_t *bf; + ddi_fm_error_t err; + uint_t try = 0; + + ASSERT3U(mlwq->mlwq_type, ==, MLXCX_WQ_TYPE_SENDQ); + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + + mlwq->mlwq_doorbell->mlwqd_send_counter = to_be16(mlwq->mlwq_pc); + + ASSERT(mlwq->mlwq_cq != NULL); + ASSERT(mlwq->mlwq_cq->mlcq_eq != NULL); + idx = mlwq->mlwq_cq->mlcq_eq->mleq_intr_index & MLXCX_BF_PER_UAR_MASK; + bf = &mlwq->mlwq_uar->mlu_bf[idx]; + +retry: + MLXCX_DMA_SYNC(mlwq->mlwq_doorbell_dma, DDI_DMA_SYNC_FORDEV); + ddi_fm_dma_err_get(mlwq->mlwq_doorbell_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + if (try++ < mlxcx_doorbell_tries) { + ddi_fm_dma_err_clear( + mlwq->mlwq_doorbell_dma.mxdb_dma_handle, + DDI_FME_VERSION); + goto retry; + } else { + goto err; + } + } + + mlxcx_put64(mlxp, bf->mbf_even, from_be64( + mlwq->mlwq_bf_ent[first].mlsqbf_qwords[0])); + ddi_fm_acc_err_get(mlxp->mlx_regs_handle, &err, + DDI_FME_VERSION); + if (err.fme_status == DDI_FM_OK) + return (B_TRUE); + if (try++ < mlxcx_doorbell_tries) { + ddi_fm_acc_err_clear(mlxp->mlx_regs_handle, DDI_FME_VERSION); + goto retry; + } + +err: + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_LOST); + return (B_FALSE); +} + +boolean_t +mlxcx_sq_add_nop(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + uint_t index, start_pc; + mlxcx_sendq_ent_t *ent0; + ddi_fm_error_t err; + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + + index = mlwq->mlwq_pc & (mlwq->mlwq_nents - 1); + ent0 = &mlwq->mlwq_send_ent[index]; + start_pc = mlwq->mlwq_pc; + ++mlwq->mlwq_pc; + + bzero(ent0, sizeof (mlxcx_sendq_ent_t)); + ent0->mlsqe_control.mlcs_opcode = MLXCX_WQE_OP_NOP; + ent0->mlsqe_control.mlcs_qp_or_sq = to_be24(mlwq->mlwq_num); + ent0->mlsqe_control.mlcs_wqe_index = to_be16(start_pc); + + set_bits8(&ent0->mlsqe_control.mlcs_flags, + MLXCX_SQE_FENCE_MODE, MLXCX_SQE_FENCE_NONE); + set_bits8(&ent0->mlsqe_control.mlcs_flags, + MLXCX_SQE_COMPLETION_MODE, MLXCX_SQE_CQE_ALWAYS); + + ent0->mlsqe_control.mlcs_ds = 1; + + VERIFY0(ddi_dma_sync(mlwq->mlwq_dma.mxdb_dma_handle, + (uintptr_t)ent0 - (uintptr_t)mlwq->mlwq_send_ent, + sizeof (mlxcx_sendq_ent_t), DDI_DMA_SYNC_FORDEV)); + ddi_fm_dma_err_get(mlwq->mlwq_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + return (B_FALSE); + } + if (!mlxcx_sq_ring_dbell(mlxp, mlwq, index)) { + return (B_FALSE); + } + return (B_TRUE); +} + +boolean_t +mlxcx_sq_add_buffer(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq, + uint8_t *inlinehdrs, size_t inlinelen, uint32_t chkflags, + mlxcx_buffer_t *b0) +{ + uint_t index, first, ents = 0; + mlxcx_completion_queue_t *cq; + mlxcx_sendq_ent_t *ent0; + mlxcx_sendq_extra_ent_t *ent; + mlxcx_wqe_data_seg_t *seg; + uint_t ptri, nptr; + const ddi_dma_cookie_t *c; + size_t rem; + mlxcx_buffer_t *b; + ddi_fm_error_t err; + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + ASSERT3P(b0->mlb_tx_head, ==, b0); + ASSERT3U(b0->mlb_state, ==, MLXCX_BUFFER_ON_WQ); + cq = mlwq->mlwq_cq; + + index = mlwq->mlwq_pc & (mlwq->mlwq_nents - 1); + ent0 = &mlwq->mlwq_send_ent[index]; + b0->mlb_wqe_index = mlwq->mlwq_pc; + ++mlwq->mlwq_pc; + ++ents; + + first = index; + + mutex_enter(&cq->mlcq_bufbmtx); + list_insert_tail(&cq->mlcq_buffers_b, b0); + atomic_inc_64(&cq->mlcq_bufcnt); + mutex_exit(&cq->mlcq_bufbmtx); + + bzero(ent0, sizeof (mlxcx_sendq_ent_t)); + ent0->mlsqe_control.mlcs_opcode = MLXCX_WQE_OP_SEND; + ent0->mlsqe_control.mlcs_qp_or_sq = to_be24(mlwq->mlwq_num); + ent0->mlsqe_control.mlcs_wqe_index = to_be16(b0->mlb_wqe_index); + + set_bits8(&ent0->mlsqe_control.mlcs_flags, + MLXCX_SQE_FENCE_MODE, MLXCX_SQE_FENCE_WAIT_OTHERS); + set_bits8(&ent0->mlsqe_control.mlcs_flags, + MLXCX_SQE_COMPLETION_MODE, MLXCX_SQE_CQE_ALWAYS); + + VERIFY3U(inlinelen, <=, sizeof (ent0->mlsqe_eth.mles_inline_headers)); + set_bits16(&ent0->mlsqe_eth.mles_szflags, + MLXCX_SQE_ETH_INLINE_HDR_SZ, inlinelen); + if (inlinelen > 0) { + bcopy(inlinehdrs, ent0->mlsqe_eth.mles_inline_headers, + inlinelen); + } + + ent0->mlsqe_control.mlcs_ds = + offsetof(mlxcx_sendq_ent_t, mlsqe_data) / 16; + + if (chkflags & HCK_IPV4_HDRCKSUM) { + ASSERT(mlxp->mlx_caps->mlc_checksum); + set_bit8(&ent0->mlsqe_eth.mles_csflags, + MLXCX_SQE_ETH_CSFLAG_L3_CHECKSUM); + } + if (chkflags & HCK_FULLCKSUM) { + ASSERT(mlxp->mlx_caps->mlc_checksum); + set_bit8(&ent0->mlsqe_eth.mles_csflags, + MLXCX_SQE_ETH_CSFLAG_L4_CHECKSUM); + } + + b = b0; + ptri = 0; + nptr = sizeof (ent0->mlsqe_data) / sizeof (mlxcx_wqe_data_seg_t); + seg = ent0->mlsqe_data; + while (b != NULL) { + rem = b->mlb_used; + + c = NULL; + while (rem > 0 && + (c = mlxcx_dma_cookie_iter(&b->mlb_dma, c)) != NULL) { + if (ptri >= nptr) { + index = mlwq->mlwq_pc & (mlwq->mlwq_nents - 1); + ent = &mlwq->mlwq_send_extra_ent[index]; + ++mlwq->mlwq_pc; + ++ents; + + seg = ent->mlsqe_data; + ptri = 0; + nptr = sizeof (ent->mlsqe_data) / + sizeof (mlxcx_wqe_data_seg_t); + } + + seg->mlds_lkey = to_be32(mlxp->mlx_rsvd_lkey); + if (c->dmac_size > rem) { + seg->mlds_byte_count = to_be32(rem); + rem = 0; + } else { + seg->mlds_byte_count = to_be32(c->dmac_size); + rem -= c->dmac_size; + } + seg->mlds_address = to_be64(c->dmac_laddress); + ++seg; + ++ptri; + ++ent0->mlsqe_control.mlcs_ds; + + ASSERT3U(ent0->mlsqe_control.mlcs_ds, <=, + MLXCX_SQE_MAX_DS); + } + + if (b == b0) { + b = list_head(&b0->mlb_tx_chain); + } else { + b = list_next(&b0->mlb_tx_chain, b); + } + } + + for (; ptri < nptr; ++ptri, ++seg) { + seg->mlds_lkey = to_be32(MLXCX_NULL_LKEY); + seg->mlds_byte_count = to_be32(0); + seg->mlds_address = to_be64(0); + } + + /* + * Make sure the workqueue entry is flushed out before updating + * the doorbell. + */ + VERIFY0(ddi_dma_sync(mlwq->mlwq_dma.mxdb_dma_handle, + (uintptr_t)ent0 - (uintptr_t)mlwq->mlwq_send_ent, + ents * sizeof (mlxcx_sendq_ent_t), DDI_DMA_SYNC_FORDEV)); + ddi_fm_dma_err_get(mlwq->mlwq_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + return (B_FALSE); + } + if (!mlxcx_sq_ring_dbell(mlxp, mlwq, first)) { + return (B_FALSE); + } + return (B_TRUE); +} + +boolean_t +mlxcx_rq_add_buffer(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq, + mlxcx_buffer_t *buf) +{ + return (mlxcx_rq_add_buffers(mlxp, mlwq, &buf, 1)); +} + +boolean_t +mlxcx_rq_add_buffers(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq, + mlxcx_buffer_t **bufs, size_t nbufs) +{ + uint_t index; + mlxcx_recvq_ent_t *ent; + mlxcx_completion_queue_t *cq; + mlxcx_wqe_data_seg_t *seg; + uint_t bi, ptri; + const ddi_dma_cookie_t *c; + mlxcx_buffer_t *buf; + ddi_fm_error_t err; + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + cq = mlwq->mlwq_cq; + ASSERT(mutex_owned(&cq->mlcq_mtx)); + + for (bi = 0; bi < nbufs; ++bi) { + buf = bufs[bi]; + bufs[bi] = NULL; + ASSERT3U(buf->mlb_state, ==, MLXCX_BUFFER_ON_WQ); + + index = mlwq->mlwq_pc & (mlwq->mlwq_nents - 1); + ent = &mlwq->mlwq_recv_ent[index]; + buf->mlb_wqe_index = mlwq->mlwq_pc; + + ++mlwq->mlwq_pc; + + mutex_enter(&cq->mlcq_bufbmtx); + list_insert_tail(&cq->mlcq_buffers, buf); + atomic_inc_64(&cq->mlcq_bufcnt); + mutex_exit(&cq->mlcq_bufbmtx); + + ASSERT3U(buf->mlb_dma.mxdb_ncookies, <=, MLXCX_RECVQ_MAX_PTRS); + ptri = 0; + c = NULL; + while ((c = mlxcx_dma_cookie_iter(&buf->mlb_dma, c)) != NULL) { + seg = &ent->mlrqe_data[ptri++]; + seg->mlds_lkey = to_be32(mlxp->mlx_rsvd_lkey); + seg->mlds_byte_count = to_be32(c->dmac_size); + seg->mlds_address = to_be64(c->dmac_laddress); + } + /* + * Fill any unused scatter pointers with the special null + * value. + */ + for (; ptri < MLXCX_RECVQ_MAX_PTRS; ++ptri) { + seg = &ent->mlrqe_data[ptri]; + seg->mlds_lkey = to_be32(MLXCX_NULL_LKEY); + seg->mlds_byte_count = to_be32(0); + seg->mlds_address = to_be64(0); + } + + /* + * Make sure the workqueue entry is flushed out before updating + * the doorbell. + */ + VERIFY0(ddi_dma_sync(mlwq->mlwq_dma.mxdb_dma_handle, + (uintptr_t)ent - (uintptr_t)mlwq->mlwq_recv_ent, + sizeof (mlxcx_recvq_ent_t), DDI_DMA_SYNC_FORDEV)); + ddi_fm_dma_err_get(mlwq->mlwq_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + return (B_FALSE); + } + } + + mlwq->mlwq_doorbell->mlwqd_recv_counter = to_be16(mlwq->mlwq_pc); + /* + * Flush the CQ doorbell as well so that HW knows how many + * completions we've consumed. + */ + MLXCX_DMA_SYNC(cq->mlcq_doorbell_dma, DDI_DMA_SYNC_FORDEV); + ddi_fm_dma_err_get(cq->mlcq_doorbell_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + return (B_FALSE); + } + MLXCX_DMA_SYNC(mlwq->mlwq_doorbell_dma, DDI_DMA_SYNC_FORDEV); + ddi_fm_dma_err_get(mlwq->mlwq_doorbell_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + return (B_FALSE); + } + return (B_TRUE); +} + +void +mlxcx_rq_refill(mlxcx_t *mlxp, mlxcx_work_queue_t *mlwq) +{ + size_t target, current, want, done, n; + mlxcx_completion_queue_t *cq; + mlxcx_buffer_t *b[MLXCX_RQ_REFILL_STEP]; + uint_t i; + + ASSERT(mutex_owned(&mlwq->mlwq_mtx)); + cq = mlwq->mlwq_cq; + ASSERT(mutex_owned(&cq->mlcq_mtx)); + + ASSERT(mlwq->mlwq_state & MLXCX_WQ_BUFFERS); + + target = mlwq->mlwq_nents - MLXCX_RQ_REFILL_STEP; + cq = mlwq->mlwq_cq; + + if (cq->mlcq_state & MLXCX_CQ_TEARDOWN) + return; + + current = cq->mlcq_bufcnt; + + if (current >= target - MLXCX_RQ_REFILL_STEP) + return; + + want = target - current; + done = 0; + + while (!(mlwq->mlwq_state & MLXCX_WQ_TEARDOWN) && done < want) { + n = mlxcx_buf_take_n(mlxp, mlwq, b, MLXCX_RQ_REFILL_STEP); + if (n == 0) { + mlxcx_warn(mlxp, "!exiting rq refill early, done %u " + "but wanted %u", done, want); + return; + } + if (mlwq->mlwq_state & MLXCX_WQ_TEARDOWN) { + for (i = 0; i < n; ++i) + mlxcx_buf_return(mlxp, b[i]); + return; + } + if (!mlxcx_rq_add_buffers(mlxp, mlwq, b, n)) { + /* + * mlxcx_rq_add_buffers NULLs out the buffers as it + * enqueues them, so any that are non-NULL we have to + * free now. The others now belong to the WQ, even if + * we failed. + */ + for (i = 0; i < n; ++i) { + if (b[i] != NULL) { + mlxcx_buf_return(mlxp, b[i]); + } + } + return; + } + done += n; + } +} + +static const char * +mlxcx_cq_err_syndrome_string(mlxcx_cq_error_syndrome_t sy) +{ + switch (sy) { + case MLXCX_CQ_ERR_LOCAL_LENGTH: + return ("LOCAL_LENGTH"); + case MLXCX_CQ_ERR_LOCAL_QP_OP: + return ("LOCAL_QP_OP"); + case MLXCX_CQ_ERR_LOCAL_PROTECTION: + return ("LOCAL_PROTECTION"); + case MLXCX_CQ_ERR_WR_FLUSHED: + return ("WR_FLUSHED"); + case MLXCX_CQ_ERR_MEM_WINDOW_BIND: + return ("MEM_WINDOW_BIND"); + case MLXCX_CQ_ERR_BAD_RESPONSE: + return ("BAD_RESPONSE"); + case MLXCX_CQ_ERR_LOCAL_ACCESS: + return ("LOCAL_ACCESS"); + case MLXCX_CQ_ERR_XPORT_RETRY_CTR: + return ("XPORT_RETRY_CTR"); + case MLXCX_CQ_ERR_RNR_RETRY_CTR: + return ("RNR_RETRY_CTR"); + case MLXCX_CQ_ERR_ABORTED: + return ("ABORTED"); + default: + return ("UNKNOWN"); + } +} + +static void +mlxcx_fm_cqe_ereport(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq, + mlxcx_completionq_error_ent_t *ent) +{ + uint64_t ena; + char buf[FM_MAX_CLASS]; + const char *name = mlxcx_cq_err_syndrome_string(ent->mlcqee_syndrome); + + if (!DDI_FM_EREPORT_CAP(mlxp->mlx_fm_caps)) + return; + + (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", + MLXCX_FM_SERVICE_MLXCX, "cqe.err"); + ena = fm_ena_generate(0, FM_ENA_FMT1); + + ddi_fm_ereport_post(mlxp->mlx_dip, buf, ena, DDI_NOSLEEP, + FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, + "syndrome", DATA_TYPE_STRING, name, + "syndrome_num", DATA_TYPE_UINT8, ent->mlcqee_syndrome, + "vendor_syndrome", DATA_TYPE_UINT8, + ent->mlcqee_vendor_error_syndrome, + "wqe_counter", DATA_TYPE_UINT16, from_be16(ent->mlcqee_wqe_counter), + "wq_type", DATA_TYPE_STRING, + (mlcq->mlcq_wq->mlwq_type == MLXCX_WQ_TYPE_SENDQ) ? "send": "recv", + "cq_num", DATA_TYPE_UINT32, mlcq->mlcq_num, + "wq_num", DATA_TYPE_UINT32, mlcq->mlcq_wq->mlwq_num, + NULL); + ddi_fm_service_impact(mlxp->mlx_dip, DDI_SERVICE_DEGRADED); +} + +void +mlxcx_tx_completion(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq, + mlxcx_completionq_ent_t *ent, mlxcx_buffer_t *buf) +{ + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + if (ent->mlcqe_opcode == MLXCX_CQE_OP_REQ_ERR) { + mlxcx_completionq_error_ent_t *eent = + (mlxcx_completionq_error_ent_t *)ent; + mlxcx_fm_cqe_ereport(mlxp, mlcq, eent); + mlxcx_buf_return_chain(mlxp, buf, B_FALSE); + mutex_enter(&mlcq->mlcq_wq->mlwq_mtx); + mlxcx_check_sq(mlxp, mlcq->mlcq_wq); + mutex_exit(&mlcq->mlcq_wq->mlwq_mtx); + return; + } + + if (ent->mlcqe_opcode != MLXCX_CQE_OP_REQ) { + mlxcx_warn(mlxp, "!got weird cq opcode: %x", ent->mlcqe_opcode); + mlxcx_buf_return_chain(mlxp, buf, B_FALSE); + return; + } + + if (ent->mlcqe_send_wqe_opcode != MLXCX_WQE_OP_SEND) { + mlxcx_warn(mlxp, "!got weird cq wqe opcode: %x", + ent->mlcqe_send_wqe_opcode); + mlxcx_buf_return_chain(mlxp, buf, B_FALSE); + return; + } + + if (ent->mlcqe_format != MLXCX_CQE_FORMAT_BASIC) { + mlxcx_warn(mlxp, "!got weird cq format: %x", ent->mlcqe_format); + mlxcx_buf_return_chain(mlxp, buf, B_FALSE); + return; + } + + mlxcx_buf_return_chain(mlxp, buf, B_FALSE); +} + +mblk_t * +mlxcx_rx_completion(mlxcx_t *mlxp, mlxcx_completion_queue_t *mlcq, + mlxcx_completionq_ent_t *ent, mlxcx_buffer_t *buf) +{ + uint32_t chkflags = 0; + ddi_fm_error_t err; + + ASSERT(mutex_owned(&mlcq->mlcq_mtx)); + + if (ent->mlcqe_opcode == MLXCX_CQE_OP_RESP_ERR) { + mlxcx_completionq_error_ent_t *eent = + (mlxcx_completionq_error_ent_t *)ent; + mlxcx_fm_cqe_ereport(mlxp, mlcq, eent); + mlxcx_buf_return(mlxp, buf); + mutex_enter(&mlcq->mlcq_wq->mlwq_mtx); + mlxcx_check_rq(mlxp, mlcq->mlcq_wq); + mutex_exit(&mlcq->mlcq_wq->mlwq_mtx); + return (NULL); + } + + if (ent->mlcqe_opcode != MLXCX_CQE_OP_RESP) { + mlxcx_warn(mlxp, "!got weird cq opcode: %x", ent->mlcqe_opcode); + mlxcx_buf_return(mlxp, buf); + return (NULL); + } + + if (ent->mlcqe_format != MLXCX_CQE_FORMAT_BASIC) { + mlxcx_warn(mlxp, "!got weird cq format: %x", ent->mlcqe_format); + mlxcx_buf_return(mlxp, buf); + return (NULL); + } + + if (ent->mlcqe_rx_drop_counter > 0) { + atomic_add_64(&mlcq->mlcq_stats->mlps_rx_drops, + ent->mlcqe_rx_drop_counter); + } + + MLXCX_DMA_SYNC(buf->mlb_dma, DDI_DMA_SYNC_FORCPU); + ddi_fm_dma_err_get(buf->mlb_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + ddi_fm_dma_err_clear(buf->mlb_dma.mxdb_dma_handle, + DDI_FME_VERSION); + mlxcx_buf_return(mlxp, buf); + return (NULL); + } + + if (!mlxcx_buf_loan(mlxp, buf)) { + mlxcx_warn(mlxp, "!loan failed, dropping packet"); + mlxcx_buf_return(mlxp, buf); + return (NULL); + } + + buf->mlb_mp->b_next = NULL; + buf->mlb_mp->b_cont = NULL; + buf->mlb_mp->b_wptr = buf->mlb_mp->b_rptr + + from_be32(ent->mlcqe_byte_cnt); + + if (get_bit8(ent->mlcqe_csflags, MLXCX_CQE_CSFLAGS_L4_OK)) { + chkflags |= HCK_FULLCKSUM_OK; + } + if (get_bit8(ent->mlcqe_csflags, MLXCX_CQE_CSFLAGS_L3_OK)) { + chkflags |= HCK_IPV4_HDRCKSUM_OK; + } + if (chkflags != 0) { + mac_hcksum_set(buf->mlb_mp, 0, 0, 0, + from_be16(ent->mlcqe_checksum), chkflags); + } + + /* + * Don't check if a refill is needed on every single completion, + * since checking involves taking the RQ lock. + */ + if ((buf->mlb_wqe_index & 0x7) == 0) { + mlxcx_work_queue_t *wq = mlcq->mlcq_wq; + ASSERT(wq != NULL); + mutex_enter(&wq->mlwq_mtx); + if (!(wq->mlwq_state & MLXCX_WQ_TEARDOWN)) + mlxcx_rq_refill(mlxp, wq); + mutex_exit(&wq->mlwq_mtx); + } + + return (buf->mlb_mp); +} + +static void +mlxcx_buf_mp_return(caddr_t arg) +{ + mlxcx_buffer_t *b = (mlxcx_buffer_t *)arg; + mlxcx_t *mlxp = b->mlb_mlx; + + if (b->mlb_state != MLXCX_BUFFER_ON_LOAN) { + b->mlb_mp = NULL; + return; + } + /* + * The mblk for this buffer_t (in its mlb_mp field) has been used now, + * so NULL it out. + */ + b->mlb_mp = NULL; + mlxcx_buf_return(mlxp, b); +} + +boolean_t +mlxcx_buf_create(mlxcx_t *mlxp, mlxcx_buf_shard_t *shard, mlxcx_buffer_t **bp) +{ + mlxcx_buffer_t *b; + ddi_device_acc_attr_t acc; + ddi_dma_attr_t attr; + boolean_t ret; + + b = kmem_cache_alloc(mlxp->mlx_bufs_cache, KM_SLEEP); + b->mlb_shard = shard; + b->mlb_foreign = B_FALSE; + + mlxcx_dma_acc_attr(mlxp, &acc); + mlxcx_dma_buf_attr(mlxp, &attr); + + ret = mlxcx_dma_alloc_offset(mlxp, &b->mlb_dma, &attr, &acc, + B_FALSE, mlxp->mlx_ports[0].mlp_mtu, 2, B_TRUE); + if (!ret) { + kmem_cache_free(mlxp->mlx_bufs_cache, b); + return (B_FALSE); + } + + b->mlb_frtn.free_func = mlxcx_buf_mp_return; + b->mlb_frtn.free_arg = (caddr_t)b; + b->mlb_mp = desballoc((unsigned char *)b->mlb_dma.mxdb_va, + b->mlb_dma.mxdb_len, 0, &b->mlb_frtn); + + *bp = b; + + return (B_TRUE); +} + +boolean_t +mlxcx_buf_create_foreign(mlxcx_t *mlxp, mlxcx_buf_shard_t *shard, + mlxcx_buffer_t **bp) +{ + mlxcx_buffer_t *b; + ddi_dma_attr_t attr; + boolean_t ret; + + b = kmem_cache_alloc(mlxp->mlx_bufs_cache, KM_SLEEP); + b->mlb_shard = shard; + b->mlb_foreign = B_TRUE; + + mlxcx_dma_buf_attr(mlxp, &attr); + + ret = mlxcx_dma_init(mlxp, &b->mlb_dma, &attr, B_TRUE); + if (!ret) { + kmem_cache_free(mlxp->mlx_bufs_cache, b); + return (B_FALSE); + } + + *bp = b; + + return (B_TRUE); +} + +static void +mlxcx_buf_take_foreign(mlxcx_t *mlxp, mlxcx_work_queue_t *wq, + mlxcx_buffer_t **bp) +{ + mlxcx_buffer_t *b; + mlxcx_buf_shard_t *s = wq->mlwq_foreign_bufs; + + mutex_enter(&s->mlbs_mtx); + while (list_is_empty(&s->mlbs_free)) + cv_wait(&s->mlbs_free_nonempty, &s->mlbs_mtx); + b = list_remove_head(&s->mlbs_free); + ASSERT3U(b->mlb_state, ==, MLXCX_BUFFER_FREE); + ASSERT(b->mlb_foreign); + b->mlb_state = MLXCX_BUFFER_ON_WQ; + list_insert_tail(&s->mlbs_busy, b); + mutex_exit(&s->mlbs_mtx); + + *bp = b; +} + +boolean_t +mlxcx_buf_bind_or_copy(mlxcx_t *mlxp, mlxcx_work_queue_t *wq, + mblk_t *mpb, size_t off, mlxcx_buffer_t **bp) +{ + mlxcx_buffer_t *b, *b0 = NULL; + boolean_t first = B_TRUE; + ddi_fm_error_t err; + mblk_t *mp; + uint8_t *rptr; + size_t sz; + size_t ncookies = 0; + boolean_t ret; + uint_t attempts = 0; + + for (mp = mpb; mp != NULL; mp = mp->b_cont) { + rptr = mp->b_rptr; + sz = MBLKL(mp); + + if (off > 0) + ASSERT3U(off, <, sz); + rptr += off; + sz -= off; + + if (sz < mlxp->mlx_props.mldp_tx_bind_threshold) + goto copyb; + + mlxcx_buf_take_foreign(mlxp, wq, &b); + ret = mlxcx_dma_bind_mblk(mlxp, &b->mlb_dma, mp, off, B_FALSE); + + if (!ret) { + mlxcx_buf_return(mlxp, b); + +copyb: + mlxcx_buf_take(mlxp, wq, &b); + ASSERT3U(b->mlb_dma.mxdb_len, >=, sz); + bcopy(rptr, b->mlb_dma.mxdb_va, sz); + MLXCX_DMA_SYNC(b->mlb_dma, DDI_DMA_SYNC_FORDEV); + ddi_fm_dma_err_get(b->mlb_dma.mxdb_dma_handle, &err, + DDI_FME_VERSION); + if (err.fme_status != DDI_FM_OK) { + ddi_fm_dma_err_clear(b->mlb_dma.mxdb_dma_handle, + DDI_FME_VERSION); + mlxcx_buf_return(mlxp, b); + if (++attempts > MLXCX_BUF_BIND_MAX_ATTEMTPS) { + *bp = NULL; + return (B_FALSE); + } + goto copyb; + } + } + + /* + * We might overestimate here when we've copied data, since + * the buffer might be longer than what we copied into it. This + * is safe since it's always wrong in the conservative + * direction (and we will blow up later when we actually + * generate the WQE anyway). + * + * If the assert below ever blows, we'll have to come and fix + * this up so we can transmit these packets. + */ + ncookies += b->mlb_dma.mxdb_ncookies; + + if (first) + b0 = b; + + if (!first) + b->mlb_state = MLXCX_BUFFER_ON_CHAIN; + + b->mlb_tx_mp = mp; + b->mlb_tx_head = b0; + b->mlb_used = sz; + + if (!first) + list_insert_tail(&b0->mlb_tx_chain, b); + first = B_FALSE; + off = 0; + } + + ASSERT3U(ncookies, <=, MLXCX_SQE_MAX_PTRS); + + *bp = b0; + return (B_TRUE); +} + +void +mlxcx_buf_take(mlxcx_t *mlxp, mlxcx_work_queue_t *wq, mlxcx_buffer_t **bp) +{ + mlxcx_buffer_t *b; + mlxcx_buf_shard_t *s = wq->mlwq_bufs; + + mutex_enter(&s->mlbs_mtx); + while (list_is_empty(&s->mlbs_free)) + cv_wait(&s->mlbs_free_nonempty, &s->mlbs_mtx); + b = list_remove_head(&s->mlbs_free); + ASSERT3U(b->mlb_state, ==, MLXCX_BUFFER_FREE); + b->mlb_state = MLXCX_BUFFER_ON_WQ; + list_insert_tail(&s->mlbs_busy, b); + mutex_exit(&s->mlbs_mtx); + + *bp = b; +} + +#define MLXCX_BUF_TAKE_N_TIMEOUT_USEC 5000 +#define MLXCX_BUF_TAKE_N_MAX_RETRIES 3 + +size_t +mlxcx_buf_take_n(mlxcx_t *mlxp, mlxcx_work_queue_t *wq, + mlxcx_buffer_t **bp, size_t nbufs) +{ + mlxcx_buffer_t *b; + size_t done = 0, empty = 0; + clock_t wtime = drv_usectohz(MLXCX_BUF_TAKE_N_TIMEOUT_USEC); + mlxcx_buf_shard_t *s; + + s = wq->mlwq_bufs; + + mutex_enter(&s->mlbs_mtx); + while (done < nbufs) { + while (list_is_empty(&s->mlbs_free)) { + (void) cv_reltimedwait(&s->mlbs_free_nonempty, + &s->mlbs_mtx, wtime, TR_MILLISEC); + if (list_is_empty(&s->mlbs_free) && + empty++ >= MLXCX_BUF_TAKE_N_MAX_RETRIES) { + mutex_exit(&s->mlbs_mtx); + return (done); + } + } + b = list_remove_head(&s->mlbs_free); + ASSERT3U(b->mlb_state, ==, MLXCX_BUFFER_FREE); + b->mlb_state = MLXCX_BUFFER_ON_WQ; + list_insert_tail(&s->mlbs_busy, b); + bp[done++] = b; + } + mutex_exit(&s->mlbs_mtx); + return (done); +} + +boolean_t +mlxcx_buf_loan(mlxcx_t *mlxp, mlxcx_buffer_t *b) +{ + VERIFY3U(b->mlb_state, ==, MLXCX_BUFFER_ON_WQ); + ASSERT3P(b->mlb_mlx, ==, mlxp); + + if (b->mlb_mp == NULL) { + b->mlb_mp = desballoc((unsigned char *)b->mlb_dma.mxdb_va, + b->mlb_dma.mxdb_len, 0, &b->mlb_frtn); + if (b->mlb_mp == NULL) + return (B_FALSE); + } + + b->mlb_state = MLXCX_BUFFER_ON_LOAN; + b->mlb_wqe_index = 0; + return (B_TRUE); +} + +void +mlxcx_buf_return_chain(mlxcx_t *mlxp, mlxcx_buffer_t *b0, boolean_t keepmp) +{ + mlxcx_buffer_t *b; + + if (b0->mlb_tx_head != b0) { + mlxcx_buf_return(mlxp, b0); + return; + } + + while ((b = list_head(&b0->mlb_tx_chain)) != NULL) { + mlxcx_buf_return(mlxp, b); + } + if (keepmp) { + b0->mlb_tx_mp = NULL; + b0->mlb_tx_head = NULL; + } + mlxcx_buf_return(mlxp, b0); +} + +void +mlxcx_buf_return(mlxcx_t *mlxp, mlxcx_buffer_t *b) +{ + mlxcx_buffer_state_t oldstate = b->mlb_state; + mlxcx_buffer_t *txhead = b->mlb_tx_head; + mlxcx_buf_shard_t *s = b->mlb_shard; + mblk_t *mp = b->mlb_tx_mp; + + VERIFY3U(oldstate, !=, MLXCX_BUFFER_FREE); + ASSERT3P(b->mlb_mlx, ==, mlxp); + b->mlb_state = MLXCX_BUFFER_FREE; + b->mlb_wqe_index = 0; + b->mlb_tx_head = NULL; + b->mlb_tx_mp = NULL; + b->mlb_used = 0; + ASSERT(list_is_empty(&b->mlb_tx_chain)); + + mutex_enter(&s->mlbs_mtx); + switch (oldstate) { + case MLXCX_BUFFER_INIT: + break; + case MLXCX_BUFFER_ON_WQ: + list_remove(&s->mlbs_busy, b); + break; + case MLXCX_BUFFER_ON_LOAN: + ASSERT(!b->mlb_foreign); + list_remove(&s->mlbs_busy, b); + break; + case MLXCX_BUFFER_FREE: + VERIFY(0); + break; + case MLXCX_BUFFER_ON_CHAIN: + ASSERT(txhead != NULL); + list_remove(&txhead->mlb_tx_chain, b); + list_remove(&s->mlbs_busy, b); + break; + } + + if (b->mlb_foreign) { + if (b->mlb_dma.mxdb_flags & MLXCX_DMABUF_BOUND) { + mlxcx_dma_unbind(mlxp, &b->mlb_dma); + } + } + + list_insert_tail(&s->mlbs_free, b); + cv_signal(&s->mlbs_free_nonempty); + + mutex_exit(&s->mlbs_mtx); + + /* + * For TX chain heads, free the mblk_t after we let go of the lock. + * This might be a borrowed buf that we in turn loaned to MAC, in which + * case calling freemsg() on it will re-enter this very function -- so + * we better not be holding the lock! + */ + if (txhead == b) + freemsg(mp); +} + +void +mlxcx_buf_destroy(mlxcx_t *mlxp, mlxcx_buffer_t *b) +{ + mlxcx_buf_shard_t *s = b->mlb_shard; + VERIFY(b->mlb_state == MLXCX_BUFFER_FREE || + b->mlb_state == MLXCX_BUFFER_INIT); + ASSERT(mutex_owned(&s->mlbs_mtx)); + if (b->mlb_state == MLXCX_BUFFER_FREE) + list_remove(&s->mlbs_free, b); + + /* + * This is going back to the kmem cache, so it needs to be set up in + * the same way we expect a new buffer to come out (state INIT, other + * fields NULL'd) + */ + b->mlb_state = MLXCX_BUFFER_INIT; + b->mlb_shard = NULL; + if (b->mlb_mp != NULL) { + freeb(b->mlb_mp); + ASSERT(b->mlb_mp == NULL); + } + mlxcx_dma_free(&b->mlb_dma); + ASSERT(list_is_empty(&b->mlb_tx_chain)); + + kmem_cache_free(mlxp->mlx_bufs_cache, b); +} diff --git a/usr/src/uts/common/io/ptm.c b/usr/src/uts/common/io/ptm.c index 4d24932269..d4dfe83766 100644 --- a/usr/src/uts/common/io/ptm.c +++ b/usr/src/uts/common/io/ptm.c @@ -24,7 +24,9 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ - +/* + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ /* * Pseudo Terminal Master Driver. @@ -533,6 +535,13 @@ ptmwput(queue_t *qp, mblk_t *mp) DBG(("ack the UNLKPT/ISPTM\n")); miocack(qp, mp, 0, 0); break; + case PTSSTTY: + mutex_enter(&ptmp->pt_lock); + ptmp->pt_state |= PTSTTY; + mutex_exit(&ptmp->pt_lock); + DBG(("ack PTSSTTY\n")); + miocack(qp, mp, 0, 0); + break; case ZONEPT: { zoneid_t z; diff --git a/usr/src/uts/common/io/pts.c b/usr/src/uts/common/io/pts.c index d67beb255a..ff2d91f566 100644 --- a/usr/src/uts/common/io/pts.c +++ b/usr/src/uts/common/io/pts.c @@ -25,7 +25,9 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ - +/* + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ /* * Pseudo Terminal Slave Driver. @@ -106,6 +108,7 @@ #include <sys/sysmacros.h> #include <sys/stream.h> #include <sys/stropts.h> +#include <sys/strsubr.h> #include <sys/stat.h> #include <sys/errno.h> #include <sys/debug.h> @@ -337,7 +340,6 @@ ptsopen( DDBGP("ptsopen: p = %p\n", (uintptr_t)ptsp); DDBG("ptsopen: state = %x\n", ptsp->pt_state); - ASSERT(ptsp->pt_minor == dminor); if ((ptsp->pt_state & PTLOCK) || !(ptsp->pt_state & PTMOPEN)) { @@ -347,7 +349,7 @@ ptsopen( } /* - * if already, open simply return... + * if already open, simply return... */ if (ptsp->pt_state & PTSOPEN) { ASSERT(rqp->q_ptr == ptsp); @@ -386,6 +388,9 @@ ptsopen( mutex_exit(&ptsp->pt_lock); mutex_exit(&ptms_lock); + if (ptsp->pt_state & PTSTTY) + STREAM(rqp)->sd_flag |= STRXPG4TTY; + qprocson(rqp); /* @@ -416,8 +421,6 @@ ptsopen( return (0); } - - /* * Find the address to private data identifying the slave's write * queue. Send a 0-length msg up the slave's read queue to designate diff --git a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c index 0e342e8bcc..721aead599 100644 --- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c +++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c @@ -1432,6 +1432,7 @@ ahci_tran_probe_port(dev_info_t *dip, sata_device_t *sd) uint8_t port; int rval = SATA_SUCCESS, rval_init; + port_state = 0; ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip)); port = ahci_ctlp->ahcictl_cport_to_port[cport]; @@ -1996,6 +1997,7 @@ ahci_claim_free_slot(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, ahci_portp->ahciport_pending_tags, ahci_portp->ahciport_pending_ncq_tags); + free_slots = 0; /* * According to the AHCI spec, system software is responsible to * ensure that queued and non-queued commands are not mixed in @@ -9837,6 +9839,8 @@ ahci_watchdog_handler(ahci_ctl_t *ahci_ctlp) AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_watchdog_handler entered", NULL); + current_slot = 0; + current_tags = 0; for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) { if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) { continue; diff --git a/usr/src/uts/common/io/vnic/vnic_dev.c b/usr/src/uts/common/io/vnic/vnic_dev.c index e532a551e7..d75db5f258 100644 --- a/usr/src/uts/common/io/vnic/vnic_dev.c +++ b/usr/src/uts/common/io/vnic/vnic_dev.c @@ -22,6 +22,7 @@ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2018 Joyent, Inc. * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #include <sys/types.h> @@ -198,7 +199,7 @@ vnic_unicast_add(vnic_t *vnic, vnic_mac_addr_type_t vnic_addr_type, uint8_t *mac_addr_arg, uint16_t flags, vnic_ioc_diag_t *diag, uint16_t vid, boolean_t req_hwgrp_flag) { - mac_diag_t mac_diag; + mac_diag_t mac_diag = MAC_DIAG_NONE; uint16_t mac_flags = 0; int err; uint_t addr_len; @@ -1060,7 +1061,7 @@ static int vnic_m_setprop(void *m_driver, const char *pr_name, mac_prop_id_t pr_num, uint_t pr_valsize, const void *pr_val) { - int err = 0; + int err = 0; vnic_t *vn = m_driver; switch (pr_num) { @@ -1158,7 +1159,7 @@ vnic_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, uint_t pr_valsize, void *pr_val) { vnic_t *vn = arg; - int ret = 0; + int ret = 0; boolean_t out; switch (pr_num) { diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c index 1a1a734d5f..866fd3fc2c 100644 --- a/usr/src/uts/common/os/streamio.c +++ b/usr/src/uts/common/os/streamio.c @@ -25,7 +25,7 @@ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2017 Joyent, Inc. - * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #include <sys/types.h> @@ -79,6 +79,7 @@ #include <sys/dld.h> #include <sys/zone.h> #include <sys/limits.h> +#include <sys/ptms.h> #include <c2/audit.h> /* @@ -232,6 +233,50 @@ push_mod(queue_t *qp, dev_t *devp, struct stdata *stp, const char *name, return (0); } +static int +xpg4_fixup(queue_t *qp, dev_t *devp, struct stdata *stp, cred_t *crp) +{ + static const char *ptsmods[] = { + "ptem", "ldterm", "ttcompat" + }; + dev_t dummydev = *devp; + struct strioctl strioc; + zoneid_t zoneid; + int32_t rval; + uint_t i; + + /* + * Push modules required for the slave PTY to have terminal + * semantics out of the box; this is required by XPG4v2. + * These three modules are flagged as single-instance so that + * the system will never end up with duplicate copies pushed + * onto a stream. + */ + + zoneid = crgetzoneid(crp); + for (i = 0; i < ARRAY_SIZE(ptsmods); i++) { + int error; + + error = push_mod(qp, &dummydev, stp, ptsmods[i], 0, + crp, zoneid); + if (error != 0) + return (error); + } + + /* + * Send PTSSTTY down the stream + */ + + strioc.ic_cmd = PTSSTTY; + strioc.ic_timout = 0; + strioc.ic_len = 0; + strioc.ic_dp = NULL; + + (void) strdoioctl(stp, &strioc, FNATIVE, K_TO_K, crp, &rval); + + return (0); +} + /* * Open a stream device. */ @@ -550,10 +595,15 @@ retryap: opendone: + if (error == 0 && + (stp->sd_flag & (STRISTTY|STRXPG4TTY)) == (STRISTTY|STRXPG4TTY)) { + error = xpg4_fixup(qp, devp, stp, crp); + } + /* * let specfs know that open failed part way through */ - if (error) { + if (error != 0) { mutex_enter(&stp->sd_lock); stp->sd_flag |= STREOPENFAIL; mutex_exit(&stp->sd_lock); diff --git a/usr/src/uts/common/sys/fm/io/ddi.h b/usr/src/uts/common/sys/fm/io/ddi.h index 75afff5c38..d8c772cdaf 100644 --- a/usr/src/uts/common/sys/fm/io/ddi.h +++ b/usr/src/uts/common/sys/fm/io/ddi.h @@ -66,6 +66,17 @@ extern "C" { #define DVR_STACK_DEPTH "dvr-stack-depth" #define DVR_ERR_SPECIFIC "dvr-error-specific" +/* Generic NIC driver ereports. */ +#define DDI_FM_NIC "nic" +#define DDI_FM_TXR_ERROR "txr-err" + +/* Valid values of the "error" field in txr-err ereports */ +#define DDI_FM_TXR_ERROR_WHITELIST "whitelist" +#define DDI_FM_TXR_ERROR_NOTSUPP "notsupp" +#define DDI_FM_TXR_ERROR_OVERTEMP "overtemp" +#define DDI_FM_TXR_ERROR_HWFAIL "hwfail" +#define DDI_FM_TXR_ERROR_UNKNOWN "unknown" + #ifdef __cplusplus } #endif diff --git a/usr/src/uts/common/sys/fs/namenode.h b/usr/src/uts/common/sys/fs/namenode.h index 9ebf2cf1ca..24d276b6c3 100644 --- a/usr/src/uts/common/sys/fs/namenode.h +++ b/usr/src/uts/common/sys/fs/namenode.h @@ -26,6 +26,10 @@ * Use is subject to license terms. */ +/* + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ + #ifndef _SYS_FS_NAMENODE_H #define _SYS_FS_NAMENODE_H @@ -93,6 +97,10 @@ extern struct vnodeops *nm_vnodeops; extern const struct fs_operation_def nm_vnodeops_template[]; extern kmutex_t ntable_lock; +typedef int nm_walk_mounts_f(const struct namenode *, cred_t *, void *); +extern int nm_walk_mounts(const vnode_t *, nm_walk_mounts_f *, cred_t *, + void *); + #endif /* _KERNEL */ #ifdef __cplusplus diff --git a/usr/src/uts/common/sys/mac_client_impl.h b/usr/src/uts/common/sys/mac_client_impl.h index 21641b884d..0f8be50fde 100644 --- a/usr/src/uts/common/sys/mac_client_impl.h +++ b/usr/src/uts/common/sys/mac_client_impl.h @@ -230,7 +230,7 @@ extern int mac_tx_percpu_cnt; &(mcip)->mci_flent->fe_resource_props) #define MCIP_EFFECTIVE_PROPS(mcip) \ - (mcip->mci_flent == NULL ? NULL : \ + (mcip->mci_flent == NULL ? NULL : \ &(mcip)->mci_flent->fe_effective_props) #define MCIP_RESOURCE_PROPS_MASK(mcip) \ diff --git a/usr/src/uts/common/sys/mac_impl.h b/usr/src/uts/common/sys/mac_impl.h index 21f2c10a8e..3c103c073a 100644 --- a/usr/src/uts/common/sys/mac_impl.h +++ b/usr/src/uts/common/sys/mac_impl.h @@ -290,6 +290,54 @@ struct mac_group_s { #define GROUP_INTR_ENABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_enable #define GROUP_INTR_DISABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_disable +#define MAC_RING_TX(mhp, rh, mp, rest) { \ + mac_ring_handle_t mrh = rh; \ + mac_impl_t *mimpl = (mac_impl_t *)mhp; \ + /* \ + * Send packets through a selected tx ring, or through the \ + * default handler if there is no selected ring. \ + */ \ + if (mrh == NULL) \ + mrh = mimpl->mi_default_tx_ring; \ + if (mrh == NULL) { \ + rest = mimpl->mi_tx(mimpl->mi_driver, mp); \ + } else { \ + rest = mac_hwring_tx(mrh, mp); \ + } \ +} + +/* + * This is the final stop before reaching the underlying driver + * or aggregation, so this is where the bridging hook is implemented. + * Packets that are bridged will return through mac_bridge_tx(), with + * rh nulled out if the bridge chooses to send output on a different + * link due to forwarding. + */ +#define MAC_TX(mip, rh, mp, src_mcip) { \ + mac_ring_handle_t rhandle = (rh); \ + /* \ + * If there is a bound Hybrid I/O share, send packets through \ + * the default tx ring. (When there's a bound Hybrid I/O share, \ + * the tx rings of this client are mapped in the guest domain \ + * and not accessible from here.) \ + */ \ + _NOTE(CONSTANTCONDITION) \ + if ((src_mcip)->mci_state_flags & MCIS_SHARE_BOUND) \ + rhandle = (mip)->mi_default_tx_ring; \ + if (mip->mi_promisc_list != NULL) \ + mac_promisc_dispatch(mip, mp, src_mcip); \ + /* \ + * Grab the proper transmit pointer and handle. Special \ + * optimization: we can test mi_bridge_link itself atomically, \ + * and if that indicates no bridge send packets through tx ring.\ + */ \ + if (mip->mi_bridge_link == NULL) { \ + MAC_RING_TX(mip, rhandle, mp, mp); \ + } else { \ + mp = mac_bridge_tx(mip, rhandle, mp); \ + } \ +} + /* mci_tx_flag */ #define MCI_TX_QUIESCE 0x1 diff --git a/usr/src/uts/common/sys/mac_provider.h b/usr/src/uts/common/sys/mac_provider.h index 2dea3a4758..fc3b3892bd 100644 --- a/usr/src/uts/common/sys/mac_provider.h +++ b/usr/src/uts/common/sys/mac_provider.h @@ -567,14 +567,14 @@ extern void mac_free(mac_register_t *); extern int mac_register(mac_register_t *, mac_handle_t *); extern int mac_disable_nowait(mac_handle_t); extern int mac_disable(mac_handle_t); -extern int mac_unregister(mac_handle_t); -extern void mac_rx(mac_handle_t, mac_resource_handle_t, +extern int mac_unregister(mac_handle_t); +extern void mac_rx(mac_handle_t, mac_resource_handle_t, mblk_t *); -extern void mac_rx_ring(mac_handle_t, mac_ring_handle_t, +extern void mac_rx_ring(mac_handle_t, mac_ring_handle_t, mblk_t *, uint64_t); -extern void mac_link_update(mac_handle_t, link_state_t); -extern void mac_link_redo(mac_handle_t, link_state_t); -extern void mac_unicst_update(mac_handle_t, +extern void mac_link_update(mac_handle_t, link_state_t); +extern void mac_link_redo(mac_handle_t, link_state_t); +extern void mac_unicst_update(mac_handle_t, const uint8_t *); extern void mac_dst_update(mac_handle_t, const uint8_t *); extern void mac_tx_update(mac_handle_t); diff --git a/usr/src/uts/common/sys/strsubr.h b/usr/src/uts/common/sys/strsubr.h index 65bdfb2e17..14e17c1c0c 100644 --- a/usr/src/uts/common/sys/strsubr.h +++ b/usr/src/uts/common/sys/strsubr.h @@ -29,7 +29,7 @@ */ /* - * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ #ifndef _SYS_STRSUBR_H @@ -289,7 +289,7 @@ typedef struct stdata { #define SNDMREAD 0x00008000 /* used for read notification */ #define OLDNDELAY 0x00010000 /* use old TTY semantics for */ /* NDELAY reads and writes */ - /* 0x00020000 unused */ +#define STRXPG4TTY 0x00020000 /* Use XPG4 TTY semantics */ /* 0x00040000 unused */ #define STRTOSTOP 0x00080000 /* block background writes */ #define STRCMDWAIT 0x00100000 /* someone is doing an _I_CMD */ diff --git a/usr/src/uts/i86pc/io/mp_platform_common.c b/usr/src/uts/i86pc/io/mp_platform_common.c index efb4c81092..aea7f2e856 100644 --- a/usr/src/uts/i86pc/io/mp_platform_common.c +++ b/usr/src/uts/i86pc/io/mp_platform_common.c @@ -24,6 +24,7 @@ * Copyright 2017 Joyent, Inc. * Copyright (c) 2017 by Delphix. All rights reserved. * Copyright (c) 2019, Joyent, Inc. + * Copyright 2020 RackTop Systems, Inc. */ /* * Copyright (c) 2010, Intel Corporation. @@ -79,7 +80,7 @@ /* * Local Function Prototypes */ -static int apic_handle_defconf(); +static int apic_handle_defconf(void); static int apic_parse_mpct(caddr_t mpct, int bypass); static struct apic_mpfps_hdr *apic_find_fps_sig(caddr_t fptr, int size); static int apic_checksum(caddr_t bptr, int len); @@ -182,7 +183,7 @@ int apic_num_rebind = 0; * Maximum number of APIC CPUs in the system, -1 indicates that dynamic * allocation of CPU ids is disabled. */ -int apic_max_nproc = -1; +int apic_max_nproc = -1; int apic_nproc = 0; size_t apic_cpus_size = 0; int apic_defconf = 0; @@ -589,10 +590,22 @@ apic_free_apic_cpus(void) } } +static uint32_t +acpi_get_apic_lid(void) +{ + uint32_t id; + + id = apic_reg_ops->apic_read(APIC_LID_REG); + if (apic_mode != LOCAL_X2APIC) + id >>= APIC_ID_BIT_OFFSET; + + return (id); +} + static int acpi_probe(char *modname) { - int i, intmax, index; + int i, intmax; uint32_t id, ver; int acpi_verboseflags = 0; int madt_seen, madt_size; @@ -640,9 +653,9 @@ acpi_probe(char *modname) return (PSM_FAILURE); } - id = apic_reg_ops->apic_read(APIC_LID_REG); - local_ids[0] = (uchar_t)(id >> 24); - apic_nproc = index = 1; + local_ids[0] = acpi_get_apic_lid(); + + apic_nproc = 1; apic_io_max = 0; ap = (ACPI_SUBTABLE_HEADER *) (acpi_mapic_dtp + 1); @@ -657,25 +670,19 @@ acpi_probe(char *modname) if (mpa->Id == 255) { cmn_err(CE_WARN, "!%s: encountered " "invalid entry in MADT: CPU %d " - "has Local APIC Id equal to 255 ", + "has Local APIC Id equal to 255", psm_name, mpa->ProcessorId); } if (mpa->Id == local_ids[0]) { - ASSERT(index == 1); proc_ids[0] = mpa->ProcessorId; } else if (apic_nproc < NCPU && use_mp && apic_nproc < boot_ncpus) { - local_ids[index] = mpa->Id; - proc_ids[index] = mpa->ProcessorId; - index++; + local_ids[apic_nproc] = mpa->Id; + proc_ids[apic_nproc] = mpa->ProcessorId; apic_nproc++; } else if (apic_nproc == NCPU && !warned) { cmn_err(CE_WARN, "%s: CPU limit " - "exceeded" -#if !defined(__amd64) - " for 32-bit mode" -#endif - "; Solaris will use %d CPUs.", + "exceeded; will use %d CPUs.", psm_name, NCPU); warned = 1; } @@ -716,7 +723,7 @@ acpi_probe(char *modname) acpi_nmi_sp = mns; acpi_nmi_scnt++; - cmn_err(CE_NOTE, "!apic: nmi source: %d 0x%x\n", + cmn_err(CE_NOTE, "!apic: nmi source: %d 0x%x", mns->GlobalIrq, mns->IntiFlags); break; @@ -727,7 +734,7 @@ acpi_probe(char *modname) acpi_nmi_cp = mlan; acpi_nmi_ccnt++; - cmn_err(CE_NOTE, "!apic: local nmi: %d 0x%x %d\n", + cmn_err(CE_NOTE, "!apic: local nmi: %d 0x%x %d", mlan->ProcessorId, mlan->IntiFlags, mlan->Lint); break; @@ -735,7 +742,7 @@ acpi_probe(char *modname) case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: /* UNIMPLEMENTED */ mao = (ACPI_MADT_LOCAL_APIC_OVERRIDE *) ap; - cmn_err(CE_NOTE, "!apic: address override: %lx\n", + cmn_err(CE_NOTE, "!apic: address override: %lx", (long)mao->Address); break; @@ -743,7 +750,7 @@ acpi_probe(char *modname) /* UNIMPLEMENTED */ misa = (ACPI_MADT_IO_SAPIC *) ap; - cmn_err(CE_NOTE, "!apic: io sapic: %d %d %lx\n", + cmn_err(CE_NOTE, "!apic: io sapic: %d %d %lx", misa->Id, misa->GlobalIrqBase, (long)misa->Address); break; @@ -753,7 +760,7 @@ acpi_probe(char *modname) mis = (ACPI_MADT_INTERRUPT_SOURCE *) ap; cmn_err(CE_NOTE, - "!apic: irq source: %d %d %d 0x%x %d %d\n", + "!apic: irq source: %d %d %d 0x%x %d %d", mis->Id, mis->Eid, mis->GlobalIrq, mis->IntiFlags, mis->Type, mis->IoSapicVector); @@ -764,21 +771,16 @@ acpi_probe(char *modname) if (mpx2a->LapicFlags & ACPI_MADT_ENABLED) { if (mpx2a->LocalApicId == local_ids[0]) { - ASSERT(index == 1); proc_ids[0] = mpx2a->Uid; } else if (apic_nproc < NCPU && use_mp && apic_nproc < boot_ncpus) { - local_ids[index] = mpx2a->LocalApicId; - proc_ids[index] = mpx2a->Uid; - index++; + local_ids[apic_nproc] = + mpx2a->LocalApicId; + proc_ids[apic_nproc] = mpx2a->Uid; apic_nproc++; } else if (apic_nproc == NCPU && !warned) { cmn_err(CE_WARN, "%s: CPU limit " - "exceeded" -#if !defined(__amd64) - " for 32-bit mode" -#endif - "; Solaris will use %d CPUs.", + "exceeded; will use %d CPUs.", psm_name, NCPU); warned = 1; } @@ -792,9 +794,9 @@ acpi_probe(char *modname) if (mx2alan->Uid >> 8) acpi_nmi_ccnt++; -#ifdef DEBUG +#ifdef DEBUG cmn_err(CE_NOTE, - "!apic: local x2apic nmi: %d 0x%x %d\n", + "!apic: local x2apic nmi: %d 0x%x %d", mx2alan->Uid, mx2alan->IntiFlags, mx2alan->Lint); #endif @@ -848,19 +850,19 @@ acpi_probe(char *modname) * The state for each apic CPU info structure will be assigned according * to the following rules: * Rule 1: - * Slot index range: [0, min(apic_nproc, boot_ncpus)) + * Slot index range: [0, min(apic_nproc, boot_ncpus)) * State flags: 0 * Note: cpu exists and will be configured/enabled at boot time * Rule 2: - * Slot index range: [boot_ncpus, apic_nproc) + * Slot index range: [boot_ncpus, apic_nproc) * State flags: APIC_CPU_FREE | APIC_CPU_DIRTY * Note: cpu exists but won't be configured/enabled at boot time * Rule 3: - * Slot index range: [apic_nproc, boot_ncpus) + * Slot index range: [apic_nproc, boot_ncpus) * State flags: APIC_CPU_FREE * Note: cpu doesn't exist at boot time * Rule 4: - * Slot index range: [max(apic_nproc, boot_ncpus), max_ncpus) + * Slot index range: [max(apic_nproc, boot_ncpus), max_ncpus) * State flags: APIC_CPU_FREE * Note: cpu doesn't exist at boot time */ @@ -1014,10 +1016,8 @@ cleanup: * Fill all details as MP table does not give any more info */ static int -apic_handle_defconf() +apic_handle_defconf(void) { - uint_t lid; - /* Failed to probe ACPI MADT tables, disable CPU DR. */ apic_max_nproc = -1; apic_free_apic_cpus(); @@ -1035,8 +1035,7 @@ apic_handle_defconf() CPUSET_ONLY(apic_cpumask, 0); CPUSET_ADD(apic_cpumask, 1); apic_nproc = 2; - lid = apic_reg_ops->apic_read(APIC_LID_REG); - apic_cpus[0].aci_local_id = (uchar_t)(lid >> APIC_ID_BIT_OFFSET); + apic_cpus[0].aci_local_id = acpi_get_apic_lid(); /* * According to the PC+MP spec 1.1, the local ids * for the default configuration has to be 0 or 1 @@ -1081,10 +1080,9 @@ apic_parse_mpct(caddr_t mpct, int bypass_cpus_and_ioapics) struct apic_io_entry *ioapicp; struct apic_io_intr *intrp; int ioapic_ix; - uint_t lid; - uint32_t id; - uchar_t hid; - int warned = 0; + uint32_t lid, id; + uchar_t hid; + int warned = 0; /*LINTED: pointer cast may result in improper alignment */ procp = (struct apic_procent *)(mpct + sizeof (struct apic_mp_cnf_hdr)); @@ -1103,11 +1101,7 @@ apic_parse_mpct(caddr_t mpct, int bypass_cpus_and_ioapics) apic_nproc++; } else if (apic_nproc == NCPU && !warned) { cmn_err(CE_WARN, "%s: CPU limit " - "exceeded" -#if !defined(__amd64) - " for 32-bit mode" -#endif - "; Solaris will use %d CPUs.", + "exceeded; will use %d CPUs.", psm_name, NCPU); warned = 1; } @@ -1137,10 +1131,9 @@ apic_parse_mpct(caddr_t mpct, int bypass_cpus_and_ioapics) if (!bypass_cpus_and_ioapics && procp->proc_cpuflags & CPUFLAGS_EN) { if (procp->proc_cpuflags & CPUFLAGS_BP) { /* Boot CPU */ - lid = apic_reg_ops->apic_read(APIC_LID_REG); + lid = acpi_get_apic_lid(); apic_cpus[0].aci_local_id = procp->proc_apicid; - if (apic_cpus[0].aci_local_id != - (uchar_t)(lid >> APIC_ID_BIT_OFFSET)) { + if (apic_cpus[0].aci_local_id != lid) { return (PSM_FAILURE); } apic_cpus[0].aci_local_ver = @@ -1624,7 +1617,8 @@ apic_allocate_irq(int irq) if (freeirq == -1) { /* This shouldn't happen, but just in case */ - cmn_err(CE_WARN, "%s: NO available IRQ", psm_name); + cmn_err(CE_WARN, "%s: NO available IRQ", + psm_name); return (-1); } } diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index 820e0a4e31..aed47948a9 100644 --- a/usr/src/uts/intel/Makefile.intel +++ b/usr/src/uts/intel/Makefile.intel @@ -318,6 +318,7 @@ DRV_KMODS += log DRV_KMODS += logindmux DRV_KMODS += mega_sas DRV_KMODS += mc-amd +DRV_KMODS += mlxcx DRV_KMODS += mm DRV_KMODS += mouse8042 DRV_KMODS += mpt_sas diff --git a/usr/src/uts/intel/ipsecah/Makefile b/usr/src/uts/intel/ipsecah/Makefile index d744c131f1..dd8485f210 100644 --- a/usr/src/uts/intel/ipsecah/Makefile +++ b/usr/src/uts/intel/ipsecah/Makefile @@ -42,7 +42,6 @@ UTSBASE = ../.. # MODULE = ipsecah OBJECTS = $(IPSECAH_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(IPSECAH_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE) CONF_SRCDIR = $(UTSBASE)/common/inet/ip @@ -56,7 +55,6 @@ include $(UTSBASE)/intel/Makefile.intel # Define targets # ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # @@ -64,24 +62,9 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # LDFLAGS += -dy -Ndrv/ip -Ndrv/tcp -Nmisc/kcf -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - CERRWARN += -_gcc=-Wno-parentheses CERRWARN += $(CNOWARN_UNINIT) -# needs work -$(OBJS_DIR)/ipsecahddi.o := SMOFF += index_overflow -$(OBJS_DIR)/ipsecah.o := SMOFF += deref_check -$(OBJS_DIR)/sadb.o := SMOFF += signed_integer_overflow_check,deref_check,indenting,shift_to_zero - # # Default build targets. # @@ -95,12 +78,6 @@ clean: $(CLEAN_DEPS) $(SISCLEAN_DEPS) clobber: $(CLOBBER_DEPS) $(SISCLEAN_DEPS) -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - install: $(INSTALL_DEPS) $(SISCHECK_DEPS) $(ROOTLINK): $(ROOT_STRMOD_DIR) $(ROOTMODULE) diff --git a/usr/src/uts/intel/ipsecesp/Makefile b/usr/src/uts/intel/ipsecesp/Makefile index 713ad82d7c..3ae4a4cac1 100644 --- a/usr/src/uts/intel/ipsecesp/Makefile +++ b/usr/src/uts/intel/ipsecesp/Makefile @@ -26,7 +26,7 @@ # Copyright (c) 2018, Joyent, Inc. # -# This makefile drives the production of the ipsecesp driver +# This makefile drives the production of the ipsecesp driver # kernel module. # # intel implementation architecture dependent @@ -42,7 +42,6 @@ UTSBASE = ../.. # MODULE = ipsecesp OBJECTS = $(IPSECESP_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(IPSECESP_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE) CONF_SRCDIR = $(UTSBASE)/common/inet/ip @@ -56,7 +55,6 @@ include $(UTSBASE)/intel/Makefile.intel # Define targets # ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # @@ -64,21 +62,8 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # LDFLAGS += -dy -Ndrv/ip -Ndrv/ipsecah -Nmisc/kcf -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - CERRWARN += $(CNOWARN_UNINIT) -# needs work -$(OBJS_DIR)/ipsecespddi.o := SMOFF += index_overflow -$(OBJS_DIR)/ipsecesp.o := SMOFF += deref_check - # # Default build targets. # @@ -92,12 +77,6 @@ clean: $(CLEAN_DEPS) $(SISCLEAN_DEPS) clobber: $(CLOBBER_DEPS) $(SISCLEAN_DEPS) -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - install: $(INSTALL_DEPS) $(SISCHECK_DEPS) $(ROOTLINK): $(ROOT_STRMOD_DIR) $(ROOTMODULE) diff --git a/usr/src/uts/intel/mlxcx/Makefile b/usr/src/uts/intel/mlxcx/Makefile new file mode 100644 index 0000000000..27bdfa4b73 --- /dev/null +++ b/usr/src/uts/intel/mlxcx/Makefile @@ -0,0 +1,44 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +UTSBASE = ../.. + +MODULE = mlxcx +OBJECTS = $(MLXCX_OBJS:%=$(OBJS_DIR)/%) +ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) +CONF_SRCDIR = $(UTSBASE)/common/io/mlxcx + +include $(UTSBASE)/intel/Makefile.intel + +CPPFLAGS += -I$(UTSBASE)/common/io/mlxcx + +ALL_TARGET = $(BINARY) $(CONFMOD) +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) + +LDFLAGS += -dy -N misc/mac + +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +install: $(INSTALL_DEPS) + +include $(UTSBASE)/intel/Makefile.targ diff --git a/usr/src/uts/intel/os/driver_aliases b/usr/src/uts/intel/os/driver_aliases index f9b5129d3b..f5b0a08489 100644 --- a/usr/src/uts/intel/os/driver_aliases +++ b/usr/src/uts/intel/os/driver_aliases @@ -1085,6 +1085,19 @@ mega_sas "pci1028,15.1028.1f01" mega_sas "pci1028,15.1028.1f02" mega_sas "pci1028,15.1028.1f03" mouse8042 "pnpPNP,f03" +mlxcx "pciex15b3,1013" +mlxcx "pciex15b3,1014" +mlxcx "pciex15b3,1015" +mlxcx "pciex15b3,1016" +mlxcx "pciex15b3,1017" +mlxcx "pciex15b3,1018" +mlxcx "pciex15b3,1019" +mlxcx "pciex15b3,101a" +mlxcx "pciex15b3,101b" +mlxcx "pciex15b3,101c" +mlxcx "pciex15b3,101d" +mlxcx "pciex15b3,101e" +mlxcx "pciex15b3,101f" mpt "pci1000,30" mpt "pci1000,50" mpt "pci1000,54" diff --git a/usr/src/uts/intel/procfs/Makefile b/usr/src/uts/intel/procfs/Makefile index 1db5848438..630b6a25d3 100644 --- a/usr/src/uts/intel/procfs/Makefile +++ b/usr/src/uts/intel/procfs/Makefile @@ -25,6 +25,7 @@ # Use is subject to license terms. # # Copyright 2019 Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # This makefile drives the production of the procfs file system @@ -83,6 +84,8 @@ $(OBJS_DIR)/prsubr.o := SMOFF += all_func_returns $(OBJS_DIR)/prcontrol.o := SMOFF += all_func_returns $(OBJS_DIR)/prioctl.o := SMOFF += signed +LDFLAGS += -dy -Nfs/namefs + # # Default build targets. # diff --git a/usr/src/uts/sparc/ipsecah/Makefile b/usr/src/uts/sparc/ipsecah/Makefile index 55ee48c88f..ad14fa4e5b 100644 --- a/usr/src/uts/sparc/ipsecah/Makefile +++ b/usr/src/uts/sparc/ipsecah/Makefile @@ -24,7 +24,7 @@ # # -# This makefile drives the production of the ipsecah driver +# This makefile drives the production of the ipsecah driver # kernel module. # # sparc architecture dependent @@ -40,7 +40,6 @@ UTSBASE = ../.. # MODULE = ipsecah OBJECTS = $(IPSECAH_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(IPSECAH_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE) CONF_SRCDIR = $(UTSBASE)/common/inet/ip @@ -54,7 +53,6 @@ include $(UTSBASE)/sparc/Makefile.sparc # Define targets # ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # @@ -62,21 +60,6 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # LDFLAGS += -dy -Ndrv/ip -Ndrv/tcp -Nmisc/kcf -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV -LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON - CERRWARN += -_gcc=-Wno-parentheses CERRWARN += $(CNOWARN_UNINIT) @@ -93,12 +76,6 @@ clean: $(CLEAN_DEPS) $(SISCLEAN_DEPS) clobber: $(CLOBBER_DEPS) $(SISCLEAN_DEPS) -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - install: $(INSTALL_DEPS) $(SISCHECK_DEPS) $(ROOTLINK): $(ROOT_STRMOD_DIR) $(ROOTMODULE) diff --git a/usr/src/uts/sparc/ipsecesp/Makefile b/usr/src/uts/sparc/ipsecesp/Makefile index 1a36e4fbc7..931dc913a2 100644 --- a/usr/src/uts/sparc/ipsecesp/Makefile +++ b/usr/src/uts/sparc/ipsecesp/Makefile @@ -24,7 +24,7 @@ # # -# This makefile drives the production of the ipsecesp driver +# This makefile drives the production of the ipsecesp driver # kernel module. # # sparc architecture dependent @@ -40,7 +40,6 @@ UTSBASE = ../.. # MODULE = ipsecesp OBJECTS = $(IPSECESP_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(IPSECESP_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) ROOTLINK = $(ROOT_STRMOD_DIR)/$(MODULE) CONF_SRCDIR = $(UTSBASE)/common/inet/ip @@ -54,7 +53,6 @@ include $(UTSBASE)/sparc/Makefile.sparc # Define targets # ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # @@ -62,20 +60,6 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) # LDFLAGS += -dy -Ndrv/ip -Ndrv/ipsecah -Nmisc/kcf -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - CERRWARN += $(CNOWARN_UNINIT) # @@ -91,12 +75,6 @@ clean: $(CLEAN_DEPS) $(SISCLEAN_DEPS) clobber: $(CLOBBER_DEPS) $(SISCLEAN_DEPS) -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - install: $(INSTALL_DEPS) $(SISCHECK_DEPS) $(ROOTLINK): $(ROOT_STRMOD_DIR) $(ROOTMODULE) diff --git a/usr/src/uts/sparc/procfs/Makefile b/usr/src/uts/sparc/procfs/Makefile index 8dd05fe72b..3226238bd4 100644 --- a/usr/src/uts/sparc/procfs/Makefile +++ b/usr/src/uts/sparc/procfs/Makefile @@ -23,6 +23,7 @@ # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # This makefile drives the production of the procfs file system @@ -41,7 +42,6 @@ UTSBASE = ../.. # MODULE = procfs OBJECTS = $(PROC_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(PROC_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_FS_DIR)/$(MODULE) # @@ -53,7 +53,6 @@ include $(UTSBASE)/sparc/Makefile.sparc # Define targets # ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # @@ -64,19 +63,12 @@ $(MODSTUBS_O) := AS_CPPFLAGS += -DPROC_MODULE CLEANFILES += $(MODSTUBS_O) CFLAGS += $(CCVERBOSE) -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-switch CERRWARN += $(CNOWARN_UNINIT) +LDFLAGS += -dy -Nfs/namefs + # # Default build targets. # @@ -90,12 +82,6 @@ clean: $(CLEAN_DEPS) clobber: $(CLOBBER_DEPS) -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - install: $(INSTALL_DEPS) # diff --git a/usr/src/uts/sun4v/io/vnet.c b/usr/src/uts/sun4v/io/vnet.c index f30ef8e2d4..96fb04175d 100644 --- a/usr/src/uts/sun4v/io/vnet.c +++ b/usr/src/uts/sun4v/io/vnet.c @@ -1133,9 +1133,9 @@ vnet_mac_register(vnet_t *vnetp) static int vnet_read_mac_address(vnet_t *vnetp) { - uchar_t *macaddr; - uint32_t size; - int rv; + uchar_t *macaddr; + uint32_t size; + int rv; rv = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, vnetp->dip, DDI_PROP_DONTPASS, macaddr_propname, &macaddr, &size); @@ -2318,7 +2318,7 @@ vnet_get_ring(void *arg, mac_ring_type_t rtype, const int g_index, */ static void vnet_get_group(void *arg, mac_ring_type_t type, const int index, - mac_group_info_t *infop, mac_group_handle_t handle) + mac_group_info_t *infop, mac_group_handle_t handle) { vnet_t *vnetp = (vnet_t *)arg; @@ -2631,7 +2631,7 @@ vnet_rx_poll(void *arg, int bytes_to_pickup) /* ARGSUSED */ void vnet_hio_rx_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp, - boolean_t loopback) + boolean_t loopback) { vnet_t *vnetp = (vnet_t *)arg; vnet_pseudo_rx_ring_t *ringp = (vnet_pseudo_rx_ring_t *)mrh; |