diff --git a/Makefile.inc1 b/Makefile.inc1 index a3189cd84644..bba32772cc97 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -655,7 +655,8 @@ LIBCOMPAT= SOFT # when the ABI breaks though that we want to force rebuilding WORLDTMP # to get updated host tools. .if ${MK_META_MODE} == "yes" && defined(NO_CLEAN) && \ - !defined(NO_META_IGNORE_HOST) && !defined(NO_META_IGNORE_HOST_HEADERS) + !defined(NO_META_IGNORE_HOST) && !defined(NO_META_IGNORE_HOST_HEADERS) && \ + !make(showconfig) # r318736 - ino64 major ABI breakage META_MODE_BAD_ABI_VERS+= 1200031 @@ -761,7 +762,15 @@ _worldtmp: .PHONY .endif .else rm -rf ${WORLDTMP}/legacy/usr/include -.endif +.if ${USING_SYSTEM_COMPILER} == "yes" +.for cc in cc c++ + if [ -x ${WORLDTMP}/usr/bin/${cc} ]; then \ + inum=$$(stat -f %i ${WORLDTMP}/usr/bin/${cc}); \ + find ${WORLDTMP}/usr/bin -inum $${inum} -delete; \ + fi +.endfor +.endif # ${USING_SYSTEM_COMPILER} == "yes" +.endif # !defined(NO_CLEAN) # Our current approach to dependency tracking cannot cope with certain source # tree changes, particularly with respect to removing source files and @@ -1641,8 +1650,8 @@ create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap .for _kernel in ${BUILDKERNELS:[2..-1]} .if exists(${KSTAGEDIR}/kernel.${_kernel}.meta) .for flavor in "" -debug -create-kernel-packages: create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},} -create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap .PHONY +create-kernel-packages: create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kernel} +create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kernel}: _pkgbootstrap .PHONY @cd ${KSTAGEDIR}/kernel.${_kernel} ; \ awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk \ -v kernel=yes -v _kernconf=${_kernel} \ diff --git a/bin/Makefile b/bin/Makefile index b3385dcd32d9..3e7571c27e61 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -47,8 +47,6 @@ SUBDIR.${MK_TESTS}+= tests .include -SUBDIR:= ${SUBDIR:O} - SUBDIR_PARALLEL= .include diff --git a/bin/ed/main.c b/bin/ed/main.c index 6cb7d03364d0..babffa813088 100644 --- a/bin/ed/main.c +++ b/bin/ed/main.c @@ -350,7 +350,8 @@ next_addr(void) ibufp++; addr_cnt++; second_addr = (c == ';') ? current_addr : 1; - addr = addr_last; + if ((addr = next_addr()) < 0) + addr = addr_last; break; } /* FALLTHROUGH */ @@ -809,7 +810,7 @@ exec_command(void) if ((addr = write_file(*fnp ? fnp : old_filename, (c == 'W') ? "a" : "w", first_addr, second_addr)) < 0) return ERR; - else if (addr == addr_last) + else if (addr == addr_last && *fnp != '!') modified = 0; else if (modified && !scripted && n == 'q') gflag = EMOD; diff --git a/bin/rcp/rcp.1 b/bin/rcp/rcp.1 index 05913f335a3b..9d2b8ae35bca 100644 --- a/bin/rcp/rcp.1 +++ b/bin/rcp/rcp.1 @@ -29,7 +29,7 @@ .\" @(#)rcp.1 8.1 (Berkeley) 5/31/93 .\" $FreeBSD$ .\" -.Dd October 16, 2002 +.Dd July 3, 2017 .Dt RCP 1 .Os .Sh NAME @@ -43,6 +43,15 @@ .Op Fl 46pr .Ar .Ar directory +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/contrib/ipfilter/man/ippool.8 b/contrib/ipfilter/man/ippool.8 index 26cec206c264..9e39f297dd67 100644 --- a/contrib/ipfilter/man/ippool.8 +++ b/contrib/ipfilter/man/ippool.8 @@ -18,7 +18,7 @@ ippool \- user interface to the IPFilter pools -F [-dv] [-o ] [-t ] .br .B ippool --l [-dv] [-m ] [-t ] +-l [-dv] [-m ] [-t ] [-o ] [-M ] [-N ] .br .B ippool -r [-dnv] [-m ] [-o ] [-t ] -i [/] diff --git a/contrib/ipfilter/tools/ippool.c b/contrib/ipfilter/tools/ippool.c index de61885d967c..b2b026a54f81 100644 --- a/contrib/ipfilter/tools/ippool.c +++ b/contrib/ipfilter/tools/ippool.c @@ -79,7 +79,7 @@ usage(prog) fprintf(stderr, "\t-A [-dnv] [-m ] [-o ] [-S ] [-t ]\n"); fprintf(stderr, "\t-f [-dnuv]\n"); fprintf(stderr, "\t-F [-dv] [-o ] [-t ]\n"); - fprintf(stderr, "\t-l [-dv] [-m ] [-t ]\n"); + fprintf(stderr, "\t-l [-dv] [-m ] [-t ] [-o ] [-M ] [-N ]\n"); fprintf(stderr, "\t-r [-dnv] [-m ] [-o ] [-t type] -i [/netmask]\n"); fprintf(stderr, "\t-R [-dnv] [-m ] [-o ] [-t ]\n"); fprintf(stderr, "\t-s [-dtv] [-M ] [-N ]\n"); diff --git a/contrib/jemalloc/ChangeLog b/contrib/jemalloc/ChangeLog index 98c12f2048e5..967d04d0dff3 100644 --- a/contrib/jemalloc/ChangeLog +++ b/contrib/jemalloc/ChangeLog @@ -4,6 +4,41 @@ brevity. Much more detail can be found in the git revision history: https://github.com/jemalloc/jemalloc +* 5.0.1 (July 1, 2017) + + This bugfix release fixes several issues, most of which are obscure enough + that typical applications are not impacted. + + Bug fixes: + - Update decay->nunpurged before purging, in order to avoid potential update + races and subsequent incorrect purging volume. (@interwq) + - Only abort on dlsym(3) error if the failure impacts an enabled feature (lazy + locking and/or background threads). This mitigates an initialization + failure bug for which we still do not have a clear reproduction test case. + (@interwq) + - Modify tsd management so that it neither crashes nor leaks if a thread's + only allocation activity is to call free() after TLS destructors have been + executed. This behavior was observed when operating with GNU libc, and is + unlikely to be an issue with other libc implementations. (@interwq) + - Mask signals during background thread creation. This prevents signals from + being inadvertently delivered to background threads. (@jasone, + @davidtgoldblatt, @interwq) + - Avoid inactivity checks within background threads, in order to prevent + recursive mutex acquisition. (@interwq) + - Fix extent_grow_retained() to use the specified hooks when the + arena..extent_hooks mallctl is used to override the default hooks. + (@interwq) + - Add missing reentrancy support for custom extent hooks which allocate. + (@interwq) + - Post-fork(2), re-initialize the list of tcaches associated with each arena + to contain no tcaches except the forking thread's. (@interwq) + - Add missing post-fork(2) mutex reinitialization for extent_grow_mtx. This + fixes potential deadlocks after fork(2). (@interwq) + - Enforce minimum autoconf version (currently 2.68), since 2.63 is known to + generate corrupt configure scripts. (@jasone) + - Ensure that the configured page size (--with-lg-page) is no larger than the + configured huge page size (--with-lg-hugepage). (@jasone) + * 5.0.0 (June 13, 2017) Unlike all previous jemalloc releases, this release does not use naturally diff --git a/contrib/jemalloc/VERSION b/contrib/jemalloc/VERSION index e5f1992caa25..50baf739c66c 100644 --- a/contrib/jemalloc/VERSION +++ b/contrib/jemalloc/VERSION @@ -1 +1 @@ -5.0.0-4-g84f6c2cae0fb1399377ef6aea9368444c4987cc6 +5.0.1-0-g896ed3a8b3f41998d4fb4d625d30ac63ef2d51fb diff --git a/contrib/jemalloc/doc/jemalloc.3 b/contrib/jemalloc/doc/jemalloc.3 index c5fd0c70e4e8..0ab82024d26c 100644 --- a/contrib/jemalloc/doc/jemalloc.3 +++ b/contrib/jemalloc/doc/jemalloc.3 @@ -2,12 +2,12 @@ .\" Title: JEMALLOC .\" Author: Jason Evans .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 06/29/2017 +.\" Date: 07/01/2017 .\" Manual: User Manual -.\" Source: jemalloc 5.0.0-4-g84f6c2cae0fb1399377ef6aea9368444c4987cc6 +.\" Source: jemalloc 5.0.1-0-g896ed3a8b3f41998d4fb4d625d30ac63ef2d51fb .\" Language: English .\" -.TH "JEMALLOC" "3" "06/29/2017" "jemalloc 5.0.0-4-g84f6c2cae0fb" "User Manual" +.TH "JEMALLOC" "3" "07/01/2017" "jemalloc 5.0.1-0-g896ed3a8b3f4" "User Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -31,7 +31,7 @@ jemalloc \- general purpose memory allocation functions .SH "LIBRARY" .PP -This manual describes jemalloc 5\&.0\&.0\-4\-g84f6c2cae0fb1399377ef6aea9368444c4987cc6\&. More information can be found at the +This manual describes jemalloc 5\&.0\&.1\-0\-g896ed3a8b3f41998d4fb4d625d30ac63ef2d51fb\&. More information can be found at the \m[blue]\fBjemalloc website\fR\m[]\&\s-2\u[1]\d\s+2\&. .PP The following configuration options are enabled in libc\*(Aqs built\-in jemalloc: diff --git a/contrib/jemalloc/include/jemalloc/internal/arena_externs.h b/contrib/jemalloc/include/jemalloc/internal/arena_externs.h index 3a85bcbb299d..af16d1588529 100644 --- a/contrib/jemalloc/include/jemalloc/internal/arena_externs.h +++ b/contrib/jemalloc/include/jemalloc/internal/arena_externs.h @@ -90,6 +90,7 @@ void arena_prefork3(tsdn_t *tsdn, arena_t *arena); void arena_prefork4(tsdn_t *tsdn, arena_t *arena); void arena_prefork5(tsdn_t *tsdn, arena_t *arena); void arena_prefork6(tsdn_t *tsdn, arena_t *arena); +void arena_prefork7(tsdn_t *tsdn, arena_t *arena); void arena_postfork_parent(tsdn_t *tsdn, arena_t *arena); void arena_postfork_child(tsdn_t *tsdn, arena_t *arena); diff --git a/contrib/jemalloc/include/jemalloc/internal/background_thread_inlines.h b/contrib/jemalloc/include/jemalloc/internal/background_thread_inlines.h index fd5095f253f1..ef50231e8d7e 100644 --- a/contrib/jemalloc/include/jemalloc/internal/background_thread_inlines.h +++ b/contrib/jemalloc/include/jemalloc/internal/background_thread_inlines.h @@ -41,8 +41,9 @@ background_thread_indefinite_sleep(background_thread_info_t *info) { } JEMALLOC_ALWAYS_INLINE void -arena_background_thread_inactivity_check(tsdn_t *tsdn, arena_t *arena) { - if (!background_thread_enabled()) { +arena_background_thread_inactivity_check(tsdn_t *tsdn, arena_t *arena, + bool is_background_thread) { + if (!background_thread_enabled() || is_background_thread) { return; } background_thread_info_t *info = diff --git a/contrib/jemalloc/include/jemalloc/internal/base_externs.h b/contrib/jemalloc/include/jemalloc/internal/base_externs.h index 0a1114f4ac13..a4fd5ac7d9a6 100644 --- a/contrib/jemalloc/include/jemalloc/internal/base_externs.h +++ b/contrib/jemalloc/include/jemalloc/internal/base_externs.h @@ -3,7 +3,7 @@ base_t *b0get(void); base_t *base_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks); -void base_delete(base_t *base); +void base_delete(tsdn_t *tsdn, base_t *base); extent_hooks_t *base_extent_hooks_get(base_t *base); extent_hooks_t *base_extent_hooks_set(base_t *base, extent_hooks_t *extent_hooks); diff --git a/contrib/jemalloc/include/jemalloc/internal/ctl.h b/contrib/jemalloc/include/jemalloc/internal/ctl.h index f159383d5ca8..a91c4cf556bc 100644 --- a/contrib/jemalloc/include/jemalloc/internal/ctl.h +++ b/contrib/jemalloc/include/jemalloc/internal/ctl.h @@ -91,8 +91,7 @@ typedef struct ctl_arenas_s { int ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen); -int ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, - size_t *miblenp); +int ctl_nametomib(tsd_t *tsd, const char *name, size_t *mibp, size_t *miblenp); int ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); diff --git a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h index 12a7e5a86be6..b24eb54d8fbe 100644 --- a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h +++ b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h @@ -25,6 +25,7 @@ # include # endif # include +# include # ifdef JEMALLOC_OS_UNFAIR_LOCK # include # endif diff --git a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h index 8f6e266502d4..a2dd13390dee 100644 --- a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h +++ b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h @@ -99,6 +99,9 @@ /* Defined if pthread_atfork(3) is available. */ #define JEMALLOC_HAVE_PTHREAD_ATFORK +/* Defined if pthread_setname_np(3) is available. */ +/* #undef JEMALLOC_HAVE_PTHREAD_SETNAME_NP */ + /* * Defined if clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is available. */ diff --git a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h index 854fb1e2c7e0..24ea416297f8 100644 --- a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h +++ b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h @@ -146,7 +146,10 @@ tcache_get(tsd_t *tsd) { } static inline void -pre_reentrancy(tsd_t *tsd) { +pre_reentrancy(tsd_t *tsd, arena_t *arena) { + /* arena is the current context. Reentry from a0 is not allowed. */ + assert(arena != arena_get(tsd_tsdn(tsd), 0, false)); + bool fast = tsd_fast(tsd); ++*tsd_reentrancy_levelp_get(tsd); if (fast) { diff --git a/contrib/jemalloc/include/jemalloc/internal/private_namespace.h b/contrib/jemalloc/include/jemalloc/internal/private_namespace.h index f3d9e618d635..00bf8da1f8f3 100644 --- a/contrib/jemalloc/include/jemalloc/internal/private_namespace.h +++ b/contrib/jemalloc/include/jemalloc/internal/private_namespace.h @@ -69,6 +69,7 @@ #define arena_prefork4 JEMALLOC_N(arena_prefork4) #define arena_prefork5 JEMALLOC_N(arena_prefork5) #define arena_prefork6 JEMALLOC_N(arena_prefork6) +#define arena_prefork7 JEMALLOC_N(arena_prefork7) #define arena_prof_promote JEMALLOC_N(arena_prof_promote) #define arena_ralloc JEMALLOC_N(arena_ralloc) #define arena_ralloc_no_move JEMALLOC_N(arena_ralloc_no_move) diff --git a/contrib/jemalloc/include/jemalloc/internal/tcache_externs.h b/contrib/jemalloc/include/jemalloc/internal/tcache_externs.h index abe133fabba9..db3e9c7d5d18 100644 --- a/contrib/jemalloc/include/jemalloc/internal/tcache_externs.h +++ b/contrib/jemalloc/include/jemalloc/internal/tcache_externs.h @@ -48,7 +48,7 @@ void tcache_arena_associate(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena); void tcache_prefork(tsdn_t *tsdn); void tcache_postfork_parent(tsdn_t *tsdn); void tcache_postfork_child(tsdn_t *tsdn); -void tcache_flush(void); +void tcache_flush(tsd_t *tsd); bool tsd_tcache_data_init(tsd_t *tsd); bool tsd_tcache_enabled_data_init(tsd_t *tsd); diff --git a/contrib/jemalloc/include/jemalloc/internal/tsd.h b/contrib/jemalloc/include/jemalloc/internal/tsd.h index 631fbf1f7a47..155a2ec6c44b 100644 --- a/contrib/jemalloc/include/jemalloc/internal/tsd.h +++ b/contrib/jemalloc/include/jemalloc/internal/tsd.h @@ -99,9 +99,10 @@ enum { tsd_state_nominal_slow = 1, /* Initialized but on slow path. */ /* the above 2 nominal states should be lower values. */ tsd_state_nominal_max = 1, /* used for comparison only. */ - tsd_state_purgatory = 2, - tsd_state_reincarnated = 3, - tsd_state_uninitialized = 4 + tsd_state_minimal_initialized = 2, + tsd_state_purgatory = 3, + tsd_state_reincarnated = 4, + tsd_state_uninitialized = 5 }; /* Manually limit tsd_state_t to a single byte. */ @@ -190,7 +191,8 @@ JEMALLOC_ALWAYS_INLINE t * \ tsd_##n##p_get(tsd_t *tsd) { \ assert(tsd->state == tsd_state_nominal || \ tsd->state == tsd_state_nominal_slow || \ - tsd->state == tsd_state_reincarnated); \ + tsd->state == tsd_state_reincarnated || \ + tsd->state == tsd_state_minimal_initialized); \ return tsd_##n##p_get_unsafe(tsd); \ } MALLOC_TSD @@ -225,7 +227,8 @@ MALLOC_TSD #define O(n, t, nt) \ JEMALLOC_ALWAYS_INLINE void \ tsd_##n##_set(tsd_t *tsd, t val) { \ - assert(tsd->state != tsd_state_reincarnated); \ + assert(tsd->state != tsd_state_reincarnated && \ + tsd->state != tsd_state_minimal_initialized); \ *tsd_##n##p_get(tsd) = val; \ } MALLOC_TSD @@ -248,7 +251,7 @@ tsd_fast(tsd_t *tsd) { } JEMALLOC_ALWAYS_INLINE tsd_t * -tsd_fetch_impl(bool init, bool internal) { +tsd_fetch_impl(bool init, bool minimal) { tsd_t *tsd = tsd_get(init); if (!init && tsd_get_allocates() && tsd == NULL) { @@ -257,7 +260,7 @@ tsd_fetch_impl(bool init, bool internal) { assert(tsd != NULL); if (unlikely(tsd->state != tsd_state_nominal)) { - return tsd_fetch_slow(tsd, internal); + return tsd_fetch_slow(tsd, minimal); } assert(tsd_fast(tsd)); tsd_assert_fast(tsd); @@ -265,9 +268,20 @@ tsd_fetch_impl(bool init, bool internal) { return tsd; } +/* Get a minimal TSD that requires no cleanup. See comments in free(). */ +JEMALLOC_ALWAYS_INLINE tsd_t * +tsd_fetch_min(void) { + return tsd_fetch_impl(true, true); +} + +/* For internal background threads use only. */ JEMALLOC_ALWAYS_INLINE tsd_t * tsd_internal_fetch(void) { - return tsd_fetch_impl(true, true); + tsd_t *tsd = tsd_fetch_min(); + /* Use reincarnated state to prevent full initialization. */ + tsd->state = tsd_state_reincarnated; + + return tsd; } JEMALLOC_ALWAYS_INLINE tsd_t * diff --git a/contrib/jemalloc/include/jemalloc/jemalloc.h b/contrib/jemalloc/include/jemalloc/jemalloc.h index c4ad45b2a0c5..a7095432f386 100644 --- a/contrib/jemalloc/include/jemalloc/jemalloc.h +++ b/contrib/jemalloc/include/jemalloc/jemalloc.h @@ -87,12 +87,12 @@ extern "C" { #include #include -#define JEMALLOC_VERSION "5.0.0-4-g84f6c2cae0fb1399377ef6aea9368444c4987cc6" +#define JEMALLOC_VERSION "5.0.1-0-g896ed3a8b3f41998d4fb4d625d30ac63ef2d51fb" #define JEMALLOC_VERSION_MAJOR 5 #define JEMALLOC_VERSION_MINOR 0 -#define JEMALLOC_VERSION_BUGFIX 0 -#define JEMALLOC_VERSION_NREV 4 -#define JEMALLOC_VERSION_GID "84f6c2cae0fb1399377ef6aea9368444c4987cc6" +#define JEMALLOC_VERSION_BUGFIX 1 +#define JEMALLOC_VERSION_NREV 0 +#define JEMALLOC_VERSION_GID "896ed3a8b3f41998d4fb4d625d30ac63ef2d51fb" #define MALLOCX_LG_ALIGN(la) ((int)(la)) #if LG_SIZEOF_PTR == 2 diff --git a/contrib/jemalloc/src/arena.c b/contrib/jemalloc/src/arena.c index 019dd8775746..632fce5233e1 100644 --- a/contrib/jemalloc/src/arena.c +++ b/contrib/jemalloc/src/arena.c @@ -61,7 +61,8 @@ const uint64_t h_steps[SMOOTHSTEP_NSTEPS] = { */ static void arena_decay_to_limit(tsdn_t *tsdn, arena_t *arena, - arena_decay_t *decay, extents_t *extents, bool all, size_t npages_limit); + arena_decay_t *decay, extents_t *extents, bool all, size_t npages_limit, + bool is_background_thread); static bool arena_decay_dirty(tsdn_t *tsdn, arena_t *arena, bool is_background_thread, bool all); static void arena_dalloc_bin_slab(tsdn_t *tsdn, arena_t *arena, extent_t *slab, @@ -378,7 +379,7 @@ arena_extents_dirty_dalloc(tsdn_t *tsdn, arena_t *arena, if (arena_dirty_decay_ms_get(arena) == 0) { arena_decay_dirty(tsdn, arena, false, true); } else { - arena_background_thread_inactivity_check(tsdn, arena); + arena_background_thread_inactivity_check(tsdn, arena, false); } } @@ -687,10 +688,11 @@ arena_decay_backlog_update(arena_decay_t *decay, uint64_t nadvance_u64, static void arena_decay_try_purge(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, - extents_t *extents, size_t current_npages, size_t npages_limit) { + extents_t *extents, size_t current_npages, size_t npages_limit, + bool is_background_thread) { if (current_npages > npages_limit) { arena_decay_to_limit(tsdn, arena, decay, extents, false, - npages_limit); + npages_limit, is_background_thread); } } @@ -720,7 +722,7 @@ arena_decay_epoch_advance_helper(arena_decay_t *decay, const nstime_t *time, static void arena_decay_epoch_advance(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, - extents_t *extents, const nstime_t *time, bool purge) { + extents_t *extents, const nstime_t *time, bool is_background_thread) { size_t current_npages = extents_npages_get(extents); arena_decay_epoch_advance_helper(decay, time, current_npages); @@ -728,9 +730,10 @@ arena_decay_epoch_advance(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, /* We may unlock decay->mtx when try_purge(). Finish logging first. */ decay->nunpurged = (npages_limit > current_npages) ? npages_limit : current_npages; - if (purge) { + + if (!background_thread_enabled() || is_background_thread) { arena_decay_try_purge(tsdn, arena, decay, extents, - current_npages, npages_limit); + current_npages, npages_limit, is_background_thread); } } @@ -795,7 +798,7 @@ arena_maybe_decay(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, if (decay_ms <= 0) { if (decay_ms == 0) { arena_decay_to_limit(tsdn, arena, decay, extents, false, - 0); + 0, is_background_thread); } return false; } @@ -830,14 +833,13 @@ arena_maybe_decay(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, */ bool advance_epoch = arena_decay_deadline_reached(decay, &time); if (advance_epoch) { - bool should_purge = is_background_thread || - !background_thread_enabled(); arena_decay_epoch_advance(tsdn, arena, decay, extents, &time, - should_purge); + is_background_thread); } else if (is_background_thread) { arena_decay_try_purge(tsdn, arena, decay, extents, extents_npages_get(extents), - arena_decay_backlog_npages_limit(decay)); + arena_decay_backlog_npages_limit(decay), + is_background_thread); } return advance_epoch; @@ -916,7 +918,7 @@ arena_stash_decayed(tsdn_t *tsdn, arena_t *arena, static size_t arena_decay_stashed(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, arena_decay_t *decay, extents_t *extents, - bool all, extent_list_t *decay_extents) { + bool all, extent_list_t *decay_extents, bool is_background_thread) { UNUSED size_t nmadvise, nunmapped; size_t npurged; @@ -946,7 +948,7 @@ arena_decay_stashed(tsdn_t *tsdn, arena_t *arena, extents_dalloc(tsdn, arena, r_extent_hooks, &arena->extents_muzzy, extent); arena_background_thread_inactivity_check(tsdn, - arena); + arena, is_background_thread); break; } /* Fall through. */ @@ -985,7 +987,8 @@ arena_decay_stashed(tsdn_t *tsdn, arena_t *arena, */ static void arena_decay_to_limit(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, - extents_t *extents, bool all, size_t npages_limit) { + extents_t *extents, bool all, size_t npages_limit, + bool is_background_thread) { witness_assert_depth_to_rank(tsdn_witness_tsdp_get(tsdn), WITNESS_RANK_CORE, 1); malloc_mutex_assert_owner(tsdn, &decay->mtx); @@ -1005,7 +1008,8 @@ arena_decay_to_limit(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, npages_limit, &decay_extents); if (npurge != 0) { UNUSED size_t npurged = arena_decay_stashed(tsdn, arena, - &extent_hooks, decay, extents, all, &decay_extents); + &extent_hooks, decay, extents, all, &decay_extents, + is_background_thread); assert(npurged == npurge); } @@ -1018,7 +1022,8 @@ arena_decay_impl(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay, extents_t *extents, bool is_background_thread, bool all) { if (all) { malloc_mutex_lock(tsdn, &decay->mtx); - arena_decay_to_limit(tsdn, arena, decay, extents, all, 0); + arena_decay_to_limit(tsdn, arena, decay, extents, all, 0, + is_background_thread); malloc_mutex_unlock(tsdn, &decay->mtx); return false; @@ -1252,7 +1257,7 @@ arena_destroy(tsd_t *tsd, arena_t *arena) { * Destroy the base allocator, which manages all metadata ever mapped by * this arena. */ - base_delete(arena->base); + base_delete(tsd_tsdn(tsd), arena->base); } static extent_t * @@ -2046,7 +2051,7 @@ arena_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) { * is done enough that we should have tsd. */ assert(!tsdn_null(tsdn)); - pre_reentrancy(tsdn_tsd(tsdn)); + pre_reentrancy(tsdn_tsd(tsdn), arena); if (hooks_arena_new_hook) { hooks_arena_new_hook(); } @@ -2056,7 +2061,7 @@ arena_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) { return arena; label_error: if (ind != 0) { - base_delete(base); + base_delete(tsdn, base); } return NULL; } @@ -2082,28 +2087,33 @@ arena_prefork1(tsdn_t *tsdn, arena_t *arena) { void arena_prefork2(tsdn_t *tsdn, arena_t *arena) { + malloc_mutex_prefork(tsdn, &arena->extent_grow_mtx); +} + +void +arena_prefork3(tsdn_t *tsdn, arena_t *arena) { extents_prefork(tsdn, &arena->extents_dirty); extents_prefork(tsdn, &arena->extents_muzzy); extents_prefork(tsdn, &arena->extents_retained); } void -arena_prefork3(tsdn_t *tsdn, arena_t *arena) { +arena_prefork4(tsdn_t *tsdn, arena_t *arena) { malloc_mutex_prefork(tsdn, &arena->extent_avail_mtx); } void -arena_prefork4(tsdn_t *tsdn, arena_t *arena) { +arena_prefork5(tsdn_t *tsdn, arena_t *arena) { base_prefork(tsdn, arena->base); } void -arena_prefork5(tsdn_t *tsdn, arena_t *arena) { +arena_prefork6(tsdn_t *tsdn, arena_t *arena) { malloc_mutex_prefork(tsdn, &arena->large_mtx); } void -arena_prefork6(tsdn_t *tsdn, arena_t *arena) { +arena_prefork7(tsdn_t *tsdn, arena_t *arena) { for (unsigned i = 0; i < NBINS; i++) { malloc_mutex_prefork(tsdn, &arena->bins[i].lock); } @@ -2122,6 +2132,7 @@ arena_postfork_parent(tsdn_t *tsdn, arena_t *arena) { extents_postfork_parent(tsdn, &arena->extents_dirty); extents_postfork_parent(tsdn, &arena->extents_muzzy); extents_postfork_parent(tsdn, &arena->extents_retained); + malloc_mutex_postfork_parent(tsdn, &arena->extent_grow_mtx); malloc_mutex_postfork_parent(tsdn, &arena->decay_dirty.mtx); malloc_mutex_postfork_parent(tsdn, &arena->decay_muzzy.mtx); if (config_stats) { @@ -2133,6 +2144,23 @@ void arena_postfork_child(tsdn_t *tsdn, arena_t *arena) { unsigned i; + atomic_store_u(&arena->nthreads[0], 0, ATOMIC_RELAXED); + atomic_store_u(&arena->nthreads[1], 0, ATOMIC_RELAXED); + if (tsd_arena_get(tsdn_tsd(tsdn)) == arena) { + arena_nthreads_inc(arena, false); + } + if (tsd_iarena_get(tsdn_tsd(tsdn)) == arena) { + arena_nthreads_inc(arena, true); + } + if (config_stats) { + ql_new(&arena->tcache_ql); + tcache_t *tcache = tcache_get(tsdn_tsd(tsdn)); + if (tcache != NULL && tcache->arena == arena) { + ql_elm_new(tcache, link); + ql_tail_insert(&arena->tcache_ql, tcache, link); + } + } + for (i = 0; i < NBINS; i++) { malloc_mutex_postfork_child(tsdn, &arena->bins[i].lock); } @@ -2142,6 +2170,7 @@ arena_postfork_child(tsdn_t *tsdn, arena_t *arena) { extents_postfork_child(tsdn, &arena->extents_dirty); extents_postfork_child(tsdn, &arena->extents_muzzy); extents_postfork_child(tsdn, &arena->extents_retained); + malloc_mutex_postfork_child(tsdn, &arena->extent_grow_mtx); malloc_mutex_postfork_child(tsdn, &arena->decay_dirty.mtx); malloc_mutex_postfork_child(tsdn, &arena->decay_muzzy.mtx); if (config_stats) { diff --git a/contrib/jemalloc/src/background_thread.c b/contrib/jemalloc/src/background_thread.c index 1ff594476f00..eb30eb5b423d 100644 --- a/contrib/jemalloc/src/background_thread.c +++ b/contrib/jemalloc/src/background_thread.c @@ -316,7 +316,7 @@ background_threads_disable_single(tsd_t *tsd, background_thread_info_t *info) { &background_thread_lock); } - pre_reentrancy(tsd); + pre_reentrancy(tsd, NULL); malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx); bool has_thread; assert(info->state != background_thread_paused); @@ -347,6 +347,38 @@ background_threads_disable_single(tsd_t *tsd, background_thread_info_t *info) { static void *background_thread_entry(void *ind_arg); +static int +background_thread_create_signals_masked(pthread_t *thread, + const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { + /* + * Mask signals during thread creation so that the thread inherits + * an empty signal set. + */ + sigset_t set; + sigfillset(&set); + sigset_t oldset; + int mask_err = pthread_sigmask(SIG_SETMASK, &set, &oldset); + if (mask_err != 0) { + return mask_err; + } + int create_err = pthread_create_wrapper(thread, attr, start_routine, + arg); + /* + * Restore the signal mask. Failure to restore the signal mask here + * changes program behavior. + */ + int restore_err = pthread_sigmask(SIG_SETMASK, &oldset, NULL); + if (restore_err != 0) { + malloc_printf(": background thread creation " + "failed (%d), and signal mask restoration failed " + "(%d)\n", create_err, restore_err); + if (opt_abort) { + abort(); + } + } + return create_err; +} + static void check_background_thread_creation(tsd_t *tsd, unsigned *n_created, bool *created_threads) { @@ -376,9 +408,9 @@ check_background_thread_creation(tsd_t *tsd, unsigned *n_created, */ malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock); - pre_reentrancy(tsd); - int err = pthread_create_wrapper(&info->thread, NULL, - background_thread_entry, (void *)(uintptr_t)i); + pre_reentrancy(tsd, NULL); + int err = background_thread_create_signals_masked(&info->thread, + NULL, background_thread_entry, (void *)(uintptr_t)i); post_reentrancy(tsd); if (err == 0) { @@ -467,7 +499,9 @@ static void * background_thread_entry(void *ind_arg) { unsigned thread_ind = (unsigned)(uintptr_t)ind_arg; assert(thread_ind < ncpus); - +#ifdef JEMALLOC_HAVE_PTHREAD_SETNAME_NP + pthread_setname_np(pthread_self(), "jemalloc_bg_thd"); +#endif if (opt_percpu_arena != percpu_arena_disabled) { set_current_thread_affinity((int)thread_ind); } @@ -523,12 +557,12 @@ background_thread_create(tsd_t *tsd, unsigned arena_ind) { return false; } - pre_reentrancy(tsd); + pre_reentrancy(tsd, NULL); /* * To avoid complications (besides reentrancy), create internal * background threads with the underlying pthread_create. */ - int err = pthread_create_wrapper(&info->thread, NULL, + int err = background_thread_create_signals_masked(&info->thread, NULL, background_thread_entry, (void *)thread_ind); post_reentrancy(tsd); diff --git a/contrib/jemalloc/src/base.c b/contrib/jemalloc/src/base.c index 8e1544fd9ee4..97078b134d17 100644 --- a/contrib/jemalloc/src/base.c +++ b/contrib/jemalloc/src/base.c @@ -15,7 +15,7 @@ static base_t *b0; /******************************************************************************/ static void * -base_map(extent_hooks_t *extent_hooks, unsigned ind, size_t size) { +base_map(tsdn_t *tsdn, extent_hooks_t *extent_hooks, unsigned ind, size_t size) { void *addr; bool zero = true; bool commit = true; @@ -25,15 +25,19 @@ base_map(extent_hooks_t *extent_hooks, unsigned ind, size_t size) { if (extent_hooks == &extent_hooks_default) { addr = extent_alloc_mmap(NULL, size, PAGE, &zero, &commit); } else { + /* No arena context as we are creating new arenas. */ + tsd_t *tsd = tsdn_null(tsdn) ? tsd_fetch() : tsdn_tsd(tsdn); + pre_reentrancy(tsd, NULL); addr = extent_hooks->alloc(extent_hooks, NULL, size, PAGE, &zero, &commit, ind); + post_reentrancy(tsd); } return addr; } static void -base_unmap(extent_hooks_t *extent_hooks, unsigned ind, void *addr, +base_unmap(tsdn_t *tsdn, extent_hooks_t *extent_hooks, unsigned ind, void *addr, size_t size) { /* * Cascade through dalloc, decommit, purge_forced, and purge_lazy, @@ -61,27 +65,32 @@ base_unmap(extent_hooks_t *extent_hooks, unsigned ind, void *addr, /* Nothing worked. This should never happen. */ not_reached(); } else { + tsd_t *tsd = tsdn_null(tsdn) ? tsd_fetch() : tsdn_tsd(tsdn); + pre_reentrancy(tsd, NULL); if (extent_hooks->dalloc != NULL && !extent_hooks->dalloc(extent_hooks, addr, size, true, ind)) { - return; + goto label_done; } if (extent_hooks->decommit != NULL && !extent_hooks->decommit(extent_hooks, addr, size, 0, size, ind)) { - return; + goto label_done; } if (extent_hooks->purge_forced != NULL && !extent_hooks->purge_forced(extent_hooks, addr, size, 0, size, ind)) { - return; + goto label_done; } if (extent_hooks->purge_lazy != NULL && !extent_hooks->purge_lazy(extent_hooks, addr, size, 0, size, ind)) { - return; + goto label_done; } /* Nothing worked. That's the application's problem. */ + label_done: + post_reentrancy(tsd); + return; } } @@ -157,7 +166,7 @@ base_extent_bump_alloc(tsdn_t *tsdn, base_t *base, extent_t *extent, * On success a pointer to the initialized base_block_t header is returned. */ static base_block_t * -base_block_alloc(extent_hooks_t *extent_hooks, unsigned ind, +base_block_alloc(tsdn_t *tsdn, extent_hooks_t *extent_hooks, unsigned ind, pszind_t *pind_last, size_t *extent_sn_next, size_t size, size_t alignment) { alignment = ALIGNMENT_CEILING(alignment, QUANTUM); @@ -179,7 +188,7 @@ base_block_alloc(extent_hooks_t *extent_hooks, unsigned ind, size_t next_block_size = HUGEPAGE_CEILING(sz_pind2sz(pind_next)); size_t block_size = (min_block_size > next_block_size) ? min_block_size : next_block_size; - base_block_t *block = (base_block_t *)base_map(extent_hooks, ind, + base_block_t *block = (base_block_t *)base_map(tsdn, extent_hooks, ind, block_size); if (block == NULL) { return NULL; @@ -207,8 +216,9 @@ base_extent_alloc(tsdn_t *tsdn, base_t *base, size_t size, size_t alignment) { * called. */ malloc_mutex_unlock(tsdn, &base->mtx); - base_block_t *block = base_block_alloc(extent_hooks, base_ind_get(base), - &base->pind_last, &base->extent_sn_next, size, alignment); + base_block_t *block = base_block_alloc(tsdn, extent_hooks, + base_ind_get(base), &base->pind_last, &base->extent_sn_next, size, + alignment); malloc_mutex_lock(tsdn, &base->mtx); if (block == NULL) { return NULL; @@ -234,8 +244,8 @@ base_t * base_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) { pszind_t pind_last = 0; size_t extent_sn_next = 0; - base_block_t *block = base_block_alloc(extent_hooks, ind, &pind_last, - &extent_sn_next, sizeof(base_t), QUANTUM); + base_block_t *block = base_block_alloc(tsdn, extent_hooks, ind, + &pind_last, &extent_sn_next, sizeof(base_t), QUANTUM); if (block == NULL) { return NULL; } @@ -249,7 +259,7 @@ base_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) { atomic_store_p(&base->extent_hooks, extent_hooks, ATOMIC_RELAXED); if (malloc_mutex_init(&base->mtx, "base", WITNESS_RANK_BASE, malloc_mutex_rank_exclusive)) { - base_unmap(extent_hooks, ind, block, block->size); + base_unmap(tsdn, extent_hooks, ind, block, block->size); return NULL; } base->pind_last = pind_last; @@ -272,13 +282,13 @@ base_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) { } void -base_delete(base_t *base) { +base_delete(tsdn_t *tsdn, base_t *base) { extent_hooks_t *extent_hooks = base_extent_hooks_get(base); base_block_t *next = base->blocks; do { base_block_t *block = next; next = block->next; - base_unmap(extent_hooks, base_ind_get(base), block, + base_unmap(tsdn, extent_hooks, base_ind_get(base), block, block->size); } while (next != NULL); } diff --git a/contrib/jemalloc/src/ctl.c b/contrib/jemalloc/src/ctl.c index f1310cdf1dbc..36bc8fb5b755 100644 --- a/contrib/jemalloc/src/ctl.c +++ b/contrib/jemalloc/src/ctl.c @@ -622,7 +622,7 @@ arenas_i2a(size_t i) { } static ctl_arena_t * -arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) { +arenas_i_impl(tsd_t *tsd, size_t i, bool compat, bool init) { ctl_arena_t *ret; assert(!compat || !init); @@ -635,15 +635,15 @@ arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) { ctl_arena_stats_t astats; }; struct container_s *cont = - (struct container_s *)base_alloc(tsdn, b0get(), - sizeof(struct container_s), QUANTUM); + (struct container_s *)base_alloc(tsd_tsdn(tsd), + b0get(), sizeof(struct container_s), QUANTUM); if (cont == NULL) { return NULL; } ret = &cont->ctl_arena; ret->astats = &cont->astats; } else { - ret = (ctl_arena_t *)base_alloc(tsdn, b0get(), + ret = (ctl_arena_t *)base_alloc(tsd_tsdn(tsd), b0get(), sizeof(ctl_arena_t), QUANTUM); if (ret == NULL) { return NULL; @@ -659,7 +659,7 @@ arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) { static ctl_arena_t * arenas_i(size_t i) { - ctl_arena_t *ret = arenas_i_impl(TSDN_NULL, i, true, false); + ctl_arena_t *ret = arenas_i_impl(tsd_fetch(), i, true, false); assert(ret != NULL); return ret; } @@ -863,7 +863,7 @@ ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena, } static unsigned -ctl_arena_init(tsdn_t *tsdn, extent_hooks_t *extent_hooks) { +ctl_arena_init(tsd_t *tsd, extent_hooks_t *extent_hooks) { unsigned arena_ind; ctl_arena_t *ctl_arena; @@ -876,12 +876,12 @@ ctl_arena_init(tsdn_t *tsdn, extent_hooks_t *extent_hooks) { } /* Trigger stats allocation. */ - if (arenas_i_impl(tsdn, arena_ind, false, true) == NULL) { + if (arenas_i_impl(tsd, arena_ind, false, true) == NULL) { return UINT_MAX; } /* Initialize new arena. */ - if (arena_init(tsdn, arena_ind, extent_hooks) == NULL) { + if (arena_init(tsd_tsdn(tsd), arena_ind, extent_hooks) == NULL) { return UINT_MAX; } @@ -975,8 +975,9 @@ ctl_refresh(tsdn_t *tsdn) { } static bool -ctl_init(tsdn_t *tsdn) { +ctl_init(tsd_t *tsd) { bool ret; + tsdn_t *tsdn = tsd_tsdn(tsd); malloc_mutex_lock(tsdn, &ctl_mtx); if (!ctl_initialized) { @@ -1010,14 +1011,14 @@ ctl_init(tsdn_t *tsdn) { * here rather than doing it lazily elsewhere, in order * to limit when OOM-caused errors can occur. */ - if ((ctl_sarena = arenas_i_impl(tsdn, MALLCTL_ARENAS_ALL, false, + if ((ctl_sarena = arenas_i_impl(tsd, MALLCTL_ARENAS_ALL, false, true)) == NULL) { ret = true; goto label_return; } ctl_sarena->initialized = true; - if ((ctl_darena = arenas_i_impl(tsdn, MALLCTL_ARENAS_DESTROYED, + if ((ctl_darena = arenas_i_impl(tsd, MALLCTL_ARENAS_DESTROYED, false, true)) == NULL) { ret = true; goto label_return; @@ -1031,7 +1032,7 @@ ctl_init(tsdn_t *tsdn) { ctl_arenas->narenas = narenas_total_get(); for (i = 0; i < ctl_arenas->narenas; i++) { - if (arenas_i_impl(tsdn, i, false, true) == NULL) { + if (arenas_i_impl(tsd, i, false, true) == NULL) { ret = true; goto label_return; } @@ -1156,7 +1157,7 @@ ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, size_t mib[CTL_MAX_DEPTH]; const ctl_named_node_t *node; - if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { + if (!ctl_initialized && ctl_init(tsd)) { ret = EAGAIN; goto label_return; } @@ -1180,15 +1181,15 @@ ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, } int -ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) { +ctl_nametomib(tsd_t *tsd, const char *name, size_t *mibp, size_t *miblenp) { int ret; - if (!ctl_initialized && ctl_init(tsdn)) { + if (!ctl_initialized && ctl_init(tsd)) { ret = EAGAIN; goto label_return; } - ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp); + ret = ctl_lookup(tsd_tsdn(tsd), name, NULL, mibp, miblenp); label_return: return(ret); } @@ -1200,7 +1201,7 @@ ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, const ctl_named_node_t *node; size_t i; - if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { + if (!ctl_initialized && ctl_init(tsd)) { ret = EAGAIN; goto label_return; } @@ -1696,7 +1697,7 @@ thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, READONLY(); WRITEONLY(); - tcache_flush(); + tcache_flush(tsd); ret = 0; label_return: @@ -1970,7 +1971,7 @@ arena_reset_finish_background_thread(tsd_t *tsd, unsigned arena_ind) { unsigned ind = arena_ind % ncpus; background_thread_info_t *info = &background_thread_info[ind]; - assert(info->state = background_thread_paused); + assert(info->state == background_thread_paused); malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx); info->state = background_thread_started; malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx); @@ -2312,8 +2313,7 @@ arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, extent_hooks = (extent_hooks_t *)&extent_hooks_default; WRITE(extent_hooks, extent_hooks_t *); - if ((arena_ind = ctl_arena_init(tsd_tsdn(tsd), extent_hooks)) == - UINT_MAX) { + if ((arena_ind = ctl_arena_init(tsd, extent_hooks)) == UINT_MAX) { ret = EAGAIN; goto label_return; } diff --git a/contrib/jemalloc/src/extent.c b/contrib/jemalloc/src/extent.c index f31ed32ebb9a..fa45c84d34f3 100644 --- a/contrib/jemalloc/src/extent.c +++ b/contrib/jemalloc/src/extent.c @@ -1025,6 +1025,18 @@ extent_alloc_default(extent_hooks_t *extent_hooks, void *new_addr, size_t size, alignment, zero, commit); } +static void +extent_hook_pre_reentrancy(tsdn_t *tsdn, arena_t *arena) { + tsd_t *tsd = tsdn_null(tsdn) ? tsd_fetch() : tsdn_tsd(tsdn); + pre_reentrancy(tsd, arena); +} + +static void +extent_hook_post_reentrancy(tsdn_t *tsdn) { + tsd_t *tsd = tsdn_null(tsdn) ? tsd_fetch() : tsdn_tsd(tsdn); + post_reentrancy(tsd); +} + /* * If virtual memory is retained, create increasingly larger extents from which * to split requested extents in order to limit the total number of disjoint @@ -1073,9 +1085,11 @@ extent_grow_retained(tsdn_t *tsdn, arena_t *arena, &zeroed, &committed, (dss_prec_t)atomic_load_u( &arena->dss_prec, ATOMIC_RELAXED)); } else { + extent_hook_pre_reentrancy(tsdn, arena); ptr = (*r_extent_hooks)->alloc(*r_extent_hooks, NULL, alloc_size, PAGE, &zeroed, &committed, arena_ind_get(arena)); + extent_hook_post_reentrancy(tsdn); } extent_init(extent, arena, ptr, alloc_size, false, NSIZES, @@ -1247,8 +1261,10 @@ extent_alloc_wrapper_hard(tsdn_t *tsdn, arena_t *arena, addr = extent_alloc_default_impl(tsdn, arena, new_addr, esize, alignment, zero, commit); } else { + extent_hook_pre_reentrancy(tsdn, arena); addr = (*r_extent_hooks)->alloc(*r_extent_hooks, new_addr, esize, alignment, zero, commit, arena_ind_get(arena)); + extent_hook_post_reentrancy(tsdn); } if (addr == NULL) { extent_dalloc(tsdn, arena, extent); @@ -1486,10 +1502,12 @@ extent_dalloc_wrapper_try(tsdn_t *tsdn, arena_t *arena, err = extent_dalloc_default_impl(extent_base_get(extent), extent_size_get(extent)); } else { + extent_hook_pre_reentrancy(tsdn, arena); err = ((*r_extent_hooks)->dalloc == NULL || (*r_extent_hooks)->dalloc(*r_extent_hooks, extent_base_get(extent), extent_size_get(extent), extent_committed_get(extent), arena_ind_get(arena))); + extent_hook_post_reentrancy(tsdn); } if (!err) { @@ -1515,6 +1533,9 @@ extent_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, } extent_reregister(tsdn, extent); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_pre_reentrancy(tsdn, arena); + } /* Try to decommit; purge if that fails. */ bool zeroed; if (!extent_committed_get(extent)) { @@ -1536,6 +1557,9 @@ extent_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, } else { zeroed = false; } + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_post_reentrancy(tsdn); + } extent_zeroed_set(extent, zeroed); if (config_prof) { @@ -1579,9 +1603,11 @@ extent_destroy_wrapper(tsdn_t *tsdn, arena_t *arena, extent_destroy_default_impl(extent_base_get(extent), extent_size_get(extent)); } else if ((*r_extent_hooks)->destroy != NULL) { + extent_hook_pre_reentrancy(tsdn, arena); (*r_extent_hooks)->destroy(*r_extent_hooks, extent_base_get(extent), extent_size_get(extent), extent_committed_get(extent), arena_ind_get(arena)); + extent_hook_post_reentrancy(tsdn); } extent_dalloc(tsdn, arena, extent); @@ -1602,9 +1628,15 @@ extent_commit_impl(tsdn_t *tsdn, arena_t *arena, WITNESS_RANK_CORE, growing_retained ? 1 : 0); extent_hooks_assure_initialized(arena, r_extent_hooks); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_pre_reentrancy(tsdn, arena); + } bool err = ((*r_extent_hooks)->commit == NULL || (*r_extent_hooks)->commit(*r_extent_hooks, extent_base_get(extent), extent_size_get(extent), offset, length, arena_ind_get(arena))); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_post_reentrancy(tsdn); + } extent_committed_set(extent, extent_committed_get(extent) || !err); return err; } @@ -1633,10 +1665,16 @@ extent_decommit_wrapper(tsdn_t *tsdn, arena_t *arena, extent_hooks_assure_initialized(arena, r_extent_hooks); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_pre_reentrancy(tsdn, arena); + } bool err = ((*r_extent_hooks)->decommit == NULL || (*r_extent_hooks)->decommit(*r_extent_hooks, extent_base_get(extent), extent_size_get(extent), offset, length, arena_ind_get(arena))); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_post_reentrancy(tsdn); + } extent_committed_set(extent, extent_committed_get(extent) && err); return err; } @@ -1663,10 +1701,21 @@ extent_purge_lazy_impl(tsdn_t *tsdn, arena_t *arena, WITNESS_RANK_CORE, growing_retained ? 1 : 0); extent_hooks_assure_initialized(arena, r_extent_hooks); - return ((*r_extent_hooks)->purge_lazy == NULL || - (*r_extent_hooks)->purge_lazy(*r_extent_hooks, + + if ((*r_extent_hooks)->purge_lazy == NULL) { + return true; + } + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_pre_reentrancy(tsdn, arena); + } + bool err = (*r_extent_hooks)->purge_lazy(*r_extent_hooks, extent_base_get(extent), extent_size_get(extent), offset, length, - arena_ind_get(arena))); + arena_ind_get(arena)); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_post_reentrancy(tsdn); + } + + return err; } bool @@ -1699,10 +1748,20 @@ extent_purge_forced_impl(tsdn_t *tsdn, arena_t *arena, WITNESS_RANK_CORE, growing_retained ? 1 : 0); extent_hooks_assure_initialized(arena, r_extent_hooks); - return ((*r_extent_hooks)->purge_forced == NULL || - (*r_extent_hooks)->purge_forced(*r_extent_hooks, + + if ((*r_extent_hooks)->purge_forced == NULL) { + return true; + } + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_pre_reentrancy(tsdn, arena); + } + bool err = (*r_extent_hooks)->purge_forced(*r_extent_hooks, extent_base_get(extent), extent_size_get(extent), offset, length, - arena_ind_get(arena))); + arena_ind_get(arena)); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_post_reentrancy(tsdn); + } + return err; } bool @@ -1771,9 +1830,16 @@ extent_split_impl(tsdn_t *tsdn, arena_t *arena, extent_lock2(tsdn, extent, trail); - if ((*r_extent_hooks)->split(*r_extent_hooks, extent_base_get(extent), + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_pre_reentrancy(tsdn, arena); + } + bool err = (*r_extent_hooks)->split(*r_extent_hooks, extent_base_get(extent), size_a + size_b, size_a, size_b, extent_committed_get(extent), - arena_ind_get(arena))) { + arena_ind_get(arena)); + if (*r_extent_hooks != &extent_hooks_default) { + extent_hook_post_reentrancy(tsdn); + } + if (err) { goto label_error_c; } @@ -1843,10 +1909,12 @@ extent_merge_impl(tsdn_t *tsdn, arena_t *arena, err = extent_merge_default_impl(extent_base_get(a), extent_base_get(b)); } else { + extent_hook_pre_reentrancy(tsdn, arena); err = (*r_extent_hooks)->merge(*r_extent_hooks, extent_base_get(a), extent_size_get(a), extent_base_get(b), extent_size_get(b), extent_committed_get(a), arena_ind_get(arena)); + extent_hook_post_reentrancy(tsdn); } if (err) { diff --git a/contrib/jemalloc/src/jemalloc.c b/contrib/jemalloc/src/jemalloc.c index 868c9e867c9d..0d747ea84c46 100644 --- a/contrib/jemalloc/src/jemalloc.c +++ b/contrib/jemalloc/src/jemalloc.c @@ -1480,7 +1480,7 @@ malloc_init_hard(void) { malloc_mutex_lock(tsd_tsdn(tsd), &init_lock); /* Set reentrancy level to 1 during init. */ - pre_reentrancy(tsd); + pre_reentrancy(tsd, NULL); /* Initialize narenas before prof_boot2 (for allocation). */ if (malloc_init_narenas() || background_thread_boot1(tsd_tsdn(tsd))) { UNLOCK_RETURN(tsd_tsdn(tsd), true, true) @@ -1803,7 +1803,7 @@ imalloc_body(static_opts_t *sopts, dynamic_opts_t *dopts, tsd_t *tsd) { */ assert(dopts->tcache_ind == TCACHE_IND_AUTOMATIC || dopts->tcache_ind == TCACHE_IND_NONE); - assert(dopts->arena_ind = ARENA_IND_AUTOMATIC); + assert(dopts->arena_ind == ARENA_IND_AUTOMATIC); dopts->tcache_ind = TCACHE_IND_NONE; /* We know that arena 0 has already been initialized. */ dopts->arena_ind = 0; @@ -2268,7 +2268,15 @@ JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_free(void *ptr) { UTRACE(ptr, 0, 0); if (likely(ptr != NULL)) { - tsd_t *tsd = tsd_fetch(); + /* + * We avoid setting up tsd fully (e.g. tcache, arena binding) + * based on only free() calls -- other activities trigger the + * minimal to full transition. This is because free() may + * happen during thread shutdown after tls deallocation: if a + * thread never had any malloc activities until then, a + * fully-setup tsd won't be destructed properly. + */ + tsd_t *tsd = tsd_fetch_min(); check_entry_exit_locking(tsd_tsdn(tsd)); tcache_t *tcache; @@ -2914,16 +2922,15 @@ je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlnametomib(const char *name, size_t *mibp, size_t *miblenp) { int ret; - tsdn_t *tsdn; if (unlikely(malloc_init())) { return EAGAIN; } - tsdn = tsdn_fetch(); - check_entry_exit_locking(tsdn); - ret = ctl_nametomib(tsdn, name, mibp, miblenp); - check_entry_exit_locking(tsdn); + tsd_t *tsd = tsd_fetch(); + check_entry_exit_locking(tsd_tsdn(tsd)); + ret = ctl_nametomib(tsd, name, mibp, miblenp); + check_entry_exit_locking(tsd_tsdn(tsd)); return ret; } @@ -3143,7 +3150,7 @@ _malloc_prefork(void) background_thread_prefork1(tsd_tsdn(tsd)); } /* Break arena prefork into stages to preserve lock order. */ - for (i = 0; i < 7; i++) { + for (i = 0; i < 8; i++) { for (j = 0; j < narenas; j++) { if ((arena = arena_get(tsd_tsdn(tsd), j, false)) != NULL) { @@ -3169,6 +3176,9 @@ _malloc_prefork(void) case 6: arena_prefork6(tsd_tsdn(tsd), arena); break; + case 7: + arena_prefork7(tsd_tsdn(tsd), arena); + break; default: not_reached(); } } diff --git a/contrib/jemalloc/src/prof.c b/contrib/jemalloc/src/prof.c index 61dfa2cee588..975722c4c38a 100644 --- a/contrib/jemalloc/src/prof.c +++ b/contrib/jemalloc/src/prof.c @@ -1633,7 +1633,7 @@ prof_dump(tsd_t *tsd, bool propagate_err, const char *filename, return true; } - pre_reentrancy(tsd); + pre_reentrancy(tsd, NULL); malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_mtx); prof_gctx_tree_t gctxs; diff --git a/contrib/jemalloc/src/tcache.c b/contrib/jemalloc/src/tcache.c index 6355805b196f..936ef3140d51 100644 --- a/contrib/jemalloc/src/tcache.c +++ b/contrib/jemalloc/src/tcache.c @@ -474,8 +474,7 @@ tcache_flush_cache(tsd_t *tsd, tcache_t *tcache) { } void -tcache_flush(void) { - tsd_t *tsd = tsd_fetch(); +tcache_flush(tsd_t *tsd) { assert(tcache_available(tsd)); tcache_flush_cache(tsd, tsd_tcachep_get(tsd)); } diff --git a/contrib/jemalloc/src/tsd.c b/contrib/jemalloc/src/tsd.c index 97330332d119..f968992f2b59 100644 --- a/contrib/jemalloc/src/tsd.c +++ b/contrib/jemalloc/src/tsd.c @@ -87,7 +87,8 @@ assert_tsd_data_cleanup_done(tsd_t *tsd) { static bool tsd_data_init_nocleanup(tsd_t *tsd) { - assert(tsd->state == tsd_state_reincarnated); + assert(tsd->state == tsd_state_reincarnated || + tsd->state == tsd_state_minimal_initialized); /* * During reincarnation, there is no guarantee that the cleanup function * will be called (deallocation may happen after all tsd destructors). @@ -103,15 +104,8 @@ tsd_data_init_nocleanup(tsd_t *tsd) { } tsd_t * -tsd_fetch_slow(tsd_t *tsd, bool internal) { - if (internal) { - /* For internal background threads use only. */ - assert(tsd->state == tsd_state_uninitialized); - tsd->state = tsd_state_reincarnated; - tsd_set(tsd); - tsd_data_init_nocleanup(tsd); - return tsd; - } +tsd_fetch_slow(tsd_t *tsd, bool minimal) { + assert(!tsd_fast(tsd)); if (tsd->state == tsd_state_nominal_slow) { /* On slow path but no work needed. */ @@ -119,11 +113,28 @@ tsd_fetch_slow(tsd_t *tsd, bool internal) { tsd_reentrancy_level_get(tsd) > 0 || *tsd_arenas_tdata_bypassp_get(tsd)); } else if (tsd->state == tsd_state_uninitialized) { - tsd->state = tsd_state_nominal; - tsd_slow_update(tsd); - /* Trigger cleanup handler registration. */ - tsd_set(tsd); - tsd_data_init(tsd); + if (!minimal) { + tsd->state = tsd_state_nominal; + tsd_slow_update(tsd); + /* Trigger cleanup handler registration. */ + tsd_set(tsd); + tsd_data_init(tsd); + } else { + tsd->state = tsd_state_minimal_initialized; + tsd_set(tsd); + tsd_data_init_nocleanup(tsd); + } + } else if (tsd->state == tsd_state_minimal_initialized) { + if (!minimal) { + /* Switch to fully initialized. */ + tsd->state = tsd_state_nominal; + assert(*tsd_reentrancy_levelp_get(tsd) >= 1); + (*tsd_reentrancy_levelp_get(tsd))--; + tsd_slow_update(tsd); + tsd_data_init(tsd); + } else { + assert_tsd_data_cleanup_done(tsd); + } } else if (tsd->state == tsd_state_purgatory) { tsd->state = tsd_state_reincarnated; tsd_set(tsd); @@ -197,6 +208,9 @@ tsd_cleanup(void *arg) { case tsd_state_uninitialized: /* Do nothing. */ break; + case tsd_state_minimal_initialized: + /* This implies the thread only did free() in its life time. */ + /* Fall through. */ case tsd_state_reincarnated: /* * Reincarnated means another destructor deallocated memory diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS index 9e517934547e..9527e662a86e 100644 --- a/contrib/libarchive/NEWS +++ b/contrib/libarchive/NEWS @@ -1,3 +1,5 @@ +Jul 09, 2017: libarchive 3.3.2 released + Mar 16, 2017: NFSv4 ACL support for Linux (librichacl) Feb 26, 2017: libarchive 3.3.1 released diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h index 586c73ad6f24..c3681e60c50a 100644 --- a/contrib/libarchive/libarchive/archive.h +++ b/contrib/libarchive/libarchive/archive.h @@ -36,7 +36,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */ -#define ARCHIVE_VERSION_NUMBER 3003001 +#define ARCHIVE_VERSION_NUMBER 3003002 #include #include /* for wchar_t */ @@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_ONLY_STRING "3.3.1" +#define ARCHIVE_VERSION_ONLY_STRING "3.3.2" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h index 97758e223d44..793e2330e52a 100644 --- a/contrib/libarchive/libarchive/archive_entry.h +++ b/contrib/libarchive/libarchive/archive_entry.h @@ -30,7 +30,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */ -#define ARCHIVE_VERSION_NUMBER 3003001 +#define ARCHIVE_VERSION_NUMBER 3003002 /* * Note: archive_entry.h is for use outside of libarchive; the diff --git a/contrib/libarchive/libarchive/test/test_archive_read_close_twice_open_filename.c b/contrib/libarchive/libarchive/test/test_archive_read_close_twice_open_filename.c index f82539117bcb..9a194fdc4a8b 100644 --- a/contrib/libarchive/libarchive/test/test_archive_read_close_twice_open_filename.c +++ b/contrib/libarchive/libarchive/test/test_archive_read_close_twice_open_filename.c @@ -28,10 +28,12 @@ __FBSDID("$FreeBSD$"); DEFINE_TEST(test_archive_read_close_twice_open_filename) { + const char *filename = "empty.file"; struct archive* a = archive_read_new(); + assertMakeFile(filename, 0644, ""); assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a)); - assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, 0, 0)); + assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, filename, 0)); assertEqualInt(0, archive_errno(a)); assertEqualString(NULL, archive_error_string(a)); diff --git a/contrib/libpcap/bpf/net/bpf_filter.c b/contrib/libpcap/bpf/net/bpf_filter.c index 01a1b64e7197..0a80cdc52883 100644 --- a/contrib/libpcap/bpf/net/bpf_filter.c +++ b/contrib/libpcap/bpf/net/bpf_filter.c @@ -61,7 +61,12 @@ #include #include -#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__))) +#if (defined(sun) && (defined(__SVR4) || defined(__svr4__))) +#define SOLARIS 1 +#else +#define SOLARIS 0 +#endif + #if defined(__hpux) || SOLARIS # include # include diff --git a/contrib/mdocml/lib.in b/contrib/mdocml/lib.in index e3e1af2aecd2..716756d3d04d 100644 --- a/contrib/mdocml/lib.in +++ b/contrib/mdocml/lib.in @@ -46,6 +46,7 @@ LINE("libdevctl", "Device Control Library (libdevctl, \\-ldevctl)") LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)") LINE("libdevstat", "Device Statistics Library (libdevstat, \\-ldevstat)") LINE("libdisk", "Interface to Slice and Partition Labels Library (libdisk, \\-ldisk)") +LINE("libdl", "Dynamic Linker Services Filter (libdl, \\-ldl)") LINE("libdm", "Device Mapper Library (libdm, \\-ldm)") LINE("libdwarf", "DWARF Access Library (libdwarf, \\-ldwarf)") LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)") diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c index 02dd17694740..5900a29cc028 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c @@ -34,11 +34,13 @@ __RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $"); #include #include +#include #include +#include #include #include -static char domain[MAXHOSTNAMELEN]; +#define DOMAIN_BACKUP_FILE "domain.bak" static const char domains[][MAXHOSTNAMELEN] = { "1234567890", @@ -47,6 +49,45 @@ static const char domains[][MAXHOSTNAMELEN] = { "--------------------------------------------------------------------" }; +static void +backup_domain(void) +{ + char domain[MAXHOSTNAMELEN]; + int fd; + size_t l; + ssize_t r,n = 0; + + memset(domain, 0, sizeof(domain)); + + ATF_REQUIRE_EQ(0, getdomainname(domain, sizeof(domain))); + l = strnlen(domain, MAXHOSTNAMELEN); + fd = open(DOMAIN_BACKUP_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644); + ATF_REQUIRE(fd >= 0); + while ((r = write(fd, domain + n, l - n)) > 0) + n += r; + ATF_REQUIRE_EQ(0, r); + close(fd); +} + +static void +restore_domain(void) +{ + char domain[MAXHOSTNAMELEN]; + int fd; + ssize_t r, n = 0; + + memset(domain, 0, sizeof(domain)); + if ((fd = open(DOMAIN_BACKUP_FILE, O_RDONLY)) < 0) + err(1, "open"); + while ((r = read(fd, domain + n, sizeof(domain) - n)) > 0) + n += r; + if (r < 0) + err(1, "read"); + if (setdomainname(domain, n) != 0) + err(1, "setdomainname"); + close(fd); +} + ATF_TC_WITH_CLEANUP(setdomainname_basic); ATF_TC_HEAD(setdomainname_basic, tc) { @@ -59,6 +100,7 @@ ATF_TC_BODY(setdomainname_basic, tc) char name[MAXHOSTNAMELEN]; size_t i; + backup_domain(); for (i = 0; i < __arraycount(domains); i++) { (void)memset(name, 0, sizeof(name)); @@ -80,12 +122,11 @@ ATF_TC_BODY(setdomainname_basic, tc) ATF_REQUIRE(strcmp(domains[i], name) == 0); } - (void)setdomainname(domain, sizeof(domain)); } ATF_TC_CLEANUP(setdomainname_basic, tc) { - (void)setdomainname(domain, sizeof(domain)); + restore_domain(); } ATF_TC_WITH_CLEANUP(setdomainname_limit); @@ -100,6 +141,7 @@ ATF_TC_BODY(setdomainname_limit, tc) char name[MAXHOSTNAMELEN + 1]; (void)memset(name, 0, sizeof(name)); + backup_domain(); #ifdef __FreeBSD__ ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN - 1 ) == 0); @@ -110,10 +152,10 @@ ATF_TC_BODY(setdomainname_limit, tc) ATF_TC_CLEANUP(setdomainname_limit, tc) { - (void)setdomainname(domain, sizeof(domain)); + restore_domain(); } -ATF_TC_WITH_CLEANUP(setdomainname_perm); +ATF_TC(setdomainname_perm); ATF_TC_HEAD(setdomainname_perm, tc) { atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?"); @@ -122,24 +164,16 @@ ATF_TC_HEAD(setdomainname_perm, tc) ATF_TC_BODY(setdomainname_perm, tc) { + char domain[MAXHOSTNAMELEN]; + + memset(domain, 0, sizeof(domain)); errno = 0; - ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1); } -ATF_TC_CLEANUP(setdomainname_perm, tc) -{ - (void)setdomainname(domain, sizeof(domain)); -} - ATF_TP_ADD_TCS(tp) { - - (void)memset(domain, 0, sizeof(domain)); - - ATF_REQUIRE(getdomainname(domain, sizeof(domain)) == 0); - ATF_TP_ADD_TC(tp, setdomainname_basic); ATF_TP_ADD_TC(tp, setdomainname_limit); ATF_TP_ADD_TC(tp, setdomainname_perm); diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c index 95b4b2c9dffe..5fda26ea2720 100644 --- a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c +++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c @@ -127,6 +127,10 @@ ATF_TC_HEAD(snprintf_float, tc) atf_tc_set_md_var(tc, "descr", "test that floating conversions don't" " leak memory"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.memory", "64m"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif } ATF_TC_BODY(snprintf_float, tc) @@ -140,10 +144,17 @@ ATF_TC_BODY(snprintf_float, tc) char buf[1000]; struct rlimit rl; +#ifdef __FreeBSD__ + rl.rlim_cur = rl.rlim_max = 32 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_AS, &rl) != -1); + rl.rlim_cur = rl.rlim_max = 32 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_DATA, &rl) != -1); +#else rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; ATF_CHECK(setrlimit(RLIMIT_AS, &rl) != -1); rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; ATF_CHECK(setrlimit(RLIMIT_DATA, &rl) != -1); +#endif time(&now); srand(now); diff --git a/crypto/heimdal/lib/krb5/ticket.c b/crypto/heimdal/lib/krb5/ticket.c index 4845a93d9446..5b6eabe2b0e0 100644 --- a/crypto/heimdal/lib/krb5/ticket.c +++ b/crypto/heimdal/lib/krb5/ticket.c @@ -713,8 +713,8 @@ _krb5_extract_ticket(krb5_context context, /* check server referral and save principal */ ret = _krb5_principalname2krb5_principal (context, &tmp_principal, - rep->kdc_rep.ticket.sname, - rep->kdc_rep.ticket.realm); + rep->enc_part.sname, + rep->enc_part.srealm); if (ret) goto out; if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){ diff --git a/etc/Makefile b/etc/Makefile index 7eadb1bba99b..9713c795eae4 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -342,19 +342,6 @@ distribution: MTREE_CMD?= mtree -.if ${MK_INSTALL_AS_USER} == "yes" && ${_uid} != 0 -MTREE_FILTER= sed -e 's,\([gu]\)name=,\1id=,g' \ - -e 's,\(uid=\)[^ ]* ,\1${_uid} ,' \ - -e 's,\(gid=\)[^ ]* ,\1${_gid} ,' \ - -e 's,\(uid=\)[^ ]*$$,\1${_uid},' \ - -e 's,\(gid=\)[^ ]*$$,\1${_gid},' -.else -MTREE_FILTER= cat -.if !defined(NO_FSCHG) -MTREE_FSCHG= -i -.endif -.endif - MTREES= mtree/BSD.root.dist / \ mtree/BSD.var.dist /var \ mtree/BSD.usr.dist /usr \ @@ -467,3 +454,16 @@ etc-examples: etc-examples-install DESTDIR=${DESTDIR}${SHAREDIR}/examples .include + +.if ${MK_INSTALL_AS_USER} == "yes" && ${_uid} != 0 +MTREE_FILTER= sed -e 's,\([gu]\)name=,\1id=,g' \ + -e 's,\(uid=\)[^ ]* ,\1${_uid} ,' \ + -e 's,\(gid=\)[^ ]* ,\1${_gid} ,' \ + -e 's,\(uid=\)[^ ]*$$,\1${_uid},' \ + -e 's,\(gid=\)[^ ]*$$,\1${_gid},' +.else +MTREE_FILTER= cat +.if !defined(NO_FSCHG) +MTREE_FSCHG= -i +.endif +.endif diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index b8ae9596e6bb..3f2b3742d238 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -92,7 +92,7 @@ geli_autodetach="YES" # Automatically detach on last close. root_rw_mount="YES" # Set to NO to inhibit remounting root read-write. root_hold_delay="30" # Time to wait for root mount hold release. fsck_y_enable="NO" # Set to YES to do fsck -y if the initial preen fails. -fsck_y_flags="" # Additional flags for fsck -y +fsck_y_flags="-T ffs:-R -T ufs:-R" # Additional flags for fsck -y background_fsck="YES" # Attempt to run fsck in the background where possible. background_fsck_delay="60" # Time to wait (seconds) before starting the fsck. netfs_types="nfs:NFS smbfs:SMB" # Net filesystems. diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index 0e6316354a76..717a8f777582 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -90,6 +90,8 @@ cam ata .. + mmc + .. nvme .. scsi @@ -234,7 +236,7 @@ gssapi .. infiniband - complib + complib .. iba .. diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 3ddd8cc278fc..56ecb47e4dca 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -400,6 +400,8 @@ .. .. .. + zoneinfo + .. .. sys acl @@ -642,6 +644,8 @@ .. gzip .. + hexdump + .. ident .. indent diff --git a/etc/rc.d/bsnmpd b/etc/rc.d/bsnmpd index a29926f31775..ecebfe0174a3 100755 --- a/etc/rc.d/bsnmpd +++ b/etc/rc.d/bsnmpd @@ -5,7 +5,7 @@ # PROVIDE: bsnmpd # REQUIRE: NETWORKING syslogd -# KEYWORD: nojail shutdown +# KEYWORD: nojailvnet shutdown . /etc/rc.subr diff --git a/etc/rc.d/defaultroute b/etc/rc.d/defaultroute index cc10a01a9a35..a4c9647766a8 100755 --- a/etc/rc.d/defaultroute +++ b/etc/rc.d/defaultroute @@ -7,7 +7,7 @@ # PROVIDE: defaultroute # REQUIRE: devd netif stf -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr . /etc/network.subr diff --git a/etc/rc.d/dhclient b/etc/rc.d/dhclient index f2d17c5c04b2..eb9860ea4cc0 100755 --- a/etc/rc.d/dhclient +++ b/etc/rc.d/dhclient @@ -4,7 +4,7 @@ # # PROVIDE: dhclient -# KEYWORD: nojail nostart +# KEYWORD: nojailvnet nostart . /etc/rc.subr . /etc/network.subr diff --git a/etc/rc.d/ip6addrctl b/etc/rc.d/ip6addrctl index 8752f09eb38b..3260b1cab9a5 100755 --- a/etc/rc.d/ip6addrctl +++ b/etc/rc.d/ip6addrctl @@ -6,7 +6,7 @@ # PROVIDE: ip6addrctl # REQUIRE: FILESYSTEMS # BEFORE: netif -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr . /etc/network.subr diff --git a/etc/rc.d/ipfw b/etc/rc.d/ipfw index deb9bdad137d..b9417f6679db 100755 --- a/etc/rc.d/ipfw +++ b/etc/rc.d/ipfw @@ -17,7 +17,9 @@ start_cmd="ipfw_start" start_precmd="ipfw_prestart" start_postcmd="ipfw_poststart" stop_cmd="ipfw_stop" +status_cmd="ipfw_status" required_modules="ipfw" +extra_commands="status" set_rcvar_obsolete ipv6_firewall_enable @@ -109,6 +111,18 @@ ipfw_stop() done } +ipfw_status() +{ + status=$(sysctl -n net.inet.ip.fw.enable) + if [ ${status} -eq 0 ]; then + echo "ipfw is not enabled" + exit 1 + else + echo "ipfw is enabled" + exit 0 + fi +} + load_rc_config $name firewall_coscripts="/etc/rc.d/natd ${firewall_coscripts}" diff --git a/etc/rc.d/ipfw_netflow b/etc/rc.d/ipfw_netflow new file mode 100755 index 000000000000..9ef14997e954 --- /dev/null +++ b/etc/rc.d/ipfw_netflow @@ -0,0 +1,77 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: ipfw_netflow +# REQUIRE: ipfw +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="ipfw_netflow" +desc="firewall, ipfw, netflow" +rcvar="${name}_enable" +start_cmd="${name}_start" +stop_cmd="${name}_stop" +start_precmd="${name}_test" +status_cmd="${name}_status" +required_modules="ipfw ng_netflow ng_ipfw" +extra_commands="status" + +: ${ipfw_netflow_hook:=9995} +: ${ipfw_netflow_rule:=01000} +: ${ipfw_netflow_ip:=127.0.0.1} +: ${ipfw_netflow_port:=9995} +: ${ipfw_netflow_version:=} + +ipfw_netflow_test() +{ + if [ "${ipfw_netflow_version}" != "" ] && [ "${ipfw_netflow_version}" != 9 ]; then + err 1 "Unknown netflow version \'${ipfw_netflow_version}\'" + fi + case "${ipfw_netflow_hook}" in + [!0-9]*) + err 1 "Bad value \"${ipfw_netflow_hook}\": Hook must be numerical" + esac + case "${ipfw_netflow_rule}" in + [!0-9]*) + err 1 "Bad value \"${ipfw_netflow_rule}\": Rule number must be numerical" + esac +} + +ipfw_netflow_is_running() +{ + ngctl show netflow: > /dev/null 2>&1 && return 0 || return 1 +} + +ipfw_netflow_status() +{ + ipfw_netflow_is_running && echo "ipfw_netflow is active" || echo "ipfw_netflow is not active" +} + +ipfw_netflow_start() +{ + ipfw_netflow_is_running && err 1 "ipfw_netflow is already active" + ipfw add ${ipfw_netflow_rule} ngtee ${ipfw_netflow_hook} ip from any to any + ngctl -f - <<-EOF + mkpeer ipfw: netflow ${ipfw_netflow_hook} iface0 + name ipfw:${ipfw_netflow_hook} netflow + mkpeer netflow: ksocket export${ipfw_netflow_version} inet/dgram/udp + msg netflow: setdlt {iface=0 dlt=12} + name netflow:export${ipfw_netflow_version} netflow_export + msg netflow:export${ipfw_netflow_version} connect inet/${ipfw_netflow_ip}:${ipfw_netflow_port} +EOF +} + +ipfw_netflow_stop() +{ + ipfw_netflow_is_running || err 1 "ipfw_netflow is not active" + ngctl shutdown netflow: + ipfw delete ${ipfw_netflow_rule} +} + +load_rc_config $name + +run_rc_command $* diff --git a/etc/rc.d/ipsec b/etc/rc.d/ipsec index 5e12f646b81c..a48bd485d999 100755 --- a/etc/rc.d/ipsec +++ b/etc/rc.d/ipsec @@ -6,7 +6,7 @@ # PROVIDE: ipsec # REQUIRE: FILESYSTEMS # BEFORE: DAEMON mountcritremote -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr diff --git a/etc/rc.d/natd b/etc/rc.d/natd index 1a16d981a17b..635113581805 100755 --- a/etc/rc.d/natd +++ b/etc/rc.d/natd @@ -4,7 +4,7 @@ # # PROVIDE: natd -# KEYWORD: nostart nojail +# KEYWORD: nostart nojailvnet . /etc/rc.subr . /etc/network.subr diff --git a/etc/rc.d/pf b/etc/rc.d/pf index 4f8cbfc123ea..cab7d8ee9eae 100755 --- a/etc/rc.d/pf +++ b/etc/rc.d/pf @@ -6,7 +6,7 @@ # PROVIDE: pf # REQUIRE: FILESYSTEMS netif pflog pfsync # BEFORE: routing -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr diff --git a/etc/rc.d/pflog b/etc/rc.d/pflog index fc80975afcfa..d0fb4e6cbf08 100755 --- a/etc/rc.d/pflog +++ b/etc/rc.d/pflog @@ -5,7 +5,7 @@ # PROVIDE: pflog # REQUIRE: FILESYSTEMS netif -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr diff --git a/etc/rc.d/pfsync b/etc/rc.d/pfsync index cc8e85f073e3..77369aa59961 100755 --- a/etc/rc.d/pfsync +++ b/etc/rc.d/pfsync @@ -5,7 +5,7 @@ # PROVIDE: pfsync # REQUIRE: FILESYSTEMS netif -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr @@ -15,7 +15,7 @@ rcvar="pfsync_enable" start_precmd="pfsync_prestart" start_cmd="pfsync_start" stop_cmd="pfsync_stop" -required_modules="pf" +required_modules="pf pfsync" pfsync_prestart() { @@ -36,7 +36,6 @@ pfsync_start() if [ -n "${pfsync_syncpeer}" ]; then _syncpeer="syncpeer ${pfsync_syncpeer}" fi - load_kld pfsync ifconfig pfsync0 $_syncpeer syncdev $pfsync_syncdev $pfsync_ifconfig up } diff --git a/etc/rc.d/rarpd b/etc/rc.d/rarpd index 433139a6f82a..ef87bcba8f83 100755 --- a/etc/rc.d/rarpd +++ b/etc/rc.d/rarpd @@ -6,7 +6,7 @@ # PROVIDE: rarpd # REQUIRE: DAEMON FILESYSTEMS # BEFORE: LOGIN -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr diff --git a/etc/rc.d/route6d b/etc/rc.d/route6d index ca8d2938fcc7..f17f7b4090c0 100755 --- a/etc/rc.d/route6d +++ b/etc/rc.d/route6d @@ -5,7 +5,7 @@ # PROVIDE: route6d # REQUIRE: netif routing -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr diff --git a/etc/rc.d/routed b/etc/rc.d/routed index fe150bf0b442..f8890537b22c 100755 --- a/etc/rc.d/routed +++ b/etc/rc.d/routed @@ -6,7 +6,7 @@ # PROVIDE: routed # REQUIRE: netif routing # BEFORE: NETWORK -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr diff --git a/etc/rc.d/rtadvd b/etc/rc.d/rtadvd index 10fbb7fedf29..ed9e8b948348 100755 --- a/etc/rc.d/rtadvd +++ b/etc/rc.d/rtadvd @@ -6,7 +6,7 @@ # PROVIDE: rtadvd # REQUIRE: DAEMON # BEFORE: LOGIN -# KEYWORD: nojail shutdown +# KEYWORD: nojailvnet shutdown . /etc/rc.subr . /etc/network.subr diff --git a/etc/rc.d/rtsold b/etc/rc.d/rtsold index 145c624f61b0..0bc7d9287adf 100755 --- a/etc/rc.d/rtsold +++ b/etc/rc.d/rtsold @@ -6,7 +6,7 @@ # PROVIDE: rtsold # REQUIRE: netif # BEFORE: NETWORKING -# KEYWORD: nojail shutdown +# KEYWORD: nojailvnet shutdown . /etc/rc.subr diff --git a/etc/rc.d/static_arp b/etc/rc.d/static_arp index 7242dcf8fed0..f874a5bc4306 100755 --- a/etc/rc.d/static_arp +++ b/etc/rc.d/static_arp @@ -31,7 +31,7 @@ # PROVIDE: static_arp # REQUIRE: netif -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr . /etc/network.subr diff --git a/etc/rc.d/static_ndp b/etc/rc.d/static_ndp index 314adbf7c565..bf44b65af088 100755 --- a/etc/rc.d/static_ndp +++ b/etc/rc.d/static_ndp @@ -31,7 +31,7 @@ # PROVIDE: static_ndp # REQUIRE: netif -# KEYWORD: nojail +# KEYWORD: nojailvnet . /etc/rc.subr . /etc/network.subr diff --git a/etc/root/dot.login b/etc/root/dot.login index a849b68dbb41..8d87604f4f7d 100644 --- a/etc/root/dot.login +++ b/etc/root/dot.login @@ -2,8 +2,11 @@ # # .login - csh login script, read by login shell, after `.cshrc' at login. # -# see also csh(1), environ(7). +# See also csh(1), environ(7). # -# Uncomment to display a random cookie each login: +# Query terminal size; useful for serial lines. +if ( -x /usr/bin/resizewin ) /usr/bin/resizewin -z + +# Uncomment to display a random cookie on each login. # if ( -x /usr/bin/fortune ) /usr/bin/fortune -s diff --git a/etc/root/dot.profile b/etc/root/dot.profile index 1656b9b214bb..9f13f39fc478 100644 --- a/etc/root/dot.profile +++ b/etc/root/dot.profile @@ -8,3 +8,9 @@ TERM=${TERM:-xterm} export TERM PAGER=more export PAGER + +# Query terminal size; useful for serial lines. +if [ -x /usr/bin/resizewin ] ; then /usr/bin/resizewin -z ; fi + +# Uncomment to display a random cookie on each login. +# if [ -x /usr/bin/fortune ] ; then /usr/bin/fortune -s ; fi diff --git a/gnu/usr.bin/gdb/gdb/gdb.1 b/gnu/usr.bin/gdb/gdb/gdb.1 index ee84659ac578..635e5c311882 100644 --- a/gnu/usr.bin/gdb/gdb/gdb.1 +++ b/gnu/usr.bin/gdb/gdb/gdb.1 @@ -44,6 +44,11 @@ gdb \- The GNU Debugger .IR core \||\| procID\c \&\|]\&\|] .ad b +.SH DEPRECATION NOTICE +This version of gdb is deprecated and will be removed from future versions +of the FreeBSD base system. +A newer version of gdb is available from ports or packages +(devel/gdb). .SH DESCRIPTION The purpose of a debugger such as GDB is to allow you to see what is going on ``inside'' another program while it executes\(em\&or what another diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.1 b/gnu/usr.bin/gdb/kgdb/kgdb.1 index 58d0786dbed7..8ebfbf55ce9f 100644 --- a/gnu/usr.bin/gdb/kgdb/kgdb.1 +++ b/gnu/usr.bin/gdb/kgdb/kgdb.1 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 11, 2006 +.Dd July 5, 2017 .Dt KGDB 1 .Os .Sh NAME @@ -40,6 +40,16 @@ .Op Fl d Ar crashdir .Op Fl c Ar core | Fl n Ar dumpnr | Fl r Ar device .Op Ar kernel Op Ar core +.Sh DEPRECATION NOTICE +This version of +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +A newer version of +.Nm +is available from ports or packages +(devel/gdb). .Sh DESCRIPTION The .Nm diff --git a/include/Makefile b/include/Makefile index 4f7007729909..33fc6743b494 100644 --- a/include/Makefile +++ b/include/Makefile @@ -42,7 +42,7 @@ LHDRS= aio.h errno.h fcntl.h linker_set.h poll.h stdatomic.h stdint.h \ LDIRS= bsm cam geom net net80211 netgraph netinet netinet6 \ netipsec netsmb nfs nfsclient nfsserver sys vm -LSUBDIRS= cam/ata cam/nvme cam/scsi \ +LSUBDIRS= cam/ata cam/mmc cam/nvme cam/scsi \ dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \ dev/hwpmc dev/hyperv \ dev/ic dev/iicbus dev/io dev/lmc dev/mfi dev/mmc dev/nvme \ diff --git a/lib/Makefile b/lib/Makefile index f93778b91ca1..dcf81007d0aa 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -40,6 +40,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \ libdevctl \ libdevinfo \ libdevstat \ + ${_libdl} \ libdwarf \ libedit \ libevent \ @@ -183,6 +184,10 @@ _libproc= libproc _librtld_db= librtld_db .endif +.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mfilter} +_libdl= libdl +.endif + SUBDIR.${MK_OPENSSL}+= libmp SUBDIR.${MK_PMC}+= libpmc SUBDIR.${MK_RADIUS_SUPPORT}+= libradius diff --git a/lib/libc++experimental/Makefile.depend b/lib/libc++experimental/Makefile.depend new file mode 100644 index 000000000000..c210061155d2 --- /dev/null +++ b/lib/libc++experimental/Makefile.depend @@ -0,0 +1,14 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/xlocale \ + lib/msun \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c index 53c9d67ab9e2..55e7fc760fdd 100644 --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD$"); +#if !defined(IN_LIBDL) || defined(PIC) + /* * Linkage to services provided by the dynamic linker. */ @@ -57,95 +59,107 @@ void _rtld_atfork_post(int *); #pragma weak _rtld_error void -_rtld_error(const char *fmt, ...) +_rtld_error(const char *fmt __unused, ...) { } #pragma weak dladdr int -dladdr(const void *addr, Dl_info *dlip) +dladdr(const void *addr __unused, Dl_info *dlip __unused) { + _rtld_error(sorry); - return 0; + return (0); } #pragma weak dlclose int -dlclose(void *handle) +dlclose(void *handle __unused) { + _rtld_error(sorry); - return -1; + return (-1); } #pragma weak dlerror char * dlerror(void) { - return sorry; + + return (sorry); } #pragma weak dllockinit void dllockinit(void *context, - void *(*lock_create)(void *context), - void (*rlock_acquire)(void *lock), - void (*wlock_acquire)(void *lock), - void (*lock_release)(void *lock), - void (*lock_destroy)(void *lock), - void (*context_destroy)(void *context)) + void *(*lock_create)(void *context) __unused, + void (*rlock_acquire)(void *lock) __unused, + void (*wlock_acquire)(void *lock) __unused, + void (*lock_release)(void *lock) __unused, + void (*lock_destroy)(void *lock) __unused, + void (*context_destroy)(void *context) __unused) { + if (context_destroy != NULL) context_destroy(context); } #pragma weak dlopen void * -dlopen(const char *name, int mode) +dlopen(const char *name __unused, int mode __unused) { + _rtld_error(sorry); - return NULL; + return (NULL); } #pragma weak dlsym void * -dlsym(void * __restrict handle, const char * __restrict name) +dlsym(void * __restrict handle __unused, const char * __restrict name __unused) { + _rtld_error(sorry); - return NULL; + return (NULL); } #pragma weak dlfunc dlfunc_t -dlfunc(void * __restrict handle, const char * __restrict name) +dlfunc(void * __restrict handle __unused, const char * __restrict name __unused) { + _rtld_error(sorry); - return NULL; + return (NULL); } #pragma weak dlvsym void * -dlvsym(void * __restrict handle, const char * __restrict name, - const char * __restrict version) +dlvsym(void * __restrict handle __unused, const char * __restrict name __unused, + const char * __restrict version __unused) { + _rtld_error(sorry); - return NULL; + return (NULL); } #pragma weak dlinfo int -dlinfo(void * __restrict handle, int request, void * __restrict p) +dlinfo(void * __restrict handle __unused, int request __unused, + void * __restrict p __unused) { + _rtld_error(sorry); - return 0; + return (0); } #pragma weak _rtld_thread_init void -_rtld_thread_init(void * li) +_rtld_thread_init(void *li __unused) { + _rtld_error(sorry); } +#ifndef IN_LIBDL static pthread_once_t dl_phdr_info_once = PTHREAD_ONCE_INIT; static struct dl_phdr_info phdr_info; @@ -181,44 +195,50 @@ dl_init_phdr_info(void) } phdr_info.dlpi_adds = 1; } +#endif #pragma weak dl_iterate_phdr int -dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), - void *data) +dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *) __unused, + void *data __unused) { +#ifndef IN_LIBDL __init_elf_aux_vector(); if (__elf_aux_vector == NULL) return (1); _once(&dl_phdr_info_once, dl_init_phdr_info); return (callback(&phdr_info, sizeof(phdr_info), data)); +#else + return (0); +#endif } #pragma weak fdlopen void * -fdlopen(int fd, int mode) +fdlopen(int fd __unused, int mode __unused) { _rtld_error(sorry); - return NULL; + return (NULL); } #pragma weak _rtld_atfork_pre void -_rtld_atfork_pre(int *locks) +_rtld_atfork_pre(int *locks __unused) { } #pragma weak _rtld_atfork_post void -_rtld_atfork_post(int *locks) +_rtld_atfork_post(int *locks __unused) { } #pragma weak _rtld_addr_phdr int -_rtld_addr_phdr(const void *addr, struct dl_phdr_info *phdr_info) +_rtld_addr_phdr(const void *addr __unused, + struct dl_phdr_info *phdr_info_a __unused) { return (0); @@ -234,8 +254,10 @@ _rtld_get_stack_prot(void) #pragma weak _rtld_is_dlopened int -_rtld_is_dlopened(void *arg) +_rtld_is_dlopened(void *arg __unused) { return (0); } + +#endif /* !defined(IN_LIBDL) || defined(PIC) */ diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 index 1963528b54bf..202f1af48648 100644 --- a/lib/libc/gen/dlopen.3 +++ b/lib/libc/gen/dlopen.3 @@ -32,7 +32,7 @@ .\" @(#) dlopen.3 1.6 90/01/31 SMI .\" $FreeBSD$ .\" -.Dd February 14, 2015 +.Dd July 7, 2017 .Dt DLOPEN 3 .Os .Sh NAME @@ -377,6 +377,14 @@ option to for symbols defined in the executable to become visible to .Fn dlsym . .Pp +Other ELF platforms require linking with +.Lb libdl +to provide +.Fn dlopen +and other functions. +.Fx +does not require linking with the library, but supports it for compatibility. +.Pp In previous implementations, it was necessary to prepend an underscore to all external symbols in order to gain symbol compatibility with object code compiled from the C language. diff --git a/lib/libc/net/nsdispatch.c b/lib/libc/net/nsdispatch.c index a0defa50bab1..308f58f2688d 100644 --- a/lib/libc/net/nsdispatch.c +++ b/lib/libc/net/nsdispatch.c @@ -525,7 +525,7 @@ nss_load_module(const char *source, nss_module_register_fn reg_fn) vector_sort(_nsmod, _nsmodsize, sizeof(*_nsmod), string_compare); } - +static int exiting = 0; static void ns_mod_free(ns_mod *mod) @@ -536,12 +536,10 @@ ns_mod_free(ns_mod *mod) return; if (mod->unregister != NULL) mod->unregister(mod->mtab, mod->mtabsize); - if (mod->handle != nss_builtin_handle) + if (mod->handle != nss_builtin_handle && !exiting) (void)dlclose(mod->handle); } - - /* * Cleanup */ @@ -550,6 +548,7 @@ nss_atexit(void) { int isthreaded; + exiting = 1; isthreaded = __isthreaded; if (isthreaded) (void)_pthread_rwlock_wrlock(&nss_lock); @@ -561,8 +560,6 @@ nss_atexit(void) (void)_pthread_rwlock_unlock(&nss_lock); } - - /* * Finally, the actual implementation. */ diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c index bc83aeda5397..d356d80c5f8b 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -61,6 +62,24 @@ __FBSDID("$FreeBSD$"); #include "cname.h" +/* + * Branching context, used to keep track of branch state for all of the branch- + * aware functions. In addition to keeping track of branch positions for the + * p_branch_* functions, we use this to simplify some clumsiness in BREs for + * detection of whether ^ is acting as an anchor or being used erroneously and + * also for whether we're in a sub-expression or not. + */ +struct branchc { + sopno start; + sopno back; + sopno fwd; + + int nbranch; + int nchain; + bool outer; + bool terminate; +}; + /* * parse structure, passed up and down to avoid global variables and * other clumsinesses @@ -77,6 +96,11 @@ struct parse { # define NPAREN 10 /* we need to remember () 1-9 for back refs */ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ sopno pend[NPAREN]; /* -> ) ([0] unused) */ + bool allowbranch; /* can this expression branch? */ + bool bre; /* convenience; is this a BRE? */ + bool (*parse_expr)(struct parse *, struct branchc *); + void (*pre_parse)(struct parse *, struct branchc *); + void (*post_parse)(struct parse *, struct branchc *); }; /* ========= begin header generated by ./mkh ========= */ @@ -85,11 +109,17 @@ extern "C" { #endif /* === regcomp.c === */ -static void p_ere(struct parse *p, int stop); -static void p_ere_exp(struct parse *p); +static bool p_ere_exp(struct parse *p, struct branchc *bc); static void p_str(struct parse *p); -static void p_bre(struct parse *p, int end1, int end2); -static int p_simp_re(struct parse *p, int starordinary); +static int p_branch_eat_delim(struct parse *p, struct branchc *bc); +static void p_branch_ins_offset(struct parse *p, struct branchc *bc); +static void p_branch_fix_tail(struct parse *p, struct branchc *bc); +static bool p_branch_empty(struct parse *p, struct branchc *bc); +static bool p_branch_do(struct parse *p, struct branchc *bc); +static void p_bre_pre_parse(struct parse *p, struct branchc *bc); +static void p_bre_post_parse(struct parse *p, struct branchc *bc); +static void p_re(struct parse *p, int end1, int end2); +static bool p_simp_re(struct parse *p, struct branchc *bc); static int p_count(struct parse *p); static void p_bracket(struct parse *p); static void p_b_term(struct parse *p, cset *cs); @@ -139,6 +169,7 @@ static char nuls[10]; /* place to point scanner in event of error */ #define MORE2() (p->next+1 < p->end) #define SEE(c) (MORE() && PEEK() == (c)) #define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) +#define SEESPEC(a) (p->bre ? SEETWO('\\', a) : SEE(a)) #define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) #define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) #define NEXT() (p->next++) @@ -247,6 +278,19 @@ regcomp(regex_t * __restrict preg, p->pbegin[i] = 0; p->pend[i] = 0; } + if (cflags & REG_EXTENDED) { + p->allowbranch = true; + p->bre = false; + p->parse_expr = p_ere_exp; + p->pre_parse = NULL; + p->post_parse = NULL; + } else { + p->allowbranch = false; + p->bre = true; + p->parse_expr = p_simp_re; + p->pre_parse = p_bre_pre_parse; + p->post_parse = p_bre_post_parse; + } g->sets = NULL; g->ncsets = 0; g->cflags = cflags; @@ -264,12 +308,10 @@ regcomp(regex_t * __restrict preg, /* do it */ EMIT(OEND, 0); g->firststate = THERE(); - if (cflags®_EXTENDED) - p_ere(p, OUT); - else if (cflags®_NOSPEC) + if (cflags & REG_NOSPEC) p_str(p); else - p_bre(p, OUT, OUT); + p_re(p, OUT, OUT); EMIT(OEND, 0); g->laststate = THERE(); @@ -305,56 +347,12 @@ regcomp(regex_t * __restrict preg, } /* - - p_ere - ERE parser top level, concatenation and alternation - == static void p_ere(struct parse *p, int_t stop); + - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op, + - return whether we should terminate or not + == static bool p_ere_exp(struct parse *p); */ -static void -p_ere(struct parse *p, - int stop) /* character this ERE should end at */ -{ - char c; - sopno prevback; - sopno prevfwd; - sopno conc; - int first = 1; /* is this the first alternative? */ - - for (;;) { - /* do a bunch of concatenated expressions */ - conc = HERE(); - while (MORE() && (c = PEEK()) != '|' && c != stop) - p_ere_exp(p); - (void)REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ - - if (!EAT('|')) - break; /* NOTE BREAK OUT */ - - if (first) { - INSERT(OCH_, conc); /* offset is wrong */ - prevfwd = conc; - prevback = conc; - first = 0; - } - ASTERN(OOR1, prevback); - prevback = THERE(); - AHEAD(prevfwd); /* fix previous offset */ - prevfwd = HERE(); - EMIT(OOR2, 0); /* offset is very wrong */ - } - - if (!first) { /* tail-end fixups */ - AHEAD(prevfwd); - ASTERN(O_CH, prevback); - } - - assert(!MORE() || SEE(stop)); -} - -/* - - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op - == static void p_ere_exp(struct parse *p); - */ -static void -p_ere_exp(struct parse *p) +static bool +p_ere_exp(struct parse *p, struct branchc *bc) { char c; wint_t wc; @@ -377,7 +375,7 @@ p_ere_exp(struct parse *p) p->pbegin[subno] = HERE(); EMIT(OLPAREN, subno); if (!SEE(')')) - p_ere(p, ')'); + p_re(p, ')', IGN); if (subno < NPAREN) { p->pend[subno] = HERE(); assert(p->pend[subno] != 0); @@ -445,7 +443,7 @@ p_ere_exp(struct parse *p) /* FALLTHROUGH */ default: if (p->error != 0) - return; + return (false); p->next--; wc = WGETNEXT(); ordinary(p, wc); @@ -453,12 +451,12 @@ p_ere_exp(struct parse *p) } if (!MORE()) - return; + return (false); c = PEEK(); /* we call { a repetition if followed by a digit */ if (!( c == '*' || c == '+' || c == '?' || (c == '{' && MORE2() && isdigit((uch)PEEK2())) )) - return; /* no repetition, we're done */ + return (false); /* no repetition, we're done */ NEXT(); (void)REQUIRE(!wascaret, REG_BADRPT); @@ -504,12 +502,13 @@ p_ere_exp(struct parse *p) } if (!MORE()) - return; + return (false); c = PEEK(); if (!( c == '*' || c == '+' || c == '?' || (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) ) - return; + return (false); SETERROR(REG_BADRPT); + return (false); } /* @@ -525,9 +524,129 @@ p_str(struct parse *p) } /* - - p_bre - BRE parser top level, anchoring and concatenation - == static void p_bre(struct parse *p, int end1, \ - == int end2); + * Eat consecutive branch delimiters for the kind of expression that we are + * parsing, return the number of delimiters that we ate. + */ +static int +p_branch_eat_delim(struct parse *p, struct branchc *bc) +{ + int nskip; + + nskip = 0; + while (EAT('|')) + ++nskip; + return (nskip); +} + +/* + * Insert necessary branch book-keeping operations. This emits a + * bogus 'next' offset, since we still have more to parse + */ +static void +p_branch_ins_offset(struct parse *p, struct branchc *bc) +{ + + if (bc->nbranch == 0) { + INSERT(OCH_, bc->start); /* offset is wrong */ + bc->fwd = bc->start; + bc->back = bc->start; + } + + ASTERN(OOR1, bc->back); + bc->back = THERE(); + AHEAD(bc->fwd); /* fix previous offset */ + bc->fwd = HERE(); + EMIT(OOR2, 0); /* offset is very wrong */ + ++bc->nbranch; +} + +/* + * Fix the offset of the tail branch, if we actually had any branches. + * This is to correct the bogus placeholder offset that we use. + */ +static void +p_branch_fix_tail(struct parse *p, struct branchc *bc) +{ + + /* Fix bogus offset at the tail if we actually have branches */ + if (bc->nbranch > 0) { + AHEAD(bc->fwd); + ASTERN(O_CH, bc->back); + } +} + +/* + * Signal to the parser that an empty branch has been encountered; this will, + * in the future, be used to allow for more permissive behavior with empty + * branches. The return value should indicate whether parsing may continue + * or not. + */ +static bool +p_branch_empty(struct parse *p, struct branchc *bc) +{ + + SETERROR(REG_EMPTY); + return (false); +} + +/* + * Take care of any branching requirements. This includes inserting the + * appropriate branching instructions as well as eating all of the branch + * delimiters until we either run out of pattern or need to parse more pattern. + */ +static bool +p_branch_do(struct parse *p, struct branchc *bc) +{ + int ate = 0; + + ate = p_branch_eat_delim(p, bc); + if (ate == 0) + return (false); + else if ((ate > 1 || (bc->outer && !MORE())) && !p_branch_empty(p, bc)) + /* + * Halt parsing only if we have an empty branch and p_branch_empty + * indicates that we must not continue. In the future, this will not + * necessarily be an error. + */ + return (false); + p_branch_ins_offset(p, bc); + + return (true); +} + +static void +p_bre_pre_parse(struct parse *p, struct branchc *bc) +{ + + (void) bc; + /* + * Does not move cleanly into expression parser because of + * ordinary interpration of * at the beginning position of + * an expression. + */ + if (EAT('^')) { + EMIT(OBOL, 0); + p->g->iflags |= USEBOL; + p->g->nbol++; + } +} + +static void +p_bre_post_parse(struct parse *p, struct branchc *bc) +{ + + /* Expression is terminating due to EOL token */ + if (bc->terminate) { + DROP(1); + EMIT(OEOL, 0); + p->g->iflags |= USEEOL; + p->g->neol++; + } +} + +/* + - p_re - Top level parser, concatenation and BRE anchoring + == static void p_re(struct parse *p, int end1, int end2); * Giving end1 as OUT essentially eliminates the end1/end2 check. * * This implementation is a bit of a kludge, in that a trailing $ is first @@ -535,40 +654,55 @@ p_str(struct parse *p) * The amount of lookahead needed to avoid this kludge is excessive. */ static void -p_bre(struct parse *p, - int end1, /* first terminating character */ - int end2) /* second terminating character */ +p_re(struct parse *p, + int end1, /* first terminating character */ + int end2) /* second terminating character; ignored for EREs */ { - sopno start = HERE(); - int first = 1; /* first subexpression? */ - int wasdollar = 0; + struct branchc bc; - if (EAT('^')) { - EMIT(OBOL, 0); - p->g->iflags |= USEBOL; - p->g->nbol++; + bc.nbranch = 0; + if (end1 == OUT && end2 == OUT) + bc.outer = true; + else + bc.outer = false; +#define SEEEND() (!p->bre ? SEE(end1) : SEETWO(end1, end2)) + for (;;) { + bc.start = HERE(); + bc.nchain = 0; + bc.terminate = false; + if (p->pre_parse != NULL) + p->pre_parse(p, &bc); + while (MORE() && (!p->allowbranch || !SEESPEC('|')) && !SEEEND()) { + bc.terminate = p->parse_expr(p, &bc); + ++bc.nchain; + } + if (p->post_parse != NULL) + p->post_parse(p, &bc); + (void) REQUIRE(HERE() != bc.start, REG_EMPTY); + if (!p->allowbranch) + break; + /* + * p_branch_do's return value indicates whether we should + * continue parsing or not. This is both for correctness and + * a slight optimization, because it will check if we've + * encountered an empty branch or the end of the string + * immediately following a branch delimiter. + */ + if (!p_branch_do(p, &bc)) + break; } - while (MORE() && !SEETWO(end1, end2)) { - wasdollar = p_simp_re(p, first); - first = 0; - } - if (wasdollar) { /* oops, that was a trailing anchor */ - DROP(1); - EMIT(OEOL, 0); - p->g->iflags |= USEEOL; - p->g->neol++; - } - - (void)REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ +#undef SEE_END + if (p->allowbranch) + p_branch_fix_tail(p, &bc); + assert(!MORE() || SEE(end1)); } /* - p_simp_re - parse a simple RE, an atom possibly followed by a repetition - == static int p_simp_re(struct parse *p, int starordinary); + == static bool p_simp_re(struct parse *p, struct branchc *bc); */ -static int /* was the simple RE an unbackslashed $? */ -p_simp_re(struct parse *p, - int starordinary) /* is a leading * an ordinary character? */ +static bool /* was the simple RE an unbackslashed $? */ +p_simp_re(struct parse *p, struct branchc *bc) { int c; int count; @@ -614,7 +748,7 @@ p_simp_re(struct parse *p, EMIT(OLPAREN, subno); /* the MORE here is an error heuristic */ if (MORE() && !SEETWO('\\', ')')) - p_bre(p, '\\', ')'); + p_re(p, '\\', ')'); if (subno < NPAREN) { p->pend[subno] = HERE(); assert(p->pend[subno] != 0); @@ -650,11 +784,16 @@ p_simp_re(struct parse *p, p->g->backrefs = 1; break; case '*': - (void)REQUIRE(starordinary, REG_BADRPT); + /* + * Ordinary if used as the first character beyond BOL anchor of + * a (sub-)expression, counts as a bad repetition operator if it + * appears otherwise. + */ + (void)REQUIRE(bc->nchain == 0, REG_BADRPT); /* FALLTHROUGH */ default: if (p->error != 0) - return(0); /* Definitely not $... */ + return (false); /* Definitely not $... */ p->next--; wc = WGETNEXT(); ordinary(p, wc); @@ -685,9 +824,9 @@ p_simp_re(struct parse *p, SETERROR(REG_BADBR); } } else if (c == '$') /* $ (but not \$) ends it */ - return(1); + return (true); - return(0); + return (false); } /* diff --git a/lib/libc/regex/regex2.h b/lib/libc/regex/regex2.h index e9e63810cfa8..a9c831b441cd 100644 --- a/lib/libc/regex/regex2.h +++ b/lib/libc/regex/regex2.h @@ -189,4 +189,5 @@ struct re_guts { /* misc utilities */ #define OUT (CHAR_MIN - 1) /* a non-character value */ +#define IGN (CHAR_MIN - 2) #define ISWORD(c) (iswalnum((uch)(c)) || (c) == '_') diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2 index b7704a2351c0..607a0a636352 100644 --- a/lib/libc/sys/mmap.2 +++ b/lib/libc/sys/mmap.2 @@ -329,10 +329,12 @@ stack top is the starting address returned by the call, plus bytes. The bottom of the stack at maximum growth is the starting address returned by the call. -The system uses guards to prevent the inadvertent use of -regions into which stacks created with +.Pp +Stacks created with .Dv MAP_STACK -will automatically grow, without mapping the whole stack in advance. +automatically grow. +Guards prevent inadvertent use of the regions into which those +stacks can grow without requiring mapping the whole stack in advance. .El .Pp The diff --git a/lib/libc/tests/gen/Makefile b/lib/libc/tests/gen/Makefile index 7ec09259ae21..6685552a139b 100644 --- a/lib/libc/tests/gen/Makefile +++ b/lib/libc/tests/gen/Makefile @@ -72,6 +72,7 @@ CFLAGS+= -I${.CURDIR} SRCS.fmtcheck2_test= fmtcheck_test.c SRCS.fnmatch2_test= fnmatch_test.c +TEST_METADATA.setdomainname_test+= is_exclusive=true TESTS_SUBDIRS= execve TESTS_SUBDIRS+= posix_spawn diff --git a/lib/libcam/Makefile b/lib/libcam/Makefile index 3cf1a0d71db9..4ea82681a071 100644 --- a/lib/libcam/Makefile +++ b/lib/libcam/Makefile @@ -36,8 +36,10 @@ MLINKS+= cam.3 cam_open_device.3 \ cam_cdbparse.3 csio_encode_visit.3 \ cam_cdbparse.3 buff_encode_visit.3 -.PATH: ${SRCTOP}/sys/cam/scsi ${SRCTOP}/sys/cam/ata \ - ${SRCTOP}/sys/cam +.PATH: ${SRCTOP}/sys/cam \ + ${SRCTOP}/sys/cam/ata \ + ${SRCTOP}/sys/cam/mmc \ + ${SRCTOP}/sys/cam/scsi CFLAGS+= -I${.CURDIR} -I${SRCTOP}/sys diff --git a/lib/libclang_rt/stats/Makefile.depend b/lib/libclang_rt/stats/Makefile.depend new file mode 100644 index 000000000000..1df7d3387057 --- /dev/null +++ b/lib/libclang_rt/stats/Makefile.depend @@ -0,0 +1,16 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/arpa \ + include/xlocale \ + lib/libc++ \ + lib/ncurses/ncursesw \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libclang_rt/stats_client/Makefile.depend b/lib/libclang_rt/stats_client/Makefile.depend new file mode 100644 index 000000000000..3ac123f440c2 --- /dev/null +++ b/lib/libclang_rt/stats_client/Makefile.depend @@ -0,0 +1,13 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + lib/libc++ \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libcompiler_rt/Makefile.inc b/lib/libcompiler_rt/Makefile.inc index 2f0ad2378130..b2eb3fa1e069 100644 --- a/lib/libcompiler_rt/Makefile.inc +++ b/lib/libcompiler_rt/Makefile.inc @@ -225,9 +225,8 @@ SRCS+= switchu8.S SRCS+= sync_synchronize.S .endif -# GCC-6.3 on mips32 requires bswap32 built-in. -.if ${MACHINE_CPUARCH} == "mips" +# On some archs GCC-6.3 requires bswap32 built-in. +.if ${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "sparc64" SRCS+= bswapdi2.c SRCS+= bswapsi2.c .endif - diff --git a/lib/libdl/Makefile b/lib/libdl/Makefile new file mode 100644 index 000000000000..8feb782c1ba7 --- /dev/null +++ b/lib/libdl/Makefile @@ -0,0 +1,15 @@ +# $FreeBSD$ + +LIB=dl +SHLIB_MAJOR=1 + +.PATH: ${SRCTOP}/lib/libc/gen +CFLAGS+=-I${SRCTOP}/lib/libc/include +CFLAGS+=-DIN_LIBDL +LDFLAGS+=-Wl,-F,libc.so.7 +VERSION_DEF=${SRCTOP}/lib/libc/Versions.def +SYMBOL_MAPS=${.CURDIR}/Symbol.map + +SRCS = dlfcn.c + +.include diff --git a/lib/libdl/Makefile.depend b/lib/libdl/Makefile.depend new file mode 100644 index 000000000000..3646e2e2b1af --- /dev/null +++ b/lib/libdl/Makefile.depend @@ -0,0 +1,18 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libdl/Symbol.map b/lib/libdl/Symbol.map new file mode 100644 index 000000000000..82ab6012e121 --- /dev/null +++ b/lib/libdl/Symbol.map @@ -0,0 +1,20 @@ +/* + * $FreeBSD$ + */ + +FBSD_1.0 { + dladdr; + dlclose; + dlerror; + dlfunc; + dlopen; + dlsym; + dlvsym; + dlinfo; + dl_iterate_phdr; +}; + + +FBSD_1.3 { + fdlopen; +}; diff --git a/lib/libelftc/elftc_version.c b/lib/libelftc/elftc_version.c index 22a29ed5fb88..3d0023d0ce3f 100644 --- a/lib/libelftc/elftc_version.c +++ b/lib/libelftc/elftc_version.c @@ -6,5 +6,5 @@ const char * elftc_version(void) { - return "elftoolchain r3520M"; + return "elftoolchain r3561M"; } diff --git a/lib/libgcc_s/Version.map b/lib/libgcc_s/Version.map index e6d923a5b1dc..622732edb447 100644 --- a/lib/libgcc_s/Version.map +++ b/lib/libgcc_s/Version.map @@ -48,9 +48,9 @@ global: __moddi3; __modti3; __muldi3; + __multi3; __mulvdi3; __mulvsi3; - __multi3; __negdi2; __negti2; __negvdi2; diff --git a/lib/libifconfig/Makefile.depend b/lib/libifconfig/Makefile.depend new file mode 100644 index 000000000000..18be76b0cb6f --- /dev/null +++ b/lib/libifconfig/Makefile.depend @@ -0,0 +1,13 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/xlocale \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/librss/Makefile.depend b/lib/librss/Makefile.depend new file mode 100644 index 000000000000..3646e2e2b1af --- /dev/null +++ b/lib/librss/Makefile.depend @@ -0,0 +1,18 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libsysdecode/Makefile.depend b/lib/libsysdecode/Makefile.depend index c7ab903a0056..6470465f751c 100644 --- a/lib/libsysdecode/Makefile.depend +++ b/lib/libsysdecode/Makefile.depend @@ -74,6 +74,7 @@ DIRDEPS = \ lib/libfigpar \ lib/libgeom \ lib/libgpio \ + lib/libifconfig \ lib/libjail \ lib/libkvm \ lib/liblzma \ @@ -92,6 +93,7 @@ DIRDEPS = \ lib/libproc \ lib/libprocstat \ lib/libradius \ + lib/librss \ lib/librtld_db \ lib/libsdp \ lib/libsqlite3 \ diff --git a/libexec/rlogind/rlogind.8 b/libexec/rlogind/rlogind.8 index 209cec94b433..09ec8b5000a3 100644 --- a/libexec/rlogind/rlogind.8 +++ b/libexec/rlogind/rlogind.8 @@ -28,7 +28,7 @@ .\" @(#)rlogind.8 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd February 9, 2005 +.Dd July 3, 2017 .Dt RLOGIND 8 .Os .Sh NAME @@ -37,6 +37,15 @@ .Sh SYNOPSIS .Nm .Op Fl Daln +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/libexec/rshd/rshd.8 b/libexec/rshd/rshd.8 index 6c6e57ce8e5d..700c2ed0b59c 100644 --- a/libexec/rshd/rshd.8 +++ b/libexec/rshd/rshd.8 @@ -28,7 +28,7 @@ .\" @(#)rshd.8 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd July 3, 2017 .Dt RSHD 8 .Os .Sh NAME @@ -37,6 +37,15 @@ .Sh SYNOPSIS .Nm .Op Fl aDLln +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 61beae035fb5..ea3cacb2a73d 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -1659,6 +1659,7 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, const Elf_Sym *ref; const Elf_Sym *def; const Obj_Entry *defobj; + const Ver_Entry *ve; SymLook req; const char *name; int res; @@ -1678,6 +1679,7 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, name = refobj->strtab + ref->st_name; def = NULL; defobj = NULL; + ve = NULL; /* * We don't have to do a full scale lookup if the symbol is local. @@ -1694,7 +1696,7 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, } symlook_init(&req, name); req.flags = flags; - req.ventry = fetch_ventry(refobj, symnum); + ve = req.ventry = fetch_ventry(refobj, symnum); req.lockstate = lockstate; res = symlook_default(&req, refobj); if (res == 0) { @@ -1724,7 +1726,8 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, } } else { if (refobj != &obj_rtld) - _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name); + _rtld_error("%s: Undefined symbol \"%s%s%s\"", refobj->path, name, + ve != NULL ? "@" : "", ve != NULL ? ve->name : ""); } return def; } @@ -3489,7 +3492,8 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve, return (sym); } - _rtld_error("Undefined symbol \"%s\"", name); + _rtld_error("Undefined symbol \"%s%s%s\"", name, ve != NULL ? "@" : "", + ve != NULL ? ve->name : ""); lock_release(rtld_bind_lock, &lockstate); LD_UTRACE(UTRACE_DLSYM_STOP, handle, NULL, 0, 0, name); return NULL; @@ -5296,14 +5300,14 @@ open_binary_fd(const char *argv0, bool search_in_path) fd = -1; errno = ENOENT; while ((pe = strsep(&pathenv, ":")) != NULL) { - if (strlcpy(binpath, pe, sizeof(binpath)) > + if (strlcpy(binpath, pe, sizeof(binpath)) >= sizeof(binpath)) continue; if (binpath[0] != '\0' && - strlcat(binpath, "/", sizeof(binpath)) > + strlcat(binpath, "/", sizeof(binpath)) >= sizeof(binpath)) continue; - if (strlcat(binpath, argv0, sizeof(binpath)) > + if (strlcat(binpath, argv0, sizeof(binpath)) >= sizeof(binpath)) continue; fd = open(binpath, O_RDONLY | O_CLOEXEC | O_VERIFY); diff --git a/release/Makefile b/release/Makefile index 9be38fe6a5e2..3cd6b7c0ffca 100644 --- a/release/Makefile +++ b/release/Makefile @@ -269,7 +269,7 @@ packagesystem: base.txz kernel.txz ${EXTRA_PACKAGES} touch ${.TARGET} pkg-stage: -.if !defined(NOPKG) +.if !defined(NOPKG) || empty(NOPKG) env PORTSDIR=${PORTSDIR} REPOS_DIR=${.CURDIR}/pkg_repos/ \ sh ${.CURDIR}/scripts/pkg-stage.sh mkdir -p ${.OBJDIR}/dvd/packages/repos/ diff --git a/release/Makefile.mirrors b/release/Makefile.mirrors index bc16b1e77e8b..0d3dd106999e 100644 --- a/release/Makefile.mirrors +++ b/release/Makefile.mirrors @@ -21,7 +21,7 @@ STAGE_TARGETS?= iso-images-stage .endif .if (defined(EMBEDDED_TARGET) && !empty(EMBEDDED_TARGET)) || (defined(EMBEDDEDBUILD) && !empty(EMBEDDEDBUILD)) -. if ${TARGET} == "arm" || ${EMBEDDED_TARGET} == "arm" +. if ${TARGET:Marm*} != "" || ${EMBEDDED_TARGET:Marm*} != "" EMBEDDED= 1 . endif .endif @@ -57,7 +57,7 @@ TLD?= ${FTPDIR}/releases .endif .if defined(EMBEDDED) && !empty(EMBEDDED) -. if ${TARGET} == "arm" && ${TARGET_ARCH} == "armv6" +. if ${TARGET:Marm*} != "" && (${TARGET_ARCH} == "armv6" || ${TARGET_ARCH} == "aarch64") . if !defined(BOARDNAME) && empty(BOARDNAME) BOARDNAME:= ${KERNCONF} . else diff --git a/release/scripts/atlas-upload.sh b/release/scripts/atlas-upload.sh index cf8b282bd690..f7c40b463f67 100755 --- a/release/scripts/atlas-upload.sh +++ b/release/scripts/atlas-upload.sh @@ -27,7 +27,7 @@ # ATLAS_API_URL='' -ATLAS_UPLOAD_URL='https://binstore.hashicorp.com' +ATLAS_UPLOAD_URL='https://app.vagrantup.com' DESCRIPTION="FreeBSD Snapshot Build" usage() { @@ -76,7 +76,7 @@ main () { fi # Check to see if the box exists or create it - BOXRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}?access_token=${KEY}") + BOXRESULT=$(/usr/local/bin/curl -s "${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}?access_token=${KEY}") if [ $? != 0 ]; then echo "Failed to connect to the API" exit 2; @@ -84,26 +84,26 @@ main () { echo $BOXRESULT | grep "\"name\":\"${BOX}\"" > /dev/null if [ $? != 0 ]; then echo "Creating box: ${BOX}" - /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/boxes -X POST -d "box[name]=${BOX}" -d "access_token=${KEY}" > /dev/null - /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX} -X PUT -d "box[is_private]=false" -d "access_token=${KEY}" > /dev/null - /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX} -X PUT -d "box[description]='${DESCRIPTION}'" -d "access_token=${KEY}" > /dev/null + /usr/local/bin/curl -s ${ATLAS_UPLOAD_URL}/api/v1/boxes -X POST -d "box[name]=${BOX}" -d "access_token=${KEY}" > /dev/null + /usr/local/bin/curl -s ${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX} -X PUT -d "box[is_private]=false" -d "access_token=${KEY}" > /dev/null + /usr/local/bin/curl -s ${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX} -X PUT -d "box[description]='${DESCRIPTION}'" -d "access_token=${KEY}" > /dev/null else echo "Box already exists" fi # Check to see if the version exists or create it - VERSIONRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}?access_token=${KEY}") + VERSIONRESULT=$(/usr/local/bin/curl -s "${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}?access_token=${KEY}") if [ $? != 0 ]; then echo "Failed to connect to the API" exit 2; fi - echo $VERSIONRESULT | grep "\"version\":\"${VERSION}\"" > /dev/null + echo $VERSIONRESULT | grep "version/${VERSION}" > /dev/null if [ $? != 0 ]; then echo "Creating version: ${VERSION}" - /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/versions -X POST -d "version[version]=${VERSION}" -d "access_token=${KEY}" > /dev/null - /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION} -X PUT -d "version[description]=${DESCRIPTION}" -d "access_token=${KEY}" > /dev/null - VERSIONRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}?access_token=${KEY}") - echo $VERSIONRESULT | grep "\"version\":\"${VERSION}\"" > /dev/null + /usr/local/bin/curl -s ${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/versions -X POST -d "version[version]=${VERSION}" -d "access_token=${KEY}" > /dev/null + /usr/local/bin/curl -s ${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION} -X PUT -d "version[description]=${DESCRIPTION}" -d "access_token=${KEY}" > /dev/null + VERSIONRESULT=$(/usr/local/bin/curl -s "${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}?access_token=${KEY}") + echo $VERSIONRESULT | grep "version/${VERSION}" > /dev/null if [ $? != 0 ]; then echo "Failed to create version" exit 2 @@ -113,37 +113,37 @@ main () { fi # Check to see if the provider exists or create it - PROVIDERRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}?access_token=${KEY}") + PROVIDERRESULT=$(/usr/local/bin/curl -s "${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}?access_token=${KEY}") if [ $? != 0 ]; then echo "Failed to connect to the API" exit 2; fi - echo $PROVIDERRESULT | grep "\"name\":\"${PROVIDER}\"" > /dev/null + echo $PROVIDERRESULT | grep "provider/${PROVIDER}" > /dev/null if [ $? != 0 ]; then echo "Creating provider: ${PROVIDER}" - /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/providers -X POST -d "provider[name]=${PROVIDER}" -d "access_token=${KEY}" > /dev/null + /usr/local/bin/curl -s ${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/providers -X POST -d "provider[name]=${PROVIDER}" -d "access_token=${KEY}" > /dev/null else echo "Provider already exists" fi # Request an upload token - TOKENRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}/upload?access_token=${KEY}") + TOKENRESULT=$(/usr/local/bin/curl -s "${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}/upload?access_token=${KEY}") if [ $? != 0 ]; then echo "Failed to get the token from the API" exit 2; fi - echo ${TOKENRESULT} | grep -E "\"(token|upload_path)\":" > /dev/null + echo ${TOKENRESULT} | grep -E "upload_path" > /dev/null if [ $? != 0 ]; then echo "No token found from the API" exit 2 else TOKEN=$(echo $TOKENRESULT | sed -e 's/.*token":"//' -e 's/.*upload_path":"//' -e 's/}$//g' -e 's/"//g') echo "Uploading to Atlas" - UPLOADRESULT=$(/usr/local/bin/curl -s -X PUT --upload-file ${FILE} ${TOKEN}) + UPLOADRESULT=$(/usr/local/bin/curl -s -X PUT --upload-file ${FILE} "${TOKEN}") # Validate the Upload echo "Validating" - VALIDRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}?access_token=${KEY}") + VALIDRESULT=$(/usr/local/bin/curl -s "${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}?access_token=${KEY}") HOSTED_TOKEN=$(echo $VALIDRESULT | sed -e 's/.*"hosted"://' -e 's/,.*$//') if [ ! -z ${TOKEN} -a "${HOSTED_TOKEN}" != "true" ]; then echo "Upload failed, try again." @@ -152,7 +152,7 @@ main () { # Release the version echo "Releasing ${VERSION} of ${BOX} in Atlas" - /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/release -X PUT -d "access_token=${KEY}" > /dev/null + /usr/local/bin/curl -s ${ATLAS_UPLOAD_URL}/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/release -X PUT -d "access_token=${KEY}" > /dev/null fi } diff --git a/sbin/Makefile b/sbin/Makefile index 51e80bae8001..43f3cec7e03c 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -93,8 +93,6 @@ SUBDIR.${MK_TESTS}+= tests .include -SUBDIR:= ${SUBDIR:O} - SUBDIR_PARALLEL= .include diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 2a9ca1867b67..7e30e58eb4fc 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "camcontrol.h" @@ -104,7 +105,8 @@ typedef enum { CAM_CMD_REPROBE = 0x00000025, CAM_CMD_ZONE = 0x00000026, CAM_CMD_EPC = 0x00000027, - CAM_CMD_TIMESTAMP = 0x00000028 + CAM_CMD_TIMESTAMP = 0x00000028, + CAM_CMD_MMCSD_CMD = 0x00000029 } cam_cmdmask; typedef enum { @@ -205,6 +207,7 @@ static struct camcontrol_opts option_table[] = { {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL}, #ifndef MINIMALISTIC {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, + {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"}, {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"}, {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts}, @@ -300,6 +303,8 @@ static int scsicmd(struct cam_device *device, int argc, char **argv, int timeout); static int smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); +static int mmcsdcmd(struct cam_device *device, int argc, char **argv, + char *combinedopt, int retry_count, int timeout); static int smpreportgeneral(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int smpphycontrol(struct cam_device *device, int argc, char **argv, @@ -375,14 +380,14 @@ getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum, *argnum = opts->argnum; *subopt = opts->subopt; if (++num_matches > 1) - return(CC_OR_AMBIGUOUS); + return (CC_OR_AMBIGUOUS); } } if (num_matches > 0) - return(CC_OR_FOUND); + return (CC_OR_FOUND); else - return(CC_OR_NOT_FOUND); + return (CC_OR_NOT_FOUND); } #ifndef MINIMALISTIC @@ -404,7 +409,7 @@ getdevlist(struct cam_device *device) if (cam_send_ccb(device, ccb) < 0) { perror("error getting device list"); cam_freeccb(ccb); - return(1); + return (1); } status[0] = '\0'; @@ -442,7 +447,7 @@ getdevlist(struct cam_device *device) cam_freeccb(ccb); - return(error); + return (error); } #endif /* MINIMALISTIC */ @@ -471,7 +476,7 @@ getdevtree(int argc, char **argv, char *combinedopt) if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { warn("couldn't open %s", XPT_DEVICE); - return(1); + return (1); } bzero(&ccb, sizeof(union ccb)); @@ -487,7 +492,7 @@ getdevtree(int argc, char **argv, char *combinedopt) if (ccb.cdm.matches == NULL) { warnx("can't malloc memory for matches"); close(fd); - return(1); + return (1); } ccb.cdm.num_matches = 0; @@ -592,6 +597,13 @@ getdevtree(int argc, char **argv, char *combinedopt) sizeof(revision)); sprintf(tmpstr, "<%s %s>", product, revision); + } else if (dev_result->protocol == PROTO_MMCSD) { + if (strlen(dev_result->mmc_ident_data.model) > 0) { + sprintf(tmpstr, "<%s>", dev_result->mmc_ident_data.model); + } else { + sprintf(tmpstr, "<%s card>", + dev_result->mmc_ident_data.card_features & CARD_FEATURE_SDIO ? "SDIO" : "unknown"); + } } else if (dev_result->protocol == PROTO_SEMB) { struct sep_identify_data *sid; @@ -663,7 +675,7 @@ getdevtree(int argc, char **argv, char *combinedopt) close(fd); - return(error); + return (error); } #ifndef MINIMALISTIC @@ -699,7 +711,7 @@ testunitready(struct cam_device *device, int task_attr, int retry_count, } cam_freeccb(ccb); - return(1); + return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { @@ -718,7 +730,7 @@ testunitready(struct cam_device *device, int task_attr, int retry_count, cam_freeccb(ccb); - return(error); + return (error); } static int @@ -768,7 +780,7 @@ scsistart(struct cam_device *device, int startstop, int loadeject, } cam_freeccb(ccb); - return(1); + return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) @@ -802,7 +814,7 @@ scsistart(struct cam_device *device, int startstop, int loadeject, cam_freeccb(ccb); - return(error); + return (error); } int @@ -839,7 +851,7 @@ scsidoinquiry(struct cam_device *device, int argc, char **argv, error = scsiinquiry(device, task_attr, retry_count, timeout); if (error != 0) - return(error); + return (error); if (arglist & CAM_ARG_GET_SERIAL) scsiserial(device, task_attr, retry_count, timeout); @@ -847,7 +859,7 @@ scsidoinquiry(struct cam_device *device, int argc, char **argv, if (arglist & CAM_ARG_GET_XFERRATE) error = camxferrate(device); - return(error); + return (error); } static int @@ -862,7 +874,7 @@ scsiinquiry(struct cam_device *device, int task_attr, int retry_count, if (ccb == NULL) { warnx("couldn't allocate CCB"); - return(1); + return (1); } /* cam_getccb cleans up the header, caller has to zero the payload */ @@ -874,7 +886,7 @@ scsiinquiry(struct cam_device *device, int task_attr, int retry_count, if (inq_buf == NULL) { cam_freeccb(ccb); warnx("can't malloc memory for inquiry\n"); - return(1); + return (1); } bzero(inq_buf, sizeof(*inq_buf)); @@ -937,7 +949,7 @@ scsiinquiry(struct cam_device *device, int task_attr, int retry_count, } cam_freeccb(ccb); - return(1); + return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { @@ -953,7 +965,7 @@ scsiinquiry(struct cam_device *device, int task_attr, int retry_count, if (error != 0) { free(inq_buf); - return(error); + return (error); } fprintf(stdout, "%s%d: ", device->device_name, @@ -962,7 +974,7 @@ scsiinquiry(struct cam_device *device, int task_attr, int retry_count, free(inq_buf); - return(0); + return (0); } static int @@ -978,7 +990,7 @@ scsiserial(struct cam_device *device, int task_attr, int retry_count, if (ccb == NULL) { warnx("couldn't allocate CCB"); - return(1); + return (1); } /* cam_getccb cleans up the header, caller has to zero the payload */ @@ -990,7 +1002,7 @@ scsiserial(struct cam_device *device, int task_attr, int retry_count, if (serial_buf == NULL) { cam_freeccb(ccb); warnx("can't malloc memory for serial number"); - return(1); + return (1); } scsi_inquiry(&ccb->csio, @@ -1020,7 +1032,7 @@ scsiserial(struct cam_device *device, int task_attr, int retry_count, cam_freeccb(ccb); free(serial_buf); - return(1); + return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { @@ -1036,7 +1048,7 @@ scsiserial(struct cam_device *device, int task_attr, int retry_count, if (error != 0) { free(serial_buf); - return(error); + return (error); } bcopy(serial_buf->serial_num, serial_num, serial_buf->length); @@ -1051,7 +1063,7 @@ scsiserial(struct cam_device *device, int task_attr, int retry_count, free(serial_buf); - return(0); + return (0); } int @@ -1071,7 +1083,7 @@ camxferrate(struct cam_device *device) if (ccb == NULL) { warnx("couldn't allocate CCB"); - return(1); + return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); @@ -1210,13 +1222,13 @@ camxferrate(struct cam_device *device) } } - fprintf(stdout, "\n"); + fprintf(stdout, "\n"); xferrate_bailout: cam_freeccb(ccb); - return(retval); + return (retval); } static void @@ -1239,7 +1251,7 @@ atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header) if (parm->support.command1 & ATA_SUPPORT_PROTECTED) { u_int64_t lba = lbasize48 ? lbasize48 : lbasize; printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ", - lba, hpasize); + lba, hpasize); printf("HPA - Security "); if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY) @@ -3029,8 +3041,7 @@ atasecurity(struct cam_device *device, int retry_count, int timeout, } error = atasecurity_erase(device, ccb, retry_count, - timeout, erase_timeout, &pwd, - quiet); + timeout, erase_timeout, &pwd, quiet); } else { warnx("Can't secure erase (security is disabled)"); error = 1; @@ -3123,7 +3134,7 @@ dorescan_or_reset(int argc, char **argv, int rescan) if (argc < 3) { warnx(must, rescan? "rescan" : "reset"); - return(1); + return (1); } tstr = argv[optind]; @@ -3135,7 +3146,7 @@ dorescan_or_reset(int argc, char **argv, int rescan) rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist); if (rv != 1 && rv != 3) { warnx(must, rescan? "rescan" : "reset"); - return(1); + return (1); } } else { char name[30]; @@ -3243,7 +3254,7 @@ dorescan_or_reset(int argc, char **argv, int rescan) bailout: - return(error); + return (error); } static int @@ -3258,7 +3269,7 @@ rescan_or_reset_bus(path_id_t bus, int rescan) if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { warnx("error opening transport layer device %s", XPT_DEVICE); warn("%s", XPT_DEVICE); - return(1); + return (1); } ccb = malloc(sizeof(*ccb)); @@ -3423,7 +3434,7 @@ rescan_or_reset_bus(path_id_t bus, int rescan) } free(ccb); - return(retval); + return (retval); } static int @@ -3437,17 +3448,17 @@ scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan) if (bus == CAM_BUS_WILDCARD) { warnx("invalid bus number %d", bus); - return(1); + return (1); } if (target == CAM_TARGET_WILDCARD) { warnx("invalid target number %d", target); - return(1); + return (1); } if (lun == CAM_LUN_WILDCARD) { warnx("invalid lun number %jx", (uintmax_t)lun); - return(1); + return (1); } fd = -1; @@ -3459,13 +3470,13 @@ scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan) warnx("error opening transport layer device %s\n", XPT_DEVICE); warn("%s", XPT_DEVICE); - return(1); + return (1); } } else { device = cam_open_btl(bus, target, lun, O_RDWR, NULL); if (device == NULL) { warnx("%s", cam_errbuf); - return(1); + return (1); } } @@ -3483,13 +3494,13 @@ scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan) if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { warn("CAMIOCOMMAND ioctl failed"); close(fd); - return(1); + return (1); } } else { if (cam_send_ccb(device, &ccb) < 0) { warn("error sending XPT_RESET_DEV CCB"); cam_close_device(device); - return(1); + return (1); } } @@ -3506,12 +3517,12 @@ scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan) && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) { fprintf(stdout, "%s of %d:%d:%jx was successful\n", scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun); - return(0); + return (0); } else { fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n", scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun, ccb.ccb_h.status & CAM_STATUS_MASK); - return(1); + return (1); } } @@ -3743,7 +3754,7 @@ readdefects(struct cam_device *device, int argc, char **argv, error = 1; goto defect_bailout; break; - } + } max_possible_size = (hdr_max / entry_size) * entry_size; num_returned = returned_length / entry_size; @@ -4089,7 +4100,7 @@ readdefects(struct cam_device *device, int argc, char **argv, if (ccb != NULL) cam_freeccb(ccb); - return(error); + return (error); } #endif /* MINIMALISTIC */ @@ -4290,7 +4301,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, if (ccb == NULL) { warnx("scsicmd: error allocating ccb"); - return(1); + return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(ccb); @@ -4490,7 +4501,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, case 3: case 6: case 7: - /* computed by buff_encode_visit */ + /* computed by buff_encode_visit */ break; case 4: cdb_len = 16; @@ -4619,7 +4630,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, cam_freeccb(ccb); - return(error); + return (error); } static int @@ -4673,7 +4684,7 @@ camdebug(int argc, char **argv, char *combinedopt) if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { warnx("error opening transport layer device %s", XPT_DEVICE); warn("%s", XPT_DEVICE); - return(1); + return (1); } argc -= optind; argv += optind; @@ -4682,7 +4693,7 @@ camdebug(int argc, char **argv, char *combinedopt) warnx("you must specify \"off\", \"all\" or a bus,"); warnx("bus:target, or bus:target:lun"); close(fd); - return(1); + return (1); } tstr = *argv; @@ -4756,7 +4767,7 @@ camdebug(int argc, char **argv, char *combinedopt) close(fd); } - return(error); + return (error); } static int @@ -4774,7 +4785,7 @@ tagcontrol(struct cam_device *device, int argc, char **argv, if (ccb == NULL) { warnx("tagcontrol: error allocating ccb"); - return(1); + return (1); } while ((c = getopt(argc, argv, combinedopt)) != -1) { @@ -4870,7 +4881,7 @@ tagcontrol(struct cam_device *device, int argc, char **argv, tagcontrol_bailout: cam_freeccb(ccb); - return(retval); + return (retval); } static void @@ -5023,7 +5034,7 @@ get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) ccb = cam_getccb(device); if (ccb == NULL) { warnx("get_cpi: couldn't allocate CCB"); - return(1); + return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi); ccb->ccb_h.func_code = XPT_PATH_INQ; @@ -5046,7 +5057,7 @@ get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) get_cpi_bailout: cam_freeccb(ccb); - return(retval); + return (retval); } /* @@ -5061,7 +5072,7 @@ get_cgd(struct cam_device *device, struct ccb_getdev *cgd) ccb = cam_getccb(device); if (ccb == NULL) { warnx("get_cgd: couldn't allocate CCB"); - return(1); + return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd); ccb->ccb_h.func_code = XPT_GDEV_TYPE; @@ -5084,7 +5095,7 @@ get_cgd(struct cam_device *device, struct ccb_getdev *cgd) get_cgd_bailout: cam_freeccb(ccb); - return(retval); + return (retval); } /* @@ -5106,7 +5117,7 @@ dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count, retval = -1; goto bailout; } - + /* cam_getccb cleans up the header, caller has to zero the payload */ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); @@ -5153,7 +5164,7 @@ dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count, bailout: if (ccb != NULL) cam_freeccb(ccb); - + return (retval); } @@ -5183,7 +5194,7 @@ get_device_type(struct cam_device *dev, int retry_count, int timeout, break; /*NOTREACHED*/ default: *devtype = CC_DT_UNKNOWN; - goto bailout; + goto bailout; break; /*NOTREACHED*/ } @@ -5258,7 +5269,7 @@ build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags, /*protocol*/ protocol, /*ata_flags*/ ata_flags, /*features*/ features, - /*sector_count*/ sector_count, + /*sector_count*/ sector_count, /*lba*/ lba, /*command*/ command, /*device*/ 0, @@ -5290,7 +5301,7 @@ get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error, /* * In this case, we have SCSI ATA PASS-THROUGH command, 12 - * or 16 byte, and need to see what + * or 16 byte, and need to see what */ if (ccb->ccb_h.flags & CAM_CDB_POINTER) opcode = ccb->csio.cdb_io.cdb_ptr[0]; @@ -5340,7 +5351,7 @@ get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error, ((uint64_t)desc->lba_31_24 << 24) | (desc->lba_23_16 << 16) | (desc->lba_15_8 << 8) | - desc->lba_7_0; + desc->lba_7_0; *device = desc->device; *status = desc->status; @@ -5391,7 +5402,7 @@ get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error, res = &ccb->ataio.res; *error = res->error; *status = res->status; - *device = res->device; + *device = res->device; *count = res->sector_count; *lba = (res->lba_high << 16) | (res->lba_mid << 8) | @@ -5591,7 +5602,7 @@ get_print_cts(struct cam_device *device, int user_settings, int quiet, if (ccb == NULL) { warnx("get_print_cts: error allocating ccb"); - return(1); + return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); @@ -5631,7 +5642,7 @@ get_print_cts(struct cam_device *device, int user_settings, int quiet, cam_freeccb(ccb); - return(retval); + return (retval); } static int @@ -5654,7 +5665,7 @@ ratecontrol(struct cam_device *device, int task_attr, int retry_count, ccb = cam_getccb(device); if (ccb == NULL) { warnx("ratecontrol: error allocating ccb"); - return(1); + return (1); } while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c){ @@ -5986,7 +5997,7 @@ ratecontrol(struct cam_device *device, int task_attr, int retry_count, ratecontrol_bailout: cam_freeccb(ccb); - return(retval); + return (retval); } static int @@ -6010,7 +6021,7 @@ scsiformat(struct cam_device *device, int argc, char **argv, if (ccb == NULL) { warnx("scsiformat: error allocating ccb"); - return(1); + return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); @@ -6276,7 +6287,7 @@ scsiformat(struct cam_device *device, int argc, char **argv, cam_freeccb(ccb); - return(error); + return (error); } static int @@ -6305,7 +6316,7 @@ scsisanitize(struct cam_device *device, int argc, char **argv, if (ccb == NULL) { warnx("scsisanitize: error allocating ccb"); - return(1); + return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); @@ -6686,7 +6697,7 @@ scsisanitize(struct cam_device *device, int argc, char **argv, free(data_ptr); cam_freeccb(ccb); - return(error); + return (error); } static int @@ -7316,7 +7327,7 @@ smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, } else if ((amt_written == 0) && (amt_to_write > 0)) { warnx("only wrote %u bytes out of %u", - response_size - amt_to_write, + response_size - amt_to_write, response_size); } } @@ -7334,6 +7345,290 @@ smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, return (error); } +static int +mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, + int retry_count, int timeout) +{ + int c, error = 0; + union ccb *ccb; + int32_t mmc_opcode = 0, mmc_arg = 0; + int32_t mmc_flags = -1; + int retval; + int is_write = 0; + int is_bw_4 = 0, is_bw_1 = 0; + int is_highspeed = 0, is_stdspeed = 0; + int is_info_request = 0; + int flags = 0; + uint8_t mmc_data_byte = 0; + + /* For IO_RW_EXTENDED command */ + uint8_t *mmc_data = NULL; + struct mmc_data mmc_d; + int mmc_data_len = 0; + + /* + * Note that at the moment we don't support sending SMP CCBs to + * devices that aren't probed by CAM. + */ + ccb = cam_getccb(device); + if (ccb == NULL) { + warnx("%s: error allocating CCB", __func__); + return (1); + } + + bzero(&(&ccb->ccb_h)[1], + sizeof(union ccb) - sizeof(struct ccb_hdr)); + + while ((c = getopt(argc, argv, combinedopt)) != -1) { + switch (c) { + case '4': + is_bw_4 = 1; + break; + case '1': + is_bw_1 = 1; + break; + case 'S': + if (!strcmp(optarg, "high")) + is_highspeed = 1; + else + is_stdspeed = 1; + break; + case 'I': + is_info_request = 1; + break; + case 'c': + mmc_opcode = strtol(optarg, NULL, 0); + if (mmc_opcode < 0) { + warnx("invalid MMC opcode %d", + mmc_opcode); + error = 1; + goto mmccmd_bailout; + } + break; + case 'a': + mmc_arg = strtol(optarg, NULL, 0); + if (mmc_arg < 0) { + warnx("invalid MMC arg %d", + mmc_arg); + error = 1; + goto mmccmd_bailout; + } + break; + case 'f': + mmc_flags = strtol(optarg, NULL, 0); + if (mmc_flags < 0) { + warnx("invalid MMC flags %d", + mmc_flags); + error = 1; + goto mmccmd_bailout; + } + break; + case 'l': + mmc_data_len = strtol(optarg, NULL, 0); + if (mmc_data_len <= 0) { + warnx("invalid MMC data len %d", + mmc_data_len); + error = 1; + goto mmccmd_bailout; + } + break; + case 'W': + is_write = 1; + break; + case 'b': + mmc_data_byte = strtol(optarg, NULL, 0); + break; + default: + break; + } + } + flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */ + + /* If flags are left default, supply the right flags */ + if (mmc_flags < 0) + switch (mmc_opcode) { + case MMC_GO_IDLE_STATE: + mmc_flags = MMC_RSP_NONE | MMC_CMD_BC; + break; + case IO_SEND_OP_COND: + mmc_flags = MMC_RSP_R4; + break; + case SD_SEND_RELATIVE_ADDR: + mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR; + break; + case MMC_SELECT_CARD: + mmc_flags = MMC_RSP_R1B | MMC_CMD_AC; + mmc_arg = mmc_arg << 16; + break; + case SD_IO_RW_DIRECT: + mmc_flags = MMC_RSP_R5 | MMC_CMD_AC; + mmc_arg = SD_IO_RW_ADR(mmc_arg); + if (is_write) + mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte); + break; + case SD_IO_RW_EXTENDED: + mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC; + mmc_arg = SD_IO_RW_ADR(mmc_arg); + int len_arg = mmc_data_len; + if (mmc_data_len == 512) + len_arg = 0; + + // Byte mode + mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR; + // Block mode +// mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR; + break; + default: + mmc_flags = MMC_RSP_R1; + break; + } + + // Switch bus width instead of sending IO command + if (is_bw_4 || is_bw_1) { + struct ccb_trans_settings_mmc *cts; + ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + ccb->ccb_h.flags = 0; + cts = &ccb->cts.proto_specific.mmc; + cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1; + cts->ios_valid = MMC_BW; + if (((retval = cam_send_ccb(device, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + warn("Error sending command"); + } else { + printf("Parameters set OK\n"); + } + cam_freeccb(ccb); + return (retval); + } + + // Switch bus speed instead of sending IO command + if (is_stdspeed || is_highspeed) { + struct ccb_trans_settings_mmc *cts; + ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + ccb->ccb_h.flags = 0; + cts = &ccb->cts.proto_specific.mmc; + cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal; + cts->ios_valid = MMC_BT; + if (((retval = cam_send_ccb(device, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + warn("Error sending command"); + } else { + printf("Speed set OK (HS: %d)\n", is_highspeed); + } + cam_freeccb(ccb); + return (retval); + } + + // Get information about controller and its settings + if (is_info_request) { + ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + ccb->ccb_h.flags = 0; + struct ccb_trans_settings_mmc *cts; + cts = &ccb->cts.proto_specific.mmc; + if (((retval = cam_send_ccb(device, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + warn("Error sending command"); + return (retval); + } + printf("Host controller information\n"); + printf("Host OCR: 0x%x\n", cts->host_ocr); + printf("Min frequency: %u KHz\n", cts->host_f_min / 1000); + printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000); + printf("Supported bus width: "); + if (cts->host_caps & MMC_CAP_4_BIT_DATA) + printf(" 4 bit\n"); + if (cts->host_caps & MMC_CAP_8_BIT_DATA) + printf(" 8 bit\n"); + printf("\nCurrent settings:\n"); + printf("Bus width: "); + switch (cts->ios.bus_width) { + case bus_width_1: + printf("1 bit\n"); + break; + case bus_width_4: + printf("4 bit\n"); + break; + case bus_width_8: + printf("8 bit\n"); + break; + } + printf("Freq: %d.%03d MHz%s\n", + cts->ios.clock / 1000000, + (cts->ios.clock / 1000) % 1000, + cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : ""); + return (0); + } + + printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags); + + if (mmc_data_len > 0) { + flags |= CAM_DIR_IN; + mmc_data = malloc(mmc_data_len); + memset(mmc_data, 0, mmc_data_len); + mmc_d.len = mmc_data_len; + mmc_d.data = mmc_data; + mmc_d.flags = MMC_DATA_READ; + } else flags |= CAM_DIR_NONE; + + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ retry_count, + /*cbfcnp*/ NULL, + /*flags*/ flags, + /*mmc_opcode*/ mmc_opcode, + /*mmc_arg*/ mmc_arg, + /*mmc_flags*/ mmc_flags, + /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL, + /*timeout*/ timeout ? timeout : 5000); + + if (((retval = cam_send_ccb(device, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + const char warnstr[] = "error sending command"; + + if (retval < 0) + warn(warnstr); + else + warnx(warnstr); + + if (arglist & CAM_ARG_VERBOSE) { + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + } + } + + if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { + printf("MMCIO: error %d, %08x %08x %08x %08x\n", + ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0], + ccb->mmcio.cmd.resp[1], + ccb->mmcio.cmd.resp[2], + ccb->mmcio.cmd.resp[3]); + + switch (mmc_opcode) { + case SD_IO_RW_DIRECT: + printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n", + SD_R5_DATA(ccb->mmcio.cmd.resp), + (ccb->mmcio.cmd.resp[0] >> 12) & 0x3); + break; + case SD_IO_RW_EXTENDED: + printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len); + hexdump(mmc_data, mmc_data_len, NULL, 0); + break; + case SD_SEND_RELATIVE_ADDR: + printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16); + break; + default: + printf("No command-specific decoder for CMD %d\n", mmc_opcode); + } + } +mmccmd_bailout: + if (ccb != NULL) + cam_freeccb(ccb); + + if (mmc_data_len > 0 && mmc_data != NULL) + free(mmc_data); + + return (error); +} + static int smpreportgeneral(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) @@ -7926,7 +8221,7 @@ buildbusdevlist(struct cam_devlist *devlist) if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { warn("couldn't open %s", XPT_DEVICE); - return(1); + return (1); } bzero(&ccb, sizeof(union ccb)); @@ -7942,7 +8237,7 @@ buildbusdevlist(struct cam_devlist *devlist) if (ccb.cdm.matches == NULL) { warnx("can't malloc memory for matches"); close(fd); - return(1); + return (1); } ccb.cdm.num_matches = 0; ccb.cdm.num_patterns = 2; @@ -7993,7 +8288,7 @@ buildbusdevlist(struct cam_devlist *devlist) case DEV_MATCH_DEVICE: { struct device_match_result *dev_result; - dev_result = + dev_result = &ccb.cdm.matches[i].result.device_result; if (dev_result->flags & @@ -8344,7 +8639,7 @@ smpphylist(struct cam_device *device, int argc, char **argv, fprintf(stdout, "%s%d", item->periph_matches[j].periph_name, item->periph_matches[j].unit_number); - + } fprintf(stdout, ")\n"); } @@ -8546,7 +8841,7 @@ scsigetopcodes(struct cam_device *device, int opcode_set, int opcode, alloc_len += num_opcodes * sizeof(struct scsi_report_supported_opcodes_timeout); } - + if (sa_set != 0) { options |= RSO_OPTIONS_OC_SA; if (show_sa_errors != 0) @@ -8557,7 +8852,7 @@ scsigetopcodes(struct cam_device *device, int opcode_set, int opcode, if (buf != NULL) { free(buf); buf = NULL; - } + } buf = malloc(alloc_len); if (buf == NULL) { @@ -8594,7 +8889,6 @@ scsigetopcodes(struct cam_device *device, int opcode_set, int opcode, if (verbosemode != 0) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); - retval = 1; goto bailout; } @@ -9580,167 +9874,171 @@ main(int argc, char **argv) switch(cmdlist) { #ifndef MINIMALISTIC - case CAM_CMD_DEVLIST: - error = getdevlist(cam_dev); - break; - case CAM_CMD_HPA: - error = atahpa(cam_dev, retry_count, timeout, - argc, argv, combinedopt); - break; + case CAM_CMD_DEVLIST: + error = getdevlist(cam_dev); + break; + case CAM_CMD_HPA: + error = atahpa(cam_dev, retry_count, timeout, + argc, argv, combinedopt); + break; #endif /* MINIMALISTIC */ - case CAM_CMD_DEVTREE: - error = getdevtree(argc, argv, combinedopt); - break; + case CAM_CMD_DEVTREE: + error = getdevtree(argc, argv, combinedopt); + break; #ifndef MINIMALISTIC - case CAM_CMD_TUR: - error = testunitready(cam_dev, task_attr, retry_count, - timeout, 0); - break; - case CAM_CMD_INQUIRY: - error = scsidoinquiry(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout); - break; - case CAM_CMD_IDENTIFY: - error = ataidentify(cam_dev, retry_count, timeout); - break; - case CAM_CMD_STARTSTOP: - error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, - arglist & CAM_ARG_EJECT, task_attr, - retry_count, timeout); - break; + case CAM_CMD_TUR: + error = testunitready(cam_dev, task_attr, retry_count, + timeout, 0); + break; + case CAM_CMD_INQUIRY: + error = scsidoinquiry(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout); + break; + case CAM_CMD_IDENTIFY: + error = ataidentify(cam_dev, retry_count, timeout); + break; + case CAM_CMD_STARTSTOP: + error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, + arglist & CAM_ARG_EJECT, task_attr, + retry_count, timeout); + break; #endif /* MINIMALISTIC */ - case CAM_CMD_RESCAN: - error = dorescan_or_reset(argc, argv, 1); - break; - case CAM_CMD_RESET: - error = dorescan_or_reset(argc, argv, 0); - break; + case CAM_CMD_RESCAN: + error = dorescan_or_reset(argc, argv, 1); + break; + case CAM_CMD_RESET: + error = dorescan_or_reset(argc, argv, 0); + break; #ifndef MINIMALISTIC - case CAM_CMD_READ_DEFECTS: - error = readdefects(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout); - break; - case CAM_CMD_MODE_PAGE: - modepage(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout); - break; - case CAM_CMD_SCSI_CMD: - error = scsicmd(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout); - break; - case CAM_CMD_SMP_CMD: - error = smpcmd(cam_dev, argc, argv, combinedopt, + case CAM_CMD_READ_DEFECTS: + error = readdefects(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout); + break; + case CAM_CMD_MODE_PAGE: + modepage(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout); + break; + case CAM_CMD_SCSI_CMD: + error = scsicmd(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout); + break; + case CAM_CMD_MMCSD_CMD: + error = mmcsdcmd(cam_dev, argc, argv, combinedopt, + retry_count, timeout); + break; + case CAM_CMD_SMP_CMD: + error = smpcmd(cam_dev, argc, argv, combinedopt, + retry_count, timeout); + break; + case CAM_CMD_SMP_RG: + error = smpreportgeneral(cam_dev, argc, argv, + combinedopt, retry_count, + timeout); + break; + case CAM_CMD_SMP_PC: + error = smpphycontrol(cam_dev, argc, argv, combinedopt, + retry_count, timeout); + break; + case CAM_CMD_SMP_PHYLIST: + error = smpphylist(cam_dev, argc, argv, combinedopt, + retry_count, timeout); + break; + case CAM_CMD_SMP_MANINFO: + error = smpmaninfo(cam_dev, argc, argv, combinedopt, + retry_count, timeout); + break; + case CAM_CMD_DEBUG: + error = camdebug(argc, argv, combinedopt); + break; + case CAM_CMD_TAG: + error = tagcontrol(cam_dev, argc, argv, combinedopt); + break; + case CAM_CMD_RATE: + error = ratecontrol(cam_dev, task_attr, retry_count, + timeout, argc, argv, combinedopt); + break; + case CAM_CMD_FORMAT: + error = scsiformat(cam_dev, argc, argv, + combinedopt, task_attr, retry_count, + timeout); + break; + case CAM_CMD_REPORTLUNS: + error = scsireportluns(cam_dev, argc, argv, + combinedopt, task_attr, retry_count, timeout); - break; - case CAM_CMD_SMP_RG: - error = smpreportgeneral(cam_dev, argc, argv, - combinedopt, retry_count, - timeout); - break; - case CAM_CMD_SMP_PC: - error = smpphycontrol(cam_dev, argc, argv, combinedopt, - retry_count, timeout); - break; - case CAM_CMD_SMP_PHYLIST: - error = smpphylist(cam_dev, argc, argv, combinedopt, - retry_count, timeout); - break; - case CAM_CMD_SMP_MANINFO: - error = smpmaninfo(cam_dev, argc, argv, combinedopt, - retry_count, timeout); - break; - case CAM_CMD_DEBUG: - error = camdebug(argc, argv, combinedopt); - break; - case CAM_CMD_TAG: - error = tagcontrol(cam_dev, argc, argv, combinedopt); - break; - case CAM_CMD_RATE: - error = ratecontrol(cam_dev, task_attr, retry_count, - timeout, argc, argv, combinedopt); - break; - case CAM_CMD_FORMAT: - error = scsiformat(cam_dev, argc, argv, - combinedopt, task_attr, retry_count, - timeout); - break; - case CAM_CMD_REPORTLUNS: - error = scsireportluns(cam_dev, argc, argv, - combinedopt, task_attr, - retry_count, timeout); - break; - case CAM_CMD_READCAP: - error = scsireadcapacity(cam_dev, argc, argv, - combinedopt, task_attr, - retry_count, timeout); - break; - case CAM_CMD_IDLE: - case CAM_CMD_STANDBY: - case CAM_CMD_SLEEP: - error = atapm(cam_dev, argc, argv, - combinedopt, retry_count, timeout); - break; - case CAM_CMD_APM: - case CAM_CMD_AAM: - error = ataaxm(cam_dev, argc, argv, - combinedopt, retry_count, timeout); - break; - case CAM_CMD_SECURITY: - error = atasecurity(cam_dev, retry_count, timeout, - argc, argv, combinedopt); - break; - case CAM_CMD_DOWNLOAD_FW: - error = fwdownload(cam_dev, argc, argv, combinedopt, - arglist & CAM_ARG_VERBOSE, task_attr, retry_count, - timeout); - break; - case CAM_CMD_SANITIZE: - error = scsisanitize(cam_dev, argc, argv, - combinedopt, task_attr, - retry_count, timeout); - break; - case CAM_CMD_PERSIST: - error = scsipersist(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout, - arglist & CAM_ARG_VERBOSE, - arglist & CAM_ARG_ERR_RECOVER); - break; - case CAM_CMD_ATTRIB: - error = scsiattrib(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout, - arglist & CAM_ARG_VERBOSE, - arglist & CAM_ARG_ERR_RECOVER); - break; - case CAM_CMD_OPCODES: - error = scsiopcodes(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout, - arglist & CAM_ARG_VERBOSE); - break; - case CAM_CMD_REPROBE: - error = scsireprobe(cam_dev); - break; - case CAM_CMD_ZONE: - error = zone(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout, - arglist & CAM_ARG_VERBOSE); - break; - case CAM_CMD_EPC: - error = epc(cam_dev, argc, argv, combinedopt, - retry_count, timeout, arglist & CAM_ARG_VERBOSE); - break; - case CAM_CMD_TIMESTAMP: - error = timestamp(cam_dev, argc, argv, combinedopt, - task_attr, retry_count, timeout, - arglist & CAM_ARG_VERBOSE); - break; + break; + case CAM_CMD_READCAP: + error = scsireadcapacity(cam_dev, argc, argv, + combinedopt, task_attr, + retry_count, timeout); + break; + case CAM_CMD_IDLE: + case CAM_CMD_STANDBY: + case CAM_CMD_SLEEP: + error = atapm(cam_dev, argc, argv, + combinedopt, retry_count, timeout); + break; + case CAM_CMD_APM: + case CAM_CMD_AAM: + error = ataaxm(cam_dev, argc, argv, + combinedopt, retry_count, timeout); + break; + case CAM_CMD_SECURITY: + error = atasecurity(cam_dev, retry_count, timeout, + argc, argv, combinedopt); + break; + case CAM_CMD_DOWNLOAD_FW: + error = fwdownload(cam_dev, argc, argv, combinedopt, + arglist & CAM_ARG_VERBOSE, task_attr, retry_count, + timeout); + break; + case CAM_CMD_SANITIZE: + error = scsisanitize(cam_dev, argc, argv, + combinedopt, task_attr, + retry_count, timeout); + break; + case CAM_CMD_PERSIST: + error = scsipersist(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout, + arglist & CAM_ARG_VERBOSE, + arglist & CAM_ARG_ERR_RECOVER); + break; + case CAM_CMD_ATTRIB: + error = scsiattrib(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout, + arglist & CAM_ARG_VERBOSE, + arglist & CAM_ARG_ERR_RECOVER); + break; + case CAM_CMD_OPCODES: + error = scsiopcodes(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout, + arglist & CAM_ARG_VERBOSE); + break; + case CAM_CMD_REPROBE: + error = scsireprobe(cam_dev); + break; + case CAM_CMD_ZONE: + error = zone(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout, + arglist & CAM_ARG_VERBOSE); + break; + case CAM_CMD_EPC: + error = epc(cam_dev, argc, argv, combinedopt, + retry_count, timeout, arglist & CAM_ARG_VERBOSE); + break; + case CAM_CMD_TIMESTAMP: + error = timestamp(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout, + arglist & CAM_ARG_VERBOSE); + break; #endif /* MINIMALISTIC */ - case CAM_CMD_USAGE: - usage(1); - break; - default: - usage(0); - error = 1; - break; + case CAM_CMD_USAGE: + usage(1); + break; + default: + usage(0); + error = 1; + break; } if (cam_dev != NULL) diff --git a/sbin/init/init.c b/sbin/init/init.c index cc7d8e5d2060..34e40457622f 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -1271,8 +1271,8 @@ new_session(session_t *sprev, struct ttyent *typ) sp->se_flags |= SE_PRESENT; - sp->se_device = malloc(sizeof(_PATH_DEV) + strlen(typ->ty_name)); - sprintf(sp->se_device, "%s%s", _PATH_DEV, typ->ty_name); + if (asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name) < 0) + err(1, "asprintf"); /* * Attempt to open the device, if we get "device not configured" @@ -1315,8 +1315,8 @@ setupargv(session_t *sp, struct ttyent *typ) free(sp->se_getty_argv_space); free(sp->se_getty_argv); } - sp->se_getty = malloc(strlen(typ->ty_getty) + strlen(typ->ty_name) + 2); - sprintf(sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name); + if (asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name) < 0) + err(1, "asprintf"); sp->se_getty_argv_space = strdup(sp->se_getty); sp->se_getty_argv = construct_argv(sp->se_getty_argv_space); if (sp->se_getty_argv == NULL) { @@ -1429,7 +1429,7 @@ start_window_system(session_t *sp) if (sp->se_type) { /* Don't use malloc after fork */ strcpy(term, "TERM="); - strncat(term, sp->se_type, sizeof(term) - 6); + strlcat(term, sp->se_type, sizeof(term)); env[0] = term; env[1] = 0; } @@ -1493,7 +1493,7 @@ start_getty(session_t *sp) if (sp->se_type) { /* Don't use malloc after fork */ strcpy(term, "TERM="); - strncat(term, sp->se_type, sizeof(term) - 6); + strlcat(term, sp->se_type, sizeof(term)); env[0] = term; env[1] = 0; } else diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index e474eac483e5..8b600e1f8cba 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -398,7 +398,9 @@ main(int argc, char *argv[]) have_fstab = 1; mntfromname = mntbuf->f_mntfromname; } else if (argv[0][0] == '/' && - argv[0][1] == '\0') { + argv[0][1] == '\0' && + strcmp(fs->fs_vfstype, + mntbuf->f_fstypename) == 0) { fs = getfsfile("/"); have_fstab = 1; mntfromname = fs->fs_spec; diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8 index 01270b5f1b50..335d92086013 100644 --- a/sbin/newfs/newfs.8 +++ b/sbin/newfs/newfs.8 @@ -28,7 +28,7 @@ .\" @(#)newfs.8 8.6 (Berkeley) 5/3/95 .\" $FreeBSD$ .\" -.Dd July 15, 2015 +.Dd July 7, 2017 .Dt NEWFS 8 .Os .Sh NAME @@ -79,11 +79,9 @@ The following options define the general layout policies: .It Fl E Erase the content of the disk before making the filesystem. The reserved area in front of the superblock (for bootcode) will not be erased. -.Pp -This option is only relevant for flash based storage devices that use -wear-leveling algorithms. -.Pp -Erasing may take a long time as it writes to every sector on the disk. +Erasing is only relevant to flash-memory or thinly provisioned devices. +Erasing may take a long time. +If the device does not support BIO_DELETE, the command will fail. .It Fl J Enable journaling on the new file system via gjournal. See @@ -264,9 +262,11 @@ Turn on the TRIM enable flag. If enabled, and if the underlying device supports the BIO_DELETE command, the file system will send a delete request to the underlying device for each freed block. -The trim enable flag is typically set when the underlying device -uses flash-memory as the device can use the delete command to -pre-zero or at least avoid copying blocks that have been deleted. +The trim enable flag is typically set for flash-memory devices to +reduce write amplification which reduces wear on write-limited +flash-memory and often improves long-term performance. +Thinly provisioned storage also benefits by returning unused blocks to +the global pool. .El .Pp The following options override the standard sizes for the disk geometry. diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c index 9c1cd98418eb..22b4793f4ff5 100644 --- a/sbin/savecore/savecore.c +++ b/sbin/savecore/savecore.c @@ -119,7 +119,7 @@ printheader(xo_handle_t *xo, const struct kerneldumpheader *h, const char *devic xo_emit_h(xo, "{P: }{Lwc:Dumptime}{:dumptime/%s}", ctime(&t)); xo_emit_h(xo, "{P: }{Lwc:Hostname}{:hostname/%s}\n", h->hostname); xo_emit_h(xo, "{P: }{Lwc:Magic}{:magic/%s}\n", h->magic); - xo_emit_h(xo, "{P: }{Lwc:Version String}{:version_string/%s}", h->versionstring); + xo_emit_h(xo, "{P: }{Lwc:Version String}{:version_string/%s}\n", h->versionstring); xo_emit_h(xo, "{P: }{Lwc:Panic String}{:panic_string/%s}\n", h->panicstring); xo_emit_h(xo, "{P: }{Lwc:Dump Parity}{:dump_parity/%u}\n", h->parity); xo_emit_h(xo, "{P: }{Lwc:Bounds}{:bounds/%d}\n", bounds); @@ -334,6 +334,13 @@ check_space(const char *savedir, off_t dumpsize, int bounds) return (1); } +static bool +compare_magic(const struct kerneldumpheader *kdh, const char *magic) +{ + + return (strncmp(kdh->magic, magic, sizeof(kdh->magic)) == 0); +} + #define BLOCKSIZE (1<<12) #define BLOCKMASK (~(BLOCKSIZE-1)) @@ -564,7 +571,7 @@ DoFile(const char *savedir, const char *device) } memcpy(&kdhl, temp, sizeof(kdhl)); istextdump = 0; - if (strncmp(kdhl.magic, TEXTDUMPMAGIC, sizeof kdhl) == 0) { + if (compare_magic(&kdhl, TEXTDUMPMAGIC)) { if (verbose) printf("textdump magic on last dump header on %s\n", device); @@ -578,8 +585,7 @@ DoFile(const char *savedir, const char *device) if (force == 0) goto closefd; } - } else if (memcmp(kdhl.magic, KERNELDUMPMAGIC, sizeof kdhl.magic) == - 0) { + } else if (compare_magic(&kdhl, KERNELDUMPMAGIC)) { if (dtoh32(kdhl.version) != KERNELDUMPVERSION) { syslog(LOG_ERR, "unknown version (%d) in last dump header on %s", @@ -598,8 +604,7 @@ DoFile(const char *savedir, const char *device) if (force == 0) goto closefd; - if (memcmp(kdhl.magic, KERNELDUMPMAGIC_CLEARED, - sizeof kdhl.magic) == 0) { + if (compare_magic(&kdhl, KERNELDUMPMAGIC_CLEARED)) { if (verbose) printf("forcing magic on %s\n", device); memcpy(kdhl.magic, KERNELDUMPMAGIC, diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 7444b91d4963..a5747e213254 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -141,6 +141,7 @@ MAN= aac.4 \ edsc.4 \ ehci.4 \ em.4 \ + ena.4 \ enc.4 \ epair.4 \ esp.4 \ diff --git a/share/man/man4/dtrace_lockstat.4 b/share/man/man4/dtrace_lockstat.4 index 4f70dc0cee50..95fe5ea1aaca 100644 --- a/share/man/man4/dtrace_lockstat.4 +++ b/share/man/man4/dtrace_lockstat.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 11, 2017 +.Dd July 3, 2017 .Dt DTRACE_LOCKSTAT 4 .Os .Sh NAME @@ -54,198 +54,247 @@ .Sh DESCRIPTION The DTrace .Nm lockstat -provider allows the tracing of events related to locking on FreeBSD. +provider allows the tracing of events related to locking on +.Fx . .Pp The .Nm lockstat -provider contains DTrace probe for inspecting the kernel's lock +provider contains DTrace probes for inspecting the kernel's lock state transitions. -Tracepoints exist for several types of kernel -locking primitives, including mutexes, spin, reader-writer, -and shared exclusive locks. -An attempt has been made to provide a regular and easy to understand -interface to the +Probes exist for the +.Xr mutex 9 , +.Xr rwlock 9 +and +.Xr sx 9 +lock types. +The +.Xr lockstat 1 +utility can be used to collect and display data collected from the .Nm lockstat provider. -Each type of lock has an +Each type of lock has .Fn acquire and .Fn release -probe which exposes the lock structure that is being operated upon. -.Pp -Whenever an MTX_DEF mutex is acquired the -.Fn lockstat:::adaptive-acquire -probe fires. -The only argument is a pointer to the lock structure which describes -the lock that is being acquired. +probes which expose the lock structure being operated upon, +as well as probes which fire when a thread contends with other threads +for ownership of a lock. .Pp The +.Fn lockstat:::adaptive-acquire +and .Fn lockstat:::adaptive-release -probe fires whenever an adaptive lock is released. +probes fire when an +.Dv MTX_DEF +.Xr mutex 9 +is acquired and released, respectively. The only argument is a pointer to the lock structure which describes -the lock that is being released. +the lock being acquired or released. .Pp The .Fn lockstat:::adaptive-spin -probe fires when an adaptive lock is acquired. +probe fires when a thread spins while waiting for a +.Dv MTX_DEF +.Xr mutex 9 +to be released by another thread. The first argument is a pointer to the lock structure that describes the lock and the second argument is the amount of time, -in nanoseconds, -that the mutex spent spinning. -.Pp +in nanoseconds, that the mutex spent spinning. The .Fn lockstat:::adaptive-block -probe fires whenever thread takes itself off of the CPU -while trying to acquire the lock. +probe fires when a thread takes itself off the CPU while trying to acquire an +.Dv MTX_DEF +.Xr mutex 9 +that is owned by another thread. The first argument is a pointer to the lock structure that describes the lock and the second argument is the length of time, -in nanoseconds, -that the waiting thread was blocked. +in nanoseconds, that the waiting thread was blocked. The .Fn lockstat:::adaptive-block -probe fires only after the lock has been successfully acquired, -after the adaptive-acquire probe fires. -.Pp -Whenever a spin mutex is acquired the -.Fn lockstat:::spin-acquire +and +.Fn lockstat:::adaptive-spin +probes fire only after the lock has been successfully acquired, +and in particular, after the +.Fn lockstat:::adaptive-acquire probe fires. -The only argument is a pointer to the lock structure which describes -the lock that is being acquired. .Pp The +.Fn lockstat:::spin-acquire +and .Fn lockstat:::spin-release -probe fires whenever a spin mutex is released. +probes fire when a +.Dv MTX_SPIN +.Xr mutex 9 +is acquired and released, respectively. The only argument is a pointer to the lock structure which describes -the lock that is being released. +the lock being acquired or released. .Pp The .Fn lockstat:::spin-spin -probe fires when a thread stops spinning waiting for a spin mutex. +probe fires when a thread spins while waiting for a +.Dv MTX_SPIN +.Xr mutex 9 +to be released by another thread. The first argument is a pointer to the lock structure that describes the lock and the second argument is the length of the time spent spinning, in nanoseconds. -.Pp -Whenever a reader-writer lock is acquired the -.Fn lockstat:::rw-acquire +The +.Fn lockstat:::spin-spin +probe fires only after the lock has been successfully acquired, +and in particular, after the +.Fn lockstat:::spin-acquire probe fires. -The only argument is a pointer to the structure which describes -the lock that is being acquired. .Pp The +.Fn lockstat:::rw-acquire +and .Fn lockstat:::rw-release -probe fires whenever a reader-writer lock is released. +probes fire when a +.Xr rwlock 9 +is acquired and released, respectively. +The first argument is a pointer to the structure which describes +the lock being acquired. +The second argument is +.Dv 0 +if the lock is being acquired or released as a writer, and +.Dv 1 +if it is being acquired or released as a reader. .Pp The .Fn lockstat:::rw-block -probe fires whenever a thread removes itself from the CPU while -waiting to acquire the lock. -The first argument is a pointer to the lock structure that describes -the lock and the second argument is the length of time, -in nanoseconds, -that the waiting thread was blocked. -The third argument is 1 if the thread was were spinning while -trying to acquire a read lock, -otherwise it will be 0 indicating that we were spinning for the write lock. -The fourth argument is 1 if we were waiting for a reader to release the lock, -otherwise it will be 0 indicating that we were waiting for a writer -to release the lock. -The fifth argument is the number of readers that held the lock when -we started spinning; in particular, argument 5 is non-zero only -if the fourth argument is 1. -.Pp +probe fires when a thread removes itself from the CPU while +waiting to acquire a +.Xr rwlock 9 . The .Fn lockstat:::rw-spin -probe fires when a reader-writer lock takes itself off the CPU -while waiting for the lock. +probe fires when a thread spins while waiting to acquire a +.Xr rwlock 9 . +Both probes take the same set of arguments. The first argument is a pointer to the lock structure that describes -the lock and the second argument returns an integer count of the -number of spins that were completed. +the lock. +The second argument is the length of time, in nanoseconds, +that the waiting thread was off the CPU or spinning for the lock. +The third argument is +.Dv 0 +if the thread is attempting to acquire the lock as a writer, and +.Dv 1 +if the thread is attempting to acquire the lock as a reader. +The fourth argument is +.Dv 0 +if the thread is waiting for a writer to release the lock, and +.Dv 1 +if the thread is waiting for a reader to release the lock. +The fifth argument is the number of readers that held the lock when +the thread first attempted to acquire the lock. +This argument will be +.Dv 0 +if the fourth argument is +.Dv 0 . .Pp The .Fn lockstat:::rw-upgrade -probe fires whenever a thread tries to upgrade a lock from a +probe fires when a thread successfully upgrades a held +.Xr rwlock 9 read lock to a write lock. -The only argument is a pointer to the structure which describes -the lock that is being acquired. -.Pp +The .Fn lockstat:::rw-downgrade -probe fires whenever a thread tries downgrades a lock from a -read and write lock to a read lock. +probe first when a thread downgrades a held +.Xr rwlock 9 +write lock to a read lock. The only argument is a pointer to the structure which describes -the lock that is being acquired. -.Pp -Whenever a shared-exclusive lock is acquired the -.Fn lockstat:::sx-acquire -probe fires. -The only argument is a pointer to the structure which describes -the lock that is being acquired. +the lock being acquired. .Pp The +.Fn lockstat:::sx-acquire +and .Fn lockstat:::sx-release -probe fires whenever an adaptive lock is released. -The only argument is a pointer to the lock structure which describes -the lock that is being released. +probes fire when a +.Xr sx 9 +is acquired and released, respectively. +The first argument is a pointer to the structure which describes +the lock being acquired. +The second argument is +.Dv 0 +if the shared lock is being acquired or released, and +.Dv 1 +if the exclusive lock is being acquired or released. .Pp The .Fn lockstat:::sx-block -probe fires whenever a thread takes itself off the CPU while -waiting for the lock. -The first argument is a pointer to the structure that describes -the lock and the second argument is the length of time, -in nanoseconds, -that the waiting thread was blocked. -The third argument is 1 if the thread was were spinning while -trying to acquire a read lock, -otherwise it will be 0 indicating that we were spinning for the write lock. -The fourth argument is 1 if we were waiting for a reader to release the lock, -otherwise it will be 0 indicating that we were waiting for a writer -to release the lock. -The fifth argument is the number of readers that held the lock when -we started spinning; in particular, argument 5 is non-zero only -if the fourth argument is 1. -.Pp +probe fires when a thread takes itself off the CPU while +waiting to acquire a +.Xr sx 9 . The .Fn lockstat:::sx-spin -probe fires when a thread takes itself off of the CPU while -waiting for the lock. -The first argument is a pointer to the structure that describes -the lock and the second argument returns an integer count of the -number of spins that were completed. +probe first when a thread spins while waiting to acquire a +.Xr sx 9 . +Both probes take the same set of arguments. +The first argument is a pointer to the lock structure that describes +the lock. +The second argument is the length of time, in nanoseconds, +that the waiting thread was off the CPU or spinning for the lock. +The third argument is +.Dv 0 +if the thread is attempting to acquire the lock as a writer, and +.Dv 1 +if the thread is attempting to acquire the lock as a reader. +The fourth argument is +.Dv 0 +if the thread is waiting for a writer to release the lock, and +.Dv 1 +if the thread is waiting for a reader to release the lock. +The fifth argument is the number of readers that held the lock when +the thread first attempted to acquire the lock. +This argument will be +.Dv 0 +if the fourth argument is +.Dv 0 . .Pp The .Fn lockstat:::sx-upgrade -probe fires whenever a thread tries to upgrade a lock from a -shared lock to a shared-exclusive lock. +probe fires when a thread successfully upgrades a held +.Xr sx 9 +shared lock to an exclusive lock. The only argument is a pointer to the structure which describes -the lock that is being upgraded. -.Pp +the lock being acquired. The .Fn lockstat:::sx-downgrade -probe fires whenever a thread downgrades a lock from a -shared-exclusive lock to a shared lock. -The only argument is a pointer to the structure which describes -the lock that is being downgraded. +probe fires when a thread downgrades a held +.Xr sx 9 +exclusive lock to a shared lock. .Pp The .Fn lockstat:::thread-spin -probe fires whenever a thread spins on a spin lock. +probe fires when a thread spins on a thread lock, which is a specialized +.Dv MTX_SPIN +.Xr mutex 9 . The first argument is a pointer to the structure that describes the lock and the second argument is the length of time, -in nanoseconds, -that the thread was spinning. +in nanoseconds, that the thread was spinning. .Sh SEE ALSO .Xr dtrace 1 , .Xr lockstat 1 , .Xr locking 9 , -.Xr SDT 9 +.Xr mutex 9 , +.Xr rwlock 9 , +.Xr SDT 9 , +.Xr sx 9 .Sh HISTORY The .Nm lockstat -provider first appeared in OpenSolaris. -The FreeBSD implementation of the +provider first appeared in Solaris. +The +.Fx +implementation of the .Nm lockstat provider first appeared in .Fx 9. .Sh AUTHORS This manual page was written by .An George V. Neville-Neil Aq Mt gnn@FreeBSD.org . +.Sh BUGS +Probes for +.Xr lockmgr 9 +and +.Xr rmlock 9 +locks have not yet been added. diff --git a/share/man/man4/isp.4 b/share/man/man4/isp.4 index 1031ad5d6d4a..e9686646a200 100644 --- a/share/man/man4/isp.4 +++ b/share/man/man4/isp.4 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2009-2015 Alexander Motin +.\" Copyright (c) 2009-2017 Alexander Motin .\" Copyright (c) 2006 Marcus Alves Grando .\" Copyright (c) 1998-2001 Matthew Jacob, for NASA/Ames Research Center .\" @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 20, 2016 +.Dd July 3, 2017 .Dt ISP 4 .Os .Sh NAME @@ -221,6 +221,15 @@ This value says how long to wait for devices to reappear if they (temporarily) disappear due to loop or fabric events. While this timeout is running, I/O to those devices will simply be held. +.It Va dev.isp.N.use_gff_id +.It Va dev.isp.N.use_gft_id +Setting those options to 0 allows to disable use of GFF_ID and GFT_ID SNS +requests during FC fabric scan. +It may be useful if switch does not implement them correctly, +preventing some devices from being found. +Disabling them may cause unneeded logins to ports not supporting target role +or even FCP at all. +The default is 1 (enabled). .It Va dev.isp.N.wwnn This is the readonly World Wide Node Name value for this port. .It Va dev.isp.N.wwpn @@ -239,7 +248,7 @@ The driver was written by .An Matthew Jacob originally for NetBSD at NASA/Ames Research Center. -Some later improvement was done by +Later improvement was done by .An Alexander Motin Aq Mt mav@FreeBSD.org . .Sh BUGS The driver currently ignores some NVRAM settings. diff --git a/share/man/man4/vt.4 b/share/man/man4/vt.4 index 56e38019906c..2f5d0875655b 100644 --- a/share/man/man4/vt.4 +++ b/share/man/man4/vt.4 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd July 19, 2016 -.Dt "VIRTUAL TERMINALS" 4 +.Dt "VT" 4 .Os .Sh NAME .Nm vt diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 4a4c8e83cc6a..a3361a1b2c74 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,6 +1,6 @@ .\" DO NOT EDIT-- this file is generated by tools/build/options/makeman. .\" $FreeBSD$ -.Dd June 20, 2017 +.Dd July 5, 2017 .Dt SRC.CONF 5 .Os .Sh NAME @@ -764,9 +764,18 @@ by linking against libgnuregex. Set to not build .Xr gpioctl 8 as part of the base system. +.It Va WITHOUT_GPL_DTC +Set to build the BSD licensed version of the device tree compiler rather +than the GPLed one from elinux.org. +.Pp +This is a default setting on +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpcspe. .It Va WITH_GPL_DTC Set to build the GPL'd version of the device tree compiler from elinux.org, instead of the BSD licensed one. +.Pp +This is a default setting on +riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. .It Va WITHOUT_GSSAPI Set to not build libgssapi. .It Va WITHOUT_HAST @@ -1270,8 +1279,8 @@ by proxy. .It Va WITHOUT_RBOOTD Set to not build or install .Xr rbootd 8 . -.It Va WITHOUT_RCMDS -Disable building of the +.It Va WITH_RCMDS +Enable building of the .Bx r-commands. This includes @@ -1536,6 +1545,19 @@ protocols (usable only via 802.1X). Set to not build ZFS file system. .It Va WITHOUT_ZONEINFO Set to not build the timezone database. +When set, it enforces these options: +.Pp +.Bl -item -compact +.It +.Va WITHOUT_ZONEINFO_LEAPSECONDS_SUPPORT +.It +.Va WITHOUT_ZONEINFO_OLD_TIMEZONES_SUPPORT +.El +.It Va WITH_ZONEINFO_LEAPSECONDS_SUPPORT +Set to build leapsecond information in to the timezone database. +.It Va WITH_ZONEINFO_OLD_TIMEZONES_SUPPORT +Set to build backward compatibility timezone aliases in to the timezone +database. .El .Sh FILES .Bl -tag -compact -width Pa diff --git a/share/man/man9/bitset.9 b/share/man/man9/bitset.9 index d4060ace24cc..1d02eee252b5 100644 --- a/share/man/man9/bitset.9 +++ b/share/man/man9/bitset.9 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 24, 2017 +.Dd July 7, 2017 .Dt BITSET 9 .Os .Sh NAME @@ -43,6 +43,7 @@ .Nm BIT_EMPTY , .Nm BIT_ISFULLSET , .Nm BIT_FFS , +.Nm BIT_FLS , .Nm BIT_COUNT , .Nm BIT_SUBSET , .Nm BIT_OVERLAP , @@ -85,6 +86,8 @@ .Ft int .Fn BIT_FFS "const SETSIZE" "struct STRUCTNAME *bitset" .Ft int +.Fn BIT_FLS "const SETSIZE" "struct STRUCTNAME *bitset" +.Ft int .Fn BIT_COUNT "const SETSIZE" "struct STRUCTNAME *bitset" .\" .Ft bool @@ -282,6 +285,23 @@ index parameter to any other macro, you must subtract one from the result. .Pp The +.Fn BIT_FLS +macro returns the 1-index of the last (highest) set bit in +.Fa bitset , +or zero if +.Fa bitset +is empty. +Like with +.Xr fls 3 , +to use the non-zero result of +.Fn BIT_FLS +as a +.Fa bit +index parameter to any other +.Nm +macro, you must subtract one from the result. +.Pp +The .Fn BIT_COUNT macro returns the total number of set bits in .Fa bitset . @@ -499,4 +519,6 @@ argument to all of these macros must match the value given to .Pp Unlike every other reference to individual set members, which are zero-indexed, .Fn BIT_FFS -returns a one-indexed result (or zero if the set is empty). +and +.Fn BIT_FLS +return a one-indexed result (or zero if the set is empty). diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index c216f295181a..6a592c84b422 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -56,6 +56,7 @@ LIBDEVDCTL?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevdctl.a LIBDEVINFO?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevinfo.a LIBDEVSTAT?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevstat.a LIBDIALOG?= ${LIBDESTDIR}${LIBDIR_BASE}/libdialog.a +LIBDL?= ${LIBDESTDIR}${LIBDIR_BASE}/libdl.a LIBDNS?= ${LIBDESTDIR}${LIBDIR_BASE}/libdns.a LIBDPV?= ${LIBDESTDIR}${LIBDIR_BASE}/libdpv.a LIBDTRACE?= ${LIBDESTDIR}${LIBDIR_BASE}/libdtrace.a diff --git a/share/mk/bsd.linker.mk b/share/mk/bsd.linker.mk index 90691f78965c..791ee16e0905 100644 --- a/share/mk/bsd.linker.mk +++ b/share/mk/bsd.linker.mk @@ -70,6 +70,9 @@ ${X_}LINKER_FEATURES= .if ${${X_}LINKER_TYPE} != "bfd" || ${${X_}LINKER_VERSION} > 21750 ${X_}LINKER_FEATURES+= build-id .endif +.if ${${X_}LINKER_TYPE} == "bfd" +${X_}LINKER_FEATURES+= filter +.endif .endif .else # Use LD's values diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index 62402a51c5bc..fb5f77c989d9 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -88,6 +88,7 @@ _LIBRARIES= \ devinfo \ devstat \ dialog \ + dl \ dpv \ dtrace \ dwarf \ diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 1d7824f3081e..925b23d14e80 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -190,6 +190,8 @@ __DEFAULT_NO_OPTIONS = \ SHARED_TOOLCHAIN \ SORT_THREADS \ SVN \ + ZONEINFO_LEAPSECONDS_SUPPORT \ + ZONEINFO_OLD_TIMEZONES_SUPPORT \ # @@ -387,6 +389,11 @@ MK_AUTHPF:= no MK_DTRACE_TESTS:= no .endif +.if ${MK_ZONEINFO} == "no" +MK_ZONEINFO_LEAPSECONDS_SUPPORT:= no +MK_ZONEINFO_OLD_TIMEZONES_SUPPORT:= no +.endif + .if ${MK_CROSS_COMPILER} == "no" MK_BINUTILS_BOOTSTRAP:= no MK_CLANG_BOOTSTRAP:= no diff --git a/share/skel/dot.login b/share/skel/dot.login index 170d25c7dc10..470b92ed29ae 100644 --- a/share/skel/dot.login +++ b/share/skel/dot.login @@ -2,7 +2,11 @@ # # .login - csh login script, read by login shell, after `.cshrc' at login. # -# see also csh(1), environ(7). +# See also csh(1), environ(7). # +# Query terminal size; useful for serial lines. +if ( -x /usr/bin/resizewin ) /usr/bin/resizewin -z + +# Display a random cookie on each login. if ( -x /usr/bin/fortune ) /usr/bin/fortune freebsd-tips diff --git a/share/skel/dot.profile b/share/skel/dot.profile index ad66198ce5e8..211347935200 100644 --- a/share/skel/dot.profile +++ b/share/skel/dot.profile @@ -21,4 +21,8 @@ PAGER=more; export PAGER # set ENV to a file invoked each time sh is started for interactive use. ENV=$HOME/.shrc; export ENV +# Query terminal size; useful for serial lines. +if [ -x /usr/bin/resizewin ] ; then /usr/bin/resizewin -z ; fi + +# Display a random cookie on each login. if [ -x /usr/bin/fortune ] ; then /usr/bin/fortune freebsd-tips ; fi diff --git a/share/zoneinfo/Makefile b/share/zoneinfo/Makefile index b83bbb6a7303..a13a43c62160 100644 --- a/share/zoneinfo/Makefile +++ b/share/zoneinfo/Makefile @@ -28,12 +28,24 @@ # $ svn commit # Commit message: "MFV of tzdata2008X" # +.include + CLEANFILES+= yearistype CLEANDIRS+= builddir CONTRIBDIR= ${SRCTOP}/contrib/tzdata/ .PATH: ${CONTRIBDIR} .if defined(LEAPSECONDS) +.warning "Using backwards compatibility variable for LEAPSECONDS; please use WITH_ZONEINFO_LEAPSECONDS_SUPPORT instead" +MK_ZONEINFO_LEAPSECONDS_SUPPORT= yes +.endif + +.if defined(OLDTIMEZONES) +.warning "Using backwards compatibility variable for OLDTIMEZONES; please use WITH_ZONEINFO_OLD_TIMEZONES_SUPPORT instead" +MK_ZONEINFO_OLD_TIMEZONES_SUPPORT= yes +.endif + +.if ${MK_ZONEINFO_LEAPSECONDS_SUPPORT} != "no" LEAPFILE= -L ${CONTRIBDIR}leapseconds .else LEAPFILE= @@ -43,7 +55,7 @@ TZFILES= africa antarctica asia australasia etcetera europe \ factory northamerica southamerica POSIXRULES= America/New_York -.if defined(OLDTIMEZONES) +.if ${MK_ZONEINFO_OLD_TIMEZONES_SUPPORT} != "no" TZFILES+= backward systemv .endif @@ -67,7 +79,7 @@ TZBUILDSUBDIRS= \ Pacific \ SystemV -.if defined(OLDTIMEZONES) +.if ${MK_ZONEINFO_OLD_TIMEZONES_SUPPORT} != "no" TZBUILDSUBDIRS+= US Mexico Chile Canada Brazil .endif @@ -119,4 +131,8 @@ afterinstall: echo "Run tzsetup(8) manually to update /etc/localtime."; \ fi +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include diff --git a/share/zoneinfo/tests/Makefile b/share/zoneinfo/tests/Makefile new file mode 100644 index 000000000000..b8515df02291 --- /dev/null +++ b/share/zoneinfo/tests/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +.include + +.PATH: ${SRCTOP}/contrib/tzdata + +PACKAGE= tests + +FILESGROUPS+= TESTFILES + +.if ${MK_ZONEINFO_OLD_TIMEZONES_SUPPORT} != "no" +ATF_TESTS_SH+= backward_test +TESTFILES+= backward +.endif + +TESTFILES+= zoneinfo_common.sh +TESTFILESPACKAGE= ${PACKAGE} +TESTFILESDIR= ${TESTSDIR} + +.include diff --git a/share/zoneinfo/tests/backward_test.sh b/share/zoneinfo/tests/backward_test.sh new file mode 100755 index 000000000000..41d2df92914c --- /dev/null +++ b/share/zoneinfo/tests/backward_test.sh @@ -0,0 +1,44 @@ +# +# Copyright (c) 2017 Ngie Cooper +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +atf_test_case links +links_head() +{ + atf_set "descr" "Verify Links directives in contrib/tzdata/backward" +} + +links_body() +{ + verify_Links $(atf_get_srcdir)/backward +} + +atf_init_test_cases() +{ + . "$(dirname "$0")/zoneinfo_common.sh" + + atf_add_test_case links +} diff --git a/share/zoneinfo/tests/zoneinfo_common.sh b/share/zoneinfo/tests/zoneinfo_common.sh new file mode 100755 index 000000000000..0a00a39cfbee --- /dev/null +++ b/share/zoneinfo/tests/zoneinfo_common.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# +# Copyright (c) 2017 Ngie Cooper +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +ZONEINFO_DIR=/usr/share/zoneinfo + +verify_Links() +{ + local zoneinfo_file + + zoneinfo_file=$1 + + awk '$1 == "Link" && NF == 3 { print $2, $3; }' < $zoneinfo_file | \ + while read src dest; do + verify_Link $src $dest + done +} + +verify_Link() +{ + local src dest + + old_path=$ZONEINFO_DIR/$src + new_path=$ZONEINFO_DIR/$dest + + atf_check test -f $new_path + atf_check test -f $old_path + + atf_check cmp $old_path $new_path +} diff --git a/sys/amd64/amd64/efirt.c b/sys/amd64/amd64/efirt.c index ee2dc21ac1b5..94229db1f9ee 100644 --- a/sys/amd64/amd64/efirt.c +++ b/sys/amd64/amd64/efirt.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -193,8 +194,8 @@ efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) uint64_t idx; int bits, i, mode; - obj_1t1_pt = vm_pager_allocate(OBJT_PHYS, NULL, 1 + NPML4EPG + - NPML4EPG * NPDPEPG + NPML4EPG * NPDPEPG * NPDEPG, + obj_1t1_pt = vm_pager_allocate(OBJT_PHYS, NULL, ptoa(1 + + NPML4EPG + NPML4EPG * NPDPEPG + NPML4EPG * NPDPEPG * NPDEPG), VM_PROT_ALL, 0, NULL); VM_OBJECT_WLOCK(obj_1t1_pt); efi_pml4_page = efi_1t1_page(0); @@ -445,7 +446,7 @@ efi_get_time_locked(struct efi_tm *tm) efi_status status; int error; - mtx_assert(&resettodr_lock, MA_OWNED); + mtx_assert(&atrtc_time_lock, MA_OWNED); error = efi_enter(); if (error != 0) return (error); @@ -462,9 +463,9 @@ efi_get_time(struct efi_tm *tm) if (efi_runtime == NULL) return (ENXIO); - mtx_lock(&resettodr_lock); + mtx_lock(&atrtc_time_lock); error = efi_get_time_locked(tm); - mtx_unlock(&resettodr_lock); + mtx_unlock(&atrtc_time_lock); return (error); } @@ -487,7 +488,7 @@ efi_set_time_locked(struct efi_tm *tm) efi_status status; int error; - mtx_assert(&resettodr_lock, MA_OWNED); + mtx_assert(&atrtc_time_lock, MA_OWNED); error = efi_enter(); if (error != 0) return (error); @@ -504,9 +505,9 @@ efi_set_time(struct efi_tm *tm) if (efi_runtime == NULL) return (ENXIO); - mtx_lock(&resettodr_lock); + mtx_lock(&atrtc_time_lock); error = efi_set_time_locked(tm); - mtx_unlock(&resettodr_lock); + mtx_unlock(&atrtc_time_lock); return (error); } diff --git a/sys/amd64/conf/MMCCAM b/sys/amd64/conf/MMCCAM new file mode 100644 index 000000000000..c8bbeb817f5c --- /dev/null +++ b/sys/amd64/conf/MMCCAM @@ -0,0 +1,36 @@ +# MMCCAM is the kernel config for doing MMC on CAM development +# and testing on bhyve +# $FreeBSD$ + +include MINIMAL + +ident MMCCAM + +# Access GPT-formatted and labeled root volume +options GEOM_PART_GPT +options GEOM_LABEL + +# UART -- for bhyve console +device uart + +# kgdb stub +device bvmdebug + +# VirtIO support, needed for bhyve +device virtio # Generic VirtIO bus (required) +device virtio_pci # VirtIO PCI device +device vtnet # VirtIO Ethernet device +device virtio_blk # VirtIO Block device +device virtio_scsi # VirtIO SCSI device +device virtio_balloon # VirtIO Memory Balloon device + +# CAM-specific stuff +device pass +device scbus +device da +device mmccam + +options MMCCAM +# Add CAMDEBUG stuff +options CAMDEBUG +options CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_PROBE|CAM_DEBUG_PERIPH|CAM_DEBUG_TRACE) diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index 70af189d7b24..346c20a5be1b 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -414,7 +414,6 @@ device arcmsr # Areca SATA II RAID # The driver is implemented as a SIM, and so, needs the CAM infrastructure. # options TWA_DEBUG # 0-10; 10 prints the most messages. -options TWA_FLASH_FIRMWARE # firmware image bundled when defined. device twa # 3ware 9000 series PATA/SATA RAID # diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index f77c2c943524..646645392cbd 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -923,9 +923,22 @@ static Elf64_Brandinfo linux_glibc2brandshort = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; +static Elf64_Brandinfo linux_muslbrand = { + .brand = ELFOSABI_LINUX, + .machine = EM_X86_64, + .compat_3_brand = "Linux", + .emul_path = "/compat/linux", + .interp_path = "/lib/ld-musl-x86_64.so.1", + .sysvec = &elf_linux_sysvec, + .interp_newpath = NULL, + .brand_note = &linux64_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + Elf64_Brandinfo *linux_brandlist[] = { &linux_glibc2brand, &linux_glibc2brandshort, + &linux_muslbrand, NULL }; diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index ea849ba3d847..b50b1bae823e 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -1141,9 +1141,22 @@ static Elf32_Brandinfo linux_glibc2brand = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; +static Elf32_Brandinfo linux_muslbrand = { + .brand = ELFOSABI_LINUX, + .machine = EM_386, + .compat_3_brand = "Linux", + .emul_path = "/compat/linux", + .interp_path = "/lib/ld-musl-i386.so.1", + .sysvec = &elf_linux_sysvec, + .interp_newpath = NULL, + .brand_note = &linux32_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + Elf32_Brandinfo *linux_brandlist[] = { &linux_brand, &linux_glibc2brand, + &linux_muslbrand, NULL }; diff --git a/sys/amd64/vmm/amd/amdvi_hw.c b/sys/amd64/vmm/amd/amdvi_hw.c index 7d21e83838fd..22d4a12e3210 100644 --- a/sys/amd64/vmm/amd/amdvi_hw.c +++ b/sys/amd64/vmm/amd/amdvi_hw.c @@ -496,7 +496,7 @@ amdvi_cmp_wait(struct amdvi_softc *softc) #ifdef AMDVI_DEBUG_CMD if (status) - device_printf(softc->dev, "CMD completion DONE Tail:0x%x, + device_printf(softc->dev, "CMD completion DONE Tail:0x%x, " "Head:0x%x, loop:%d.\n", ctrl->cmd_tail, ctrl->cmd_head, loop); #endif diff --git a/sys/amd64/vmm/amd/amdvi_priv.h b/sys/amd64/vmm/amd/amdvi_priv.h index 990b6f7bfd13..c292d3ef9881 100755 --- a/sys/amd64/vmm/amd/amdvi_priv.h +++ b/sys/amd64/vmm/amd/amdvi_priv.h @@ -65,7 +65,7 @@ struct amdvi_dte { uint32_t dt_valid:1; /* Device Table valid. */ uint32_t pt_valid:1; /* Page translation valid. */ - uint8_t :7; /* Reserved[8:2] */ + uint16_t :7; /* Reserved[8:2] */ uint8_t pt_level:3; /* Paging level, 0 to disable. */ uint64_t pt_base:40; /* Page table root pointer. */ uint8_t :3; /* Reserved[54:52] */ diff --git a/sys/amd64/vmm/amd/ivrs_drv.c b/sys/amd64/vmm/amd/ivrs_drv.c index 511fbcf993f1..dc47717006a0 100755 --- a/sys/amd64/vmm/amd/ivrs_drv.c +++ b/sys/amd64/vmm/amd/ivrs_drv.c @@ -75,6 +75,12 @@ ivrs_hdr_iterate_tbl(ivhd_iter_t iter, void *arg) end = (ACPI_IVRS_HEADER *)((char *)ivrs + ivrs->Header.Length); while (ivrs_hdr < end) { + if ((uint8_t *)ivrs_hdr + ivrs_hdr->Length > (uint8_t *)end) { + printf("AMD-Vi:IVHD/IVMD is corrupted, length : %d\n", + ivrs_hdr->Length); + break; + } + switch (ivrs_hdr->Type) { case ACPI_IVRS_TYPE_HARDWARE: /* Legacy */ case 0x11: @@ -98,10 +104,6 @@ ivrs_hdr_iterate_tbl(ivhd_iter_t iter, void *arg) ivrs_hdr = (ACPI_IVRS_HEADER *)((uint8_t *)ivrs_hdr + ivrs_hdr->Length); - if (ivrs_hdr->Length < 0) { - printf("AMD-Vi:IVHD/IVMD is corrupted, length : %d\n", ivrs_hdr->Length); - break; - } } } diff --git a/sys/arm/allwinner/a10_mmc.c b/sys/arm/allwinner/a10_mmc.c index a93fef432b8d..ff617b5f2d6c 100644 --- a/sys/arm/allwinner/a10_mmc.c +++ b/sys/arm/allwinner/a10_mmc.c @@ -65,6 +65,7 @@ static struct ofw_compat_data compat_data[] = { {"allwinner,sun4i-a10-mmc", 1}, {"allwinner,sun5i-a13-mmc", 1}, {"allwinner,sun7i-a20-mmc", 1}, + {"allwinner,sun50i-a64-mmc", 1}, {NULL, 0} }; diff --git a/sys/arm/allwinner/clkng/aw_ccung.c b/sys/arm/allwinner/clkng/aw_ccung.c index e92d907d76e2..652d835aa8ce 100644 --- a/sys/arm/allwinner/clkng/aw_ccung.c +++ b/sys/arm/allwinner/clkng/aw_ccung.c @@ -54,10 +54,18 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef __aarch64__ +#include "opt_soc.h" +#endif + #if defined(SOC_ALLWINNER_A31) #include #endif +#if defined(SOC_ALLWINNER_A64) +#include +#endif + #if defined(SOC_ALLWINNER_H3) #include #endif @@ -78,12 +86,19 @@ static struct resource_spec aw_ccung_spec[] = { #define A31_CCU 2 #endif +#if defined(SOC_ALLWINNER_A64) +#define A64_CCU 2 +#endif + static struct ofw_compat_data compat_data[] = { #if defined(SOC_ALLWINNER_H3) { "allwinner,sun8i-h3-ccu", H3_CCU }, #endif #if defined(SOC_ALLWINNER_A31) { "allwinner,sun6i-a31-ccu", A31_CCU }, +#endif +#if defined(SOC_ALLWINNER_A64) + { "allwinner,sun50i-a64-ccu", A64_CCU }, #endif {NULL, 0 } }; @@ -261,7 +276,7 @@ aw_ccung_init_clocks(struct aw_ccung_softc *sc) sc->clk_init[i].default_freq, 0 , 0); if (error != 0) { device_printf(sc->dev, - "Cannot set frequency for %s to %llu\n", + "Cannot set frequency for %s to %ju\n", sc->clk_init[i].name, sc->clk_init[i].default_freq); continue; @@ -310,6 +325,11 @@ aw_ccung_attach(device_t dev) case A31_CCU: ccu_a31_register_clocks(sc); break; +#endif +#if defined(SOC_ALLWINNER_A64) + case A64_CCU: + ccu_a64_register_clocks(sc); + break; #endif } diff --git a/sys/arm/allwinner/clkng/ccu_a64.c b/sys/arm/allwinner/clkng/ccu_a64.c new file mode 100644 index 000000000000..ea2aea3d88ce --- /dev/null +++ b/sys/arm/allwinner/clkng/ccu_a64.c @@ -0,0 +1,743 @@ +/*- + * Copyright (c) 2017 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ccu_a64.h" + +static struct aw_ccung_reset a64_ccu_resets[] = { + CCU_RESET(A64_RST_USB_PHY0, 0x0cc, 0) + CCU_RESET(A64_RST_USB_PHY1, 0x0cc, 1) + CCU_RESET(A64_RST_USB_HSIC, 0x0cc, 2) + + CCU_RESET(A64_RST_BUS_MIPI_DSI, 0x2c0, 1) + CCU_RESET(A64_RST_BUS_CE, 0x2c0, 5) + CCU_RESET(A64_RST_BUS_DMA, 0x2c0, 6) + CCU_RESET(A64_RST_BUS_MMC0, 0x2c0, 8) + CCU_RESET(A64_RST_BUS_MMC1, 0x2c0, 9) + CCU_RESET(A64_RST_BUS_MMC2, 0x2c0, 10) + CCU_RESET(A64_RST_BUS_NAND, 0x2c0, 13) + CCU_RESET(A64_RST_BUS_DRAM, 0x2c0, 14) + CCU_RESET(A64_RST_BUS_EMAC, 0x2c0, 17) + CCU_RESET(A64_RST_BUS_TS, 0x2c0, 18) + CCU_RESET(A64_RST_BUS_HSTIMER, 0x2c0, 19) + CCU_RESET(A64_RST_BUS_SPI0, 0x2c0, 20) + CCU_RESET(A64_RST_BUS_SPI1, 0x2c0, 21) + CCU_RESET(A64_RST_BUS_OTG, 0x2c0, 23) + CCU_RESET(A64_RST_BUS_EHCI0, 0x2c0, 24) + CCU_RESET(A64_RST_BUS_EHCI1, 0x2c0, 25) + CCU_RESET(A64_RST_BUS_OHCI0, 0x2c0, 26) + CCU_RESET(A64_RST_BUS_OHCI1, 0x2c0, 27) + + CCU_RESET(A64_RST_BUS_VE, 0x2c4, 0) + CCU_RESET(A64_RST_BUS_TCON0, 0x2c4, 3) + CCU_RESET(A64_RST_BUS_TCON1, 0x2c4, 4) + CCU_RESET(A64_RST_BUS_DEINTERLACE, 0x2c4, 5) + CCU_RESET(A64_RST_BUS_CSI, 0x2c4, 8) + CCU_RESET(A64_RST_BUS_HDMI0, 0x2c4, 10) + CCU_RESET(A64_RST_BUS_HDMI1, 0x2c4, 11) + CCU_RESET(A64_RST_BUS_DE, 0x2c4, 12) + CCU_RESET(A64_RST_BUS_GPU, 0x2c4, 20) + CCU_RESET(A64_RST_BUS_MSGBOX, 0x2c4, 21) + CCU_RESET(A64_RST_BUS_SPINLOCK, 0x2c4, 22) + CCU_RESET(A64_RST_BUS_DBG, 0x2c4, 31) + + CCU_RESET(A64_RST_BUS_LVDS, 0x2C8, 31) + + CCU_RESET(A64_RST_BUS_CODEC, 0x2D0, 0) + CCU_RESET(A64_RST_BUS_SPDIF, 0x2D0, 1) + CCU_RESET(A64_RST_BUS_THS, 0x2D0, 8) + CCU_RESET(A64_RST_BUS_I2S0, 0x2D0, 12) + CCU_RESET(A64_RST_BUS_I2S1, 0x2D0, 13) + CCU_RESET(A64_RST_BUS_I2S2, 0x2D0, 14) + + CCU_RESET(A64_RST_BUS_I2C0, 0x2D8, 0) + CCU_RESET(A64_RST_BUS_I2C1, 0x2D8, 1) + CCU_RESET(A64_RST_BUS_I2C2, 0x2D8, 2) + CCU_RESET(A64_RST_BUS_SCR, 0x2D8, 5) + CCU_RESET(A64_RST_BUS_UART0, 0x2D8, 16) + CCU_RESET(A64_RST_BUS_UART1, 0x2D8, 17) + CCU_RESET(A64_RST_BUS_UART2, 0x2D8, 18) + CCU_RESET(A64_RST_BUS_UART3, 0x2D8, 19) + CCU_RESET(A64_RST_BUS_UART4, 0x2D8, 20) +}; + +static struct aw_ccung_gate a64_ccu_gates[] = { + CCU_GATE(A64_CLK_BUS_MIPI_DSI, "bus-mipi-dsi", "ahb1", 0x60, 1) + CCU_GATE(A64_CLK_BUS_CE, "bus-ce", "ahb1", 0x60, 5) + CCU_GATE(A64_CLK_BUS_DMA, "bus-dma", "ahb1", 0x60, 6) + CCU_GATE(A64_CLK_BUS_MMC0, "bus-mmc0", "ahb1", 0x60, 8) + CCU_GATE(A64_CLK_BUS_MMC1, "bus-mmc1", "ahb1", 0x60, 9) + CCU_GATE(A64_CLK_BUS_MMC2, "bus-mmc2", "ahb1", 0x60, 10) + CCU_GATE(A64_CLK_BUS_NAND, "bus-nand", "ahb1", 0x60, 13) + CCU_GATE(A64_CLK_BUS_DRAM, "bus-dram", "ahb1", 0x60, 14) + CCU_GATE(A64_CLK_BUS_EMAC, "bus-emac", "ahb2", 0x60, 16) + CCU_GATE(A64_CLK_BUS_TS, "bus-ts", "ahb1", 0x60, 18) + CCU_GATE(A64_CLK_BUS_HSTIMER, "bus-hstimer", "ahb1", 0x60, 19) + CCU_GATE(A64_CLK_BUS_SPI0, "bus-spi0", "ahb1", 0x60, 20) + CCU_GATE(A64_CLK_BUS_SPI1, "bus-spi1", "ahb1", 0x60, 21) + CCU_GATE(A64_CLK_BUS_OTG, "bus-otg", "ahb1", 0x60, 23) + CCU_GATE(A64_CLK_BUS_EHCI0, "bus-ehci0", "ahb1", 0x60, 24) + CCU_GATE(A64_CLK_BUS_EHCI1, "bus-ehci1", "ahb2", 0x60, 25) + CCU_GATE(A64_CLK_BUS_OHCI0, "bus-ohci0", "ahb1", 0x60, 26) + CCU_GATE(A64_CLK_BUS_OHCI1, "bus-ohci1", "ahb2", 0x60, 27) + + CCU_GATE(A64_CLK_BUS_VE, "bus-ve", "ahb1", 0x64, 0) + CCU_GATE(A64_CLK_BUS_TCON0, "bus-tcon0", "ahb1", 0x64, 3) + CCU_GATE(A64_CLK_BUS_TCON1, "bus-tcon1", "ahb1", 0x64, 4) + CCU_GATE(A64_CLK_BUS_DEINTERLACE, "bus-deinterlace", "ahb1", 0x64, 5) + CCU_GATE(A64_CLK_BUS_CSI, "bus-csi", "ahb1", 0x64, 8) + CCU_GATE(A64_CLK_BUS_HDMI, "bus-hdmi", "ahb1", 0x64, 11) + CCU_GATE(A64_CLK_BUS_DE, "bus-de", "ahb1", 0x64, 12) + CCU_GATE(A64_CLK_BUS_GPU, "bus-gpu", "ahb1", 0x64, 20) + CCU_GATE(A64_CLK_BUS_MSGBOX, "bus-msgbox", "ahb1", 0x64, 21) + CCU_GATE(A64_CLK_BUS_SPINLOCK, "bus-spinlock", "ahb1", 0x64, 22) + + CCU_GATE(A64_CLK_BUS_CODEC, "bus-codec", "apb1", 0x68, 0) + CCU_GATE(A64_CLK_BUS_SPDIF, "bus-spdif", "apb1", 0x68, 1) + CCU_GATE(A64_CLK_BUS_PIO, "bus-pio", "apb1", 0x68, 5) + CCU_GATE(A64_CLK_BUS_THS, "bus-ths", "apb1", 0x68, 8) + CCU_GATE(A64_CLK_BUS_I2S0, "bus-i2s0", "apb1", 0x68, 12) + CCU_GATE(A64_CLK_BUS_I2S1, "bus-i2s1", "apb1", 0x68, 13) + CCU_GATE(A64_CLK_BUS_I2S2, "bus-i2s2", "apb1", 0x68, 14) + + CCU_GATE(A64_CLK_BUS_I2C0, "bus-i2c0", "apb2", 0x6C, 0) + CCU_GATE(A64_CLK_BUS_I2C1, "bus-i2c1", "apb2", 0x6C, 1) + CCU_GATE(A64_CLK_BUS_I2C2, "bus-i2c2", "apb2", 0x6C, 2) + CCU_GATE(A64_CLK_BUS_SCR, "bus-src", "apb2", 0x6C, 5) + CCU_GATE(A64_CLK_BUS_UART0, "bus-uart0", "apb2", 0x6C, 16) + CCU_GATE(A64_CLK_BUS_UART1, "bus-uart1", "apb2", 0x6C, 17) + CCU_GATE(A64_CLK_BUS_UART2, "bus-uart2", "apb2", 0x6C, 18) + CCU_GATE(A64_CLK_BUS_UART3, "bus-uart3", "apb2", 0x6C, 19) + CCU_GATE(A64_CLK_BUS_UART4, "bus-uart4", "apb2", 0x6C, 20) + + CCU_GATE(A64_CLK_BUS_DBG, "bus-dbg", "ahb1", 0x70, 7) + + CCU_GATE(A64_CLK_USB_PHY0, "usb-phy0", "osc24M", 0xcc, 8) + CCU_GATE(A64_CLK_USB_PHY1, "usb-phy1", "osc24M", 0xcc, 9) + CCU_GATE(A64_CLK_USB_HSIC, "usb-hsic", "pll_hsic", 0xcc, 10) + CCU_GATE(A64_CLK_USB_HSIC_12M, "usb-hsic-12M", "osc12M", 0xcc, 11) + CCU_GATE(A64_CLK_USB_OHCI0, "usb-ohci0", "osc12M", 0xcc, 16) + CCU_GATE(A64_CLK_USB_OHCI1, "usb-ohci1", "usb-ohci0", 0xcc, 17) + + CCU_GATE(A64_CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0) + CCU_GATE(A64_CLK_DRAM_CSI, "dram-csi", "dram", 0x100, 1) + CCU_GATE(A64_CLK_DRAM_DEINTERLACE, "dram-deinterlace", "dram", 0x100, 2) + CCU_GATE(A64_CLK_DRAM_TS, "dram-ts", "dram", 0x100, 3) + + CCU_GATE(A64_CLK_CSI_MISC, "csi-misc", "osc24M", 0x130, 31) + + CCU_GATE(A64_CLK_AC_DIG_4X, "ac-dig-4x", "pll_audio-4x", 0x140, 30) + CCU_GATE(A64_CLK_AC_DIG, "ac-dig", "pll_audio", 0x140, 31) + + CCU_GATE(A64_CLK_AVS, "avs", "osc24M", 0x144, 31) + + CCU_GATE(A64_CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x154, 31) +}; + +static const char *osc12m_parents[] = {"osc24M"}; +FIXED_CLK(osc12m_clk, + A64_CLK_OSC_12M, /* id */ + "osc12M", /* name */ + osc12m_parents, /* parent */ + 0, /* freq */ + 1, /* mult */ + 2, /* div */ + 0); /* flags */ + +static const char *pll_cpux_parents[] = {"osc24M"}; +NKMP_CLK(pll_cpux_clk, + A64_CLK_PLL_CPUX, /* id */ + "pll_cpux", pll_cpux_parents, /* name, parents */ + 0x00, /* offset */ + 8, 5, 0, 0, /* n factor */ + 4, 2, 0, 0, /* k factor */ + 0, 2, 0, 0, /* m factor */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* p factor */ + 31, /* gate */ + 28, 1000, /* lock */ + AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK | AW_CLK_SCALE_CHANGE); /* flags */ + +static const char *pll_audio_parents[] = {"osc24M"}; +NKMP_CLK(pll_audio_clk, + A64_CLK_PLL_AUDIO, /* id */ + "pll_audio", pll_audio_parents, /* name, parents */ + 0x08, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* k factor (fake) */ + 0, 5, 0, 0, /* m factor */ + 16, 4, 0, 0, /* p factor */ + 31, /* gate */ + 28, 1000, /* lock */ + AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ + +static const char *pll_audio_mult_parents[] = {"pll_audio"}; +FIXED_CLK(pll_audio_2x_clk, + A64_CLK_PLL_AUDIO_2X, /* id */ + "pll_audio-2x", /* name */ + pll_audio_mult_parents, /* parent */ + 0, /* freq */ + 2, /* mult */ + 1, /* div */ + 0); /* flags */ +FIXED_CLK(pll_audio_4x_clk, + A64_CLK_PLL_AUDIO_4X, /* id */ + "pll_audio-4x", /* name */ + pll_audio_mult_parents, /* parent */ + 0, /* freq */ + 4, /* mult */ + 1, /* div */ + 0); /* flags */ +FIXED_CLK(pll_audio_8x_clk, + A64_CLK_PLL_AUDIO_8X, /* id */ + "pll_audio-8x", /* name */ + pll_audio_mult_parents, /* parent */ + 0, /* freq */ + 8, /* mult */ + 1, /* div */ + 0); /* flags */ + +static const char *pll_video0_parents[] = {"osc24M"}; +NM_CLK_WITH_FRAC(pll_video0_clk, + A64_CLK_PLL_VIDEO0, /* id */ + "pll_video0", pll_video0_parents, /* name, parents */ + 0x10, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 31, 28, 1000, /* gate, lock, lock retries */ + AW_CLK_HAS_LOCK, /* flags */ + 270000000, 297000000, /* freq0, freq1 */ + 24, 25); /* mode sel, freq sel */ + +static const char *pll_ve_parents[] = {"osc24M"}; +NM_CLK_WITH_FRAC(pll_ve_clk, + A64_CLK_PLL_VE, /* id */ + "pll_ve", pll_ve_parents, /* name, parents */ + 0x18, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 31, 28, 1000, /* gate, lock, lock retries */ + AW_CLK_HAS_LOCK, /* flags */ + 270000000, 297000000, /* freq0, freq1 */ + 24, 25); /* mode sel, freq sel */ + +static const char *pll_ddr0_parents[] = {"osc24M"}; +NKMP_CLK_WITH_UPDATE(pll_ddr0_clk, + A64_CLK_PLL_DDR0, /* id */ + "pll_ddr0", pll_ddr0_parents, /* name, parents */ + 0x20, /* offset */ + 8, 5, 0, 0, /* n factor */ + 4, 2, 0, 0, /* k factor */ + 0, 2, 0, 0, /* m factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* p factor (fake) */ + 31, /* gate */ + 28, 1000, /* lock */ + 20, /* update */ + AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ + +static const char *pll_periph0_2x_parents[] = {"osc24M"}; +static const char *pll_periph0_parents[] = {"pll_periph0_2x"}; +NKMP_CLK(pll_periph0_2x_clk, + A64_CLK_PLL_PERIPH0_2X, /* id */ + "pll_periph0_2x", pll_periph0_2x_parents, /* name, parents */ + 0x28, /* offset */ + 8, 5, 0, 0, /* n factor */ + 4, 2, 0, 0, /* k factor */ + 0, 0, 2, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* p factor (fake) */ + 31, /* gate */ + 28, 1000, /* lock */ + AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ +FIXED_CLK(pll_periph0_clk, + A64_CLK_PLL_PERIPH0, /* id */ + "pll_periph0", /* name */ + pll_periph0_parents, /* parent */ + 0, /* freq */ + 1, /* mult */ + 2, /* div */ + 0); /* flags */ + +static const char *pll_periph1_2x_parents[] = {"osc24M"}; +static const char *pll_periph1_parents[] = {"pll_periph1_2x"}; +NKMP_CLK(pll_periph1_2x_clk, + A64_CLK_PLL_PERIPH1_2X, /* id */ + "pll_periph1_2x", pll_periph1_2x_parents, /* name, parents */ + 0x2C, /* offset */ + 8, 5, 0, 0, /* n factor */ + 4, 2, 0, 0, /* k factor */ + 0, 0, 2, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* p factor (fake) */ + 31, /* gate */ + 28, 1000, /* lock */ + AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ +FIXED_CLK(pll_periph1_clk, + A64_CLK_PLL_PERIPH1, /* id */ + "pll_periph1", /* name */ + pll_periph1_parents, /* parent */ + 0, /* freq */ + 1, /* mult */ + 2, /* div */ + 0); /* flags */ + +static const char *pll_video1_parents[] = {"osc24M"}; +NM_CLK_WITH_FRAC(pll_video1_clk, + A64_CLK_PLL_VIDEO1, /* id */ + "pll_video1", pll_video1_parents, /* name, parents */ + 0x30, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 31, 28, 1000, /* gate, lock, lock retries */ + AW_CLK_HAS_LOCK, /* flags */ + 270000000, 297000000, /* freq0, freq1 */ + 24, 25); /* mode sel, freq sel */ + +static const char *pll_gpu_parents[] = {"osc24M"}; +NM_CLK_WITH_FRAC(pll_gpu_clk, + A64_CLK_PLL_GPU, /* id */ + "pll_gpu", pll_gpu_parents, /* name, parents */ + 0x38, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 31, 28, 1000, /* gate, lock, lock retries */ + AW_CLK_HAS_LOCK, /* flags */ + 270000000, 297000000, /* freq0, freq1 */ + 24, 25); /* mode sel, freq sel */ + +/* PLL MIPI is missing */ + +static const char *pll_hsic_parents[] = {"osc24M"}; +NM_CLK_WITH_FRAC(pll_hsic_clk, + A64_CLK_PLL_HSIC, /* id */ + "pll_hsic", pll_hsic_parents, /* name, parents */ + 0x44, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 31, 28, 1000, /* gate, lock, lock retries */ + AW_CLK_HAS_LOCK, /* flags */ + 270000000, 297000000, /* freq0, freq1 */ + 24, 25); /* mode sel, freq sel */ + +static const char *pll_de_parents[] = {"osc24M"}; +NM_CLK_WITH_FRAC(pll_de_clk, + A64_CLK_PLL_DE, /* id */ + "pll_de", pll_de_parents, /* name, parents */ + 0x48, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 31, 28, 1000, /* gate, lock, lock retries */ + AW_CLK_HAS_LOCK, /* flags */ + 270000000, 297000000, /* freq0, freq1 */ + 24, 25); /* mode sel, freq sel */ + +static const char *pll_ddr1_parents[] = {"osc24M"}; +NKMP_CLK_WITH_UPDATE(pll_ddr1_clk, + A64_CLK_PLL_DDR1, /* id */ + "pll_ddr1", pll_ddr1_parents, /* name, parents */ + 0x4C, /* offset */ + 8, 7, 0, 0, /* n factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* k factor (fake) */ + 0, 2, 0, 0, /* m factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* p factor (fake) */ + 31, /* gate */ + 28, 1000, /* lock */ + 20, /* update */ + AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ + +static const char *cpux_parents[] = {"osc32k", "osc24M", "pll_cpux"}; +MUX_CLK(cpux_clk, + A64_CLK_CPUX, /* id */ + "cpux", cpux_parents, /* name, parents */ + 0x50, 16, 2); /* offset, shift, width */ + +static const char *axi_parents[] = {"cpux"}; +DIV_CLK(axi_clk, + A64_CLK_AXI, /* id */ + "axi", axi_parents, /* name, parents */ + 0x50, /* offset */ + 0, 2, /* shift, width */ + 0, NULL); /* flags, div table */ + +static const char *apb_parents[] = {"cpux"}; +DIV_CLK(apb_clk, + A64_CLK_APB, /* id */ + "apb", apb_parents, /* name, parents */ + 0x50, /* offset */ + 8, 2, /* shift, width */ + 0, NULL); /* flags, div table */ + +static const char *ahb1_parents[] = {"osc32k", "osc24M", "axi", "pll_periph0"}; +PREDIV_CLK(ahb1_clk, A64_CLK_AHB1, /* id */ + "ahb1", ahb1_parents, /* name, parents */ + 0x54, /* offset */ + 12, 2, /* mux */ + 4, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* div */ + 6, 2, 0, AW_CLK_FACTOR_HAS_COND, /* prediv */ + 12, 2, 3); /* prediv condition */ + +static const char *apb1_parents[] = {"ahb1"}; +static struct clk_div_table apb1_div_table[] = { + { .value = 0, .divider = 2, }, + { .value = 1, .divider = 2, }, + { .value = 2, .divider = 4, }, + { .value = 3, .divider = 8, }, + { }, +}; +DIV_CLK(apb1_clk, + A64_CLK_APB1, /* id */ + "apb1", apb1_parents, /* name, parents */ + 0x54, /* offset */ + 8, 2, /* shift, width */ + CLK_DIV_WITH_TABLE, /* flags */ + apb1_div_table); /* div table */ + +static const char *apb2_parents[] = {"osc32k", "osc24M", "pll_periph0_2x", "pll_periph0_2x"}; +NM_CLK(apb2_clk, + A64_CLK_APB2, /* id */ + "apb2", apb2_parents, /* name, parents */ + 0x58, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 5, 0, 0, /* m factor */ + 24, 2, /* mux */ + 0, /* gate */ + AW_CLK_HAS_MUX); + +static const char *ahb2_parents[] = {"ahb1", "pll_periph0"}; +PREDIV_CLK(ahb2_clk, A64_CLK_AHB2, /* id */ + "ahb2", ahb2_parents, /* name, parents */ + 0x5c, /* offset */ + 0, 2, /* mux */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* div */ + 0, 0, 2, AW_CLK_FACTOR_HAS_COND | AW_CLK_FACTOR_FIXED, /* prediv */ + 0, 2, 1); /* prediv condition */ + +static const char *mod_parents[] = {"osc24M", "pll_periph0_2x", "pll_periph1_2x"}; +NM_CLK(nand_clk, + A64_CLK_NAND, "nand", mod_parents, /* id, name, parents */ + 0x80, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ + +NM_CLK(mmc0_clk, + A64_CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ + 0x88, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | + AW_CLK_REPARENT); /* flags */ + +NM_CLK(mmc1_clk, + A64_CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ + 0x8c, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | + AW_CLK_REPARENT); /* flags */ + +NM_CLK(mmc2_clk, + A64_CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ + 0x90, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | + AW_CLK_REPARENT); /* flags */ + +static const char *ts_parents[] = {"osc24M", "pll_periph0"}; +NM_CLK(ts_clk, + A64_CLK_TS, "ts", ts_parents, /* id, name, parents */ + 0x98, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ + +NM_CLK(ce_clk, + A64_CLK_CE, "ce", mod_parents, /* id, name, parents */ + 0x9C, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ + +NM_CLK(spi0_clk, + A64_CLK_SPI0, "spi0", mod_parents, /* id, name, parents */ + 0xA0, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | + AW_CLK_REPARENT); /* flags */ + +NM_CLK(spi1_clk, + A64_CLK_SPI1, "spi1", mod_parents, /* id, name, parents */ + 0xA4, /* offset */ + 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | + AW_CLK_REPARENT); /* flags */ + +static const char *i2s_parents[] = {"pll_audio-8x", "pll_audio-4x", "pll_audio-2x", "pll_audio"}; +MUX_CLK(i2s0mux_clk, + 0, "i2s0mux", i2s_parents, /* id, name, parents */ + 0xb0, 16, 2); /* offset, mux shift, mux width */ +MUX_CLK(i2s1mux_clk, + 0, "i2s1mux", i2s_parents, /* id, name, parents */ + 0xb4, 16, 2); /* offset, mux shift, mux width */ +MUX_CLK(i2s2mux_clk, + 0, "i2s2mux", i2s_parents, /* id, name, parents */ + 0xb8, 16, 2); /* offset, mux shift, mux width */ + +static const char *spdif_parents[] = {"pll_audio"}; +NM_CLK(spdif_clk, + A64_CLK_SPDIF, "spdif", spdif_parents, /* id, name, parents */ + 0xC0, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake); */ + 0, 4, 0, 0, /* m factor */ + 0, 0, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE); /* flags */ + +/* USBPHY clk sel */ + +/* DRAM needs update bit */ +static const char *dram_parents[] = {"pll_ddr0", "pll_ddr1"}; +NM_CLK(dram_clk, + A64_CLK_DRAM, "dram", dram_parents, /* id, name, parents */ + 0xF4, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 2, 0, 0, /* m factor */ + 20, 2, /* mux */ + 0, /* gate */ + AW_CLK_HAS_MUX); /* flags */ + +static const char *de_parents[] = {"pll_periph0_2x", "pll_de"}; +NM_CLK(de_clk, + A64_CLK_DE, "de", de_parents, /* id, name, parents */ + 0x104, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +/* TCON0/1 Needs mux table */ + +static const char *deinterlace_parents[] = {"pll_periph0", "pll_periph1"}; +NM_CLK(deinterlace_clk, + A64_CLK_DEINTERLACE, "deinterlace", deinterlace_parents, /* id, name, parents */ + 0x124, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *csi_sclk_parents[] = {"pll_periph0", "pll_periph1"}; +NM_CLK(csi_sclk_clk, + A64_CLK_CSI_SCLK, "csi-sclk", csi_sclk_parents, /* id, name, parents */ + 0x134, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 16, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *csi_mclk_parents[] = {"osc24M", "pll_video0", "pll_periph1"}; +NM_CLK(csi_mclk_clk, + A64_CLK_CSI_MCLK, "csi-mclk", csi_mclk_parents, /* id, name, parents */ + 0x134, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 8, 2, /* mux */ + 15, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *ve_parents[] = {"pll_ve"}; +NM_CLK(ve_clk, + A64_CLK_VE, "ve", ve_parents, /* id, name, parents */ + 0x13C, /* offset */ + 16, 3, 0, 0, /* n factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ + 0, 0, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE); /* flags */ + +static const char *hdmi_parents[] = {"pll_video0"}; +NM_CLK(hdmi_clk, + A64_CLK_HDMI, "hdmi", hdmi_parents, /* id, name, parents */ + 0x150, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *mbus_parents[] = {"osc24M", "pll_periph0_2x", "pll_ddr0"}; +NM_CLK(mbus_clk, + A64_CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */ + 0x15C, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 3, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *gpu_parents[] = {"pll_gpu"}; +NM_CLK(gpu_clk, + A64_CLK_GPU, "gpu", gpu_parents, /* id, name, parents */ + 0x1A0, /* offset */ + 0, 2, 0, 0, /* n factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ + 0, 0, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE); /* flags */ + +static struct aw_clk_nkmp_def *nkmp_clks[] = { + &pll_cpux_clk, + &pll_audio_clk, + &pll_periph0_2x_clk, + &pll_periph1_2x_clk, + &pll_ddr0_clk, + &pll_ddr1_clk, +}; + +static struct aw_clk_nm_def *nm_clks[] = { + &pll_video0_clk, + &pll_video1_clk, + &pll_ve_clk, + &pll_gpu_clk, + &pll_de_clk, + &pll_hsic_clk, + &apb2_clk, + &nand_clk, + &mmc0_clk, + &mmc1_clk, + &mmc2_clk, + &ts_clk, + &ce_clk, + &spi0_clk, + &spi1_clk, + &spdif_clk, + &dram_clk, + &de_clk, + &deinterlace_clk, + &csi_sclk_clk, + &csi_mclk_clk, + &ve_clk, + &hdmi_clk, + &mbus_clk, + &gpu_clk, +}; + +static struct aw_clk_prediv_mux_def *prediv_mux_clks[] = { + &ahb1_clk, + &ahb2_clk, +}; + +static struct clk_mux_def *mux_clks[] = { + &cpux_clk, + &i2s0mux_clk, + &i2s1mux_clk, + &i2s2mux_clk, +}; + +static struct clk_div_def *div_clks[] = { + &axi_clk, + &apb1_clk, + &apb_clk, +}; + +static struct clk_fixed_def *fixed_factor_clks[] = { + &osc12m_clk, + &pll_periph0_clk, + &pll_periph1_clk, + &pll_audio_2x_clk, + &pll_audio_4x_clk, + &pll_audio_8x_clk, +}; + +static struct aw_clk_init init_clks[] = { + {"ahb1", "pll_periph0", 0, false}, + {"ahb2", "pll_periph0", 0, false}, + {"dram", "pll_ddr", 0, false}, +}; + +void +ccu_a64_register_clocks(struct aw_ccung_softc *sc) +{ + int i; + + sc->resets = a64_ccu_resets; + sc->nresets = nitems(a64_ccu_resets); + sc->gates = a64_ccu_gates; + sc->ngates = nitems(a64_ccu_gates); + sc->clk_init = init_clks; + sc->n_clk_init = nitems(init_clks); + + for (i = 0; i < nitems(nkmp_clks); i++) + aw_clk_nkmp_register(sc->clkdom, nkmp_clks[i]); + for (i = 0; i < nitems(nm_clks); i++) + aw_clk_nm_register(sc->clkdom, nm_clks[i]); + for (i = 0; i < nitems(prediv_mux_clks); i++) + aw_clk_prediv_mux_register(sc->clkdom, prediv_mux_clks[i]); + + for (i = 0; i < nitems(mux_clks); i++) + clknode_mux_register(sc->clkdom, mux_clks[i]); + for (i = 0; i < nitems(div_clks); i++) + clknode_div_register(sc->clkdom, div_clks[i]); + for (i = 0; i < nitems(fixed_factor_clks); i++) + clknode_fixed_register(sc->clkdom, fixed_factor_clks[i]); +} diff --git a/sys/arm/allwinner/clkng/ccu_a64.h b/sys/arm/allwinner/clkng/ccu_a64.h new file mode 100644 index 000000000000..bda1ce6d76aa --- /dev/null +++ b/sys/arm/allwinner/clkng/ccu_a64.h @@ -0,0 +1,204 @@ +/*- + * Copyright (c) 2017 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __CCU_A64_H__ +#define __CCU_A64_H__ + +#define A64_RST_USB_PHY0 0 +#define A64_RST_USB_PHY1 1 +#define A64_RST_USB_HSIC 2 +#define A64_RST_DRAM 3 +#define A64_RST_MBUS 4 +#define A64_RST_BUS_MIPI_DSI 5 +#define A64_RST_BUS_CE 6 +#define A64_RST_BUS_DMA 7 +#define A64_RST_BUS_MMC0 8 +#define A64_RST_BUS_MMC1 9 +#define A64_RST_BUS_MMC2 10 +#define A64_RST_BUS_NAND 11 +#define A64_RST_BUS_DRAM 12 +#define A64_RST_BUS_EMAC 13 +#define A64_RST_BUS_TS 14 +#define A64_RST_BUS_HSTIMER 15 +#define A64_RST_BUS_SPI0 16 +#define A64_RST_BUS_SPI1 17 +#define A64_RST_BUS_OTG 18 +#define A64_RST_BUS_EHCI0 19 +#define A64_RST_BUS_EHCI1 20 +#define A64_RST_BUS_OHCI0 21 +#define A64_RST_BUS_OHCI1 22 +#define A64_RST_BUS_VE 23 +#define A64_RST_BUS_TCON0 24 +#define A64_RST_BUS_TCON1 25 +#define A64_RST_BUS_DEINTERLACE 26 +#define A64_RST_BUS_CSI 27 +#define A64_RST_BUS_HDMI0 28 +#define A64_RST_BUS_HDMI1 29 +#define A64_RST_BUS_DE 30 +#define A64_RST_BUS_GPU 31 +#define A64_RST_BUS_MSGBOX 32 +#define A64_RST_BUS_SPINLOCK 33 +#define A64_RST_BUS_DBG 34 +#define A64_RST_BUS_LVDS 35 +#define A64_RST_BUS_CODEC 36 +#define A64_RST_BUS_SPDIF 37 +#define A64_RST_BUS_THS 38 +#define A64_RST_BUS_I2S0 39 +#define A64_RST_BUS_I2S1 40 +#define A64_RST_BUS_I2S2 41 +#define A64_RST_BUS_I2C0 42 +#define A64_RST_BUS_I2C1 43 +#define A64_RST_BUS_I2C2 44 +#define A64_RST_BUS_SCR 45 +#define A64_RST_BUS_UART0 46 +#define A64_RST_BUS_UART1 47 +#define A64_RST_BUS_UART2 48 +#define A64_RST_BUS_UART3 49 +#define A64_RST_BUS_UART4 50 + +#define A64_CLK_OSC_12M 0 +#define A64_CLK_PLL_CPUX 1 +#define A64_CLK_PLL_AUDIO_BASE 2 +#define A64_CLK_PLL_AUDIO 3 +#define A64_CLK_PLL_AUDIO_2X 4 +#define A64_CLK_PLL_AUDIO_4X 5 +#define A64_CLK_PLL_AUDIO_8X 6 +#define A64_CLK_PLL_VIDEO0 7 +#define A64_CLK_PLL_VIDEO0_2X 8 +#define A64_CLK_PLL_VE 9 +#define A64_CLK_PLL_DDR0 10 +#define A64_CLK_PLL_PERIPH0 11 +#define A64_CLK_PLL_PERIPH0_2X 12 +#define A64_CLK_PLL_PERIPH1 13 +#define A64_CLK_PLL_PERIPH1_2X 14 +#define A64_CLK_PLL_VIDEO1 15 +#define A64_CLK_PLL_GPU 16 +#define A64_CLK_PLL_MIPI 17 +#define A64_CLK_PLL_HSIC 18 +#define A64_CLK_PLL_DE 19 +#define A64_CLK_PLL_DDR1 20 +#define A64_CLK_CPUX 21 +#define A64_CLK_AXI 22 +#define A64_CLK_APB 23 +#define A64_CLK_AHB1 24 +#define A64_CLK_APB1 25 +#define A64_CLK_APB2 26 +#define A64_CLK_AHB2 27 +#define A64_CLK_BUS_MIPI_DSI 28 +#define A64_CLK_BUS_CE 29 +#define A64_CLK_BUS_DMA 30 +#define A64_CLK_BUS_MMC0 31 +#define A64_CLK_BUS_MMC1 32 +#define A64_CLK_BUS_MMC2 33 +#define A64_CLK_BUS_NAND 34 +#define A64_CLK_BUS_DRAM 35 +#define A64_CLK_BUS_EMAC 36 +#define A64_CLK_BUS_TS 37 +#define A64_CLK_BUS_HSTIMER 38 +#define A64_CLK_BUS_SPI0 39 +#define A64_CLK_BUS_SPI1 40 +#define A64_CLK_BUS_OTG 41 +#define A64_CLK_BUS_EHCI0 42 +#define A64_CLK_BUS_EHCI1 43 +#define A64_CLK_BUS_OHCI0 44 +#define A64_CLK_BUS_OHCI1 45 +#define A64_CLK_BUS_VE 46 +#define A64_CLK_BUS_TCON0 47 +#define A64_CLK_BUS_TCON1 48 +#define A64_CLK_BUS_DEINTERLACE 49 +#define A64_CLK_BUS_CSI 50 +#define A64_CLK_BUS_HDMI 51 +#define A64_CLK_BUS_DE 52 +#define A64_CLK_BUS_GPU 53 +#define A64_CLK_BUS_MSGBOX 54 +#define A64_CLK_BUS_SPINLOCK 55 +#define A64_CLK_BUS_CODEC 56 +#define A64_CLK_BUS_SPDIF 57 +#define A64_CLK_BUS_PIO 58 +#define A64_CLK_BUS_THS 59 +#define A64_CLK_BUS_I2S0 60 +#define A64_CLK_BUS_I2S1 61 +#define A64_CLK_BUS_I2S2 62 +#define A64_CLK_BUS_I2C0 63 +#define A64_CLK_BUS_I2C1 64 +#define A64_CLK_BUS_I2C2 65 +#define A64_CLK_BUS_SCR 66 +#define A64_CLK_BUS_UART0 67 +#define A64_CLK_BUS_UART1 68 +#define A64_CLK_BUS_UART2 69 +#define A64_CLK_BUS_UART3 70 +#define A64_CLK_BUS_UART4 71 +#define A64_CLK_BUS_DBG 72 +#define A64_CLK_THS 73 +#define A64_CLK_NAND 74 +#define A64_CLK_MMC0 75 +#define A64_CLK_MMC1 76 +#define A64_CLK_MMC2 77 +#define A64_CLK_TS 78 +#define A64_CLK_CE 79 +#define A64_CLK_SPI0 80 +#define A64_CLK_SPI1 81 +#define A64_CLK_I2S0 82 +#define A64_CLK_I2S1 83 +#define A64_CLK_I2S2 84 +#define A64_CLK_SPDIF 85 +#define A64_CLK_USB_PHY0 86 +#define A64_CLK_USB_PHY1 87 +#define A64_CLK_USB_HSIC 88 +#define A64_CLK_USB_HSIC_12M 89 +#define A64_CLK_USB_OHCI0_12M 90 +#define A64_CLK_USB_OHCI0 91 +#define A64_CLK_USB_OHCI1_12M 92 +#define A64_CLK_USB_OHCI1 93 +#define A64_CLK_DRAM 94 +#define A64_CLK_DRAM_VE 95 +#define A64_CLK_DRAM_CSI 96 +#define A64_CLK_DRAM_DEINTERLACE 97 +#define A64_CLK_DRAM_TS 98 +#define A64_CLK_DE 99 +#define A64_CLK_TCON0 100 +#define A64_CLK_TCON1 101 +#define A64_CLK_DEINTERLACE 102 +#define A64_CLK_CSI_MISC 103 +#define A64_CLK_CSI_SCLK 104 +#define A64_CLK_CSI_MCLK 105 +#define A64_CLK_VE 106 +#define A64_CLK_AC_DIG 107 +#define A64_CLK_AC_DIG_4X 108 +#define A64_CLK_AVS 109 +#define A64_CLK_HDMI 110 +#define A64_CLK_HDMI_DDC 111 + +#define A64_CLK_MBUS 112 + +#define A64_CLK_DSI_DPHY 113 +#define A64_CLK_GPU 114 + +void ccu_a64_register_clocks(struct aw_ccung_softc *sc); + +#endif /* __CCU_A64_H__ */ diff --git a/sys/arm/allwinner/if_awg.c b/sys/arm/allwinner/if_awg.c index ddd771d7561c..58c233b59052 100644 --- a/sys/arm/allwinner/if_awg.c +++ b/sys/arm/allwinner/if_awg.c @@ -146,11 +146,13 @@ TUNABLE_INT("hw.awg.rx_batch", &awg_rx_batch); enum awg_type { EMAC_A83T = 1, EMAC_H3, + EMAC_A64, }; static struct ofw_compat_data compat_data[] = { { "allwinner,sun8i-a83t-emac", EMAC_A83T }, { "allwinner,sun8i-h3-emac", EMAC_H3 }, + { "allwinner,sun50i-a64-emac", EMAC_A64 }, { NULL, 0 } }; diff --git a/sys/arm/annapurna/alpine/alpine_common.c b/sys/arm/annapurna/alpine/alpine_common.c index b03c3a487552..ce84b39b867b 100644 --- a/sys/arm/annapurna/alpine/alpine_common.c +++ b/sys/arm/annapurna/alpine/alpine_common.c @@ -43,97 +43,10 @@ __FBSDID("$FreeBSD$"); #include #include -#define WDTLOAD 0x000 -#define LOAD_MIN 0x00000001 -#define LOAD_MAX 0xFFFFFFFF -#define WDTVALUE 0x004 -#define WDTCONTROL 0x008 -/* control register masks */ -#define INT_ENABLE (1 << 0) -#define RESET_ENABLE (1 << 1) -#define WDTLOCK 0xC00 -#define UNLOCK 0x1ACCE551 -#define LOCK 0x00000001 - -extern bus_addr_t al_devmap_pa; - -static int alpine_get_wdt_base(uint32_t *pbase, uint32_t *psize); +#ifndef INTRNG static int alpine_pic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt, int *trig, int *pol); -int alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size); - -int alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size) -{ - phandle_t node; - - if ((node = OF_finddevice("/")) == 0) - return (ENXIO); - - if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0) - return (ENXIO); - - return fdt_get_range(node, 0, pa, size); -} - -static int -alpine_get_wdt_base(uint32_t *pbase, uint32_t *psize) -{ - phandle_t node; - u_long base = 0; - u_long size = 0; - - if (pbase == NULL || psize == NULL) - return (EINVAL); - - if ((node = OF_finddevice("/")) == -1) - return (EFAULT); - - if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0) - return (EFAULT); - - if ((node = - fdt_find_compatible(node, "arm,sp805", 1)) == 0) - return (EFAULT); - - if (fdt_regsize(node, &base, &size)) - return (EFAULT); - - *pbase = base; - *psize = size; - - return (0); -} - -void -cpu_reset(void) -{ - uint32_t wdbase, wdsize; - bus_addr_t wdbaddr; - int ret; - - ret = alpine_get_wdt_base(&wdbase, &wdsize); - if (ret) { - printf("Unable to get WDT base, do power down manually..."); - goto infinite; - } - - ret = bus_space_map(fdtbus_bs_tag, al_devmap_pa + wdbase, - wdsize, 0, &wdbaddr); - if (ret) { - printf("Unable to map WDT base, do power down manually..."); - goto infinite; - } - - bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOCK, UNLOCK); - bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOAD, LOAD_MIN); - bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTCONTROL, INT_ENABLE | RESET_ENABLE); - -infinite: - while (1) {} -} - -#ifndef INTRNG static int alpine_pic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt, int *trig, int *pol) diff --git a/sys/arm/annapurna/alpine/alpine_machdep.c b/sys/arm/annapurna/alpine/alpine_machdep.c index 7f87c7d68984..e57b360140eb 100644 --- a/sys/arm/annapurna/alpine/alpine_machdep.c +++ b/sys/arm/annapurna/alpine/alpine_machdep.c @@ -26,66 +26,137 @@ * */ +#include "opt_ddb.h" +#include "opt_platform.h" + #include __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include #include #include #include -#include /* For trapframe_t, used in */ -#include -#include #include +#include -#include "opt_ddb.h" -#include "opt_platform.h" +#include +#include + +#include + +#include "platform_if.h" + +#define WDTLOAD 0x000 +#define LOAD_MIN 0x00000001 +#define LOAD_MAX 0xFFFFFFFF +#define WDTVALUE 0x004 +#define WDTCONTROL 0x008 +/* control register masks */ +#define INT_ENABLE (1 << 0) +#define RESET_ENABLE (1 << 1) +#define WDTLOCK 0xC00 +#define UNLOCK 0x1ACCE551 +#define LOCK 0x00000001 -#define DEVMAP_MAX_VA_ADDRESS 0xF0000000 bus_addr_t al_devmap_pa; bus_addr_t al_devmap_size; -int alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size); - -vm_offset_t -platform_lastaddr(void) +static int +alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size) { + phandle_t node; - return (DEVMAP_MAX_VA_ADDRESS); + if ((node = OF_finddevice("/")) == 0) + return (ENXIO); + + if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0) + return (ENXIO); + + return fdt_get_range(node, 0, pa, size); } -void -platform_probe_and_attach(void) +static int +alpine_get_wdt_base(uint32_t *pbase, uint32_t *psize) { + phandle_t node; + u_long base = 0; + u_long size = 0; -} + if (pbase == NULL || psize == NULL) + return (EINVAL); -void -platform_gpio_init(void) -{ + if ((node = OF_finddevice("/")) == -1) + return (EFAULT); -} + if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0) + return (EFAULT); -void -platform_late_init(void) -{ + if ((node = + fdt_find_compatible(node, "arm,sp805", 1)) == 0) + return (EFAULT); + if (fdt_regsize(node, &base, &size)) + return (EFAULT); + + *pbase = base; + *psize = size; + + return (0); } /* * Construct devmap table with DT-derived config data. */ -int -platform_devmap_init(void) +static int +alpine_devmap_init(platform_t plat) { alpine_get_devmap_base(&al_devmap_pa, &al_devmap_size); devmap_add_entry(al_devmap_pa, al_devmap_size); return (0); } + +static void +alpine_cpu_reset(platform_t plat) +{ + uint32_t wdbase, wdsize; + bus_addr_t wdbaddr; + int ret; + + ret = alpine_get_wdt_base(&wdbase, &wdsize); + if (ret) { + printf("Unable to get WDT base, do power down manually..."); + goto infinite; + } + + ret = bus_space_map(fdtbus_bs_tag, al_devmap_pa + wdbase, + wdsize, 0, &wdbaddr); + if (ret) { + printf("Unable to map WDT base, do power down manually..."); + goto infinite; + } + + bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOCK, UNLOCK); + bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOAD, LOAD_MIN); + bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTCONTROL, + INT_ENABLE | RESET_ENABLE); + +infinite: + while (1) {} +} + +static platform_method_t alpine_methods[] = { + PLATFORMMETHOD(platform_devmap_init, alpine_devmap_init), + PLATFORMMETHOD(platform_cpu_reset, alpine_cpu_reset), + +#ifdef SMP + PLATFORMMETHOD(platform_mp_start_ap, alpine_mp_start_ap), + PLATFORMMETHOD(platform_mp_setmaxid, alpine_mp_setmaxid), +#endif + PLATFORMMETHOD_END, +}; +FDT_PLATFORM_DEF(alpine, "alpine", 0, "annapurna,alpine", 200); diff --git a/sys/arm/annapurna/alpine/alpine_machdep_mp.c b/sys/arm/annapurna/alpine/alpine_machdep_mp.c index 4ef2db1ba0f3..7e6ea3479570 100644 --- a/sys/arm/annapurna/alpine/alpine_machdep_mp.c +++ b/sys/arm/annapurna/alpine/alpine_machdep_mp.c @@ -43,12 +43,15 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include +#include + #define AL_CPU_RESUME_WATERMARK_REG 0x00 #define AL_CPU_RESUME_FLAGS_REG 0x04 #define AL_CPU_RESUME_PCPU_RADDR_REG(cpu) (0x08 + 0x04 + 8*(cpu)) @@ -112,7 +115,7 @@ platform_mp_get_core_cnt(void) } void -platform_mp_setmaxid(void) +alpine_mp_setmaxid(platform_t plat) { mp_ncpus = platform_mp_get_core_cnt(); @@ -172,7 +175,7 @@ alpine_get_nb_base(u_long *pbase, u_long *psize) } void -platform_mp_start_ap(void) +alpine_mp_start_ap(platform_t plat) { uint32_t physaddr; vm_offset_t vaddr; diff --git a/sys/arm/annapurna/alpine/alpine_mp.h b/sys/arm/annapurna/alpine/alpine_mp.h new file mode 100644 index 000000000000..736b6cd36b89 --- /dev/null +++ b/sys/arm/annapurna/alpine/alpine_mp.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2017 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _ANNAPURNA_ALPINE_MP_H_ +#define _ANNAPURNA_ALPINE_MP_H_ + +void alpine_mp_start_ap(platform_t plat); +void alpine_mp_setmaxid(platform_t plat); + +#endif /* _ANNAPURNA_ALPINE_MP_H_ */ diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c index e42a699986cc..f7ae7f1d5fe0 100644 --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef MULTIDELAY +#if defined(__arm__) #include /* For arm_set_delay */ #endif @@ -427,7 +427,7 @@ arm_tmr_attach(device_t dev) sc->et.et_priv = sc; et_register(&sc->et); -#ifdef MULTIDELAY +#if defined(__arm__) arm_set_delay(arm_tmr_do_delay, sc); #endif @@ -505,7 +505,7 @@ arm_tmr_do_delay(int usec, void *arg) } } -#ifndef MULTIDELAY +#if defined(__aarch64__) void DELAY(int usec) { diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index 211a40450a00..66af88027f18 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -145,6 +145,14 @@ static struct resource_spec arm_gic_spec[] = { { -1, 0 } }; + +#if defined(__arm__) && defined(INVARIANTS) +static int gic_debug_spurious = 1; +#else +static int gic_debug_spurious = 0; +#endif +TUNABLE_INT("hw.gic.debug_spurious", &gic_debug_spurious); + static u_int arm_gic_map[MAXCPU]; static struct arm_gic_softc *gic_sc = NULL; @@ -671,11 +679,10 @@ arm_gic_intr(void *arg) */ if (irq >= sc->nirqs) { -#ifdef GIC_DEBUG_SPURIOUS - device_printf(sc->gic_dev, - "Spurious interrupt detected: last irq: %d on CPU%d\n", - sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid)); -#endif + if (gic_debug_spurious) + device_printf(sc->gic_dev, + "Spurious interrupt detected: last irq: %d on CPU%d\n", + sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid)); return (FILTER_HANDLED); } @@ -700,9 +707,8 @@ arm_gic_intr(void *arg) #endif } -#ifdef GIC_DEBUG_SPURIOUS - sc->last_irq[PCPU_GET(cpuid)] = irq; -#endif + if (gic_debug_spurious) + sc->last_irq[PCPU_GET(cpuid)] = irq; if ((gi->gi_flags & GI_FLAG_EARLY_EOI) == GI_FLAG_EARLY_EOI) gic_c_write_4(sc, GICC_EOIR, irq_active_reg); diff --git a/sys/arm/arm/gic.h b/sys/arm/arm/gic.h index d6d0db143e18..c1b7d532ca90 100644 --- a/sys/arm/arm/gic.h +++ b/sys/arm/arm/gic.h @@ -39,8 +39,6 @@ #ifndef _ARM_GIC_H_ #define _ARM_GIC_H_ -#define GIC_DEBUG_SPURIOUS - #define GIC_FIRST_SGI 0 /* Irqs 0-15 are SGIs/IPIs. */ #define GIC_LAST_SGI 15 #define GIC_FIRST_PPI 16 /* Irqs 16-31 are private (per */ @@ -70,9 +68,7 @@ struct arm_gic_softc { struct mtx mutex; uint32_t nirqs; uint32_t typer; -#ifdef GIC_DEBUG_SPURIOUS uint32_t last_irq[MAXCPU]; -#endif #ifdef INTRNG uint32_t gic_iidr; diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 3bfc39e12524..e995ee0fcf3c 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -146,7 +146,7 @@ static struct pv_addr kernelstack; #endif /* __ARM_ARCH >= 6 */ #endif /* FDT */ -#ifdef MULTIDELAY +#ifdef PLATFORM static delay_func *delay_impl; static void *delay_arg; #endif @@ -331,7 +331,7 @@ cpu_initclocks(void) } #endif -#ifdef MULTIDELAY +#ifdef PLATFORM void arm_set_delay(delay_func *impl, void *arg) { diff --git a/sys/arm/arm/mpcore_timer.c b/sys/arm/arm/mpcore_timer.c index 16f660d0d2fc..aee065c07c38 100644 --- a/sys/arm/arm/mpcore_timer.c +++ b/sys/arm/arm/mpcore_timer.c @@ -59,9 +59,7 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef MULTIDELAY #include /* For arm_set_delay */ -#endif #include #include @@ -438,7 +436,7 @@ arm_tmr_attach(device_t dev) return (ENXIO); } -#ifdef MULTIDELAY +#ifdef PLATFORM /* * We can register as the DELAY() implementation only if we successfully * set up the global timer. @@ -529,7 +527,7 @@ arm_tmr_delay(int usec, void *arg) } } -#ifndef MULTIDELAY +#ifndef PLATFORM /** * DELAY - Delay for at least usec microseconds. * @usec: number of microseconds to delay by diff --git a/sys/arm/arm/pl310.c b/sys/arm/arm/pl310.c index b6bbf8cc98e1..7e95d7b868b1 100644 --- a/sys/arm/arm/pl310.c +++ b/sys/arm/arm/pl310.c @@ -42,11 +42,18 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef PLATFORM +#include +#endif #include #include #include +#ifdef PLATFORM +#include "platform_pl310_if.h" +#endif + /* * Define this if you need to disable PL310 for debugging purpose * Spec: @@ -89,6 +96,29 @@ static struct ofw_compat_data compat_data[] = { {NULL, false} }; +#ifdef PLATFORM +static void +platform_pl310_init(struct pl310_softc *sc) +{ + + PLATFORM_PL310_INIT(platform_obj(), sc); +} + +static void +platform_pl310_write_ctrl(struct pl310_softc *sc, uint32_t val) +{ + + PLATFORM_PL310_WRITE_CTRL(platform_obj(), sc, val); +} + +static void +platform_pl310_write_debug(struct pl310_softc *sc, uint32_t val) +{ + + PLATFORM_PL310_WRITE_DEBUG(platform_obj(), sc, val); +} +#endif + static void pl310_print_config(struct pl310_softc *sc) { diff --git a/sys/arm/arm/platform.c b/sys/arm/arm/platform.c index 7703be63f11f..465fd90b87f7 100644 --- a/sys/arm/arm/platform.c +++ b/sys/arm/arm/platform.c @@ -75,9 +75,14 @@ SYSCTL_STRING(_hw, OID_AUTO, platform, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, plat_nam */ SET_DECLARE(platform_set, platform_def_t); -#ifdef MULTIDELAY static delay_func platform_delay; -#endif + +platform_t +platform_obj(void) +{ + + return (plat_obj); +} void platform_probe_and_attach(void) @@ -152,10 +157,8 @@ platform_probe_and_attach(void) strlcpy(plat_name, plat_def_impl->name, sizeof(plat_name)); -#ifdef MULTIDELAY /* Set a default delay function */ arm_set_delay(platform_delay, NULL); -#endif PLATFORM_ATTACH(plat_obj); } @@ -202,7 +205,6 @@ cpu_reset(void) } } -#ifdef MULTIDELAY static void platform_delay(int usec, void *arg __unused) { @@ -216,9 +218,8 @@ platform_delay(int usec, void *arg __unused) */ cpufunc_nullop(); } -#endif -#if defined(SMP) && defined(PLATFORM_SMP) +#if defined(SMP) void platform_mp_setmaxid(void) { diff --git a/sys/arm/arm/platform_pl310_if.m b/sys/arm/arm/platform_pl310_if.m new file mode 100644 index 000000000000..e032bebbf8aa --- /dev/null +++ b/sys/arm/arm/platform_pl310_if.m @@ -0,0 +1,84 @@ +#- +# Copyright (c) 2017 Andrew Turner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include +#include +#include +#include + +#include +#include +#include + +INTERFACE platform_pl310; + +HEADER { + struct pl310_softc; +}; + +CODE { + static void platform_pl310_default_write_ctrl(platform_t plat, + struct pl310_softc *sc, uint32_t val) + { + pl310_write4(sc, PL310_CTRL, val); + } + + static void platform_pl310_default_write_debug(platform_t plat, + struct pl310_softc *sc, uint32_t val) + { + pl310_write4(sc, PL310_DEBUG_CTRL, val); + } +}; + +/** + * Initialize the pl310, e.g. to configure the prefetch control. The following + * write functions may have already been called so they must not rely on + * this function. + */ +METHOD void init { + platform_t _plat; + struct pl310_softc *sc; +}; + +/** + * Write to the Control Register. + */ +METHOD void write_ctrl { + platform_t _plat; + struct pl310_softc *sc; + uint32_t val; +} DEFAULT platform_pl310_default_write_ctrl; + +/** + * Write to the Debug Control Register. + */ +METHOD void write_debug { + platform_t _plat; + struct pl310_softc *sc; + uint32_t val; +} DEFAULT platform_pl310_default_write_debug; diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index 1954b7d40a60..0471d42ad452 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include "mmcbr_if.h" #include "sdhci_if.h" +#include "opt_mmccam.h" + #include "bcm2835_dma.h" #include #include "bcm2835_vcbus.h" @@ -253,7 +255,11 @@ bcm_sdhci_attach(device_t dev) bus_generic_probe(dev); bus_generic_attach(dev); +#ifdef MMCCAM + sdhci_cam_start_slot(&sc->sc_slot); +#else sdhci_start_slot(&sc->sc_slot); +#endif return (0); diff --git a/sys/arm/conf/ALLWINNER_UP b/sys/arm/conf/ALLWINNER_UP index 68c20a64f636..3c2384a823b9 100644 --- a/sys/arm/conf/ALLWINNER_UP +++ b/sys/arm/conf/ALLWINNER_UP @@ -30,7 +30,6 @@ options SOC_ALLWINNER_A13 options SCHED_4BSD # 4BSD scheduler options PLATFORM -options MULTIDELAY # NFS root from boopt/dhcp #options BOOTP diff --git a/sys/arm/conf/ALPINE b/sys/arm/conf/ALPINE index 7ef285bf82f9..bb64740b56f9 100644 --- a/sys/arm/conf/ALPINE +++ b/sys/arm/conf/ALPINE @@ -27,6 +27,7 @@ makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options SMP # Enable multiple cores +options PLATFORM # Interrupt controller device gic diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE index 77a7bdba25e8..fec1f2859a61 100644 --- a/sys/arm/conf/BEAGLEBONE +++ b/sys/arm/conf/BEAGLEBONE @@ -29,7 +29,6 @@ include "../ti/am335x/std.am335x" makeoptions MODULES_EXTRA="dtb/am335x am335x_dmtpps" options INTRNG -options MULTIDELAY options SCHED_4BSD # 4BSD scheduler options PLATFORM diff --git a/sys/arm/conf/BEAGLEBONE-MMCCAM b/sys/arm/conf/BEAGLEBONE-MMCCAM new file mode 100644 index 000000000000..3d83352e79c0 --- /dev/null +++ b/sys/arm/conf/BEAGLEBONE-MMCCAM @@ -0,0 +1,21 @@ +# +# BEAGLEBONE-MMCCAM +# +# Custom kernel for Beaglebone plus MMCCAM as opposed to the prior MMC stack. It is +# present to keep it building in tree since it wouldn't work in LINT. +# +# $FreeBSD$ + +include BEAGLEBONE + +# Add CAMDEBUG stuff +options CAMDEBUG +options CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_PROBE|CAM_DEBUG_PERIPH|CAM_DEBUG_TRACE) + +# pass(4) device +device pass +device mmccam +options MMCCAM + +nodevice mmc +nodevice mmcsd diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX index 759dfa257387..a77a5a8eb1c6 100644 --- a/sys/arm/conf/EFIKA_MX +++ b/sys/arm/conf/EFIKA_MX @@ -31,7 +31,6 @@ options SCHED_4BSD # 4BSD scheduler #options MD_ROOT # MD is a potential root device #options NFSD # Network Filesystem Server options PLATFORM -options MULTIDELAY options INCLUDE_CONFIG_FILE # Include this file in kernel # NFS root from boopt/dhcp diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common index 2f176afcdb8e..5bfc9c792265 100644 --- a/sys/arm/conf/EXYNOS5.common +++ b/sys/arm/conf/EXYNOS5.common @@ -23,7 +23,6 @@ makeoptions WERROR="-Werror" include "std.armv6" options SCHED_ULE # ULE scheduler options PLATFORM # Platform based SoC -options PLATFORM_SMP options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index e9dd817c7b75..4341e0417ea0 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -62,8 +62,6 @@ options SOC_OMAP4 options SCHED_ULE # ULE scheduler options SMP # Enable multiple cores options PLATFORM -options PLATFORM_SMP -options MULTIDELAY options LINUX_BOOT_ABI # EXT_RESOURCES pseudo devices @@ -118,6 +116,7 @@ device pty device snp device md # Memory "disks" device random # Entropy device +device pl310 # PL310 L2 cache controller device psci # I2C support diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53 index a168dcd4cb48..0cf6205fe7f3 100644 --- a/sys/arm/conf/IMX53 +++ b/sys/arm/conf/IMX53 @@ -28,7 +28,6 @@ options SOC_IMX53 options SCHED_4BSD # 4BSD scheduler #options NFSD # Network Filesystem Server options PLATFORM -options MULTIDELAY options INCLUDE_CONFIG_FILE # Include this file in kernel # kernel/memory size reduction diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 5d09edcc3cda..f8340334f395 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -30,9 +30,7 @@ options SCHED_ULE # ULE scheduler #options NFSD # Network Filesystem Server options INCLUDE_CONFIG_FILE # Include this file in kernel options PLATFORM -options PLATFORM_SMP options SMP # Enable multiple cores -options MULTIDELAY # NFS root from boopt/dhcp #options BOOTP diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD index 2a0170d71abd..05ea2af69962 100644 --- a/sys/arm/conf/PANDABOARD +++ b/sys/arm/conf/PANDABOARD @@ -34,7 +34,6 @@ makeoptions MODULES_EXTRA=dtb/omap4 options SCHED_ULE # ULE scheduler options PLATFORM -options PLATFORM_SMP options SMP # Enable multiple cores # NFS root from boopt/dhcp diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188 index 15b98cfbef86..00dfcd45b729 100644 --- a/sys/arm/conf/RK3188 +++ b/sys/arm/conf/RK3188 @@ -28,8 +28,6 @@ options SOC_ROCKCHIP_RK3188 options SCHED_ULE # ULE scheduler options SMP # Enable multiple cores options PLATFORM -options PLATFORM_SMP -options MULTIDELAY # Root mount from MMC/SD card options ROOTDEVNAME=\"ufs:/dev/mmcsd0\" diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B index 66d702e0238d..ce408aba9ef1 100644 --- a/sys/arm/conf/RPI-B +++ b/sys/arm/conf/RPI-B @@ -28,7 +28,6 @@ options INTRNG options SCHED_4BSD # 4BSD scheduler options PLATFORM -options MULTIDELAY # NFS root from boopt/dhcp #options BOOTP diff --git a/sys/arm/conf/RPI2 b/sys/arm/conf/RPI2 index 0c92e17859a6..058100176a3b 100644 --- a/sys/arm/conf/RPI2 +++ b/sys/arm/conf/RPI2 @@ -31,8 +31,6 @@ options INTRNG options SCHED_ULE # ULE scheduler options SMP # Enable multiple cores options PLATFORM -options PLATFORM_SMP -options MULTIDELAY # NFS root from boopt/dhcp #options BOOTP diff --git a/sys/arm/conf/SOCFPGA b/sys/arm/conf/SOCFPGA index a4c8654b1386..0291db7a4bdb 100644 --- a/sys/arm/conf/SOCFPGA +++ b/sys/arm/conf/SOCFPGA @@ -28,9 +28,7 @@ makeoptions WERROR="-Werror" options SCHED_ULE # ULE scheduler options PLATFORM # Platform based SoC -options PLATFORM_SMP options SMP # Enable multiple cores -options MULTIDELAY options SOC_ALTERA_ARRIA10 options SOC_ALTERA_CYCLONE5 diff --git a/sys/arm/conf/TEGRA124 b/sys/arm/conf/TEGRA124 index eb60b2a2a6cf..cf466bb89307 100644 --- a/sys/arm/conf/TEGRA124 +++ b/sys/arm/conf/TEGRA124 @@ -25,8 +25,6 @@ ident TEGRA124 options SCHED_ULE # ULE scheduler options PLATFORM # Platform based SoC -options PLATFORM_SMP -options MULTIDELAY options SMP # Enable multiple cores options LINUX_BOOT_ABI diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB index 9525ac41fe42..10686ea8b6c3 100644 --- a/sys/arm/conf/VERSATILEPB +++ b/sys/arm/conf/VERSATILEPB @@ -69,6 +69,7 @@ device md device random # Entropy device options INTRNG +options PLATFORM # Flattened Device Tree options FDT # Configure using FDT/DTB data diff --git a/sys/arm/conf/VIRT b/sys/arm/conf/VIRT index ad266c7ceff3..64f3a3df59e3 100644 --- a/sys/arm/conf/VIRT +++ b/sys/arm/conf/VIRT @@ -25,9 +25,7 @@ include "../qemu/std.virt" options SCHED_ULE # ULE scheduler options PLATFORM -options PLATFORM_SMP options SMP # Enable multiple cores -options MULTIDELAY # Interrupt controller device gic diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD index c743a69c1ccc..4085aa8d1370 100644 --- a/sys/arm/conf/ZEDBOARD +++ b/sys/arm/conf/ZEDBOARD @@ -28,7 +28,6 @@ makeoptions MODULES_EXTRA="dtb/zynq" options SCHED_ULE # ULE scheduler options PLATFORM # Platform based SoC -options PLATFORM_SMP #options NFSSD # Network Filesystem Server options SMP # Enable multiple cores diff --git a/sys/arm/freescale/imx/files.imx6 b/sys/arm/freescale/imx/files.imx6 index 55082885dda2..4f09d79ccdb7 100644 --- a/sys/arm/freescale/imx/files.imx6 +++ b/sys/arm/freescale/imx/files.imx6 @@ -14,6 +14,7 @@ arm/freescale/imx/imx6_ccm.c standard arm/freescale/imx/imx6_machdep.c standard arm/freescale/imx/imx6_mp.c optional smp arm/freescale/imx/imx6_pl310.c standard +arm/freescale/imx/imx6_snvs.c standard arm/freescale/imx/imx6_src.c standard arm/freescale/imx/imx_epit.c standard arm/freescale/imx/imx_iomux.c standard diff --git a/sys/arm/freescale/imx/imx6_machdep.c b/sys/arm/freescale/imx/imx6_machdep.c index b53684251a08..3e82b5b0a33f 100644 --- a/sys/arm/freescale/imx/imx6_machdep.c +++ b/sys/arm/freescale/imx/imx6_machdep.c @@ -50,9 +50,10 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include "platform_if.h" +#include "platform_pl310_if.h" static platform_attach_t imx6_attach; static platform_devmap_init_t imx6_devmap_init; @@ -321,6 +322,8 @@ static platform_method_t imx6_methods[] = { PLATFORMMETHOD(platform_mp_setmaxid, imx6_mp_setmaxid), #endif + PLATFORMMETHOD(platform_pl310_init, imx6_pl310_init), + PLATFORMMETHOD_END, }; diff --git a/sys/arm/freescale/imx/imx6_mp.h b/sys/arm/freescale/imx/imx6_machdep.h similarity index 90% rename from sys/arm/freescale/imx/imx6_mp.h rename to sys/arm/freescale/imx/imx6_machdep.h index 617ab8a0af27..4db1bb354530 100644 --- a/sys/arm/freescale/imx/imx6_mp.h +++ b/sys/arm/freescale/imx/imx6_machdep.h @@ -26,10 +26,13 @@ * $FreeBSD$ */ -#ifndef IMX6_MP_H -#define IMX6_MP_H +#ifndef IMX6_MACHDEP_H +#define IMX6_MACHDEP_H + +struct pl310_softc; void imx6_mp_start_ap(platform_t); void imx6_mp_setmaxid(platform_t); +void imx6_pl310_init(platform_t, struct pl310_softc *); -#endif /* IMX6_MP_H */ +#endif /* IMX6_MACHDEP_H */ diff --git a/sys/arm/freescale/imx/imx6_mp.c b/sys/arm/freescale/imx/imx6_mp.c index d26daab91f53..e36773d4cf6b 100644 --- a/sys/arm/freescale/imx/imx6_mp.c +++ b/sys/arm/freescale/imx/imx6_mp.c @@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #define SCU_PHYSBASE 0x00a00000 #define SCU_SIZE 0x00001000 diff --git a/sys/arm/freescale/imx/imx6_pl310.c b/sys/arm/freescale/imx/imx6_pl310.c index 9e0427faf4ed..189958709b8d 100644 --- a/sys/arm/freescale/imx/imx6_pl310.c +++ b/sys/arm/freescale/imx/imx6_pl310.c @@ -40,9 +40,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include + +#include + +#include "platform_pl310_if.h" void -platform_pl310_init(struct pl310_softc *sc) +imx6_pl310_init(platform_t plat, struct pl310_softc *sc) { uint32_t reg; @@ -58,18 +63,3 @@ platform_pl310_init(struct pl310_softc *sc) pl310_set_ram_latency(sc, PL310_TAG_RAM_CTRL, 4, 2, 3); pl310_set_ram_latency(sc, PL310_DATA_RAM_CTRL, 4, 2, 3); } - -void -platform_pl310_write_ctrl(struct pl310_softc *sc, uint32_t val) -{ - - pl310_write4(sc, PL310_CTRL, val); -} - -void -platform_pl310_write_debug(struct pl310_softc *sc, uint32_t val) -{ - - pl310_write4(sc, PL310_DEBUG_CTRL, val); -} - diff --git a/sys/arm/freescale/imx/imx6_snvs.c b/sys/arm/freescale/imx/imx6_snvs.c new file mode 100644 index 000000000000..82dee8b8ddce --- /dev/null +++ b/sys/arm/freescale/imx/imx6_snvs.c @@ -0,0 +1,228 @@ +/*- + * Copyright (c) 2017 Ian Lepore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * Driver for imx6 Secure Non-Volatile Storage system, which really means "all + * the stuff that's powered by a battery when main power is off". This includes + * realtime clock, tamper monitor, and power-management functions. Currently + * this driver provides only realtime clock support. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clock_if.h" + +#define SNVS_LPCR 0x38 /* Control register */ +#define LPCR_LPCALB_VAL_SHIFT 10 /* Calibration shift */ +#define LPCR_LPCALB_VAL_MASK 0x1f /* Calibration mask */ +#define LPCR_LPCALB_EN (1u << 8) /* Calibration enable */ +#define LPCR_SRTC_ENV (1u << 0) /* RTC enabled/valid */ + +#define SNVS_LPSRTCMR 0x50 /* Counter MSB */ +#define SNVS_LPSRTCLR 0x54 /* Counter LSB */ + +#define RTC_RESOLUTION_US (1000000 / 32768) /* 32khz clock */ + +/* + * The RTC is a 47-bit counter clocked at 32KHz and organized as a 32.15 + * fixed-point binary value. Shifting by SBT_LSB bits translates between + * counter and sbintime values. + */ +#define RTC_BITS 47 +#define SBT_BITS 64 +#define SBT_LSB (SBT_BITS - RTC_BITS) + +struct snvs_softc { + device_t dev; + struct resource * memres; + uint32_t lpcr; +}; + +static struct ofw_compat_data compat_data[] = { + {"fsl,sec-v4.0-mon", true}, + {NULL, false} +}; + +static inline uint32_t +RD4(struct snvs_softc *sc, bus_size_t offset) +{ + + return (bus_read_4(sc->memres, offset)); +} + +static inline void +WR4(struct snvs_softc *sc, bus_size_t offset, uint32_t value) +{ + + bus_write_4(sc->memres, offset, value); +} + +static void +snvs_rtc_enable(struct snvs_softc *sc, bool enable) +{ + uint32_t enbit; + + if (enable) + sc->lpcr |= LPCR_SRTC_ENV; + else + sc->lpcr &= ~LPCR_SRTC_ENV; + WR4(sc, SNVS_LPCR, sc->lpcr); + + /* Wait for the hardware to achieve the requested state. */ + enbit = sc->lpcr & LPCR_SRTC_ENV; + while ((RD4(sc, SNVS_LPCR) & LPCR_SRTC_ENV) != enbit) + continue; +} + +static int +snvs_gettime(device_t dev, struct timespec *ts) +{ + struct snvs_softc *sc; + sbintime_t counter1, counter2; + + sc = device_get_softc(dev); + + /* If the clock is not enabled and valid, we can't help. */ + if (!(RD4(sc, SNVS_LPCR) & LPCR_SRTC_ENV)) { + return (EINVAL); + } + + /* + * The counter is clocked asynchronously to cpu accesses; read and + * assemble the pieces of the counter until we get the same value twice. + * The counter is 47 bits, organized as a 32.15 binary fixed-point + * value. If we shift it up to the high order part of a 64-bit word it + * turns into an sbintime. + */ + do { + counter1 = (uint64_t)RD4(sc, SNVS_LPSRTCMR) << (SBT_LSB + 32); + counter1 |= (uint64_t)RD4(sc, SNVS_LPSRTCLR) << (SBT_LSB); + counter2 = (uint64_t)RD4(sc, SNVS_LPSRTCMR) << (SBT_LSB + 32); + counter2 |= (uint64_t)RD4(sc, SNVS_LPSRTCLR) << (SBT_LSB); + } while (counter1 != counter2); + + *ts = sbttots(counter1); + + return (0); +} + +static int +snvs_settime(device_t dev, struct timespec *unused) +{ + struct snvs_softc *sc; + struct bintime bt; + sbintime_t sbt; + + sc = device_get_softc(dev); + + /* + * Ignore the inaccurate time passed in from the common clock code and + * obtain a time worthy of our 30us accuracy. + */ + bintime(&bt); + bt.sec -= utc_offset(); + sbt = bttosbt(bt); + + /* + * It takes two clock cycles for the counter to start after setting the + * enable bit, so add two SBT_LSBs to what we're about to set. + */ + sbt += 2 << SBT_LSB; + snvs_rtc_enable(sc, false); + WR4(sc, SNVS_LPSRTCMR, (uint32_t)(sbt >> (SBT_LSB + 32))); + WR4(sc, SNVS_LPSRTCLR, (uint32_t)(sbt >> (SBT_LSB))); + snvs_rtc_enable(sc, true); + + return (0); +} + +static int +snvs_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, "i.MX6 SNVS RTC"); + return (BUS_PROBE_DEFAULT); +} + +static int +snvs_attach(device_t dev) +{ + struct snvs_softc *sc; + int rid; + + sc = device_get_softc(dev); + sc->dev = dev; + + rid = 0; + sc->memres = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->memres == NULL) { + device_printf(sc->dev, "could not allocate registers\n"); + return (ENXIO); + } + + clock_register(sc->dev, RTC_RESOLUTION_US); + + return (0); +} + +static device_method_t snvs_methods[] = { + DEVMETHOD(device_probe, snvs_probe), + DEVMETHOD(device_attach, snvs_attach), + + /* clock_if methods */ + DEVMETHOD(clock_gettime, snvs_gettime), + DEVMETHOD(clock_settime, snvs_settime), + + DEVMETHOD_END +}; + +static driver_t snvs_driver = { + "snvs", + snvs_methods, + sizeof(struct snvs_softc), +}; + +static devclass_t snvs_devclass; + +DRIVER_MODULE(snvs, simplebus, snvs_driver, snvs_devclass, 0, 0); diff --git a/sys/arm/freescale/imx/imx6_usbphy.c b/sys/arm/freescale/imx/imx6_usbphy.c index 432af83f7fee..ad63ed6f1793 100644 --- a/sys/arm/freescale/imx/imx6_usbphy.c +++ b/sys/arm/freescale/imx/imx6_usbphy.c @@ -198,5 +198,11 @@ static driver_t usbphy_driver = { static devclass_t usbphy_devclass; -DRIVER_MODULE(usbphy, simplebus, usbphy_driver, usbphy_devclass, 0, 0); +/* + * This driver needs to start before the ehci driver, but later than the usual + * "special" drivers like clocks and cpu. Ehci starts at DEFAULT so + * DEFAULT-1000 seems good. + */ +EARLY_DRIVER_MODULE(usbphy, simplebus, usbphy_driver, usbphy_devclass, 0, 0, + BUS_PASS_DEFAULT - 1000); diff --git a/sys/arm/freescale/imx/imx_epit.c b/sys/arm/freescale/imx/imx_epit.c index 3731ed9f83df..1295bc75c783 100644 --- a/sys/arm/freescale/imx/imx_epit.c +++ b/sys/arm/freescale/imx/imx_epit.c @@ -106,11 +106,6 @@ struct epit_softc { bool oneshot; }; -#ifndef MULTIDELAY -/* Global softc pointer for use in DELAY(). */ -static struct epit_softc *epit_sc; -#endif - /* * Probe data. For some reason, the standard linux dts files don't have * compatible properties on the epit devices (other properties are missing too, @@ -218,11 +213,8 @@ epit_tc_attach(struct epit_softc *sc) tc_init(&sc->tc); /* We are the DELAY() implementation. */ -#ifdef MULTIDELAY arm_set_delay(epit_do_delay, sc); -#else - epit_sc = sc; -#endif + return (0); } @@ -497,32 +489,3 @@ static devclass_t epit_devclass; EARLY_DRIVER_MODULE(imx_epit, simplebus, epit_driver, epit_devclass, 0, 0, BUS_PASS_TIMER); - -#ifndef MULTIDELAY - -/* - * Hand-calibrated delay-loop counter. This was calibrated on an i.MX6 running - * at 792mhz. It will delay a bit too long on slower processors -- that's - * better than not delaying long enough. In practice this is unlikely to get - * used much since the clock driver is one of the first to start up, and once - * we're attached the delay loop switches to using the timer hardware. - */ -static const int epit_delay_count = 78; - -void -DELAY(int usec) -{ - uint64_t ticks; - - /* If the timer hardware is not accessible, just use a loop. */ - if (epit_sc == NULL) { - while (usec-- > 0) - for (ticks = 0; ticks < epit_delay_count; ++ticks) - cpufunc_nullop(); - return; - } else { - epit_do_delay(usec, epit_sc); - } -} - -#endif diff --git a/sys/arm/freescale/imx/imx_gpt.c b/sys/arm/freescale/imx/imx_gpt.c index 48fb1152e233..2f62db5dd313 100644 --- a/sys/arm/freescale/imx/imx_gpt.c +++ b/sys/arm/freescale/imx/imx_gpt.c @@ -40,9 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef MULTIDELAY #include /* For arm_set_delay */ -#endif #include #include @@ -92,20 +90,6 @@ struct imx_gpt_softc { struct eventtimer et; }; -#ifndef MULTIDELAY -/* Global softc pointer for use in DELAY(). */ -static struct imx_gpt_softc *imx_gpt_sc; - -/* - * Hand-calibrated delay-loop counter. This was calibrated on an i.MX6 running - * at 792mhz. It will delay a bit too long on slower processors -- that's - * better than not delaying long enough. In practice this is unlikely to get - * used much since the clock driver is one of the first to start up, and once - * we're attached the delay loop switches to using the timer hardware. - */ -static const int imx_gpt_delay_count = 78; -#endif - /* Try to divide down an available fast clock to this frequency. */ #define TARGET_FREQUENCY 1000000000 @@ -293,11 +277,7 @@ imx_gpt_attach(device_t dev) /* If this is the first unit, store the softc for use in DELAY. */ if (device_get_unit(dev) == 0) { -#ifdef MULTIDELAY arm_set_delay(imx_gpt_do_delay, sc); -#else - imx_gpt_sc = sc; -#endif } return (0); @@ -441,21 +421,3 @@ imx_gpt_do_delay(int usec, void *arg) curcnt += 1ULL << 32; } } - -#ifndef MULTIDELAY -void -DELAY(int usec) -{ - uint64_t ticks; - - /* If the timer hardware is not accessible, just use a loop. */ - if (imx_gpt_sc == NULL) { - while (usec-- > 0) - for (ticks = 0; ticks < imx_gpt_delay_count; ++ticks) - cpufunc_nullop(); - return; - } else - imx_gpt_do_delay(usec, imx_gpt_sc); - -} -#endif diff --git a/sys/arm/freescale/vybrid/vf_machdep.c b/sys/arm/freescale/vybrid/vf_machdep.c index abe6a3a1cd05..5b46121ea568 100644 --- a/sys/arm/freescale/vybrid/vf_machdep.c +++ b/sys/arm/freescale/vybrid/vf_machdep.c @@ -83,4 +83,4 @@ static platform_method_t vf_methods[] = { PLATFORMMETHOD_END, }; -FDT_PLATFORM_DEF(vf, "vybrid", 0, "freescale,vybrid", 0); +FDT_PLATFORM_DEF(vf, "vybrid", 0, "freescale,vybrid", 200); diff --git a/sys/arm/include/machdep.h b/sys/arm/include/machdep.h index b2bc82b72269..b738b971bd3f 100644 --- a/sys/arm/include/machdep.h +++ b/sys/arm/include/machdep.h @@ -48,7 +48,7 @@ void board_set_revision(uint32_t); int arm_predict_branch(void *, u_int, register_t, register_t *, u_int (*)(void*, int), u_int (*)(void*, vm_offset_t, u_int*)); -#ifdef MULTIDELAY +#ifdef PLATFORM typedef void delay_func(int, void *); void arm_set_delay(delay_func *, void *); #endif diff --git a/sys/arm/include/pl310.h b/sys/arm/include/pl310.h index 76b1444972a9..7d977aa23fd7 100644 --- a/sys/arm/include/pl310.h +++ b/sys/arm/include/pl310.h @@ -181,8 +181,10 @@ pl310_write4(struct pl310_softc *sc, bus_size_t off, uint32_t val) void pl310_set_ram_latency(struct pl310_softc *sc, uint32_t which_reg, uint32_t read, uint32_t write, uint32_t setup); +#ifndef PLATFORM void platform_pl310_init(struct pl310_softc *); void platform_pl310_write_ctrl(struct pl310_softc *, uint32_t); void platform_pl310_write_debug(struct pl310_softc *, uint32_t); +#endif #endif /* PL310_H_ */ diff --git a/sys/arm/include/platformvar.h b/sys/arm/include/platformvar.h index a80f628c6d5c..fafdd749e2ed 100644 --- a/sys/arm/include/platformvar.h +++ b/sys/arm/include/platformvar.h @@ -90,15 +90,9 @@ typedef struct fdt_platform_class fdt_platform_def_t; extern platform_method_t fdt_platform_methods[]; -#ifdef MULTIDELAY -#define FDT_PLATFORM_CTASSERT(delay) CTASSERT(delay > 0) -#else -#define FDT_PLATFORM_CTASSERT(delay) -#endif - #define FDT_PLATFORM_DEF2(NAME, VAR_NAME, NAME_STR, size, compatible, \ delay) \ -FDT_PLATFORM_CTASSERT(delay); \ +CTASSERT(delay > 0); \ static fdt_platform_def_t VAR_NAME ## _fdt_platform = { \ .name = NAME_STR, \ .methods = fdt_platform_methods, \ @@ -120,6 +114,11 @@ DATA_SET(platform_set, VAR_NAME ## _platform) #endif +/* + * Helper to get the platform object + */ +platform_t platform_obj(void); + bool arm_tmr_timed_wait(platform_t, int); #endif /* _MACHINE_PLATFORMVAR_H_ */ diff --git a/sys/arm/samsung/exynos/exynos5_machdep.c b/sys/arm/samsung/exynos/exynos5_machdep.c index ebcd486d2136..6f800fd67ce0 100644 --- a/sys/arm/samsung/exynos/exynos5_machdep.c +++ b/sys/arm/samsung/exynos/exynos5_machdep.c @@ -91,4 +91,4 @@ static platform_method_t exynos5_methods[] = { PLATFORMMETHOD_END, }; -FDT_PLATFORM_DEF(exynos5, "exynos5", 0, "samsung,exynos5", 0); +FDT_PLATFORM_DEF(exynos5, "exynos5", 0, "samsung,exynos5", 200); diff --git a/sys/arm/ti/am335x/am335x_dmtimer.c b/sys/arm/ti/am335x/am335x_dmtimer.c index 9d28565fa1f3..a7572afedbc4 100644 --- a/sys/arm/ti/am335x/am335x_dmtimer.c +++ b/sys/arm/ti/am335x/am335x_dmtimer.c @@ -38,9 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef MULTIDELAY #include /* For arm_set_delay */ -#endif #include #include @@ -241,9 +239,7 @@ am335x_dmtimer_tc_init(struct am335x_dmtimer_softc *sc) am335x_dmtimer_tc_sc = sc; tc_init(&sc->func.tc); -#ifdef MULTIDELAY arm_set_delay(am335x_dmtimer_delay, sc); -#endif return (0); } @@ -360,20 +356,3 @@ am335x_dmtimer_delay(int usec, void *arg) first = last; } } - -#ifndef MULTIDELAY -void -DELAY(int usec) -{ - int32_t counts; - - if (am335x_dmtimer_tc_sc == NULL) { - for (; usec > 0; usec--) - for (counts = 200; counts > 0; counts--) - /* Prevent gcc from optimizing out the loop */ - cpufunc_nullop(); - return; - } else - am335x_dmtimer_delay(usec, am335x_dmtimer_tc_sc); -} -#endif diff --git a/sys/arm/ti/omap4/omap4_l2cache.c b/sys/arm/ti/omap4/omap4_l2cache.c index 8fddc6f71989..946752ac3312 100644 --- a/sys/arm/ti/omap4/omap4_l2cache.c +++ b/sys/arm/ti/omap4/omap4_l2cache.c @@ -32,13 +32,18 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include #include #include +#include + +#include +#include +#include + +#include "platform_pl310_if.h" void -platform_pl310_init(struct pl310_softc *sc) +omap4_pl310_init(platform_t plat, struct pl310_softc *sc) { uint32_t aux, prefetch; @@ -70,13 +75,15 @@ platform_pl310_init(struct pl310_softc *sc) } void -platform_pl310_write_ctrl(struct pl310_softc *sc, uint32_t val) +omap4_pl310_write_ctrl(platform_t plat, struct pl310_softc *sc, uint32_t val) { + ti_smc0(val, 0, L2CACHE_WRITE_CTRL_REG); } void -platform_pl310_write_debug(struct pl310_softc *sc, uint32_t val) +omap4_pl310_write_debug(platform_t plat, struct pl310_softc *sc, uint32_t val) { + ti_smc0(val, 0, L2CACHE_WRITE_DEBUG_REG); } diff --git a/sys/arm/ti/omap4/omap4_mp.h b/sys/arm/ti/omap4/omap4_machdep.h similarity index 82% rename from sys/arm/ti/omap4/omap4_mp.h rename to sys/arm/ti/omap4/omap4_machdep.h index d4aa8df876b3..50c370ebe24b 100644 --- a/sys/arm/ti/omap4/omap4_mp.h +++ b/sys/arm/ti/omap4/omap4_machdep.h @@ -25,9 +25,16 @@ * $FreeBSD$ */ -#ifndef _OMAP4_MP_H_ -#define _OMAP4_MP_H_ +#ifndef _OMAP4_MACHDEP_H_ +#define _OMAP4_MACHDEP_H_ + +struct pl310_softc; + void omap4_mp_setmaxid(platform_t plat); void omap4_mp_start_ap(platform_t plat); -#endif /* _OMAP4_MP_H_ */ +void omap4_pl310_init(platform_t, struct pl310_softc *); +void omap4_pl310_write_ctrl(platform_t, struct pl310_softc *, uint32_t); +void omap4_pl310_write_debug(platform_t, struct pl310_softc *, uint32_t); + +#endif /* _OMAP4_MACHDEP_H_ */ diff --git a/sys/arm/ti/omap4/omap4_mp.c b/sys/arm/ti/omap4/omap4_mp.c index 165cbcfb9936..16c53f56b09d 100644 --- a/sys/arm/ti/omap4/omap4_mp.c +++ b/sys/arm/ti/omap4/omap4_mp.c @@ -41,8 +41,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include -#include void omap4_mp_setmaxid(platform_t plat) diff --git a/sys/arm/ti/ti_machdep.c b/sys/arm/ti/ti_machdep.c index eb10700b3cd2..981b223cc90c 100644 --- a/sys/arm/ti/ti_machdep.c +++ b/sys/arm/ti/ti_machdep.c @@ -52,13 +52,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include -#include #include #include "platform_if.h" #if defined(SOC_OMAP4) +#include "platform_pl310_if.h" + static platform_attach_t omap4_attach; static platform_devmap_init_t ti_omap4_devmap_init; #endif @@ -139,6 +141,11 @@ static platform_method_t omap4_methods[] = { PLATFORMMETHOD(platform_mp_start_ap, omap4_mp_start_ap), PLATFORMMETHOD(platform_mp_setmaxid, omap4_mp_setmaxid), #endif + + PLATFORMMETHOD(platform_pl310_init, omap4_pl310_init), + PLATFORMMETHOD(platform_pl310_write_ctrl, omap4_pl310_write_ctrl), + PLATFORMMETHOD(platform_pl310_write_debug, omap4_pl310_write_debug), + PLATFORMMETHOD_END, }; FDT_PLATFORM_DEF(omap4, "omap4", 0, "ti,omap4430", 200); diff --git a/sys/arm/ti/ti_sdhci.c b/sys/arm/ti/ti_sdhci.c index 6b188ddd0728..00c2fcfa49f2 100644 --- a/sys/arm/ti/ti_sdhci.c +++ b/sys/arm/ti/ti_sdhci.c @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -60,6 +62,8 @@ __FBSDID("$FreeBSD$"); #include #include "gpio_if.h" +#include "opt_mmccam.h" + struct ti_sdhci_softc { device_t dev; struct sdhci_fdt_gpio * gpio; @@ -122,6 +126,11 @@ static struct ofw_compat_data compat_data[] = { #define MMCHS_SD_CAPA_VS30 (1 << 25) #define MMCHS_SD_CAPA_VS33 (1 << 24) +/* Forward declarations, CAM-relataed */ +// static void ti_sdhci_cam_poll(struct cam_sim *); +// static void ti_sdhci_cam_action(struct cam_sim *, union ccb *); +// static int ti_sdhci_cam_settran_settings(struct ti_sdhci_softc *sc, union ccb *); + static inline uint32_t ti_mmchs_read_4(struct ti_sdhci_softc *sc, bus_size_t off) { @@ -241,6 +250,22 @@ ti_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, struct ti_sdhci_softc *sc = device_get_softc(dev); uint32_t val32; +#ifdef MMCCAM + uint32_t newval32; + if (off == SDHCI_HOST_CONTROL) { + val32 = ti_mmchs_read_4(sc, MMCHS_CON); + newval32 = val32; + if (val & SDHCI_CTRL_8BITBUS) { + device_printf(dev, "Custom-enabling 8-bit bus\n"); + newval32 |= MMCHS_CON_DW8; + } else { + device_printf(dev, "Custom-disabling 8-bit bus\n"); + newval32 &= ~MMCHS_CON_DW8; + } + if (newval32 != val32) + ti_mmchs_write_4(sc, MMCHS_CON, newval32); + } +#endif val32 = RD4(sc, off & ~3); val32 &= ~(0xff << (off & 3) * 8); val32 |= (val << (off & 3) * 8); @@ -658,8 +683,11 @@ ti_sdhci_attach(device_t dev) bus_generic_probe(dev); bus_generic_attach(dev); +#ifdef MMCCAM + sdhci_cam_start_slot(&sc->slot); +#else sdhci_start_slot(&sc->slot); - +#endif return (0); fail: @@ -730,4 +758,7 @@ static driver_t ti_sdhci_driver = { DRIVER_MODULE(sdhci_ti, simplebus, ti_sdhci_driver, ti_sdhci_devclass, NULL, NULL); MODULE_DEPEND(sdhci_ti, sdhci, 1, 1, 1); + +#ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_ti); +#endif diff --git a/sys/arm/versatile/sp804.c b/sys/arm/versatile/sp804.c index ecc3b7cba8ff..d0efb448750e 100644 --- a/sys/arm/versatile/sp804.c +++ b/sys/arm/versatile/sp804.c @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include + #include #include #include @@ -42,9 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef MULTIDELAY #include /* For arm_set_delay */ -#endif #include #include @@ -292,9 +290,7 @@ sp804_timer_attach(device_t dev) (sp804_timer_tc_read_4(SP804_PRIMECELL_ID0 + i*4) & 0xff); } -#ifdef MULTIDELAY arm_set_delay(sp804_timer_delay, sc); -#endif device_printf(dev, "PrimeCell ID: %08x\n", id); @@ -343,35 +339,3 @@ sp804_timer_delay(int usec, void *arg) first = last; } } - -#ifndef MULTIDELAY -void -DELAY(int usec) -{ - int32_t counts; - device_t timer_dev; - struct sp804_timer_softc *sc; - int timer_initialized = 0; - - timer_dev = devclass_get_device(sp804_timer_devclass, 0); - - if (timer_dev) { - sc = device_get_softc(timer_dev); - - if (sc) - timer_initialized = sc->timer_initialized; - } - - if (!timer_initialized) { - /* - * Timer is not initialized yet - */ - for (; usec > 0; usec--) - for (counts = 200; counts > 0; counts--) - /* Prevent gcc from optimizing out the loop */ - cpufunc_nullop(); - } else { - sp804_timer_delay(usec, sc); - } -} -#endif diff --git a/sys/arm/versatile/versatile_machdep.c b/sys/arm/versatile/versatile_machdep.c index 22cf82b2e1bd..b25a1dce922e 100644 --- a/sys/arm/versatile/versatile_machdep.c +++ b/sys/arm/versatile/versatile_machdep.c @@ -49,34 +49,21 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include +#include + +#include "platform_if.h" /* Start of address space used for bootstrap map */ #define DEVMAP_BOOTSTRAP_MAP_START 0xE0000000 -vm_offset_t -platform_lastaddr(void) +static vm_offset_t +versatile_lastaddr(platform_t plat) { return (DEVMAP_BOOTSTRAP_MAP_START); } -void -platform_probe_and_attach(void) -{ - -} - -void -platform_gpio_init(void) -{ -} - -void -platform_late_init(void) -{ -} - #define FDT_DEVMAP_MAX (2) /* FIXME */ static struct devmap_entry fdt_devmap[FDT_DEVMAP_MAX] = { { 0, 0, 0, }, @@ -87,8 +74,8 @@ static struct devmap_entry fdt_devmap[FDT_DEVMAP_MAX] = { /* * Construct devmap table with DT-derived config data. */ -int -platform_devmap_init(void) +static int +versatile_devmap_init(platform_t plat) { int i = 0; fdt_devmap[i].pd_va = 0xf0100000; @@ -99,10 +86,18 @@ platform_devmap_init(void) return (0); } -void -cpu_reset(void) +static void +versatile_cpu_reset(platform_t plat) { printf("cpu_reset\n"); while (1); } +static platform_method_t versatile_methods[] = { + PLATFORMMETHOD(platform_lastaddr, versatile_lastaddr), + PLATFORMMETHOD(platform_devmap_init, versatile_devmap_init), + PLATFORMMETHOD(platform_cpu_reset, versatile_cpu_reset), + + PLATFORMMETHOD_END, +}; +FDT_PLATFORM_DEF(versatile, "versatile", 0, "arm,versatile-pb", 1); diff --git a/sys/arm/xilinx/zy7_l2cache.c b/sys/arm/xilinx/zy7_l2cache.c index 818fd0321aeb..5bf353fcfe0d 100644 --- a/sys/arm/xilinx/zy7_l2cache.c +++ b/sys/arm/xilinx/zy7_l2cache.c @@ -39,22 +39,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include + +#include + +#include "platform_pl310_if.h" void -platform_pl310_init(struct pl310_softc *softc) +zynq7_pl310_init(platform_t plat, struct pl310_softc *softc) { } - -void -platform_pl310_write_ctrl(struct pl310_softc *sc, uint32_t val) -{ - - pl310_write4(sc, PL310_CTRL, val); -} - -void -platform_pl310_write_debug(struct pl310_softc *sc, uint32_t val) -{ - - pl310_write4(sc, PL310_DEBUG_CTRL, val); -} diff --git a/sys/arm/xilinx/zy7_machdep.c b/sys/arm/xilinx/zy7_machdep.c index 8eac5be88b48..94856fe5c694 100644 --- a/sys/arm/xilinx/zy7_machdep.c +++ b/sys/arm/xilinx/zy7_machdep.c @@ -51,10 +51,11 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #include "platform_if.h" +#include "platform_pl310_if.h" void (*zynq7_cpu_reset)(void); @@ -93,7 +94,9 @@ static platform_method_t zynq7_methods[] = { PLATFORMMETHOD(platform_mp_start_ap, zynq7_mp_start_ap), #endif + PLATFORMMETHOD(platform_pl310_init, zynq7_pl310_init), + PLATFORMMETHOD_END, }; -FDT_PLATFORM_DEF(zynq7, "zynq7", 0, "xlnx,zynq-7000", 0); +FDT_PLATFORM_DEF(zynq7, "zynq7", 0, "xlnx,zynq-7000", 200); diff --git a/sys/arm/xilinx/zy7_mp.h b/sys/arm/xilinx/zy7_machdep.h similarity index 90% rename from sys/arm/xilinx/zy7_mp.h rename to sys/arm/xilinx/zy7_machdep.h index c339c264f09a..e45409546d26 100644 --- a/sys/arm/xilinx/zy7_mp.h +++ b/sys/arm/xilinx/zy7_machdep.h @@ -25,10 +25,14 @@ * $FreeBSD$ */ -#ifndef _ZY7_MP_H_ -#define _ZY7_MP_H_ +#ifndef _ZY7_MACHDEP_H_ +#define _ZY7_MACHDEP_H_ + +struct pl310_softc; void zynq7_mp_setmaxid(platform_t); void zynq7_mp_start_ap(platform_t); -#endif /* _ZY7_MP_H_ */ +void zynq7_pl310_init(platform_t, struct pl310_softc *); + +#endif /* _ZY7_MACHDEP_H_ */ diff --git a/sys/arm/xilinx/zy7_mp.c b/sys/arm/xilinx/zy7_mp.c index cb6a359fea1a..d9bcf602ac10 100644 --- a/sys/arm/xilinx/zy7_mp.c +++ b/sys/arm/xilinx/zy7_mp.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #define ZYNQ7_CPU1_ENTRY 0xfffffff0 diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index f3f58d0df000..a652bcbd9d9b 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -176,6 +176,7 @@ device aw_rsb # Allwinner Reduced Serial Bus device bcm2835_bsc # Broadcom BCM283x I2C bus device iicbus device iic +device twsi # Allwinner I2C controller # Clock and reset controllers device aw_ccu # Allwinner clock controller diff --git a/sys/boot/fdt/dts/arm/h3.dtsi b/sys/boot/fdt/dts/arm/h3.dtsi index 08e9f292b57d..078b802c0669 100644 --- a/sys/boot/fdt/dts/arm/h3.dtsi +++ b/sys/boot/fdt/dts/arm/h3.dtsi @@ -96,14 +96,12 @@ "PD7", "PD8", "PD9", "PD10", "PD12", "PD13", "PD15", "PD16", "PD17"; allwinner,function = "emac"; - allwinner,drive = ; - allwinner,pull = ; + allwinner,drive = <40>; }; emac_phy_reset_pin: emac_phy_reset_pin@0 { allwinner,pins = "PD6"; allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; + allwinner,drive = <10>; }; }; diff --git a/sys/boot/fdt/dts/arm/orangepi-plus-2e.dts b/sys/boot/fdt/dts/arm/orangepi-plus-2e.dts index 9a6a562eb243..28298cac50e5 100644 --- a/sys/boot/fdt/dts/arm/orangepi-plus-2e.dts +++ b/sys/boot/fdt/dts/arm/orangepi-plus-2e.dts @@ -50,15 +50,13 @@ emac_phy_reset_pin: emac_phy_reset_pin@0 { allwinner,pins = "PD6"; allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; + allwinner,drive = <10>; }; codec_pa_pin: codec_pa_pin@0 { allwinner,pins = "PA16"; allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; + allwinner,drive = <10>; }; }; diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index ad06fcfacbc0..69c123c56682 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -30,7 +30,7 @@ __FBSDID("$FreeBSD$"); #include #ifdef _KERNEL -#include +#include "opt_scsi.h" #include #include diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 4e778dcbd34f..3a529c5ebb74 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -635,6 +635,14 @@ static struct ada_quirk_entry ada_quirk_table[] = { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX4*", "*" }, /*quirks*/ADA_Q_4K }, + { + /* + * Samsung 750 SSDs + * 4k optimised, NCQ TRIM seems to work + */ + { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 750*", "*" }, + /*quirks*/ADA_Q_4K + }, { /* * Samsung 830 Series SSDs @@ -651,6 +659,14 @@ static struct ada_quirk_entry ada_quirk_table[] = { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 840*", "*" }, /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN }, + { + /* + * Samsung 845 SSDs + * 4k optimised, NCQ TRIM Broken (normal TRIM is fine) + */ + { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 845*", "*" }, + /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN + }, { /* * Samsung 850 SSDs diff --git a/sys/cam/cam.h b/sys/cam/cam.h index b0c55e7075f4..1308bbedc59b 100644 --- a/sys/cam/cam.h +++ b/sys/cam/cam.h @@ -32,7 +32,7 @@ #define _CAM_CAM_H 1 #ifdef _KERNEL -#include +#include "opt_cam.h" #endif #include diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 4cfe2e4fa34a..ac0bdd6e4ee4 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -42,6 +42,7 @@ #include #include #include +#include /* General allocation length definitions for CCB structures */ #define IOCDBLEN CAM_MAX_CDBLEN /* Space for CDB bytes/pointer */ @@ -208,10 +209,10 @@ typedef enum { XPT_NVME_IO = 0x1c | XPT_FC_DEV_QUEUED, /* Execiute the requestred NVMe I/O operation */ - XPT_MMCSD_IO = 0x1d | XPT_FC_DEV_QUEUED, + XPT_MMC_IO = 0x1d | XPT_FC_DEV_QUEUED, /* Placeholder for MMC / SD / SDIO I/O stuff */ - XPT_SCAN_TGT = 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB + XPT_SCAN_TGT = 0x1e | XPT_FC_QUEUED | XPT_FC_USER_CCB | XPT_FC_XPT_ONLY, /* Scan Target */ @@ -267,6 +268,7 @@ typedef enum { PROTO_SATAPM, /* SATA Port Multiplier */ PROTO_SEMB, /* SATA Enclosure Management Bridge */ PROTO_NVME, /* NVME */ + PROTO_MMCSD, /* MMC, SD, SDIO */ } cam_proto; typedef enum { @@ -283,6 +285,7 @@ typedef enum { XPORT_ISCSI, /* iSCSI */ XPORT_SRP, /* SCSI RDMA Protocol */ XPORT_NVME, /* NVMe over PCIe */ + XPORT_MMCSD, /* MMC, SD, SDIO card */ } cam_xport; #define XPORT_IS_NVME(t) ((t) == XPORT_NVME) @@ -330,8 +333,8 @@ typedef struct { struct ccb_hdr { cam_pinfo pinfo; /* Info for priority scheduling */ - camq_entry xpt_links; /* For chaining in the XPT layer */ - camq_entry sim_links; /* For chaining in the SIM layer */ + camq_entry xpt_links; /* For chaining in the XPT layer */ + camq_entry sim_links; /* For chaining in the SIM layer */ camq_entry periph_links; /* For chaining in the type driver */ u_int32_t retry_count; void (*cbfcnp)(struct cam_periph *, union ccb *); @@ -367,7 +370,7 @@ struct ccb_getdev { /* Device Statistics CCB */ struct ccb_getdevstats { struct ccb_hdr ccb_h; - int dev_openings; /* Space left for more work on device*/ + int dev_openings; /* Space left for more work on device*/ int dev_active; /* Transactions running on the device */ int allocated; /* CCBs allocated for the device */ int queued; /* CCBs queued to be sent to the device */ @@ -441,7 +444,7 @@ struct device_match_pattern { union { struct scsi_static_inquiry_pattern inq_pat; struct device_id_match_pattern devid_pat; - } data; + } data; }; typedef enum { @@ -499,6 +502,7 @@ struct device_match_result { struct scsi_inquiry_data inq_data; struct ata_params ident_data; dev_result_flags flags; + struct mmc_params mmc_ident_data; }; struct bus_match_result { @@ -541,7 +545,7 @@ typedef enum { struct ccb_dm_cookie { void *bus; - void *target; + void *target; void *device; void *periph; void *pdrv; @@ -724,7 +728,7 @@ struct ccb_scsiio { u_int8_t *req_map; /* Ptr to mapping info */ u_int8_t *data_ptr; /* Ptr to the data buf/SG list */ u_int32_t dxfer_len; /* Data transfer length */ - /* Autosense storage */ + /* Autosense storage */ struct scsi_sense_data sense_data; u_int8_t sense_len; /* Number of bytes to autosense */ u_int8_t cdb_len; /* Number of bytes for the CDB */ @@ -773,6 +777,16 @@ struct ccb_ataio { uint32_t unused; }; +/* + * MMC I/O Request CCB used for the XPT_MMC_IO function code. + */ +struct ccb_mmcio { + struct ccb_hdr ccb_h; + union ccb *next_ccb; /* Ptr for next CCB for action */ + struct mmc_command cmd; + struct mmc_command stop; +}; + struct ccb_accept_tio { struct ccb_hdr ccb_h; cdb_t cdb_io; /* Union for CDB bytes/pointer */ @@ -863,7 +877,7 @@ struct ac_device_changed { /* Set Asynchronous Callback CCB */ struct ccb_setasync { struct ccb_hdr ccb_h; - u_int32_t event_enable; /* Async Event enables */ + u_int32_t event_enable; /* Async Event enables */ ac_callback_t *callback; void *callback_arg; }; @@ -1005,7 +1019,28 @@ struct ccb_trans_settings_nvme u_int max_xfer; /* Max transfer size (0 -> unlimited */ u_int caps; }; - + +#include +struct ccb_trans_settings_mmc { + struct mmc_ios ios; +#define MMC_CLK (1 << 1) +#define MMC_VDD (1 << 2) +#define MMC_CS (1 << 3) +#define MMC_BW (1 << 4) +#define MMC_PM (1 << 5) +#define MMC_BT (1 << 6) +#define MMC_BM (1 << 7) + uint32_t ios_valid; +/* The folowing is used only for GET_TRAN_SETTINGS */ + uint32_t host_ocr; + int host_f_min; + int host_f_max; +#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can do 4-bit data transfers */ +#define MMC_CAP_8_BIT_DATA (1 << 1) /* Can do 8-bit data transfers */ +#define MMC_CAP_HSPEED (1 << 2) /* Can do High Speed transfers */ + uint32_t host_caps; +}; + /* Get/Set transfer rate/width/disconnection/tag queueing settings */ struct ccb_trans_settings { struct ccb_hdr ccb_h; @@ -1019,6 +1054,7 @@ struct ccb_trans_settings { struct ccb_trans_settings_ata ata; struct ccb_trans_settings_scsi scsi; struct ccb_trans_settings_nvme nvme; + struct ccb_trans_settings_mmc mmc; } proto_specific; union { u_int valid; /* Which fields to honor */ @@ -1040,7 +1076,7 @@ struct ccb_calc_geometry { struct ccb_hdr ccb_h; u_int32_t block_size; u_int64_t volume_size; - u_int32_t cylinders; + u_int32_t cylinders; u_int8_t heads; u_int8_t secs_per_track; }; @@ -1262,8 +1298,8 @@ union ccb { struct ccb_getdevstats cgds; struct ccb_dev_match cdm; struct ccb_trans_settings cts; - struct ccb_calc_geometry ccg; - struct ccb_sim_knob knob; + struct ccb_calc_geometry ccg; + struct ccb_sim_knob knob; struct ccb_abort cab; struct ccb_resetbus crb; struct ccb_resetdev crd; @@ -1284,6 +1320,7 @@ union ccb { struct ccb_dev_advinfo cdai; struct ccb_async casync; struct ccb_nvmeio nvmeio; + struct ccb_mmcio mmcio; }; #define CCB_CLEAR_ALL_EXCEPT_HDR(ccbp) \ @@ -1320,12 +1357,19 @@ cam_fill_ataio(struct ccb_ataio *ataio, u_int32_t retries, u_int32_t timeout); static __inline void -cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, +cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, uint8_t *smp_request, int smp_request_len, uint8_t *smp_response, int smp_response_len, uint32_t timeout); +static __inline void +cam_fill_mmcio(struct ccb_mmcio *mmcio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, + uint32_t mmc_opcode, uint32_t mmc_arg, uint32_t mmc_flags, + struct mmc_data *mmc_d, + uint32_t timeout); + static __inline void cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), @@ -1337,7 +1381,7 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries, csio->ccb_h.func_code = XPT_SCSI_IO; csio->ccb_h.flags = flags; csio->ccb_h.xflags = 0; - csio->ccb_h.retry_count = retries; + csio->ccb_h.retry_count = retries; csio->ccb_h.cbfcnp = cbfcnp; csio->ccb_h.timeout = timeout; csio->data_ptr = data_ptr; @@ -1360,7 +1404,7 @@ cam_fill_ctio(struct ccb_scsiio *csio, u_int32_t retries, csio->ccb_h.func_code = XPT_CONT_TARGET_IO; csio->ccb_h.flags = flags; csio->ccb_h.xflags = 0; - csio->ccb_h.retry_count = retries; + csio->ccb_h.retry_count = retries; csio->ccb_h.cbfcnp = cbfcnp; csio->ccb_h.timeout = timeout; csio->data_ptr = data_ptr; @@ -1389,7 +1433,7 @@ cam_fill_ataio(struct ccb_ataio *ataio, u_int32_t retries, } static __inline void -cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, +cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, uint8_t *smp_request, int smp_request_len, uint8_t *smp_response, int smp_response_len, @@ -1414,6 +1458,34 @@ cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, smpio->smp_response_len = smp_response_len; } +static __inline void +cam_fill_mmcio(struct ccb_mmcio *mmcio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, + uint32_t mmc_opcode, uint32_t mmc_arg, uint32_t mmc_flags, + struct mmc_data *mmc_d, + uint32_t timeout) +{ + mmcio->ccb_h.func_code = XPT_MMC_IO; + mmcio->ccb_h.flags = flags; + mmcio->ccb_h.retry_count = retries; + mmcio->ccb_h.cbfcnp = cbfcnp; + mmcio->ccb_h.timeout = timeout; + mmcio->cmd.opcode = mmc_opcode; + mmcio->cmd.arg = mmc_arg; + mmcio->cmd.flags = mmc_flags; + mmcio->stop.opcode = 0; + mmcio->stop.arg = 0; + mmcio->stop.flags = 0; + if (mmc_d != NULL) { + mmcio->cmd.data = mmc_d; + } else + mmcio->cmd.data = NULL; + mmcio->cmd.resp[0] = 0; + mmcio->cmd.resp[1] = 0; + mmcio->cmd.resp[2] = 0; + mmcio->cmd.resp[3] = 0; +} + static __inline void cam_set_ccbstatus(union ccb *ccb, cam_status status) { diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 2c4c9cf9e27b..35d2f5e74bd1 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -827,6 +827,18 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo, dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; numbufs = 1; break; + case XPT_MMC_IO: + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) + return(0); + /* Two mappings: one for cmd->data and one for cmd->data->data */ + data_ptrs[0] = (unsigned char **)&ccb->mmcio.cmd.data; + lengths[0] = sizeof(struct mmc_data *); + dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; + data_ptrs[1] = (unsigned char **)&ccb->mmcio.cmd.data->data; + lengths[1] = ccb->mmcio.cmd.data->len; + dirs[1] = ccb->ccb_h.flags & CAM_DIR_MASK; + numbufs = 2; + break; case XPT_SMP_IO: data_ptrs[0] = &ccb->smpio.smp_request; lengths[0] = ccb->smpio.smp_request_len; diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index a848c3eee3d7..2c58efa829d5 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -329,7 +329,6 @@ static xpt_devicefunc_t xptsetasyncfunc; static xpt_busfunc_t xptsetasyncbusfunc; static cam_status xptregister(struct cam_periph *periph, void *arg); -static const char * xpt_action_name(uint32_t action); static __inline int device_is_queued(struct cam_ed *device); static __inline int @@ -412,7 +411,7 @@ xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td } return (error); } - + static int xptdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { @@ -1503,7 +1502,7 @@ xptdevicematch(struct dev_match_pattern *patterns, u_int num_patterns, cur_pattern = &patterns[i].pattern.device_pattern; - /* Error out if mutually exclusive options are specified. */ + /* Error out if mutually exclusive options are specified. */ if ((cur_pattern->flags & (DEV_MATCH_INQUIRY|DEV_MATCH_DEVID)) == (DEV_MATCH_INQUIRY|DEV_MATCH_DEVID)) return(DM_RET_ERROR); @@ -1905,6 +1904,9 @@ xptedtdevicefunc(struct cam_ed *device, void *arg) bcopy(&device->ident_data, &cdm->matches[j].result.device_result.ident_data, sizeof(struct ata_params)); + bcopy(&device->mmc_ident_data, + &cdm->matches[j].result.device_result.mmc_ident_data, + sizeof(struct mmc_params)); /* Let the user know whether this device is unconfigured */ if (device->flags & CAM_DEV_UNCONFIGURED) @@ -2690,6 +2692,8 @@ xpt_action_default(union ccb *start_ccb) if (start_ccb->ccb_h.func_code == XPT_NVME_IO) start_ccb->nvmeio.resid = 0; /* FALLTHROUGH */ + case XPT_MMC_IO: + /* XXX just like nmve_io? */ case XPT_RESET_DEV: case XPT_ENG_EXEC: case XPT_SMP_IO: @@ -2801,11 +2805,12 @@ xpt_action_default(union ccb *start_ccb) mtx_lock(mtx); else mtx = NULL; + CAM_DEBUG(path, CAM_DEBUG_TRACE, - ("sim->sim_action: func=%#x\n", start_ccb->ccb_h.func_code)); + ("Calling sim->sim_action(): func=%#x\n", start_ccb->ccb_h.func_code)); (*(sim->sim_action))(sim, start_ccb); CAM_DEBUG(path, CAM_DEBUG_TRACE, - ("sim->sim_action: status=%#x\n", start_ccb->ccb_h.status)); + ("sim->sim_action returned: status=%#x\n", start_ccb->ccb_h.status)); if (mtx) mtx_unlock(mtx); break; @@ -5540,7 +5545,7 @@ static struct kv map[] = { { XPT_GET_SIM_KNOB, "XPT_GET_SIM_KNOB" }, { XPT_SET_SIM_KNOB, "XPT_SET_SIM_KNOB" }, { XPT_NVME_IO, "XPT_NVME_IO" }, - { XPT_MMCSD_IO, "XPT_MMCSD_IO" }, + { XPT_MMC_IO, "XPT_MMC_IO" }, { XPT_SMP_IO, "XPT_SMP_IO" }, { XPT_SCAN_TGT, "XPT_SCAN_TGT" }, { XPT_ENG_INQ, "XPT_ENG_INQ" }, @@ -5556,7 +5561,7 @@ static struct kv map[] = { { 0, 0 } }; -static const char * +const char * xpt_action_name(uint32_t action) { static char buffer[32]; /* Only for unknown messages -- racy */ diff --git a/sys/cam/cam_xpt.h b/sys/cam/cam_xpt.h index 8e6027e56447..47fdbd748b2d 100644 --- a/sys/cam/cam_xpt.h +++ b/sys/cam/cam_xpt.h @@ -141,6 +141,8 @@ void xpt_copy_path(struct cam_path *new_path, void xpt_release_path(struct cam_path *path); +const char * xpt_action_name(uint32_t action); + #endif /* _KERNEL */ #endif /* _CAM_CAM_XPT_H */ diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h index b33b4e7a25f6..cdc11c83abc7 100644 --- a/sys/cam/cam_xpt_internal.h +++ b/sys/cam/cam_xpt_internal.h @@ -125,6 +125,7 @@ struct cam_ed { uint32_t rcap_len; uint8_t *rcap_buf; struct ata_params ident_data; + struct mmc_params mmc_ident_data; u_int8_t inq_flags; /* * Current settings for inquiry flags. * This allows us to override settings diff --git a/sys/cam/mmc/mmc.h b/sys/cam/mmc/mmc.h new file mode 100644 index 000000000000..9fae837e9e03 --- /dev/null +++ b/sys/cam/mmc/mmc.h @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2014-2016 Ilya Bakulin. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Portions of this software may have been developed with reference to + * the SD Simplified Specification. The following disclaimer may apply: + * + * The following conditions apply to the release of the simplified + * specification ("Simplified Specification") by the SD Card Association and + * the SD Group. The Simplified Specification is a subset of the complete SD + * Specification which is owned by the SD Card Association and the SD + * Group. This Simplified Specification is provided on a non-confidential + * basis subject to the disclaimers below. Any implementation of the + * Simplified Specification may require a license from the SD Card + * Association, SD Group, SD-3C LLC or other third parties. + * + * Disclaimers: + * + * The information contained in the Simplified Specification is presented only + * as a standard specification for SD Cards and SD Host/Ancillary products and + * is provided "AS-IS" without any representations or warranties of any + * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD + * Card Association for any damages, any infringements of patents or other + * right of the SD Group, SD-3C LLC, the SD Card Association or any third + * parties, which may result from its use. No license is granted by + * implication, estoppel or otherwise under any patent or other rights of the + * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing + * herein shall be construed as an obligation by the SD Group, the SD-3C LLC + * or the SD Card Association to disclose or distribute any technical + * information, know-how or other confidential information to any third party. + * + * Inspired coded in sys/dev/mmc. Thanks to Warner Losh , + * Bernd Walter , and other authors. + * + * $FreeBSD$ + */ + +#ifndef CAM_MMC_H +#define CAM_MMC_H + +#include +/* + * This structure describes an MMC/SD card + */ +struct mmc_params { + u_int8_t model[40]; /* Card model */ + + /* Card OCR */ + uint32_t card_ocr; + + /* OCR of the IO portion of the card */ + uint32_t io_ocr; + + /* Card CID -- raw and parsed */ + uint32_t card_cid[4]; + struct mmc_cid cid; + + /* Card CSD -- raw */ + uint32_t card_csd[4]; + + /* Card RCA */ + uint16_t card_rca; + + /* What kind of card is it */ + uint32_t card_features; +#define CARD_FEATURE_MEMORY 0x1 +#define CARD_FEATURE_SDHC 0x1 << 1 +#define CARD_FEATURE_SDIO 0x1 << 2 +#define CARD_FEATURE_SD20 0x1 << 3 +#define CARD_FEATURE_MMC 0x1 << 4 + + uint8_t sdio_func_count; +} __packed; + +#endif diff --git a/sys/cam/mmc/mmc_all.h b/sys/cam/mmc/mmc_all.h new file mode 100644 index 000000000000..c2494894ca2e --- /dev/null +++ b/sys/cam/mmc/mmc_all.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2014-2016 Ilya Bakulin. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Portions of this software may have been developed with reference to + * the SD Simplified Specification. The following disclaimer may apply: + * + * The following conditions apply to the release of the simplified + * specification ("Simplified Specification") by the SD Card Association and + * the SD Group. The Simplified Specification is a subset of the complete SD + * Specification which is owned by the SD Card Association and the SD + * Group. This Simplified Specification is provided on a non-confidential + * basis subject to the disclaimers below. Any implementation of the + * Simplified Specification may require a license from the SD Card + * Association, SD Group, SD-3C LLC or other third parties. + * + * Disclaimers: + * + * The information contained in the Simplified Specification is presented only + * as a standard specification for SD Cards and SD Host/Ancillary products and + * is provided "AS-IS" without any representations or warranties of any + * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD + * Card Association for any damages, any infringements of patents or other + * right of the SD Group, SD-3C LLC, the SD Card Association or any third + * parties, which may result from its use. No license is granted by + * implication, estoppel or otherwise under any patent or other rights of the + * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing + * herein shall be construed as an obligation by the SD Group, the SD-3C LLC + * or the SD Card Association to disclose or distribute any technical + * information, know-how or other confidential information to any third party. + * + * $FreeBSD$ + */ + +/* + * MMC function that should be visible to the CAM subsystem + * and are somehow useful should be declared here + * + * Like in other *_all.h, it's also a nice place to include + * some other transport-specific headers. + */ + +#ifndef CAM_MMC_ALL_H +#define CAM_MMC_ALL_H + +#include +#include + +void mmc_print_ident(struct mmc_params *ident_data); + +#endif diff --git a/sys/cam/mmc/mmc_bus.h b/sys/cam/mmc/mmc_bus.h new file mode 100644 index 000000000000..db77da510788 --- /dev/null +++ b/sys/cam/mmc/mmc_bus.h @@ -0,0 +1,5 @@ +/* + * This file is in the public domain. + * $FreeBSD$ + */ +#include diff --git a/sys/cam/mmc/mmc_da.c b/sys/cam/mmc/mmc_da.c new file mode 100644 index 000000000000..31bbf000e14c --- /dev/null +++ b/sys/cam/mmc/mmc_da.c @@ -0,0 +1,1432 @@ +/*- + * Copyright (c) 2006 Bernd Walter + * Copyright (c) 2006 M. Warner Losh + * Copyright (c) 2009 Alexander Motin + * Copyright (c) 2015-2017 Ilya Bakulin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Some code derived from the sys/dev/mmc and sys/cam/ata + * Thanks to Warner Losh , Alexander Motin + * Bernd Walter , and other authors. + */ + +#include +__FBSDID("$FreeBSD$"); + +//#include "opt_sdda.h" + +#include + +#ifdef _KERNEL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for PRIu64 */ +#endif /* _KERNEL */ + +#ifndef _KERNEL +#include +#include +#endif /* _KERNEL */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include /* geometry translation */ + +#ifdef _KERNEL + +typedef enum { + SDDA_FLAG_OPEN = 0x0002, + SDDA_FLAG_DIRTY = 0x0004 +} sdda_flags; + +typedef enum { + SDDA_STATE_INIT, + SDDA_STATE_INVALID, + SDDA_STATE_NORMAL +} sdda_state; + +struct sdda_softc { + struct bio_queue_head bio_queue; + int outstanding_cmds; /* Number of active commands */ + int refcount; /* Active xpt_action() calls */ + sdda_state state; + sdda_flags flags; + struct mmc_data *mmcdata; +// sdda_quirks quirks; + struct task start_init_task; + struct disk *disk; + uint32_t raw_csd[4]; + uint8_t raw_ext_csd[512]; /* MMC only? */ + struct mmc_csd csd; + struct mmc_cid cid; + struct mmc_scr scr; + /* Calculated from CSD */ + uint64_t sector_count; + uint64_t mediasize; + + /* Calculated from CID */ + char card_id_string[64];/* Formatted CID info (serial, MFG, etc) */ + char card_sn_string[16];/* Formatted serial # for disk->d_ident */ + /* Determined from CSD + is highspeed card*/ + uint32_t card_f_max; +}; + +#define ccb_bp ppriv_ptr1 + +static disk_strategy_t sddastrategy; +static periph_init_t sddainit; +static void sddaasync(void *callback_arg, u_int32_t code, + struct cam_path *path, void *arg); +static periph_ctor_t sddaregister; +static periph_dtor_t sddacleanup; +static periph_start_t sddastart; +static periph_oninv_t sddaoninvalidate; +static void sddadone(struct cam_periph *periph, + union ccb *done_ccb); +static int sddaerror(union ccb *ccb, u_int32_t cam_flags, + u_int32_t sense_flags); + +static uint16_t get_rca(struct cam_periph *periph); +static cam_status sdda_hook_into_geom(struct cam_periph *periph); +static void sdda_start_init(void *context, union ccb *start_ccb); +static void sdda_start_init_task(void *context, int pending); + +static struct periph_driver sddadriver = +{ + sddainit, "sdda", + TAILQ_HEAD_INITIALIZER(sddadriver.units), /* generation */ 0 +}; + +PERIPHDRIVER_DECLARE(sdda, sddadriver); + +static MALLOC_DEFINE(M_SDDA, "sd_da", "sd_da buffers"); + +static const int exp[8] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 +}; + +static const int mant[16] = { + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 +}; + +static const int cur_min[8] = { + 500, 1000, 5000, 10000, 25000, 35000, 60000, 100000 +}; + +static const int cur_max[8] = { + 1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000 +}; + +static uint16_t +get_rca(struct cam_periph *periph) { + return periph->path->device->mmc_ident_data.card_rca; +} + +static uint32_t +mmc_get_bits(uint32_t *bits, int bit_len, int start, int size) +{ + const int i = (bit_len / 32) - (start / 32) - 1; + const int shift = start & 31; + uint32_t retval = bits[i] >> shift; + if (size + shift > 32) + retval |= bits[i - 1] << (32 - shift); + return (retval & ((1llu << size) - 1)); +} + + +static void +mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd) +{ + int v; + int m; + int e; + + memset(csd, 0, sizeof(*csd)); + csd->csd_structure = v = mmc_get_bits(raw_csd, 128, 126, 2); + if (v == 0) { + m = mmc_get_bits(raw_csd, 128, 115, 4); + e = mmc_get_bits(raw_csd, 128, 112, 3); + csd->tacc = (exp[e] * mant[m] + 9) / 10; + csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100; + m = mmc_get_bits(raw_csd, 128, 99, 4); + e = mmc_get_bits(raw_csd, 128, 96, 3); + csd->tran_speed = exp[e] * 10000 * mant[m]; + csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12); + csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4); + csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1); + csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1); + csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1); + csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1); + csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 59, 3)]; + csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 56, 3)]; + csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 53, 3)]; + csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 50, 3)]; + m = mmc_get_bits(raw_csd, 128, 62, 12); + e = mmc_get_bits(raw_csd, 128, 47, 3); + csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; + csd->erase_blk_en = mmc_get_bits(raw_csd, 128, 46, 1); + csd->erase_sector = mmc_get_bits(raw_csd, 128, 39, 7) + 1; + csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 7); + csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1); + csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3); + csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4); + csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1); + } else if (v == 1) { + m = mmc_get_bits(raw_csd, 128, 115, 4); + e = mmc_get_bits(raw_csd, 128, 112, 3); + csd->tacc = (exp[e] * mant[m] + 9) / 10; + csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100; + m = mmc_get_bits(raw_csd, 128, 99, 4); + e = mmc_get_bits(raw_csd, 128, 96, 3); + csd->tran_speed = exp[e] * 10000 * mant[m]; + csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12); + csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4); + csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1); + csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1); + csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1); + csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1); + csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 128, 48, 22) + 1) * + 512 * 1024; + csd->erase_blk_en = mmc_get_bits(raw_csd, 128, 46, 1); + csd->erase_sector = mmc_get_bits(raw_csd, 128, 39, 7) + 1; + csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 7); + csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1); + csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3); + csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4); + csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1); + } else + panic("unknown SD CSD version"); +} + +static void +mmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd) +{ + int m; + int e; + + memset(csd, 0, sizeof(*csd)); + csd->csd_structure = mmc_get_bits(raw_csd, 128, 126, 2); + csd->spec_vers = mmc_get_bits(raw_csd, 128, 122, 4); + m = mmc_get_bits(raw_csd, 128, 115, 4); + e = mmc_get_bits(raw_csd, 128, 112, 3); + csd->tacc = exp[e] * mant[m] + 9 / 10; + csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100; + m = mmc_get_bits(raw_csd, 128, 99, 4); + e = mmc_get_bits(raw_csd, 128, 96, 3); + csd->tran_speed = exp[e] * 10000 * mant[m]; + csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12); + csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4); + csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1); + csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1); + csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1); + csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1); + csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 59, 3)]; + csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 56, 3)]; + csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 53, 3)]; + csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 50, 3)]; + m = mmc_get_bits(raw_csd, 128, 62, 12); + e = mmc_get_bits(raw_csd, 128, 47, 3); + csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; + csd->erase_blk_en = 0; + csd->erase_sector = (mmc_get_bits(raw_csd, 128, 42, 5) + 1) * + (mmc_get_bits(raw_csd, 128, 37, 5) + 1); + csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 5); + csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1); + csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3); + csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4); + csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1); +} + +static void +mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid) +{ + int i; + + /* There's no version info, so we take it on faith */ + memset(cid, 0, sizeof(*cid)); + cid->mid = mmc_get_bits(raw_cid, 128, 120, 8); + cid->oid = mmc_get_bits(raw_cid, 128, 104, 16); + for (i = 0; i < 5; i++) + cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8); + cid->pnm[5] = 0; + cid->prv = mmc_get_bits(raw_cid, 128, 56, 8); + cid->psn = mmc_get_bits(raw_cid, 128, 24, 32); + cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2000; + cid->mdt_month = mmc_get_bits(raw_cid, 128, 8, 4); +} + +static void +mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid) +{ + int i; + + /* There's no version info, so we take it on faith */ + memset(cid, 0, sizeof(*cid)); + cid->mid = mmc_get_bits(raw_cid, 128, 120, 8); + cid->oid = mmc_get_bits(raw_cid, 128, 104, 8); + for (i = 0; i < 6; i++) + cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8); + cid->pnm[6] = 0; + cid->prv = mmc_get_bits(raw_cid, 128, 48, 8); + cid->psn = mmc_get_bits(raw_cid, 128, 16, 32); + cid->mdt_month = mmc_get_bits(raw_cid, 128, 12, 4); + cid->mdt_year = mmc_get_bits(raw_cid, 128, 8, 4) + 1997; +} + +static void +mmc_format_card_id_string(struct sdda_softc *sc, struct mmc_params *mmcp) +{ + char oidstr[8]; + uint8_t c1; + uint8_t c2; + + /* + * Format a card ID string for use by the mmcsd driver, it's what + * appears between the <> in the following: + * mmcsd0: 968MB at mmc0 + * 22.5MHz/4bit/128-block + * + * Also format just the card serial number, which the mmcsd driver will + * use as the disk->d_ident string. + * + * The card_id_string in mmc_ivars is currently allocated as 64 bytes, + * and our max formatted length is currently 55 bytes if every field + * contains the largest value. + * + * Sometimes the oid is two printable ascii chars; when it's not, + * format it as 0xnnnn instead. + */ + c1 = (sc->cid.oid >> 8) & 0x0ff; + c2 = sc->cid.oid & 0x0ff; + if (c1 > 0x1f && c1 < 0x7f && c2 > 0x1f && c2 < 0x7f) + snprintf(oidstr, sizeof(oidstr), "%c%c", c1, c2); + else + snprintf(oidstr, sizeof(oidstr), "0x%04x", sc->cid.oid); + snprintf(sc->card_sn_string, sizeof(sc->card_sn_string), + "%08X", sc->cid.psn); + snprintf(sc->card_id_string, sizeof(sc->card_id_string), + "%s%s %s %d.%d SN %08X MFG %02d/%04d by %d %s", + mmcp->card_features & CARD_FEATURE_MMC ? "MMC" : "SD", + mmcp->card_features & CARD_FEATURE_SDHC ? "HC" : "", + sc->cid.pnm, sc->cid.prv >> 4, sc->cid.prv & 0x0f, + sc->cid.psn, sc->cid.mdt_month, sc->cid.mdt_year, + sc->cid.mid, oidstr); +} + +static int +sddaopen(struct disk *dp) +{ + struct cam_periph *periph; + struct sdda_softc *softc; + int error; + + periph = (struct cam_periph *)dp->d_drv1; + if (cam_periph_acquire(periph) != CAM_REQ_CMP) { + return(ENXIO); + } + + cam_periph_lock(periph); + if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) { + cam_periph_unlock(periph); + cam_periph_release(periph); + return (error); + } + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, + ("sddaopen\n")); + + softc = (struct sdda_softc *)periph->softc; + softc->flags |= SDDA_FLAG_OPEN; + + cam_periph_unhold(periph); + cam_periph_unlock(periph); + return (0); +} + +static int +sddaclose(struct disk *dp) +{ + struct cam_periph *periph; + struct sdda_softc *softc; +// union ccb *ccb; +// int error; + + periph = (struct cam_periph *)dp->d_drv1; + softc = (struct sdda_softc *)periph->softc; + softc->flags &= ~SDDA_FLAG_OPEN; + + cam_periph_lock(periph); + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, + ("sddaclose\n")); + + while (softc->refcount != 0) + cam_periph_sleep(periph, &softc->refcount, PRIBIO, "sddaclose", 1); + cam_periph_unlock(periph); + cam_periph_release(periph); + return (0); +} + +static void +sddaschedule(struct cam_periph *periph) +{ + struct sdda_softc *softc = (struct sdda_softc *)periph->softc; + + /* Check if we have more work to do. */ + if (bioq_first(&softc->bio_queue)) { + xpt_schedule(periph, CAM_PRIORITY_NORMAL); + } +} + +/* + * Actually translate the requested transfer into one the physical driver + * can understand. The transfer is described by a buf and will include + * only one physical transfer. + */ +static void +sddastrategy(struct bio *bp) +{ + struct cam_periph *periph; + struct sdda_softc *softc; + + periph = (struct cam_periph *)bp->bio_disk->d_drv1; + softc = (struct sdda_softc *)periph->softc; + + cam_periph_lock(periph); + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddastrategy(%p)\n", bp)); + + /* + * If the device has been made invalid, error out + */ + if ((periph->flags & CAM_PERIPH_INVALID) != 0) { + cam_periph_unlock(periph); + biofinish(bp, NULL, ENXIO); + return; + } + + /* + * Place it in the queue of disk activities for this disk + */ + bioq_disksort(&softc->bio_queue, bp); + + /* + * Schedule ourselves for performing the work. + */ + sddaschedule(periph); + cam_periph_unlock(periph); + + return; +} + +static void +sddainit(void) +{ + cam_status status; + + /* + * Install a global async callback. This callback will + * receive async callbacks like "new device found". + */ + status = xpt_register_async(AC_FOUND_DEVICE, sddaasync, NULL, NULL); + + if (status != CAM_REQ_CMP) { + printf("sdda: Failed to attach master async callback " + "due to status 0x%x!\n", status); + } +} + +/* + * Callback from GEOM, called when it has finished cleaning up its + * resources. + */ +static void +sddadiskgonecb(struct disk *dp) +{ + struct cam_periph *periph; + + periph = (struct cam_periph *)dp->d_drv1; + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddadiskgonecb\n")); + + cam_periph_release(periph); +} + +static void +sddaoninvalidate(struct cam_periph *periph) +{ + struct sdda_softc *softc; + + softc = (struct sdda_softc *)periph->softc; + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaoninvalidate\n")); + + /* + * De-register any async callbacks. + */ + xpt_register_async(0, sddaasync, periph, periph->path); + + /* + * Return all queued I/O with ENXIO. + * XXX Handle any transactions queued to the card + * with XPT_ABORT_CCB. + */ + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("bioq_flush start\n")); + bioq_flush(&softc->bio_queue, NULL, ENXIO); + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("bioq_flush end\n")); + + disk_gone(softc->disk); +} + +static void +sddacleanup(struct cam_periph *periph) +{ + struct sdda_softc *softc; + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddacleanup\n")); + softc = (struct sdda_softc *)periph->softc; + + cam_periph_unlock(periph); + + disk_destroy(softc->disk); + free(softc, M_DEVBUF); + cam_periph_lock(periph); +} + +static void +sddaasync(void *callback_arg, u_int32_t code, + struct cam_path *path, void *arg) +{ + struct ccb_getdev cgd; + struct cam_periph *periph; + struct sdda_softc *softc; + + periph = (struct cam_periph *)callback_arg; + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("sddaasync(code=%d)\n", code)); + switch (code) { + case AC_FOUND_DEVICE: + { + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> AC_FOUND_DEVICE\n")); + struct ccb_getdev *cgd; + cam_status status; + + cgd = (struct ccb_getdev *)arg; + if (cgd == NULL) + break; + + if (cgd->protocol != PROTO_MMCSD) + break; + + if (!(path->device->mmc_ident_data.card_features & CARD_FEATURE_MEMORY)) { + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("No memory on the card!\n")); + break; + } + + /* + * Allocate a peripheral instance for + * this device and start the probe + * process. + */ + status = cam_periph_alloc(sddaregister, sddaoninvalidate, + sddacleanup, sddastart, + "sdda", CAM_PERIPH_BIO, + path, sddaasync, + AC_FOUND_DEVICE, cgd); + + if (status != CAM_REQ_CMP + && status != CAM_REQ_INPROG) + printf("sddaasync: Unable to attach to new device " + "due to status 0x%x\n", status); + break; + } + case AC_GETDEV_CHANGED: + { + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> AC_GETDEV_CHANGED\n")); + softc = (struct sdda_softc *)periph->softc; + xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NORMAL); + cgd.ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)&cgd); + cam_periph_async(periph, code, path, arg); + break; + } + case AC_ADVINFO_CHANGED: + { + uintptr_t buftype; + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> AC_ADVINFO_CHANGED\n")); + buftype = (uintptr_t)arg; + if (buftype == CDAI_TYPE_PHYS_PATH) { + struct sdda_softc *softc; + + softc = periph->softc; + disk_attr_changed(softc->disk, "GEOM::physpath", + M_NOWAIT); + } + break; + } + case AC_SENT_BDR: + case AC_BUS_RESET: + { + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("AC_BUS_RESET")); + } + default: + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> default?!\n")); + cam_periph_async(periph, code, path, arg); + break; + } +} + + +static int +sddagetattr(struct bio *bp) +{ + int ret; + struct cam_periph *periph; + + periph = (struct cam_periph *)bp->bio_disk->d_drv1; + cam_periph_lock(periph); + ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute, + periph->path); + cam_periph_unlock(periph); + if (ret == 0) + bp->bio_completed = bp->bio_length; + return ret; +} + +static cam_status +sddaregister(struct cam_periph *periph, void *arg) +{ + struct sdda_softc *softc; +// struct ccb_pathinq cpi; + struct ccb_getdev *cgd; +// char announce_buf[80], buf1[32]; +// caddr_t match; + union ccb *request_ccb; /* CCB representing the probe request */ + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaregister\n")); + cgd = (struct ccb_getdev *)arg; + if (cgd == NULL) { + printf("sddaregister: no getdev CCB, can't register device\n"); + return(CAM_REQ_CMP_ERR); + } + + softc = (struct sdda_softc *)malloc(sizeof(*softc), M_DEVBUF, + M_NOWAIT|M_ZERO); + + if (softc == NULL) { + printf("sddaregister: Unable to probe new device. " + "Unable to allocate softc\n"); + return(CAM_REQ_CMP_ERR); + } + + bioq_init(&softc->bio_queue); + softc->state = SDDA_STATE_INIT; + softc->mmcdata = + (struct mmc_data *) malloc(sizeof(struct mmc_data), M_DEVBUF, M_NOWAIT|M_ZERO); + periph->softc = softc; + + request_ccb = (union ccb*) arg; + xpt_schedule(periph, CAM_PRIORITY_XPT); + TASK_INIT(&softc->start_init_task, 0, sdda_start_init_task, periph); + taskqueue_enqueue(taskqueue_thread, &softc->start_init_task); + + return (CAM_REQ_CMP); +} + +static cam_status +sdda_hook_into_geom(struct cam_periph *periph) +{ + struct sdda_softc *softc; + struct ccb_pathinq cpi; + struct ccb_getdev cgd; + u_int maxio; + + softc = (struct sdda_softc*) periph->softc; + + bzero(&cpi, sizeof(cpi)); + xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + + bzero(&cgd, sizeof(cgd)); + xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NONE); + cpi.ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)&cgd); + + /* + * Register this media as a disk + */ + (void)cam_periph_hold(periph, PRIBIO); + cam_periph_unlock(periph); + + softc->disk = disk_alloc(); + softc->disk->d_rotation_rate = 0; + softc->disk->d_devstat = devstat_new_entry(periph->periph_name, + periph->unit_number, 512, + DEVSTAT_ALL_SUPPORTED, + DEVSTAT_TYPE_DIRECT | + XPORT_DEVSTAT_TYPE(cpi.transport), + DEVSTAT_PRIORITY_DISK); + softc->disk->d_open = sddaopen; + softc->disk->d_close = sddaclose; + softc->disk->d_strategy = sddastrategy; + softc->disk->d_getattr = sddagetattr; +// softc->disk->d_dump = sddadump; + softc->disk->d_gone = sddadiskgonecb; + softc->disk->d_name = "sdda"; + softc->disk->d_drv1 = periph; + maxio = cpi.maxio; /* Honor max I/O size of SIM */ + if (maxio == 0) + maxio = DFLTPHYS; /* traditional default */ + else if (maxio > MAXPHYS) + maxio = MAXPHYS; /* for safety */ + softc->disk->d_maxsize = maxio; + softc->disk->d_unit = periph->unit_number; + softc->disk->d_flags = DISKFLAG_CANDELETE; + strlcpy(softc->disk->d_descr, softc->card_id_string, + MIN(sizeof(softc->disk->d_descr), sizeof(softc->card_id_string))); + strlcpy(softc->disk->d_ident, softc->card_sn_string, + MIN(sizeof(softc->disk->d_ident), sizeof(softc->card_sn_string))); + softc->disk->d_hba_vendor = cpi.hba_vendor; + softc->disk->d_hba_device = cpi.hba_device; + softc->disk->d_hba_subvendor = cpi.hba_subvendor; + softc->disk->d_hba_subdevice = cpi.hba_subdevice; + + softc->disk->d_sectorsize = 512; + softc->disk->d_mediasize = softc->mediasize; + softc->disk->d_stripesize = 0; + softc->disk->d_fwsectors = 0; + softc->disk->d_fwheads = 0; + + /* + * Acquire a reference to the periph before we register with GEOM. + * We'll release this reference once GEOM calls us back (via + * sddadiskgonecb()) telling us that our provider has been freed. + */ + if (cam_periph_acquire(periph) != CAM_REQ_CMP) { + xpt_print(periph->path, "%s: lost periph during " + "registration!\n", __func__); + cam_periph_lock(periph); + return (CAM_REQ_CMP_ERR); + } + disk_create(softc->disk, DISK_VERSION); + cam_periph_lock(periph); + cam_periph_unhold(periph); + + xpt_announce_periph(periph, softc->card_id_string); + + /* + * Add async callbacks for bus reset and + * bus device reset calls. I don't bother + * checking if this fails as, in most cases, + * the system will function just fine without + * them and the only alternative would be to + * not attach the device on failure. + */ + xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE | + AC_GETDEV_CHANGED | AC_ADVINFO_CHANGED, + sddaasync, periph, periph->path); + + return(CAM_REQ_CMP); +} + +static int +mmc_exec_app_cmd(struct cam_periph *periph, union ccb *ccb, + struct mmc_command *cmd) { + int err; + + /* Send APP_CMD first */ + memset(&ccb->mmcio.cmd, 0, sizeof(struct mmc_command)); + memset(&ccb->mmcio.stop, 0, sizeof(struct mmc_command)); + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ CAM_DIR_NONE, + /*mmc_opcode*/ MMC_APP_CMD, + /*mmc_arg*/ get_rca(periph) << 16, + /*mmc_flags*/ MMC_RSP_R1 | MMC_CMD_AC, + /*mmc_data*/ NULL, + /*timeout*/ 0); + + err = cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + if (err != 0) + return err; + if (!(ccb->mmcio.cmd.resp[0] & R1_APP_CMD)) + return MMC_ERR_FAILED; + + /* Now exec actual command */ + int flags = 0; + if (cmd->data != NULL) { + ccb->mmcio.cmd.data = cmd->data; + if (cmd->data->flags & MMC_DATA_READ) + flags |= CAM_DIR_IN; + if (cmd->data->flags & MMC_DATA_WRITE) + flags |= CAM_DIR_OUT; + } else flags = CAM_DIR_NONE; + + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ flags, + /*mmc_opcode*/ cmd->opcode, + /*mmc_arg*/ cmd->arg, + /*mmc_flags*/ cmd->flags, + /*mmc_data*/ cmd->data, + /*timeout*/ 0); + + err = cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + memcpy(cmd->resp, ccb->mmcio.cmd.resp, sizeof(cmd->resp)); + cmd->error = ccb->mmcio.cmd.error; + if (err != 0) + return err; + return 0; +} + +static int +mmc_app_get_scr(struct cam_periph *periph, union ccb *ccb, uint32_t *rawscr) { + int err; + struct mmc_command cmd; + struct mmc_data d; + + memset(&cmd, 0, sizeof(cmd)); + + memset(rawscr, 0, 8); + cmd.opcode = ACMD_SEND_SCR; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + cmd.arg = 0; + + d.data = rawscr; + d.len = 8; + d.flags = MMC_DATA_READ; + cmd.data = &d; + + err = mmc_exec_app_cmd(periph, ccb, &cmd); + rawscr[0] = be32toh(rawscr[0]); + rawscr[1] = be32toh(rawscr[1]); + return (err); +} + +static int +mmc_send_ext_csd(struct cam_periph *periph, union ccb *ccb, + uint8_t *rawextcsd, size_t buf_len) { + int err; + struct mmc_data d; + + KASSERT(buf_len == 512, ("Buffer for ext csd must be 512 bytes")); + d.data = rawextcsd; + d.len = buf_len; + d.flags = MMC_DATA_READ; + memset(d.data, 0, d.len); + + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ CAM_DIR_IN, + /*mmc_opcode*/ MMC_SEND_EXT_CSD, + /*mmc_arg*/ 0, + /*mmc_flags*/ MMC_RSP_R1 | MMC_CMD_ADTC, + /*mmc_data*/ &d, + /*timeout*/ 0); + + err = cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + if (err != 0) + return err; + if (!(ccb->mmcio.cmd.resp[0] & R1_APP_CMD)) + return MMC_ERR_FAILED; + + return MMC_ERR_NONE; +} + +static void +mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr) +{ + unsigned int scr_struct; + + memset(scr, 0, sizeof(*scr)); + + scr_struct = mmc_get_bits(raw_scr, 64, 60, 4); + if (scr_struct != 0) { + printf("Unrecognised SCR structure version %d\n", + scr_struct); + return; + } + scr->sda_vsn = mmc_get_bits(raw_scr, 64, 56, 4); + scr->bus_widths = mmc_get_bits(raw_scr, 64, 48, 4); +} + +static int +mmc_switch(struct cam_periph *periph, union ccb *ccb, + uint8_t set, uint8_t index, uint8_t value) +{ + int arg = (MMC_SWITCH_FUNC_WR << 24) | + (index << 16) | + (value << 8) | + set; + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ CAM_DIR_NONE, + /*mmc_opcode*/ MMC_SWITCH_FUNC, + /*mmc_arg*/ arg, + /*mmc_flags*/ MMC_RSP_R1B | MMC_CMD_AC, + /*mmc_data*/ NULL, + /*timeout*/ 0); + + cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + + if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { + if (ccb->mmcio.cmd.error != 0) { + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, + ("%s: MMC command failed", __func__)); + return EIO; + } + return 0; /* Normal return */ + } else { + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, + ("%s: CAM request failed\n", __func__)); + return EIO; + } + +} + +static int +mmc_sd_switch(struct cam_periph *periph, union ccb *ccb, + uint8_t mode, uint8_t grp, uint8_t value, + uint8_t *res) { + + struct mmc_data mmc_d; + + memset(res, 0, 64); + mmc_d.len = 64; + mmc_d.data = res; + mmc_d.flags = MMC_DATA_READ; + + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ CAM_DIR_IN, + /*mmc_opcode*/ SD_SWITCH_FUNC, + /*mmc_arg*/ mode << 31, + /*mmc_flags*/ MMC_RSP_R1 | MMC_CMD_ADTC, + /*mmc_data*/ &mmc_d, + /*timeout*/ 0); + + cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + + if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { + if (ccb->mmcio.cmd.error != 0) { + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, + ("%s: MMC command failed", __func__)); + return EIO; + } + return 0; /* Normal return */ + } else { + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, + ("%s: CAM request failed\n", __func__)); + return EIO; + } +} + +static int +mmc_set_timing(struct cam_periph *periph, + union ccb *ccb, + enum mmc_bus_timing timing) +{ + u_char switch_res[64]; + int err; + uint8_t value; + struct mmc_params *mmcp = &periph->path->device->mmc_ident_data; + + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("mmc_set_timing(timing=%d)", timing)); + switch (timing) { + case bus_timing_normal: + value = 0; + break; + case bus_timing_hs: + value = 1; + break; + default: + return (MMC_ERR_INVALID); + } + if (mmcp->card_features & CARD_FEATURE_MMC) { + err = mmc_switch(periph, ccb, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_HS_TIMING, value); + } else { + err = mmc_sd_switch(periph, ccb, SD_SWITCH_MODE_SET, SD_SWITCH_GROUP1, value, switch_res); + } + + /* Set high-speed timing on the host */ + struct ccb_trans_settings_mmc *cts; + cts = &ccb->cts.proto_specific.mmc; + ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + ccb->ccb_h.flags = CAM_DIR_NONE; + ccb->ccb_h.retry_count = 0; + ccb->ccb_h.timeout = 100; + ccb->ccb_h.cbfcnp = NULL; + cts->ios.timing = timing; + cts->ios_valid = MMC_BT; + xpt_action(ccb); + + return (err); +} + +static void +sdda_start_init_task(void *context, int pending) { + union ccb *new_ccb; + struct cam_periph *periph; + + periph = (struct cam_periph *)context; + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sdda_start_init_task\n")); + new_ccb = xpt_alloc_ccb(); + xpt_setup_ccb(&new_ccb->ccb_h, periph->path, + CAM_PRIORITY_NONE); + + cam_periph_lock(periph); + sdda_start_init(context, new_ccb); + cam_periph_unlock(periph); + xpt_free_ccb(new_ccb); +} + +static void +sdda_set_bus_width(struct cam_periph *periph, union ccb *ccb, int width) { + struct mmc_params *mmcp = &periph->path->device->mmc_ident_data; + int err; + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sdda_set_bus_width\n")); + + /* First set for the card, then for the host */ + if (mmcp->card_features & CARD_FEATURE_MMC) { + uint8_t value; + switch (width) { + case bus_width_1: + value = EXT_CSD_BUS_WIDTH_1; + break; + case bus_width_4: + value = EXT_CSD_BUS_WIDTH_4; + break; + case bus_width_8: + value = EXT_CSD_BUS_WIDTH_8; + break; + default: + panic("Invalid bus width %d", width); + } + err = mmc_switch(periph, ccb, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BUS_WIDTH, value); + } else { + /* For SD cards we send ACMD6 with the required bus width in arg */ + struct mmc_command cmd; + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = ACMD_SET_BUS_WIDTH; + cmd.arg = width; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + err = mmc_exec_app_cmd(periph, ccb, &cmd); + } + + if (err != MMC_ERR_NONE) { + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Error %d when setting bus width on the card\n", err)); + return; + } + /* Now card is done, set the host to the same width */ + struct ccb_trans_settings_mmc *cts; + cts = &ccb->cts.proto_specific.mmc; + ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + ccb->ccb_h.flags = CAM_DIR_NONE; + ccb->ccb_h.retry_count = 0; + ccb->ccb_h.timeout = 100; + ccb->ccb_h.cbfcnp = NULL; + cts->ios.bus_width = width; + cts->ios_valid = MMC_BW; + xpt_action(ccb); +} + +static inline const char *bus_width_str(enum mmc_bus_width w) { + switch (w) { + case bus_width_1: + return "1-bit"; + case bus_width_4: + return "4-bit"; + case bus_width_8: + return "8-bit"; + } +} + +static void +sdda_start_init(void *context, union ccb *start_ccb) { + struct cam_periph *periph; + periph = (struct cam_periph *)context; + int err; + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sdda_start_init\n")); + /* periph was held for us when this task was enqueued */ + if ((periph->flags & CAM_PERIPH_INVALID) != 0) { + cam_periph_release(periph); + return; + } + + struct sdda_softc *softc = (struct sdda_softc *)periph->softc; + //struct ccb_mmcio *mmcio = &start_ccb->mmcio; + struct mmc_params *mmcp = &periph->path->device->mmc_ident_data; + struct cam_ed *device = periph->path->device; + + if (mmcp->card_features & CARD_FEATURE_MMC) { + mmc_decode_csd_mmc(mmcp->card_csd, &softc->csd); + mmc_decode_cid_mmc(mmcp->card_cid, &softc->cid); + if (softc->csd.spec_vers >= 4) + err = mmc_send_ext_csd(periph, start_ccb, + (uint8_t *)&softc->raw_ext_csd, + sizeof(softc->raw_ext_csd)); + } else { + mmc_decode_csd_sd(mmcp->card_csd, &softc->csd); + mmc_decode_cid_sd(mmcp->card_cid, &softc->cid); + } + + softc->sector_count = softc->csd.capacity / 512; + softc->mediasize = softc->csd.capacity; + + /* MMC >= 4.x have EXT_CSD that has its own opinion about capacity */ + if (softc->csd.spec_vers >= 4) { + uint32_t sec_count = softc->raw_ext_csd[EXT_CSD_SEC_CNT] + + (softc->raw_ext_csd[EXT_CSD_SEC_CNT + 1] << 8) + + (softc->raw_ext_csd[EXT_CSD_SEC_CNT + 2] << 16) + + (softc->raw_ext_csd[EXT_CSD_SEC_CNT + 3] << 24); + if (sec_count != 0) { + softc->sector_count = sec_count; + softc->mediasize = softc->sector_count * 512; + /* FIXME: there should be a better name for this option...*/ + mmcp->card_features |= CARD_FEATURE_SDHC; + } + + } + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("Capacity: %"PRIu64", sectors: %"PRIu64"\n", + softc->mediasize, + softc->sector_count)); + mmc_format_card_id_string(softc, mmcp); + + /* Update info for CAM */ + device->serial_num_len = strlen(softc->card_sn_string); + device->serial_num = + (u_int8_t *)malloc((device->serial_num_len + 1), + M_CAMXPT, M_NOWAIT); + strlcpy(device->serial_num, softc->card_sn_string, device->serial_num_len); + + device->device_id_len = strlen(softc->card_id_string); + device->device_id = + (u_int8_t *)malloc((device->device_id_len + 1), + M_CAMXPT, M_NOWAIT); + strlcpy(device->device_id, softc->card_id_string, device->device_id_len); + + strlcpy(mmcp->model, softc->card_id_string, sizeof(mmcp->model)); + + /* Set the clock frequency that the card can handle */ + struct ccb_trans_settings_mmc *cts; + cts = &start_ccb->cts.proto_specific.mmc; + + /* First, get the host's max freq */ + start_ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + start_ccb->ccb_h.flags = CAM_DIR_NONE; + start_ccb->ccb_h.retry_count = 0; + start_ccb->ccb_h.timeout = 100; + start_ccb->ccb_h.cbfcnp = NULL; + xpt_action(start_ccb); + + if (start_ccb->ccb_h.status != CAM_REQ_CMP) + panic("Cannot get max host freq"); + int host_f_max = cts->host_f_max; + uint32_t host_caps = cts->host_caps; + if (cts->ios.bus_width != bus_width_1) + panic("Bus width in ios is not 1-bit"); + + /* Now check if the card supports High-speed */ + softc->card_f_max = softc->csd.tran_speed; + + if (host_caps & MMC_CAP_HSPEED) { + /* Find out if the card supports High speed timing */ + if (mmcp->card_features & CARD_FEATURE_SD20) { + /* Get and decode SCR */ + uint32_t rawscr; + uint8_t res[64]; + if (mmc_app_get_scr(periph, start_ccb, &rawscr)) { + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Cannot get SCR\n")); + goto finish_hs_tests; + } + mmc_app_decode_scr(&rawscr, &softc->scr); + + if ((softc->scr.sda_vsn >= 1) && (softc->csd.ccc & (1<<10))) { + mmc_sd_switch(periph, start_ccb, SD_SWITCH_MODE_CHECK, + SD_SWITCH_GROUP1, SD_SWITCH_NOCHANGE, res); + if (res[13] & 2) { + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Card supports HS\n")); + softc->card_f_max = SD_HS_MAX; + } + } else { + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Not trying the switch\n")); + goto finish_hs_tests; + } + } + + if (mmcp->card_features & CARD_FEATURE_MMC && softc->csd.spec_vers >= 4) { + if (softc->raw_ext_csd[EXT_CSD_CARD_TYPE] + & EXT_CSD_CARD_TYPE_HS_52) + softc->card_f_max = MMC_TYPE_HS_52_MAX; + else if (softc->raw_ext_csd[EXT_CSD_CARD_TYPE] + & EXT_CSD_CARD_TYPE_HS_26) + softc->card_f_max = MMC_TYPE_HS_26_MAX; + } + } + int f_max; +finish_hs_tests: + f_max = min(host_f_max, softc->card_f_max); + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Set SD freq to %d MHz (min out of host f=%d MHz and card f=%d MHz)\n", f_max / 1000000, host_f_max / 1000000, softc->card_f_max / 1000000)); + + start_ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + start_ccb->ccb_h.flags = CAM_DIR_NONE; + start_ccb->ccb_h.retry_count = 0; + start_ccb->ccb_h.timeout = 100; + start_ccb->ccb_h.cbfcnp = NULL; + cts->ios.clock = f_max; + cts->ios_valid = MMC_CLK; + xpt_action(start_ccb); + + /* Set bus width */ + enum mmc_bus_width desired_bus_width = bus_width_1; + enum mmc_bus_width max_host_bus_width = + (host_caps & MMC_CAP_8_BIT_DATA ? bus_width_8 : + host_caps & MMC_CAP_4_BIT_DATA ? bus_width_4 : bus_width_1); + enum mmc_bus_width max_card_bus_width = bus_width_1; + if (mmcp->card_features & CARD_FEATURE_SD20 && + softc->scr.bus_widths & SD_SCR_BUS_WIDTH_4) + max_card_bus_width = bus_width_4; + /* + * Unlike SD, MMC cards don't have any information about supported bus width... + * So we need to perform read/write test to find out the width. + */ + /* TODO: figure out bus width for MMC; use 8-bit for now (to test on BBB) */ + if (mmcp->card_features & CARD_FEATURE_MMC) + max_card_bus_width = bus_width_8; + + desired_bus_width = min(max_host_bus_width, max_card_bus_width); + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("Set bus width to %s (min of host %s and card %s)\n", + bus_width_str(desired_bus_width), + bus_width_str(max_host_bus_width), + bus_width_str(max_card_bus_width))); + sdda_set_bus_width(periph, start_ccb, desired_bus_width); + + if (f_max > 25000000) { + err = mmc_set_timing(periph, start_ccb, bus_timing_hs); + if (err != MMC_ERR_NONE) + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("Cannot switch card to high-speed mode")); + } + softc->state = SDDA_STATE_NORMAL; + sdda_hook_into_geom(periph); +} + +/* Called with periph lock held! */ +static void +sddastart(struct cam_periph *periph, union ccb *start_ccb) +{ + struct sdda_softc *softc = (struct sdda_softc *)periph->softc; + struct mmc_params *mmcp = &periph->path->device->mmc_ident_data; + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddastart\n")); + + if (softc->state != SDDA_STATE_NORMAL) { + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("device is not in SDDA_STATE_NORMAL yet")); + xpt_release_ccb(start_ccb); + return; + } + struct bio *bp; + + /* Run regular command. */ + bp = bioq_first(&softc->bio_queue); + if (bp == NULL) { + xpt_release_ccb(start_ccb); + return; + } + bioq_remove(&softc->bio_queue, bp); + + switch (bp->bio_cmd) { + case BIO_WRITE: + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_WRITE\n")); + softc->flags |= SDDA_FLAG_DIRTY; + /* FALLTHROUGH */ + case BIO_READ: + { + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_READ\n")); + uint64_t blockno = bp->bio_pblkno; + uint16_t count = bp->bio_bcount / 512; + uint16_t opcode; + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("Block %"PRIu64" cnt %u\n", blockno, count)); + + /* Construct new MMC command */ + if (bp->bio_cmd == BIO_READ) { + if (count > 1) + opcode = MMC_READ_MULTIPLE_BLOCK; + else + opcode = MMC_READ_SINGLE_BLOCK; + } else { + if (count > 1) + opcode = MMC_WRITE_MULTIPLE_BLOCK; + else + opcode = MMC_WRITE_BLOCK; + } + + start_ccb->ccb_h.func_code = XPT_MMC_IO; + start_ccb->ccb_h.flags = (bp->bio_cmd == BIO_READ ? CAM_DIR_IN : CAM_DIR_OUT); + start_ccb->ccb_h.retry_count = 0; + start_ccb->ccb_h.timeout = 15 * 1000; + start_ccb->ccb_h.cbfcnp = sddadone; + struct ccb_mmcio *mmcio; + + mmcio = &start_ccb->mmcio; + mmcio->cmd.opcode = opcode; + mmcio->cmd.arg = blockno; + if (!(mmcp->card_features & CARD_FEATURE_SDHC)) + mmcio->cmd.arg <<= 9; + + mmcio->cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + mmcio->cmd.data = softc->mmcdata; + mmcio->cmd.data->data = bp->bio_data; + mmcio->cmd.data->len = 512 * count; + mmcio->cmd.data->flags = (bp->bio_cmd == BIO_READ ? MMC_DATA_READ : MMC_DATA_WRITE); + /* Direct h/w to issue CMD12 upon completion */ + if (count > 1) { + mmcio->stop.opcode = MMC_STOP_TRANSMISSION; + mmcio->stop.flags = MMC_RSP_R1B | MMC_CMD_AC; + mmcio->stop.arg = 0; + } + + break; + } + case BIO_FLUSH: + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_FLUSH\n")); + sddaschedule(periph); + break; + case BIO_DELETE: + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_DELETE\n")); + sddaschedule(periph); + break; + } + start_ccb->ccb_h.ccb_bp = bp; + softc->outstanding_cmds++; + softc->refcount++; + cam_periph_unlock(periph); + xpt_action(start_ccb); + cam_periph_lock(periph); + softc->refcount--; + + /* May have more work to do, so ensure we stay scheduled */ + sddaschedule(periph); +} + +static void +sddadone(struct cam_periph *periph, union ccb *done_ccb) +{ + struct sdda_softc *softc; + struct ccb_mmcio *mmcio; +// struct ccb_getdev *cgd; + struct cam_path *path; +// int state; + + softc = (struct sdda_softc *)periph->softc; + mmcio = &done_ccb->mmcio; + path = done_ccb->ccb_h.path; + + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("sddadone\n")); + + struct bio *bp; + int error = 0; + +// cam_periph_lock(periph); + if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("Error!!!\n")); + if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) + cam_release_devq(path, + /*relsim_flags*/0, + /*reduction*/0, + /*timeout*/0, + /*getcount_only*/0); + error = 5; /* EIO */ + } else { + if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) + panic("REQ_CMP with QFRZN"); + error = 0; + } + + + bp = (struct bio *)done_ccb->ccb_h.ccb_bp; + bp->bio_error = error; + if (error != 0) { + bp->bio_resid = bp->bio_bcount; + bp->bio_flags |= BIO_ERROR; + } else { + /* XXX: How many bytes remaining? */ + bp->bio_resid = 0; + if (bp->bio_resid > 0) + bp->bio_flags |= BIO_ERROR; + } + + uint32_t card_status = mmcio->cmd.resp[0]; + CAM_DEBUG(path, CAM_DEBUG_TRACE, + ("Card status: %08x\n", R1_STATUS(card_status))); + CAM_DEBUG(path, CAM_DEBUG_TRACE, + ("Current state: %d\n", R1_CURRENT_STATE(card_status))); + + softc->outstanding_cmds--; + xpt_release_ccb(done_ccb); + biodone(bp); +} + +static int +sddaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) +{ + return(cam_periph_error(ccb, cam_flags, sense_flags, NULL)); +} +#endif /* _KERNEL */ diff --git a/sys/cam/mmc/mmc_sdio.c b/sys/cam/mmc/mmc_sdio.c new file mode 100644 index 000000000000..093da15d6fac --- /dev/null +++ b/sys/cam/mmc/mmc_sdio.c @@ -0,0 +1,126 @@ +/*- + * Copyright (c) 2015 Ilya Bakulin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include /* for xpt_print below */ +#include /* for PRIu64 */ +#include "opt_cam.h" + + +void +sdio_print_stupid_message(struct cam_periph *periph) { + + CAM_DEBUG(periph->path, CAM_DEBUG_INFO, + ("%s\n", __func__)); +} + +/* + * f - function to read from / write to + * wr - is write + * adr - address to r/w + * data - actual data to write + */ +void sdio_fill_mmcio_rw_direct(union ccb *ccb, uint8_t f, uint8_t wr, uint32_t adr, uint8_t *data) { + struct ccb_mmcio *mmcio; + + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("sdio_fill_mmcio(f=%d, wr=%d, adr=%02x, data=%02x)\n", f, wr, adr, (data == NULL ? 0 : *data))); + mmcio = &ccb->mmcio; + + mmcio->cmd.opcode = SD_IO_RW_DIRECT; + mmcio->cmd.arg = SD_IO_RW_FUNC(f) | SD_IO_RW_ADR(adr); + if (wr) + mmcio->cmd.arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(*data); + mmcio->cmd.flags = MMC_RSP_R5 | MMC_CMD_AC; + mmcio->cmd.data->len = 0; +} + +uint8_t sdio_parse_mmcio_rw_direct(union ccb *ccb, uint8_t *data) { + struct ccb_mmcio *mmcio; + + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("sdio_parse_mmcio(datap=%p)\n", data)); + mmcio = &ccb->mmcio; + + if (mmcio->cmd.error) + return (mmcio->cmd.error); + if (mmcio->cmd.resp[0] & R5_COM_CRC_ERROR) + return (MMC_ERR_BADCRC); + if (mmcio->cmd.resp[0] & (R5_ILLEGAL_COMMAND | R5_FUNCTION_NUMBER)) + return (MMC_ERR_INVALID); + if (mmcio->cmd.resp[0] & R5_OUT_OF_RANGE) + return (MMC_ERR_FAILED); + + /* Just for information... */ + if (R5_IO_CURRENT_STATE(mmcio->cmd.resp[0]) != 1) + printf("!!! SDIO state %d\n", R5_IO_CURRENT_STATE(mmcio->cmd.resp[0])); + + if (mmcio->cmd.resp[0] & R5_ERROR) + printf("An error was detected!\n"); + + if (mmcio->cmd.resp[0] & R5_COM_CRC_ERROR) + printf("A CRC error was detected!\n"); + + if (data != NULL) + *data = (uint8_t) (mmcio->cmd.resp[0] & 0xff); + return (MMC_ERR_NONE); + +} diff --git a/sys/cam/mmc/mmc_sdio.h b/sys/cam/mmc/mmc_sdio.h new file mode 100644 index 000000000000..6d22ffc02c13 --- /dev/null +++ b/sys/cam/mmc/mmc_sdio.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2014 Ilya Bakulin. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Portions of this software may have been developed with reference to + * the SD Simplified Specification. The following disclaimer may apply: + * + * The following conditions apply to the release of the simplified + * specification ("Simplified Specification") by the SD Card Association and + * the SD Group. The Simplified Specification is a subset of the complete SD + * Specification which is owned by the SD Card Association and the SD + * Group. This Simplified Specification is provided on a non-confidential + * basis subject to the disclaimers below. Any implementation of the + * Simplified Specification may require a license from the SD Card + * Association, SD Group, SD-3C LLC or other third parties. + * + * Disclaimers: + * + * The information contained in the Simplified Specification is presented only + * as a standard specification for SD Cards and SD Host/Ancillary products and + * is provided "AS-IS" without any representations or warranties of any + * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD + * Card Association for any damages, any infringements of patents or other + * right of the SD Group, SD-3C LLC, the SD Card Association or any third + * parties, which may result from its use. No license is granted by + * implication, estoppel or otherwise under any patent or other rights of the + * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing + * herein shall be construed as an obligation by the SD Group, the SD-3C LLC + * or the SD Card Association to disclose or distribute any technical + * information, know-how or other confidential information to any third party. + * + * $FreeBSD$ + */ + +/* + * Various SDIO-related stuff + */ + +#ifndef CAM_MMC_SDIO_H +#define CAM_MMC_SDIO_H + +void sdio_print_stupid_message(struct cam_periph *periph); +void sdio_fill_mmcio_rw_direct(union ccb *ccb, uint8_t f, uint8_t wr, uint32_t adr, uint8_t *data); +uint8_t sdio_parse_mmcio_rw_direct(union ccb *ccb, uint8_t *data); +#endif diff --git a/sys/cam/mmc/mmc_xpt.c b/sys/cam/mmc/mmc_xpt.c new file mode 100644 index 000000000000..0142a6f07916 --- /dev/null +++ b/sys/cam/mmc/mmc_xpt.c @@ -0,0 +1,1077 @@ +/*- + * Copyright (c) 2013,2014 Ilya Bakulin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include /* for xpt_print below */ +#include /* for PRIu64 */ +#include "opt_cam.h" + +static struct cam_ed * mmc_alloc_device(struct cam_eb *bus, + struct cam_et *target, lun_id_t lun_id); +static void mmc_dev_async(u_int32_t async_code, struct cam_eb *bus, + struct cam_et *target, struct cam_ed *device, void *async_arg); +static void mmc_action(union ccb *start_ccb); +static void mmc_dev_advinfo(union ccb *start_ccb); +static void mmc_announce_periph(struct cam_periph *periph); +static void mmc_scan_lun(struct cam_periph *periph, + struct cam_path *path, cam_flags flags, union ccb *ccb); + +/* mmcprobe methods */ +static cam_status mmcprobe_register(struct cam_periph *periph, void *arg); +static void mmcprobe_start(struct cam_periph *periph, union ccb *start_ccb); +static void mmcprobe_cleanup(struct cam_periph *periph); +static void mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb); + +static void mmc_proto_announce(struct cam_ed *device); +static void mmc_proto_denounce(struct cam_ed *device); +static void mmc_proto_debug_out(union ccb *ccb); + +typedef enum { + PROBE_RESET, + PROBE_IDENTIFY, + PROBE_SDIO_RESET, + PROBE_SEND_IF_COND, + PROBE_SDIO_INIT, + PROBE_MMC_INIT, + PROBE_SEND_APP_OP_COND, + PROBE_GET_CID, + PROBE_GET_CSD, + PROBE_SEND_RELATIVE_ADDR, + PROBE_SELECT_CARD, + PROBE_DONE, + PROBE_INVALID +} probe_action; + +static char *probe_action_text[] = { + "PROBE_RESET", + "PROBE_IDENTIFY", + "PROBE_SDIO_RESET", + "PROBE_SEND_IF_COND", + "PROBE_SDIO_INIT", + "PROBE_MMC_INIT", + "PROBE_SEND_APP_OP_COND", + "PROBE_GET_CID", + "PROBE_GET_CSD", + "PROBE_SEND_RELATIVE_ADDR", + "PROBE_SELECT_CARD", + "PROBE_DONE", + "PROBE_INVALID" +}; + +#define PROBE_SET_ACTION(softc, newaction) \ +do { \ + char **text; \ + text = probe_action_text; \ + CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE, \ + ("Probe %s to %s\n", text[(softc)->action], \ + text[(newaction)])); \ + (softc)->action = (newaction); \ +} while(0) + +static struct xpt_xport_ops mmc_xport_ops = { + .alloc_device = mmc_alloc_device, + .action = mmc_action, + .async = mmc_dev_async, + .announce = mmc_announce_periph, +}; + +#define MMC_XPT_XPORT(x, X) \ + static struct xpt_xport mmc_xport_ ## x = { \ + .xport = XPORT_ ## X, \ + .name = #x, \ + .ops = &mmc_xport_ops, \ + }; \ + CAM_XPT_XPORT(mmc_xport_ ## x); + +MMC_XPT_XPORT(mmc, MMCSD); + +static struct xpt_proto_ops mmc_proto_ops = { + .announce = mmc_proto_announce, + .denounce = mmc_proto_denounce, + .debug_out = mmc_proto_debug_out, +}; + +static struct xpt_proto mmc_proto = { + .proto = PROTO_MMCSD, + .name = "mmcsd", + .ops = &mmc_proto_ops, +}; +CAM_XPT_PROTO(mmc_proto); + +typedef struct { + probe_action action; + int restart; + union ccb saved_ccb; + uint32_t flags; +#define PROBE_FLAG_ACMD_SENT 0x1 /* CMD55 is sent, card expects ACMD */ + struct cam_periph *periph; +} mmcprobe_softc; + +/* XPort functions -- an interface to CAM at periph side */ + +static struct cam_ed * +mmc_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id) +{ + struct cam_ed *device; + + printf("mmc_alloc_device()\n"); + device = xpt_alloc_device(bus, target, lun_id); + if (device == NULL) + return (NULL); + + device->quirk = NULL; + device->mintags = 0; + device->maxtags = 0; + bzero(&device->inq_data, sizeof(device->inq_data)); + device->inq_flags = 0; + device->queue_flags = 0; + device->serial_num = NULL; + device->serial_num_len = 0; + return (device); +} + +static void +mmc_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, + struct cam_ed *device, void *async_arg) +{ + + printf("mmc_dev_async(async_code=0x%x, path_id=%d, target_id=%x, lun_id=%" SCNx64 "\n", + async_code, + bus->path_id, + target->target_id, + device->lun_id); + /* + * We only need to handle events for real devices. + */ + if (target->target_id == CAM_TARGET_WILDCARD + || device->lun_id == CAM_LUN_WILDCARD) + return; + + if (async_code == AC_LOST_DEVICE) { + if ((device->flags & CAM_DEV_UNCONFIGURED) == 0) { + printf("AC_LOST_DEVICE -> set to unconfigured\n"); + device->flags |= CAM_DEV_UNCONFIGURED; + xpt_release_device(device); + } else { + printf("AC_LOST_DEVICE on unconfigured device\n"); + } + } else if (async_code == AC_FOUND_DEVICE) { + printf("Got AC_FOUND_DEVICE -- whatever...\n"); + } else if (async_code == AC_PATH_REGISTERED) { + printf("Got AC_PATH_REGISTERED -- whatever...\n"); + } else if (async_code == AC_PATH_DEREGISTERED ) { + printf("Got AC_PATH_DEREGISTERED -- whatever...\n"); + } else + panic("Unknown async code\n"); +} + +/* Taken from nvme_scan_lun, thanks to bsdimp@ */ +static void +mmc_scan_lun(struct cam_periph *periph, struct cam_path *path, + cam_flags flags, union ccb *request_ccb) +{ + struct ccb_pathinq cpi; + cam_status status; + struct cam_periph *old_periph; + int lock; + + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("mmc_scan_lun\n")); + + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + + if (cpi.ccb_h.status != CAM_REQ_CMP) { + if (request_ccb != NULL) { + request_ccb->ccb_h.status = cpi.ccb_h.status; + xpt_done(request_ccb); + } + return; + } + + if (xpt_path_lun_id(path) == CAM_LUN_WILDCARD) { + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("mmd_scan_lun ignoring bus\n")); + request_ccb->ccb_h.status = CAM_REQ_CMP; /* XXX signal error ? */ + xpt_done(request_ccb); + return; + } + + lock = (xpt_path_owned(path) == 0); + if (lock) + xpt_path_lock(path); + + if ((old_periph = cam_periph_find(path, "mmcprobe")) != NULL) { + if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) { +// mmcprobe_softc *softc; +// softc = (mmcprobe_softc *)old_periph->softc; +// Not sure if we need request ccb queue for mmc +// TAILQ_INSERT_TAIL(&softc->request_ccbs, +// &request_ccb->ccb_h, periph_links.tqe); +// softc->restart = 1; + CAM_DEBUG(path, CAM_DEBUG_INFO, + ("Got scan request, but mmcprobe already exists\n")); + request_ccb->ccb_h.status = CAM_REQ_CMP_ERR; + xpt_done(request_ccb); + } else { + request_ccb->ccb_h.status = CAM_REQ_CMP_ERR; + xpt_done(request_ccb); + } + } else { + xpt_print(path, " Set up the mmcprobe device...\n"); + + status = cam_periph_alloc(mmcprobe_register, NULL, + mmcprobe_cleanup, + mmcprobe_start, + "mmcprobe", + CAM_PERIPH_BIO, + path, NULL, 0, + request_ccb); + if (status != CAM_REQ_CMP) { + xpt_print(path, "xpt_scan_lun: cam_alloc_periph " + "returned an error, can't continue probe\n"); + } + request_ccb->ccb_h.status = status; + xpt_done(request_ccb); + } + + if (lock) + xpt_path_unlock(path); +} + +static void +mmc_action(union ccb *start_ccb) +{ + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, + ("mmc_action! func_code=%x, action %s\n", start_ccb->ccb_h.func_code, + xpt_action_name(start_ccb->ccb_h.func_code))); + switch (start_ccb->ccb_h.func_code) { + + case XPT_SCAN_BUS: + /* FALLTHROUGH */ + case XPT_SCAN_TGT: + /* FALLTHROUGH */ + case XPT_SCAN_LUN: + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, + ("XPT_SCAN_{BUS,TGT,LUN}\n")); + mmc_scan_lun(start_ccb->ccb_h.path->periph, + start_ccb->ccb_h.path, start_ccb->crcn.flags, + start_ccb); + break; + + case XPT_DEV_ADVINFO: + { + mmc_dev_advinfo(start_ccb); + break; + } + + default: + xpt_action_default(start_ccb); + break; + } +} + +static void +mmc_dev_advinfo(union ccb *start_ccb) +{ + struct cam_ed *device; + struct ccb_dev_advinfo *cdai; + off_t amt; + + start_ccb->ccb_h.status = CAM_REQ_INVALID; + device = start_ccb->ccb_h.path->device; + cdai = &start_ccb->cdai; + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("%s: request %x\n", __func__, cdai->buftype)); + + /* We don't support writing any data */ + if (cdai->flags & CDAI_FLAG_STORE) + panic("Attempt to store data?!"); + + switch(cdai->buftype) { + case CDAI_TYPE_SCSI_DEVID: + cdai->provsiz = device->device_id_len; + if (device->device_id_len == 0) + break; + amt = MIN(cdai->provsiz, cdai->bufsiz); + memcpy(cdai->buf, device->device_id, amt); + break; + case CDAI_TYPE_SERIAL_NUM: + cdai->provsiz = device->serial_num_len; + if (device->serial_num_len == 0) + break; + amt = MIN(cdai->provsiz, cdai->bufsiz); + memcpy(cdai->buf, device->serial_num, amt); + break; + case CDAI_TYPE_PHYS_PATH: /* pass(4) wants this */ + cdai->provsiz = 0; + break; + default: + panic("Unknown buftype"); + return; + } + start_ccb->ccb_h.status = CAM_REQ_CMP; +} + +static void +mmc_announce_periph(struct cam_periph *periph) +{ + struct ccb_pathinq cpi; + struct ccb_trans_settings cts; + struct cam_path *path = periph->path; + + cam_periph_assert(periph, MA_OWNED); + + CAM_DEBUG(periph->path, CAM_DEBUG_INFO, + ("mmc_announce_periph: called\n")); + + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + cts.type = CTS_TYPE_CURRENT_SETTINGS; + xpt_action((union ccb*)&cts); + if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) + return; + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + printf("XPT info: CLK %04X, ...\n", cts.proto_specific.mmc.ios.clock); +} + +/* This func is called per attached device :-( */ +void +mmc_print_ident(struct mmc_params *ident_data) +{ + printf("Relative addr: %08x\n", ident_data->card_rca); + printf("Card features: <"); + if (ident_data->card_features & CARD_FEATURE_MMC) + printf("MMC "); + if (ident_data->card_features & CARD_FEATURE_MEMORY) + printf("Memory "); + if (ident_data->card_features & CARD_FEATURE_SDHC) + printf("High-Capacity "); + if (ident_data->card_features & CARD_FEATURE_SD20) + printf("SD2.0-Conditions "); + if (ident_data->card_features & CARD_FEATURE_SDIO) + printf("SDIO "); + printf(">\n"); + + if (ident_data->card_features & CARD_FEATURE_MEMORY) + printf("Card memory OCR: %08x\n", ident_data->card_ocr); + + if (ident_data->card_features & CARD_FEATURE_SDIO) { + printf("Card IO OCR: %08x\n", ident_data->io_ocr); + printf("Number of funcitions: %u\n", ident_data->sdio_func_count); + } +} + +static void +mmc_proto_announce(struct cam_ed *device) +{ + mmc_print_ident(&device->mmc_ident_data); +} + +static void +mmc_proto_denounce(struct cam_ed *device) +{ + mmc_print_ident(&device->mmc_ident_data); +} + +static void +mmc_proto_debug_out(union ccb *ccb) +{ + if (ccb->ccb_h.func_code != XPT_MMC_IO) + return; + + CAM_DEBUG(ccb->ccb_h.path, + CAM_DEBUG_CDB,("mmc_proto_debug_out\n")); +} + +static periph_init_t probe_periph_init; + +static struct periph_driver probe_driver = +{ + probe_periph_init, "mmcprobe", + TAILQ_HEAD_INITIALIZER(probe_driver.units), /* generation */ 0, + CAM_PERIPH_DRV_EARLY +}; + +PERIPHDRIVER_DECLARE(mmcprobe, probe_driver); + +#define CARD_ID_FREQUENCY 400000 /* Spec requires 400kHz max during ID phase. */ + +static void +probe_periph_init() +{ +} + +static cam_status +mmcprobe_register(struct cam_periph *periph, void *arg) +{ + union ccb *request_ccb; /* CCB representing the probe request */ + cam_status status; + mmcprobe_softc *softc; + + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("mmcprobe_register\n")); + + request_ccb = (union ccb *)arg; + if (request_ccb == NULL) { + printf("mmcprobe_register: no probe CCB, " + "can't register device\n"); + return(CAM_REQ_CMP_ERR); + } + + softc = (mmcprobe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_NOWAIT); + + if (softc == NULL) { + printf("proberegister: Unable to probe new device. " + "Unable to allocate softc\n"); + return(CAM_REQ_CMP_ERR); + } + + softc->flags = 0; + periph->softc = softc; + softc->periph = periph; + softc->action = PROBE_INVALID; + softc->restart = 0; + status = cam_periph_acquire(periph); + + memset(&periph->path->device->mmc_ident_data, 0, sizeof(struct mmc_params)); + if (status != CAM_REQ_CMP) { + printf("proberegister: cam_periph_acquire failed (status=%d)\n", + status); + return (status); + } + CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n")); + + if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) + PROBE_SET_ACTION(softc, PROBE_RESET); + else + PROBE_SET_ACTION(softc, PROBE_IDENTIFY); + + /* This will kick the ball */ + xpt_schedule(periph, CAM_PRIORITY_XPT); + + return(CAM_REQ_CMP); +} + +static int +mmc_highest_voltage(uint32_t ocr) +{ + int i; + + for (i = MMC_OCR_MAX_VOLTAGE_SHIFT; + i >= MMC_OCR_MIN_VOLTAGE_SHIFT; i--) + if (ocr & (1 << i)) + return (i); + return (-1); +} + +static inline void +init_standard_ccb(union ccb *ccb, uint32_t cmd) +{ + ccb->ccb_h.func_code = cmd; + ccb->ccb_h.flags = CAM_DIR_OUT; + ccb->ccb_h.retry_count = 0; + ccb->ccb_h.timeout = 15 * 1000; + ccb->ccb_h.cbfcnp = mmcprobe_done; +} + +static void +mmcprobe_start(struct cam_periph *periph, union ccb *start_ccb) +{ + mmcprobe_softc *softc; + struct cam_path *path; + struct ccb_mmcio *mmcio; + struct mtx *p_mtx = cam_periph_mtx(periph); + struct ccb_trans_settings_mmc *cts; + + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("mmcprobe_start\n")); + softc = (mmcprobe_softc *)periph->softc; + path = start_ccb->ccb_h.path; + mmcio = &start_ccb->mmcio; + cts = &start_ccb->cts.proto_specific.mmc; + struct mmc_params *mmcp = &path->device->mmc_ident_data; + + memset(&mmcio->cmd, 0, sizeof(struct mmc_command)); + + if (softc->restart) { + softc->restart = 0; + if (path->device->flags & CAM_DEV_UNCONFIGURED) + softc->action = PROBE_RESET; + else + softc->action = PROBE_IDENTIFY; + + } + + /* Here is the place where the identify fun begins */ + switch (softc->action) { + case PROBE_RESET: + /* FALLTHROUGH */ + case PROBE_IDENTIFY: + init_standard_ccb(start_ccb, XPT_PATH_INQ); + xpt_action(start_ccb); + + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("Start with PROBE_RESET\n")); + init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS); + cts->ios.power_mode = power_off; + cts->ios_valid = MMC_PM; + xpt_action(start_ccb); + mtx_sleep(periph, p_mtx, 0, "mmcios", 100); + + /* mmc_power_up */ + /* Get the host OCR */ + init_standard_ccb(start_ccb, XPT_GET_TRAN_SETTINGS); + xpt_action(start_ccb); + + uint32_t hv = mmc_highest_voltage(cts->host_ocr); + init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS); + cts->ios.vdd = hv; + cts->ios.bus_mode = opendrain; + cts->ios.chip_select = cs_dontcare; + cts->ios.power_mode = power_up; + cts->ios.bus_width = bus_width_1; + cts->ios.clock = 0; + cts->ios_valid = MMC_VDD | MMC_PM | MMC_BM | + MMC_CS | MMC_BW | MMC_CLK; + xpt_action(start_ccb); + mtx_sleep(periph, p_mtx, 0, "mmcios", 100); + + init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS); + cts->ios.power_mode = power_on; + cts->ios.clock = CARD_ID_FREQUENCY; + cts->ios.timing = bus_timing_normal; + cts->ios_valid = MMC_PM | MMC_CLK | MMC_BT; + xpt_action(start_ccb); + mtx_sleep(periph, p_mtx, 0, "mmcios", 100); + /* End for mmc_power_on */ + + /* Begin mmc_idle_cards() */ + init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS); + cts->ios.chip_select = cs_high; + cts->ios_valid = MMC_CS; + xpt_action(start_ccb); + mtx_sleep(periph, p_mtx, 0, "mmcios", 1); + + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("Send first XPT_MMC_IO\n")); + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = MMC_GO_IDLE_STATE; /* CMD 0 */ + mmcio->cmd.arg = 0; + mmcio->cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; + mmcio->cmd.data = NULL; + mmcio->stop.opcode = 0; + + /* XXX Reset I/O portion as well */ + break; + case PROBE_SDIO_RESET: + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Start with PROBE_SDIO_RESET\n")); + uint32_t mmc_arg = SD_IO_RW_ADR(SD_IO_CCCR_CTL) + | SD_IO_RW_DAT(CCCR_CTL_RES) | SD_IO_RW_WR | SD_IO_RW_RAW; + cam_fill_mmcio(&start_ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ mmcprobe_done, + /*flags*/ CAM_DIR_NONE, + /*mmc_opcode*/ SD_IO_RW_DIRECT, + /*mmc_arg*/ mmc_arg, + /*mmc_flags*/ MMC_RSP_R5 | MMC_CMD_AC, + /*mmc_data*/ NULL, + /*timeout*/ 1000); + break; + case PROBE_SEND_IF_COND: + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Start with PROBE_SEND_IF_COND\n")); + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = SD_SEND_IF_COND; /* CMD 8 */ + mmcio->cmd.arg = (1 << 8) + 0xAA; + mmcio->cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; + mmcio->stop.opcode = 0; + break; + + case PROBE_SDIO_INIT: + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Start with PROBE_SDIO_INIT\n")); + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = IO_SEND_OP_COND; /* CMD 5 */ + mmcio->cmd.arg = mmcp->io_ocr; + mmcio->cmd.flags = MMC_RSP_R4; + mmcio->stop.opcode = 0; + break; + + case PROBE_MMC_INIT: + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Start with PROBE_MMC_INIT\n")); + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = MMC_SEND_OP_COND; /* CMD 1 */ + mmcio->cmd.arg = MMC_OCR_CCS | mmcp->card_ocr; /* CCS + ocr */; + mmcio->cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; + mmcio->stop.opcode = 0; + break; + + case PROBE_SEND_APP_OP_COND: + init_standard_ccb(start_ccb, XPT_MMC_IO); + if (softc->flags & PROBE_FLAG_ACMD_SENT) { + mmcio->cmd.opcode = ACMD_SD_SEND_OP_COND; /* CMD 41 */ + /* + * We set CCS bit because we do support SDHC cards. + * XXX: Don't set CCS if no response to CMD8. + */ + mmcio->cmd.arg = MMC_OCR_CCS | mmcp->card_ocr; /* CCS + ocr */ + mmcio->cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; + } else { + mmcio->cmd.opcode = MMC_APP_CMD; /* CMD 55 */ + mmcio->cmd.arg = 0; /* rca << 16 */ + mmcio->cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + } + mmcio->stop.opcode = 0; + break; + + case PROBE_GET_CID: /* XXX move to mmc_da */ + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = MMC_ALL_SEND_CID; + mmcio->cmd.arg = 0; + mmcio->cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; + mmcio->stop.opcode = 0; + break; + + case PROBE_SEND_RELATIVE_ADDR: + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = SD_SEND_RELATIVE_ADDR; + mmcio->cmd.arg = 0; + mmcio->cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; + mmcio->stop.opcode = 0; + break; + case PROBE_SELECT_CARD: + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = MMC_SELECT_CARD; + mmcio->cmd.arg = (uint32_t)path->device->mmc_ident_data.card_rca << 16; + mmcio->cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; + mmcio->stop.opcode = 0; + break; + case PROBE_GET_CSD: /* XXX move to mmc_da */ + init_standard_ccb(start_ccb, XPT_MMC_IO); + mmcio->cmd.opcode = MMC_SEND_CSD; + mmcio->cmd.arg = (uint32_t)path->device->mmc_ident_data.card_rca << 16; + mmcio->cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; + mmcio->stop.opcode = 0; + break; + case PROBE_DONE: + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("Start with PROBE_DONE\n")); + init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS); + cts->ios.bus_mode = pushpull; + cts->ios_valid = MMC_BM; + xpt_action(start_ccb); + return; + /* NOTREACHED */ + break; + case PROBE_INVALID: + break; + default: + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("probestart: invalid action state 0x%x\n", softc->action)); + panic("default: case in mmc_probe_start()"); + } + + start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; + xpt_action(start_ccb); +} + +static void mmcprobe_cleanup(struct cam_periph *periph) +{ + free(periph->softc, M_CAMXPT); +} + +static void +mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb) +{ + mmcprobe_softc *softc; + struct cam_path *path; + + int err; + struct ccb_mmcio *mmcio; + u_int32_t priority; + + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("mmcprobe_done\n")); + softc = (mmcprobe_softc *)periph->softc; + path = done_ccb->ccb_h.path; + priority = done_ccb->ccb_h.pinfo.priority; + + switch (softc->action) { + case PROBE_RESET: + /* FALLTHROUGH */ + case PROBE_IDENTIFY: + { + printf("Starting completion of PROBE_RESET\n"); + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_RESET\n")); + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + + if (err != MMC_ERR_NONE) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("GO_IDLE_STATE failed with error %d\n", + err)); + + /* There was a device there, but now it's gone... */ + if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { + xpt_async(AC_LOST_DEVICE, path, NULL); + PROBE_SET_ACTION(softc, PROBE_INVALID); + } + } + path->device->protocol = PROTO_MMCSD; + PROBE_SET_ACTION(softc, PROBE_SEND_IF_COND); + break; + } + case PROBE_SEND_IF_COND: + { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + struct mmc_params *mmcp = &path->device->mmc_ident_data; + + if (err != MMC_ERR_NONE || mmcio->cmd.resp[0] != 0x1AA) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("IF_COND: error %d, pattern %08x\n", + err, mmcio->cmd.resp[0])); + } else { + mmcp->card_features |= CARD_FEATURE_SD20; + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("SD 2.0 interface conditions: OK\n")); + + } + PROBE_SET_ACTION(softc, PROBE_SDIO_RESET); + break; + } + case PROBE_SDIO_RESET: + { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("SDIO_RESET: error %d, CCCR CTL register: %08x\n", + err, mmcio->cmd.resp[0])); + PROBE_SET_ACTION(softc, PROBE_SDIO_INIT); + break; + } + case PROBE_SDIO_INIT: + { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + struct mmc_params *mmcp = &path->device->mmc_ident_data; + + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("SDIO_INIT: error %d, %08x %08x %08x %08x\n", + err, mmcio->cmd.resp[0], + mmcio->cmd.resp[1], + mmcio->cmd.resp[2], + mmcio->cmd.resp[3])); + + /* + * Error here means that this card is not SDIO, + * so proceed with memory init as if nothing has happened + */ + if (err != MMC_ERR_NONE) { + PROBE_SET_ACTION(softc, PROBE_SEND_APP_OP_COND); + break; + } + mmcp->card_features |= CARD_FEATURE_SDIO; + uint32_t ioifcond = mmcio->cmd.resp[0]; + uint32_t io_ocr = ioifcond & R4_IO_OCR_MASK; + + mmcp->sdio_func_count = R4_IO_NUM_FUNCTIONS(ioifcond); + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("SDIO card: %d functions\n", mmcp->sdio_func_count)); + if (io_ocr == 0) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("SDIO OCR invalid?!\n")); + break; /* Retry */ + } + + if (io_ocr != 0 && mmcp->io_ocr == 0) { + mmcp->io_ocr = io_ocr; + break; /* Retry, this time with non-0 OCR */ + } + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("SDIO OCR: %08x\n", mmcp->io_ocr)); + + if (ioifcond & R4_IO_MEM_PRESENT) { + /* Combo card -- proceed to memory initialization */ + PROBE_SET_ACTION(softc, PROBE_SEND_APP_OP_COND); + } else { + /* No memory portion -- get RCA and select card */ + PROBE_SET_ACTION(softc, PROBE_SEND_RELATIVE_ADDR); + } + break; + } + case PROBE_MMC_INIT: + { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + struct mmc_params *mmcp = &path->device->mmc_ident_data; + + if (err != MMC_ERR_NONE) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("MMC_INIT: error %d, resp %08x\n", + err, mmcio->cmd.resp[0])); + PROBE_SET_ACTION(softc, PROBE_INVALID); + break; + } + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("MMC card, OCR %08x\n", mmcio->cmd.resp[0])); + + if (mmcp->card_ocr == 0) { + /* We haven't sent the OCR to the card yet -- do it */ + mmcp->card_ocr = mmcio->cmd.resp[0]; + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("-> sending OCR to card\n")); + break; + } + + if (!(mmcio->cmd.resp[0] & MMC_OCR_CARD_BUSY)) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card is still powering up\n")); + break; + } + + mmcp->card_features |= CARD_FEATURE_MMC | CARD_FEATURE_MEMORY; + PROBE_SET_ACTION(softc, PROBE_GET_CID); + break; + } + case PROBE_SEND_APP_OP_COND: + { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + + if (err != MMC_ERR_NONE) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("APP_OP_COND: error %d, resp %08x\n", + err, mmcio->cmd.resp[0])); + PROBE_SET_ACTION(softc, PROBE_MMC_INIT); + break; + } + + if (!(softc->flags & PROBE_FLAG_ACMD_SENT)) { + /* Don't change the state */ + softc->flags |= PROBE_FLAG_ACMD_SENT; + break; + } + + softc->flags &= ~PROBE_FLAG_ACMD_SENT; + if ((mmcio->cmd.resp[0] & MMC_OCR_CARD_BUSY) || + (mmcio->cmd.arg & MMC_OCR_VOLTAGE) == 0) { + struct mmc_params *mmcp = &path->device->mmc_ident_data; + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card OCR: %08x\n", mmcio->cmd.resp[0])); + if (mmcp->card_ocr == 0) { + mmcp->card_ocr = mmcio->cmd.resp[0]; + /* Now when we know OCR that we want -- send it to card */ + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("-> sending OCR to card\n")); + } else { + /* We already know the OCR and despite of that we + * are processing the answer to ACMD41 -> move on + */ + PROBE_SET_ACTION(softc, PROBE_GET_CID); + } + /* Getting an answer to ACMD41 means the card has memory */ + mmcp->card_features |= CARD_FEATURE_MEMORY; + + /* Standard capacity vs High Capacity memory card */ + if (mmcio->cmd.resp[0] & MMC_OCR_CCS) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card is SDHC\n")); + mmcp->card_features |= CARD_FEATURE_SDHC; + } + + } else { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card not ready: %08x\n", mmcio->cmd.resp[0])); + /* Send CMD55+ACMD41 once again */ + PROBE_SET_ACTION(softc, PROBE_SEND_APP_OP_COND); + } + + break; + } + case PROBE_GET_CID: /* XXX move to mmc_da */ + { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + + if (err != MMC_ERR_NONE) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("PROBE_GET_CID: error %d\n", err)); + PROBE_SET_ACTION(softc, PROBE_INVALID); + break; + } + + struct mmc_params *mmcp = &path->device->mmc_ident_data; + memcpy(mmcp->card_cid, mmcio->cmd.resp, 4 * sizeof(uint32_t)); + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("CID %08x%08x%08x%08x\n", + mmcp->card_cid[0], + mmcp->card_cid[1], + mmcp->card_cid[2], + mmcp->card_cid[3])); + PROBE_SET_ACTION(softc, PROBE_SEND_RELATIVE_ADDR); + break; + } + case PROBE_SEND_RELATIVE_ADDR: { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + struct mmc_params *mmcp = &path->device->mmc_ident_data; + uint16_t rca = mmcio->cmd.resp[0] >> 16; + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card published RCA: %u\n", rca)); + path->device->mmc_ident_data.card_rca = rca; + if (err != MMC_ERR_NONE) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("PROBE_SEND_RELATIVE_ADDR: error %d\n", err)); + PROBE_SET_ACTION(softc, PROBE_INVALID); + break; + } + + /* If memory is present, get CSD, otherwise select card */ + if (mmcp->card_features & CARD_FEATURE_MEMORY) + PROBE_SET_ACTION(softc, PROBE_GET_CSD); + else + PROBE_SET_ACTION(softc, PROBE_SELECT_CARD); + break; + } + case PROBE_GET_CSD: { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + + if (err != MMC_ERR_NONE) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("PROBE_GET_CSD: error %d\n", err)); + PROBE_SET_ACTION(softc, PROBE_INVALID); + break; + } + + struct mmc_params *mmcp = &path->device->mmc_ident_data; + memcpy(mmcp->card_csd, mmcio->cmd.resp, 4 * sizeof(uint32_t)); + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("CSD %08x%08x%08x%08x\n", + mmcp->card_csd[0], + mmcp->card_csd[1], + mmcp->card_csd[2], + mmcp->card_csd[3])); + PROBE_SET_ACTION(softc, PROBE_SELECT_CARD); + break; + } + case PROBE_SELECT_CARD: { + mmcio = &done_ccb->mmcio; + err = mmcio->cmd.error; + if (err != MMC_ERR_NONE) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("PROBE_SEND_RELATIVE_ADDR: error %d\n", err)); + PROBE_SET_ACTION(softc, PROBE_INVALID); + break; + } + + PROBE_SET_ACTION(softc, PROBE_DONE); + break; + } + default: + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("mmc_probedone: invalid action state 0x%x\n", softc->action)); + panic("default: case in mmc_probe_done()"); + } + + if (softc->action == PROBE_INVALID && + (path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("mmc_probedone: Should send AC_LOST_DEVICE but won't for now\n")); + //xpt_async(AC_LOST_DEVICE, path, NULL); + } + + xpt_release_ccb(done_ccb); + if (softc->action != PROBE_INVALID) + xpt_schedule(periph, priority); + /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */ + int frozen = cam_release_devq(path, 0, 0, 0, FALSE); + printf("mmc_probedone: remaining freezecnt %d\n", frozen); + + if (softc->action == PROBE_DONE) { + /* Notify the system that the device is found! */ + if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { + path->device->flags &= ~CAM_DEV_UNCONFIGURED; + xpt_acquire_device(path->device); + done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action(done_ccb); + xpt_async(AC_FOUND_DEVICE, path, done_ccb); + } + + /* Also announce each SDIO function */ + struct mmc_params *mmcp = &path->device->mmc_ident_data; + + for (int i = 0; i < mmcp->sdio_func_count; i++) { + struct cam_path *newpath; + cam_status status; + status = xpt_create_path(&newpath, NULL, + done_ccb->ccb_h.path_id, 0, i + 1); + if (status != CAM_REQ_CMP) + printf("xpt_create_path failed" + " with status %#x\n", + status); + xpt_async(AC_FOUND_DEVICE, newpath, done_ccb); + } + } + if (softc->action == PROBE_DONE || softc->action == PROBE_INVALID) { + cam_periph_invalidate(periph); + cam_periph_release_locked(periph); + } +} diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index b28742037524..4e50baccd702 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$"); #include #ifdef _KERNEL -#include +#include "opt_scsi.h" #include #include diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index d3fde419f1a2..903f5091e4d2 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -1258,6 +1258,14 @@ static struct da_quirk_entry da_quirk_table[] = { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-VERTEX4*", "*" }, /*quirks*/DA_Q_4K }, + { + /* + * Samsung 750 Series SSDs + * 4k optimised & trim only works in 4k requests + 4k aligned + */ + { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 750*", "*" }, + /*quirks*/DA_Q_4K + }, { /* * Samsung 830 Series SSDs @@ -1274,6 +1282,14 @@ static struct da_quirk_entry da_quirk_table[] = { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 840*", "*" }, /*quirks*/DA_Q_4K }, + { + /* + * Samsung 845 SSDs + * 4k optimised & trim only works in 4k requests + 4k aligned + */ + { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 845*", "*" }, + /*quirks*/DA_Q_4K + }, { /* * Samsung 850 SSDs diff --git a/sys/cam/scsi/scsi_enc.c b/sys/cam/scsi/scsi_enc.c index 5f3a1e538ba5..f27e81399a24 100644 --- a/sys/cam/scsi/scsi_enc.c +++ b/sys/cam/scsi/scsi_enc.c @@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include "opt_ses.h" MALLOC_DEFINE(M_SCSIENC, "SCSI ENC", "SCSI ENC buffers"); diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 0941c4f4d668..c7ead838f731 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -2202,7 +2202,7 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb) */ fc = ccb->ccb_h.func_code; if ((fc == XPT_SCSI_IO) || (fc == XPT_ATA_IO) || (fc == XPT_SMP_IO) - || (fc == XPT_DEV_MATCH) || (fc == XPT_DEV_ADVINFO)) { + || (fc == XPT_DEV_MATCH) || (fc == XPT_DEV_ADVINFO) || (fc == XPT_MMC_IO)) { bzero(&mapinfo, sizeof(mapinfo)); /* diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index 05082281f6f4..17b8bc3bacbe 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$"); #ifdef _KERNEL -#include +#include "opt_sa.h" #ifndef SA_IO_TIMEOUT #define SA_IO_TIMEOUT 32 diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h index f868c32d5656..278730a95daa 100644 --- a/sys/compat/linuxkpi/common/include/linux/device.h +++ b/sys/compat/linuxkpi/common/include/linux/device.h @@ -79,6 +79,15 @@ struct dev_pm_ops { int (*runtime_idle)(struct device *dev); }; +struct device_driver { + const char *name; + const struct dev_pm_ops *pm; +}; + +struct device_type { + const char *name; +}; + struct device { struct device *parent; struct list_head irqents; @@ -91,6 +100,8 @@ struct device { * done somewhere else. */ bool bsddev_attached_here; + struct device_driver *driver; + struct device_type *type; dev_t devt; struct class *class; void (*release)(struct device *dev); @@ -348,13 +359,20 @@ device_create_with_groups(struct class *class, return dev; } +static inline bool +device_is_registered(struct device *dev) +{ + + return (dev->bsddev != NULL); +} + static inline int device_register(struct device *dev) { device_t bsddev = NULL; int unit = -1; - if (dev->bsddev != NULL) + if (device_is_registered(dev)) goto done; if (dev->devt) { diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h index ef5d1cc265e1..4f3e378292ec 100644 --- a/sys/compat/linuxkpi/common/include/linux/fs.h +++ b/sys/compat/linuxkpi/common/include/linux/fs.h @@ -80,8 +80,12 @@ struct linux_file { struct selinfo f_selinfo; struct sigio *f_sigio; struct vnode *f_vnode; +#define f_inode f_vnode volatile u_int f_count; + /* anonymous shmem object */ + vm_object_t f_shmem; + /* kqfilter support */ int f_kqflags; #define LINUX_KQ_FLAG_HAS_READ (1 << 0) @@ -156,7 +160,8 @@ struct file_operations { int (*setlease)(struct file *, long, struct file_lock **); #endif }; -#define fops_get(fops) (fops) +#define fops_get(fops) (fops) +#define replace_fops(f, fops) ((f)->f_op = (fops)) #define FMODE_READ FREAD #define FMODE_WRITE FWRITE diff --git a/sys/compat/linuxkpi/common/include/linux/io-mapping.h b/sys/compat/linuxkpi/common/include/linux/io-mapping.h index 7c92c50d637a..12643be9c6e6 100644 --- a/sys/compat/linuxkpi/common/include/linux/io-mapping.h +++ b/sys/compat/linuxkpi/common/include/linux/io-mapping.h @@ -53,8 +53,13 @@ io_mapping_init_wc(struct io_mapping *mapping, resource_size_t base, mapping->base = base; mapping->size = size; +#ifdef VM_MEMATTR_WRITE_COMBINING mapping->mem = ioremap_wc(base, size); mapping->attr = VM_MEMATTR_WRITE_COMBINING; +#else + mapping->mem = ioremap_nocache(base, size); + mapping->attr = VM_MEMATTR_UNCACHEABLE; +#endif return (mapping); } diff --git a/sys/compat/linuxkpi/common/include/linux/jiffies.h b/sys/compat/linuxkpi/common/include/linux/jiffies.h index 5f5f35eb8cc5..3727d90a81ef 100644 --- a/sys/compat/linuxkpi/common/include/linux/jiffies.h +++ b/sys/compat/linuxkpi/common/include/linux/jiffies.h @@ -68,11 +68,14 @@ timespec_to_jiffies(const struct timespec *ts) } static inline int -msecs_to_jiffies(const u64 msec) +msecs_to_jiffies(uint64_t msec) { - u64 result; + uint64_t msec_max, result; - result = howmany(msec * (u64)hz, 1000ULL); + msec_max = -1ULL / (uint64_t)hz; + if (msec > msec_max) + msec = msec_max; + result = howmany(msec * (uint64_t)hz, 1000ULL); if (result > MAX_JIFFY_OFFSET) result = MAX_JIFFY_OFFSET; @@ -80,27 +83,61 @@ msecs_to_jiffies(const u64 msec) } static inline int -usecs_to_jiffies(const u64 u) +usecs_to_jiffies(uint64_t usec) { - u64 result; + uint64_t usec_max, result; - result = howmany(u * (u64)hz, 1000000ULL); + usec_max = -1ULL / (uint64_t)hz; + if (usec > usec_max) + usec = usec_max; + result = howmany(usec * (uint64_t)hz, 1000000ULL); if (result > MAX_JIFFY_OFFSET) result = MAX_JIFFY_OFFSET; return ((int)result); } -static inline u64 -nsecs_to_jiffies(const u64 n) +static inline uint64_t +nsecs_to_jiffies64(uint64_t nsec) { + uint64_t nsec_max, result; + + nsec_max = -1ULL / (uint64_t)hz; + if (nsec > nsec_max) + nsec = nsec_max; + result = howmany(nsec * (uint64_t)hz, 1000000000ULL); + if (result > MAX_JIFFY_OFFSET) + result = MAX_JIFFY_OFFSET; + + return (result); +} + +static inline uint64_t +nsecs_to_jiffies(uint64_t n) +{ + return (usecs_to_jiffies(howmany(n, 1000ULL))); } -static inline u64 +static inline uint64_t +jiffies_to_nsecs(int j) +{ + + return ((1000000000ULL / hz) * (uint64_t)(unsigned int)j); +} + +static inline uint64_t +jiffies_to_usecs(int j) +{ + + return ((1000000ULL / hz) * (uint64_t)(unsigned int)j); +} + +static inline uint64_t get_jiffies_64(void) { - return ((u64)(unsigned)ticks); + + return ((uint64_t)(unsigned int)ticks); } static inline int diff --git a/sys/compat/linuxkpi/common/include/linux/ktime.h b/sys/compat/linuxkpi/common/include/linux/ktime.h index e2fd977a7cc5..a1b8af008e68 100644 --- a/sys/compat/linuxkpi/common/include/linux/ktime.h +++ b/sys/compat/linuxkpi/common/include/linux/ktime.h @@ -26,8 +26,9 @@ * * $FreeBSD$ */ + #ifndef _LINUX_KTIME_H -#define _LINUX_KTIME_H +#define _LINUX_KTIME_H #include #include @@ -153,7 +154,7 @@ timeval_to_ktime(struct timeval tv) #define ktime_to_timeval(kt) ns_to_timeval((kt).tv64) #define ktime_to_ns(kt) ((kt).tv64) -static inline s64 +static inline int64_t ktime_get_ns(void) { struct timespec ts; @@ -164,6 +165,8 @@ ktime_get_ns(void) return (ktime_to_ns(kt)); } +#define ktime_get_raw_ns() ktime_get_ns() + static inline ktime_t ktime_get(void) { @@ -173,4 +176,22 @@ ktime_get(void) return (timespec_to_ktime(ts)); } -#endif /* _LINUX_KTIME_H */ +static inline ktime_t +ktime_get_boottime(void) +{ + struct timespec ts; + + nanouptime(&ts); + return (timespec_to_ktime(ts)); +} + +static inline ktime_t +ktime_get_real(void) +{ + struct timespec ts; + + nanotime(&ts); + return (timespec_to_ktime(ts)); +} + +#endif /* _LINUX_KTIME_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/math64.h b/sys/compat/linuxkpi/common/include/linux/math64.h index 2a488f1216f4..9b22416a9e97 100644 --- a/sys/compat/linuxkpi/common/include/linux/math64.h +++ b/sys/compat/linuxkpi/common/include/linux/math64.h @@ -26,6 +26,7 @@ * * $FreeBSD$ */ + #ifndef _LINUX_MATH64_H #define _LINUX_MATH64_H @@ -39,17 +40,48 @@ __rem; \ }) +static inline uint64_t +div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder) +{ + + *remainder = dividend % divisor; + return (dividend / divisor); +} + +static inline int64_t +div64_s64(int64_t dividend, int64_t divisor) +{ + + return (dividend / divisor); +} + +static inline uint64_t +div64_u64(uint64_t dividend, uint64_t divisor) +{ + + return (dividend / divisor); +} + static inline uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder) { + *remainder = dividend % divisor; return (dividend / divisor); } +static inline int64_t +div_s64(int64_t dividend, int32_t divisor) +{ + + return (dividend / divisor); +} + static inline uint64_t div_u64(uint64_t dividend, uint32_t divisor) { + return (dividend / divisor); } -#endif /* _LINUX_MATH64_H */ +#endif /* _LINUX_MATH64_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/page.h b/sys/compat/linuxkpi/common/include/linux/page.h index a504bedef7bb..c4ba0389810c 100644 --- a/sys/compat/linuxkpi/common/include/linux/page.h +++ b/sys/compat/linuxkpi/common/include/linux/page.h @@ -76,8 +76,10 @@ pgprot2cachemode(pgprot_t prot) #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) #define clear_page(page) memset((page), 0, PAGE_SIZE) -#define pgprot_noncached(prot) ((pgprot_t)VM_MEMATTR_UNCACHEABLE) -#define pgprot_writecombine(prot) ((pgprot_t)VM_MEMATTR_WRITE_COMBINING) +#define pgprot_noncached(prot) \ + ((prot) | cachemode2protval(VM_MEMATTR_UNCACHEABLE)) +#define pgprot_writecombine(prot) \ + ((prot) | cachemode2protval(VM_MEMATTR_WRITE_COMBINING)) #undef PAGE_MASK #define PAGE_MASK (~(PAGE_SIZE-1)) diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index 82d1e279e27c..f7581636c715 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -56,13 +56,21 @@ struct pci_device_id { uint32_t vendor; uint32_t device; - uint32_t subvendor; + uint32_t subvendor; uint32_t subdevice; + uint32_t class; uint32_t class_mask; uintptr_t driver_data; }; #define MODULE_DEVICE_TABLE(bus, table) + +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_VGA 0x0300 +#define PCI_CLASS_DISPLAY_OTHER 0x0380 +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_ISA 0x0601 + #define PCI_ANY_ID (-1) #define PCI_VENDOR_ID_APPLE 0x106b #define PCI_VENDOR_ID_ASUSTEK 0x1043 @@ -175,9 +183,10 @@ struct pci_driver { int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */ int (*resume) (struct pci_dev *dev); /* Device woken up */ void (*shutdown) (struct pci_dev *dev); /* Device shutdown */ - driver_t driver; + driver_t bsddriver; devclass_t bsdclass; - const struct pci_error_handlers *err_handler; + struct device_driver driver; + const struct pci_error_handlers *err_handler; }; extern struct list_head pci_drivers; @@ -195,7 +204,8 @@ struct pci_dev { uint16_t vendor; unsigned int irq; unsigned int devfn; - u8 revision; + uint32_t class; + uint8_t revision; }; static inline struct resource_list_entry * diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h index 589c0f1e50db..56af57733cfa 100644 --- a/sys/compat/linuxkpi/common/include/linux/sched.h +++ b/sys/compat/linuxkpi/common/include/linux/sched.h @@ -56,6 +56,8 @@ #define TASK_WAKING 0x0100 #define TASK_PARKED 0x0200 +#define TASK_COMM_LEN (MAXCOMLEN + 1) + struct task_struct { struct thread *task_thread; struct mm_struct *mm; diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index a802ef999472..408a547f4162 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -463,6 +463,8 @@ void linux_file_free(struct linux_file *filp) { if (filp->_file == NULL) { + if (filp->f_shmem != NULL) + vm_object_deallocate(filp->f_shmem); kfree(filp); } else { /* @@ -473,12 +475,58 @@ linux_file_free(struct linux_file *filp) } } +static int +linux_cdev_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, + vm_page_t *mres) +{ + struct vm_area_struct *vmap; + + vmap = linux_cdev_handle_find(vm_obj->handle); + + MPASS(vmap != NULL); + MPASS(vmap->vm_private_data == vm_obj->handle); + + if (likely(vmap->vm_ops != NULL && offset < vmap->vm_len)) { + vm_paddr_t paddr = IDX_TO_OFF(vmap->vm_pfn) + offset; + vm_page_t page; + + if (((*mres)->flags & PG_FICTITIOUS) != 0) { + /* + * If the passed in result page is a fake + * page, update it with the new physical + * address. + */ + page = *mres; + vm_page_updatefake(page, paddr, vm_obj->memattr); + } else { + /* + * Replace the passed in "mres" page with our + * own fake page and free up the all of the + * original pages. + */ + VM_OBJECT_WUNLOCK(vm_obj); + page = vm_page_getfake(paddr, vm_obj->memattr); + VM_OBJECT_WLOCK(vm_obj); + + vm_page_replace_checked(page, vm_obj, + (*mres)->pindex, *mres); + + vm_page_lock(*mres); + vm_page_free(*mres); + vm_page_unlock(*mres); + *mres = page; + } + page->valid = VM_PAGE_BITS_ALL; + return (VM_PAGER_OK); + } + return (VM_PAGER_FAIL); +} + static int linux_cdev_pager_populate(vm_object_t vm_obj, vm_pindex_t pidx, int fault_type, vm_prot_t max_prot, vm_pindex_t *first, vm_pindex_t *last) { struct vm_area_struct *vmap; - struct vm_fault vmf; int err; linux_set_current(curthread); @@ -488,18 +536,20 @@ linux_cdev_pager_populate(vm_object_t vm_obj, vm_pindex_t pidx, int fault_type, MPASS(vmap != NULL); MPASS(vmap->vm_private_data == vm_obj->handle); - /* fill out VM fault structure */ - vmf.virtual_address = (void *)((uintptr_t)pidx << PAGE_SHIFT); - vmf.flags = (fault_type & VM_PROT_WRITE) ? FAULT_FLAG_WRITE : 0; - vmf.pgoff = 0; - vmf.page = NULL; - VM_OBJECT_WUNLOCK(vm_obj); down_write(&vmap->vm_mm->mmap_sem); - if (unlikely(vmap->vm_ops == NULL || vmap->vm_ops->fault == NULL)) { + if (unlikely(vmap->vm_ops == NULL)) { err = VM_FAULT_SIGBUS; } else { + struct vm_fault vmf; + + /* fill out VM fault structure */ + vmf.virtual_address = (void *)((uintptr_t)pidx << PAGE_SHIFT); + vmf.flags = (fault_type & VM_PROT_WRITE) ? FAULT_FLAG_WRITE : 0; + vmf.pgoff = 0; + vmf.page = NULL; + vmap->vm_pfn_count = 0; vmap->vm_pfn_pcount = &vmap->vm_pfn_count; vmap->vm_obj = vm_obj; @@ -631,10 +681,19 @@ linux_cdev_pager_dtor(void *handle) linux_cdev_handle_free(vmap); } -static struct cdev_pager_ops linux_cdev_pager_ops = { +static struct cdev_pager_ops linux_cdev_pager_ops[2] = { + { + /* OBJT_MGTDEVICE */ .cdev_pg_populate = linux_cdev_pager_populate, .cdev_pg_ctor = linux_cdev_pager_ctor, .cdev_pg_dtor = linux_cdev_pager_dtor + }, + { + /* OBJT_DEVICE */ + .cdev_pg_fault = linux_cdev_pager_fault, + .cdev_pg_ctor = linux_cdev_pager_ctor, + .cdev_pg_dtor = linux_cdev_pager_dtor + }, }; static int @@ -1184,8 +1243,15 @@ linux_dev_mmap_single(struct cdev *dev, vm_ooffset_t *offset, vmap = linux_cdev_handle_insert(vm_private_data, vmap); - *object = cdev_pager_allocate(vm_private_data, OBJT_MGTDEVICE, - &linux_cdev_pager_ops, size, nprot, *offset, curthread->td_ucred); + if (vmap->vm_ops->fault == NULL) { + *object = cdev_pager_allocate(vm_private_data, OBJT_DEVICE, + &linux_cdev_pager_ops[1], size, nprot, *offset, + curthread->td_ucred); + } else { + *object = cdev_pager_allocate(vm_private_data, OBJT_MGTDEVICE, + &linux_cdev_pager_ops[0], size, nprot, *offset, + curthread->td_ucred); + } if (*object == NULL) { linux_cdev_handle_remove(vmap); @@ -1196,7 +1262,8 @@ linux_dev_mmap_single(struct cdev *dev, vm_ooffset_t *offset, struct sglist *sg; sg = sglist_alloc(1, M_WAITOK); - sglist_append_phys(sg, (vm_paddr_t)vmap->vm_pfn << PAGE_SHIFT, vmap->vm_len); + sglist_append_phys(sg, + (vm_paddr_t)vmap->vm_pfn << PAGE_SHIFT, vmap->vm_len); *object = vm_pager_allocate(OBJT_SG, sg, vmap->vm_len, nprot, 0, curthread->td_ucred); diff --git a/sys/compat/linuxkpi/common/src/linux_current.c b/sys/compat/linuxkpi/common/src/linux_current.c index f0d1e199e816..331f6e2d2b7a 100644 --- a/sys/compat/linuxkpi/common/src/linux_current.c +++ b/sys/compat/linuxkpi/common/src/linux_current.c @@ -226,6 +226,23 @@ SYSINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_init, static void linux_current_uninit(void *arg __unused) { + struct proc *p; + struct task_struct *ts; + struct thread *td; + + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + PROC_LOCK(p); + FOREACH_THREAD_IN_PROC(p, td) { + if ((ts = td->td_lkpi_task) != NULL) { + td->td_lkpi_task = NULL; + put_task_struct(ts); + } + } + PROC_UNLOCK(p); + } + sx_sunlock(&allproc_lock); + EVENTHANDLER_DEREGISTER(thread_dtor, linuxkpi_thread_dtor_tag); } SYSUNINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_uninit, NULL); diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index 84a38d875564..dd37160083c5 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -108,7 +108,7 @@ linux_pci_probe(device_t dev) if ((pdrv = linux_pci_find(dev, &id)) == NULL) return (ENXIO); - if (device_get_driver(dev) != &pdrv->driver) + if (device_get_driver(dev) != &pdrv->bsddriver) return (ENXIO); device_set_desc(dev, pdrv->name); return (0); @@ -129,8 +129,11 @@ linux_pci_attach(device_t dev) pdev->dev.parent = &linux_root_device; pdev->dev.bsddev = dev; INIT_LIST_HEAD(&pdev->dev.irqents); + pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev)); pdev->device = id->device; pdev->vendor = id->vendor; + pdev->class = pci_get_class(dev); + pdev->revision = pci_get_revid(dev); pdev->dev.dma_mask = &pdev->dma_mask; pdev->pdrv = pdrv; kobject_init(&pdev->dev.kobj, &linux_dev_ktype); @@ -180,32 +183,47 @@ linux_pci_detach(device_t dev) static int linux_pci_suspend(device_t dev) { + const struct dev_pm_ops *pmops; struct pm_message pm = { }; struct pci_dev *pdev; - int err; + int error; + error = 0; linux_set_current(curthread); pdev = device_get_softc(dev); + pmops = pdev->pdrv->driver.pm; + if (pdev->pdrv->suspend != NULL) - err = -pdev->pdrv->suspend(pdev, pm); - else - err = 0; - return (err); + error = -pdev->pdrv->suspend(pdev, pm); + else if (pmops != NULL && pmops->suspend != NULL) { + error = -pmops->suspend(&pdev->dev); + if (error == 0 && pmops->suspend_late != NULL) + error = -pmops->suspend_late(&pdev->dev); + } + return (error); } static int linux_pci_resume(device_t dev) { + const struct dev_pm_ops *pmops; struct pci_dev *pdev; - int err; + int error; + error = 0; linux_set_current(curthread); pdev = device_get_softc(dev); + pmops = pdev->pdrv->driver.pm; + if (pdev->pdrv->resume != NULL) - err = -pdev->pdrv->resume(pdev); - else - err = 0; - return (err); + error = -pdev->pdrv->resume(pdev); + else if (pmops != NULL && pmops->resume != NULL) { + if (pmops->resume_early != NULL) + error = -pmops->resume_early(&pdev->dev); + if (error == 0 && pmops->resume != NULL) + error = -pmops->resume(&pdev->dev); + } + return (error); } static int @@ -235,13 +253,14 @@ pci_register_driver(struct pci_driver *pdrv) spin_lock(&pci_lock); list_add(&pdrv->links, &pci_drivers); spin_unlock(&pci_lock); - pdrv->driver.name = pdrv->name; - pdrv->driver.methods = pci_methods; - pdrv->driver.size = sizeof(struct pci_dev); + pdrv->bsddriver.name = pdrv->name; + pdrv->bsddriver.methods = pci_methods; + pdrv->bsddriver.size = sizeof(struct pci_dev); + mtx_lock(&Giant); if (bus != NULL) { - error = devclass_add_driver(bus, &pdrv->driver, BUS_PASS_DEFAULT, - &pdrv->bsdclass); + error = devclass_add_driver(bus, &pdrv->bsddriver, + BUS_PASS_DEFAULT, &pdrv->bsdclass); } mtx_unlock(&Giant); return (-error); @@ -254,10 +273,11 @@ pci_unregister_driver(struct pci_driver *pdrv) bus = devclass_find("pci"); + spin_lock(&pci_lock); list_del(&pdrv->links); + spin_unlock(&pci_lock); mtx_lock(&Giant); if (bus != NULL) - devclass_delete_driver(bus, &pdrv->driver); + devclass_delete_driver(bus, &pdrv->bsddriver); mtx_unlock(&Giant); } - diff --git a/sys/compat/linuxkpi/common/src/linux_rcu.c b/sys/compat/linuxkpi/common/src/linux_rcu.c index 32d532b13095..3cf6aba78782 100644 --- a/sys/compat/linuxkpi/common/src/linux_rcu.c +++ b/sys/compat/linuxkpi/common/src/linux_rcu.c @@ -299,8 +299,9 @@ linux_synchronize_rcu(void) old_cpu = PCPU_GET(cpuid); old_pinned = td->td_pinned; old_prio = td->td_priority; - td->td_pinned = 0; was_bound = sched_is_bound(td); + sched_unbind(td); + td->td_pinned = 0; sched_bind(td, old_cpu); ck_epoch_synchronize_wait(&linux_epoch, diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 089ce7d6fc67..b60869aff4c9 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -302,7 +302,7 @@ options SX_NOINLINE # TURNSTILE_PROFILING enables rudimentary profiling of the hash table # used to hold active lock queues. # UMTX_PROFILING enables rudimentary profiling of the hash table used - to hold active lock queues. +# to hold active lock queues. # WITNESS enables the witness code which detects deadlocks and cycles # during locking operations. # WITNESS_KDB causes the witness code to drop into the kernel debugger if diff --git a/sys/conf/files b/sys/conf/files index a4577792a8fe..61e4edcbd287 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -110,6 +110,9 @@ cam/ctl/ctl_tpc_local.c optional ctl cam/ctl/ctl_error.c optional ctl cam/ctl/ctl_util.c optional ctl cam/ctl/scsi_ctl.c optional ctl +cam/mmc/mmc_xpt.c optional scbus mmccam +cam/mmc/mmc_da.c optional scbus mmccam da +cam/mmc/mmc_sdio.c optional scbus mmccam cam/scsi/scsi_da.c optional da cam/scsi/scsi_low.c optional ncv | nsp | stg cam/scsi/scsi_pass.c optional pass @@ -2130,6 +2133,14 @@ dev/ixgbe/if_ix.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_ixv.c optional ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" +dev/ixgbe/if_bypass.c optional ix inet \ + compile-with "${NORMAL_C} -I$S/dev/ixgbe" +dev/ixgbe/ixgbe_netmap.c optional ix inet \ + compile-with "${NORMAL_C} -I$S/dev/ixgbe" +dev/ixgbe/if_fdir.c optional ix inet | ixv inet \ + compile-with "${NORMAL_C} -I$S/dev/ixgbe" +dev/ixgbe/if_sriov.c optional ix inet | ixv inet \ + compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ix_txrx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_osdep.c optional ix inet | ixv inet \ @@ -2232,11 +2243,12 @@ dev/mlx/mlx.c optional mlx dev/mlx/mlx_disk.c optional mlx dev/mlx/mlx_pci.c optional mlx pci dev/mly/mly.c optional mly -dev/mmc/mmc_subr.c optional mmc | mmcsd -dev/mmc/mmc.c optional mmc +dev/mmc/mmc_subr.c optional mmc | mmcsd !mmccam +dev/mmc/mmc.c optional mmc !mmccam dev/mmc/mmcbr_if.m standard dev/mmc/mmcbus_if.m standard -dev/mmc/mmcsd.c optional mmcsd +dev/mmc/mmcsd.c optional mmcsd !mmccam +dev/mmcnull/mmcnull.c optional mmcnull dev/mn/if_mn.c optional mn pci dev/mpr/mpr.c optional mpr dev/mpr/mpr_config.c optional mpr diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 0b0808d07c27..e4aacfc3c104 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -84,6 +84,7 @@ arm/arm/pl190.c optional pl190 arm/arm/pl310.c optional pl310 arm/arm/platform.c optional platform arm/arm/platform_if.m optional platform +arm/arm/platform_pl310_if.m optional platform pl310 arm/arm/pmap-v4.c optional !armv6 arm/arm/pmap-v6.c optional armv6 arm/arm/pmu.c optional pmu | fdt hwpmc diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index ad05c4b79534..84029a5af25e 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -37,6 +37,12 @@ arm/allwinner/clk/aw_pll.c optional aw_ccu fdt \ compile-with "${NORMAL_C} -I$S/gnu/dts/include" arm/allwinner/clk/aw_thsclk.c optional aw_ccu fdt arm/allwinner/clk/aw_usbclk.c optional aw_ccu fdt +arm/allwinner/clkng/aw_ccung.c optional aw_ccu fdt +arm/allwinner/clkng/aw_clk_nkmp.c optional aw_ccu fdt +arm/allwinner/clkng/aw_clk_nm.c optional aw_ccu fdt +arm/allwinner/clkng/aw_clk_prediv_mux.c optional aw_ccu fdt +arm/allwinner/clkng/ccu_a64.c optional aw_ccu fdt + arm/allwinner/if_awg.c optional awg fdt arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt arm/annapurna/alpine/alpine_nb_service.c optional al_nb_service fdt @@ -152,6 +158,8 @@ dev/axgbe/xgbe-dev.c optional axgbe dev/axgbe/xgbe-drv.c optional axgbe dev/axgbe/xgbe-mdio.c optional axgbe dev/cpufreq/cpufreq_dt.c optional cpufreq fdt +dev/iicbus/twsi/a10_twsi.c optional twsi fdt +dev/iicbus/twsi/twsi.c optional twsi fdt dev/hwpmc/hwpmc_arm64.c optional hwpmc dev/hwpmc/hwpmc_arm64_md.c optional hwpmc dev/mbox/mbox_if.m optional soc_brcm_bcm2837 diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk index b131b72d6ac7..95b94fb2dda2 100644 --- a/sys/conf/kern.post.mk +++ b/sys/conf/kern.post.mk @@ -203,8 +203,7 @@ _meta_filemon= 1 # for _meta_filemon but not for _SKIP_DEPEND. .if !empty(.MAKEFLAGS:M-V${_V_READ_DEPEND}) || make(*obj) || \ ${.TARGETS:M*clean*} == ${.TARGETS} || \ - ${.TARGETS:M*install*} == ${.TARGETS} || \ - defined(_meta_filemon) + ${.TARGETS:M*install*} == ${.TARGETS} _SKIP_DEPEND= 1 .endif .if defined(_SKIP_DEPEND) || defined(_meta_filemon) diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index f6c9c0e0a7d0..d23d531ced64 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -114,7 +114,7 @@ DEFINED_PROF= ${PROF} # can override the others. CFLAGS+= ${CONF_CFLAGS} -.if ${LINKER_FEATURES:Mbuild-id} +.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mbuild-id} LDFLAGS+= -Wl,--build-id=sha1 .endif diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 4e589efaa1f9..da65f7117927 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -125,7 +125,7 @@ CFLAGS.gcc+= --param large-function-growth=1000 CFLAGS+= -fno-common LDFLAGS+= -d -warn-common -.if ${LINKER_FEATURES:Mbuild-id} +.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mbuild-id} LDFLAGS+= -Wl,--build-id=sha1 .endif diff --git a/sys/conf/options b/sys/conf/options index a8ff2506f492..eda2dfb8e52c 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -45,7 +45,6 @@ AHD_REG_PRETTY_PRINT opt_aic79xx.h ADW_ALLOW_MEMIO opt_adw.h TWA_DEBUG opt_twa.h -TWA_FLASH_FIRMWARE opt_twa.h # Debugging options. ALT_BREAK_TO_DEBUGGER opt_kdb.h @@ -997,5 +996,7 @@ UINPUT_DEBUG opt_evdev.h # Hyper-V network driver HN_DEBUG opt_hn.h +# CAM-based MMC stack +MMCCAM # Encrypted kernel crash dumps EKCD opt_ekcd.h diff --git a/sys/conf/options.arm b/sys/conf/options.arm index 6668ccf9e504..f3ab2fc0214e 100644 --- a/sys/conf/options.arm +++ b/sys/conf/options.arm @@ -34,11 +34,9 @@ KERNBASE opt_global.h KERNVIRTADDR opt_global.h LINUX_BOOT_ABI opt_global.h LOADERRAMADDR opt_global.h -MULTIDELAY opt_global.h NKPT2PG opt_pmap.h PHYSADDR opt_global.h PLATFORM opt_global.h -PLATFORM_SMP opt_global.h SOCDEV_PA opt_global.h SOCDEV_VA opt_global.h PV_STATS opt_pmap.h diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 7642e91838fd..bec81b706484 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -325,11 +325,26 @@ static void db_cmd_list(struct command_table *table) { struct command *cmd; + int have_subcommands; + have_subcommands = 0; LIST_FOREACH(cmd, table, next) { + if (cmd->more != NULL) + have_subcommands++; db_printf("%-16s", cmd->name); db_end_line(16); } + + if (have_subcommands > 0) { + db_printf("\nThe following have subcommands; append \"help\" " + "to list (e.g. \"show help\"):\n"); + LIST_FOREACH(cmd, table, next) { + if (cmd->more == NULL) + continue; + db_printf("%-16s", cmd->name); + db_end_line(16); + } + } } static void @@ -357,7 +372,8 @@ db_command(struct command **last_cmdp, struct command_table *cmd_table, return; } else if (t != tIDENT) { - db_printf("?\n"); + db_printf("Unrecognized input; use \"help\" " + "to list available commands\n"); db_flush_lex(); return; } @@ -371,7 +387,8 @@ db_command(struct command **last_cmdp, struct command_table *cmd_table, &cmd); switch (result) { case CMD_NONE: - db_printf("No such command\n"); + db_printf("No such command; use \"help\" " + "to list available commands\n"); db_flush_lex(); return; case CMD_AMBIGUOUS: @@ -379,6 +396,13 @@ db_command(struct command **last_cmdp, struct command_table *cmd_table, db_flush_lex(); return; case CMD_HELP: + if (cmd_table == &db_cmd_table) { + db_printf("This is ddb(4), the kernel debugger; " + "see http://man.freebsd.org/ddb/4 for help.\n"); + db_printf("Use \"bt\" for backtrace, \"dump\" for " + "kernel core dump, \"reset\" to reboot.\n"); + db_printf("Available commands:\n"); + } db_cmd_list(cmd_table); db_flush_lex(); return; @@ -388,6 +412,8 @@ db_command(struct command **last_cmdp, struct command_table *cmd_table, if ((cmd_table = cmd->more) != NULL) { t = db_read_token(); if (t != tIDENT) { + db_printf("Subcommand required; " + "available subcommands:\n"); db_cmd_list(cmd_table); db_flush_lex(); return; @@ -618,7 +644,7 @@ db_fncall(db_expr_t dummy1, bool dummy2, db_expr_t dummy3, char *dummy4) db_unread_token(t); } if (db_read_token() != tRPAREN) { - db_printf("?\n"); + db_printf("Mismatched parens\n"); db_flush_lex(); return; } diff --git a/sys/ddb/db_input.c b/sys/ddb/db_input.c index a2a7b3829e8c..04c0d592b8ff 100644 --- a/sys/ddb/db_input.c +++ b/sys/ddb/db_input.c @@ -195,6 +195,7 @@ db_inputchar(c) db_delete(1, DEL_FWD); break; case CTRL('u'): + case CTRL('c'): /* kill entire line: */ /* at first, delete to beginning of line */ if (db_lc > db_lbuf_start) @@ -217,6 +218,19 @@ db_inputchar(c) cnputc(db_lc[-1]); } break; + case CTRL('w'): + /* erase previous word */ + for (; db_lc > db_lbuf_start;) { + if (*(db_lc - 1) != ' ') + break; + db_delete(1, DEL_BWD); + } + for (; db_lc > db_lbuf_start;) { + if (*(db_lc - 1) == ' ') + break; + db_delete(1, DEL_BWD); + } + break; case CTRL('r'): db_putstring("^R\n", 3); redraw: diff --git a/sys/ddb/db_sym.c b/sys/ddb/db_sym.c index d3f9554aa90b..8b257b191148 100644 --- a/sys/ddb/db_sym.c +++ b/sys/ddb/db_sym.c @@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include "opt_ddb.h" /* * Multiple symbol tables diff --git a/sys/dev/acpica/Osd/OsdSchedule.c b/sys/dev/acpica/Osd/OsdSchedule.c index 0b9b12bcd2af..8e3810279114 100644 --- a/sys/dev/acpica/Osd/OsdSchedule.c +++ b/sys/dev/acpica/Osd/OsdSchedule.c @@ -128,7 +128,7 @@ acpi_taskq_init(void *arg) acpi_taskq_started = 1; } -SYSINIT(acpi_taskq, SI_SUB_CONFIGURE, SI_ORDER_SECOND, acpi_taskq_init, NULL); +SYSINIT(acpi_taskq, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, acpi_taskq_init, NULL); /* * Bounce through this wrapper function since ACPI-CA doesn't understand diff --git a/sys/dev/agp/agp_i810.c b/sys/dev/agp/agp_i810.c index 7a0b2ff51519..63315308aaeb 100644 --- a/sys/dev/agp/agp_i810.c +++ b/sys/dev/agp/agp_i810.c @@ -2242,6 +2242,16 @@ agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries, return (0); } +static void +agp_intel_gtt_install_pte(device_t dev, u_int index, vm_paddr_t addr, + u_int flags) +{ + struct agp_i810_softc *sc; + + sc = device_get_softc(dev); + sc->match->driver->install_gtt_pte(dev, index, addr, flags); +} + void agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list, u_int first_entry, u_int flags) @@ -2320,6 +2330,13 @@ intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry, agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags); } +void +intel_gtt_install_pte(u_int index, vm_paddr_t addr, u_int flags) +{ + + agp_intel_gtt_install_pte(intel_agp, index, addr, flags); +} + device_t intel_gtt_get_bridge_device(void) { diff --git a/sys/dev/agp/agp_i810.h b/sys/dev/agp/agp_i810.h index 2cb71eb65027..1df5e78a162c 100644 --- a/sys/dev/agp/agp_i810.h +++ b/sys/dev/agp/agp_i810.h @@ -87,6 +87,7 @@ struct intel_gtt *intel_gtt_get(void); int intel_gtt_chipset_flush(void); void intel_gtt_unmap_memory(struct sglist *sg_list); void intel_gtt_clear_range(u_int first_entry, u_int num_entries); +void intel_gtt_install_pte(u_int index, vm_paddr_t addr, u_int flags); int intel_gtt_map_memory(vm_page_t *pages, u_int num_entries, struct sglist **sg_list); void intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int pg_start, diff --git a/sys/dev/aic7xxx/aic79xx_osm.h b/sys/dev/aic7xxx/aic79xx_osm.h index db790dffd58d..dd0764a77517 100644 --- a/sys/dev/aic7xxx/aic79xx_osm.h +++ b/sys/dev/aic7xxx/aic79xx_osm.h @@ -38,7 +38,7 @@ #ifndef _AIC79XX_FREEBSD_H_ #define _AIC79XX_FREEBSD_H_ -#include /* for config options */ +#include "opt_aic79xx.h" /* for config options */ #include #include diff --git a/sys/dev/aic7xxx/aic7xxx_osm.h b/sys/dev/aic7xxx/aic7xxx_osm.h index 054811e9d97f..601130f71f7e 100644 --- a/sys/dev/aic7xxx/aic7xxx_osm.h +++ b/sys/dev/aic7xxx/aic7xxx_osm.h @@ -37,7 +37,7 @@ #ifndef _AIC7XXX_FREEBSD_H_ #define _AIC7XXX_FREEBSD_H_ -#include /* for config options */ +#include "opt_aic7xxx.h" /* for config options */ #include #include diff --git a/sys/dev/bnxt/bnxt.h b/sys/dev/bnxt/bnxt.h index 0e6582532f5c..3648352f1da6 100644 --- a/sys/dev/bnxt/bnxt.h +++ b/sys/dev/bnxt/bnxt.h @@ -438,6 +438,7 @@ struct bnxt_ring { uint32_t ring_size; /* Must be a power of two */ uint16_t id; /* Logical ID */ uint16_t phys_id; + struct bnxt_full_tpa_start *tpa_start; }; struct bnxt_cp_ring { @@ -564,7 +565,6 @@ struct bnxt_softc { struct sysctl_ctx_list hw_stats; struct sysctl_oid *hw_stats_oid; - struct bnxt_full_tpa_start *tpa_start; struct bnxt_ver_info *ver_info; struct bnxt_nvram_info *nvm_info; bool wol; diff --git a/sys/dev/bnxt/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_hwrm.c index 706a5e9c7931..3590944f3dd6 100644 --- a/sys/dev/bnxt/bnxt_hwrm.c +++ b/sys/dev/bnxt/bnxt_hwrm.c @@ -935,7 +935,7 @@ bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic, /* TODO: Calculate this based on ring size? */ req.max_agg_segs = htole16(3); /* Base this in the allocated TPA start size... */ - req.max_aggs = htole16(2); + req.max_aggs = htole16(7); /* * TODO: max_agg_timer? * req.mag_agg_timer = htole32(XXX); diff --git a/sys/dev/bnxt/bnxt_txrx.c b/sys/dev/bnxt/bnxt_txrx.c index dd2484e67a8d..e3ba37548a21 100644 --- a/sys/dev/bnxt/bnxt_txrx.c +++ b/sys/dev/bnxt/bnxt_txrx.c @@ -264,6 +264,7 @@ bnxt_isc_rxd_refill(void *sc, if_rxd_update_t iru) uint8_t flid; uint64_t *paddrs; caddr_t *vaddrs; + qidx_t *frag_idxs; rxqid = iru->iru_qsidx; count = iru->iru_count; @@ -272,6 +273,7 @@ bnxt_isc_rxd_refill(void *sc, if_rxd_update_t iru) flid = iru->iru_flidx; vaddrs = iru->iru_vaddrs; paddrs = iru->iru_paddrs; + frag_idxs = iru->iru_idxs; if (flid == 0) { rx_ring = &softc->rx_rings[rxqid]; @@ -287,8 +289,8 @@ bnxt_isc_rxd_refill(void *sc, if_rxd_update_t iru) rxbd[pidx].flags_type = htole16(type); rxbd[pidx].len = htole16(len); /* No need to byte-swap the opaque value */ - rxbd[pidx].opaque = ((rxqid & 0xff) << 24) | (flid << 16) - | pidx; + rxbd[pidx].opaque = (((rxqid & 0xff) << 24) | (flid << 16) + | (frag_idxs[i])); rxbd[pidx].addr = htole64(paddrs[i]); if (++pidx == rx_ring->ring_size) pidx = 0; @@ -329,7 +331,6 @@ bnxt_isc_rxd_available(void *sc, uint16_t rxqid, qidx_t idx, qidx_t budget) struct bnxt_softc *softc = (struct bnxt_softc *)sc; struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[rxqid]; struct rx_pkt_cmpl *rcp; - struct rx_tpa_start_cmpl *rtpa; struct rx_tpa_end_cmpl *rtpae; struct cmpl_base *cmp = (struct cmpl_base *)cpr->ring.vaddr; int avail = 0; @@ -338,7 +339,6 @@ bnxt_isc_rxd_available(void *sc, uint16_t rxqid, qidx_t idx, qidx_t budget) uint8_t ags; int i; uint16_t type; - uint8_t agg_id; for (;;) { NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); @@ -388,18 +388,11 @@ bnxt_isc_rxd_available(void *sc, uint16_t rxqid, qidx_t idx, qidx_t budget) avail++; break; case CMPL_BASE_TYPE_RX_TPA_START: - rtpa = (void *)&cmp[cons]; - agg_id = (rtpa->agg_id & - RX_TPA_START_CMPL_AGG_ID_MASK) >> - RX_TPA_START_CMPL_AGG_ID_SFT; - softc->tpa_start[agg_id].low = *rtpa; NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); CMPL_PREFETCH_NEXT(cpr, cons); if (!CMP_VALID(&cmp[cons], v_bit)) goto cmpl_invalid; - softc->tpa_start[agg_id].high = - ((struct rx_tpa_start_cmpl_hi *)cmp)[cons]; break; case CMPL_BASE_TYPE_RX_AGG: break; @@ -549,7 +542,7 @@ bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri, /* Get the agg_id */ agg_id = (agend->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK) >> RX_TPA_END_CMPL_AGG_ID_SFT; - tpas = &softc->tpa_start[agg_id]; + tpas = &(softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id]); /* Extract from the first 16-byte BD */ if (le16toh(tpas->low.flags_type) & RX_TPA_START_CMPL_FLAGS_RSS_VALID) { @@ -563,8 +556,8 @@ bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri, RX_TPA_END_CMPL_AGG_BUFS_SFT; ri->iri_nfrags = ags + 1; /* No need to byte-swap the opaque value */ - ri->iri_frags[0].irf_flid = (tpas->low.opaque >> 16) & 0xff; - ri->iri_frags[0].irf_idx = tpas->low.opaque & 0xffff; + ri->iri_frags[0].irf_flid = ((tpas->low.opaque >> 16) & 0xff); + ri->iri_frags[0].irf_idx = (tpas->low.opaque & 0xffff); ri->iri_frags[0].irf_len = le16toh(tpas->low.len); ri->iri_len = le16toh(tpas->low.len); @@ -600,8 +593,8 @@ bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri, acp = &((struct rx_abuf_cmpl *)cpr->ring.vaddr)[cpr->cons]; /* No need to byte-swap the opaque value */ - ri->iri_frags[i].irf_flid = (acp->opaque >> 16) & 0xff; - ri->iri_frags[i].irf_idx = acp->opaque & 0xffff; + ri->iri_frags[i].irf_flid = ((acp->opaque >> 16) & 0xff); + ri->iri_frags[i].irf_idx = (acp->opaque & 0xffff); ri->iri_frags[i].irf_len = le16toh(acp->len); ri->iri_len += le16toh(acp->len); } @@ -609,8 +602,8 @@ bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri, /* And finally, the empty BD at the end... */ ri->iri_nfrags++; /* No need to byte-swap the opaque value */ - ri->iri_frags[i].irf_flid = (agend->opaque >> 16) % 0xff; - ri->iri_frags[i].irf_idx = agend->opaque & 0xffff; + ri->iri_frags[i].irf_flid = ((agend->opaque >> 16) & 0xff); + ri->iri_frags[i].irf_idx = (agend->opaque & 0xffff); ri->iri_frags[i].irf_len = le16toh(agend->len); ri->iri_len += le16toh(agend->len); @@ -623,9 +616,12 @@ bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri) { struct bnxt_softc *softc = (struct bnxt_softc *)sc; struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[ri->iri_qsidx]; + struct cmpl_base *cmp_q = (struct cmpl_base *)cpr->ring.vaddr; struct cmpl_base *cmp; + struct rx_tpa_start_cmpl *rtpa; uint16_t flags_type; uint16_t type; + uint8_t agg_id; for (;;) { NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); @@ -642,9 +638,18 @@ bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri) case CMPL_BASE_TYPE_RX_TPA_END: return bnxt_pkt_get_tpa(softc, ri, cpr, flags_type); case CMPL_BASE_TYPE_RX_TPA_START: + rtpa = (void *)&cmp_q[cpr->cons]; + agg_id = (rtpa->agg_id & + RX_TPA_START_CMPL_AGG_ID_MASK) >> + RX_TPA_START_CMPL_AGG_ID_SFT; + softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id].low = *rtpa; + NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); CMPL_PREFETCH_NEXT(cpr, cpr->cons); + + softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id].high = + ((struct rx_tpa_start_cmpl_hi *)cmp_q)[cpr->cons]; break; default: device_printf(softc->dev, diff --git a/sys/dev/bnxt/if_bnxt.c b/sys/dev/bnxt/if_bnxt.c index aff9f5a7c57f..7baa16e7a330 100644 --- a/sys/dev/bnxt/if_bnxt.c +++ b/sys/dev/bnxt/if_bnxt.c @@ -506,6 +506,17 @@ bnxt_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, softc->rx_rings[i].vaddr = vaddrs[i * nrxqs + 1]; softc->rx_rings[i].paddr = paddrs[i * nrxqs + 1]; + /* Allocate the TPA start buffer */ + softc->rx_rings[i].tpa_start = malloc(sizeof(struct bnxt_full_tpa_start) * + (RX_TPA_START_CMPL_AGG_ID_MASK >> RX_TPA_START_CMPL_AGG_ID_SFT), + M_DEVBUF, M_NOWAIT | M_ZERO); + if (softc->rx_rings[i].tpa_start == NULL) { + rc = -ENOMEM; + device_printf(softc->dev, + "Unable to allocate space for TPA\n"); + goto tpa_alloc_fail; + } + /* Allocate the AG ring */ softc->ag_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE; softc->ag_rings[i].softc = softc; @@ -571,7 +582,10 @@ bnxt_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, iflib_dma_free(&softc->vnic_info.rss_hash_key_tbl); rss_hash_alloc_fail: iflib_dma_free(&softc->vnic_info.mc_list); +tpa_alloc_fail: mc_list_alloc_fail: + for (i = i - 1; i >= 0; i--) + free(softc->rx_rings[i].tpa_start, M_DEVBUF); iflib_dma_free(&softc->rx_stats); hw_stats_alloc_fail: free(softc->grp_info, M_DEVBUF); @@ -635,16 +649,6 @@ bnxt_attach_pre(if_ctx_t ctx) if (rc) goto dma_fail; - /* Allocate the TPA start buffer */ - softc->tpa_start = malloc(sizeof(struct bnxt_full_tpa_start) * - (RX_TPA_START_CMPL_AGG_ID_MASK >> RX_TPA_START_CMPL_AGG_ID_SFT), - M_DEVBUF, M_NOWAIT | M_ZERO); - if (softc->tpa_start == NULL) { - rc = ENOMEM; - device_printf(softc->dev, - "Unable to allocate space for TPA\n"); - goto tpa_failed; - } /* Get firmware version and compare with driver */ softc->ver_info = malloc(sizeof(struct bnxt_ver_info), @@ -814,8 +818,6 @@ bnxt_attach_pre(if_ctx_t ctx) ver_fail: free(softc->ver_info, M_DEVBUF); ver_alloc_fail: - free(softc->tpa_start, M_DEVBUF); -tpa_failed: bnxt_free_hwrm_dma_mem(softc); dma_fail: BNXT_HWRM_LOCK_DESTROY(softc); @@ -877,7 +879,8 @@ bnxt_detach(if_ctx_t ctx) SLIST_FOREACH_SAFE(tag, &softc->vnic_info.vlan_tags, next, tmp) free(tag, M_DEVBUF); iflib_dma_free(&softc->def_cp_ring_mem); - free(softc->tpa_start, M_DEVBUF); + for (i = 0; i < softc->nrxqsets; i++) + free(softc->rx_rings[i].tpa_start, M_DEVBUF); free(softc->ver_info, M_DEVBUF); free(softc->nvm_info, M_DEVBUF); @@ -1009,14 +1012,17 @@ bnxt_init(if_ctx_t ctx) if (rc) goto fail; -#ifdef notyet - /* Enable LRO/TPA/GRO */ + /* + * Enable LRO/TPA/GRO + * TBD: + * Enable / Disable HW_LRO based on + * ifconfig lro / ifconfig -lro setting + */ rc = bnxt_hwrm_vnic_tpa_cfg(softc, &softc->vnic_info, (if_getcapenable(iflib_get_ifp(ctx)) & IFCAP_LRO) ? HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA : 0); if (rc) goto fail; -#endif for (i = 0; i < softc->ntxqsets; i++) { /* Allocate the statistics context */ diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c index 5953f27fa800..f0aa3f2a5c01 100644 --- a/sys/dev/bwi/if_bwi.c +++ b/sys/dev/bwi/if_bwi.c @@ -381,6 +381,7 @@ bwi_attach(struct bwi_softc *sc) */ sc->sc_fw_version = BWI_FW_VERSION3; sc->sc_led_idle = (2350 * hz) / 1000; + sc->sc_led_ticks = ticks - sc->sc_led_idle; sc->sc_led_blink = 1; sc->sc_txpwr_calib = 1; #ifdef BWI_DEBUG diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h index c55eb46ddd13..f0d66d9b2ff2 100644 --- a/sys/dev/drm/drmP.h +++ b/sys/dev/drm/drmP.h @@ -104,7 +104,7 @@ struct drm_file; #include "dev/drm/drm_internal.h" #include "dev/drm/drm_linux_list.h" -#include +#include "opt_drm.h" #ifdef DRM_DEBUG #undef DRM_DEBUG #define DRM_DEBUG_DEFAULT_ON 1 @@ -220,7 +220,7 @@ enum { #define PAGE_ALIGN(addr) round_page(addr) /* DRM_SUSER returns true if the user is superuser */ -#define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0) +#define DRM_SUSER(p) (priv_check(p, PRIV_KMEM_WRITE) == 0) #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_MTRR_WC MDF_WRITECOMBINE #define jiffies ticks diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c index fc82ed4aa17b..d2046963df41 100644 --- a/sys/dev/ena/ena.c +++ b/sys/dev/ena/ena.c @@ -156,6 +156,8 @@ static void ena_update_hwassist(struct ena_adapter *); static int ena_setup_ifnet(device_t, struct ena_adapter *, struct ena_com_dev_get_features_ctx *); static void ena_tx_csum(struct ena_com_tx_ctx *, struct mbuf *); +static int ena_check_and_collapse_mbuf(struct ena_ring *tx_ring, + struct mbuf **mbuf); static int ena_xmit_mbuf(struct ena_ring *, struct mbuf **); static void ena_start_xmit(struct ena_ring *); static int ena_mq_start(if_t, struct mbuf *); @@ -226,16 +228,16 @@ ena_dma_alloc(device_t dmadev, bus_size_t size, if (dma_space_addr == 0) dma_space_addr = BUS_SPACE_MAXADDR; error = bus_dma_tag_create(bus_get_dma_tag(dmadev), /* parent */ - 8, 0, /* alignment, bounds */ - dma_space_addr, /* lowaddr */ - dma_space_addr, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - maxsize, /* maxsize */ - 1, /* nsegments */ - maxsize, /* maxsegsize */ - BUS_DMA_ALLOCNOW, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockarg */ + 8, 0, /* alignment, bounds */ + dma_space_addr, /* lowaddr of exclusion window */ + BUS_SPACE_MAXADDR,/* highaddr of exclusion window */ + NULL, NULL, /* filter, filterarg */ + maxsize, /* maxsize */ + 1, /* nsegments */ + maxsize, /* maxsegsize */ + BUS_DMA_ALLOCNOW, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ &dma->tag); if (error) { device_printf(dmadev, @@ -476,7 +478,6 @@ ena_init_io_rings(struct ena_adapter *adapter) device_get_nameunit(adapter->pdev), i); mtx_init(&txr->ring_mtx, txr->mtx_name, NULL, MTX_DEF); - mtx_init(&rxr->ring_mtx, rxr->mtx_name, NULL, MTX_DEF); que = &adapter->que[i]; que->adapter = adapter; @@ -509,7 +510,6 @@ ena_free_io_ring_resources(struct ena_adapter *adapter, unsigned int qid) sizeof(rxr->rx_stats)); mtx_destroy(&txr->ring_mtx); - mtx_destroy(&rxr->ring_mtx); drbr_free(txr->br, M_DEVBUF); @@ -532,16 +532,16 @@ ena_setup_tx_dma_tag(struct ena_adapter *adapter) /* Create DMA tag for Tx buffers */ ret = bus_dma_tag_create(bus_get_dma_tag(adapter->pdev), - 1, 0, /* alignment, bounds */ - ENA_DMA_BIT_MASK(adapter->dma_width), /* lowaddr */ - ENA_DMA_BIT_MASK(adapter->dma_width), /* highaddr */ - NULL, NULL, /* filter, filterarg */ - ENA_TSO_MAXSIZE, /* maxsize */ - adapter->max_tx_sgl_size, /* nsegments */ - ENA_TSO_MAXSIZE, /* maxsegsize */ - 0, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockfuncarg */ + 1, 0, /* alignment, bounds */ + ENA_DMA_BIT_MASK(adapter->dma_width), /* lowaddr of excl window */ + BUS_SPACE_MAXADDR, /* highaddr of excl window */ + NULL, NULL, /* filter, filterarg */ + ENA_TSO_MAXSIZE, /* maxsize */ + adapter->max_tx_sgl_size - 1, /* nsegments */ + ENA_TSO_MAXSIZE, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockfuncarg */ &adapter->tx_buf_tag); if (ret != 0) @@ -569,17 +569,17 @@ ena_setup_rx_dma_tag(struct ena_adapter *adapter) int ret; /* Create DMA tag for Rx buffers*/ - ret = bus_dma_tag_create(bus_get_dma_tag(adapter->pdev), /* parent */ - 1, 0, /* alignment, bounds */ - ENA_DMA_BIT_MASK(adapter->dma_width), /* lowaddr */ - ENA_DMA_BIT_MASK(adapter->dma_width), /* highaddr */ - NULL, NULL, /* filter, filterarg */ - MJUM16BYTES, /* maxsize */ - 1, /* nsegments */ - MJUM16BYTES, /* maxsegsize */ - 0, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockarg */ + ret = bus_dma_tag_create(bus_get_dma_tag(adapter->pdev), /* parent */ + 1, 0, /* alignment, bounds */ + ENA_DMA_BIT_MASK(adapter->dma_width), /* lowaddr of excl window */ + BUS_SPACE_MAXADDR, /* highaddr of excl window */ + NULL, NULL, /* filter, filterarg */ + MJUM16BYTES, /* maxsize */ + 1, /* nsegments */ + MJUM16BYTES, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ &adapter->rx_buf_tag); if (ret != 0) @@ -642,7 +642,9 @@ ena_setup_tx_resources(struct ena_adapter *adapter, int qid) tx_ring->next_to_clean = 0; /* Make sure that drbr is empty */ + ENA_RING_MTX_LOCK(tx_ring); drbr_flush(adapter->ifp, tx_ring->br); + ENA_RING_MTX_UNLOCK(tx_ring); /* ... and create the buffer DMA maps */ for (i = 0; i < tx_ring->ring_size; i++) { @@ -709,11 +711,11 @@ ena_free_tx_resources(struct ena_adapter *adapter, int qid) taskqueue_free(tx_ring->enqueue_tq); + ENA_RING_MTX_LOCK(tx_ring); /* Flush buffer ring, */ drbr_flush(adapter->ifp, tx_ring->br); /* Free buffer DMA maps, */ - ENA_RING_MTX_LOCK(tx_ring); for (int i = 0; i < tx_ring->ring_size; i++) { m_freem(tx_ring->tx_buffer_info[i].mbuf); tx_ring->tx_buffer_info[i].mbuf = NULL; @@ -945,10 +947,8 @@ ena_alloc_rx_mbuf(struct ena_adapter *adapter, if (rx_info->mbuf != NULL) return (0); - ENA_RING_MTX_LOCK(rx_ring); /* Get mbuf using UMA allocator */ rx_info->mbuf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM16BYTES); - ENA_RING_MTX_UNLOCK(rx_ring); if (!rx_info->mbuf) { counter_u64_add(rx_ring->rx_stats.mbuf_alloc_fail, 1); @@ -1032,7 +1032,7 @@ ena_refill_rx_bufs(struct ena_ring *rx_ring, uint32_t num) &rx_ring->rx_buffer_info[next_to_use]; rc = ena_alloc_rx_mbuf(adapter, rx_ring, rx_info); - if (rc < 0) { + if (rc != 0) { device_printf(adapter->pdev, "failed to alloc buffer for rx queue\n"); break; @@ -2095,7 +2095,6 @@ ena_up_complete(struct ena_adapter *adapter) ena_change_mtu(adapter->ifp, adapter->ifp->if_mtu); ena_refill_all_rx_bufs(adapter); - ena_unmask_all_io_irqs(adapter); return (0); } @@ -2168,6 +2167,8 @@ ena_up(struct ena_adapter *adapter) taskqueue_enqueue(adapter->stats_tq, &adapter->stats_task); adapter->up = true; + + ena_unmask_all_io_irqs(adapter); } return (0); @@ -2276,8 +2277,11 @@ ena_init(void *arg) { struct ena_adapter *adapter = (struct ena_adapter *)arg; - if (adapter->up == false) + if (adapter->up == false) { + sx_xlock(&adapter->ioctl_sx); ena_up(adapter); + sx_unlock(&adapter->ioctl_sx); + } return; } @@ -2477,9 +2481,10 @@ ena_setup_ifnet(device_t pdev, struct ena_adapter *adapter, if_setcapabilitiesbit(ifp, caps, 0); /* TSO parameters */ - ifp->if_hw_tsomax = ENA_TSO_MAXSIZE; - ifp->if_hw_tsomaxsegcount = ENA_TSO_NSEGS; - ifp->if_hw_tsomaxsegsize = MCLBYTES; + ifp->if_hw_tsomax = ENA_TSO_MAXSIZE - + (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); + ifp->if_hw_tsomaxsegcount = adapter->max_tx_sgl_size - 1; + ifp->if_hw_tsomaxsegsize = ENA_TSO_MAXSIZE; if_setifheaderlen(ifp, sizeof(struct ether_vlan_header)); if_setcapenable(ifp, if_getcapabilities(ifp)); @@ -2620,10 +2625,10 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct mbuf *mbuf) } static int -ena_check_and_defragment_mbuf(struct ena_ring *tx_ring, struct mbuf **mbuf) +ena_check_and_collapse_mbuf(struct ena_ring *tx_ring, struct mbuf **mbuf) { struct ena_adapter *adapter; - struct mbuf *defrag_mbuf; + struct mbuf *collapsed_mbuf; int num_frags; adapter = tx_ring->adapter; @@ -2632,16 +2637,17 @@ ena_check_and_defragment_mbuf(struct ena_ring *tx_ring, struct mbuf **mbuf) /* One segment must be reserved for configuration descriptor. */ if (num_frags < adapter->max_tx_sgl_size) return (0); - counter_u64_add(tx_ring->tx_stats.defragment, 1); + counter_u64_add(tx_ring->tx_stats.collapse, 1); - defrag_mbuf = m_defrag(*mbuf, M_NOWAIT); - if (defrag_mbuf == NULL) { - counter_u64_add(tx_ring->tx_stats.defragment_err, 1); + collapsed_mbuf = m_collapse(*mbuf, M_NOWAIT, + adapter->max_tx_sgl_size - 1); + if (collapsed_mbuf == NULL) { + counter_u64_add(tx_ring->tx_stats.collapse_err, 1); return (ENOMEM); } - /* If mbuf was defragmented succesfully, original mbuf is released. */ - *mbuf = defrag_mbuf; + /* If mbuf was collapsed succesfully, original mbuf is released. */ + *mbuf = collapsed_mbuf; return (0); } @@ -2672,10 +2678,10 @@ ena_xmit_mbuf(struct ena_ring *tx_ring, struct mbuf **mbuf) ENA_ASSERT(*mbuf, "mbuf is NULL\n"); - rc = ena_check_and_defragment_mbuf(tx_ring, mbuf); + rc = ena_check_and_collapse_mbuf(tx_ring, mbuf); if (rc) { ena_trace(ENA_WARNING, - "Failed to defragment mbuf! err: %d", rc); + "Failed to collapse mbuf! err: %d", rc); return (rc); } @@ -2799,10 +2805,11 @@ ena_start_xmit(struct ena_ring *tx_ring) break; } + drbr_advance(adapter->ifp, tx_ring->br); + if ((adapter->ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - drbr_advance(adapter->ifp, tx_ring->br); acum_pkts++; BPF_MTAP(adapter->ifp, mbuf); diff --git a/sys/dev/ena/ena.h b/sys/dev/ena/ena.h index a20498546db8..22701d8e20c9 100644 --- a/sys/dev/ena/ena.h +++ b/sys/dev/ena/ena.h @@ -112,7 +112,7 @@ #define TX_IRQ_INTERVAL 50 #define ENA_MAX_MTU 9216 -#define ENA_TSO_MAXSIZE PAGE_SIZE +#define ENA_TSO_MAXSIZE 65536 #define ENA_TSO_NSEGS ENA_PKT_MAX_BUFS #define ENA_RX_OFFSET NET_SKB_PAD + NET_IP_ALIGN @@ -226,8 +226,8 @@ struct ena_stats_tx { counter_u64_t doorbells; counter_u64_t missing_tx_comp; counter_u64_t bad_req_id; - counter_u64_t defragment; - counter_u64_t defragment_err; + counter_u64_t collapse; + counter_u64_t collapse_err; }; struct ena_stats_rx { diff --git a/sys/dev/ena/ena_sysctl.c b/sys/dev/ena/ena_sysctl.c index 5fc1894c9673..859ef2aed699 100644 --- a/sys/dev/ena/ena_sysctl.c +++ b/sys/dev/ena/ena_sysctl.c @@ -156,13 +156,13 @@ ena_sysctl_add_stats(struct ena_adapter *adapter) "stops", CTLFLAG_RD, &tx_stats->queue_stop, "Queue stops"); SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, - "defragmentations", CTLFLAG_RD, - &tx_stats->defragment, - "Mbuf defragmentations"); + "mbuf_collapses", CTLFLAG_RD, + &tx_stats->collapse, + "Mbuf collapse count"); SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, - "defragmentation_err", CTLFLAG_RD, - &tx_stats->defragment_err, - "Mbuf defragmentation failures"); + "mbuf_collapse_err", CTLFLAG_RD, + &tx_stats->collapse_err, + "Mbuf collapse failures"); /* RX specific stats */ rx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, diff --git a/sys/dev/hptmv/vdevice.h b/sys/dev/hptmv/vdevice.h index e0bddc7d1e6e..c7f96da8d480 100644 --- a/sys/dev/hptmv/vdevice.h +++ b/sys/dev/hptmv/vdevice.h @@ -77,8 +77,8 @@ typedef struct _VDevice } VDevice; -#define ARRAY_VDEV_SIZE ((UINT)(ULONG_PTR)&((PVDevice)0)->u+sizeof(RaidArray)) -#define DISK_VDEV_SIZE ((UINT)(ULONG_PTR)&((PVDevice)0)->u+sizeof(Device)) +#define ARRAY_VDEV_SIZE (offsetof(VDevice, u) + sizeof(RaidArray)) +#define DISK_VDEV_SIZE (offsetof(VDevice, u) + sizeof(Device)) #define Map2pVDevice(pDev) ((PVDevice)((UINT_PTR)pDev - (UINT)(UINT_PTR)&((PVDevice)0)->u.disk)) diff --git a/sys/dev/iicbus/ad7418.c b/sys/dev/iicbus/ad7418.c index dcb8b958de47..82a8018c8f46 100644 --- a/sys/dev/iicbus/ad7418.c +++ b/sys/dev/iicbus/ad7418.c @@ -120,6 +120,8 @@ ad7418_attach(device_t dev) int conf; sc->sc_dev = dev; + sc->sc_lastupdate = ticks - hz; + sx_init(&sc->sc_lock, "ad7418"); SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, diff --git a/sys/dev/isci/environment.h b/sys/dev/isci/environment.h index 5c9374ca8717..63bd0e89eee4 100644 --- a/sys/dev/isci/environment.h +++ b/sys/dev/isci/environment.h @@ -42,7 +42,7 @@ #include #include #include -#include +#include "opt_isci.h" typedef int8_t S8; typedef uint8_t U8; diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index f1fb54ad118e..0a39aec0b8a4 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -117,13 +118,11 @@ static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int); static int isp_fclink_test(ispsoftc_t *, int, int); static int isp_pdb_sync(ispsoftc_t *, int); static int isp_scan_loop(ispsoftc_t *, int); -static int isp_gid_ft_sns(ispsoftc_t *, int); -static int isp_gid_ft_ct_passthru(ispsoftc_t *, int); +static int isp_gid_pt(ispsoftc_t *, int); static int isp_scan_fabric(ispsoftc_t *, int); static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *); static int isp_send_change_request(ispsoftc_t *, int); static int isp_register_fc4_type(ispsoftc_t *, int); -static int isp_register_fc4_type_24xx(ispsoftc_t *, int); static int isp_register_fc4_features_24xx(ispsoftc_t *, int); static int isp_register_port_name_24xx(ispsoftc_t *, int); static int isp_register_node_name_24xx(ispsoftc_t *, int); @@ -3042,7 +3041,7 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) if (IS_24XX(isp)) { fcp->isp_fabric_params = mbs.param[7]; fcp->isp_sns_hdl = NPH_SNS_ID; - r = isp_register_fc4_type_24xx(isp, chan); + r = isp_register_fc4_type(isp, chan); if (fcp->isp_loopstate < LOOP_TESTING_LINK) goto abort; if (r != 0) @@ -3403,54 +3402,18 @@ isp_scan_loop(ispsoftc_t *isp, int chan) return (0); } -/* - * Scan the fabric for devices and add them to our port database. - * - * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows. - * - * For 2100-23XX cards, we use the SNS mailbox command to pass simple name - * server commands to the switch management server via the QLogic f/w. - * - * For the 24XX and above card, we use CT Pass-through IOCB. - */ -#define GIDLEN ISP_FC_SCRLEN -#define NGENT ((GIDLEN - 16) >> 2) - static int -isp_gid_ft_sns(ispsoftc_t *isp, int chan) +isp_ct_sns(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt) { - union { - sns_gid_ft_req_t _x; - uint8_t _y[SNS_GID_FT_REQ_SIZE]; - } un; fcparam *fcp = FCPARAM(isp, chan); - sns_gid_ft_req_t *rq = &un._x; - uint8_t *scp = fcp->isp_scratch; mbreg_t mbs; - isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_FT via SNS", chan); - if (FC_SCRATCH_ACQUIRE(isp, chan)) { - isp_prt(isp, ISP_LOGERR, sacq); - return (-1); - } - - ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE); - rq->snscb_rblen = GIDLEN >> 1; - rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma); - rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma); - rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma); - rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma); - rq->snscb_sblen = 6; - rq->snscb_cmd = SNS_GID_FT; - rq->snscb_mword_div_2 = NGENT; - rq->snscb_fc4_type = FC4_SCSI; - - isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *)scp); - MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan); + if (isp->isp_dblev & ISP_LOGDEBUG1) + isp_print_bytes(isp, "CT SNS request", cmd_bcnt, fcp->isp_scratch); + MEMORYBARRIER(isp, SYNC_SFORDEV, 0, cmd_bcnt, chan); MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000); - mbs.param[0] = MBOX_SEND_SNS; - mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1; + mbs.param[1] = cmd_bcnt >> 1; mbs.param[2] = DMA_WD1(fcp->isp_scdma); mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); @@ -3463,12 +3426,10 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan) return (-1); } } - MEMORYBARRIER(isp, SYNC_SFORCPU, 0, GIDLEN, chan); + + MEMORYBARRIER(isp, SYNC_SFORCPU, 0, rsp_bcnt, chan); if (isp->isp_dblev & ISP_LOGDEBUG1) - isp_print_bytes(isp, "CT response", GIDLEN, scp); - isp_get_gid_ft_response(isp, (sns_gid_ft_rsp_t *)scp, - (sns_gid_ft_rsp_t *)fcp->isp_scanscratch, NGENT); - FC_SCRATCH_RELEASE(isp, chan); + isp_print_bytes(isp, "CT response", rsp_bcnt, fcp->isp_scratch); return (0); } @@ -3480,6 +3441,9 @@ isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt) void *reqp; uint8_t resp[QENTRY_LEN]; + if (isp->isp_dblev & ISP_LOGDEBUG1) + isp_print_bytes(isp, "CT request", cmd_bcnt, fcp->isp_scratch); + /* * Build a Passthrough IOCB in memory. */ @@ -3533,56 +3497,224 @@ isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt) isp_get_ct_pt(isp, (isp_ct_pt_t *)resp, &pt); if (pt.ctp_status && pt.ctp_status != RQCS_DATA_UNDERRUN) { isp_prt(isp, ISP_LOGWARN, - "Chan %d GID_FT CT Passthrough returned 0x%x", + "Chan %d CT pass-through returned 0x%x", chan, pt.ctp_status); return (-1); } + if (isp->isp_dblev & ISP_LOGDEBUG1) + isp_print_bytes(isp, "CT response", rsp_bcnt, fcp->isp_scratch); + return (0); } +/* + * Scan the fabric for devices and add them to our port database. + * + * Use the GID_PT command to get list of all Nx_Port IDs SNS knows. + * Use GFF_ID and GFT_ID to check port type (FCP) and features (target). + * + * For 2100-23XX cards, we use the SNS mailbox command to pass simple name + * server commands to the switch management server via the QLogic f/w. + * + * For the 24XX and above card, we use CT Pass-through IOCB. + */ +#define GIDLEN ISP_FC_SCRLEN +#define NGENT ((GIDLEN - 16) >> 2) + static int -isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan) +isp_gid_pt(ispsoftc_t *isp, int chan) { fcparam *fcp = FCPARAM(isp, chan); ct_hdr_t ct; - uint32_t *rp; + sns_gid_pt_req_t rq; uint8_t *scp = fcp->isp_scratch; - isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_FT via CT", chan); + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_PT", chan); if (FC_SCRATCH_ACQUIRE(isp, chan)) { isp_prt(isp, ISP_LOGERR, sacq); return (-1); } - /* - * Build the CT header and command in memory. - */ + if (IS_24XX(isp)) { + /* Build the CT command and execute via pass-through. */ + ISP_MEMZERO(&ct, sizeof (ct)); + ct.ct_revision = CT_REVISION; + ct.ct_fcs_type = CT_FC_TYPE_FC; + ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS; + ct.ct_cmd_resp = SNS_GID_PT; + ct.ct_bcnt_resid = (GIDLEN - 16) >> 2; + isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); + scp[sizeof(ct)] = 0x7f; /* Port Type = Nx_Port */ + scp[sizeof(ct)+1] = 0; /* Domain_ID = any */ + scp[sizeof(ct)+2] = 0; /* Area_ID = any */ + scp[sizeof(ct)+3] = 0; /* Flags = no Area_ID */ + + if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) { + FC_SCRATCH_RELEASE(isp, chan); + return (-1); + } + } else { + /* Build the SNS request and execute via firmware. */ + ISP_MEMZERO(&rq, SNS_GID_PT_REQ_SIZE); + rq.snscb_rblen = GIDLEN >> 1; + rq.snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma); + rq.snscb_sblen = 6; + rq.snscb_cmd = SNS_GID_PT; + rq.snscb_mword_div_2 = NGENT; + rq.snscb_port_type = 0x7f; /* Port Type = Nx_Port */ + rq.snscb_domain = 0; /* Domain_ID = any */ + rq.snscb_area = 0; /* Area_ID = any */ + rq.snscb_flags = 0; /* Flags = no Area_ID */ + isp_put_gid_pt_request(isp, &rq, (sns_gid_pt_req_t *)scp); + + if (isp_ct_sns(isp, chan, sizeof(rq), NGENT)) { + FC_SCRATCH_RELEASE(isp, chan); + return (-1); + } + } + + isp_get_gid_xx_response(isp, (sns_gid_xx_rsp_t *)scp, + (sns_gid_xx_rsp_t *)fcp->isp_scanscratch, NGENT); + FC_SCRATCH_RELEASE(isp, chan); + return (0); +} + +static int +isp_gff_id(ispsoftc_t *isp, int chan, uint32_t portid) +{ + fcparam *fcp = FCPARAM(isp, chan); + ct_hdr_t ct; + uint32_t *rp; + uint8_t *scp = fcp->isp_scratch; + sns_gff_id_rsp_t rsp; + int i, res = -1; + + if (!fcp->isp_use_gff_id) /* User may block GFF_ID use. */ + return (res); + + if (!IS_24XX(isp)) /* Old chips can't request GFF_ID. */ + return (res); + + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFF_ID", chan); + if (FC_SCRATCH_ACQUIRE(isp, chan)) { + isp_prt(isp, ISP_LOGERR, sacq); + return (res); + } + + /* Build the CT command and execute via pass-through. */ ISP_MEMZERO(&ct, sizeof (ct)); ct.ct_revision = CT_REVISION; ct.ct_fcs_type = CT_FC_TYPE_FC; ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS; - ct.ct_cmd_resp = SNS_GID_FT; - ct.ct_bcnt_resid = (GIDLEN - 16) >> 2; + ct.ct_cmd_resp = SNS_GFF_ID; + ct.ct_bcnt_resid = (SNS_GFF_ID_RESP_SIZE - sizeof(ct)) / 4; isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); rp = (uint32_t *) &scp[sizeof(ct)]; - ISP_IOZPUT_32(isp, FC4_SCSI, rp); - if (isp->isp_dblev & ISP_LOGDEBUG1) { - isp_print_bytes(isp, "CT request", - sizeof(ct) + sizeof(uint32_t), scp); - } + ISP_IOZPUT_32(isp, portid, rp); - if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) { + if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), + SNS_GFF_ID_RESP_SIZE)) { FC_SCRATCH_RELEASE(isp, chan); - return (-1); + return (res); } - if (isp->isp_dblev & ISP_LOGDEBUG1) - isp_print_bytes(isp, "CT response", GIDLEN, scp); - isp_get_gid_ft_response(isp, (sns_gid_ft_rsp_t *)scp, - (sns_gid_ft_rsp_t *)fcp->isp_scanscratch, NGENT); + isp_get_gff_id_response(isp, (sns_gff_id_rsp_t *)scp, &rsp); + if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) { + for (i = 0; i < 32; i++) { + if (rsp.snscb_fc4_features[i] != 0) { + res = 0; + break; + } + } + if (((rsp.snscb_fc4_features[FC4_SCSI / 8] >> + ((FC4_SCSI % 8) * 4)) & 0x01) != 0) + res = 1; + /* Workaround for broken Brocade firmware. */ + if (((ISP_SWAP32(isp, rsp.snscb_fc4_features[FC4_SCSI / 8]) >> + ((FC4_SCSI % 8) * 4)) & 0x01) != 0) + res = 1; + } FC_SCRATCH_RELEASE(isp, chan); - return (0); + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFF_ID result is %d", chan, res); + return (res); +} + +static int +isp_gft_id(ispsoftc_t *isp, int chan, uint32_t portid) +{ + fcparam *fcp = FCPARAM(isp, chan); + ct_hdr_t ct; + sns_gxx_id_req_t rq; + uint32_t *rp; + uint8_t *scp = fcp->isp_scratch; + sns_gft_id_rsp_t rsp; + int i, res = -1; + + if (!fcp->isp_use_gft_id) /* User may block GFT_ID use. */ + return (res); + + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFT_ID", chan); + if (FC_SCRATCH_ACQUIRE(isp, chan)) { + isp_prt(isp, ISP_LOGERR, sacq); + return (res); + } + + if (IS_24XX(isp)) { + /* Build the CT command and execute via pass-through. */ + ISP_MEMZERO(&ct, sizeof (ct)); + ct.ct_revision = CT_REVISION; + ct.ct_fcs_type = CT_FC_TYPE_FC; + ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS; + ct.ct_cmd_resp = SNS_GFT_ID; + ct.ct_bcnt_resid = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4; + isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); + rp = (uint32_t *) &scp[sizeof(ct)]; + ISP_IOZPUT_32(isp, portid, rp); + + if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), + SNS_GFT_ID_RESP_SIZE)) { + FC_SCRATCH_RELEASE(isp, chan); + return (res); + } + } else { + /* Build the SNS request and execute via firmware. */ + ISP_MEMZERO(&rq, SNS_GXX_ID_REQ_SIZE); + rq.snscb_rblen = SNS_GFT_ID_RESP_SIZE >> 1; + rq.snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma); + rq.snscb_sblen = 6; + rq.snscb_cmd = SNS_GFT_ID; + rq.snscb_mword_div_2 = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4; + rq.snscb_portid = portid; + isp_put_gxx_id_request(isp, &rq, (sns_gxx_id_req_t *)scp); + + if (isp_ct_sns(isp, chan, sizeof(rq), SNS_GFT_ID_RESP_SIZE)) { + FC_SCRATCH_RELEASE(isp, chan); + return (res); + } + } + + isp_get_gft_id_response(isp, (sns_gft_id_rsp_t *)scp, &rsp); + if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) { + for (i = 0; i < 8; i++) { + if (rsp.snscb_fc4_types[i] != 0) { + res = 0; + break; + } + } + if (((rsp.snscb_fc4_types[FC4_SCSI / 32] >> + (FC4_SCSI % 32)) & 0x01) != 0) + res = 1; + } + FC_SCRATCH_RELEASE(isp, chan); + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFT_ID result is %d", chan, res); + return (res); } static int @@ -3594,7 +3726,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) uint16_t nphdl; isp_pdb_t pdb; int portidx, portlim, r; - sns_gid_ft_rsp_t *rs; + sns_gid_xx_rsp_t *rs; if (fcp->isp_loopstate < LOOP_LSCAN_DONE) return (-1); @@ -3635,10 +3767,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) } /* Get list of port IDs from SNS. */ - if (IS_24XX(isp)) - r = isp_gid_ft_ct_passthru(isp, chan); - else - r = isp_gid_ft_sns(isp, chan); + r = isp_gid_pt(isp, chan); if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) goto abort; if (r > 0) { @@ -3649,17 +3778,20 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) return (-1); } - rs = (sns_gid_ft_rsp_t *) fcp->isp_scanscratch; + rs = (sns_gid_xx_rsp_t *) fcp->isp_scanscratch; if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) goto abort; if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) { int level; - if (rs->snscb_cthdr.ct_reason == 9 && rs->snscb_cthdr.ct_explanation == 7) { + /* FC-4 Type and Port Type not registered are not errors. */ + if (rs->snscb_cthdr.ct_reason == 9 && + (rs->snscb_cthdr.ct_explanation == 0x07 || + rs->snscb_cthdr.ct_explanation == 0x0a)) { level = ISP_LOG_SANCFG; } else { level = ISP_LOGWARN; } - isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT" + isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_PT" " (Reason=0x%x Expl=0x%x)", chan, rs->snscb_cthdr.ct_reason, rs->snscb_cthdr.ct_explanation); @@ -3791,6 +3923,20 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) continue; } + r = isp_gff_id(isp, chan, portid); + if (r == 0) { + isp_prt(isp, ISP_LOG_SANCFG, + "Chan %d Port 0x%06x is not an FCP target", chan, portid); + continue; + } + if (r < 0) + r = isp_gft_id(isp, chan, portid); + if (r == 0) { + isp_prt(isp, ISP_LOG_SANCFG, + "Chan %d Port 0x%06x is not FCP", chan, portid); + continue; + } + if (isp_login_device(isp, chan, portid, &pdb, &FCPARAM(isp, 0)->isp_lasthdl)) { if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) @@ -3918,50 +4064,10 @@ static int isp_register_fc4_type(ispsoftc_t *isp, int chan) { fcparam *fcp = FCPARAM(isp, chan); + rft_id_t rp; + ct_hdr_t *ct = &rp.rftid_hdr; uint8_t local[SNS_RFT_ID_REQ_SIZE]; sns_screq_t *reqp = (sns_screq_t *) local; - mbreg_t mbs; - - ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); - reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1; - reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); - reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100); - reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100); - reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100); - reqp->snscb_sblen = 22; - reqp->snscb_data[0] = SNS_RFT_ID; - reqp->snscb_data[4] = fcp->isp_portid & 0xffff; - reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff; - reqp->snscb_data[6] = (1 << FC4_SCSI); - if (FC_SCRATCH_ACQUIRE(isp, chan)) { - isp_prt(isp, ISP_LOGERR, sacq); - return (-1); - } - isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch); - MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000); - mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1; - mbs.param[2] = DMA_WD1(fcp->isp_scdma); - mbs.param[3] = DMA_WD0(fcp->isp_scdma); - mbs.param[6] = DMA_WD3(fcp->isp_scdma); - mbs.param[7] = DMA_WD2(fcp->isp_scdma); - MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE, chan); - isp_mboxcmd(isp, &mbs); - FC_SCRATCH_RELEASE(isp, chan); - if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { - return (0); - } else { - isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", - chan, mbs.param[0]); - return (-1); - } -} - -static int -isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan) -{ - fcparam *fcp = FCPARAM(isp, chan); - ct_hdr_t *ct; - rft_id_t rp; uint8_t *scp = fcp->isp_scratch; if (FC_SCRATCH_ACQUIRE(isp, chan)) { @@ -3969,27 +4075,43 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan) return (-1); } - /* - * Build the CT header and command in memory. - */ - ISP_MEMZERO(&rp, sizeof(rp)); - ct = &rp.rftid_hdr; - ct->ct_revision = CT_REVISION; - ct->ct_fcs_type = CT_FC_TYPE_FC; - ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; - ct->ct_cmd_resp = SNS_RFT_ID; - ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2; - rp.rftid_portid[0] = fcp->isp_portid >> 16; - rp.rftid_portid[1] = fcp->isp_portid >> 8; - rp.rftid_portid[2] = fcp->isp_portid; - rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f); - isp_put_rft_id(isp, &rp, (rft_id_t *)scp); - if (isp->isp_dblev & ISP_LOGDEBUG1) - isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp); + if (IS_24XX(isp)) { + /* Build the CT command and execute via pass-through. */ + ISP_MEMZERO(&rp, sizeof(rp)); + ct->ct_revision = CT_REVISION; + ct->ct_fcs_type = CT_FC_TYPE_FC; + ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; + ct->ct_cmd_resp = SNS_RFT_ID; + ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2; + rp.rftid_portid[0] = fcp->isp_portid >> 16; + rp.rftid_portid[1] = fcp->isp_portid >> 8; + rp.rftid_portid[2] = fcp->isp_portid; + rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f); + isp_put_rft_id(isp, &rp, (rft_id_t *)scp); - if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) { - FC_SCRATCH_RELEASE(isp, chan); - return (-1); + if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) { + FC_SCRATCH_RELEASE(isp, chan); + return (-1); + } + } else { + /* Build the SNS request and execute via firmware. */ + ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); + reqp->snscb_rblen = sizeof (ct_hdr_t) >> 1; + reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma); + reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma); + reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma); + reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma); + reqp->snscb_sblen = 22; + reqp->snscb_data[0] = SNS_RFT_ID; + reqp->snscb_data[4] = fcp->isp_portid & 0xffff; + reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff; + reqp->snscb_data[6] = (1 << FC4_SCSI); + isp_put_sns_request(isp, reqp, (sns_screq_t *)scp); + + if (isp_ct_sns(isp, chan, SNS_RFT_ID_REQ_SIZE, sizeof(ct_hdr_t))) { + FC_SCRATCH_RELEASE(isp, chan); + return (-1); + } } isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct); @@ -4105,8 +4227,6 @@ isp_register_port_name_24xx(ispsoftc_t *isp, int chan) len += rp.rspnid_length; ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2; isp_put_rspn_id(isp, &rp, (rspn_id_t *)scp); - if (isp->isp_dblev & ISP_LOGDEBUG1) - isp_print_bytes(isp, "CT request", len, scp); if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) { FC_SCRATCH_RELEASE(isp, chan); @@ -4163,8 +4283,6 @@ isp_register_node_name_24xx(ispsoftc_t *isp, int chan) len += rp.rsnnnn_length; ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2; isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)scp); - if (isp->isp_dblev & ISP_LOGDEBUG1) - isp_print_bytes(isp, "CT request", len, scp); if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) { FC_SCRATCH_RELEASE(isp, chan); diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 9e904da35184..354d2d4aa03f 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -169,6 +170,8 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) fc->path = path; fc->isp = isp; fc->ready = 1; + fcp->isp_use_gft_id = 1; + fcp->isp_use_gff_id = 1; callout_init_mtx(&fc->gdt, &isp->isp_lock, 0); TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc); @@ -235,6 +238,12 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "topo", CTLFLAG_RD, &fcp->isp_topo, 0, "Connection topology"); + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "use_gft_id", CTLFLAG_RWTUN, &fcp->isp_use_gft_id, 0, + "Use GFT_ID during fabric scan"); + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "use_gff_id", CTLFLAG_RWTUN, &fcp->isp_use_gff_id, 0, + "Use GFF_ID during fabric scan"); } return (0); } diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c index 83cf39217e90..72e2f179e3f2 100644 --- a/sys/dev/isp/isp_library.c +++ b/sys/dev/isp/isp_library.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -1742,7 +1743,7 @@ isp_put_gid_ft_request(ispsoftc_t *isp, sns_gid_ft_req_t *src, sns_gid_ft_req_t } void -isp_put_gxn_id_request(ispsoftc_t *isp, sns_gxn_id_req_t *src, sns_gxn_id_req_t *dst) +isp_put_gid_pt_request(ispsoftc_t *isp, sns_gid_pt_req_t *src, sns_gid_pt_req_t *dst) { ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen); ISP_IOXPUT_16(isp, src->snscb_reserved0, &dst->snscb_reserved0); @@ -1753,48 +1754,46 @@ isp_put_gxn_id_request(ispsoftc_t *isp, sns_gxn_id_req_t *src, sns_gxn_id_req_t ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen); ISP_IOXPUT_16(isp, src->snscb_reserved1, &dst->snscb_reserved1); ISP_IOXPUT_16(isp, src->snscb_cmd, &dst->snscb_cmd); - ISP_IOXPUT_16(isp, src->snscb_reserved2, &dst->snscb_reserved2); + ISP_IOXPUT_16(isp, src->snscb_mword_div_2, &dst->snscb_mword_div_2); + ISP_IOXPUT_32(isp, src->snscb_reserved3, &dst->snscb_reserved3); + ISP_IOXPUT_8(isp, src->snscb_port_type, &dst->snscb_port_type); + ISP_IOXPUT_8(isp, src->snscb_domain, &dst->snscb_domain); + ISP_IOXPUT_8(isp, src->snscb_area, &dst->snscb_area); + ISP_IOXPUT_8(isp, src->snscb_flags, &dst->snscb_flags); +} + +void +isp_put_gxx_id_request(ispsoftc_t *isp, sns_gxx_id_req_t *src, sns_gxx_id_req_t *dst) +{ + ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen); + ISP_IOXPUT_16(isp, src->snscb_reserved0, &dst->snscb_reserved0); + ISP_IOXPUT_16(isp, src->snscb_addr[0], &dst->snscb_addr[0]); + ISP_IOXPUT_16(isp, src->snscb_addr[1], &dst->snscb_addr[1]); + ISP_IOXPUT_16(isp, src->snscb_addr[2], &dst->snscb_addr[2]); + ISP_IOXPUT_16(isp, src->snscb_addr[3], &dst->snscb_addr[3]); + ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen); + ISP_IOXPUT_16(isp, src->snscb_reserved1, &dst->snscb_reserved1); + ISP_IOXPUT_16(isp, src->snscb_cmd, &dst->snscb_cmd); + ISP_IOXPUT_16(isp, src->snscb_mword_div_2, &dst->snscb_mword_div_2); ISP_IOXPUT_32(isp, src->snscb_reserved3, &dst->snscb_reserved3); ISP_IOXPUT_32(isp, src->snscb_portid, &dst->snscb_portid); } -/* - * Generic SNS response - not particularly useful since the per-command data - * isn't always 16 bit words. - */ void -isp_get_sns_response(ispsoftc_t *isp, sns_scrsp_t *src, sns_scrsp_t *dst, int nwords) +isp_get_gid_xx_response(ispsoftc_t *isp, sns_gid_xx_rsp_t *src, sns_gid_xx_rsp_t *dst, int nwords) { - int i; - isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); - ISP_IOXGET_8(isp, &src->snscb_port_type, dst->snscb_port_type); - for (i = 0; i < 3; i++) { - ISP_IOXGET_8(isp, &src->snscb_port_id[i], - dst->snscb_port_id[i]); - } - for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_portname[i], - dst->snscb_portname[i]); - } - for (i = 0; i < nwords; i++) { - ISP_IOXGET_16(isp, &src->snscb_data[i], dst->snscb_data[i]); - } -} + int i, j; -void -isp_get_gid_ft_response(ispsoftc_t *isp, sns_gid_ft_rsp_t *src, sns_gid_ft_rsp_t *dst, int nwords) -{ - int i; isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); for (i = 0; i < nwords; i++) { - int j; - ISP_IOXGET_8(isp, &src->snscb_ports[i].control, dst->snscb_ports[i].control); + ISP_IOZGET_8(isp, &src->snscb_ports[i].control, + dst->snscb_ports[i].control); for (j = 0; j < 3; j++) { - ISP_IOXGET_8(isp, &src->snscb_ports[i].portid[j], dst->snscb_ports[i].portid[j]); + ISP_IOZGET_8(isp, &src->snscb_ports[i].portid[j], + dst->snscb_ports[i].portid[j]); } - if (dst->snscb_ports[i].control & 0x80) { + if (dst->snscb_ports[i].control & 0x80) break; - } } } @@ -1802,9 +1801,21 @@ void isp_get_gxn_id_response(ispsoftc_t *isp, sns_gxn_id_rsp_t *src, sns_gxn_id_rsp_t *dst) { int i; + + isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); + for (i = 0; i < 8; i++) + ISP_IOZGET_8(isp, &src->snscb_wwn[i], dst->snscb_wwn[i]); +} + +void +isp_get_gft_id_response(ispsoftc_t *isp, sns_gft_id_rsp_t *src, sns_gft_id_rsp_t *dst) +{ + int i; + isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_wwn[i], dst->snscb_wwn[i]); + ISP_IOZGET_32(isp, &src->snscb_fc4_types[i], + dst->snscb_fc4_types[i]); } } @@ -1812,9 +1823,11 @@ void isp_get_gff_id_response(ispsoftc_t *isp, sns_gff_id_rsp_t *src, sns_gff_id_rsp_t *dst) { int i; + isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); for (i = 0; i < 32; i++) { - ISP_IOXGET_32(isp, &src->snscb_fc4_features[i], dst->snscb_fc4_features[i]); + ISP_IOZGET_32(isp, &src->snscb_fc4_features[i], + dst->snscb_fc4_features[i]); } } @@ -1823,42 +1836,42 @@ isp_get_ga_nxt_response(ispsoftc_t *isp, sns_ga_nxt_rsp_t *src, sns_ga_nxt_rsp_t { int i; isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); - ISP_IOXGET_8(isp, &src->snscb_port_type, dst->snscb_port_type); + ISP_IOZGET_8(isp, &src->snscb_port_type, dst->snscb_port_type); for (i = 0; i < 3; i++) { - ISP_IOXGET_8(isp, &src->snscb_port_id[i], dst->snscb_port_id[i]); + ISP_IOZGET_8(isp, &src->snscb_port_id[i], dst->snscb_port_id[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_portname[i], dst->snscb_portname[i]); + ISP_IOZGET_8(isp, &src->snscb_portname[i], dst->snscb_portname[i]); } - ISP_IOXGET_8(isp, &src->snscb_pnlen, dst->snscb_pnlen); + ISP_IOZGET_8(isp, &src->snscb_pnlen, dst->snscb_pnlen); for (i = 0; i < 255; i++) { - ISP_IOXGET_8(isp, &src->snscb_pname[i], dst->snscb_pname[i]); + ISP_IOZGET_8(isp, &src->snscb_pname[i], dst->snscb_pname[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_nodename[i], dst->snscb_nodename[i]); + ISP_IOZGET_8(isp, &src->snscb_nodename[i], dst->snscb_nodename[i]); } - ISP_IOXGET_8(isp, &src->snscb_nnlen, dst->snscb_nnlen); + ISP_IOZGET_8(isp, &src->snscb_nnlen, dst->snscb_nnlen); for (i = 0; i < 255; i++) { - ISP_IOXGET_8(isp, &src->snscb_nname[i], dst->snscb_nname[i]); + ISP_IOZGET_8(isp, &src->snscb_nname[i], dst->snscb_nname[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_ipassoc[i], dst->snscb_ipassoc[i]); + ISP_IOZGET_8(isp, &src->snscb_ipassoc[i], dst->snscb_ipassoc[i]); } for (i = 0; i < 16; i++) { - ISP_IOXGET_8(isp, &src->snscb_ipaddr[i], dst->snscb_ipaddr[i]); + ISP_IOZGET_8(isp, &src->snscb_ipaddr[i], dst->snscb_ipaddr[i]); } for (i = 0; i < 4; i++) { - ISP_IOXGET_8(isp, &src->snscb_svc_class[i], dst->snscb_svc_class[i]); + ISP_IOZGET_8(isp, &src->snscb_svc_class[i], dst->snscb_svc_class[i]); } for (i = 0; i < 32; i++) { - ISP_IOXGET_8(isp, &src->snscb_fc4_types[i], dst->snscb_fc4_types[i]); + ISP_IOZGET_8(isp, &src->snscb_fc4_types[i], dst->snscb_fc4_types[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_fpname[i], dst->snscb_fpname[i]); + ISP_IOZGET_8(isp, &src->snscb_fpname[i], dst->snscb_fpname[i]); } - ISP_IOXGET_8(isp, &src->snscb_reserved, dst->snscb_reserved); + ISP_IOZGET_8(isp, &src->snscb_reserved, dst->snscb_reserved); for (i = 0; i < 3; i++) { - ISP_IOXGET_8(isp, &src->snscb_hardaddr[i], dst->snscb_hardaddr[i]); + ISP_IOZGET_8(isp, &src->snscb_hardaddr[i], dst->snscb_hardaddr[i]); } } diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h index 8ec97c1ceb4f..1b45ad22ee5d 100644 --- a/sys/dev/isp/isp_library.h +++ b/sys/dev/isp/isp_library.h @@ -1,5 +1,6 @@ /* $FreeBSD$ */ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -127,10 +128,11 @@ void isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *); void isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *); void isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *); void isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *, sns_gid_ft_req_t *); -void isp_put_gxn_id_request(ispsoftc_t *, sns_gxn_id_req_t *, sns_gxn_id_req_t *); -void isp_get_sns_response(ispsoftc_t *, sns_scrsp_t *, sns_scrsp_t *, int); -void isp_get_gid_ft_response(ispsoftc_t *, sns_gid_ft_rsp_t *, sns_gid_ft_rsp_t *, int); +void isp_put_gid_pt_request(ispsoftc_t *, sns_gid_pt_req_t *, sns_gid_pt_req_t *); +void isp_put_gxx_id_request(ispsoftc_t *, sns_gxx_id_req_t *, sns_gxx_id_req_t *); +void isp_get_gid_xx_response(ispsoftc_t *, sns_gid_xx_rsp_t *, sns_gid_xx_rsp_t *, int); void isp_get_gxn_id_response(ispsoftc_t *, sns_gxn_id_rsp_t *, sns_gxn_id_rsp_t *); +void isp_get_gft_id_response(ispsoftc_t *, sns_gft_id_rsp_t *, sns_gft_id_rsp_t *); void isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *, sns_gff_id_rsp_t *); void isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *, sns_ga_nxt_rsp_t *); void isp_get_els(ispsoftc_t *, els_t *, els_t *); diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index e747c5544fbc..3d3d5f2ac950 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -1,5 +1,6 @@ /* $FreeBSD$ */ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -1551,8 +1552,10 @@ typedef struct { #define SNS_GA_NXT 0x100 #define SNS_GPN_ID 0x112 #define SNS_GNN_ID 0x113 +#define SNS_GFT_ID 0x117 #define SNS_GFF_ID 0x11F #define SNS_GID_FT 0x171 +#define SNS_GID_PT 0x1A1 #define SNS_RFT_ID 0x217 #define SNS_RSPN_ID 0x218 #define SNS_RFF_ID 0x21F @@ -1579,18 +1582,18 @@ typedef struct { } sns_ga_nxt_req_t; #define SNS_GA_NXT_REQ_SIZE (sizeof (sns_ga_nxt_req_t)) -typedef struct { +typedef struct { /* Used for GFT_ID, GFF_ID, etc. */ uint16_t snscb_rblen; /* response buffer length (words) */ uint16_t snscb_reserved0; uint16_t snscb_addr[4]; /* response buffer address */ uint16_t snscb_sblen; /* subcommand buffer length (words) */ uint16_t snscb_reserved1; uint16_t snscb_cmd; - uint16_t snscb_reserved2; + uint16_t snscb_mword_div_2; uint32_t snscb_reserved3; uint32_t snscb_portid; -} sns_gxn_id_req_t; -#define SNS_GXN_ID_REQ_SIZE (sizeof (sns_gxn_id_req_t)) +} sns_gxx_id_req_t; +#define SNS_GXX_ID_REQ_SIZE (sizeof (sns_gxx_id_req_t)) typedef struct { uint16_t snscb_rblen; /* response buffer length (words) */ @@ -1605,6 +1608,22 @@ typedef struct { } sns_gid_ft_req_t; #define SNS_GID_FT_REQ_SIZE (sizeof (sns_gid_ft_req_t)) +typedef struct { + uint16_t snscb_rblen; /* response buffer length (words) */ + uint16_t snscb_reserved0; + uint16_t snscb_addr[4]; /* response buffer address */ + uint16_t snscb_sblen; /* subcommand buffer length (words) */ + uint16_t snscb_reserved1; + uint16_t snscb_cmd; + uint16_t snscb_mword_div_2; + uint32_t snscb_reserved3; + uint8_t snscb_port_type; + uint8_t snscb_domain; + uint8_t snscb_area; + uint8_t snscb_flags; +} sns_gid_pt_req_t; +#define SNS_GID_PT_REQ_SIZE (sizeof (sns_gid_pt_req_t)) + typedef struct { uint16_t snscb_rblen; /* response buffer length (words) */ uint16_t snscb_reserved0; @@ -1653,21 +1672,26 @@ typedef struct { } sns_gxn_id_rsp_t; #define SNS_GXN_ID_RESP_SIZE (sizeof (sns_gxn_id_rsp_t)) +typedef struct { + ct_hdr_t snscb_cthdr; + uint32_t snscb_fc4_types[8]; +} sns_gft_id_rsp_t; +#define SNS_GFT_ID_RESP_SIZE (sizeof (sns_gft_id_rsp_t)) + typedef struct { ct_hdr_t snscb_cthdr; uint32_t snscb_fc4_features[32]; } sns_gff_id_rsp_t; #define SNS_GFF_ID_RESP_SIZE (sizeof (sns_gff_id_rsp_t)) -typedef struct { +typedef struct { /* Used for GID_FT, GID_PT, etc. */ ct_hdr_t snscb_cthdr; struct { uint8_t control; uint8_t portid[3]; } snscb_ports[1]; -} sns_gid_ft_rsp_t; -#define SNS_GID_FT_RESP_SIZE(x) ((sizeof (sns_gid_ft_rsp_t)) + ((x - 1) << 2)) -#define SNS_RFT_ID_RESP_SIZE (sizeof (ct_hdr_t)) +} sns_gid_xx_rsp_t; +#define SNS_GID_XX_RESP_SIZE(x) ((sizeof (sns_gid_xx_rsp_t)) + ((x - 1) << 2)) /* * Other Misc Structures diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index 89c132b39875..c49ec3aff192 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -1,5 +1,6 @@ /* $FreeBSD$ */ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -446,6 +447,8 @@ typedef struct { uint16_t isp_login_hdl; /* Logging in handle */ uint8_t isp_retry_delay; uint8_t isp_retry_count; + int isp_use_gft_id; /* Use GFT_ID */ + int isp_use_gff_id; /* Use GFF_ID */ /* * Current active WWNN/WWPN diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index 8e049e36ec0f..4b3454f32b85 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -286,6 +286,7 @@ iwi_attach(device_t dev) int i, error; sc->sc_dev = dev; + sc->sc_ledevent = ticks; IWI_LOCK_INIT(sc); mbufq_init(&sc->sc_snd, ifqmaxlen); diff --git a/sys/dev/ixgbe/if_bypass.c b/sys/dev/ixgbe/if_bypass.c new file mode 100644 index 000000000000..497de3be7ec6 --- /dev/null +++ b/sys/dev/ixgbe/if_bypass.c @@ -0,0 +1,808 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + + +#include "ixgbe.h" + +/************************************************************************ + * ixgbe_bypass_mutex_enter + * + * Mutex support for the bypass feature. Using a dual lock + * to facilitate a privileged access to the watchdog update + * over other threads. + ************************************************************************/ +static void +ixgbe_bypass_mutex_enter(struct adapter *adapter) +{ + while (atomic_cmpset_int(&adapter->bypass.low, 0, 1) == 0) + usec_delay(3000); + while (atomic_cmpset_int(&adapter->bypass.high, 0, 1) == 0) + usec_delay(3000); + return; +} /* ixgbe_bypass_mutex_enter */ + +/************************************************************************ + * ixgbe_bypass_mutex_clear + ************************************************************************/ +static void +ixgbe_bypass_mutex_clear(struct adapter *adapter) +{ + while (atomic_cmpset_int(&adapter->bypass.high, 1, 0) == 0) + usec_delay(6000); + while (atomic_cmpset_int(&adapter->bypass.low, 1, 0) == 0) + usec_delay(6000); + return; +} /* ixgbe_bypass_mutex_clear */ + +/************************************************************************ + * ixgbe_bypass_wd_mutex_enter + * + * Watchdog entry is allowed to simply grab the high priority + ************************************************************************/ +static void +ixgbe_bypass_wd_mutex_enter(struct adapter *adapter) +{ + while (atomic_cmpset_int(&adapter->bypass.high, 0, 1) == 0) + usec_delay(3000); + return; +} /* ixgbe_bypass_wd_mutex_enter */ + +/************************************************************************ + * ixgbe_bypass_wd_mutex_clear + ************************************************************************/ +static void +ixgbe_bypass_wd_mutex_clear(struct adapter *adapter) +{ + while (atomic_cmpset_int(&adapter->bypass.high, 1, 0) == 0) + usec_delay(6000); + return; +} /* ixgbe_bypass_wd_mutex_clear */ + +/************************************************************************ + * ixgbe_get_bypass_time + ************************************************************************/ +static void +ixgbe_get_bypass_time(u32 *year, u32 *sec) +{ + struct timespec current; + + *year = 1970; /* time starts at 01/01/1970 */ + nanotime(¤t); + *sec = current.tv_sec; + + while(*sec > SEC_THIS_YEAR(*year)) { + *sec -= SEC_THIS_YEAR(*year); + (*year)++; + } +} /* ixgbe_get_bypass_time */ + +/************************************************************************ + * ixgbe_bp_version + * + * Display the feature version + ************************************************************************/ +static int +ixgbe_bp_version(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + static int version = 0; + u32 cmd; + + ixgbe_bypass_mutex_enter(adapter); + cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; + cmd |= (BYPASS_EEPROM_VER_ADD << BYPASS_CTL2_OFFSET_SHIFT) & + BYPASS_CTL2_OFFSET_M; + if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0)) + goto err; + msec_delay(100); + cmd &= ~BYPASS_WE; + if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0)) + goto err; + ixgbe_bypass_mutex_clear(adapter); + version &= BYPASS_CTL2_DATA_M; + error = sysctl_handle_int(oidp, &version, 0, req); + return (error); +err: + ixgbe_bypass_mutex_clear(adapter); + return (error); + +} /* ixgbe_bp_version */ + +/************************************************************************ + * ixgbe_bp_set_state + * + * Show/Set the Bypass State: + * 1 = NORMAL + * 2 = BYPASS + * 3 = ISOLATE + * + * With no argument the state is displayed, + * passing a value will set it. + ************************************************************************/ +static int +ixgbe_bp_set_state(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + static int state = 0; + + /* Get the current state */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, + BYPASS_PAGE_CTL0, &state); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (error); + state = (state >> BYPASS_STATUS_OFF_SHIFT) & 0x3; + + error = sysctl_handle_int(oidp, &state, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Sanity check new state */ + switch (state) { + case BYPASS_NORM: + case BYPASS_BYPASS: + case BYPASS_ISOLATE: + break; + default: + return (EINVAL); + } + ixgbe_bypass_mutex_enter(adapter); + if ((error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, + BYPASS_MODE_OFF_M, state) != 0)) + goto out; + /* Set AUTO back on so FW can receive events */ + error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, + BYPASS_MODE_OFF_M, BYPASS_AUTO); +out: + ixgbe_bypass_mutex_clear(adapter); + usec_delay(6000); + return (error); +} /* ixgbe_bp_set_state */ + +/************************************************************************ + * The following routines control the operational + * "rules" of the feature, what behavior will occur + * when particular events occur. + * Values are: + * 0 - no change for the event (NOP) + * 1 - go to Normal operation + * 2 - go to Bypass operation + * 3 - go to Isolate operation + * Calling the entry with no argument just displays + * the current rule setting. + ************************************************************************/ + +/************************************************************************ + * ixgbe_bp_timeout + * + * This is to set the Rule for the watchdog, + * not the actual watchdog timeout value. + ************************************************************************/ +static int +ixgbe_bp_timeout(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + static int timeout = 0; + + /* Get the current value */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &timeout); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (error); + timeout = (timeout >> BYPASS_WDTIMEOUT_SHIFT) & 0x3; + + error = sysctl_handle_int(oidp, &timeout, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Sanity check on the setting */ + switch (timeout) { + case BYPASS_NOP: + case BYPASS_NORM: + case BYPASS_BYPASS: + case BYPASS_ISOLATE: + break; + default: + return (EINVAL); + } + + /* Set the new state */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, + BYPASS_WDTIMEOUT_M, timeout << BYPASS_WDTIMEOUT_SHIFT); + ixgbe_bypass_mutex_clear(adapter); + usec_delay(6000); + return (error); +} /* ixgbe_bp_timeout */ + +/************************************************************************ + * ixgbe_bp_main_on + ************************************************************************/ +static int +ixgbe_bp_main_on(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + static int main_on = 0; + + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_on); + main_on = (main_on >> BYPASS_MAIN_ON_SHIFT) & 0x3; + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (error); + + error = sysctl_handle_int(oidp, &main_on, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Sanity check on the setting */ + switch (main_on) { + case BYPASS_NOP: + case BYPASS_NORM: + case BYPASS_BYPASS: + case BYPASS_ISOLATE: + break; + default: + return (EINVAL); + } + + /* Set the new state */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, + BYPASS_MAIN_ON_M, main_on << BYPASS_MAIN_ON_SHIFT); + ixgbe_bypass_mutex_clear(adapter); + usec_delay(6000); + return (error); +} /* ixgbe_bp_main_on */ + +/************************************************************************ + * ixgbe_bp_main_off + ************************************************************************/ +static int +ixgbe_bp_main_off(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + static int main_off = 0; + + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_off); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (error); + main_off = (main_off >> BYPASS_MAIN_OFF_SHIFT) & 0x3; + + error = sysctl_handle_int(oidp, &main_off, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Sanity check on the setting */ + switch (main_off) { + case BYPASS_NOP: + case BYPASS_NORM: + case BYPASS_BYPASS: + case BYPASS_ISOLATE: + break; + default: + return (EINVAL); + } + + /* Set the new state */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, + BYPASS_MAIN_OFF_M, main_off << BYPASS_MAIN_OFF_SHIFT); + ixgbe_bypass_mutex_clear(adapter); + usec_delay(6000); + return (error); +} /* ixgbe_bp_main_off */ + +/************************************************************************ + * ixgbe_bp_aux_on + ************************************************************************/ +static int +ixgbe_bp_aux_on(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + static int aux_on = 0; + + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_on); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (error); + aux_on = (aux_on >> BYPASS_AUX_ON_SHIFT) & 0x3; + + error = sysctl_handle_int(oidp, &aux_on, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Sanity check on the setting */ + switch (aux_on) { + case BYPASS_NOP: + case BYPASS_NORM: + case BYPASS_BYPASS: + case BYPASS_ISOLATE: + break; + default: + return (EINVAL); + } + + /* Set the new state */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, + BYPASS_AUX_ON_M, aux_on << BYPASS_AUX_ON_SHIFT); + ixgbe_bypass_mutex_clear(adapter); + usec_delay(6000); + return (error); +} /* ixgbe_bp_aux_on */ + +/************************************************************************ + * ixgbe_bp_aux_off + ************************************************************************/ +static int +ixgbe_bp_aux_off(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + static int aux_off = 0; + + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_off); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (error); + aux_off = (aux_off >> BYPASS_AUX_OFF_SHIFT) & 0x3; + + error = sysctl_handle_int(oidp, &aux_off, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Sanity check on the setting */ + switch (aux_off) { + case BYPASS_NOP: + case BYPASS_NORM: + case BYPASS_BYPASS: + case BYPASS_ISOLATE: + break; + default: + return (EINVAL); + } + + /* Set the new state */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, + BYPASS_AUX_OFF_M, aux_off << BYPASS_AUX_OFF_SHIFT); + ixgbe_bypass_mutex_clear(adapter); + usec_delay(6000); + return (error); +} /* ixgbe_bp_aux_off */ + +/************************************************************************ + * ixgbe_bp_wd_set - Set the Watchdog timer value + * + * Valid settings are: + * - 0 will disable the watchdog + * - 1, 2, 3, 4, 8, 16, 32 + * - anything else is invalid and will be ignored + ************************************************************************/ +static int +ixgbe_bp_wd_set(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + int error, tmp; + static int timeout = 0; + u32 mask, arg = BYPASS_PAGE_CTL0; + + /* Get the current hardware value */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &tmp); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (error); + /* + * If armed keep the displayed value, + * else change the display to zero. + */ + if ((tmp & (0x1 << BYPASS_WDT_ENABLE_SHIFT)) == 0) + timeout = 0; + + error = sysctl_handle_int(oidp, &timeout, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + mask = BYPASS_WDT_ENABLE_M; + switch (timeout) { + case 0: /* disables the timer */ + break; + case 1: + arg = BYPASS_WDT_1_5 << BYPASS_WDT_TIME_SHIFT; + arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; + mask |= BYPASS_WDT_VALUE_M; + break; + case 2: + arg = BYPASS_WDT_2 << BYPASS_WDT_TIME_SHIFT; + arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; + mask |= BYPASS_WDT_VALUE_M; + break; + case 3: + arg = BYPASS_WDT_3 << BYPASS_WDT_TIME_SHIFT; + arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; + mask |= BYPASS_WDT_VALUE_M; + break; + case 4: + arg = BYPASS_WDT_4 << BYPASS_WDT_TIME_SHIFT; + arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; + mask |= BYPASS_WDT_VALUE_M; + break; + case 8: + arg = BYPASS_WDT_8 << BYPASS_WDT_TIME_SHIFT; + arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; + mask |= BYPASS_WDT_VALUE_M; + break; + case 16: + arg = BYPASS_WDT_16 << BYPASS_WDT_TIME_SHIFT; + arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; + mask |= BYPASS_WDT_VALUE_M; + break; + case 32: + arg = BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT; + arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; + mask |= BYPASS_WDT_VALUE_M; + break; + default: + return (EINVAL); + } + /* Set the new watchdog */ + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, mask, arg); + ixgbe_bypass_mutex_clear(adapter); + + return (error); +} /* ixgbe_bp_wd_set */ + +/************************************************************************ + * ixgbe_bp_wd_reset - Reset the Watchdog timer + * + * To activate this it must be called with any argument. + ************************************************************************/ +static int +ixgbe_bp_wd_reset(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + u32 sec, year; + int cmd, count = 0, error = 0; + int reset_wd = 0; + + error = sysctl_handle_int(oidp, &reset_wd, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET; + + /* Resync the FW time while writing to CTL1 anyway */ + ixgbe_get_bypass_time(&year, &sec); + + cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID; + cmd |= BYPASS_CTL1_OFFTRST; + + ixgbe_bypass_wd_mutex_enter(adapter); + error = hw->mac.ops.bypass_rw(hw, cmd, &reset_wd); + + /* Read until it matches what we wrote, or we time out */ + do { + if (count++ > 10) { + error = IXGBE_BYPASS_FW_WRITE_FAILURE; + break; + } + if (hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &reset_wd)) { + error = IXGBE_ERR_INVALID_ARGUMENT; + break; + } + } while (!hw->mac.ops.bypass_valid_rd(cmd, reset_wd)); + + reset_wd = 0; + ixgbe_bypass_wd_mutex_clear(adapter); + return (error); +} /* ixgbe_bp_wd_reset */ + +/************************************************************************ + * ixgbe_bp_log - Display the bypass log + * + * You must pass a non-zero arg to sysctl + ************************************************************************/ +static int +ixgbe_bp_log(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + u32 cmd, base, head; + u32 log_off, count = 0; + static int status = 0; + u8 data; + struct ixgbe_bypass_eeprom eeprom[BYPASS_MAX_LOGS]; + int i, error = 0; + + error = sysctl_handle_int(oidp, &status, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Keep the log display single-threaded */ + while (atomic_cmpset_int(&adapter->bypass.log, 0, 1) == 0) + usec_delay(3000); + + ixgbe_bypass_mutex_enter(adapter); + + /* Find Current head of the log eeprom offset */ + cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; + cmd |= (0x1 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; + error = hw->mac.ops.bypass_rw(hw, cmd, &status); + if (error) + goto unlock_err; + + /* wait for the write to stick */ + msec_delay(100); + + /* Now read the results */ + cmd &= ~BYPASS_WE; + error = hw->mac.ops.bypass_rw(hw, cmd, &status); + if (error) + goto unlock_err; + + ixgbe_bypass_mutex_clear(adapter); + + base = status & BYPASS_CTL2_DATA_M; + head = (status & BYPASS_CTL2_HEAD_M) >> BYPASS_CTL2_HEAD_SHIFT; + + /* address of the first log */ + log_off = base + (head * 5); + + /* extract all the log entries */ + while (count < BYPASS_MAX_LOGS) { + eeprom[count].logs = 0; + eeprom[count].actions = 0; + + /* Log 5 bytes store in on u32 and a u8 */ + for (i = 0; i < 4; i++) { + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rd_eep(hw, log_off + i, + &data); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (-EINVAL); + eeprom[count].logs += data << (8 * i); + } + + ixgbe_bypass_mutex_enter(adapter); + error = hw->mac.ops.bypass_rd_eep(hw, + log_off + i, &eeprom[count].actions); + ixgbe_bypass_mutex_clear(adapter); + if (error) + return (-EINVAL); + + /* Quit if not a unread log */ + if (!(eeprom[count].logs & BYPASS_LOG_CLEAR_M)) + break; + /* + * Log looks good so store the address where it's + * Unread Log bit is so we can clear it after safely + * pulling out all of the log data. + */ + eeprom[count].clear_off = log_off; + + count++; + head = head ? head - 1 : BYPASS_MAX_LOGS; + log_off = base + (head * 5); + } + + /* reverse order (oldest first) for output */ + while (count--) { + int year; + u32 mon, days, hours, min, sec; + u32 time = eeprom[count].logs & BYPASS_LOG_TIME_M; + u32 event = (eeprom[count].logs & BYPASS_LOG_EVENT_M) >> + BYPASS_LOG_EVENT_SHIFT; + u8 action = eeprom[count].actions & BYPASS_LOG_ACTION_M; + u16 day_mon[2][13] = { + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, + {0, 31, 59, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} + }; + char *event_str[] = {"unknown", "main on", "aux on", + "main off", "aux off", "WDT", "user" }; + char *action_str[] = {"ignore", "normal", "bypass", "isolate",}; + + /* verify vaild data 1 - 6 */ + if (event < BYPASS_EVENT_MAIN_ON || event > BYPASS_EVENT_USR) + event = 0; + + /* + * time is in sec's this year, so convert to something + * printable. + */ + ixgbe_get_bypass_time(&year, &sec); + days = time / SEC_PER_DAY; + for (i = 11; days < day_mon[LEAP_YR(year)][i]; i--) + continue; + mon = i + 1; /* display month as 1-12 */ + time -= (day_mon[LEAP_YR(year)][i] * SEC_PER_DAY); + days = (time / SEC_PER_DAY) + 1; /* first day is 1 */ + time %= SEC_PER_DAY; + hours = time / (60 * 60); + time %= (60 * 60); + min = time / 60; + sec = time % 60; + device_printf(adapter->dev, + "UT %02d/%02d %02d:%02d:%02d %8.8s -> %7.7s\n", + mon, days, hours, min, sec, event_str[event], + action_str[action]); + cmd = BYPASS_PAGE_CTL2 | BYPASS_WE | BYPASS_CTL2_RW; + cmd |= ((eeprom[count].clear_off + 3) + << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; + cmd |= ((eeprom[count].logs & ~BYPASS_LOG_CLEAR_M) >> 24); + + ixgbe_bypass_mutex_enter(adapter); + + error = hw->mac.ops.bypass_rw(hw, cmd, &status); + + /* wait for the write to stick */ + msec_delay(100); + + ixgbe_bypass_mutex_clear(adapter); + + if (error) + return (-EINVAL); + } + + status = 0; /* reset */ + /* Another log command can now run */ + while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0) + usec_delay(3000); + return(error); + +unlock_err: + ixgbe_bypass_mutex_clear(adapter); + status = 0; /* reset */ + while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0) + usec_delay(3000); + return (-EINVAL); +} /* ixgbe_bp_log */ + +/************************************************************************ + * ixgbe_bypass_init - Set up infrastructure for the bypass feature + * + * Do time and sysctl initialization here. This feature is + * only enabled for the first port of a bypass adapter. + ************************************************************************/ +void +ixgbe_bypass_init(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + device_t dev = adapter->dev; + struct sysctl_oid *bp_node; + struct sysctl_oid_list *bp_list; + u32 mask, value, sec, year; + + if (!(adapter->feat_cap & IXGBE_FEATURE_BYPASS)) + return; + + /* First set up time for the hardware */ + ixgbe_get_bypass_time(&year, &sec); + + mask = BYPASS_CTL1_TIME_M + | BYPASS_CTL1_VALID_M + | BYPASS_CTL1_OFFTRST_M; + + value = (sec & BYPASS_CTL1_TIME_M) + | BYPASS_CTL1_VALID + | BYPASS_CTL1_OFFTRST; + + ixgbe_bypass_mutex_enter(adapter); + hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value); + ixgbe_bypass_mutex_clear(adapter); + + /* Now set up the SYSCTL infrastructure */ + + /* + * The log routine is kept separate from the other + * children so a general display command like: + * `sysctl dev.ix.0.bypass` will not show the log. + */ + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "bypass_log", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_log, "I", "Bypass Log"); + + /* All other setting are hung from the 'bypass' node */ + bp_node = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "bypass", CTLFLAG_RD, NULL, "Bypass"); + + bp_list = SYSCTL_CHILDREN(bp_node); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "version", CTLTYPE_INT | CTLFLAG_RD, + adapter, 0, ixgbe_bp_version, "I", "Bypass Version"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_set_state, "I", "Bypass State"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "timeout", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_timeout, "I", "Bypass Timeout"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "main_on", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_main_on, "I", "Bypass Main On"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "main_off", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_main_off, "I", "Bypass Main Off"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "aux_on", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_aux_on, "I", "Bypass Aux On"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "aux_off", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_aux_off, "I", "Bypass Aux Off"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "wd_set", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_bp_wd_set, "I", "Set BP Watchdog"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, + OID_AUTO, "wd_reset", CTLTYPE_INT | CTLFLAG_WR, + adapter, 0, ixgbe_bp_wd_reset, "S", "Bypass WD Reset"); + + adapter->feat_en |= IXGBE_FEATURE_BYPASS; + + return; +} /* ixgbe_bypass_init */ + diff --git a/sys/dev/ixgbe/if_fdir.c b/sys/dev/ixgbe/if_fdir.c new file mode 100644 index 000000000000..fa6e4ac30cbf --- /dev/null +++ b/sys/dev/ixgbe/if_fdir.c @@ -0,0 +1,160 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#include "ixgbe.h" + +#ifdef IXGBE_FDIR + +void +ixgbe_init_fdir(struct adapter *adapter) +{ + u32 hdrm = 32 << fdir_pballoc; + + if (!(adapter->feat_en & IXGBE_FEATURE_FDIR)) + return; + + adapter->hw.mac.ops.setup_rxpba(&adapter->hw, 0, hdrm, + PBA_STRATEGY_EQUAL); + ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc); +} /* ixgbe_init_fdir */ + +void +ixgbe_reinit_fdir(void *context, int pending) +{ + struct adapter *adapter = context; + struct ifnet *ifp = adapter->ifp; + + if (!(adapter->feat_en & IXGBE_FEATURE_FDIR)) + return; + if (adapter->fdir_reinit != 1) /* Shouldn't happen */ + return; + ixgbe_reinit_fdir_tables_82599(&adapter->hw); + adapter->fdir_reinit = 0; + /* re-enable flow director interrupts */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR); + /* Restart the interface */ + ifp->if_drv_flags |= IFF_DRV_RUNNING; +} /* ixgbe_reinit_fdir */ + +/************************************************************************ + * ixgbe_atr + * + * Parse packet headers so that Flow Director can make + * a hashed filter table entry allowing traffic flows + * to be identified and kept on the same cpu. This + * would be a performance hit, but we only do it at + * IXGBE_FDIR_RATE of packets. + ************************************************************************/ +void +ixgbe_atr(struct tx_ring *txr, struct mbuf *mp) +{ + struct adapter *adapter = txr->adapter; + struct ix_queue *que; + struct ip *ip; + struct tcphdr *th; + struct udphdr *uh; + struct ether_vlan_header *eh; + union ixgbe_atr_hash_dword input = {.dword = 0}; + union ixgbe_atr_hash_dword common = {.dword = 0}; + int ehdrlen, ip_hlen; + u16 etype; + + eh = mtod(mp, struct ether_vlan_header *); + if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { + ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; + etype = eh->evl_proto; + } else { + ehdrlen = ETHER_HDR_LEN; + etype = eh->evl_encap_proto; + } + + /* Only handling IPv4 */ + if (etype != htons(ETHERTYPE_IP)) + return; + + ip = (struct ip *)(mp->m_data + ehdrlen); + ip_hlen = ip->ip_hl << 2; + + /* check if we're UDP or TCP */ + switch (ip->ip_p) { + case IPPROTO_TCP: + th = (struct tcphdr *)((caddr_t)ip + ip_hlen); + /* src and dst are inverted */ + common.port.dst ^= th->th_sport; + common.port.src ^= th->th_dport; + input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_TCPV4; + break; + case IPPROTO_UDP: + uh = (struct udphdr *)((caddr_t)ip + ip_hlen); + /* src and dst are inverted */ + common.port.dst ^= uh->uh_sport; + common.port.src ^= uh->uh_dport; + input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_UDPV4; + break; + default: + return; + } + + input.formatted.vlan_id = htobe16(mp->m_pkthdr.ether_vtag); + if (mp->m_pkthdr.ether_vtag) + common.flex_bytes ^= htons(ETHERTYPE_VLAN); + else + common.flex_bytes ^= etype; + common.ip ^= ip->ip_src.s_addr ^ ip->ip_dst.s_addr; + + que = &adapter->queues[txr->me]; + /* + * This assumes the Rx queue and Tx + * queue are bound to the same CPU + */ + ixgbe_fdir_add_signature_filter_82599(&adapter->hw, + input, common, que->msix); +} /* ixgbe_atr */ + +#else + +/* TASK_INIT needs this function defined regardless if it's enabled */ +void +ixgbe_reinit_fdir(void *context, int pending) +{ + UNREFERENCED_2PARAMETER(context, pending); +} /* ixgbe_reinit_fdir */ + +void +ixgbe_atr(struct tx_ring *txr, struct mbuf *mp) +{ + UNREFERENCED_2PARAMETER(txr, mp); +} /* ixgbe_atr */ + +#endif diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index f45b737a2034..b17e24b0d2e1 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -41,27 +41,21 @@ #include "ixgbe.h" -#ifdef RSS -#include -#include -#endif - -/********************************************************************* - * Driver version - *********************************************************************/ -char ixgbe_driver_version[] = "3.1.13-k"; +/************************************************************************ + * Driver version + ************************************************************************/ +char ixgbe_driver_version[] = "3.2.12-k"; -/********************************************************************* - * PCI Device ID Table +/************************************************************************ + * PCI Device ID Table * - * Used by probe to select devices to load on - * Last field stores an index into ixgbe_strings - * Last entry must be all 0s + * Used by probe to select devices to load on + * Last field stores an index into ixgbe_strings + * Last entry must be all 0s * - * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index } - *********************************************************************/ - + * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index } + ************************************************************************/ static ixgbe_vendor_info_t ixgbe_vendor_info_array[] = { {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_DUAL_PORT, 0, 0, 0}, @@ -95,60 +89,72 @@ static ixgbe_vendor_info_t ixgbe_vendor_info_array[] = {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KR, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KX4, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_10G_T, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_1G_T, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_SFP, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_KR, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_KR_L, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SFP, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SFP_N, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SGMII, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SGMII_L, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_10G_T, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_1G_T, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_1G_T_L, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_BYPASS, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BYPASS, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; -/********************************************************************* - * Table of branding strings - *********************************************************************/ - +/************************************************************************ + * Table of branding strings + ************************************************************************/ static char *ixgbe_strings[] = { "Intel(R) PRO/10GbE PCI-Express Network Driver" }; -/********************************************************************* - * Function prototypes - *********************************************************************/ +/************************************************************************ + * Function prototypes + ************************************************************************/ static int ixgbe_probe(device_t); static int ixgbe_attach(device_t); static int ixgbe_detach(device_t); static int ixgbe_shutdown(device_t); -static int ixgbe_suspend(device_t); -static int ixgbe_resume(device_t); +static int ixgbe_suspend(device_t); +static int ixgbe_resume(device_t); static int ixgbe_ioctl(struct ifnet *, u_long, caddr_t); -static void ixgbe_init(void *); -static void ixgbe_init_locked(struct adapter *); +static void ixgbe_init(void *); +static void ixgbe_init_locked(struct adapter *); static void ixgbe_stop(void *); #if __FreeBSD_version >= 1100036 -static uint64_t ixgbe_get_counter(struct ifnet *, ift_counter); +static uint64_t ixgbe_get_counter(struct ifnet *, ift_counter); #endif -static void ixgbe_add_media_types(struct adapter *); +static void ixgbe_init_device_features(struct adapter *); +static void ixgbe_check_fan_failure(struct adapter *, u32, bool); +static void ixgbe_add_media_types(struct adapter *); static void ixgbe_media_status(struct ifnet *, struct ifmediareq *); static int ixgbe_media_change(struct ifnet *); -static void ixgbe_identify_hardware(struct adapter *); static int ixgbe_allocate_pci_resources(struct adapter *); -static void ixgbe_get_slot_info(struct adapter *); +static void ixgbe_get_slot_info(struct adapter *); static int ixgbe_allocate_msix(struct adapter *); static int ixgbe_allocate_legacy(struct adapter *); -static int ixgbe_setup_msix(struct adapter *); -static void ixgbe_free_pci_resources(struct adapter *); -static void ixgbe_local_timer(void *); -static int ixgbe_setup_interface(device_t, struct adapter *); -static void ixgbe_config_gpie(struct adapter *); -static void ixgbe_config_dmac(struct adapter *); -static void ixgbe_config_delay_values(struct adapter *); -static void ixgbe_config_link(struct adapter *); -static void ixgbe_check_wol_support(struct adapter *); -static int ixgbe_setup_low_power_mode(struct adapter *); -static void ixgbe_rearm_queues(struct adapter *, u64); +static int ixgbe_configure_interrupts(struct adapter *); +static void ixgbe_free_pci_resources(struct adapter *); +static void ixgbe_local_timer(void *); +static int ixgbe_setup_interface(device_t, struct adapter *); +static void ixgbe_config_gpie(struct adapter *); +static void ixgbe_config_dmac(struct adapter *); +static void ixgbe_config_delay_values(struct adapter *); +static void ixgbe_config_link(struct adapter *); +static void ixgbe_check_wol_support(struct adapter *); +static int ixgbe_setup_low_power_mode(struct adapter *); +static void ixgbe_rearm_queues(struct adapter *, u64); static void ixgbe_initialize_transmit_units(struct adapter *); static void ixgbe_initialize_receive_units(struct adapter *); -static void ixgbe_enable_rx_drop(struct adapter *); -static void ixgbe_disable_rx_drop(struct adapter *); -static void ixgbe_initialize_rss_mapping(struct adapter *); +static void ixgbe_enable_rx_drop(struct adapter *); +static void ixgbe_disable_rx_drop(struct adapter *); +static void ixgbe_initialize_rss_mapping(struct adapter *); static void ixgbe_enable_intr(struct adapter *); static void ixgbe_disable_intr(struct adapter *); @@ -156,78 +162,62 @@ static void ixgbe_update_stats_counters(struct adapter *); static void ixgbe_set_promisc(struct adapter *); static void ixgbe_set_multi(struct adapter *); static void ixgbe_update_link_status(struct adapter *); -static void ixgbe_set_ivar(struct adapter *, u8, u8, s8); -static void ixgbe_configure_ivars(struct adapter *); -static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); +static void ixgbe_set_ivar(struct adapter *, u8, u8, s8); +static void ixgbe_configure_ivars(struct adapter *); +static u8 *ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); -static void ixgbe_setup_vlan_hw_support(struct adapter *); -static void ixgbe_register_vlan(void *, struct ifnet *, u16); -static void ixgbe_unregister_vlan(void *, struct ifnet *, u16); +static void ixgbe_setup_vlan_hw_support(struct adapter *); +static void ixgbe_register_vlan(void *, struct ifnet *, u16); +static void ixgbe_unregister_vlan(void *, struct ifnet *, u16); -static void ixgbe_add_device_sysctls(struct adapter *); +static void ixgbe_add_device_sysctls(struct adapter *); static void ixgbe_add_hw_stats(struct adapter *); -static int ixgbe_set_flowcntl(struct adapter *, int); -static int ixgbe_set_advertise(struct adapter *, int); +static int ixgbe_set_flowcntl(struct adapter *, int); +static int ixgbe_set_advertise(struct adapter *, int); +static int ixgbe_get_advertise(struct adapter *); /* Sysctl handlers */ -static void ixgbe_set_sysctl_value(struct adapter *, const char *, - const char *, int *, int); -static int ixgbe_sysctl_flowcntl(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_advertise(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_thermal_test(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_dmac(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_phy_temp(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_phy_overtemp_occurred(SYSCTL_HANDLER_ARGS); +static void ixgbe_set_sysctl_value(struct adapter *, const char *, + const char *, int *, int); +static int ixgbe_sysctl_flowcntl(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_advertise(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_dmac(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_phy_temp(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_phy_overtemp_occurred(SYSCTL_HANDLER_ARGS); #ifdef IXGBE_DEBUG -static int ixgbe_sysctl_power_state(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_power_state(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS); #endif -static int ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_eee_enable(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_eee_negotiated(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_eee_rx_lpi_status(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_eee_tx_lpi_status(SYSCTL_HANDLER_ARGS); -static int ixgbe_sysctl_eee_tx_lpi_delay(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_rdh_handler(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_rdt_handler(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_tdt_handler(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_tdh_handler(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_eee_state(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS); /* Support for pluggable optic modules */ -static bool ixgbe_sfp_probe(struct adapter *); -static void ixgbe_setup_optics(struct adapter *); +static bool ixgbe_sfp_probe(struct adapter *); -/* Legacy (single vector interrupt handler */ -static void ixgbe_legacy_irq(void *); +/* Legacy (single vector) interrupt handler */ +static void ixgbe_legacy_irq(void *); -/* The MSI/X Interrupt handlers */ -static void ixgbe_msix_que(void *); -static void ixgbe_msix_link(void *); +/* The MSI/MSI-X Interrupt handlers */ +static void ixgbe_msix_que(void *); +static void ixgbe_msix_link(void *); /* Deferred interrupt tasklets */ -static void ixgbe_handle_que(void *, int); -static void ixgbe_handle_link(void *, int); -static void ixgbe_handle_msf(void *, int); -static void ixgbe_handle_mod(void *, int); -static void ixgbe_handle_phy(void *, int); - -#ifdef IXGBE_FDIR -static void ixgbe_reinit_fdir(void *, int); -#endif - -#ifdef PCI_IOV -static void ixgbe_ping_all_vfs(struct adapter *); -static void ixgbe_handle_mbx(void *, int); -static int ixgbe_init_iov(device_t, u16, const nvlist_t *); -static void ixgbe_uninit_iov(device_t); -static int ixgbe_add_vf(device_t, u16, const nvlist_t *); -static void ixgbe_initialize_iov(struct adapter *); -static void ixgbe_recalculate_max_frame(struct adapter *); -static void ixgbe_init_vf(struct adapter *, struct ixgbe_vf *); -#endif /* PCI_IOV */ +static void ixgbe_handle_que(void *, int); +static void ixgbe_handle_link(void *, int); +static void ixgbe_handle_msf(void *, int); +static void ixgbe_handle_mod(void *, int); +static void ixgbe_handle_phy(void *, int); -/********************************************************************* +/************************************************************************ * FreeBSD Device Interface Entry Points - *********************************************************************/ - + ************************************************************************/ static device_method_t ix_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ixgbe_probe), @@ -253,25 +243,22 @@ DRIVER_MODULE(ix, pci, ix_driver, ix_devclass, 0, 0); MODULE_DEPEND(ix, pci, 1, 1, 1); MODULE_DEPEND(ix, ether, 1, 1, 1); -#ifdef DEV_NETMAP MODULE_DEPEND(ix, netmap, 1, 1, 1); -#endif /* DEV_NETMAP */ /* -** TUNEABLE PARAMETERS: -*/ + * TUNEABLE PARAMETERS: + */ -static SYSCTL_NODE(_hw, OID_AUTO, ix, CTLFLAG_RD, 0, - "IXGBE driver parameters"); +static SYSCTL_NODE(_hw, OID_AUTO, ix, CTLFLAG_RD, 0, "IXGBE driver parameters"); /* -** AIM: Adaptive Interrupt Moderation -** which means that the interrupt rate -** is varied over time based on the -** traffic for that interrupt vector -*/ + * AIM: Adaptive Interrupt Moderation + * which means that the interrupt rate + * is varied over time based on the + * traffic for that interrupt vector + */ static int ixgbe_enable_aim = TRUE; -SYSCTL_INT(_hw_ix, OID_AUTO, enable_aim, CTLFLAG_RWTUN, &ixgbe_enable_aim, 0, +SYSCTL_INT(_hw_ix, OID_AUTO, enable_aim, CTLFLAG_RDTUN, &ixgbe_enable_aim, 0, "Enable adaptive interrupt moderation"); static int ixgbe_max_interrupt_rate = (4000000 / IXGBE_LOW_LATENCY); @@ -281,16 +268,13 @@ SYSCTL_INT(_hw_ix, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN, /* How many packets rxeof tries to clean at a time */ static int ixgbe_rx_process_limit = 256; SYSCTL_INT(_hw_ix, OID_AUTO, rx_process_limit, CTLFLAG_RDTUN, - &ixgbe_rx_process_limit, 0, - "Maximum number of received packets to process at a time," - "-1 means unlimited"); + &ixgbe_rx_process_limit, 0, "Maximum number of received packets to process at a time, -1 means unlimited"); /* How many packets txeof tries to clean at a time */ static int ixgbe_tx_process_limit = 256; SYSCTL_INT(_hw_ix, OID_AUTO, tx_process_limit, CTLFLAG_RDTUN, &ixgbe_tx_process_limit, 0, - "Maximum number of sent packets to process at a time," - "-1 means unlimited"); + "Maximum number of sent packets to process at a time, -1 means unlimited"); /* Flow control setting, default to full */ static int ixgbe_flow_control = ixgbe_fc_full; @@ -303,16 +287,16 @@ SYSCTL_INT(_hw_ix, OID_AUTO, advertise_speed, CTLFLAG_RDTUN, &ixgbe_advertise_speed, 0, "Default advertised speed for all adapters"); /* -** Smart speed setting, default to on -** this only works as a compile option -** right now as its during attach, set -** this to 'ixgbe_smart_speed_off' to -** disable. -*/ + * Smart speed setting, default to on + * this only works as a compile option + * right now as its during attach, set + * this to 'ixgbe_smart_speed_off' to + * disable. + */ static int ixgbe_smart_speed = ixgbe_smart_speed_on; /* - * MSIX should be the default for best performance, + * MSI-X should be the default for best performance, * but this allows it to be forced off for testing. */ static int ixgbe_enable_msix = 1; @@ -330,10 +314,10 @@ SYSCTL_INT(_hw_ix, OID_AUTO, num_queues, CTLFLAG_RDTUN, &ixgbe_num_queues, 0, "Number of queues to configure, 0 indicates autoconfigure"); /* -** Number of TX descriptors per ring, -** setting higher than RX as this seems -** the better performing choice. -*/ + * Number of TX descriptors per ring, + * setting higher than RX as this seems + * the better performing choice. + */ static int ixgbe_txd = PERFORM_TXD; SYSCTL_INT(_hw_ix, OID_AUTO, txd, CTLFLAG_RDTUN, &ixgbe_txd, 0, "Number of transmit descriptors per queue"); @@ -344,124 +328,376 @@ SYSCTL_INT(_hw_ix, OID_AUTO, rxd, CTLFLAG_RDTUN, &ixgbe_rxd, 0, "Number of receive descriptors per queue"); /* -** Defining this on will allow the use -** of unsupported SFP+ modules, note that -** doing so you are on your own :) -*/ + * Defining this on will allow the use + * of unsupported SFP+ modules, note that + * doing so you are on your own :) + */ static int allow_unsupported_sfp = FALSE; -TUNABLE_INT("hw.ix.unsupported_sfp", &allow_unsupported_sfp); +SYSCTL_INT(_hw_ix, OID_AUTO, unsupported_sfp, CTLFLAG_RDTUN, + &allow_unsupported_sfp, 0, + "Allow unsupported SFP modules...use at your own risk"); + +/* + * Not sure if Flow Director is fully baked, + * so we'll default to turning it off. + */ +static int ixgbe_enable_fdir = 0; +SYSCTL_INT(_hw_ix, OID_AUTO, enable_fdir, CTLFLAG_RDTUN, &ixgbe_enable_fdir, 0, + "Enable Flow Director"); + +/* Legacy Transmit (single queue) */ +static int ixgbe_enable_legacy_tx = 0; +SYSCTL_INT(_hw_ix, OID_AUTO, enable_legacy_tx, CTLFLAG_RDTUN, + &ixgbe_enable_legacy_tx, 0, "Enable Legacy TX flow"); + +/* Receive-Side Scaling */ +static int ixgbe_enable_rss = 1; +SYSCTL_INT(_hw_ix, OID_AUTO, enable_rss, CTLFLAG_RDTUN, &ixgbe_enable_rss, 0, + "Enable Receive-Side Scaling (RSS)"); /* Keep running tab on them for sanity check */ static int ixgbe_total_ports; -#ifdef IXGBE_FDIR -/* -** Flow Director actually 'steals' -** part of the packet buffer as its -** filter pool, this variable controls -** how much it uses: -** 0 = 64K, 1 = 128K, 2 = 256K -*/ -static int fdir_pballoc = 1; -#endif +static int (*ixgbe_start_locked)(struct ifnet *, struct tx_ring *); +static int (*ixgbe_ring_empty)(struct ifnet *, struct buf_ring *); + +MALLOC_DEFINE(M_IXGBE, "ix", "ix driver allocations"); + +/************************************************************************ + * ixgbe_initialize_rss_mapping + ************************************************************************/ +static void +ixgbe_initialize_rss_mapping(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 reta = 0, mrqc, rss_key[10]; + int queue_id, table_size, index_mult; + int i, j; + u32 rss_hash_config; + + if (adapter->feat_en & IXGBE_FEATURE_RSS) { + /* Fetch the configured RSS key */ + rss_getkey((uint8_t *)&rss_key); + } else { + /* set up random bits */ + arc4rand(&rss_key, sizeof(rss_key), 0); + } + + /* Set multiplier for RETA setup and table size based on MAC */ + index_mult = 0x1; + table_size = 128; + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + index_mult = 0x11; + break; + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + table_size = 512; + break; + default: + break; + } + + /* Set up the redirection table */ + for (i = 0, j = 0; i < table_size; i++, j++) { + if (j == adapter->num_queues) + j = 0; + + if (adapter->feat_en & IXGBE_FEATURE_RSS) { + /* + * Fetch the RSS bucket id for the given indirection + * entry. Cap it at the number of configured buckets + * (which is num_queues.) + */ + queue_id = rss_get_indirection_to_bucket(i); + queue_id = queue_id % adapter->num_queues; + } else + queue_id = (j * index_mult); + + /* + * The low 8 bits are for hash value (n+0); + * The next 8 bits are for hash value (n+1), etc. + */ + reta = reta >> 8; + reta = reta | (((uint32_t)queue_id) << 24); + if ((i & 3) == 3) { + if (i < 128) + IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); + else + IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32), + reta); + reta = 0; + } + } + + /* Now fill our hash function seeds */ + for (i = 0; i < 10; i++) + IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), rss_key[i]); + + /* Perform hash on these packet types */ + if (adapter->feat_en & IXGBE_FEATURE_RSS) + rss_hash_config = rss_gethashconfig(); + else { + /* + * Disable UDP - IP fragments aren't currently being handled + * and so we end up with a mix of 2-tuple and 4-tuple + * traffic. + */ + rss_hash_config = RSS_HASHTYPE_RSS_IPV4 + | RSS_HASHTYPE_RSS_TCP_IPV4 + | RSS_HASHTYPE_RSS_IPV6 + | RSS_HASHTYPE_RSS_TCP_IPV6 + | RSS_HASHTYPE_RSS_IPV6_EX + | RSS_HASHTYPE_RSS_TCP_IPV6_EX; + } + + mrqc = IXGBE_MRQC_RSSEN; + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4; + if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP; + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6; + if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP; + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX; + if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP; + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4_EX) + device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV4_EX defined, but not supported\n", + __func__); + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP; + mrqc |= ixgbe_get_mrqc(adapter->iov_mode); + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); +} /* ixgbe_initialize_rss_mapping */ + +/************************************************************************ + * ixgbe_initialize_receive_units - Setup receive registers and features. + ************************************************************************/ +#define BSIZEPKT_ROUNDUP ((1<rx_rings; + struct ixgbe_hw *hw = &adapter->hw; + struct ifnet *ifp = adapter->ifp; + int i, j; + u32 bufsz, fctrl, srrctl, rxcsum; + u32 hlreg; + + /* + * Make sure receives are disabled while + * setting up the descriptor ring + */ + ixgbe_disable_rx(hw); + + /* Enable broadcasts */ + fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + fctrl |= IXGBE_FCTRL_BAM; + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + fctrl |= IXGBE_FCTRL_DPF; + fctrl |= IXGBE_FCTRL_PMCF; + } + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + /* Set for Jumbo Frames? */ + hlreg = IXGBE_READ_REG(hw, IXGBE_HLREG0); + if (ifp->if_mtu > ETHERMTU) + hlreg |= IXGBE_HLREG0_JUMBOEN; + else + hlreg &= ~IXGBE_HLREG0_JUMBOEN; #ifdef DEV_NETMAP -/* - * The #ifdef DEV_NETMAP / #endif blocks in this file are meant to - * be a reference on how to implement netmap support in a driver. - * Additional comments are in ixgbe_netmap.h . - * - * contains functions for netmap support - * that extend the standard driver. - */ -#include + /* CRC stripping is conditional in Netmap */ + if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) && + (ifp->if_capenable & IFCAP_NETMAP) && + !ix_crcstrip) + hlreg &= ~IXGBE_HLREG0_RXCRCSTRP; + else #endif /* DEV_NETMAP */ + hlreg |= IXGBE_HLREG0_RXCRCSTRP; -static MALLOC_DEFINE(M_IXGBE, "ix", "ix driver allocations"); + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg); -/********************************************************************* - * Device identification routine - * - * ixgbe_probe determines if the driver should be loaded on - * adapter based on PCI vendor/device id of the adapter. - * - * return BUS_PROBE_DEFAULT on success, positive on failure - *********************************************************************/ + bufsz = (adapter->rx_mbuf_sz + BSIZEPKT_ROUNDUP) >> + IXGBE_SRRCTL_BSIZEPKT_SHIFT; -static int -ixgbe_probe(device_t dev) -{ - ixgbe_vendor_info_t *ent; + for (i = 0; i < adapter->num_queues; i++, rxr++) { + u64 rdba = rxr->rxdma.dma_paddr; + j = rxr->me; - u16 pci_vendor_id = 0; - u16 pci_device_id = 0; - u16 pci_subvendor_id = 0; - u16 pci_subdevice_id = 0; - char adapter_name[256]; + /* Setup the Base and Length of the Rx Descriptor Ring */ + IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), + (rdba & 0x00000000ffffffffULL)); + IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), + adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc)); - INIT_DEBUGOUT("ixgbe_probe: begin"); + /* Set up the SRRCTL register */ + srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(j)); + srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; + srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; + srrctl |= bufsz; + srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; - pci_vendor_id = pci_get_vendor(dev); - if (pci_vendor_id != IXGBE_INTEL_VENDOR_ID) - return (ENXIO); - - pci_device_id = pci_get_device(dev); - pci_subvendor_id = pci_get_subvendor(dev); - pci_subdevice_id = pci_get_subdevice(dev); - - ent = ixgbe_vendor_info_array; - while (ent->vendor_id != 0) { - if ((pci_vendor_id == ent->vendor_id) && - (pci_device_id == ent->device_id) && - - ((pci_subvendor_id == ent->subvendor_id) || - (ent->subvendor_id == 0)) && - - ((pci_subdevice_id == ent->subdevice_id) || - (ent->subdevice_id == 0))) { - sprintf(adapter_name, "%s, Version - %s", - ixgbe_strings[ent->index], - ixgbe_driver_version); - device_set_desc_copy(dev, adapter_name); - ++ixgbe_total_ports; - return (BUS_PROBE_DEFAULT); + /* + * Set DROP_EN iff we have no flow control and >1 queue. + * Note that srrctl was cleared shortly before during reset, + * so we do not need to clear the bit, but do it just in case + * this code is moved elsewhere. + */ + if (adapter->num_queues > 1 && + adapter->hw.fc.requested_mode == ixgbe_fc_none) { + srrctl |= IXGBE_SRRCTL_DROP_EN; + } else { + srrctl &= ~IXGBE_SRRCTL_DROP_EN; } - ent++; + + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(j), srrctl); + + /* Setup the HW Rx Head and Tail Descriptor Pointers */ + IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0); + IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0); + + /* Set the driver rx tail address */ + rxr->tail = IXGBE_RDT(rxr->me); } - return (ENXIO); -} -/********************************************************************* - * Device initialization routine - * - * The attach entry point is called when the driver is being loaded. - * This routine identifies the type of hardware, allocates all resources - * and initializes the hardware. - * - * return 0 on success, positive on failure - *********************************************************************/ + if (adapter->hw.mac.type != ixgbe_mac_82598EB) { + u32 psrtype = IXGBE_PSRTYPE_TCPHDR + | IXGBE_PSRTYPE_UDPHDR + | IXGBE_PSRTYPE_IPV4HDR + | IXGBE_PSRTYPE_IPV6HDR; + IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype); + } + rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); + + ixgbe_initialize_rss_mapping(adapter); + + if (adapter->num_queues > 1) { + /* RSS and RX IPP Checksum are mutually exclusive */ + rxcsum |= IXGBE_RXCSUM_PCSD; + } + + if (ifp->if_capenable & IFCAP_RXCSUM) + rxcsum |= IXGBE_RXCSUM_PCSD; + + /* This is useful for calculating UDP/IP fragment checksums */ + if (!(rxcsum & IXGBE_RXCSUM_PCSD)) + rxcsum |= IXGBE_RXCSUM_IPPCSE; + + IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); + + return; +} /* ixgbe_initialize_receive_units */ + +/************************************************************************ + * ixgbe_initialize_transmit_units - Enable transmit units. + ************************************************************************/ +static void +ixgbe_initialize_transmit_units(struct adapter *adapter) +{ + struct tx_ring *txr = adapter->tx_rings; + struct ixgbe_hw *hw = &adapter->hw; + + /* Setup the Base and Length of the Tx Descriptor Ring */ + for (int i = 0; i < adapter->num_queues; i++, txr++) { + u64 tdba = txr->txdma.dma_paddr; + u32 txctrl = 0; + int j = txr->me; + + IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j), + (tdba & 0x00000000ffffffffULL)); + IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), + adapter->num_tx_desc * sizeof(union ixgbe_adv_tx_desc)); + + /* Setup the HW Tx Head and Tail descriptor pointers */ + IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0); + IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0); + + /* Cache the tail address */ + txr->tail = IXGBE_TDT(j); + + /* Disable Head Writeback */ + /* + * Note: for X550 series devices, these registers are actually + * prefixed with TPH_ isntead of DCA_, but the addresses and + * fields remain the same. + */ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j)); + break; + default: + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j)); + break; + } + txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl); + break; + default: + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl); + break; + } + + } + + if (hw->mac.type != ixgbe_mac_82598EB) { + u32 dmatxctl, rttdcs; + + dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + dmatxctl |= IXGBE_DMATXCTL_TE; + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); + /* Disable arbiter to set MTQC */ + rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + rttdcs |= IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + IXGBE_WRITE_REG(hw, IXGBE_MTQC, + ixgbe_get_mtqc(adapter->iov_mode)); + rttdcs &= ~IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + } + + return; +} /* ixgbe_initialize_transmit_units */ + +/************************************************************************ + * ixgbe_attach - Device initialization routine + * + * Called when the driver is being loaded. + * Identifies the type of hardware, allocates all resources + * and initializes the hardware. + * + * return 0 on success, positive on failure + ************************************************************************/ static int ixgbe_attach(device_t dev) { - struct adapter *adapter; + struct adapter *adapter; struct ixgbe_hw *hw; int error = 0; - u16 csum; - u32 ctrl_ext; + u32 ctrl_ext; INIT_DEBUGOUT("ixgbe_attach: begin"); /* Allocate, clear, and link in our adapter structure */ adapter = device_get_softc(dev); + adapter->hw.back = adapter; adapter->dev = dev; hw = &adapter->hw; -#ifdef DEV_NETMAP - adapter->init_locked = ixgbe_init_locked; - adapter->stop_locked = ixgbe_stop; -#endif - /* Core Lock Init*/ IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); @@ -469,7 +705,16 @@ ixgbe_attach(device_t dev) callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); /* Determine hardware revision */ - ixgbe_identify_hardware(adapter); + hw->vendor_id = pci_get_vendor(dev); + hw->device_id = pci_get_device(dev); + hw->revision_id = pci_get_revid(dev); + hw->subsystem_vendor_id = pci_get_subvendor(dev); + hw->subsystem_device_id = pci_get_subdevice(dev); + + /* + * Make sure BUSMASTER is set + */ + pci_enable_busmaster(dev); /* Do base PCI setup - map BAR0 */ if (ixgbe_allocate_pci_resources(adapter)) { @@ -478,6 +723,73 @@ ixgbe_attach(device_t dev) goto err_out; } + /* let hardware know driver is loaded */ + ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); + ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD; + IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + + /* + * Initialize the shared code + */ + if (ixgbe_init_shared_code(hw)) { + device_printf(dev, "Unable to initialize the shared code\n"); + error = ENXIO; + goto err_out; + } + + if (hw->mbx.ops.init_params) + hw->mbx.ops.init_params(hw); + + hw->allow_unsupported_sfp = allow_unsupported_sfp; + + /* Pick up the 82599 settings */ + if (hw->mac.type != ixgbe_mac_82598EB) { + hw->phy.smart_speed = ixgbe_smart_speed; + adapter->num_segs = IXGBE_82599_SCATTER; + } else + adapter->num_segs = IXGBE_82598_SCATTER; + + ixgbe_init_device_features(adapter); + + if (ixgbe_configure_interrupts(adapter)) { + error = ENXIO; + goto err_out; + } + + /* Allocate multicast array memory. */ + adapter->mta = malloc(sizeof(*adapter->mta) * + MAX_NUM_MULTICAST_ADDRESSES, M_IXGBE, M_NOWAIT); + if (adapter->mta == NULL) { + device_printf(dev, "Can not allocate multicast setup array\n"); + error = ENOMEM; + goto err_out; + } + + /* Enable WoL (if supported) */ + ixgbe_check_wol_support(adapter); + + /* Register for VLAN events */ + adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, + ixgbe_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); + adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, + ixgbe_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); + + /* Verify adapter fan is still functional (if applicable) */ + if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) { + u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + ixgbe_check_fan_failure(adapter, esdp, FALSE); + } + + /* Ensure SW/FW semaphore is free */ + ixgbe_init_swfw_semaphore(hw); + + /* Enable EEE power saving */ + if (adapter->feat_en & IXGBE_FEATURE_EEE) + hw->mac.ops.setup_eee(hw, TRUE); + + /* Set an initial default flow control value */ + hw->fc.requested_mode = ixgbe_flow_control; + /* Sysctls for limiting the amount of work done in the taskqueues */ ixgbe_set_sysctl_value(adapter, "rx_processing_limit", "max number of rx packets to process", @@ -485,7 +797,7 @@ ixgbe_attach(device_t dev) ixgbe_set_sysctl_value(adapter, "tx_processing_limit", "max number of tx packets to process", - &adapter->tx_process_limit, ixgbe_tx_process_limit); + &adapter->tx_process_limit, ixgbe_tx_process_limit); /* Do descriptor calc and sanity checks */ if (((ixgbe_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 || @@ -496,16 +808,15 @@ ixgbe_attach(device_t dev) adapter->num_tx_desc = ixgbe_txd; /* - ** With many RX rings it is easy to exceed the - ** system mbuf allocation. Tuning nmbclusters - ** can alleviate this. - */ + * With many RX rings it is easy to exceed the + * system mbuf allocation. Tuning nmbclusters + * can alleviate this. + */ if (nmbclusters > 0) { int s; s = (ixgbe_rxd * adapter->num_queues) * ixgbe_total_ports; if (s > nmbclusters) { - device_printf(dev, "RX Descriptors exceed " - "system mbuf max, using default instead!\n"); + device_printf(dev, "RX Descriptors exceed system mbuf max, using default instead!\n"); ixgbe_rxd = DEFAULT_RXD; } } @@ -523,51 +834,49 @@ ixgbe_attach(device_t dev) goto err_out; } - /* Allocate multicast array memory. */ - adapter->mta = malloc(sizeof(*adapter->mta) * - MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT); - if (adapter->mta == NULL) { - device_printf(dev, "Can not allocate multicast setup array\n"); - error = ENOMEM; - goto err_late; - } - - /* Initialize the shared code */ - hw->allow_unsupported_sfp = allow_unsupported_sfp; - error = ixgbe_init_shared_code(hw); + hw->phy.reset_if_overtemp = TRUE; + error = ixgbe_reset_hw(hw); + hw->phy.reset_if_overtemp = FALSE; if (error == IXGBE_ERR_SFP_NOT_PRESENT) { /* - ** No optics in this port, set up - ** so the timer routine will probe - ** for later insertion. - */ + * No optics in this port, set up + * so the timer routine will probe + * for later insertion. + */ adapter->sfp_probe = TRUE; - error = 0; + error = IXGBE_SUCCESS; } else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) { device_printf(dev, "Unsupported SFP+ module detected!\n"); error = EIO; goto err_late; } else if (error) { - device_printf(dev, "Unable to initialize the shared code\n"); + device_printf(dev, "Hardware initialization failed\n"); error = EIO; goto err_late; } /* Make sure we have a good EEPROM before we read from it */ - if (ixgbe_validate_eeprom_checksum(&adapter->hw, &csum) < 0) { + if (ixgbe_validate_eeprom_checksum(&adapter->hw, NULL) < 0) { device_printf(dev, "The EEPROM Checksum Is Not Valid\n"); error = EIO; goto err_late; } - error = ixgbe_init_hw(hw); + /* Setup OS specific network interface */ + if (ixgbe_setup_interface(dev, adapter) != 0) + goto err_late; + + if (adapter->feat_en & IXGBE_FEATURE_MSIX) + error = ixgbe_allocate_msix(adapter); + else + error = ixgbe_allocate_legacy(adapter); + if (error) + goto err_late; + + error = ixgbe_start_hw(hw); switch (error) { case IXGBE_ERR_EEPROM_VERSION: - device_printf(dev, "This device is a pre-production adapter/" - "LOM. Please be aware there may be issues associated " - "with your hardware.\nIf you are experiencing problems " - "please contact your Intel or hardware representative " - "who provided you with this hardware.\n"); + device_printf(dev, "This device is a pre-production adapter/LOM. Please be aware there may be issues associated with your hardware.\nIf you are experiencing problems please contact your Intel or hardware representative who provided you with this hardware.\n"); break; case IXGBE_ERR_SFP_NOT_SUPPORTED: device_printf(dev, "Unsupported SFP+ Module\n"); @@ -580,986 +889,1062 @@ ixgbe_attach(device_t dev) break; } - /* hw.ix defaults init */ - ixgbe_set_advertise(adapter, ixgbe_advertise_speed); - ixgbe_set_flowcntl(adapter, ixgbe_flow_control); - adapter->enable_aim = ixgbe_enable_aim; - - if ((adapter->msix > 1) && (ixgbe_enable_msix)) - error = ixgbe_allocate_msix(adapter); - else - error = ixgbe_allocate_legacy(adapter); - if (error) - goto err_late; - /* Enable the optics for 82599 SFP+ fiber */ ixgbe_enable_tx_laser(hw); /* Enable power to the phy. */ ixgbe_set_phy_power(hw, TRUE); - /* Setup OS specific network interface */ - if (ixgbe_setup_interface(dev, adapter) != 0) - goto err_late; - /* Initialize statistics */ ixgbe_update_stats_counters(adapter); - /* Register for VLAN events */ - adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, - ixgbe_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); - adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, - ixgbe_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); - - /* Check PCIE slot type/speed/width */ + /* Check PCIE slot type/speed/width */ ixgbe_get_slot_info(adapter); - /* Set an initial default flow control & dmac value */ - adapter->fc = ixgbe_fc_full; + /* + * Do time init and sysctl init here, but + * only on the first port of a bypass adapter. + */ + ixgbe_bypass_init(adapter); + + /* Set an initial dmac value */ adapter->dmac = 0; - adapter->eee_enabled = 0; + /* Set initial advertised speeds (if applicable) */ + adapter->advertise = ixgbe_get_advertise(adapter); -#ifdef PCI_IOV - if ((hw->mac.type != ixgbe_mac_82598EB) && (adapter->msix > 1)) { - nvlist_t *pf_schema, *vf_schema; - - hw->mbx.ops.init_params(hw); - pf_schema = pci_iov_schema_alloc_node(); - vf_schema = pci_iov_schema_alloc_node(); - pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL); - pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof", - IOV_SCHEMA_HASDEFAULT, TRUE); - pci_iov_schema_add_bool(vf_schema, "allow-set-mac", - IOV_SCHEMA_HASDEFAULT, FALSE); - pci_iov_schema_add_bool(vf_schema, "allow-promisc", - IOV_SCHEMA_HASDEFAULT, FALSE); - error = pci_iov_attach(dev, pf_schema, vf_schema); - if (error != 0) { - device_printf(dev, - "Error %d setting up SR-IOV\n", error); - } - } -#endif /* PCI_IOV */ - - /* Check for certain supported features */ - ixgbe_check_wol_support(adapter); + if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) + ixgbe_define_iov_schemas(dev, &error); /* Add sysctls */ ixgbe_add_device_sysctls(adapter); ixgbe_add_hw_stats(adapter); - /* let hardware know driver is loaded */ - ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); - ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD; - IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + /* For Netmap */ + adapter->init_locked = ixgbe_init_locked; + adapter->stop_locked = ixgbe_stop; + + if (adapter->feat_en & IXGBE_FEATURE_NETMAP) + ixgbe_netmap_attach(adapter); -#ifdef DEV_NETMAP - ixgbe_netmap_attach(adapter); -#endif /* DEV_NETMAP */ INIT_DEBUGOUT("ixgbe_attach: end"); + return (0); err_late: ixgbe_free_transmit_structures(adapter); ixgbe_free_receive_structures(adapter); + free(adapter->queues, M_DEVBUF); err_out: if (adapter->ifp != NULL) if_free(adapter->ifp); - ixgbe_free_pci_resources(adapter); - free(adapter->mta, M_DEVBUF); - return (error); -} - -/********************************************************************* - * Device removal routine - * - * The detach entry point is called when the driver is being removed. - * This routine stops the adapter and deallocates all the resources - * that were allocated for driver operation. - * - * return 0 on success, positive on failure - *********************************************************************/ - -static int -ixgbe_detach(device_t dev) -{ - struct adapter *adapter = device_get_softc(dev); - struct ix_queue *que = adapter->queues; - struct tx_ring *txr = adapter->tx_rings; - u32 ctrl_ext; - - INIT_DEBUGOUT("ixgbe_detach: begin"); - - /* Make sure VLANS are not using driver */ - if (adapter->ifp->if_vlantrunk != NULL) { - device_printf(dev,"Vlan in use, detach first\n"); - return (EBUSY); - } - -#ifdef PCI_IOV - if (pci_iov_detach(dev) != 0) { - device_printf(dev, "SR-IOV in use; detach first.\n"); - return (EBUSY); - } -#endif /* PCI_IOV */ - - ether_ifdetach(adapter->ifp); - /* Stop the adapter */ - IXGBE_CORE_LOCK(adapter); - ixgbe_setup_low_power_mode(adapter); - IXGBE_CORE_UNLOCK(adapter); - - for (int i = 0; i < adapter->num_queues; i++, que++, txr++) { - if (que->tq) { -#ifndef IXGBE_LEGACY_TX - taskqueue_drain(que->tq, &txr->txq_task); -#endif - taskqueue_drain(que->tq, &que->que_task); - taskqueue_free(que->tq); - } - } - - /* Drain the Link queue */ - if (adapter->tq) { - taskqueue_drain(adapter->tq, &adapter->link_task); - taskqueue_drain(adapter->tq, &adapter->mod_task); - taskqueue_drain(adapter->tq, &adapter->msf_task); -#ifdef PCI_IOV - taskqueue_drain(adapter->tq, &adapter->mbx_task); -#endif - taskqueue_drain(adapter->tq, &adapter->phy_task); -#ifdef IXGBE_FDIR - taskqueue_drain(adapter->tq, &adapter->fdir_task); -#endif - taskqueue_free(adapter->tq); - } - - /* let hardware know driver is unloading */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD; IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext); - - /* Unregister VLAN events */ - if (adapter->vlan_attach != NULL) - EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach); - if (adapter->vlan_detach != NULL) - EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); - - callout_drain(&adapter->timer); -#ifdef DEV_NETMAP - netmap_detach(adapter->ifp); -#endif /* DEV_NETMAP */ ixgbe_free_pci_resources(adapter); - bus_generic_detach(dev); - if_free(adapter->ifp); - - ixgbe_free_transmit_structures(adapter); - ixgbe_free_receive_structures(adapter); - free(adapter->mta, M_DEVBUF); - + free(adapter->mta, M_IXGBE); IXGBE_CORE_LOCK_DESTROY(adapter); - return (0); -} - -/********************************************************************* - * - * Shutdown entry point - * - **********************************************************************/ - -static int -ixgbe_shutdown(device_t dev) -{ - struct adapter *adapter = device_get_softc(dev); - int error = 0; - - INIT_DEBUGOUT("ixgbe_shutdown: begin"); - - IXGBE_CORE_LOCK(adapter); - error = ixgbe_setup_low_power_mode(adapter); - IXGBE_CORE_UNLOCK(adapter); return (error); -} +} /* ixgbe_attach */ -/** - * Methods for going from: - * D0 -> D3: ixgbe_suspend - * D3 -> D0: ixgbe_resume - */ -static int -ixgbe_suspend(device_t dev) +/************************************************************************ + * ixgbe_check_wol_support + * + * Checks whether the adapter's ports are capable of + * Wake On LAN by reading the adapter's NVM. + * + * Sets each port's hw->wol_enabled value depending + * on the value read here. + ************************************************************************/ +static void +ixgbe_check_wol_support(struct adapter *adapter) { - struct adapter *adapter = device_get_softc(dev); - int error = 0; - - INIT_DEBUGOUT("ixgbe_suspend: begin"); - - IXGBE_CORE_LOCK(adapter); - - error = ixgbe_setup_low_power_mode(adapter); - - IXGBE_CORE_UNLOCK(adapter); - - return (error); -} - -static int -ixgbe_resume(device_t dev) -{ - struct adapter *adapter = device_get_softc(dev); - struct ifnet *ifp = adapter->ifp; struct ixgbe_hw *hw = &adapter->hw; - u32 wus; + u16 dev_caps = 0; - INIT_DEBUGOUT("ixgbe_resume: begin"); + /* Find out WoL support for port */ + adapter->wol_support = hw->wol_enabled = 0; + ixgbe_get_device_caps(hw, &dev_caps); + if ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0_1) || + ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0) && + hw->bus.func == 0)) + adapter->wol_support = hw->wol_enabled = 1; - IXGBE_CORE_LOCK(adapter); + /* Save initial wake up filter configuration */ + adapter->wufc = IXGBE_READ_REG(hw, IXGBE_WUFC); - /* Read & clear WUS register */ - wus = IXGBE_READ_REG(hw, IXGBE_WUS); - if (wus) - device_printf(dev, "Woken up by (WUS): %#010x\n", - IXGBE_READ_REG(hw, IXGBE_WUS)); - IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff); - /* And clear WUFC until next low-power transition */ - IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0); + return; +} /* ixgbe_check_wol_support */ - /* - * Required after D3->D0 transition; - * will re-advertise all previous advertised speeds - */ - if (ifp->if_flags & IFF_UP) - ixgbe_init_locked(adapter); - - IXGBE_CORE_UNLOCK(adapter); - - return (0); -} - - -/********************************************************************* - * Ioctl entry point +/************************************************************************ + * ixgbe_setup_interface * - * ixgbe_ioctl is called when the user wants to configure the - * interface. - * - * return 0 on success, positive on failure - **********************************************************************/ - + * Setup networking device structure and register an interface. + ************************************************************************/ static int -ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) +ixgbe_setup_interface(device_t dev, struct adapter *adapter) { - struct adapter *adapter = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *) data; -#if defined(INET) || defined(INET6) - struct ifaddr *ifa = (struct ifaddr *)data; -#endif - int error = 0; - bool avoid_reset = FALSE; + struct ifnet *ifp; - switch (command) { + INIT_DEBUGOUT("ixgbe_setup_interface: begin"); - case SIOCSIFADDR: -#ifdef INET - if (ifa->ifa_addr->sa_family == AF_INET) - avoid_reset = TRUE; -#endif -#ifdef INET6 - if (ifa->ifa_addr->sa_family == AF_INET6) - avoid_reset = TRUE; -#endif - /* - ** Calling init results in link renegotiation, - ** so we avoid doing it when possible. - */ - if (avoid_reset) { - ifp->if_flags |= IFF_UP; - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - ixgbe_init(adapter); -#ifdef INET - if (!(ifp->if_flags & IFF_NOARP)) - arp_ifinit(ifp, ifa); -#endif - } else - error = ether_ioctl(ifp, command, data); - break; - case SIOCSIFMTU: - IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); - if (ifr->ifr_mtu > IXGBE_MAX_MTU) { - error = EINVAL; - } else { - IXGBE_CORE_LOCK(adapter); - ifp->if_mtu = ifr->ifr_mtu; - adapter->max_frame_size = - ifp->if_mtu + IXGBE_MTU_HDR; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ixgbe_init_locked(adapter); -#ifdef PCI_IOV - ixgbe_recalculate_max_frame(adapter); -#endif - IXGBE_CORE_UNLOCK(adapter); - } - break; - case SIOCSIFFLAGS: - IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)"); - IXGBE_CORE_LOCK(adapter); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { - if ((ifp->if_flags ^ adapter->if_flags) & - (IFF_PROMISC | IFF_ALLMULTI)) { - ixgbe_set_promisc(adapter); - } - } else - ixgbe_init_locked(adapter); - } else - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ixgbe_stop(adapter); - adapter->if_flags = ifp->if_flags; - IXGBE_CORE_UNLOCK(adapter); - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI"); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - IXGBE_CORE_LOCK(adapter); - ixgbe_disable_intr(adapter); - ixgbe_set_multi(adapter); - ixgbe_enable_intr(adapter); - IXGBE_CORE_UNLOCK(adapter); - } - break; - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)"); - error = ifmedia_ioctl(ifp, ifr, &adapter->media, command); - break; - case SIOCSIFCAP: - { - IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)"); - - int mask = ifr->ifr_reqcap ^ ifp->if_capenable; - if (!mask) - break; - - /* HW cannot turn these on/off separately */ - if (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) { - ifp->if_capenable ^= IFCAP_RXCSUM; - ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; - } - if (mask & IFCAP_TXCSUM) - ifp->if_capenable ^= IFCAP_TXCSUM; - if (mask & IFCAP_TXCSUM_IPV6) - ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; - if (mask & IFCAP_TSO4) - ifp->if_capenable ^= IFCAP_TSO4; - if (mask & IFCAP_TSO6) - ifp->if_capenable ^= IFCAP_TSO6; - if (mask & IFCAP_LRO) - ifp->if_capenable ^= IFCAP_LRO; - if (mask & IFCAP_VLAN_HWTAGGING) - ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; - if (mask & IFCAP_VLAN_HWFILTER) - ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; - if (mask & IFCAP_VLAN_HWTSO) - ifp->if_capenable ^= IFCAP_VLAN_HWTSO; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - IXGBE_CORE_LOCK(adapter); - ixgbe_init_locked(adapter); - IXGBE_CORE_UNLOCK(adapter); - } - VLAN_CAPABILITIES(ifp); - break; + ifp = adapter->ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + device_printf(dev, "can not allocate ifnet structure\n"); + return (-1); } + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_baudrate = IF_Gbps(10); + ifp->if_init = ixgbe_init; + ifp->if_softc = adapter; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = ixgbe_ioctl; #if __FreeBSD_version >= 1100036 - case SIOCGI2C: - { - struct ixgbe_hw *hw = &adapter->hw; - struct ifi2creq i2c; - int i; - IOCTL_DEBUGOUT("ioctl: SIOCGI2C (Get I2C Data)"); - error = copyin(ifr->ifr_data, &i2c, sizeof(i2c)); - if (error != 0) - break; - if (i2c.dev_addr != 0xA0 && i2c.dev_addr != 0xA2) { - error = EINVAL; - break; - } - if (i2c.len > sizeof(i2c.data)) { - error = EINVAL; - break; - } - - for (i = 0; i < i2c.len; i++) - hw->phy.ops.read_i2c_byte(hw, i2c.offset + i, - i2c.dev_addr, &i2c.data[i]); - error = copyout(&i2c, ifr->ifr_data, sizeof(i2c)); - break; - } + if_setgetcounterfn(ifp, ixgbe_get_counter); #endif - default: - IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command); - error = ether_ioctl(ifp, command, data); - break; - } - - return (error); -} - -/* - * Set the various hardware offload abilities. - * - * This takes the ifnet's if_capenable flags (e.g. set by the user using - * ifconfig) and indicates to the OS via the ifnet's if_hwassist field what - * mbuf offload flags the driver will understand. - */ -static void -ixgbe_set_if_hwassist(struct adapter *adapter) -{ - struct ifnet *ifp = adapter->ifp; - struct ixgbe_hw *hw = &adapter->hw; - - ifp->if_hwassist = 0; -#if __FreeBSD_version >= 1000000 - if (ifp->if_capenable & IFCAP_TSO4) - ifp->if_hwassist |= CSUM_IP_TSO; - if (ifp->if_capenable & IFCAP_TSO6) - ifp->if_hwassist |= CSUM_IP6_TSO; - if (ifp->if_capenable & IFCAP_TXCSUM) { - ifp->if_hwassist |= (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP); - if (hw->mac.type != ixgbe_mac_82598EB) - ifp->if_hwassist |= CSUM_IP_SCTP; - } - if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) { - ifp->if_hwassist |= (CSUM_IP6_UDP | CSUM_IP6_TCP); - if (hw->mac.type != ixgbe_mac_82598EB) - ifp->if_hwassist |= CSUM_IP6_SCTP; - } -#else - if (ifp->if_capenable & IFCAP_TSO) - ifp->if_hwassist |= CSUM_TSO; - if (ifp->if_capenable & IFCAP_TXCSUM) { - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); - if (hw->mac.type != ixgbe_mac_82598EB) - ifp->if_hwassist |= CSUM_SCTP; - } +#if __FreeBSD_version >= 1100045 + /* TSO parameters */ + ifp->if_hw_tsomax = 65518; + ifp->if_hw_tsomaxsegcount = IXGBE_82599_SCATTER; + ifp->if_hw_tsomaxsegsize = 2048; #endif -} - -/********************************************************************* - * Init entry point - * - * This routine is used in two ways. It is used by the stack as - * init entry point in network interface structure. It is also used - * by the driver as a hw/sw initialization routine to get to a - * consistent state. - * - * return 0 on success, positive on failure - **********************************************************************/ -#define IXGBE_MHADD_MFS_SHIFT 16 - -static void -ixgbe_init_locked(struct adapter *adapter) -{ - struct ifnet *ifp = adapter->ifp; - device_t dev = adapter->dev; - struct ixgbe_hw *hw = &adapter->hw; - struct tx_ring *txr; - struct rx_ring *rxr; - u32 txdctl, mhadd; - u32 rxdctl, rxctrl; - int err = 0; -#ifdef PCI_IOV - enum ixgbe_iov_mode mode; -#endif - - mtx_assert(&adapter->core_mtx, MA_OWNED); - INIT_DEBUGOUT("ixgbe_init_locked: begin"); - - hw->adapter_stopped = FALSE; - ixgbe_stop_adapter(hw); - callout_stop(&adapter->timer); - -#ifdef PCI_IOV - mode = ixgbe_get_iov_mode(adapter); - adapter->pool = ixgbe_max_vfs(mode); - /* Queue indices may change with IOV mode */ - for (int i = 0; i < adapter->num_queues; i++) { - adapter->rx_rings[i].me = ixgbe_pf_que_index(mode, i); - adapter->tx_rings[i].me = ixgbe_pf_que_index(mode, i); - } -#endif - /* reprogram the RAR[0] in case user changed it. */ - ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, IXGBE_RAH_AV); - - /* Get the latest mac address, User can use a LAA */ - bcopy(IF_LLADDR(ifp), hw->mac.addr, IXGBE_ETH_LENGTH_OF_ADDRESS); - ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, 1); - hw->addr_ctrl.rar_used_count = 1; - - /* Set hardware offload abilities from ifnet flags */ - ixgbe_set_if_hwassist(adapter); - - /* Prepare transmit descriptors and buffers */ - if (ixgbe_setup_transmit_structures(adapter)) { - device_printf(dev, "Could not setup transmit structures\n"); - ixgbe_stop(adapter); - return; + if (adapter->feat_en & IXGBE_FEATURE_LEGACY_TX) { + ifp->if_start = ixgbe_legacy_start; + IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2); + ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 2; + IFQ_SET_READY(&ifp->if_snd); + ixgbe_start_locked = ixgbe_legacy_start_locked; + ixgbe_ring_empty = ixgbe_legacy_ring_empty; + } else { + ifp->if_transmit = ixgbe_mq_start; + ifp->if_qflush = ixgbe_qflush; + ixgbe_start_locked = ixgbe_mq_start_locked; + ixgbe_ring_empty = drbr_empty; } - ixgbe_init_hw(hw); -#ifdef PCI_IOV - ixgbe_initialize_iov(adapter); -#endif - ixgbe_initialize_transmit_units(adapter); + ether_ifattach(ifp, adapter->hw.mac.addr); - /* Setup Multicast table */ - ixgbe_set_multi(adapter); - - /* Determine the correct mbuf pool, based on frame size */ - if (adapter->max_frame_size <= MCLBYTES) - adapter->rx_mbuf_sz = MCLBYTES; - else - adapter->rx_mbuf_sz = MJUMPAGESIZE; - - /* Prepare receive descriptors and buffers */ - if (ixgbe_setup_receive_structures(adapter)) { - device_printf(dev, "Could not setup receive structures\n"); - ixgbe_stop(adapter); - return; - } - - /* Configure RX settings */ - ixgbe_initialize_receive_units(adapter); - - /* Enable SDP & MSIX interrupts based on adapter */ - ixgbe_config_gpie(adapter); - - /* Set MTU size */ - if (ifp->if_mtu > ETHERMTU) { - /* aka IXGBE_MAXFRS on 82599 and newer */ - mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); - mhadd &= ~IXGBE_MHADD_MFS_MASK; - mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT; - IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); - } - - /* Now enable all the queues */ - for (int i = 0; i < adapter->num_queues; i++) { - txr = &adapter->tx_rings[i]; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(txr->me)); - txdctl |= IXGBE_TXDCTL_ENABLE; - /* Set WTHRESH to 8, burst writeback */ - txdctl |= (8 << 16); - /* - * When the internal queue falls below PTHRESH (32), - * start prefetching as long as there are at least - * HTHRESH (1) buffers ready. The values are taken - * from the Intel linux driver 3.8.21. - * Prefetching enables tx line rate even with 1 queue. - */ - txdctl |= (32 << 0) | (1 << 8); - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(txr->me), txdctl); - } - - for (int i = 0, j = 0; i < adapter->num_queues; i++) { - rxr = &adapter->rx_rings[i]; - rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)); - if (hw->mac.type == ixgbe_mac_82598EB) { - /* - ** PTHRESH = 21 - ** HTHRESH = 4 - ** WTHRESH = 8 - */ - rxdctl &= ~0x3FFFFF; - rxdctl |= 0x080420; - } - rxdctl |= IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), rxdctl); - for (; j < 10; j++) { - if (IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)) & - IXGBE_RXDCTL_ENABLE) - break; - else - msec_delay(1); - } - wmb(); -#ifdef DEV_NETMAP - /* - * In netmap mode, we must preserve the buffers made - * available to userspace before the if_init() - * (this is true by default on the TX side, because - * init makes all buffers available to userspace). - * - * netmap_reset() and the device specific routines - * (e.g. ixgbe_setup_receive_rings()) map these - * buffers at the end of the NIC ring, so here we - * must set the RDT (tail) register to make sure - * they are not overwritten. - * - * In this driver the NIC ring starts at RDH = 0, - * RDT points to the last slot available for reception (?), - * so RDT = num_rx_desc - 1 means the whole ring is available. - */ - if (ifp->if_capenable & IFCAP_NETMAP) { - struct netmap_adapter *na = NA(adapter->ifp); - struct netmap_kring *kring = &na->rx_rings[i]; - int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring); - - IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me), t); - } else -#endif /* DEV_NETMAP */ - IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me), adapter->num_rx_desc - 1); - } - - /* Enable Receive engine */ - rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); - if (hw->mac.type == ixgbe_mac_82598EB) - rxctrl |= IXGBE_RXCTRL_DMBYPS; - rxctrl |= IXGBE_RXCTRL_RXEN; - ixgbe_enable_rx_dma(hw, rxctrl); - - callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter); - - /* Set up MSI/X routing */ - if (ixgbe_enable_msix) { - ixgbe_configure_ivars(adapter); - /* Set up auto-mask */ - if (hw->mac.type == ixgbe_mac_82598EB) - IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); - else { - IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF); - IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF); - } - } else { /* Simple settings for Legacy/MSI */ - ixgbe_set_ivar(adapter, 0, 0, 0); - ixgbe_set_ivar(adapter, 0, 0, 1); - IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); - } - -#ifdef IXGBE_FDIR - /* Init Flow director */ - if (hw->mac.type != ixgbe_mac_82598EB) { - u32 hdrm = 32 << fdir_pballoc; - - hw->mac.ops.setup_rxpba(hw, 0, hdrm, PBA_STRATEGY_EQUAL); - ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc); - } -#endif + adapter->max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; /* - * Check on any SFP devices that - * need to be kick-started + * Tell the upper layer(s) we support long frames. */ - if (hw->phy.type == ixgbe_phy_none) { - err = hw->phy.ops.identify(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev, - "Unsupported SFP+ module type was detected.\n"); - return; - } - } - - /* Set moderation on the Link interrupt */ - IXGBE_WRITE_REG(hw, IXGBE_EITR(adapter->vector), IXGBE_LINK_ITR); - - /* Configure Energy Efficient Ethernet for supported devices */ - if (hw->mac.ops.setup_eee) { - err = hw->mac.ops.setup_eee(hw, adapter->eee_enabled); - if (err) - device_printf(dev, "Error setting up EEE: %d\n", err); - } - - /* Enable power to the phy. */ - ixgbe_set_phy_power(hw, TRUE); - - /* Config/Enable Link */ - ixgbe_config_link(adapter); - - /* Hardware Packet Buffer & Flow Control setup */ - ixgbe_config_delay_values(adapter); - - /* Initialize the FC settings */ - ixgbe_start_hw(hw); - - /* Set up VLAN support and filter */ - ixgbe_setup_vlan_hw_support(adapter); - - /* Setup DMA Coalescing */ - ixgbe_config_dmac(adapter); - - /* And now turn on interrupts */ - ixgbe_enable_intr(adapter); - -#ifdef PCI_IOV - /* Enable the use of the MBX by the VF's */ - { - u32 reg = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); - reg |= IXGBE_CTRL_EXT_PFRSTD; - IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, reg); + ifp->if_hdrlen = sizeof(struct ether_vlan_header); + + /* Set capability flags */ + ifp->if_capabilities |= IFCAP_HWCSUM + | IFCAP_HWCSUM_IPV6 + | IFCAP_TSO + | IFCAP_LRO + | IFCAP_VLAN_HWTAGGING + | IFCAP_VLAN_HWTSO + | IFCAP_VLAN_HWCSUM + | IFCAP_JUMBO_MTU + | IFCAP_VLAN_MTU + | IFCAP_HWSTATS; + + /* Enable the above capabilities by default */ + ifp->if_capenable = ifp->if_capabilities; + + /* + * Don't turn this on by default, if vlans are + * created on another pseudo device (eg. lagg) + * then vlan events are not passed thru, breaking + * operation, but with HW FILTER off it works. If + * using vlans directly on the ixgbe driver you can + * enable this and get full hardware tag filtering. + */ + ifp->if_capabilities |= IFCAP_VLAN_HWFILTER; + + /* + * Specify the media types supported by this adapter and register + * callbacks to update media and link information + */ + ifmedia_init(&adapter->media, IFM_IMASK, ixgbe_media_change, + ixgbe_media_status); + + adapter->phy_layer = ixgbe_get_supported_physical_layer(&adapter->hw); + ixgbe_add_media_types(adapter); + + /* Set autoselect media by default */ + ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); + + return (0); +} /* ixgbe_setup_interface */ + +#if __FreeBSD_version >= 1100036 +/************************************************************************ + * ixgbe_get_counter + ************************************************************************/ +static uint64_t +ixgbe_get_counter(struct ifnet *ifp, ift_counter cnt) +{ + struct adapter *adapter; + struct tx_ring *txr; + uint64_t rv; + + adapter = if_getsoftc(ifp); + + switch (cnt) { + case IFCOUNTER_IPACKETS: + return (adapter->ipackets); + case IFCOUNTER_OPACKETS: + return (adapter->opackets); + case IFCOUNTER_IBYTES: + return (adapter->ibytes); + case IFCOUNTER_OBYTES: + return (adapter->obytes); + case IFCOUNTER_IMCASTS: + return (adapter->imcasts); + case IFCOUNTER_OMCASTS: + return (adapter->omcasts); + case IFCOUNTER_COLLISIONS: + return (0); + case IFCOUNTER_IQDROPS: + return (adapter->iqdrops); + case IFCOUNTER_OQDROPS: + rv = 0; + txr = adapter->tx_rings; + for (int i = 0; i < adapter->num_queues; i++, txr++) + rv += txr->br->br_drops; + return (rv); + case IFCOUNTER_IERRORS: + return (adapter->ierrors); + default: + return (if_get_counter_default(ifp, cnt)); } +} /* ixgbe_get_counter */ #endif - /* Now inform the stack we're ready */ - ifp->if_drv_flags |= IFF_DRV_RUNNING; +/************************************************************************ + * ixgbe_add_media_types + ************************************************************************/ +static void +ixgbe_add_media_types(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + device_t dev = adapter->dev; + u64 layer; + + layer = adapter->phy_layer; + + /* Media types with matching FreeBSD media defines */ + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_T, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_T) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_100BASE_TX) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_10BASE_T) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL); + + if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU || + layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_TWINAX, 0, + NULL); + + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LR) { + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_LR, 0, NULL); + if (hw->phy.multispeed_fiber) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_LX, 0, + NULL); + } + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) { + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_SR, 0, NULL); + if (hw->phy.multispeed_fiber) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, + NULL); + } else if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_CX4) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_CX4, 0, NULL); + +#ifdef IFM_ETH_XTYPE + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_KR, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_KX4, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_KX, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_2500BASE_KX) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_2500_KX, 0, NULL); +#else + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) { + device_printf(dev, "Media supported: 10GbaseKR\n"); + device_printf(dev, "10GbaseKR mapped to 10GbaseSR\n"); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_SR, 0, NULL); + } + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) { + device_printf(dev, "Media supported: 10GbaseKX4\n"); + device_printf(dev, "10GbaseKX4 mapped to 10GbaseCX4\n"); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_CX4, 0, NULL); + } + if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) { + device_printf(dev, "Media supported: 1000baseKX\n"); + device_printf(dev, "1000baseKX mapped to 1000baseCX\n"); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_CX, 0, NULL); + } + if (layer & IXGBE_PHYSICAL_LAYER_2500BASE_KX) { + device_printf(dev, "Media supported: 2500baseKX\n"); + device_printf(dev, "2500baseKX mapped to 2500baseSX\n"); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_2500_SX, 0, NULL); + } +#endif + if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_BX) + device_printf(dev, "Media supported: 1000baseBX\n"); + + if (hw->device_id == IXGBE_DEV_ID_82598AT) { + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T | IFM_FDX, + 0, NULL); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL); + } + + ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); +} /* ixgbe_add_media_types */ + +/************************************************************************ + * ixgbe_is_sfp + ************************************************************************/ +static inline bool +ixgbe_is_sfp(struct ixgbe_hw *hw) +{ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + if (hw->phy.type == ixgbe_phy_nl) + return TRUE; + return FALSE; + case ixgbe_mac_82599EB: + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + case ixgbe_media_type_fiber_qsfp: + return TRUE; + default: + return FALSE; + } + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) + return TRUE; + return FALSE; + default: + return FALSE; + } +} /* ixgbe_is_sfp */ + +/************************************************************************ + * ixgbe_config_link + ************************************************************************/ +static void +ixgbe_config_link(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 autoneg, err = 0; + bool sfp, negotiate; + + sfp = ixgbe_is_sfp(hw); + + if (sfp) { + if (hw->phy.multispeed_fiber) { + hw->mac.ops.setup_sfp(hw); + ixgbe_enable_tx_laser(hw); + taskqueue_enqueue(adapter->tq, &adapter->msf_task); + } else + taskqueue_enqueue(adapter->tq, &adapter->mod_task); + } else { + if (hw->mac.ops.check_link) + err = ixgbe_check_link(hw, &adapter->link_speed, + &adapter->link_up, FALSE); + if (err) + goto out; + autoneg = hw->phy.autoneg_advertised; + if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) + err = hw->mac.ops.get_link_capabilities(hw, &autoneg, + &negotiate); + if (err) + goto out; + if (hw->mac.ops.setup_link) + err = hw->mac.ops.setup_link(hw, autoneg, + adapter->link_up); + } +out: return; -} +} /* ixgbe_config_link */ +/************************************************************************ + * ixgbe_update_stats_counters - Update board statistics counters. + ************************************************************************/ static void -ixgbe_init(void *arg) +ixgbe_update_stats_counters(struct adapter *adapter) { - struct adapter *adapter = arg; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw_stats *stats = &adapter->stats.pf; + u32 missed_rx = 0, bprc, lxon, lxoff, total; + u64 total_missed_rx = 0; + + stats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); + stats->illerrc += IXGBE_READ_REG(hw, IXGBE_ILLERRC); + stats->errbc += IXGBE_READ_REG(hw, IXGBE_ERRBC); + stats->mspdc += IXGBE_READ_REG(hw, IXGBE_MSPDC); + stats->mpc[0] += IXGBE_READ_REG(hw, IXGBE_MPC(0)); + + for (int i = 0; i < 16; i++) { + stats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); + stats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); + stats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + } + stats->mlfc += IXGBE_READ_REG(hw, IXGBE_MLFC); + stats->mrfc += IXGBE_READ_REG(hw, IXGBE_MRFC); + stats->rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); + + /* Hardware workaround, gprc counts missed packets */ + stats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); + stats->gprc -= missed_rx; + + if (hw->mac.type != ixgbe_mac_82598EB) { + stats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL) + + ((u64)IXGBE_READ_REG(hw, IXGBE_GORCH) << 32); + stats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL) + + ((u64)IXGBE_READ_REG(hw, IXGBE_GOTCH) << 32); + stats->tor += IXGBE_READ_REG(hw, IXGBE_TORL) + + ((u64)IXGBE_READ_REG(hw, IXGBE_TORH) << 32); + stats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + stats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } else { + stats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); + stats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + /* 82598 only has a counter in the high register */ + stats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); + stats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); + stats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); + } + + /* + * Workaround: mprc hardware is incorrectly counting + * broadcasts, so for now we subtract those. + */ + bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); + stats->bprc += bprc; + stats->mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); + if (hw->mac.type == ixgbe_mac_82598EB) + stats->mprc -= bprc; + + stats->prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); + stats->prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); + stats->prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255); + stats->prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511); + stats->prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023); + stats->prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); + + lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC); + stats->lxontxc += lxon; + lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); + stats->lxofftxc += lxoff; + total = lxon + lxoff; + + stats->gptc += IXGBE_READ_REG(hw, IXGBE_GPTC); + stats->mptc += IXGBE_READ_REG(hw, IXGBE_MPTC); + stats->ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64); + stats->gptc -= total; + stats->mptc -= total; + stats->ptc64 -= total; + stats->gotc -= total * ETHER_MIN_LEN; + + stats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC); + stats->rfc += IXGBE_READ_REG(hw, IXGBE_RFC); + stats->roc += IXGBE_READ_REG(hw, IXGBE_ROC); + stats->rjc += IXGBE_READ_REG(hw, IXGBE_RJC); + stats->mngprc += IXGBE_READ_REG(hw, IXGBE_MNGPRC); + stats->mngpdc += IXGBE_READ_REG(hw, IXGBE_MNGPDC); + stats->mngptc += IXGBE_READ_REG(hw, IXGBE_MNGPTC); + stats->tpr += IXGBE_READ_REG(hw, IXGBE_TPR); + stats->tpt += IXGBE_READ_REG(hw, IXGBE_TPT); + stats->ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127); + stats->ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255); + stats->ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511); + stats->ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023); + stats->ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522); + stats->bptc += IXGBE_READ_REG(hw, IXGBE_BPTC); + stats->xec += IXGBE_READ_REG(hw, IXGBE_XEC); + stats->fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); + stats->fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST); + /* Only read FCOE on 82599 */ + if (hw->mac.type != ixgbe_mac_82598EB) { + stats->fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); + stats->fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); + stats->fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); + stats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); + stats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); + } + + /* Fill out the OS statistics structure */ + IXGBE_SET_IPACKETS(adapter, stats->gprc); + IXGBE_SET_OPACKETS(adapter, stats->gptc); + IXGBE_SET_IBYTES(adapter, stats->gorc); + IXGBE_SET_OBYTES(adapter, stats->gotc); + IXGBE_SET_IMCASTS(adapter, stats->mprc); + IXGBE_SET_OMCASTS(adapter, stats->mptc); + IXGBE_SET_COLLISIONS(adapter, 0); + IXGBE_SET_IQDROPS(adapter, total_missed_rx); + IXGBE_SET_IERRORS(adapter, stats->crcerrs + stats->rlec); +} /* ixgbe_update_stats_counters */ + +/************************************************************************ + * ixgbe_add_hw_stats + * + * Add sysctl variables, one per statistic, to the system. + ************************************************************************/ +static void +ixgbe_add_hw_stats(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct tx_ring *txr = adapter->tx_rings; + struct rx_ring *rxr = adapter->rx_rings; + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); + struct sysctl_oid *tree = device_get_sysctl_tree(dev); + struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); + struct ixgbe_hw_stats *stats = &adapter->stats.pf; + struct sysctl_oid *stat_node, *queue_node; + struct sysctl_oid_list *stat_list, *queue_list; + +#define QUEUE_NAME_LEN 32 + char namebuf[QUEUE_NAME_LEN]; + + /* Driver Statistics */ + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped", + CTLFLAG_RD, &adapter->dropped_pkts, "Driver dropped packets"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_failed", + CTLFLAG_RD, &adapter->mbuf_defrag_failed, "m_defrag() failed"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_events", + CTLFLAG_RD, &adapter->watchdog_events, "Watchdog timeouts"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq", + CTLFLAG_RD, &adapter->link_irq, "Link MSI-X IRQ Handled"); + + for (int i = 0; i < adapter->num_queues; i++, txr++) { + snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); + queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, + CTLFLAG_RD, NULL, "Queue Name"); + queue_list = SYSCTL_CHILDREN(queue_node); + + SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "interrupt_rate", + CTLTYPE_UINT | CTLFLAG_RW, &adapter->queues[i], + sizeof(&adapter->queues[i]), + ixgbe_sysctl_interrupt_rate_handler, "IU", + "Interrupt Rate"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs", + CTLFLAG_RD, &(adapter->queues[i].irqs), + "irqs on this queue"); + SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head", + CTLTYPE_UINT | CTLFLAG_RD, txr, sizeof(txr), + ixgbe_sysctl_tdh_handler, "IU", "Transmit Descriptor Head"); + SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_tail", + CTLTYPE_UINT | CTLFLAG_RD, txr, sizeof(txr), + ixgbe_sysctl_tdt_handler, "IU", "Transmit Descriptor Tail"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tso_tx", + CTLFLAG_RD, &txr->tso_tx, "TSO"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "no_tx_dma_setup", + CTLFLAG_RD, &txr->no_tx_dma_setup, + "Driver tx dma failure in xmit"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "no_desc_avail", + CTLFLAG_RD, &txr->no_desc_avail, + "Queue No Descriptor Available"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets", + CTLFLAG_RD, &txr->total_packets, + "Queue Packets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "br_drops", + CTLFLAG_RD, &txr->br->br_drops, + "Packets dropped in buf_ring"); + } + + for (int i = 0; i < adapter->num_queues; i++, rxr++) { + struct lro_ctrl *lro = &rxr->lro; + + snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); + queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, + CTLFLAG_RD, NULL, "Queue Name"); + queue_list = SYSCTL_CHILDREN(queue_node); + + SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_head", + CTLTYPE_UINT | CTLFLAG_RD, rxr, sizeof(rxr), + ixgbe_sysctl_rdh_handler, "IU", "Receive Descriptor Head"); + SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_tail", + CTLTYPE_UINT | CTLFLAG_RD, rxr, sizeof(rxr), + ixgbe_sysctl_rdt_handler, "IU", "Receive Descriptor Tail"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets", + CTLFLAG_RD, &rxr->rx_packets, "Queue Packets Received"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes", + CTLFLAG_RD, &rxr->rx_bytes, "Queue Bytes Received"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_copies", + CTLFLAG_RD, &rxr->rx_copies, "Copied RX Frames"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_discarded", + CTLFLAG_RD, &rxr->rx_discarded, "Discarded RX packets"); + SYSCTL_ADD_U64(ctx, queue_list, OID_AUTO, "lro_queued", + CTLFLAG_RD, &lro->lro_queued, 0, "LRO Queued"); + SYSCTL_ADD_U64(ctx, queue_list, OID_AUTO, "lro_flushed", + CTLFLAG_RD, &lro->lro_flushed, 0, "LRO Flushed"); + } + + /* MAC stats get their own sub node */ + + stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats", + CTLFLAG_RD, NULL, "MAC Statistics"); + stat_list = SYSCTL_CHILDREN(stat_node); + + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "crc_errs", + CTLFLAG_RD, &stats->crcerrs, "CRC Errors"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ill_errs", + CTLFLAG_RD, &stats->illerrc, "Illegal Byte Errors"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "byte_errs", + CTLFLAG_RD, &stats->errbc, "Byte Errors"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "short_discards", + CTLFLAG_RD, &stats->mspdc, "MAC Short Packets Discarded"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "local_faults", + CTLFLAG_RD, &stats->mlfc, "MAC Local Faults"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "remote_faults", + CTLFLAG_RD, &stats->mrfc, "MAC Remote Faults"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rec_len_errs", + CTLFLAG_RD, &stats->rlec, "Receive Length Errors"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_missed_packets", + CTLFLAG_RD, &stats->mpc[0], "RX Missed Packet Count"); + + /* Flow Control stats */ + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_txd", + CTLFLAG_RD, &stats->lxontxc, "Link XON Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_recvd", + CTLFLAG_RD, &stats->lxonrxc, "Link XON Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_txd", + CTLFLAG_RD, &stats->lxofftxc, "Link XOFF Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_recvd", + CTLFLAG_RD, &stats->lxoffrxc, "Link XOFF Received"); + + /* Packet Reception Stats */ + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_octets_rcvd", + CTLFLAG_RD, &stats->tor, "Total Octets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd", + CTLFLAG_RD, &stats->gorc, "Good Octets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_rcvd", + CTLFLAG_RD, &stats->tpr, "Total Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd", + CTLFLAG_RD, &stats->gprc, "Good Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd", + CTLFLAG_RD, &stats->mprc, "Multicast Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_rcvd", + CTLFLAG_RD, &stats->bprc, "Broadcast Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_64", + CTLFLAG_RD, &stats->prc64, "64 byte frames received "); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127", + CTLFLAG_RD, &stats->prc127, "65-127 byte frames received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255", + CTLFLAG_RD, &stats->prc255, "128-255 byte frames received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511", + CTLFLAG_RD, &stats->prc511, "256-511 byte frames received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023", + CTLFLAG_RD, &stats->prc1023, "512-1023 byte frames received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522", + CTLFLAG_RD, &stats->prc1522, "1023-1522 byte frames received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_undersized", + CTLFLAG_RD, &stats->ruc, "Receive Undersized"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_fragmented", + CTLFLAG_RD, &stats->rfc, "Fragmented Packets Received "); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_oversized", + CTLFLAG_RD, &stats->roc, "Oversized Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_jabberd", + CTLFLAG_RD, &stats->rjc, "Received Jabber"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "management_pkts_rcvd", + CTLFLAG_RD, &stats->mngprc, "Management Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "management_pkts_drpd", + CTLFLAG_RD, &stats->mngptc, "Management Packets Dropped"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "checksum_errs", + CTLFLAG_RD, &stats->xec, "Checksum Errors"); + + /* Packet Transmission Stats */ + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", + CTLFLAG_RD, &stats->gotc, "Good Octets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd", + CTLFLAG_RD, &stats->tpt, "Total Packets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd", + CTLFLAG_RD, &stats->gptc, "Good Packets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd", + CTLFLAG_RD, &stats->bptc, "Broadcast Packets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd", + CTLFLAG_RD, &stats->mptc, "Multicast Packets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "management_pkts_txd", + CTLFLAG_RD, &stats->mngptc, "Management Packets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_64", + CTLFLAG_RD, &stats->ptc64, "64 byte frames transmitted "); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127", + CTLFLAG_RD, &stats->ptc127, "65-127 byte frames transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255", + CTLFLAG_RD, &stats->ptc255, "128-255 byte frames transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511", + CTLFLAG_RD, &stats->ptc511, "256-511 byte frames transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023", + CTLFLAG_RD, &stats->ptc1023, "512-1023 byte frames transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522", + CTLFLAG_RD, &stats->ptc1522, "1024-1522 byte frames transmitted"); +} /* ixgbe_add_hw_stats */ + +/************************************************************************ + * ixgbe_sysctl_tdh_handler - Transmit Descriptor Head handler function + * + * Retrieves the TDH value from the hardware + ************************************************************************/ +static int +ixgbe_sysctl_tdh_handler(SYSCTL_HANDLER_ARGS) +{ + struct tx_ring *txr = ((struct tx_ring *)oidp->oid_arg1); + int error; + unsigned int val; + + if (!txr) + return (0); + + val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_TDH(txr->me)); + error = sysctl_handle_int(oidp, &val, 0, req); + if (error || !req->newptr) + return error; + + return (0); +} /* ixgbe_sysctl_tdh_handler */ + +/************************************************************************ + * ixgbe_sysctl_tdt_handler - Transmit Descriptor Tail handler function + * + * Retrieves the TDT value from the hardware + ************************************************************************/ +static int +ixgbe_sysctl_tdt_handler(SYSCTL_HANDLER_ARGS) +{ + struct tx_ring *txr = ((struct tx_ring *)oidp->oid_arg1); + int error; + unsigned int val; + + if (!txr) + return (0); + + val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_TDT(txr->me)); + error = sysctl_handle_int(oidp, &val, 0, req); + if (error || !req->newptr) + return error; + + return (0); +} /* ixgbe_sysctl_tdt_handler */ + +/************************************************************************ + * ixgbe_sysctl_rdh_handler - Receive Descriptor Head handler function + * + * Retrieves the RDH value from the hardware + ************************************************************************/ +static int +ixgbe_sysctl_rdh_handler(SYSCTL_HANDLER_ARGS) +{ + struct rx_ring *rxr = ((struct rx_ring *)oidp->oid_arg1); + int error; + unsigned int val; + + if (!rxr) + return (0); + + val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_RDH(rxr->me)); + error = sysctl_handle_int(oidp, &val, 0, req); + if (error || !req->newptr) + return error; + + return (0); +} /* ixgbe_sysctl_rdh_handler */ + +/************************************************************************ + * ixgbe_sysctl_rdt_handler - Receive Descriptor Tail handler function + * + * Retrieves the RDT value from the hardware + ************************************************************************/ +static int +ixgbe_sysctl_rdt_handler(SYSCTL_HANDLER_ARGS) +{ + struct rx_ring *rxr = ((struct rx_ring *)oidp->oid_arg1); + int error; + unsigned int val; + + if (!rxr) + return (0); + + val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_RDT(rxr->me)); + error = sysctl_handle_int(oidp, &val, 0, req); + if (error || !req->newptr) + return error; + + return (0); +} /* ixgbe_sysctl_rdt_handler */ + +/************************************************************************ + * ixgbe_register_vlan + * + * Run via vlan config EVENT, it enables us to use the + * HW Filter table since we can get the vlan id. This + * just creates the entry in the soft version of the + * VFTA, init will repopulate the real table. + ************************************************************************/ +static void +ixgbe_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) +{ + struct adapter *adapter = ifp->if_softc; + u16 index, bit; + + if (ifp->if_softc != arg) /* Not our event */ + return; + + if ((vtag == 0) || (vtag > 4095)) /* Invalid */ + return; IXGBE_CORE_LOCK(adapter); - ixgbe_init_locked(adapter); + index = (vtag >> 5) & 0x7F; + bit = vtag & 0x1F; + adapter->shadow_vfta[index] |= (1 << bit); + ++adapter->num_vlans; + ixgbe_setup_vlan_hw_support(adapter); IXGBE_CORE_UNLOCK(adapter); - return; -} +} /* ixgbe_register_vlan */ +/************************************************************************ + * ixgbe_unregister_vlan + * + * Run via vlan unconfig EVENT, remove our entry in the soft vfta. + ************************************************************************/ static void -ixgbe_config_gpie(struct adapter *adapter) +ixgbe_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) { + struct adapter *adapter = ifp->if_softc; + u16 index, bit; + + if (ifp->if_softc != arg) + return; + + if ((vtag == 0) || (vtag > 4095)) /* Invalid */ + return; + + IXGBE_CORE_LOCK(adapter); + index = (vtag >> 5) & 0x7F; + bit = vtag & 0x1F; + adapter->shadow_vfta[index] &= ~(1 << bit); + --adapter->num_vlans; + /* Re-init to load the changes */ + ixgbe_setup_vlan_hw_support(adapter); + IXGBE_CORE_UNLOCK(adapter); +} /* ixgbe_unregister_vlan */ + +/************************************************************************ + * ixgbe_setup_vlan_hw_support + ************************************************************************/ +static void +ixgbe_setup_vlan_hw_support(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; struct ixgbe_hw *hw = &adapter->hw; - u32 gpie; + struct rx_ring *rxr; + int i; + u32 ctrl; - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); - - /* Fan Failure Interrupt */ - if (hw->device_id == IXGBE_DEV_ID_82598AT) - gpie |= IXGBE_SDP1_GPIEN; /* - * Module detection (SDP2) - * Media ready (SDP1) + * We get here thru init_locked, meaning + * a soft reset, this has already cleared + * the VFTA and other state, so if there + * have been no vlan's registered do nothing. */ - if (hw->mac.type == ixgbe_mac_82599EB) { - gpie |= IXGBE_SDP2_GPIEN; - if (hw->device_id != IXGBE_DEV_ID_82599_QSFP_SF_QP) - gpie |= IXGBE_SDP1_GPIEN; + if (adapter->num_vlans == 0) + return; + + /* Setup the queues for vlans */ + for (i = 0; i < adapter->num_queues; i++) { + rxr = &adapter->rx_rings[i]; + /* On 82599 the VLAN enable is per/queue in RXDCTL */ + if (hw->mac.type != ixgbe_mac_82598EB) { + ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)); + ctrl |= IXGBE_RXDCTL_VME; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), ctrl); + } + rxr->vtag_strip = TRUE; } + if ((ifp->if_capenable & IFCAP_VLAN_HWFILTER) == 0) + return; + /* + * A soft reset zero's out the VFTA, so + * we need to repopulate it now. + */ + for (i = 0; i < IXGBE_VFTA_SIZE; i++) + if (adapter->shadow_vfta[i] != 0) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), + adapter->shadow_vfta[i]); + + ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + /* Enable the Filter Table if enabled */ + if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) { + ctrl &= ~IXGBE_VLNCTRL_CFIEN; + ctrl |= IXGBE_VLNCTRL_VFE; + } + if (hw->mac.type == ixgbe_mac_82598EB) + ctrl |= IXGBE_VLNCTRL_VME; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl); +} /* ixgbe_setup_vlan_hw_support */ + +/************************************************************************ + * ixgbe_get_slot_info + * + * Get the width and transaction speed of + * the slot this adapter is plugged into. + ************************************************************************/ +static void +ixgbe_get_slot_info(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; + u32 offset; + u16 link; + int bus_info_valid = TRUE; + + /* Some devices are behind an internal bridge */ + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_SFP_SF_QP: + case IXGBE_DEV_ID_82599_QSFP_SF_QP: + goto get_parent_info; + default: + break; + } + + ixgbe_get_bus_info(hw); + /* - * Thermal Failure Detection (X540) - * Link Detection (X552 SFP+, X552/X557-AT) + * Some devices don't use PCI-E, but there is no need + * to display "Unknown" for bus speed and width. */ - if (hw->mac.type == ixgbe_mac_X540 || - hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP || - hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) - gpie |= IXGBE_SDP0_GPIEN_X540; - - if (adapter->msix > 1) { - /* Enable Enhanced MSIX mode */ - gpie |= IXGBE_GPIE_MSIX_MODE; - gpie |= IXGBE_GPIE_EIAME | IXGBE_GPIE_PBA_SUPPORT | - IXGBE_GPIE_OCD; + switch (hw->mac.type) { + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + return; + default: + goto display; } - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); +get_parent_info: + /* + * For the Quad port adapter we need to parse back + * up the PCI tree to find the speed of the expansion + * slot into which this adapter is plugged. A bit more work. + */ + dev = device_get_parent(device_get_parent(dev)); +#ifdef IXGBE_DEBUG + device_printf(dev, "parent pcib = %x,%x,%x\n", pci_get_bus(dev), + pci_get_slot(dev), pci_get_function(dev)); +#endif + dev = device_get_parent(device_get_parent(dev)); +#ifdef IXGBE_DEBUG + device_printf(dev, "slot pcib = %x,%x,%x\n", pci_get_bus(dev), + pci_get_slot(dev), pci_get_function(dev)); +#endif + /* Now get the PCI Express Capabilities offset */ + if (pci_find_cap(dev, PCIY_EXPRESS, &offset)) { + /* + * Hmm...can't get PCI-Express capabilities. + * Falling back to default method. + */ + bus_info_valid = FALSE; + ixgbe_get_bus_info(hw); + goto display; + } + /* ...and read the Link Status Register */ + link = pci_read_config(dev, offset + PCIER_LINK_STA, 2); + ixgbe_set_pci_config_data_generic(hw, link); + +display: + device_printf(dev, "PCI Express Bus: Speed %s %s\n", + ((hw->bus.speed == ixgbe_bus_speed_8000) ? "8.0GT/s" : + (hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0GT/s" : + (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5GT/s" : + "Unknown"), + ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" : + (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" : + (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" : + "Unknown")); + + if (bus_info_valid) { + if ((hw->device_id != IXGBE_DEV_ID_82599_SFP_SF_QP) && + ((hw->bus.width <= ixgbe_bus_width_pcie_x4) && + (hw->bus.speed == ixgbe_bus_speed_2500))) { + device_printf(dev, "PCI-Express bandwidth available for this card\n is not sufficient for optimal performance.\n"); + device_printf(dev, "For optimal performance a x8 PCIE, or x4 PCIE Gen2 slot is required.\n"); + } + if ((hw->device_id == IXGBE_DEV_ID_82599_SFP_SF_QP) && + ((hw->bus.width <= ixgbe_bus_width_pcie_x8) && + (hw->bus.speed < ixgbe_bus_speed_8000))) { + device_printf(dev, "PCI-Express bandwidth available for this card\n is not sufficient for optimal performance.\n"); + device_printf(dev, "For optimal performance a x8 PCIE Gen3 slot is required.\n"); + } + } else + device_printf(dev, "Unable to determine slot speed/width. The speed/width reported are that of the internal switch.\n"); + return; -} - -/* - * Requires adapter->max_frame_size to be set. - */ -static void -ixgbe_config_delay_values(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 rxpb, frame, size, tmp; - - frame = adapter->max_frame_size; - - /* Calculate High Water */ - switch (hw->mac.type) { - case ixgbe_mac_X540: - case ixgbe_mac_X550: - case ixgbe_mac_X550EM_x: - tmp = IXGBE_DV_X540(frame, frame); - break; - default: - tmp = IXGBE_DV(frame, frame); - break; - } - size = IXGBE_BT2KB(tmp); - rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10; - hw->fc.high_water[0] = rxpb - size; - - /* Now calculate Low Water */ - switch (hw->mac.type) { - case ixgbe_mac_X540: - case ixgbe_mac_X550: - case ixgbe_mac_X550EM_x: - tmp = IXGBE_LOW_DV_X540(frame); - break; - default: - tmp = IXGBE_LOW_DV(frame); - break; - } - hw->fc.low_water[0] = IXGBE_BT2KB(tmp); - - hw->fc.requested_mode = adapter->fc; - hw->fc.pause_time = IXGBE_FC_PAUSE; - hw->fc.send_xon = TRUE; -} - -/* -** -** MSIX Interrupt Handlers and Tasklets -** -*/ +} /* ixgbe_get_slot_info */ +/************************************************************************ + * ixgbe_enable_queue - MSI-X Interrupt Handlers and Tasklets + ************************************************************************/ static inline void ixgbe_enable_queue(struct adapter *adapter, u32 vector) { struct ixgbe_hw *hw = &adapter->hw; - u64 queue = (u64)(1 << vector); - u32 mask; + u64 queue = (u64)(1 << vector); + u32 mask; if (hw->mac.type == ixgbe_mac_82598EB) { - mask = (IXGBE_EIMS_RTX_QUEUE & queue); - IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); + mask = (IXGBE_EIMS_RTX_QUEUE & queue); + IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); } else { - mask = (queue & 0xFFFFFFFF); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); - mask = (queue >> 32); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask); + mask = (queue & 0xFFFFFFFF); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); + mask = (queue >> 32); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask); } -} +} /* ixgbe_enable_queue */ +/************************************************************************ + * ixgbe_disable_queue + ************************************************************************/ static inline void ixgbe_disable_queue(struct adapter *adapter, u32 vector) { struct ixgbe_hw *hw = &adapter->hw; - u64 queue = (u64)(1 << vector); - u32 mask; + u64 queue = (u64)(1 << vector); + u32 mask; if (hw->mac.type == ixgbe_mac_82598EB) { - mask = (IXGBE_EIMS_RTX_QUEUE & queue); - IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask); + mask = (IXGBE_EIMS_RTX_QUEUE & queue); + IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask); } else { - mask = (queue & 0xFFFFFFFF); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask); - mask = (queue >> 32); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask); + mask = (queue & 0xFFFFFFFF); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask); + mask = (queue >> 32); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask); } -} +} /* ixgbe_disable_queue */ -static void -ixgbe_handle_que(void *context, int pending) -{ - struct ix_queue *que = context; - struct adapter *adapter = que->adapter; - struct tx_ring *txr = que->txr; - struct ifnet *ifp = adapter->ifp; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ixgbe_rxeof(que); - IXGBE_TX_LOCK(txr); - ixgbe_txeof(txr); -#ifndef IXGBE_LEGACY_TX - if (!drbr_empty(ifp, txr->br)) - ixgbe_mq_start_locked(ifp, txr); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - ixgbe_start_locked(txr, ifp); -#endif - IXGBE_TX_UNLOCK(txr); - } - - /* Reenable this interrupt */ - if (que->res != NULL) - ixgbe_enable_queue(adapter, que->msix); - else - ixgbe_enable_intr(adapter); - return; -} - - -/********************************************************************* - * - * Legacy Interrupt Service routine - * - **********************************************************************/ - -static void -ixgbe_legacy_irq(void *arg) -{ - struct ix_queue *que = arg; - struct adapter *adapter = que->adapter; - struct ixgbe_hw *hw = &adapter->hw; - struct ifnet *ifp = adapter->ifp; - struct tx_ring *txr = adapter->tx_rings; - bool more; - u32 reg_eicr; - - - reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICR); - - ++que->irqs; - if (reg_eicr == 0) { - ixgbe_enable_intr(adapter); - return; - } - - more = ixgbe_rxeof(que); - - IXGBE_TX_LOCK(txr); - ixgbe_txeof(txr); -#ifdef IXGBE_LEGACY_TX - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - ixgbe_start_locked(txr, ifp); -#else - if (!drbr_empty(ifp, txr->br)) - ixgbe_mq_start_locked(ifp, txr); -#endif - IXGBE_TX_UNLOCK(txr); - - /* Check for fan failure */ - if ((hw->device_id == IXGBE_DEV_ID_82598AT) && - (reg_eicr & IXGBE_EICR_GPI_SDP1)) { - device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! " - "REPLACE IMMEDIATELY!!\n"); - IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); - } - - /* Link status change */ - if (reg_eicr & IXGBE_EICR_LSC) - taskqueue_enqueue(adapter->tq, &adapter->link_task); - - /* External PHY interrupt */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T && - (reg_eicr & IXGBE_EICR_GPI_SDP0_X540)) - taskqueue_enqueue(adapter->tq, &adapter->phy_task); - - if (more) - taskqueue_enqueue(que->tq, &que->que_task); - else - ixgbe_enable_intr(adapter); - return; -} - - -/********************************************************************* - * - * MSIX Queue Interrupt Service routine - * - **********************************************************************/ +/************************************************************************ + * ixgbe_msix_que - MSI-X Queue Interrupt Service routine + ************************************************************************/ void ixgbe_msix_que(void *arg) { - struct ix_queue *que = arg; + struct ix_queue *que = arg; struct adapter *adapter = que->adapter; struct ifnet *ifp = adapter->ifp; - struct tx_ring *txr = que->txr; - struct rx_ring *rxr = que->rxr; - bool more; - u32 newitr = 0; + struct tx_ring *txr = que->txr; + struct rx_ring *rxr = que->rxr; + bool more; + u32 newitr = 0; /* Protect against spurious interrupts */ @@ -1573,13 +1958,8 @@ ixgbe_msix_que(void *arg) IXGBE_TX_LOCK(txr); ixgbe_txeof(txr); -#ifdef IXGBE_LEGACY_TX - if (!IFQ_DRV_IS_EMPTY(ifp->if_snd)) - ixgbe_start_locked(txr, ifp); -#else - if (!drbr_empty(ifp, txr->br)) - ixgbe_mq_start_locked(ifp, txr); -#endif + if (!ixgbe_ring_empty(ifp, txr->br)) + ixgbe_start_locked(ifp, txr); IXGBE_TX_UNLOCK(txr); /* Do AIM now? */ @@ -1587,26 +1967,25 @@ ixgbe_msix_que(void *arg) if (adapter->enable_aim == FALSE) goto no_calc; /* - ** Do Adaptive Interrupt Moderation: - ** - Write out last calculated setting - ** - Calculate based on average size over - ** the last interval. - */ - if (que->eitr_setting) - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(que->msix), que->eitr_setting); - - que->eitr_setting = 0; + * Do Adaptive Interrupt Moderation: + * - Write out last calculated setting + * - Calculate based on average size over + * the last interval. + */ + if (que->eitr_setting) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(que->msix), + que->eitr_setting); + + que->eitr_setting = 0; + + /* Idle, do nothing */ + if ((txr->bytes == 0) && (rxr->bytes == 0)) + goto no_calc; - /* Idle, do nothing */ - if ((txr->bytes == 0) && (rxr->bytes == 0)) - goto no_calc; - if ((txr->bytes) && (txr->packets)) - newitr = txr->bytes/txr->packets; + newitr = txr->bytes/txr->packets; if ((rxr->bytes) && (rxr->packets)) - newitr = max(newitr, - (rxr->bytes / rxr->packets)); + newitr = max(newitr, (rxr->bytes / rxr->packets)); newitr += 24; /* account for hardware frame, crc */ /* set an upper boundary */ @@ -1618,134 +1997,41 @@ ixgbe_msix_que(void *arg) else newitr = (newitr / 2); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) - newitr |= newitr << 16; - else - newitr |= IXGBE_EITR_CNT_WDIS; - - /* save for next interrupt */ - que->eitr_setting = newitr; + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + newitr |= newitr << 16; + else + newitr |= IXGBE_EITR_CNT_WDIS; - /* Reset state */ - txr->bytes = 0; - txr->packets = 0; - rxr->bytes = 0; - rxr->packets = 0; + /* save for next interrupt */ + que->eitr_setting = newitr; + + /* Reset state */ + txr->bytes = 0; + txr->packets = 0; + rxr->bytes = 0; + rxr->packets = 0; no_calc: if (more) taskqueue_enqueue(que->tq, &que->que_task); else ixgbe_enable_queue(adapter, que->msix); + return; -} - +} /* ixgbe_msix_que */ +/************************************************************************ + * ixgbe_media_status - Media Ioctl callback + * + * Called whenever the user queries the status of + * the interface using ifconfig. + ************************************************************************/ static void -ixgbe_msix_link(void *arg) +ixgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) { - struct adapter *adapter = arg; + struct adapter *adapter = ifp->if_softc; struct ixgbe_hw *hw = &adapter->hw; - u32 reg_eicr, mod_mask; - - ++adapter->link_irq; - - /* Pause other interrupts */ - IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_OTHER); - - /* First get the cause */ - reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICS); - /* Be sure the queue bits are not cleared */ - reg_eicr &= ~IXGBE_EICR_RTX_QUEUE; - /* Clear interrupt with write */ - IXGBE_WRITE_REG(hw, IXGBE_EICR, reg_eicr); - - /* Link status change */ - if (reg_eicr & IXGBE_EICR_LSC) { - IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); - taskqueue_enqueue(adapter->tq, &adapter->link_task); - } - - if (adapter->hw.mac.type != ixgbe_mac_82598EB) { -#ifdef IXGBE_FDIR - if (reg_eicr & IXGBE_EICR_FLOW_DIR) { - /* This is probably overkill :) */ - if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1)) - return; - /* Disable the interrupt */ - IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FLOW_DIR); - taskqueue_enqueue(adapter->tq, &adapter->fdir_task); - } else -#endif - if (reg_eicr & IXGBE_EICR_ECC) { - device_printf(adapter->dev, "CRITICAL: ECC ERROR!! " - "Please Reboot!!\n"); - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); - } - - /* Check for over temp condition */ - if (reg_eicr & IXGBE_EICR_TS) { - device_printf(adapter->dev, "CRITICAL: OVER TEMP!! " - "PHY IS SHUT DOWN!!\n"); - device_printf(adapter->dev, "System shutdown required!\n"); - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS); - } -#ifdef PCI_IOV - if (reg_eicr & IXGBE_EICR_MAILBOX) - taskqueue_enqueue(adapter->tq, &adapter->mbx_task); -#endif - } - - /* Pluggable optics-related interrupt */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) - mod_mask = IXGBE_EICR_GPI_SDP0_X540; - else - mod_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); - - if (ixgbe_is_sfp(hw)) { - if (reg_eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw)) { - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); - taskqueue_enqueue(adapter->tq, &adapter->msf_task); - } else if (reg_eicr & mod_mask) { - IXGBE_WRITE_REG(hw, IXGBE_EICR, mod_mask); - taskqueue_enqueue(adapter->tq, &adapter->mod_task); - } - } - - /* Check for fan failure */ - if ((hw->device_id == IXGBE_DEV_ID_82598AT) && - (reg_eicr & IXGBE_EICR_GPI_SDP1)) { - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); - device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! " - "REPLACE IMMEDIATELY!!\n"); - } - - /* External PHY interrupt */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T && - (reg_eicr & IXGBE_EICR_GPI_SDP0_X540)) { - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540); - taskqueue_enqueue(adapter->tq, &adapter->phy_task); - } - - /* Re-enable other interrupts */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); - return; -} - -/********************************************************************* - * - * Media Ioctl callback - * - * This routine is called whenever the user queries the status of - * the interface using ifconfig. - * - **********************************************************************/ -static void -ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) -{ - struct adapter *adapter = ifp->if_softc; - struct ixgbe_hw *hw = &adapter->hw; - int layer; + int layer; INIT_DEBUGOUT("ixgbe_media_status: begin"); IXGBE_CORE_LOCK(adapter); @@ -1764,7 +2050,8 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T || layer & IXGBE_PHYSICAL_LAYER_1000BASE_T || - layer & IXGBE_PHYSICAL_LAYER_100BASE_TX) + layer & IXGBE_PHYSICAL_LAYER_100BASE_TX || + layer & IXGBE_PHYSICAL_LAYER_10BASE_T) switch (adapter->link_speed) { case IXGBE_LINK_SPEED_10GB_FULL: ifmr->ifm_active |= IFM_10G_T | IFM_FDX; @@ -1775,6 +2062,9 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) case IXGBE_LINK_SPEED_100_FULL: ifmr->ifm_active |= IFM_100_TX | IFM_FDX; break; + case IXGBE_LINK_SPEED_10_FULL: + ifmr->ifm_active |= IFM_10_T | IFM_FDX; + break; } if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU || layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) @@ -1818,9 +2108,9 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) break; } /* - ** XXX: These need to use the proper media types once - ** they're added. - */ + * XXX: These need to use the proper media types once + * they're added. + */ #ifndef IFM_ETH_XTYPE if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) switch (adapter->link_speed) { @@ -1834,8 +2124,9 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) ifmr->ifm_active |= IFM_1000_CX | IFM_FDX; break; } - else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4 - || layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) + else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4 || + layer & IXGBE_PHYSICAL_LAYER_2500BASE_KX || + layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) switch (adapter->link_speed) { case IXGBE_LINK_SPEED_10GB_FULL: ifmr->ifm_active |= IFM_10G_CX4 | IFM_FDX; @@ -1860,8 +2151,9 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) ifmr->ifm_active |= IFM_1000_KX | IFM_FDX; break; } - else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4 - || layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) + else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4 || + layer & IXGBE_PHYSICAL_LAYER_2500BASE_KX || + layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) switch (adapter->link_speed) { case IXGBE_LINK_SPEED_10GB_FULL: ifmr->ifm_active |= IFM_10G_KX4 | IFM_FDX; @@ -1874,11 +2166,11 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) break; } #endif - + /* If nothing is recognized... */ if (IFM_SUBTYPE(ifmr->ifm_active) == 0) ifmr->ifm_active |= IFM_UNKNOWN; - + #if __FreeBSD_version >= 900025 /* Display current flow control setting used on link */ if (hw->fc.current_mode == ixgbe_fc_rx_pause || @@ -1892,22 +2184,20 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) IXGBE_CORE_UNLOCK(adapter); return; -} +} /* ixgbe_media_status */ -/********************************************************************* +/************************************************************************ + * ixgbe_media_change - Media Ioctl callback * - * Media Ioctl callback - * - * This routine is called when the user changes speed/duplex using - * media/mediopt option with ifconfig. - * - **********************************************************************/ + * Called when the user changes speed/duplex using + * media/mediopt option with ifconfig. + ************************************************************************/ static int -ixgbe_media_change(struct ifnet * ifp) +ixgbe_media_change(struct ifnet *ifp) { - struct adapter *adapter = ifp->if_softc; - struct ifmedia *ifm = &adapter->media; - struct ixgbe_hw *hw = &adapter->hw; + struct adapter *adapter = ifp->if_softc; + struct ifmedia *ifm = &adapter->media; + struct ixgbe_hw *hw = &adapter->hw; ixgbe_link_speed speed = 0; INIT_DEBUGOUT("ixgbe_media_change: begin"); @@ -1919,97 +2209,87 @@ ixgbe_media_change(struct ifnet * ifp) return (ENODEV); /* - ** We don't actually need to check against the supported - ** media types of the adapter; ifmedia will take care of - ** that for us. - */ + * We don't actually need to check against the supported + * media types of the adapter; ifmedia will take care of + * that for us. + */ + switch (IFM_SUBTYPE(ifm->ifm_media)) { + case IFM_AUTO: + case IFM_10G_T: + speed |= IXGBE_LINK_SPEED_100_FULL; + speed |= IXGBE_LINK_SPEED_1GB_FULL; + speed |= IXGBE_LINK_SPEED_10GB_FULL; + break; + case IFM_10G_LRM: + case IFM_10G_LR: #ifndef IFM_ETH_XTYPE - switch (IFM_SUBTYPE(ifm->ifm_media)) { - case IFM_AUTO: - case IFM_10G_T: - speed |= IXGBE_LINK_SPEED_100_FULL; - case IFM_10G_LRM: case IFM_10G_SR: /* KR, too */ - case IFM_10G_LR: case IFM_10G_CX4: /* KX4 */ - speed |= IXGBE_LINK_SPEED_1GB_FULL; - case IFM_10G_TWINAX: - speed |= IXGBE_LINK_SPEED_10GB_FULL; - break; - case IFM_1000_T: - speed |= IXGBE_LINK_SPEED_100_FULL; - case IFM_1000_LX: - case IFM_1000_SX: - case IFM_1000_CX: /* KX */ - speed |= IXGBE_LINK_SPEED_1GB_FULL; - break; - case IFM_100_TX: - speed |= IXGBE_LINK_SPEED_100_FULL; - break; - default: - goto invalid; - } #else - switch (IFM_SUBTYPE(ifm->ifm_media)) { - case IFM_AUTO: - case IFM_10G_T: - speed |= IXGBE_LINK_SPEED_100_FULL; - case IFM_10G_LRM: case IFM_10G_KR: - case IFM_10G_LR: case IFM_10G_KX4: +#endif speed |= IXGBE_LINK_SPEED_1GB_FULL; - case IFM_10G_TWINAX: speed |= IXGBE_LINK_SPEED_10GB_FULL; break; +#ifndef IFM_ETH_XTYPE + case IFM_1000_CX: /* KX */ +#else + case IFM_1000_KX: +#endif + case IFM_1000_LX: + case IFM_1000_SX: + speed |= IXGBE_LINK_SPEED_1GB_FULL; + break; case IFM_1000_T: speed |= IXGBE_LINK_SPEED_100_FULL; - case IFM_1000_LX: - case IFM_1000_SX: - case IFM_1000_KX: speed |= IXGBE_LINK_SPEED_1GB_FULL; break; + case IFM_10G_TWINAX: + speed |= IXGBE_LINK_SPEED_10GB_FULL; + break; case IFM_100_TX: speed |= IXGBE_LINK_SPEED_100_FULL; break; + case IFM_10_T: + speed |= IXGBE_LINK_SPEED_10_FULL; + break; default: goto invalid; } -#endif hw->mac.autotry_restart = TRUE; hw->mac.ops.setup_link(hw, speed, TRUE); - if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) { - adapter->advertise = 0; - } else { - if ((speed & IXGBE_LINK_SPEED_10GB_FULL) != 0) - adapter->advertise |= 1 << 2; - if ((speed & IXGBE_LINK_SPEED_1GB_FULL) != 0) - adapter->advertise |= 1 << 1; - if ((speed & IXGBE_LINK_SPEED_100_FULL) != 0) - adapter->advertise |= 1 << 0; - } + adapter->advertise = + ((speed & IXGBE_LINK_SPEED_10GB_FULL) ? 4 : 0) | + ((speed & IXGBE_LINK_SPEED_1GB_FULL) ? 2 : 0) | + ((speed & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0) | + ((speed & IXGBE_LINK_SPEED_10_FULL) ? 8 : 0); return (0); invalid: device_printf(adapter->dev, "Invalid media type!\n"); - return (EINVAL); -} + return (EINVAL); +} /* ixgbe_media_change */ + +/************************************************************************ + * ixgbe_set_promisc + ************************************************************************/ static void ixgbe_set_promisc(struct adapter *adapter) { - u_int32_t reg_rctl; - struct ifnet *ifp = adapter->ifp; - int mcnt = 0; + struct ifnet *ifp = adapter->ifp; + int mcnt = 0; + u32 rctl; - reg_rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); - reg_rctl &= (~IXGBE_FCTRL_UPE); + rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); + rctl &= (~IXGBE_FCTRL_UPE); if (ifp->if_flags & IFF_ALLMULTI) mcnt = MAX_NUM_MULTICAST_ADDRESSES; else { - struct ifmultiaddr *ifma; + struct ifmultiaddr *ifma; #if __FreeBSD_version < 800000 IF_ADDR_LOCK(ifp); #else @@ -2029,38 +2309,975 @@ ixgbe_set_promisc(struct adapter *adapter) #endif } if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) - reg_rctl &= (~IXGBE_FCTRL_MPE); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_rctl); + rctl &= (~IXGBE_FCTRL_MPE); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl); if (ifp->if_flags & IFF_PROMISC) { - reg_rctl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_rctl); + rctl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl); } else if (ifp->if_flags & IFF_ALLMULTI) { - reg_rctl |= IXGBE_FCTRL_MPE; - reg_rctl &= ~IXGBE_FCTRL_UPE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_rctl); + rctl |= IXGBE_FCTRL_MPE; + rctl &= ~IXGBE_FCTRL_UPE; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl); } +} /* ixgbe_set_promisc */ + +/************************************************************************ + * ixgbe_msix_link - Link status change ISR (MSI/MSI-X) + ************************************************************************/ +static void +ixgbe_msix_link(void *arg) +{ + struct adapter *adapter = arg; + struct ixgbe_hw *hw = &adapter->hw; + u32 eicr, eicr_mask; + s32 retval; + + ++adapter->link_irq; + + /* Pause other interrupts */ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_OTHER); + + /* First get the cause */ + eicr = IXGBE_READ_REG(hw, IXGBE_EICS); + /* Be sure the queue bits are not cleared */ + eicr &= ~IXGBE_EICR_RTX_QUEUE; + /* Clear interrupt with write */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); + + /* Link status change */ + if (eicr & IXGBE_EICR_LSC) { + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); + taskqueue_enqueue(adapter->tq, &adapter->link_task); + } + + if (adapter->hw.mac.type != ixgbe_mac_82598EB) { + if ((adapter->feat_en & IXGBE_FEATURE_FDIR) && + (eicr & IXGBE_EICR_FLOW_DIR)) { + /* This is probably overkill :) */ + if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1)) + return; + /* Disable the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR); + taskqueue_enqueue(adapter->tq, &adapter->fdir_task); + } + + if (eicr & IXGBE_EICR_ECC) { + device_printf(adapter->dev, + "CRITICAL: ECC ERROR!! Please Reboot!!\n"); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); + } + + /* Check for over temp condition */ + if (adapter->feat_en & IXGBE_FEATURE_TEMP_SENSOR) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_X550EM_a: + if (!(eicr & IXGBE_EICR_GPI_SDP0_X550EM_a)) + break; + IXGBE_WRITE_REG(hw, IXGBE_EIMC, + IXGBE_EICR_GPI_SDP0_X550EM_a); + IXGBE_WRITE_REG(hw, IXGBE_EICR, + IXGBE_EICR_GPI_SDP0_X550EM_a); + retval = hw->phy.ops.check_overtemp(hw); + if (retval != IXGBE_ERR_OVERTEMP) + break; + device_printf(adapter->dev, "CRITICAL: OVER TEMP!! PHY IS SHUT DOWN!!\n"); + device_printf(adapter->dev, "System shutdown required!\n"); + break; + default: + if (!(eicr & IXGBE_EICR_TS)) + break; + retval = hw->phy.ops.check_overtemp(hw); + if (retval != IXGBE_ERR_OVERTEMP) + break; + device_printf(adapter->dev, "CRITICAL: OVER TEMP!! PHY IS SHUT DOWN!!\n"); + device_printf(adapter->dev, "System shutdown required!\n"); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS); + break; + } + } + + /* Check for VF message */ + if ((adapter->feat_en & IXGBE_FEATURE_SRIOV) && + (eicr & IXGBE_EICR_MAILBOX)) + taskqueue_enqueue(adapter->tq, &adapter->mbx_task); + } + + if (ixgbe_is_sfp(hw)) { + /* Pluggable optics-related interrupt */ + if (hw->mac.type >= ixgbe_mac_X540) + eicr_mask = IXGBE_EICR_GPI_SDP0_X540; + else + eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); + + if (eicr & eicr_mask) { + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); + taskqueue_enqueue(adapter->tq, &adapter->mod_task); + } + + if ((hw->mac.type == ixgbe_mac_82599EB) && + (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { + IXGBE_WRITE_REG(hw, IXGBE_EICR, + IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); + taskqueue_enqueue(adapter->tq, &adapter->msf_task); + } + } + + /* Check for fan failure */ + if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) { + ixgbe_check_fan_failure(adapter, eicr, TRUE); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); + } + + /* External PHY interrupt */ + if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && + (eicr & IXGBE_EICR_GPI_SDP0_X540)) { + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540); + taskqueue_enqueue(adapter->tq, &adapter->phy_task); + } + + /* Re-enable other interrupts */ + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); +} /* ixgbe_msix_link */ + +/************************************************************************ + * ixgbe_sysctl_interrupt_rate_handler + ************************************************************************/ +static int +ixgbe_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS) +{ + struct ix_queue *que = ((struct ix_queue *)oidp->oid_arg1); + int error; + unsigned int reg, usec, rate; + + reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_EITR(que->msix)); + usec = ((reg & 0x0FF8) >> 3); + if (usec > 0) + rate = 500000 / usec; + else + rate = 0; + error = sysctl_handle_int(oidp, &rate, 0, req); + if (error || !req->newptr) + return error; + reg &= ~0xfff; /* default, no limitation */ + ixgbe_max_interrupt_rate = 0; + if (rate > 0 && rate < 500000) { + if (rate < 1000) + rate = 1000; + ixgbe_max_interrupt_rate = rate; + reg |= ((4000000/rate) & 0xff8); + } + IXGBE_WRITE_REG(&que->adapter->hw, IXGBE_EITR(que->msix), reg); + + return (0); +} /* ixgbe_sysctl_interrupt_rate_handler */ + +/************************************************************************ + * ixgbe_add_device_sysctls + ************************************************************************/ +static void +ixgbe_add_device_sysctls(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; + struct sysctl_oid_list *child; + struct sysctl_ctx_list *ctx; + + ctx = device_get_sysctl_ctx(dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); + + /* Sysctls for all devices */ + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fc", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_sysctl_flowcntl, "I", IXGBE_SYSCTL_DESC_SET_FC); + + adapter->enable_aim = ixgbe_enable_aim; + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "enable_aim", CTLFLAG_RW, + &adapter->enable_aim, 1, "Interrupt Moderation"); + + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "advertise_speed", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_sysctl_advertise, "I", + IXGBE_SYSCTL_DESC_ADV_SPEED); + +#ifdef IXGBE_DEBUG + /* testing sysctls (for all devices) */ + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "power_state", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_sysctl_power_state, + "I", "PCI Power State"); + + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "print_rss_config", + CTLTYPE_STRING | CTLFLAG_RD, adapter, 0, + ixgbe_sysctl_print_rss_config, "A", "Prints RSS Configuration"); +#endif + /* for X550 series devices */ + if (hw->mac.type >= ixgbe_mac_X550) + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "dmac", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_sysctl_dmac, + "I", "DMA Coalesce"); + + /* for WoL-capable devices */ + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) { + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "wol_enable", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, + ixgbe_sysctl_wol_enable, "I", "Enable/Disable Wake on LAN"); + + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "wufc", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_sysctl_wufc, + "I", "Enable/Disable Wake Up Filters"); + } + + /* for X552/X557-AT devices */ + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) { + struct sysctl_oid *phy_node; + struct sysctl_oid_list *phy_list; + + phy_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "phy", + CTLFLAG_RD, NULL, "External PHY sysctls"); + phy_list = SYSCTL_CHILDREN(phy_node); + + SYSCTL_ADD_PROC(ctx, phy_list, OID_AUTO, "temp", + CTLTYPE_INT | CTLFLAG_RD, adapter, 0, ixgbe_sysctl_phy_temp, + "I", "Current External PHY Temperature (Celsius)"); + + SYSCTL_ADD_PROC(ctx, phy_list, OID_AUTO, "overtemp_occurred", + CTLTYPE_INT | CTLFLAG_RD, adapter, 0, + ixgbe_sysctl_phy_overtemp_occurred, "I", + "External PHY High Temperature Event Occurred"); + } + + if (adapter->feat_cap & IXGBE_FEATURE_EEE) { + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "eee_state", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, + ixgbe_sysctl_eee_state, "I", "EEE Power Save State"); + } +} /* ixgbe_add_device_sysctls */ + +/************************************************************************ + * ixgbe_allocate_pci_resources + ************************************************************************/ +static int +ixgbe_allocate_pci_resources(struct adapter *adapter) +{ + device_t dev = adapter->dev; + int rid; + + rid = PCIR_BAR(0); + adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + + if (!(adapter->pci_mem)) { + device_printf(dev, "Unable to allocate bus resource: memory\n"); + return (ENXIO); + } + + /* Save bus_space values for READ/WRITE_REG macros */ + adapter->osdep.mem_bus_space_tag = rman_get_bustag(adapter->pci_mem); + adapter->osdep.mem_bus_space_handle = + rman_get_bushandle(adapter->pci_mem); + /* Set hw values for shared code */ + adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle; + + return (0); +} /* ixgbe_allocate_pci_resources */ + +/************************************************************************ + * ixgbe_detach - Device removal routine + * + * Called when the driver is being removed. + * Stops the adapter and deallocates all the resources + * that were allocated for driver operation. + * + * return 0 on success, positive on failure + ************************************************************************/ +static int +ixgbe_detach(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + struct ix_queue *que = adapter->queues; + struct tx_ring *txr = adapter->tx_rings; + u32 ctrl_ext; + + INIT_DEBUGOUT("ixgbe_detach: begin"); + + /* Make sure VLANS are not using driver */ + if (adapter->ifp->if_vlantrunk != NULL) { + device_printf(dev, "Vlan in use, detach first\n"); + return (EBUSY); + } + + if (ixgbe_pci_iov_detach(dev) != 0) { + device_printf(dev, "SR-IOV in use; detach first.\n"); + return (EBUSY); + } + + ether_ifdetach(adapter->ifp); + /* Stop the adapter */ + IXGBE_CORE_LOCK(adapter); + ixgbe_setup_low_power_mode(adapter); + IXGBE_CORE_UNLOCK(adapter); + + for (int i = 0; i < adapter->num_queues; i++, que++, txr++) { + if (que->tq) { + if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) + taskqueue_drain(que->tq, &txr->txq_task); + taskqueue_drain(que->tq, &que->que_task); + taskqueue_free(que->tq); + } + } + + /* Drain the Link queue */ + if (adapter->tq) { + taskqueue_drain(adapter->tq, &adapter->link_task); + taskqueue_drain(adapter->tq, &adapter->mod_task); + taskqueue_drain(adapter->tq, &adapter->msf_task); + if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) + taskqueue_drain(adapter->tq, &adapter->mbx_task); + taskqueue_drain(adapter->tq, &adapter->phy_task); + if (adapter->feat_en & IXGBE_FEATURE_FDIR) + taskqueue_drain(adapter->tq, &adapter->fdir_task); + taskqueue_free(adapter->tq); + } + + /* let hardware know driver is unloading */ + ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); + ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext); + + /* Unregister VLAN events */ + if (adapter->vlan_attach != NULL) + EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach); + if (adapter->vlan_detach != NULL) + EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); + + callout_drain(&adapter->timer); + + if (adapter->feat_en & IXGBE_FEATURE_NETMAP) + netmap_detach(adapter->ifp); + + ixgbe_free_pci_resources(adapter); + bus_generic_detach(dev); + if_free(adapter->ifp); + + ixgbe_free_transmit_structures(adapter); + ixgbe_free_receive_structures(adapter); + free(adapter->queues, M_DEVBUF); + free(adapter->mta, M_IXGBE); + + IXGBE_CORE_LOCK_DESTROY(adapter); + + return (0); +} /* ixgbe_detach */ + +/************************************************************************ + * ixgbe_setup_low_power_mode - LPLU/WoL preparation + * + * Prepare the adapter/port for LPLU and/or WoL + ************************************************************************/ +static int +ixgbe_setup_low_power_mode(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + device_t dev = adapter->dev; + s32 error = 0; + + mtx_assert(&adapter->core_mtx, MA_OWNED); + + /* Limit power management flow to X550EM baseT */ + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T && + hw->phy.ops.enter_lplu) { + /* Turn off support for APM wakeup. (Using ACPI instead) */ + IXGBE_WRITE_REG(hw, IXGBE_GRC, + IXGBE_READ_REG(hw, IXGBE_GRC) & ~(u32)2); + + /* + * Clear Wake Up Status register to prevent any previous wakeup + * events from waking us up immediately after we suspend. + */ + IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff); + + /* + * Program the Wakeup Filter Control register with user filter + * settings + */ + IXGBE_WRITE_REG(hw, IXGBE_WUFC, adapter->wufc); + + /* Enable wakeups and power management in Wakeup Control */ + IXGBE_WRITE_REG(hw, IXGBE_WUC, + IXGBE_WUC_WKEN | IXGBE_WUC_PME_EN); + + /* X550EM baseT adapters need a special LPLU flow */ + hw->phy.reset_disable = true; + ixgbe_stop(adapter); + error = hw->phy.ops.enter_lplu(hw); + if (error) + device_printf(dev, "Error entering LPLU: %d\n", error); + hw->phy.reset_disable = false; + } else { + /* Just stop for other adapters */ + ixgbe_stop(adapter); + } + + return error; +} /* ixgbe_setup_low_power_mode */ + +/************************************************************************ + * ixgbe_shutdown - Shutdown entry point + ************************************************************************/ +static int +ixgbe_shutdown(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + int error = 0; + + INIT_DEBUGOUT("ixgbe_shutdown: begin"); + + IXGBE_CORE_LOCK(adapter); + error = ixgbe_setup_low_power_mode(adapter); + IXGBE_CORE_UNLOCK(adapter); + + return (error); +} /* ixgbe_shutdown */ + +/************************************************************************ + * ixgbe_suspend + * + * From D0 to D3 + ************************************************************************/ +static int +ixgbe_suspend(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + int error = 0; + + INIT_DEBUGOUT("ixgbe_suspend: begin"); + + IXGBE_CORE_LOCK(adapter); + + error = ixgbe_setup_low_power_mode(adapter); + + IXGBE_CORE_UNLOCK(adapter); + + return (error); +} /* ixgbe_suspend */ + +/************************************************************************ + * ixgbe_resume + * + * From D3 to D0 + ************************************************************************/ +static int +ixgbe_resume(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + struct ifnet *ifp = adapter->ifp; + struct ixgbe_hw *hw = &adapter->hw; + u32 wus; + + INIT_DEBUGOUT("ixgbe_resume: begin"); + + IXGBE_CORE_LOCK(adapter); + + /* Read & clear WUS register */ + wus = IXGBE_READ_REG(hw, IXGBE_WUS); + if (wus) + device_printf(dev, "Woken up by (WUS): %#010x\n", + IXGBE_READ_REG(hw, IXGBE_WUS)); + IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff); + /* And clear WUFC until next low-power transition */ + IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0); + + /* + * Required after D3->D0 transition; + * will re-advertise all previous advertised speeds + */ + if (ifp->if_flags & IFF_UP) + ixgbe_init_locked(adapter); + + IXGBE_CORE_UNLOCK(adapter); + + return (0); +} /* ixgbe_resume */ + +/************************************************************************ + * ixgbe_set_if_hwassist - Set the various hardware offload abilities. + * + * Takes the ifnet's if_capenable flags (e.g. set by the user using + * ifconfig) and indicates to the OS via the ifnet's if_hwassist + * field what mbuf offload flags the driver will understand. + ************************************************************************/ +static void +ixgbe_set_if_hwassist(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + + ifp->if_hwassist = 0; +#if __FreeBSD_version >= 1000000 + if (ifp->if_capenable & IFCAP_TSO4) + ifp->if_hwassist |= CSUM_IP_TSO; + if (ifp->if_capenable & IFCAP_TSO6) + ifp->if_hwassist |= CSUM_IP6_TSO; + if (ifp->if_capenable & IFCAP_TXCSUM) { + ifp->if_hwassist |= (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP); + if (adapter->hw.mac.type != ixgbe_mac_82598EB) + ifp->if_hwassist |= CSUM_IP_SCTP; + } + if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) { + ifp->if_hwassist |= (CSUM_IP6_UDP | CSUM_IP6_TCP); + if (adapter->hw.mac.type != ixgbe_mac_82598EB) + ifp->if_hwassist |= CSUM_IP6_SCTP; + } +#else + if (ifp->if_capenable & IFCAP_TSO) + ifp->if_hwassist |= CSUM_TSO; + if (ifp->if_capenable & IFCAP_TXCSUM) { + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); + if (adapter->hw.mac.type != ixgbe_mac_82598EB) + ifp->if_hwassist |= CSUM_SCTP; + } +#endif +} /* ixgbe_set_if_hwassist */ + +/************************************************************************ + * ixgbe_init_locked - Init entry point + * + * Used in two ways: It is used by the stack as an init + * entry point in network interface structure. It is also + * used by the driver as a hw/sw initialization routine to + * get to a consistent state. + * + * return 0 on success, positive on failure + ************************************************************************/ +void +ixgbe_init_locked(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; + struct tx_ring *txr; + struct rx_ring *rxr; + u32 txdctl, mhadd; + u32 rxdctl, rxctrl; + u32 ctrl_ext; + int err = 0; + + mtx_assert(&adapter->core_mtx, MA_OWNED); + INIT_DEBUGOUT("ixgbe_init_locked: begin"); + + hw->adapter_stopped = FALSE; + ixgbe_stop_adapter(hw); + callout_stop(&adapter->timer); + + /* Queue indices may change with IOV mode */ + ixgbe_align_all_queue_indices(adapter); + + /* reprogram the RAR[0] in case user changed it. */ + ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, IXGBE_RAH_AV); + + /* Get the latest mac address, User can use a LAA */ + bcopy(IF_LLADDR(ifp), hw->mac.addr, IXGBE_ETH_LENGTH_OF_ADDRESS); + ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, 1); + hw->addr_ctrl.rar_used_count = 1; + + /* Set hardware offload abilities from ifnet flags */ + ixgbe_set_if_hwassist(adapter); + + /* Prepare transmit descriptors and buffers */ + if (ixgbe_setup_transmit_structures(adapter)) { + device_printf(dev, "Could not setup transmit structures\n"); + ixgbe_stop(adapter); + return; + } + + ixgbe_init_hw(hw); + ixgbe_initialize_iov(adapter); + ixgbe_initialize_transmit_units(adapter); + + /* Setup Multicast table */ + ixgbe_set_multi(adapter); + + /* Determine the correct mbuf pool, based on frame size */ + if (adapter->max_frame_size <= MCLBYTES) + adapter->rx_mbuf_sz = MCLBYTES; + else + adapter->rx_mbuf_sz = MJUMPAGESIZE; + + /* Prepare receive descriptors and buffers */ + if (ixgbe_setup_receive_structures(adapter)) { + device_printf(dev, "Could not setup receive structures\n"); + ixgbe_stop(adapter); + return; + } + + /* Configure RX settings */ + ixgbe_initialize_receive_units(adapter); + + /* Enable SDP & MSI-X interrupts based on adapter */ + ixgbe_config_gpie(adapter); + + /* Set MTU size */ + if (ifp->if_mtu > ETHERMTU) { + /* aka IXGBE_MAXFRS on 82599 and newer */ + mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); + mhadd &= ~IXGBE_MHADD_MFS_MASK; + mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); + } + + /* Now enable all the queues */ + for (int i = 0; i < adapter->num_queues; i++) { + txr = &adapter->tx_rings[i]; + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(txr->me)); + txdctl |= IXGBE_TXDCTL_ENABLE; + /* Set WTHRESH to 8, burst writeback */ + txdctl |= (8 << 16); + /* + * When the internal queue falls below PTHRESH (32), + * start prefetching as long as there are at least + * HTHRESH (1) buffers ready. The values are taken + * from the Intel linux driver 3.8.21. + * Prefetching enables tx line rate even with 1 queue. + */ + txdctl |= (32 << 0) | (1 << 8); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(txr->me), txdctl); + } + + for (int i = 0, j = 0; i < adapter->num_queues; i++) { + rxr = &adapter->rx_rings[i]; + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)); + if (hw->mac.type == ixgbe_mac_82598EB) { + /* + * PTHRESH = 21 + * HTHRESH = 4 + * WTHRESH = 8 + */ + rxdctl &= ~0x3FFFFF; + rxdctl |= 0x080420; + } + rxdctl |= IXGBE_RXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), rxdctl); + for (; j < 10; j++) { + if (IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)) & + IXGBE_RXDCTL_ENABLE) + break; + else + msec_delay(1); + } + wmb(); + + /* + * In netmap mode, we must preserve the buffers made + * available to userspace before the if_init() + * (this is true by default on the TX side, because + * init makes all buffers available to userspace). + * + * netmap_reset() and the device specific routines + * (e.g. ixgbe_setup_receive_rings()) map these + * buffers at the end of the NIC ring, so here we + * must set the RDT (tail) register to make sure + * they are not overwritten. + * + * In this driver the NIC ring starts at RDH = 0, + * RDT points to the last slot available for reception (?), + * so RDT = num_rx_desc - 1 means the whole ring is available. + */ +#ifdef DEV_NETMAP + if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) && + (ifp->if_capenable & IFCAP_NETMAP)) { + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_kring *kring = &na->rx_rings[i]; + int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring); + + IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me), t); + } else +#endif /* DEV_NETMAP */ + IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me), + adapter->num_rx_desc - 1); + } + + /* Enable Receive engine */ + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (hw->mac.type == ixgbe_mac_82598EB) + rxctrl |= IXGBE_RXCTRL_DMBYPS; + rxctrl |= IXGBE_RXCTRL_RXEN; + ixgbe_enable_rx_dma(hw, rxctrl); + + callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter); + + /* Set up MSI-X routing */ + if (adapter->feat_en & IXGBE_FEATURE_MSIX) { + ixgbe_configure_ivars(adapter); + /* Set up auto-mask */ + if (hw->mac.type == ixgbe_mac_82598EB) + IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); + else { + IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF); + IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF); + } + } else { /* Simple settings for Legacy/MSI */ + ixgbe_set_ivar(adapter, 0, 0, 0); + ixgbe_set_ivar(adapter, 0, 0, 1); + IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); + } + + ixgbe_init_fdir(adapter); + + /* + * Check on any SFP devices that + * need to be kick-started + */ + if (hw->phy.type == ixgbe_phy_none) { + err = hw->phy.ops.identify(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Unsupported SFP+ module type was detected.\n"); + return; + } + } + + /* Set moderation on the Link interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EITR(adapter->vector), IXGBE_LINK_ITR); + + /* Config/Enable Link */ + ixgbe_config_link(adapter); + + /* Hardware Packet Buffer & Flow Control setup */ + ixgbe_config_delay_values(adapter); + + /* Initialize the FC settings */ + ixgbe_start_hw(hw); + + /* Set up VLAN support and filter */ + ixgbe_setup_vlan_hw_support(adapter); + + /* Setup DMA Coalescing */ + ixgbe_config_dmac(adapter); + + /* And now turn on interrupts */ + ixgbe_enable_intr(adapter); + + /* Enable the use of the MBX by the VF's */ + if (adapter->feat_en & IXGBE_FEATURE_SRIOV) { + ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); + ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; + IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + } + + /* Now inform the stack we're ready */ + ifp->if_drv_flags |= IFF_DRV_RUNNING; + return; -} +} /* ixgbe_init_locked */ +/************************************************************************ + * ixgbe_init + ************************************************************************/ +static void +ixgbe_init(void *arg) +{ + struct adapter *adapter = arg; -/********************************************************************* - * Multicast Update + IXGBE_CORE_LOCK(adapter); + ixgbe_init_locked(adapter); + IXGBE_CORE_UNLOCK(adapter); + + return; +} /* ixgbe_init */ + +/************************************************************************ + * ixgbe_set_ivar * - * This routine is called whenever multicast address list is updated. - * - **********************************************************************/ -#define IXGBE_RAR_ENTRIES 16 + * Setup the correct IVAR register for a particular MSI-X interrupt + * (yes this is all very magic and confusing :) + * - entry is the register array entry + * - vector is the MSI-X vector for this queue + * - type is RX/TX/MISC + ************************************************************************/ +static void +ixgbe_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 ivar, index; + vector |= IXGBE_IVAR_ALLOC_VAL; + + switch (hw->mac.type) { + + case ixgbe_mac_82598EB: + if (type == -1) + entry = IXGBE_IVAR_OTHER_CAUSES_INDEX; + else + entry += (type * 64); + index = (entry >> 2) & 0x1F; + ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index)); + ivar &= ~(0xFF << (8 * (entry & 0x3))); + ivar |= (vector << (8 * (entry & 0x3))); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR(index), ivar); + break; + + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + if (type == -1) { /* MISC IVAR */ + index = (entry & 1) * 8; + ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC); + ivar &= ~(0xFF << index); + ivar |= (vector << index); + IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, ivar); + } else { /* RX/TX IVARS */ + index = (16 * (entry & 1)) + (8 * type); + ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(entry >> 1)); + ivar &= ~(0xFF << index); + ivar |= (vector << index); + IXGBE_WRITE_REG(hw, IXGBE_IVAR(entry >> 1), ivar); + } + + default: + break; + } +} /* ixgbe_set_ivar */ + +/************************************************************************ + * ixgbe_configure_ivars + ************************************************************************/ +static void +ixgbe_configure_ivars(struct adapter *adapter) +{ + struct ix_queue *que = adapter->queues; + u32 newitr; + + if (ixgbe_max_interrupt_rate > 0) + newitr = (4000000 / ixgbe_max_interrupt_rate) & 0x0FF8; + else { + /* + * Disable DMA coalescing if interrupt moderation is + * disabled. + */ + adapter->dmac = 0; + newitr = 0; + } + + for (int i = 0; i < adapter->num_queues; i++, que++) { + struct rx_ring *rxr = &adapter->rx_rings[i]; + struct tx_ring *txr = &adapter->tx_rings[i]; + /* First the RX queue entry */ + ixgbe_set_ivar(adapter, rxr->me, que->msix, 0); + /* ... and the TX */ + ixgbe_set_ivar(adapter, txr->me, que->msix, 1); + /* Set an Initial EITR value */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(que->msix), newitr); + } + + /* For the Link interrupt */ + ixgbe_set_ivar(adapter, 1, adapter->vector, -1); +} /* ixgbe_configure_ivars */ + +/************************************************************************ + * ixgbe_config_gpie + ************************************************************************/ +static void +ixgbe_config_gpie(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 gpie; + + gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + + if (adapter->feat_en & IXGBE_FEATURE_MSIX) { + /* Enable Enhanced MSI-X mode */ + gpie |= IXGBE_GPIE_MSIX_MODE + | IXGBE_GPIE_EIAME + | IXGBE_GPIE_PBA_SUPPORT + | IXGBE_GPIE_OCD; + } + + /* Fan Failure Interrupt */ + if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) + gpie |= IXGBE_SDP1_GPIEN; + + /* Thermal Sensor Interrupt */ + if (adapter->feat_en & IXGBE_FEATURE_TEMP_SENSOR) + gpie |= IXGBE_SDP0_GPIEN_X540; + + /* Link detection */ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + gpie |= IXGBE_SDP1_GPIEN | IXGBE_SDP2_GPIEN; + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + gpie |= IXGBE_SDP0_GPIEN_X540; + break; + default: + break; + } + + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); + + return; +} /* ixgbe_config_gpie */ + +/************************************************************************ + * ixgbe_config_delay_values + * + * Requires adapter->max_frame_size to be set. + ************************************************************************/ +static void +ixgbe_config_delay_values(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rxpb, frame, size, tmp; + + frame = adapter->max_frame_size; + + /* Calculate High Water */ + switch (hw->mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + tmp = IXGBE_DV_X540(frame, frame); + break; + default: + tmp = IXGBE_DV(frame, frame); + break; + } + size = IXGBE_BT2KB(tmp); + rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10; + hw->fc.high_water[0] = rxpb - size; + + /* Now calculate Low Water */ + switch (hw->mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + tmp = IXGBE_LOW_DV_X540(frame); + break; + default: + tmp = IXGBE_LOW_DV(frame); + break; + } + hw->fc.low_water[0] = IXGBE_BT2KB(tmp); + + hw->fc.pause_time = IXGBE_FC_PAUSE; + hw->fc.send_xon = TRUE; +} /* ixgbe_config_delay_values */ + +/************************************************************************ + * ixgbe_set_multi - Multicast Update + * + * Called whenever multicast address list is updated. + ************************************************************************/ static void ixgbe_set_multi(struct adapter *adapter) { - u32 fctrl; - u8 *update_ptr; - struct ifmultiaddr *ifma; - struct ixgbe_mc_addr *mta; - int mcnt = 0; - struct ifnet *ifp = adapter->ifp; + struct ifmultiaddr *ifma; + struct ixgbe_mc_addr *mta; + struct ifnet *ifp = adapter->ifp; + u8 *update_ptr; + int mcnt = 0; + u32 fctrl; IOCTL_DEBUGOUT("ixgbe_set_multi: begin"); @@ -2098,23 +3315,25 @@ ixgbe_set_multi(struct adapter *adapter) fctrl &= ~IXGBE_FCTRL_UPE; } else fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); - + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl); if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) { update_ptr = (u8 *)mta; - ixgbe_update_mc_addr_list(&adapter->hw, - update_ptr, mcnt, ixgbe_mc_array_itr, TRUE); + ixgbe_update_mc_addr_list(&adapter->hw, update_ptr, mcnt, + ixgbe_mc_array_itr, TRUE); } return; -} +} /* ixgbe_set_multi */ -/* - * This is an iterator function now needed by the multicast - * shared code. It simply feeds the shared code routine the - * addresses in the array of ixgbe_set_multi() one by one. - */ +/************************************************************************ + * ixgbe_mc_array_itr + * + * An iterator function needed by the multicast shared code. + * It feeds the shared code routine the addresses in the + * array of ixgbe_set_multi() one by one. + ************************************************************************/ static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq) { @@ -2124,26 +3343,24 @@ ixgbe_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq) *vmdq = mta->vmdq; *update_ptr = (u8*)(mta + 1); + return (mta->addr); -} +} /* ixgbe_mc_array_itr */ - -/********************************************************************* - * Timer routine +/************************************************************************ + * ixgbe_local_timer - Timer routine * - * This routine checks for link status,updates statistics, - * and runs the watchdog check. - * - **********************************************************************/ - + * Checks for link status, updates statistics, + * and runs the watchdog check. + ************************************************************************/ static void ixgbe_local_timer(void *arg) { - struct adapter *adapter = arg; - device_t dev = adapter->dev; + struct adapter *adapter = arg; + device_t dev = adapter->dev; struct ix_queue *que = adapter->queues; - u64 queues = 0; - int hung = 0; + u64 queues = 0; + int hung = 0; mtx_assert(&adapter->core_mtx, MA_OWNED); @@ -2156,19 +3373,19 @@ ixgbe_local_timer(void *arg) ixgbe_update_stats_counters(adapter); /* - ** Check the TX queues status - ** - mark hung queues so we don't schedule on them - ** - watchdog only if all queues show hung - */ + * Check the TX queues status + * - mark hung queues so we don't schedule on them + * - watchdog only if all queues show hung + */ for (int i = 0; i < adapter->num_queues; i++, que++) { /* Keep track of queues with work for soft irq */ if (que->txr->busy) queues |= ((u64)1 << que->me); /* - ** Each time txeof runs without cleaning, but there - ** are uncleaned descriptors it increments busy. If - ** we get to the MAX we declare it hung. - */ + * Each time txeof runs without cleaning, but there + * are uncleaned descriptors it increments busy. If + * we get to the MAX we declare it hung. + */ if (que->busy == IXGBE_QUEUE_HUNG) { ++hung; /* Mark the queue as inactive */ @@ -2177,15 +3394,14 @@ ixgbe_local_timer(void *arg) } else { /* Check if we've come back from hung */ if ((adapter->active_queues & ((u64)1 << que->me)) == 0) - adapter->active_queues |= ((u64)1 << que->me); + adapter->active_queues |= ((u64)1 << que->me); } if (que->busy >= IXGBE_MAX_TX_BUSY) { - device_printf(dev,"Warning queue %d " - "appears to be hung!\n", i); + device_printf(dev, + "Warning queue %d appears to be hung!\n", i); que->txr->busy = IXGBE_QUEUE_HUNG; ++hung; } - } /* Only truly watchdog if all queues show hung */ @@ -2204,65 +3420,146 @@ ixgbe_local_timer(void *arg) adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; adapter->watchdog_events++; ixgbe_init_locked(adapter); -} +} /* ixgbe_local_timer */ - -/* -** Note: this routine updates the OS on the link state -** the real check of the hardware only happens with -** a link interrupt. -*/ -static void -ixgbe_update_link_status(struct adapter *adapter) +/************************************************************************ + * ixgbe_sfp_probe + * + * Determine if a port had optics inserted. + ************************************************************************/ +static bool +ixgbe_sfp_probe(struct adapter *adapter) { - struct ifnet *ifp = adapter->ifp; - device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; + device_t dev = adapter->dev; + bool result = FALSE; - if (adapter->link_up){ - if (adapter->link_active == FALSE) { - if (bootverbose) - device_printf(dev,"Link is up %d Gbps %s \n", - ((adapter->link_speed == 128)? 10:1), - "Full Duplex"); - adapter->link_active = TRUE; - /* Update any Flow Control changes */ - ixgbe_fc_enable(&adapter->hw); - /* Update DMA coalescing config */ - ixgbe_config_dmac(adapter); - if_link_state_change(ifp, LINK_STATE_UP); -#ifdef PCI_IOV - ixgbe_ping_all_vfs(adapter); -#endif - } - } else { /* Link down */ - if (adapter->link_active == TRUE) { - if (bootverbose) - device_printf(dev,"Link is Down\n"); - if_link_state_change(ifp, LINK_STATE_DOWN); - adapter->link_active = FALSE; -#ifdef PCI_IOV - ixgbe_ping_all_vfs(adapter); -#endif + if ((hw->phy.type == ixgbe_phy_nl) && + (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) { + s32 ret = hw->phy.ops.identify_sfp(hw); + if (ret) + goto out; + ret = hw->phy.ops.reset(hw); + adapter->sfp_probe = FALSE; + if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, "Unsupported SFP+ module detected!"); + device_printf(dev, + "Reload driver with supported module.\n"); + goto out; + } else + device_printf(dev, "SFP+ module detected!\n"); + /* We now have supported optics */ + result = TRUE; + } +out: + + return (result); +} /* ixgbe_sfp_probe */ + +/************************************************************************ + * ixgbe_handle_mod - Tasklet for SFP module interrupts + ************************************************************************/ +static void +ixgbe_handle_mod(void *context, int pending) +{ + struct adapter *adapter = context; + struct ixgbe_hw *hw = &adapter->hw; + device_t dev = adapter->dev; + u32 err, cage_full = 0; + + if (adapter->hw.need_crosstalk_fix) { + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP2; + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP0; + break; + default: + break; } + + if (!cage_full) + return; } - return; -} + err = hw->phy.ops.identify_sfp(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Unsupported SFP+ module type was detected.\n"); + return; + } + + err = hw->mac.ops.setup_sfp(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Setup failure - unsupported SFP+ module type.\n"); + return; + } + taskqueue_enqueue(adapter->tq, &adapter->msf_task); +} /* ixgbe_handle_mod */ -/********************************************************************* +/************************************************************************ + * ixgbe_handle_msf - Tasklet for MSF (multispeed fiber) interrupts + ************************************************************************/ +static void +ixgbe_handle_msf(void *context, int pending) +{ + struct adapter *adapter = context; + struct ixgbe_hw *hw = &adapter->hw; + u32 autoneg; + bool negotiate; + + /* get_supported_phy_layer will call hw->phy.ops.identify_sfp() */ + adapter->phy_layer = ixgbe_get_supported_physical_layer(hw); + + autoneg = hw->phy.autoneg_advertised; + if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) + hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate); + if (hw->mac.ops.setup_link) + hw->mac.ops.setup_link(hw, autoneg, TRUE); + + /* Adjust media types shown in ifconfig */ + ifmedia_removeall(&adapter->media); + ixgbe_add_media_types(adapter); + ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); +} /* ixgbe_handle_msf */ + +/************************************************************************ + * ixgbe_handle_phy - Tasklet for external PHY interrupts + ************************************************************************/ +static void +ixgbe_handle_phy(void *context, int pending) +{ + struct adapter *adapter = context; + struct ixgbe_hw *hw = &adapter->hw; + int error; + + error = hw->phy.ops.handle_lasi(hw); + if (error == IXGBE_ERR_OVERTEMP) + device_printf(adapter->dev, "CRITICAL: EXTERNAL PHY OVER TEMP!! PHY will downshift to lower power state!\n"); + else if (error) + device_printf(adapter->dev, + "Error handling LASI interrupt: %d\n", error); +} /* ixgbe_handle_phy */ + +/************************************************************************ + * ixgbe_stop - Stop the hardware * - * This routine disables all traffic on the adapter by issuing a - * global reset on the MAC and deallocates TX/RX buffers. - * - **********************************************************************/ - + * Disables all traffic on the adapter by issuing a + * global reset on the MAC and deallocates TX/RX buffers. + ************************************************************************/ static void ixgbe_stop(void *arg) { - struct ifnet *ifp; - struct adapter *adapter = arg; + struct ifnet *ifp; + struct adapter *adapter = arg; struct ixgbe_hw *hw = &adapter->hw; + ifp = adapter->ifp; mtx_assert(&adapter->core_mtx, MA_OWNED); @@ -2284,1211 +3581,140 @@ ixgbe_stop(void *arg) /* Update the stack */ adapter->link_up = FALSE; - ixgbe_update_link_status(adapter); + ixgbe_update_link_status(adapter); /* reprogram the RAR[0] in case user changed it. */ ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV); return; -} +} /* ixgbe_stop */ - -/********************************************************************* +/************************************************************************ + * ixgbe_update_link_status - Update OS on link state * - * Determine hardware revision. - * - **********************************************************************/ + * Note: Only updates the OS on the cached link state. + * The real check of the hardware only happens with + * a link interrupt. + ************************************************************************/ static void -ixgbe_identify_hardware(struct adapter *adapter) +ixgbe_update_link_status(struct adapter *adapter) { - device_t dev = adapter->dev; - struct ixgbe_hw *hw = &adapter->hw; + struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; - /* Save off the information about this board */ - hw->vendor_id = pci_get_vendor(dev); - hw->device_id = pci_get_device(dev); - hw->revision_id = pci_read_config(dev, PCIR_REVID, 1); - hw->subsystem_vendor_id = - pci_read_config(dev, PCIR_SUBVEND_0, 2); - hw->subsystem_device_id = - pci_read_config(dev, PCIR_SUBDEV_0, 2); - - /* - ** Make sure BUSMASTER is set - */ - pci_enable_busmaster(dev); - - /* We need this here to set the num_segs below */ - ixgbe_set_mac_type(hw); - - /* Pick up the 82599 settings */ - if (hw->mac.type != ixgbe_mac_82598EB) { - hw->phy.smart_speed = ixgbe_smart_speed; - adapter->num_segs = IXGBE_82599_SCATTER; - } else - adapter->num_segs = IXGBE_82598_SCATTER; + if (adapter->link_up) { + if (adapter->link_active == FALSE) { + if (bootverbose) + device_printf(dev, "Link is up %d Gbps %s \n", + ((adapter->link_speed == 128) ? 10 : 1), + "Full Duplex"); + adapter->link_active = TRUE; + /* Update any Flow Control changes */ + ixgbe_fc_enable(&adapter->hw); + /* Update DMA coalescing config */ + ixgbe_config_dmac(adapter); + if_link_state_change(ifp, LINK_STATE_UP); + if (adapter->feat_en & IXGBE_FEATURE_SRIOV) + ixgbe_ping_all_vfs(adapter); + } + } else { /* Link down */ + if (adapter->link_active == TRUE) { + if (bootverbose) + device_printf(dev, "Link is Down\n"); + if_link_state_change(ifp, LINK_STATE_DOWN); + adapter->link_active = FALSE; + if (adapter->feat_en & IXGBE_FEATURE_SRIOV) + ixgbe_ping_all_vfs(adapter); + } + } return; -} +} /* ixgbe_update_link_status */ -/********************************************************************* - * - * Determine optic type - * - **********************************************************************/ +/************************************************************************ + * ixgbe_config_dmac - Configure DMA Coalescing + ************************************************************************/ static void -ixgbe_setup_optics(struct adapter *adapter) +ixgbe_config_dmac(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_dmac_config *dcfg = &hw->mac.dmac_config; + + if (hw->mac.type < ixgbe_mac_X550 || !hw->mac.ops.dmac_config) + return; + + if (dcfg->watchdog_timer ^ adapter->dmac || + dcfg->link_speed ^ adapter->link_speed) { + dcfg->watchdog_timer = adapter->dmac; + dcfg->fcoe_en = false; + dcfg->link_speed = adapter->link_speed; + dcfg->num_tcs = 1; + + INIT_DEBUGOUT2("dmac settings: watchdog %d, link speed %d\n", + dcfg->watchdog_timer, dcfg->link_speed); + + hw->mac.ops.dmac_config(hw); + } +} /* ixgbe_config_dmac */ + +/************************************************************************ + * ixgbe_enable_intr + ************************************************************************/ +static void +ixgbe_enable_intr(struct adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - int layer; + struct ix_queue *que = adapter->queues; + u32 mask, fwsm; - layer = adapter->phy_layer = ixgbe_get_supported_physical_layer(hw); + mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) { - adapter->optics = IFM_10G_T; - return; - } - - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_T) { - adapter->optics = IFM_1000_T; - return; - } - - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) { - adapter->optics = IFM_1000_SX; - return; - } - - if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_LR | - IXGBE_PHYSICAL_LAYER_10GBASE_LRM)) { - adapter->optics = IFM_10G_LR; - return; - } - - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) { - adapter->optics = IFM_10G_SR; - return; - } - - if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU) { - adapter->optics = IFM_10G_TWINAX; - return; - } - - if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | - IXGBE_PHYSICAL_LAYER_10GBASE_CX4)) { - adapter->optics = IFM_10G_CX4; - return; - } - - /* If we get here just set the default */ - adapter->optics = IFM_ETHER | IFM_AUTO; - return; -} - -/********************************************************************* - * - * Setup the Legacy or MSI Interrupt handler - * - **********************************************************************/ -static int -ixgbe_allocate_legacy(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct ix_queue *que = adapter->queues; -#ifndef IXGBE_LEGACY_TX - struct tx_ring *txr = adapter->tx_rings; -#endif - int error, rid = 0; - - /* MSI RID at 1 */ - if (adapter->msix == 1) - rid = 1; - - /* We allocate a single interrupt resource */ - adapter->res = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); - if (adapter->res == NULL) { - device_printf(dev, "Unable to allocate bus resource: " - "interrupt\n"); - return (ENXIO); - } - - /* - * Try allocating a fast interrupt and the associated deferred - * processing contexts. - */ -#ifndef IXGBE_LEGACY_TX - TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr); -#endif - TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que); - que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT, - taskqueue_thread_enqueue, &que->tq); - taskqueue_start_threads(&que->tq, 1, PI_NET, "%s ixq", - device_get_nameunit(adapter->dev)); - - /* Tasklets for Link, SFP and Multispeed Fiber */ - TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter); - TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter); - TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter); - TASK_INIT(&adapter->phy_task, 0, ixgbe_handle_phy, adapter); -#ifdef IXGBE_FDIR - TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter); -#endif - adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT, - taskqueue_thread_enqueue, &adapter->tq); - taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", - device_get_nameunit(adapter->dev)); - - if ((error = bus_setup_intr(dev, adapter->res, - INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_legacy_irq, - que, &adapter->tag)) != 0) { - device_printf(dev, "Failed to register fast interrupt " - "handler: %d\n", error); - taskqueue_free(que->tq); - taskqueue_free(adapter->tq); - que->tq = NULL; - adapter->tq = NULL; - return (error); - } - /* For simplicity in the handlers */ - adapter->active_queues = IXGBE_EIMS_ENABLE_MASK; - - return (0); -} - - -/********************************************************************* - * - * Setup MSIX Interrupt resources and handlers - * - **********************************************************************/ -static int -ixgbe_allocate_msix(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct ix_queue *que = adapter->queues; - struct tx_ring *txr = adapter->tx_rings; - int error, rid, vector = 0; - int cpu_id = 0; -#ifdef RSS - cpuset_t cpu_mask; -#endif - -#ifdef RSS - /* - * If we're doing RSS, the number of queues needs to - * match the number of RSS buckets that are configured. - * - * + If there's more queues than RSS buckets, we'll end - * up with queues that get no traffic. - * - * + If there's more RSS buckets than queues, we'll end - * up having multiple RSS buckets map to the same queue, - * so there'll be some contention. - */ - if (adapter->num_queues != rss_getnumbuckets()) { - device_printf(dev, - "%s: number of queues (%d) != number of RSS buckets (%d)" - "; performance will be impacted.\n", - __func__, - adapter->num_queues, - rss_getnumbuckets()); - } -#endif - - for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) { - rid = vector + 1; - que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - if (que->res == NULL) { - device_printf(dev,"Unable to allocate" - " bus resource: que interrupt [%d]\n", vector); - return (ENXIO); - } - /* Set the handler function */ - error = bus_setup_intr(dev, que->res, - INTR_TYPE_NET | INTR_MPSAFE, NULL, - ixgbe_msix_que, que, &que->tag); - if (error) { - que->res = NULL; - device_printf(dev, "Failed to register QUE handler"); - return (error); - } -#if __FreeBSD_version >= 800504 - bus_describe_intr(dev, que->res, que->tag, "q%d", i); -#endif - que->msix = vector; - adapter->active_queues |= (u64)(1 << que->msix); -#ifdef RSS - /* - * The queue ID is used as the RSS layer bucket ID. - * We look up the queue ID -> RSS CPU ID and select - * that. - */ - cpu_id = rss_getcpu(i % rss_getnumbuckets()); -#else - /* - * Bind the msix vector, and thus the - * rings to the corresponding cpu. - * - * This just happens to match the default RSS round-robin - * bucket -> queue -> CPU allocation. - */ - if (adapter->num_queues > 1) - cpu_id = i; -#endif - if (adapter->num_queues > 1) - bus_bind_intr(dev, que->res, cpu_id); -#ifdef IXGBE_DEBUG -#ifdef RSS - device_printf(dev, - "Bound RSS bucket %d to CPU %d\n", - i, cpu_id); -#else - device_printf(dev, - "Bound queue %d to cpu %d\n", - i, cpu_id); -#endif -#endif /* IXGBE_DEBUG */ - - -#ifndef IXGBE_LEGACY_TX - TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr); -#endif - TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que); - que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT, - taskqueue_thread_enqueue, &que->tq); -#ifdef RSS - CPU_SETOF(cpu_id, &cpu_mask); - taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET, - &cpu_mask, - "%s (bucket %d)", - device_get_nameunit(adapter->dev), - cpu_id); -#else - taskqueue_start_threads(&que->tq, 1, PI_NET, "%s:q%d", - device_get_nameunit(adapter->dev), i); -#endif - } - - /* and Link */ - rid = vector + 1; - adapter->res = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); - if (!adapter->res) { - device_printf(dev,"Unable to allocate" - " bus resource: Link interrupt [%d]\n", rid); - return (ENXIO); - } - /* Set the link handler function */ - error = bus_setup_intr(dev, adapter->res, - INTR_TYPE_NET | INTR_MPSAFE, NULL, - ixgbe_msix_link, adapter, &adapter->tag); - if (error) { - adapter->res = NULL; - device_printf(dev, "Failed to register LINK handler"); - return (error); - } -#if __FreeBSD_version >= 800504 - bus_describe_intr(dev, adapter->res, adapter->tag, "link"); -#endif - adapter->vector = vector; - /* Tasklets for Link, SFP and Multispeed Fiber */ - TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter); - TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter); - TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter); -#ifdef PCI_IOV - TASK_INIT(&adapter->mbx_task, 0, ixgbe_handle_mbx, adapter); -#endif - TASK_INIT(&adapter->phy_task, 0, ixgbe_handle_phy, adapter); -#ifdef IXGBE_FDIR - TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter); -#endif - adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT, - taskqueue_thread_enqueue, &adapter->tq); - taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", - device_get_nameunit(adapter->dev)); - - return (0); -} - -/* - * Setup Either MSI/X or MSI - */ -static int -ixgbe_setup_msix(struct adapter *adapter) -{ - device_t dev = adapter->dev; - int rid, want, queues, msgs; - - /* Override by tuneable */ - if (ixgbe_enable_msix == 0) - goto msi; - - /* First try MSI/X */ - msgs = pci_msix_count(dev); - if (msgs == 0) - goto msi; - rid = PCIR_BAR(MSIX_82598_BAR); - adapter->msix_mem = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (adapter->msix_mem == NULL) { - rid += 4; /* 82599 maps in higher BAR */ - adapter->msix_mem = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE); - } - if (adapter->msix_mem == NULL) { - /* May not be enabled */ - device_printf(adapter->dev, - "Unable to map MSIX table \n"); - goto msi; - } - - /* Figure out a reasonable auto config value */ - queues = (mp_ncpus > (msgs - 1)) ? (msgs - 1) : mp_ncpus; - -#ifdef RSS - /* If we're doing RSS, clamp at the number of RSS buckets */ - if (queues > rss_getnumbuckets()) - queues = rss_getnumbuckets(); -#endif - - if (ixgbe_num_queues != 0) - queues = ixgbe_num_queues; - /* Set max queues to 8 when autoconfiguring */ - else if ((ixgbe_num_queues == 0) && (queues > 8)) - queues = 8; - - /* reflect correct sysctl value */ - ixgbe_num_queues = queues; - - /* - ** Want one vector (RX/TX pair) per queue - ** plus an additional for Link. - */ - want = queues + 1; - if (msgs >= want) - msgs = want; - else { - device_printf(adapter->dev, - "MSIX Configuration Problem, " - "%d vectors but %d queues wanted!\n", - msgs, want); - goto msi; - } - if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) { - device_printf(adapter->dev, - "Using MSIX interrupts with %d vectors\n", msgs); - adapter->num_queues = queues; - return (msgs); - } - /* - ** If MSIX alloc failed or provided us with - ** less than needed, free and fall through to MSI - */ - pci_release_msi(dev); - -msi: - if (adapter->msix_mem != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - rid, adapter->msix_mem); - adapter->msix_mem = NULL; - } - msgs = 1; - if (pci_alloc_msi(dev, &msgs) == 0) { - device_printf(adapter->dev, "Using an MSI interrupt\n"); - return (msgs); - } - device_printf(adapter->dev, "Using a Legacy interrupt\n"); - return (0); -} - - -static int -ixgbe_allocate_pci_resources(struct adapter *adapter) -{ - int rid; - device_t dev = adapter->dev; - - rid = PCIR_BAR(0); - adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, RF_ACTIVE); - - if (!(adapter->pci_mem)) { - device_printf(dev, "Unable to allocate bus resource: memory\n"); - return (ENXIO); - } - - /* Save bus_space values for READ/WRITE_REG macros */ - adapter->osdep.mem_bus_space_tag = - rman_get_bustag(adapter->pci_mem); - adapter->osdep.mem_bus_space_handle = - rman_get_bushandle(adapter->pci_mem); - /* Set hw values for shared code */ - adapter->hw.hw_addr = (u8 *) &adapter->osdep.mem_bus_space_handle; - adapter->hw.back = adapter; - - /* Default to 1 queue if MSI-X setup fails */ - adapter->num_queues = 1; - - /* - ** Now setup MSI or MSI-X, should - ** return us the number of supported - ** vectors. (Will be 1 for MSI) - */ - adapter->msix = ixgbe_setup_msix(adapter); - return (0); -} - -static void -ixgbe_free_pci_resources(struct adapter * adapter) -{ - struct ix_queue *que = adapter->queues; - device_t dev = adapter->dev; - int rid, memrid; - - if (adapter->hw.mac.type == ixgbe_mac_82598EB) - memrid = PCIR_BAR(MSIX_82598_BAR); - else - memrid = PCIR_BAR(MSIX_82599_BAR); - - /* - ** There is a slight possibility of a failure mode - ** in attach that will result in entering this function - ** before interrupt resources have been initialized, and - ** in that case we do not want to execute the loops below - ** We can detect this reliably by the state of the adapter - ** res pointer. - */ - if (adapter->res == NULL) - goto mem; - - /* - ** Release all msix queue resources: - */ - for (int i = 0; i < adapter->num_queues; i++, que++) { - rid = que->msix + 1; - if (que->tag != NULL) { - bus_teardown_intr(dev, que->res, que->tag); - que->tag = NULL; - } - if (que->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, que->res); - } - - - /* Clean the Legacy or Link interrupt last */ - if (adapter->vector) /* we are doing MSIX */ - rid = adapter->vector + 1; - else - (adapter->msix != 0) ? (rid = 1):(rid = 0); - - if (adapter->tag != NULL) { - bus_teardown_intr(dev, adapter->res, adapter->tag); - adapter->tag = NULL; - } - if (adapter->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res); - -mem: - if (adapter->msix) - pci_release_msi(dev); - - if (adapter->msix_mem != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, - memrid, adapter->msix_mem); - - if (adapter->pci_mem != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, - PCIR_BAR(0), adapter->pci_mem); - - return; -} - -/********************************************************************* - * - * Setup networking device structure and register an interface. - * - **********************************************************************/ -static int -ixgbe_setup_interface(device_t dev, struct adapter *adapter) -{ - struct ifnet *ifp; - - INIT_DEBUGOUT("ixgbe_setup_interface: begin"); - - ifp = adapter->ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "can not allocate ifnet structure\n"); - return (-1); - } - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_baudrate = IF_Gbps(10); - ifp->if_init = ixgbe_init; - ifp->if_softc = adapter; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = ixgbe_ioctl; -#if __FreeBSD_version >= 1100036 - if_setgetcounterfn(ifp, ixgbe_get_counter); -#endif -#if __FreeBSD_version >= 1100045 - /* TSO parameters */ - ifp->if_hw_tsomax = 65518; - ifp->if_hw_tsomaxsegcount = IXGBE_82599_SCATTER; - ifp->if_hw_tsomaxsegsize = 2048; -#endif -#ifndef IXGBE_LEGACY_TX - ifp->if_transmit = ixgbe_mq_start; - ifp->if_qflush = ixgbe_qflush; -#else - ifp->if_start = ixgbe_start; - IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2); - ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 2; - IFQ_SET_READY(&ifp->if_snd); -#endif - - ether_ifattach(ifp, adapter->hw.mac.addr); - - adapter->max_frame_size = - ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - - /* - * Tell the upper layer(s) we support long frames. - */ - ifp->if_hdrlen = sizeof(struct ether_vlan_header); - - /* Set capability flags */ - ifp->if_capabilities |= IFCAP_RXCSUM - | IFCAP_TXCSUM - | IFCAP_RXCSUM_IPV6 - | IFCAP_TXCSUM_IPV6 - | IFCAP_TSO4 - | IFCAP_TSO6 - | IFCAP_LRO - | IFCAP_VLAN_HWTAGGING - | IFCAP_VLAN_HWTSO - | IFCAP_VLAN_HWCSUM - | IFCAP_JUMBO_MTU - | IFCAP_VLAN_MTU - | IFCAP_HWSTATS; - - /* Enable the above capabilities by default */ - ifp->if_capenable = ifp->if_capabilities; - - /* - ** Don't turn this on by default, if vlans are - ** created on another pseudo device (eg. lagg) - ** then vlan events are not passed thru, breaking - ** operation, but with HW FILTER off it works. If - ** using vlans directly on the ixgbe driver you can - ** enable this and get full hardware tag filtering. - */ - ifp->if_capabilities |= IFCAP_VLAN_HWFILTER; - - /* - * Specify the media types supported by this adapter and register - * callbacks to update media and link information - */ - ifmedia_init(&adapter->media, IFM_IMASK, ixgbe_media_change, - ixgbe_media_status); - - adapter->phy_layer = ixgbe_get_supported_physical_layer(&adapter->hw); - ixgbe_add_media_types(adapter); - - /* Set autoselect media by default */ - ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); - - return (0); -} - -static void -ixgbe_add_media_types(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - device_t dev = adapter->dev; - int layer; - - layer = adapter->phy_layer; - - /* Media types with matching FreeBSD media defines */ - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_T, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_T) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_100BASE_TX) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX, 0, NULL); - - if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU || - layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_TWINAX, 0, NULL); - - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LR) { - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_LR, 0, NULL); - if (hw->phy.multispeed_fiber) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_LX, 0, NULL); - } - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) { - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_SR, 0, NULL); - if (hw->phy.multispeed_fiber) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, NULL); - } else if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_CX4) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_CX4, 0, NULL); - -#ifdef IFM_ETH_XTYPE - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_KR, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_KX4, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_KX, 0, NULL); -#else - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) { - device_printf(dev, "Media supported: 10GbaseKR\n"); - device_printf(dev, "10GbaseKR mapped to 10GbaseSR\n"); - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_SR, 0, NULL); - } - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) { - device_printf(dev, "Media supported: 10GbaseKX4\n"); - device_printf(dev, "10GbaseKX4 mapped to 10GbaseCX4\n"); - ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_CX4, 0, NULL); - } - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) { - device_printf(dev, "Media supported: 1000baseKX\n"); - device_printf(dev, "1000baseKX mapped to 1000baseCX\n"); - ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_CX, 0, NULL); - } -#endif - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_BX) - device_printf(dev, "Media supported: 1000baseBX\n"); - - if (hw->device_id == IXGBE_DEV_ID_82598AT) { - ifmedia_add(&adapter->media, - IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); - ifmedia_add(&adapter->media, - IFM_ETHER | IFM_1000_T, 0, NULL); - } - - ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); -} - -static void -ixgbe_config_link(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 autoneg, err = 0; - bool sfp, negotiate; - - sfp = ixgbe_is_sfp(hw); - - if (sfp) { - taskqueue_enqueue(adapter->tq, &adapter->mod_task); - } else { - if (hw->mac.ops.check_link) - err = ixgbe_check_link(hw, &adapter->link_speed, - &adapter->link_up, FALSE); - if (err) - goto out; - autoneg = hw->phy.autoneg_advertised; - if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) - err = hw->mac.ops.get_link_capabilities(hw, - &autoneg, &negotiate); - if (err) - goto out; - if (hw->mac.ops.setup_link) - err = hw->mac.ops.setup_link(hw, - autoneg, adapter->link_up); - } -out: - return; -} - - -/********************************************************************* - * - * Enable transmit units. - * - **********************************************************************/ -static void -ixgbe_initialize_transmit_units(struct adapter *adapter) -{ - struct tx_ring *txr = adapter->tx_rings; - struct ixgbe_hw *hw = &adapter->hw; - - /* Setup the Base and Length of the Tx Descriptor Ring */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - u64 tdba = txr->txdma.dma_paddr; - u32 txctrl = 0; - int j = txr->me; - - IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j), - (tdba & 0x00000000ffffffffULL)); - IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), - adapter->num_tx_desc * sizeof(union ixgbe_adv_tx_desc)); - - /* Setup the HW Tx Head and Tail descriptor pointers */ - IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0); - IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0); - - /* Cache the tail address */ - txr->tail = IXGBE_TDT(j); - - /* Disable Head Writeback */ - /* - * Note: for X550 series devices, these registers are actually - * prefixed with TPH_ isntead of DCA_, but the addresses and - * fields remain the same. - */ - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j)); - break; - default: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j)); - break; - } - txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl); - break; - default: - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl); - break; - } - - } - - if (hw->mac.type != ixgbe_mac_82598EB) { - u32 dmatxctl, rttdcs; -#ifdef PCI_IOV - enum ixgbe_iov_mode mode = ixgbe_get_iov_mode(adapter); -#endif - dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); - dmatxctl |= IXGBE_DMATXCTL_TE; - IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); - /* Disable arbiter to set MTQC */ - rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); - rttdcs |= IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); -#ifdef PCI_IOV - IXGBE_WRITE_REG(hw, IXGBE_MTQC, ixgbe_get_mtqc(mode)); -#else - IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); -#endif - rttdcs &= ~IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); - } - - return; -} - -static void -ixgbe_initialize_rss_mapping(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 reta = 0, mrqc, rss_key[10]; - int queue_id, table_size, index_mult; -#ifdef RSS - u32 rss_hash_config; -#endif -#ifdef PCI_IOV - enum ixgbe_iov_mode mode; -#endif - -#ifdef RSS - /* Fetch the configured RSS key */ - rss_getkey((uint8_t *) &rss_key); -#else - /* set up random bits */ - arc4rand(&rss_key, sizeof(rss_key), 0); -#endif - - /* Set multiplier for RETA setup and table size based on MAC */ - index_mult = 0x1; - table_size = 128; switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - index_mult = 0x11; + case ixgbe_mac_82599EB: + mask |= IXGBE_EIMS_ECC; + /* Temperature sensor on some adapters */ + mask |= IXGBE_EIMS_GPI_SDP0; + /* SFP+ (RX_LOS_N & MOD_ABS_N) */ + mask |= IXGBE_EIMS_GPI_SDP1; + mask |= IXGBE_EIMS_GPI_SDP2; + break; + case ixgbe_mac_X540: + /* Detect if Thermal Sensor is enabled */ + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM); + if (fwsm & IXGBE_FWSM_TS_ENABLED) + mask |= IXGBE_EIMS_TS; + mask |= IXGBE_EIMS_ECC; break; case ixgbe_mac_X550: + /* MAC thermal sensor is automatically enabled */ + mask |= IXGBE_EIMS_TS; + mask |= IXGBE_EIMS_ECC; + break; case ixgbe_mac_X550EM_x: - table_size = 512; + case ixgbe_mac_X550EM_a: + /* Some devices use SDP0 for important information */ + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP || + hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP || + hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N || + hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) + mask |= IXGBE_EIMS_GPI_SDP0_BY_MAC(hw); + if (hw->phy.type == ixgbe_phy_x550em_ext_t) + mask |= IXGBE_EICR_GPI_SDP0_X540; + mask |= IXGBE_EIMS_ECC; break; default: break; } - /* Set up the redirection table */ - for (int i = 0, j = 0; i < table_size; i++, j++) { - if (j == adapter->num_queues) j = 0; -#ifdef RSS - /* - * Fetch the RSS bucket id for the given indirection entry. - * Cap it at the number of configured buckets (which is - * num_queues.) - */ - queue_id = rss_get_indirection_to_bucket(i); - queue_id = queue_id % adapter->num_queues; -#else - queue_id = (j * index_mult); -#endif - /* - * The low 8 bits are for hash value (n+0); - * The next 8 bits are for hash value (n+1), etc. - */ - reta = reta >> 8; - reta = reta | ( ((uint32_t) queue_id) << 24); - if ((i & 3) == 3) { - if (i < 128) - IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); - else - IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32), reta); - reta = 0; - } - } - - /* Now fill our hash function seeds */ - for (int i = 0; i < 10; i++) - IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), rss_key[i]); - - /* Perform hash on these packet types */ -#ifdef RSS - mrqc = IXGBE_MRQC_RSSEN; - rss_hash_config = rss_gethashconfig(); - if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4; - if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP; - if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6; - if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP; - if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX; - if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP; - if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; - if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4_EX) - device_printf(adapter->dev, - "%s: RSS_HASHTYPE_RSS_UDP_IPV4_EX defined, " - "but not supported\n", __func__); - if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; - if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP; -#else - /* - * Disable UDP - IP fragments aren't currently being handled - * and so we end up with a mix of 2-tuple and 4-tuple - * traffic. - */ - mrqc = IXGBE_MRQC_RSSEN - | IXGBE_MRQC_RSS_FIELD_IPV4 - | IXGBE_MRQC_RSS_FIELD_IPV4_TCP - | IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP - | IXGBE_MRQC_RSS_FIELD_IPV6_EX - | IXGBE_MRQC_RSS_FIELD_IPV6 - | IXGBE_MRQC_RSS_FIELD_IPV6_TCP - ; -#endif /* RSS */ -#ifdef PCI_IOV - mode = ixgbe_get_iov_mode(adapter); - mrqc |= ixgbe_get_mrqc(mode); -#endif - IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); -} - - -/********************************************************************* - * - * Setup receive registers and features. - * - **********************************************************************/ -#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 - -#define BSIZEPKT_ROUNDUP ((1<rx_rings; - struct ixgbe_hw *hw = &adapter->hw; - struct ifnet *ifp = adapter->ifp; - u32 bufsz, fctrl, srrctl, rxcsum; - u32 hlreg; - - /* - * Make sure receives are disabled while - * setting up the descriptor ring - */ - ixgbe_disable_rx(hw); - - /* Enable broadcasts */ - fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); - fctrl |= IXGBE_FCTRL_BAM; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - fctrl |= IXGBE_FCTRL_DPF; - fctrl |= IXGBE_FCTRL_PMCF; - } - IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); - - /* Set for Jumbo Frames? */ - hlreg = IXGBE_READ_REG(hw, IXGBE_HLREG0); - if (ifp->if_mtu > ETHERMTU) - hlreg |= IXGBE_HLREG0_JUMBOEN; - else - hlreg &= ~IXGBE_HLREG0_JUMBOEN; -#ifdef DEV_NETMAP - /* crcstrip is conditional in netmap (in RDRXCTL too ?) */ - if (ifp->if_capenable & IFCAP_NETMAP && !ix_crcstrip) - hlreg &= ~IXGBE_HLREG0_RXCRCSTRP; - else - hlreg |= IXGBE_HLREG0_RXCRCSTRP; -#endif /* DEV_NETMAP */ - IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg); - - bufsz = (adapter->rx_mbuf_sz + - BSIZEPKT_ROUNDUP) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; - - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - u64 rdba = rxr->rxdma.dma_paddr; - int j = rxr->me; - - /* Setup the Base and Length of the Rx Descriptor Ring */ - IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), - (rdba & 0x00000000ffffffffULL)); - IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), - adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc)); - - /* Set up the SRRCTL register */ - srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(j)); - srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; - srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; - srrctl |= bufsz; - srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; - - /* - * Set DROP_EN iff we have no flow control and >1 queue. - * Note that srrctl was cleared shortly before during reset, - * so we do not need to clear the bit, but do it just in case - * this code is moved elsewhere. - */ - if (adapter->num_queues > 1 && - adapter->hw.fc.requested_mode == ixgbe_fc_none) { - srrctl |= IXGBE_SRRCTL_DROP_EN; - } else { - srrctl &= ~IXGBE_SRRCTL_DROP_EN; - } - - IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(j), srrctl); - - /* Setup the HW Rx Head and Tail Descriptor Pointers */ - IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0); - IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0); - - /* Set the driver rx tail address */ - rxr->tail = IXGBE_RDT(rxr->me); - } - - if (adapter->hw.mac.type != ixgbe_mac_82598EB) { - u32 psrtype = IXGBE_PSRTYPE_TCPHDR | - IXGBE_PSRTYPE_UDPHDR | - IXGBE_PSRTYPE_IPV4HDR | - IXGBE_PSRTYPE_IPV6HDR; - IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype); - } - - rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); - - ixgbe_initialize_rss_mapping(adapter); - - if (adapter->num_queues > 1) { - /* RSS and RX IPP Checksum are mutually exclusive */ - rxcsum |= IXGBE_RXCSUM_PCSD; - } - - if (ifp->if_capenable & IFCAP_RXCSUM) - rxcsum |= IXGBE_RXCSUM_PCSD; - - /* This is useful for calculating UDP/IP fragment checksums */ - if (!(rxcsum & IXGBE_RXCSUM_PCSD)) - rxcsum |= IXGBE_RXCSUM_IPPCSE; - - IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); - - return; -} - - -/* -** This routine is run via an vlan config EVENT, -** it enables us to use the HW Filter table since -** we can get the vlan id. This just creates the -** entry in the soft version of the VFTA, init will -** repopulate the real table. -*/ -static void -ixgbe_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) -{ - struct adapter *adapter = ifp->if_softc; - u16 index, bit; - - if (ifp->if_softc != arg) /* Not our event */ - return; - - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ - return; - - IXGBE_CORE_LOCK(adapter); - index = (vtag >> 5) & 0x7F; - bit = vtag & 0x1F; - adapter->shadow_vfta[index] |= (1 << bit); - ++adapter->num_vlans; - ixgbe_setup_vlan_hw_support(adapter); - IXGBE_CORE_UNLOCK(adapter); -} - -/* -** This routine is run via an vlan -** unconfig EVENT, remove our entry -** in the soft vfta. -*/ -static void -ixgbe_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) -{ - struct adapter *adapter = ifp->if_softc; - u16 index, bit; - - if (ifp->if_softc != arg) - return; - - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ - return; - - IXGBE_CORE_LOCK(adapter); - index = (vtag >> 5) & 0x7F; - bit = vtag & 0x1F; - adapter->shadow_vfta[index] &= ~(1 << bit); - --adapter->num_vlans; - /* Re-init to load the changes */ - ixgbe_setup_vlan_hw_support(adapter); - IXGBE_CORE_UNLOCK(adapter); -} - -static void -ixgbe_setup_vlan_hw_support(struct adapter *adapter) -{ - struct ifnet *ifp = adapter->ifp; - struct ixgbe_hw *hw = &adapter->hw; - struct rx_ring *rxr; - u32 ctrl; - - - /* - ** We get here thru init_locked, meaning - ** a soft reset, this has already cleared - ** the VFTA and other state, so if there - ** have been no vlan's registered do nothing. - */ - if (adapter->num_vlans == 0) - return; - - /* Setup the queues for vlans */ - for (int i = 0; i < adapter->num_queues; i++) { - rxr = &adapter->rx_rings[i]; - /* On 82599 the VLAN enable is per/queue in RXDCTL */ - if (hw->mac.type != ixgbe_mac_82598EB) { - ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)); - ctrl |= IXGBE_RXDCTL_VME; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), ctrl); - } - rxr->vtag_strip = TRUE; - } - - if ((ifp->if_capenable & IFCAP_VLAN_HWFILTER) == 0) - return; - /* - ** A soft reset zero's out the VFTA, so - ** we need to repopulate it now. - */ - for (int i = 0; i < IXGBE_VFTA_SIZE; i++) - if (adapter->shadow_vfta[i] != 0) - IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), - adapter->shadow_vfta[i]); - - ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); - /* Enable the Filter Table if enabled */ - if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) { - ctrl &= ~IXGBE_VLNCTRL_CFIEN; - ctrl |= IXGBE_VLNCTRL_VFE; - } - if (hw->mac.type == ixgbe_mac_82598EB) - ctrl |= IXGBE_VLNCTRL_VME; - IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl); -} - -static void -ixgbe_enable_intr(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct ix_queue *que = adapter->queues; - u32 mask, fwsm; - - mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); /* Enable Fan Failure detection */ - if (hw->device_id == IXGBE_DEV_ID_82598AT) - mask |= IXGBE_EIMS_GPI_SDP1; - - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - mask |= IXGBE_EIMS_ECC; - /* Temperature sensor on some adapters */ - mask |= IXGBE_EIMS_GPI_SDP0; - /* SFP+ (RX_LOS_N & MOD_ABS_N) */ - mask |= IXGBE_EIMS_GPI_SDP1; - mask |= IXGBE_EIMS_GPI_SDP2; -#ifdef IXGBE_FDIR - mask |= IXGBE_EIMS_FLOW_DIR; -#endif -#ifdef PCI_IOV - mask |= IXGBE_EIMS_MAILBOX; -#endif - break; - case ixgbe_mac_X540: - /* Detect if Thermal Sensor is enabled */ - fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM); - if (fwsm & IXGBE_FWSM_TS_ENABLED) - mask |= IXGBE_EIMS_TS; - mask |= IXGBE_EIMS_ECC; -#ifdef IXGBE_FDIR - mask |= IXGBE_EIMS_FLOW_DIR; -#endif - break; - case ixgbe_mac_X550: - case ixgbe_mac_X550EM_x: - /* MAC thermal sensor is automatically enabled */ - mask |= IXGBE_EIMS_TS; - /* Some devices use SDP0 for important information */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP || - hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) - mask |= IXGBE_EIMS_GPI_SDP0_BY_MAC(hw); - mask |= IXGBE_EIMS_ECC; -#ifdef IXGBE_FDIR - mask |= IXGBE_EIMS_FLOW_DIR; -#endif -#ifdef PCI_IOV - mask |= IXGBE_EIMS_MAILBOX; -#endif - /* falls through */ - default: - break; - } + if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) + mask |= IXGBE_EIMS_GPI_SDP1; + /* Enable SR-IOV */ + if (adapter->feat_en & IXGBE_FEATURE_SRIOV) + mask |= IXGBE_EIMS_MAILBOX; + /* Enable Flow Director */ + if (adapter->feat_en & IXGBE_FEATURE_FDIR) + mask |= IXGBE_EIMS_FLOW_DIR; IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); @@ -3498,25 +3724,27 @@ ixgbe_enable_intr(struct adapter *adapter) /* Don't autoclear Link */ mask &= ~IXGBE_EIMS_OTHER; mask &= ~IXGBE_EIMS_LSC; -#ifdef PCI_IOV - mask &= ~IXGBE_EIMS_MAILBOX; -#endif + if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) + mask &= ~IXGBE_EIMS_MAILBOX; IXGBE_WRITE_REG(hw, IXGBE_EIAC, mask); } /* - ** Now enable all queues, this is done separately to - ** allow for handling the extended (beyond 32) MSIX - ** vectors that can be used by 82599 - */ - for (int i = 0; i < adapter->num_queues; i++, que++) - ixgbe_enable_queue(adapter, que->msix); + * Now enable all queues, this is done separately to + * allow for handling the extended (beyond 32) MSI-X + * vectors that can be used by 82599 + */ + for (int i = 0; i < adapter->num_queues; i++, que++) + ixgbe_enable_queue(adapter, que->msix); IXGBE_WRITE_FLUSH(hw); return; -} +} /* ixgbe_enable_intr */ +/************************************************************************ + * ixgbe_disable_intr + ************************************************************************/ static void ixgbe_disable_intr(struct adapter *adapter) { @@ -3530,1141 +3758,157 @@ ixgbe_disable_intr(struct adapter *adapter) IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); } IXGBE_WRITE_FLUSH(&adapter->hw); - return; -} - -/* -** Get the width and transaction speed of -** the slot this adapter is plugged into. -*/ -static void -ixgbe_get_slot_info(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_mac_info *mac = &hw->mac; - u16 link; - u32 offset; - - /* For most devices simply call the shared code routine */ - if (hw->device_id != IXGBE_DEV_ID_82599_SFP_SF_QP) { - ixgbe_get_bus_info(hw); - /* These devices don't use PCI-E */ - switch (hw->mac.type) { - case ixgbe_mac_X550EM_x: - return; - default: - goto display; - } - } - - /* - ** For the Quad port adapter we need to parse back - ** up the PCI tree to find the speed of the expansion - ** slot into which this adapter is plugged. A bit more work. - */ - dev = device_get_parent(device_get_parent(dev)); -#ifdef IXGBE_DEBUG - device_printf(dev, "parent pcib = %x,%x,%x\n", - pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev)); -#endif - dev = device_get_parent(device_get_parent(dev)); -#ifdef IXGBE_DEBUG - device_printf(dev, "slot pcib = %x,%x,%x\n", - pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev)); -#endif - /* Now get the PCI Express Capabilities offset */ - pci_find_cap(dev, PCIY_EXPRESS, &offset); - /* ...and read the Link Status Register */ - link = pci_read_config(dev, offset + PCIER_LINK_STA, 2); - switch (link & IXGBE_PCI_LINK_WIDTH) { - case IXGBE_PCI_LINK_WIDTH_1: - hw->bus.width = ixgbe_bus_width_pcie_x1; - break; - case IXGBE_PCI_LINK_WIDTH_2: - hw->bus.width = ixgbe_bus_width_pcie_x2; - break; - case IXGBE_PCI_LINK_WIDTH_4: - hw->bus.width = ixgbe_bus_width_pcie_x4; - break; - case IXGBE_PCI_LINK_WIDTH_8: - hw->bus.width = ixgbe_bus_width_pcie_x8; - break; - default: - hw->bus.width = ixgbe_bus_width_unknown; - break; - } - - switch (link & IXGBE_PCI_LINK_SPEED) { - case IXGBE_PCI_LINK_SPEED_2500: - hw->bus.speed = ixgbe_bus_speed_2500; - break; - case IXGBE_PCI_LINK_SPEED_5000: - hw->bus.speed = ixgbe_bus_speed_5000; - break; - case IXGBE_PCI_LINK_SPEED_8000: - hw->bus.speed = ixgbe_bus_speed_8000; - break; - default: - hw->bus.speed = ixgbe_bus_speed_unknown; - break; - } - - mac->ops.set_lan_id(hw); - -display: - device_printf(dev,"PCI Express Bus: Speed %s %s\n", - ((hw->bus.speed == ixgbe_bus_speed_8000) ? "8.0GT/s": - (hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0GT/s": - (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5GT/s":"Unknown"), - (hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" : - (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" : - (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" : - ("Unknown")); - - if ((hw->device_id != IXGBE_DEV_ID_82599_SFP_SF_QP) && - ((hw->bus.width <= ixgbe_bus_width_pcie_x4) && - (hw->bus.speed == ixgbe_bus_speed_2500))) { - device_printf(dev, "PCI-Express bandwidth available" - " for this card\n is not sufficient for" - " optimal performance.\n"); - device_printf(dev, "For optimal performance a x8 " - "PCIE, or x4 PCIE Gen2 slot is required.\n"); - } - if ((hw->device_id == IXGBE_DEV_ID_82599_SFP_SF_QP) && - ((hw->bus.width <= ixgbe_bus_width_pcie_x8) && - (hw->bus.speed < ixgbe_bus_speed_8000))) { - device_printf(dev, "PCI-Express bandwidth available" - " for this card\n is not sufficient for" - " optimal performance.\n"); - device_printf(dev, "For optimal performance a x8 " - "PCIE Gen3 slot is required.\n"); - } return; -} +} /* ixgbe_disable_intr */ - -/* -** Setup the correct IVAR register for a particular MSIX interrupt -** (yes this is all very magic and confusing :) -** - entry is the register array entry -** - vector is the MSIX vector for this queue -** - type is RX/TX/MISC -*/ +/************************************************************************ + * ixgbe_legacy_irq - Legacy Interrupt Service routine + ************************************************************************/ static void -ixgbe_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type) +ixgbe_legacy_irq(void *arg) { + struct ix_queue *que = arg; + struct adapter *adapter = que->adapter; struct ixgbe_hw *hw = &adapter->hw; - u32 ivar, index; + struct ifnet *ifp = adapter->ifp; + struct tx_ring *txr = adapter->tx_rings; + bool more = false; + u32 eicr, eicr_mask; - vector |= IXGBE_IVAR_ALLOC_VAL; + /* Silicon errata #26 on 82598 */ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); - switch (hw->mac.type) { + eicr = IXGBE_READ_REG(hw, IXGBE_EICR); - case ixgbe_mac_82598EB: - if (type == -1) - entry = IXGBE_IVAR_OTHER_CAUSES_INDEX; + ++que->irqs; + if (eicr == 0) { + ixgbe_enable_intr(adapter); + return; + } + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + more = ixgbe_rxeof(que); + + IXGBE_TX_LOCK(txr); + ixgbe_txeof(txr); + if (!ixgbe_ring_empty(ifp, txr->br)) + ixgbe_start_locked(ifp, txr); + IXGBE_TX_UNLOCK(txr); + } + + /* Check for fan failure */ + if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) { + ixgbe_check_fan_failure(adapter, eicr, true); + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); + } + + /* Link status change */ + if (eicr & IXGBE_EICR_LSC) + taskqueue_enqueue(adapter->tq, &adapter->link_task); + + if (ixgbe_is_sfp(hw)) { + /* Pluggable optics-related interrupt */ + if (hw->mac.type >= ixgbe_mac_X540) + eicr_mask = IXGBE_EICR_GPI_SDP0_X540; else - entry += (type * 64); - index = (entry >> 2) & 0x1F; - ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index)); - ivar &= ~(0xFF << (8 * (entry & 0x3))); - ivar |= (vector << (8 * (entry & 0x3))); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR(index), ivar); - break; + eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - case ixgbe_mac_X550: - case ixgbe_mac_X550EM_x: - if (type == -1) { /* MISC IVAR */ - index = (entry & 1) * 8; - ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC); - ivar &= ~(0xFF << index); - ivar |= (vector << index); - IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, ivar); - } else { /* RX/TX IVARS */ - index = (16 * (entry & 1)) + (8 * type); - ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(entry >> 1)); - ivar &= ~(0xFF << index); - ivar |= (vector << index); - IXGBE_WRITE_REG(hw, IXGBE_IVAR(entry >> 1), ivar); + if (eicr & eicr_mask) { + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); + taskqueue_enqueue(adapter->tq, &adapter->mod_task); } - default: - break; - } -} - -static void -ixgbe_configure_ivars(struct adapter *adapter) -{ - struct ix_queue *que = adapter->queues; - u32 newitr; - - if (ixgbe_max_interrupt_rate > 0) - newitr = (4000000 / ixgbe_max_interrupt_rate) & 0x0FF8; - else { - /* - ** Disable DMA coalescing if interrupt moderation is - ** disabled. - */ - adapter->dmac = 0; - newitr = 0; - } - - for (int i = 0; i < adapter->num_queues; i++, que++) { - struct rx_ring *rxr = &adapter->rx_rings[i]; - struct tx_ring *txr = &adapter->tx_rings[i]; - /* First the RX queue entry */ - ixgbe_set_ivar(adapter, rxr->me, que->msix, 0); - /* ... and the TX */ - ixgbe_set_ivar(adapter, txr->me, que->msix, 1); - /* Set an Initial EITR value */ - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(que->msix), newitr); - } - - /* For the Link interrupt */ - ixgbe_set_ivar(adapter, 1, adapter->vector, -1); -} - -/* -** ixgbe_sfp_probe - called in the local timer to -** determine if a port had optics inserted. -*/ -static bool -ixgbe_sfp_probe(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - device_t dev = adapter->dev; - bool result = FALSE; - - if ((hw->phy.type == ixgbe_phy_nl) && - (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) { - s32 ret = hw->phy.ops.identify_sfp(hw); - if (ret) - goto out; - ret = hw->phy.ops.reset(hw); - if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev, "Unsupported SFP+ module detected!"); - device_printf(dev, "Reload driver with supported module.\n"); - adapter->sfp_probe = FALSE; - goto out; - } else - device_printf(dev, "SFP+ module detected!\n"); - /* We now have supported optics */ - adapter->sfp_probe = FALSE; - /* Set the optics type so system reports correctly */ - ixgbe_setup_optics(adapter); - result = TRUE; - } -out: - return (result); -} - -/* -** Tasklet handler for MSIX Link interrupts -** - do outside interrupt since it might sleep -*/ -static void -ixgbe_handle_link(void *context, int pending) -{ - struct adapter *adapter = context; - struct ixgbe_hw *hw = &adapter->hw; - - ixgbe_check_link(hw, - &adapter->link_speed, &adapter->link_up, 0); - ixgbe_update_link_status(adapter); - - /* Re-enable link interrupts */ - IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_LSC); -} - -/* -** Tasklet for handling SFP module interrupts -*/ -static void -ixgbe_handle_mod(void *context, int pending) -{ - struct adapter *adapter = context; - struct ixgbe_hw *hw = &adapter->hw; - enum ixgbe_phy_type orig_type = hw->phy.type; - device_t dev = adapter->dev; - u32 err; - - IXGBE_CORE_LOCK(adapter); - - /* Check to see if the PHY type changed */ - if (hw->phy.ops.identify) { - hw->phy.type = ixgbe_phy_unknown; - hw->phy.ops.identify(hw); - } - - if (hw->phy.type != orig_type) { - device_printf(dev, "Detected phy_type %d\n", hw->phy.type); - - if (hw->phy.type == ixgbe_phy_none) { - hw->phy.sfp_type = ixgbe_sfp_type_unknown; - goto out; + if ((hw->mac.type == ixgbe_mac_82599EB) && + (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { + IXGBE_WRITE_REG(hw, IXGBE_EICR, + IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); + taskqueue_enqueue(adapter->tq, &adapter->msf_task); } - - /* Try to do the initialization that was skipped before */ - if (hw->phy.ops.init) - hw->phy.ops.init(hw); - if (hw->phy.ops.reset) - hw->phy.ops.reset(hw); } - err = hw->phy.ops.identify_sfp(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev, - "Unsupported SFP+ module type was detected.\n"); - goto out; - } + /* External PHY interrupt */ + if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && + (eicr & IXGBE_EICR_GPI_SDP0_X540)) + taskqueue_enqueue(adapter->tq, &adapter->phy_task); - err = hw->mac.ops.setup_sfp(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev, - "Setup failure - unsupported SFP+ module type.\n"); - goto out; - } - if (hw->phy.multispeed_fiber) - taskqueue_enqueue(adapter->tq, &adapter->msf_task); -out: - /* Update media type */ - switch (hw->mac.ops.get_media_type(hw)) { - case ixgbe_media_type_fiber: - adapter->optics = IFM_10G_SR; - break; - case ixgbe_media_type_copper: - adapter->optics = IFM_10G_TWINAX; - break; - case ixgbe_media_type_cx4: - adapter->optics = IFM_10G_CX4; - break; - default: - adapter->optics = 0; - break; - } - - IXGBE_CORE_UNLOCK(adapter); - return; -} - - -/* -** Tasklet for handling MSF (multispeed fiber) interrupts -*/ -static void -ixgbe_handle_msf(void *context, int pending) -{ - struct adapter *adapter = context; - struct ixgbe_hw *hw = &adapter->hw; - u32 autoneg; - bool negotiate; - - IXGBE_CORE_LOCK(adapter); - /* get_supported_phy_layer will call hw->phy.ops.identify_sfp() */ - adapter->phy_layer = ixgbe_get_supported_physical_layer(hw); - - autoneg = hw->phy.autoneg_advertised; - if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) - hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate); - if (hw->mac.ops.setup_link) - hw->mac.ops.setup_link(hw, autoneg, TRUE); - - /* Adjust media types shown in ifconfig */ - ifmedia_removeall(&adapter->media); - ixgbe_add_media_types(adapter); - ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); - IXGBE_CORE_UNLOCK(adapter); - return; -} - -/* -** Tasklet for handling interrupts from an external PHY -*/ -static void -ixgbe_handle_phy(void *context, int pending) -{ - struct adapter *adapter = context; - struct ixgbe_hw *hw = &adapter->hw; - int error; - - error = hw->phy.ops.handle_lasi(hw); - if (error == IXGBE_ERR_OVERTEMP) - device_printf(adapter->dev, - "CRITICAL: EXTERNAL PHY OVER TEMP!! " - " PHY will downshift to lower power state!\n"); - else if (error) - device_printf(adapter->dev, - "Error handling LASI interrupt: %d\n", - error); - return; -} - -#ifdef IXGBE_FDIR -/* -** Tasklet for reinitializing the Flow Director filter table -*/ -static void -ixgbe_reinit_fdir(void *context, int pending) -{ - struct adapter *adapter = context; - struct ifnet *ifp = adapter->ifp; - - if (adapter->fdir_reinit != 1) /* Shouldn't happen */ - return; - ixgbe_reinit_fdir_tables_82599(&adapter->hw); - adapter->fdir_reinit = 0; - /* re-enable flow director interrupts */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR); - /* Restart the interface */ - ifp->if_drv_flags |= IFF_DRV_RUNNING; - return; -} -#endif - -/********************************************************************* - * - * Configure DMA Coalescing - * - **********************************************************************/ -static void -ixgbe_config_dmac(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_dmac_config *dcfg = &hw->mac.dmac_config; - - if (hw->mac.type < ixgbe_mac_X550 || - !hw->mac.ops.dmac_config) - return; - - if (dcfg->watchdog_timer ^ adapter->dmac || - dcfg->link_speed ^ adapter->link_speed) { - dcfg->watchdog_timer = adapter->dmac; - dcfg->fcoe_en = false; - dcfg->link_speed = adapter->link_speed; - dcfg->num_tcs = 1; - - INIT_DEBUGOUT2("dmac settings: watchdog %d, link speed %d\n", - dcfg->watchdog_timer, dcfg->link_speed); - - hw->mac.ops.dmac_config(hw); - } -} - -/* - * Checks whether the adapter's ports are capable of - * Wake On LAN by reading the adapter's NVM. - * - * Sets each port's hw->wol_enabled value depending - * on the value read here. - */ -static void -ixgbe_check_wol_support(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u16 dev_caps = 0; - - /* Find out WoL support for port */ - adapter->wol_support = hw->wol_enabled = 0; - ixgbe_get_device_caps(hw, &dev_caps); - if ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0_1) || - ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0) && - hw->bus.func == 0)) - adapter->wol_support = hw->wol_enabled = 1; - - /* Save initial wake up filter configuration */ - adapter->wufc = IXGBE_READ_REG(hw, IXGBE_WUFC); + if (more) + taskqueue_enqueue(que->tq, &que->que_task); + else + ixgbe_enable_intr(adapter); return; -} +} /* ixgbe_legacy_irq */ -/* - * Prepare the adapter/port for LPLU and/or WoL - */ -static int -ixgbe_setup_low_power_mode(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - device_t dev = adapter->dev; - s32 error = 0; - - mtx_assert(&adapter->core_mtx, MA_OWNED); - - if (!hw->wol_enabled) - ixgbe_set_phy_power(hw, FALSE); - - /* Limit power management flow to X550EM baseT */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T - && hw->phy.ops.enter_lplu) { - /* Turn off support for APM wakeup. (Using ACPI instead) */ - IXGBE_WRITE_REG(hw, IXGBE_GRC, - IXGBE_READ_REG(hw, IXGBE_GRC) & ~(u32)2); - - /* - * Clear Wake Up Status register to prevent any previous wakeup - * events from waking us up immediately after we suspend. - */ - IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff); - - /* - * Program the Wakeup Filter Control register with user filter - * settings - */ - IXGBE_WRITE_REG(hw, IXGBE_WUFC, adapter->wufc); - - /* Enable wakeups and power management in Wakeup Control */ - IXGBE_WRITE_REG(hw, IXGBE_WUC, - IXGBE_WUC_WKEN | IXGBE_WUC_PME_EN); - - /* X550EM baseT adapters need a special LPLU flow */ - hw->phy.reset_disable = true; - ixgbe_stop(adapter); - error = hw->phy.ops.enter_lplu(hw); - if (error) - device_printf(dev, - "Error entering LPLU: %d\n", error); - hw->phy.reset_disable = false; - } else { - /* Just stop for other adapters */ - ixgbe_stop(adapter); - } - - return error; -} - -/********************************************************************** - * - * Update the board statistics counters. - * - **********************************************************************/ +/************************************************************************ + * ixgbe_free_pci_resources + ************************************************************************/ static void -ixgbe_update_stats_counters(struct adapter *adapter) +ixgbe_free_pci_resources(struct adapter *adapter) { - struct ixgbe_hw *hw = &adapter->hw; - u32 missed_rx = 0, bprc, lxon, lxoff, total; - u64 total_missed_rx = 0; + struct ix_queue *que = adapter->queues; + device_t dev = adapter->dev; + int rid, memrid; - adapter->stats.pf.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); - adapter->stats.pf.illerrc += IXGBE_READ_REG(hw, IXGBE_ILLERRC); - adapter->stats.pf.errbc += IXGBE_READ_REG(hw, IXGBE_ERRBC); - adapter->stats.pf.mspdc += IXGBE_READ_REG(hw, IXGBE_MSPDC); - - for (int i = 0; i < 16; i++) { - adapter->stats.pf.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); - adapter->stats.pf.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); - adapter->stats.pf.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); - } - adapter->stats.pf.mlfc += IXGBE_READ_REG(hw, IXGBE_MLFC); - adapter->stats.pf.mrfc += IXGBE_READ_REG(hw, IXGBE_MRFC); - adapter->stats.pf.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); - - /* Hardware workaround, gprc counts missed packets */ - adapter->stats.pf.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); - adapter->stats.pf.gprc -= missed_rx; - - if (hw->mac.type != ixgbe_mac_82598EB) { - adapter->stats.pf.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL) + - ((u64)IXGBE_READ_REG(hw, IXGBE_GORCH) << 32); - adapter->stats.pf.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL) + - ((u64)IXGBE_READ_REG(hw, IXGBE_GOTCH) << 32); - adapter->stats.pf.tor += IXGBE_READ_REG(hw, IXGBE_TORL) + - ((u64)IXGBE_READ_REG(hw, IXGBE_TORH) << 32); - adapter->stats.pf.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); - adapter->stats.pf.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - } else { - adapter->stats.pf.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); - adapter->stats.pf.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); - /* 82598 only has a counter in the high register */ - adapter->stats.pf.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); - adapter->stats.pf.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); - adapter->stats.pf.tor += IXGBE_READ_REG(hw, IXGBE_TORH); - } + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + memrid = PCIR_BAR(MSIX_82598_BAR); + else + memrid = PCIR_BAR(MSIX_82599_BAR); /* - * Workaround: mprc hardware is incorrectly counting - * broadcasts, so for now we subtract those. + * There is a slight possibility of a failure mode + * in attach that will result in entering this function + * before interrupt resources have been initialized, and + * in that case we do not want to execute the loops below + * We can detect this reliably by the state of the adapter + * res pointer. */ - bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); - adapter->stats.pf.bprc += bprc; - adapter->stats.pf.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); - if (hw->mac.type == ixgbe_mac_82598EB) - adapter->stats.pf.mprc -= bprc; + if (adapter->res == NULL) + goto mem; - adapter->stats.pf.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); - adapter->stats.pf.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); - adapter->stats.pf.prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255); - adapter->stats.pf.prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511); - adapter->stats.pf.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023); - adapter->stats.pf.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); - - lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC); - adapter->stats.pf.lxontxc += lxon; - lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); - adapter->stats.pf.lxofftxc += lxoff; - total = lxon + lxoff; - - adapter->stats.pf.gptc += IXGBE_READ_REG(hw, IXGBE_GPTC); - adapter->stats.pf.mptc += IXGBE_READ_REG(hw, IXGBE_MPTC); - adapter->stats.pf.ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64); - adapter->stats.pf.gptc -= total; - adapter->stats.pf.mptc -= total; - adapter->stats.pf.ptc64 -= total; - adapter->stats.pf.gotc -= total * ETHER_MIN_LEN; - - adapter->stats.pf.ruc += IXGBE_READ_REG(hw, IXGBE_RUC); - adapter->stats.pf.rfc += IXGBE_READ_REG(hw, IXGBE_RFC); - adapter->stats.pf.roc += IXGBE_READ_REG(hw, IXGBE_ROC); - adapter->stats.pf.rjc += IXGBE_READ_REG(hw, IXGBE_RJC); - adapter->stats.pf.mngprc += IXGBE_READ_REG(hw, IXGBE_MNGPRC); - adapter->stats.pf.mngpdc += IXGBE_READ_REG(hw, IXGBE_MNGPDC); - adapter->stats.pf.mngptc += IXGBE_READ_REG(hw, IXGBE_MNGPTC); - adapter->stats.pf.tpr += IXGBE_READ_REG(hw, IXGBE_TPR); - adapter->stats.pf.tpt += IXGBE_READ_REG(hw, IXGBE_TPT); - adapter->stats.pf.ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127); - adapter->stats.pf.ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255); - adapter->stats.pf.ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511); - adapter->stats.pf.ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023); - adapter->stats.pf.ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522); - adapter->stats.pf.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC); - adapter->stats.pf.xec += IXGBE_READ_REG(hw, IXGBE_XEC); - adapter->stats.pf.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); - adapter->stats.pf.fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST); - /* Only read FCOE on 82599 */ - if (hw->mac.type != ixgbe_mac_82598EB) { - adapter->stats.pf.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); - adapter->stats.pf.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); - adapter->stats.pf.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); - adapter->stats.pf.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); - adapter->stats.pf.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); + /* + * Release all msix queue resources: + */ + for (int i = 0; i < adapter->num_queues; i++, que++) { + rid = que->msix + 1; + if (que->tag != NULL) { + bus_teardown_intr(dev, que->res, que->tag); + que->tag = NULL; + } + if (que->res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, rid, que->res); } - /* Fill out the OS statistics structure */ - IXGBE_SET_IPACKETS(adapter, adapter->stats.pf.gprc); - IXGBE_SET_OPACKETS(adapter, adapter->stats.pf.gptc); - IXGBE_SET_IBYTES(adapter, adapter->stats.pf.gorc); - IXGBE_SET_OBYTES(adapter, adapter->stats.pf.gotc); - IXGBE_SET_IMCASTS(adapter, adapter->stats.pf.mprc); - IXGBE_SET_OMCASTS(adapter, adapter->stats.pf.mptc); - IXGBE_SET_COLLISIONS(adapter, 0); - IXGBE_SET_IQDROPS(adapter, total_missed_rx); - IXGBE_SET_IERRORS(adapter, adapter->stats.pf.crcerrs - + adapter->stats.pf.rlec); -} -#if __FreeBSD_version >= 1100036 -static uint64_t -ixgbe_get_counter(struct ifnet *ifp, ift_counter cnt) -{ - struct adapter *adapter; - struct tx_ring *txr; - uint64_t rv; - - adapter = if_getsoftc(ifp); - - switch (cnt) { - case IFCOUNTER_IPACKETS: - return (adapter->ipackets); - case IFCOUNTER_OPACKETS: - return (adapter->opackets); - case IFCOUNTER_IBYTES: - return (adapter->ibytes); - case IFCOUNTER_OBYTES: - return (adapter->obytes); - case IFCOUNTER_IMCASTS: - return (adapter->imcasts); - case IFCOUNTER_OMCASTS: - return (adapter->omcasts); - case IFCOUNTER_COLLISIONS: - return (0); - case IFCOUNTER_IQDROPS: - return (adapter->iqdrops); - case IFCOUNTER_OQDROPS: - rv = 0; - txr = adapter->tx_rings; - for (int i = 0; i < adapter->num_queues; i++, txr++) - rv += txr->br->br_drops; - return (rv); - case IFCOUNTER_IERRORS: - return (adapter->ierrors); - default: - return (if_get_counter_default(ifp, cnt)); - } -} -#endif - -/** ixgbe_sysctl_tdh_handler - Handler function - * Retrieves the TDH value from the hardware - */ -static int -ixgbe_sysctl_tdh_handler(SYSCTL_HANDLER_ARGS) -{ - int error; - - struct tx_ring *txr = ((struct tx_ring *)oidp->oid_arg1); - if (!txr) return 0; - - unsigned val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_TDH(txr->me)); - error = sysctl_handle_int(oidp, &val, 0, req); - if (error || !req->newptr) - return error; - return 0; -} - -/** ixgbe_sysctl_tdt_handler - Handler function - * Retrieves the TDT value from the hardware - */ -static int -ixgbe_sysctl_tdt_handler(SYSCTL_HANDLER_ARGS) -{ - int error; - - struct tx_ring *txr = ((struct tx_ring *)oidp->oid_arg1); - if (!txr) return 0; - - unsigned val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_TDT(txr->me)); - error = sysctl_handle_int(oidp, &val, 0, req); - if (error || !req->newptr) - return error; - return 0; -} - -/** ixgbe_sysctl_rdh_handler - Handler function - * Retrieves the RDH value from the hardware - */ -static int -ixgbe_sysctl_rdh_handler(SYSCTL_HANDLER_ARGS) -{ - int error; - - struct rx_ring *rxr = ((struct rx_ring *)oidp->oid_arg1); - if (!rxr) return 0; - - unsigned val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_RDH(rxr->me)); - error = sysctl_handle_int(oidp, &val, 0, req); - if (error || !req->newptr) - return error; - return 0; -} - -/** ixgbe_sysctl_rdt_handler - Handler function - * Retrieves the RDT value from the hardware - */ -static int -ixgbe_sysctl_rdt_handler(SYSCTL_HANDLER_ARGS) -{ - int error; - - struct rx_ring *rxr = ((struct rx_ring *)oidp->oid_arg1); - if (!rxr) return 0; - - unsigned val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_RDT(rxr->me)); - error = sysctl_handle_int(oidp, &val, 0, req); - if (error || !req->newptr) - return error; - return 0; -} - -static int -ixgbe_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS) -{ - int error; - struct ix_queue *que = ((struct ix_queue *)oidp->oid_arg1); - unsigned int reg, usec, rate; - - reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_EITR(que->msix)); - usec = ((reg & 0x0FF8) >> 3); - if (usec > 0) - rate = 500000 / usec; - else - rate = 0; - error = sysctl_handle_int(oidp, &rate, 0, req); - if (error || !req->newptr) - return error; - reg &= ~0xfff; /* default, no limitation */ - ixgbe_max_interrupt_rate = 0; - if (rate > 0 && rate < 500000) { - if (rate < 1000) - rate = 1000; - ixgbe_max_interrupt_rate = rate; - reg |= ((4000000/rate) & 0xff8 ); - } - IXGBE_WRITE_REG(&que->adapter->hw, IXGBE_EITR(que->msix), reg); - return 0; -} - -static void -ixgbe_add_device_sysctls(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct ixgbe_hw *hw = &adapter->hw; - struct sysctl_oid_list *child; - struct sysctl_ctx_list *ctx; - - ctx = device_get_sysctl_ctx(dev); - child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); - - /* Sysctls for all devices */ - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fc", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_flowcntl, "I", IXGBE_SYSCTL_DESC_SET_FC); - - SYSCTL_ADD_INT(ctx, child, OID_AUTO, "enable_aim", - CTLFLAG_RW, - &ixgbe_enable_aim, 1, "Interrupt Moderation"); - - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "advertise_speed", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_advertise, "I", IXGBE_SYSCTL_DESC_ADV_SPEED); - - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "thermal_test", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_thermal_test, "I", "Thermal Test"); - -#ifdef IXGBE_DEBUG - /* testing sysctls (for all devices) */ - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "power_state", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_power_state, "I", "PCI Power State"); - - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "print_rss_config", - CTLTYPE_STRING | CTLFLAG_RD, adapter, 0, - ixgbe_sysctl_print_rss_config, "A", "Prints RSS Configuration"); -#endif - /* for X550 series devices */ - if (hw->mac.type >= ixgbe_mac_X550) - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "dmac", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_dmac, "I", "DMA Coalesce"); - - /* for X552 backplane devices */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) { - struct sysctl_oid *eee_node; - struct sysctl_oid_list *eee_list; - - eee_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "eee", - CTLFLAG_RD, NULL, - "Energy Efficient Ethernet sysctls"); - eee_list = SYSCTL_CHILDREN(eee_node); - - SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "enable", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_eee_enable, "I", - "Enable or Disable EEE"); - - SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "negotiated", - CTLTYPE_INT | CTLFLAG_RD, adapter, 0, - ixgbe_sysctl_eee_negotiated, "I", - "EEE negotiated on link"); - - SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "tx_lpi_status", - CTLTYPE_INT | CTLFLAG_RD, adapter, 0, - ixgbe_sysctl_eee_tx_lpi_status, "I", - "Whether or not TX link is in LPI state"); - - SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "rx_lpi_status", - CTLTYPE_INT | CTLFLAG_RD, adapter, 0, - ixgbe_sysctl_eee_rx_lpi_status, "I", - "Whether or not RX link is in LPI state"); - - SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "tx_lpi_delay", - CTLTYPE_INT | CTLFLAG_RD, adapter, 0, - ixgbe_sysctl_eee_tx_lpi_delay, "I", - "TX LPI entry delay in microseconds"); + if (adapter->tag != NULL) { + bus_teardown_intr(dev, adapter->res, adapter->tag); + adapter->tag = NULL; } - /* for WoL-capable devices */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) { - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "wol_enable", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_wol_enable, "I", - "Enable/Disable Wake on LAN"); + /* Clean the Legacy or Link interrupt last */ + if (adapter->res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, adapter->link_rid, + adapter->res); - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "wufc", - CTLTYPE_INT | CTLFLAG_RW, adapter, 0, - ixgbe_sysctl_wufc, "I", - "Enable/Disable Wake Up Filters"); - } +mem: + if ((adapter->feat_en & IXGBE_FEATURE_MSI) || + (adapter->feat_en & IXGBE_FEATURE_MSIX)) + pci_release_msi(dev); - /* for X552/X557-AT devices */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) { - struct sysctl_oid *phy_node; - struct sysctl_oid_list *phy_list; + if (adapter->msix_mem != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, memrid, + adapter->msix_mem); - phy_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "phy", - CTLFLAG_RD, NULL, - "External PHY sysctls"); - phy_list = SYSCTL_CHILDREN(phy_node); + if (adapter->pci_mem != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), + adapter->pci_mem); - SYSCTL_ADD_PROC(ctx, phy_list, OID_AUTO, "temp", - CTLTYPE_INT | CTLFLAG_RD, adapter, 0, - ixgbe_sysctl_phy_temp, "I", - "Current External PHY Temperature (Celsius)"); - - SYSCTL_ADD_PROC(ctx, phy_list, OID_AUTO, "overtemp_occurred", - CTLTYPE_INT | CTLFLAG_RD, adapter, 0, - ixgbe_sysctl_phy_overtemp_occurred, "I", - "External PHY High Temperature Event Occurred"); - } -} - -/* - * Add sysctl variables, one per statistic, to the system. - */ -static void -ixgbe_add_hw_stats(struct adapter *adapter) -{ - device_t dev = adapter->dev; - - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; - - struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); - struct sysctl_oid *tree = device_get_sysctl_tree(dev); - struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); - struct ixgbe_hw_stats *stats = &adapter->stats.pf; - - struct sysctl_oid *stat_node, *queue_node; - struct sysctl_oid_list *stat_list, *queue_list; - -#define QUEUE_NAME_LEN 32 - char namebuf[QUEUE_NAME_LEN]; - - /* Driver Statistics */ - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped", - CTLFLAG_RD, &adapter->dropped_pkts, - "Driver dropped packets"); - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_failed", - CTLFLAG_RD, &adapter->mbuf_defrag_failed, - "m_defrag() failed"); - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_events", - CTLFLAG_RD, &adapter->watchdog_events, - "Watchdog timeouts"); - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq", - CTLFLAG_RD, &adapter->link_irq, - "Link MSIX IRQ Handled"); - - for (int i = 0; i < adapter->num_queues; i++, txr++) { - snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); - queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, - CTLFLAG_RD, NULL, "Queue Name"); - queue_list = SYSCTL_CHILDREN(queue_node); - - SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "interrupt_rate", - CTLTYPE_UINT | CTLFLAG_RW, &adapter->queues[i], - sizeof(&adapter->queues[i]), - ixgbe_sysctl_interrupt_rate_handler, "IU", - "Interrupt Rate"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs", - CTLFLAG_RD, &(adapter->queues[i].irqs), - "irqs on this queue"); - SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head", - CTLTYPE_UINT | CTLFLAG_RD, txr, sizeof(txr), - ixgbe_sysctl_tdh_handler, "IU", - "Transmit Descriptor Head"); - SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_tail", - CTLTYPE_UINT | CTLFLAG_RD, txr, sizeof(txr), - ixgbe_sysctl_tdt_handler, "IU", - "Transmit Descriptor Tail"); - SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "tso_tx", - CTLFLAG_RD, &txr->tso_tx, - "TSO"); - SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "no_tx_dma_setup", - CTLFLAG_RD, &txr->no_tx_dma_setup, - "Driver tx dma failure in xmit"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "no_desc_avail", - CTLFLAG_RD, &txr->no_desc_avail, - "Queue No Descriptor Available"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets", - CTLFLAG_RD, &txr->total_packets, - "Queue Packets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "br_drops", - CTLFLAG_RD, &txr->br->br_drops, - "Packets dropped in buf_ring"); - } - - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); - queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, - CTLFLAG_RD, NULL, "Queue Name"); - queue_list = SYSCTL_CHILDREN(queue_node); - - struct lro_ctrl *lro = &rxr->lro; - - snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); - queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, - CTLFLAG_RD, NULL, "Queue Name"); - queue_list = SYSCTL_CHILDREN(queue_node); - - SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_head", - CTLTYPE_UINT | CTLFLAG_RD, rxr, sizeof(rxr), - ixgbe_sysctl_rdh_handler, "IU", - "Receive Descriptor Head"); - SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_tail", - CTLTYPE_UINT | CTLFLAG_RD, rxr, sizeof(rxr), - ixgbe_sysctl_rdt_handler, "IU", - "Receive Descriptor Tail"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets", - CTLFLAG_RD, &rxr->rx_packets, - "Queue Packets Received"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes", - CTLFLAG_RD, &rxr->rx_bytes, - "Queue Bytes Received"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_copies", - CTLFLAG_RD, &rxr->rx_copies, - "Copied RX Frames"); - SYSCTL_ADD_U64(ctx, queue_list, OID_AUTO, "lro_queued", - CTLFLAG_RD, &lro->lro_queued, 0, - "LRO Queued"); - SYSCTL_ADD_U64(ctx, queue_list, OID_AUTO, "lro_flushed", - CTLFLAG_RD, &lro->lro_flushed, 0, - "LRO Flushed"); - } - - /* MAC stats get the own sub node */ - - stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats", - CTLFLAG_RD, NULL, "MAC Statistics"); - stat_list = SYSCTL_CHILDREN(stat_node); - - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "crc_errs", - CTLFLAG_RD, &stats->crcerrs, - "CRC Errors"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ill_errs", - CTLFLAG_RD, &stats->illerrc, - "Illegal Byte Errors"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "byte_errs", - CTLFLAG_RD, &stats->errbc, - "Byte Errors"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "short_discards", - CTLFLAG_RD, &stats->mspdc, - "MAC Short Packets Discarded"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "local_faults", - CTLFLAG_RD, &stats->mlfc, - "MAC Local Faults"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "remote_faults", - CTLFLAG_RD, &stats->mrfc, - "MAC Remote Faults"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rec_len_errs", - CTLFLAG_RD, &stats->rlec, - "Receive Length Errors"); - - /* Flow Control stats */ - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_txd", - CTLFLAG_RD, &stats->lxontxc, - "Link XON Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_recvd", - CTLFLAG_RD, &stats->lxonrxc, - "Link XON Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_txd", - CTLFLAG_RD, &stats->lxofftxc, - "Link XOFF Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_recvd", - CTLFLAG_RD, &stats->lxoffrxc, - "Link XOFF Received"); - - /* Packet Reception Stats */ - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_octets_rcvd", - CTLFLAG_RD, &stats->tor, - "Total Octets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd", - CTLFLAG_RD, &stats->gorc, - "Good Octets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_rcvd", - CTLFLAG_RD, &stats->tpr, - "Total Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd", - CTLFLAG_RD, &stats->gprc, - "Good Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd", - CTLFLAG_RD, &stats->mprc, - "Multicast Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_rcvd", - CTLFLAG_RD, &stats->bprc, - "Broadcast Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_64", - CTLFLAG_RD, &stats->prc64, - "64 byte frames received "); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127", - CTLFLAG_RD, &stats->prc127, - "65-127 byte frames received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255", - CTLFLAG_RD, &stats->prc255, - "128-255 byte frames received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511", - CTLFLAG_RD, &stats->prc511, - "256-511 byte frames received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023", - CTLFLAG_RD, &stats->prc1023, - "512-1023 byte frames received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522", - CTLFLAG_RD, &stats->prc1522, - "1023-1522 byte frames received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_undersized", - CTLFLAG_RD, &stats->ruc, - "Receive Undersized"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_fragmented", - CTLFLAG_RD, &stats->rfc, - "Fragmented Packets Received "); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_oversized", - CTLFLAG_RD, &stats->roc, - "Oversized Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_jabberd", - CTLFLAG_RD, &stats->rjc, - "Received Jabber"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "management_pkts_rcvd", - CTLFLAG_RD, &stats->mngprc, - "Management Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "management_pkts_drpd", - CTLFLAG_RD, &stats->mngptc, - "Management Packets Dropped"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "checksum_errs", - CTLFLAG_RD, &stats->xec, - "Checksum Errors"); - - /* Packet Transmission Stats */ - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", - CTLFLAG_RD, &stats->gotc, - "Good Octets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd", - CTLFLAG_RD, &stats->tpt, - "Total Packets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd", - CTLFLAG_RD, &stats->gptc, - "Good Packets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd", - CTLFLAG_RD, &stats->bptc, - "Broadcast Packets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd", - CTLFLAG_RD, &stats->mptc, - "Multicast Packets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "management_pkts_txd", - CTLFLAG_RD, &stats->mngptc, - "Management Packets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_64", - CTLFLAG_RD, &stats->ptc64, - "64 byte frames transmitted "); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127", - CTLFLAG_RD, &stats->ptc127, - "65-127 byte frames transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255", - CTLFLAG_RD, &stats->ptc255, - "128-255 byte frames transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511", - CTLFLAG_RD, &stats->ptc511, - "256-511 byte frames transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023", - CTLFLAG_RD, &stats->ptc1023, - "512-1023 byte frames transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522", - CTLFLAG_RD, &stats->ptc1522, - "1024-1522 byte frames transmitted"); -} + return; +} /* ixgbe_free_pci_resources */ +/************************************************************************ + * ixgbe_set_sysctl_value + ************************************************************************/ static void ixgbe_set_sysctl_value(struct adapter *adapter, const char *name, const char *description, int *limit, int value) @@ -4673,46 +3917,50 @@ ixgbe_set_sysctl_value(struct adapter *adapter, const char *name, SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), OID_AUTO, name, CTLFLAG_RW, limit, value, description); -} +} /* ixgbe_set_sysctl_value */ -/* -** Set flow control using sysctl: -** Flow control values: -** 0 - off -** 1 - rx pause -** 2 - tx pause -** 3 - full -*/ +/************************************************************************ + * ixgbe_sysctl_flowcntl + * + * SYSCTL wrapper around setting Flow Control + ************************************************************************/ static int ixgbe_sysctl_flowcntl(SYSCTL_HANDLER_ARGS) { - int error, fc; struct adapter *adapter; + int error, fc; - adapter = (struct adapter *) arg1; - fc = adapter->fc; + adapter = (struct adapter *)arg1; + fc = adapter->hw.fc.current_mode; error = sysctl_handle_int(oidp, &fc, 0, req); if ((error) || (req->newptr == NULL)) return (error); /* Don't bother if it's not changed */ - if (adapter->fc == fc) + if (fc == adapter->hw.fc.current_mode) return (0); return ixgbe_set_flowcntl(adapter, fc); -} - +} /* ixgbe_sysctl_flowcntl */ +/************************************************************************ + * ixgbe_set_flowcntl - Set flow control + * + * Flow control values: + * 0 - off + * 1 - rx pause + * 2 - tx pause + * 3 - full + ************************************************************************/ static int ixgbe_set_flowcntl(struct adapter *adapter, int fc) { - switch (fc) { case ixgbe_fc_rx_pause: case ixgbe_fc_tx_pause: case ixgbe_fc_full: - adapter->hw.fc.requested_mode = adapter->fc; + adapter->hw.fc.requested_mode = fc; if (adapter->num_queues > 1) ixgbe_disable_rx_drop(adapter); break; @@ -4724,27 +3972,81 @@ ixgbe_set_flowcntl(struct adapter *adapter, int fc) default: return (EINVAL); } - adapter->fc = fc; + /* Don't autoneg if forcing a value */ adapter->hw.fc.disable_fc_autoneg = TRUE; ixgbe_fc_enable(&adapter->hw); - return (0); -} -/* -** Control advertised link speed: -** Flags: -** 0x1 - advertise 100 Mb -** 0x2 - advertise 1G -** 0x4 - advertise 10G -*/ + return (0); +} /* ixgbe_set_flowcntl */ + +/************************************************************************ + * ixgbe_enable_rx_drop + * + * Enable the hardware to drop packets when the buffer is + * full. This is useful with multiqueue, so that no single + * queue being full stalls the entire RX engine. We only + * enable this when Multiqueue is enabled AND Flow Control + * is disabled. + ************************************************************************/ +static void +ixgbe_enable_rx_drop(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct rx_ring *rxr; + u32 srrctl; + + for (int i = 0; i < adapter->num_queues; i++) { + rxr = &adapter->rx_rings[i]; + srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me)); + srrctl |= IXGBE_SRRCTL_DROP_EN; + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl); + } + + /* enable drop for each vf */ + for (int i = 0; i < adapter->num_vfs; i++) { + IXGBE_WRITE_REG(hw, IXGBE_QDE, + (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT) | + IXGBE_QDE_ENABLE)); + } +} /* ixgbe_enable_rx_drop */ + +/************************************************************************ + * ixgbe_disable_rx_drop + ************************************************************************/ +static void +ixgbe_disable_rx_drop(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct rx_ring *rxr; + u32 srrctl; + + for (int i = 0; i < adapter->num_queues; i++) { + rxr = &adapter->rx_rings[i]; + srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me)); + srrctl &= ~IXGBE_SRRCTL_DROP_EN; + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl); + } + + /* disable drop for each vf */ + for (int i = 0; i < adapter->num_vfs; i++) { + IXGBE_WRITE_REG(hw, IXGBE_QDE, + (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT))); + } +} /* ixgbe_disable_rx_drop */ + +/************************************************************************ + * ixgbe_sysctl_advertise + * + * SYSCTL wrapper around setting advertised speed + ************************************************************************/ static int ixgbe_sysctl_advertise(SYSCTL_HANDLER_ARGS) { - int error, advertise; struct adapter *adapter; + int error, advertise; - adapter = (struct adapter *) arg1; + adapter = (struct adapter *)arg1; advertise = adapter->advertise; error = sysctl_handle_int(oidp, &advertise, 0, req); @@ -4752,166 +4054,153 @@ ixgbe_sysctl_advertise(SYSCTL_HANDLER_ARGS) return (error); return ixgbe_set_advertise(adapter, advertise); -} +} /* ixgbe_sysctl_advertise */ +/************************************************************************ + * ixgbe_set_advertise - Control advertised link speed + * + * Flags: + * 0x1 - advertise 100 Mb + * 0x2 - advertise 1G + * 0x4 - advertise 10G + * 0x8 - advertise 10 Mb (yes, Mb) + ************************************************************************/ static int ixgbe_set_advertise(struct adapter *adapter, int advertise) { - device_t dev; - struct ixgbe_hw *hw; - ixgbe_link_speed speed; + device_t dev; + struct ixgbe_hw *hw; + ixgbe_link_speed speed = 0; + ixgbe_link_speed link_caps = 0; + s32 err = IXGBE_NOT_IMPLEMENTED; + bool negotiate = FALSE; /* Checks to validate new value */ if (adapter->advertise == advertise) /* no change */ return (0); - hw = &adapter->hw; dev = adapter->dev; + hw = &adapter->hw; /* No speed changes for backplane media */ if (hw->phy.media_type == ixgbe_media_type_backplane) return (ENODEV); if (!((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.multispeed_fiber))) { - device_printf(dev, - "Advertised speed can only be set on copper or " - "multispeed fiber media types.\n"); + (hw->phy.multispeed_fiber))) { + device_printf(dev, "Advertised speed can only be set on copper or multispeed fiber media types.\n"); return (EINVAL); } - if (advertise < 0x1 || advertise > 0x7) { - device_printf(dev, - "Invalid advertised speed; valid modes are 0x1 through 0x7\n"); + if (advertise < 0x1 || advertise > 0xF) { + device_printf(dev, "Invalid advertised speed; valid modes are 0x1 through 0xF\n"); return (EINVAL); } - if ((advertise & 0x1) - && (hw->mac.type != ixgbe_mac_X540) - && (hw->mac.type != ixgbe_mac_X550)) { - device_printf(dev, "Set Advertise: 100Mb on X540/X550 only\n"); - return (EINVAL); + if (hw->mac.ops.get_link_capabilities) { + err = hw->mac.ops.get_link_capabilities(hw, &link_caps, + &negotiate); + if (err != IXGBE_SUCCESS) { + device_printf(dev, "Unable to determine supported advertise speeds\n"); + return (ENODEV); + } } /* Set new value and report new advertised mode */ - speed = 0; - if (advertise & 0x1) + if (advertise & 0x1) { + if (!(link_caps & IXGBE_LINK_SPEED_100_FULL)) { + device_printf(dev, "Interface does not support 100Mb advertised speed\n"); + return (EINVAL); + } speed |= IXGBE_LINK_SPEED_100_FULL; - if (advertise & 0x2) + } + if (advertise & 0x2) { + if (!(link_caps & IXGBE_LINK_SPEED_1GB_FULL)) { + device_printf(dev, "Interface does not support 1Gb advertised speed\n"); + return (EINVAL); + } speed |= IXGBE_LINK_SPEED_1GB_FULL; - if (advertise & 0x4) + } + if (advertise & 0x4) { + if (!(link_caps & IXGBE_LINK_SPEED_10GB_FULL)) { + device_printf(dev, "Interface does not support 10Gb advertised speed\n"); + return (EINVAL); + } speed |= IXGBE_LINK_SPEED_10GB_FULL; - adapter->advertise = advertise; + } + if (advertise & 0x8) { + if (!(link_caps & IXGBE_LINK_SPEED_10_FULL)) { + device_printf(dev, "Interface does not support 10Mb advertised speed\n"); + return (EINVAL); + } + speed |= IXGBE_LINK_SPEED_10_FULL; + } hw->mac.autotry_restart = TRUE; hw->mac.ops.setup_link(hw, speed, TRUE); + adapter->advertise = advertise; return (0); -} +} /* ixgbe_set_advertise */ -/* - * The following two sysctls are for X552/X557-AT devices; - * they deal with the external PHY used in them. - */ +/************************************************************************ + * ixgbe_get_advertise - Get current advertised speed settings + * + * Formatted for sysctl usage. + * Flags: + * 0x1 - advertise 100 Mb + * 0x2 - advertise 1G + * 0x4 - advertise 10G + * 0x8 - advertise 10 Mb (yes, Mb) + ************************************************************************/ static int -ixgbe_sysctl_phy_temp(SYSCTL_HANDLER_ARGS) +ixgbe_get_advertise(struct adapter *adapter) { - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - u16 reg; + struct ixgbe_hw *hw = &adapter->hw; + int speed; + ixgbe_link_speed link_caps = 0; + s32 err; + bool negotiate = FALSE; - if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) { - device_printf(adapter->dev, - "Device has no supported external thermal sensor.\n"); - return (ENODEV); - } + /* + * Advertised speed means nothing unless it's copper or + * multi-speed fiber + */ + if (!(hw->phy.media_type == ixgbe_media_type_copper) && + !(hw->phy.multispeed_fiber)) + return (0); - if (hw->phy.ops.read_reg(hw, IXGBE_PHY_CURRENT_TEMP, - IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, - ®)) { - device_printf(adapter->dev, - "Error reading from PHY's current temperature register\n"); - return (EAGAIN); - } + err = hw->mac.ops.get_link_capabilities(hw, &link_caps, &negotiate); + if (err != IXGBE_SUCCESS) + return (0); - /* Shift temp for output */ - reg = reg >> 8; + speed = + ((link_caps & IXGBE_LINK_SPEED_10GB_FULL) ? 4 : 0) | + ((link_caps & IXGBE_LINK_SPEED_1GB_FULL) ? 2 : 0) | + ((link_caps & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0) | + ((link_caps & IXGBE_LINK_SPEED_10_FULL) ? 8 : 0); - return (sysctl_handle_int(oidp, NULL, reg, req)); -} + return speed; +} /* ixgbe_get_advertise */ -/* - * Reports whether the current PHY temperature is over - * the overtemp threshold. - * - This is reported directly from the PHY - */ -static int -ixgbe_sysctl_phy_overtemp_occurred(SYSCTL_HANDLER_ARGS) -{ - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - u16 reg; - - if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) { - device_printf(adapter->dev, - "Device has no supported external thermal sensor.\n"); - return (ENODEV); - } - - if (hw->phy.ops.read_reg(hw, IXGBE_PHY_OVERTEMP_STATUS, - IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, - ®)) { - device_printf(adapter->dev, - "Error reading from PHY's temperature status register\n"); - return (EAGAIN); - } - - /* Get occurrence bit */ - reg = !!(reg & 0x4000); - return (sysctl_handle_int(oidp, 0, reg, req)); -} - -/* -** Thermal Shutdown Trigger (internal MAC) -** - Set this to 1 to cause an overtemp event to occur -*/ -static int -ixgbe_sysctl_thermal_test(SYSCTL_HANDLER_ARGS) -{ - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - int error, fire = 0; - - error = sysctl_handle_int(oidp, &fire, 0, req); - if ((error) || (req->newptr == NULL)) - return (error); - - if (fire) { - u32 reg = IXGBE_READ_REG(hw, IXGBE_EICS); - reg |= IXGBE_EICR_TS; - IXGBE_WRITE_REG(hw, IXGBE_EICS, reg); - } - - return (0); -} - -/* -** Manage DMA Coalescing. -** Control values: -** 0/1 - off / on (use default value of 1000) -** -** Legal timer values are: -** 50,100,250,500,1000,2000,5000,10000 -** -** Turning off interrupt moderation will also turn this off. -*/ +/************************************************************************ + * ixgbe_sysctl_dmac - Manage DMA Coalescing + * + * Control values: + * 0/1 - off / on (use default value of 1000) + * + * Legal timer values are: + * 50,100,250,500,1000,2000,5000,10000 + * + * Turning off interrupt moderation will also turn this off. + ************************************************************************/ static int ixgbe_sysctl_dmac(SYSCTL_HANDLER_ARGS) { - struct adapter *adapter = (struct adapter *) arg1; - struct ifnet *ifp = adapter->ifp; - int error; - u32 newval; + struct adapter *adapter = (struct adapter *)arg1; + struct ifnet *ifp = adapter->ifp; + int error; + u32 newval; newval = adapter->dmac; error = sysctl_handle_int(oidp, &newval, 0, req); @@ -4948,22 +4237,24 @@ ixgbe_sysctl_dmac(SYSCTL_HANDLER_ARGS) ixgbe_init(adapter); return (0); -} +} /* ixgbe_sysctl_dmac */ #ifdef IXGBE_DEBUG -/** - * Sysctl to test power states - * Values: - * 0 - set device to D0 - * 3 - set device to D3 - * (none) - get current device power state - */ +/************************************************************************ + * ixgbe_sysctl_power_state + * + * Sysctl to test power states + * Values: + * 0 - set device to D0 + * 3 - set device to D3 + * (none) - get current device power state + ************************************************************************/ static int ixgbe_sysctl_power_state(SYSCTL_HANDLER_ARGS) { - struct adapter *adapter = (struct adapter *) arg1; - device_t dev = adapter->dev; - int curr_ps, new_ps, error = 0; + struct adapter *adapter = (struct adapter *)arg1; + device_t dev = adapter->dev; + int curr_ps, new_ps, error = 0; curr_ps = new_ps = pci_get_powerstate(dev); @@ -4984,21 +4275,26 @@ ixgbe_sysctl_power_state(SYSCTL_HANDLER_ARGS) device_printf(dev, "New state: %d\n", pci_get_powerstate(dev)); return (error); -} +} /* ixgbe_sysctl_power_state */ #endif -/* - * Sysctl to enable/disable the WoL capability, if supported by the adapter. - * Values: - * 0 - disabled - * 1 - enabled - */ + +/************************************************************************ + * ixgbe_sysctl_wol_enable + * + * Sysctl to enable/disable the WoL capability, + * if supported by the adapter. + * + * Values: + * 0 - disabled + * 1 - enabled + ************************************************************************/ static int ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS) { - struct adapter *adapter = (struct adapter *) arg1; + struct adapter *adapter = (struct adapter *)arg1; struct ixgbe_hw *hw = &adapter->hw; - int new_wol_enabled; - int error = 0; + int new_wol_enabled; + int error = 0; new_wol_enabled = hw->wol_enabled; error = sysctl_handle_int(oidp, &new_wol_enabled, 0, req); @@ -5014,129 +4310,31 @@ ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS) hw->wol_enabled = new_wol_enabled; return (0); -} +} /* ixgbe_sysctl_wol_enable */ -/* - * Sysctl to enable/disable the Energy Efficient Ethernet capability, - * if supported by the adapter. - * Values: - * 0 - disabled - * 1 - enabled - */ -static int -ixgbe_sysctl_eee_enable(SYSCTL_HANDLER_ARGS) -{ - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - struct ifnet *ifp = adapter->ifp; - int new_eee_enabled, error = 0; - - new_eee_enabled = adapter->eee_enabled; - error = sysctl_handle_int(oidp, &new_eee_enabled, 0, req); - if ((error) || (req->newptr == NULL)) - return (error); - new_eee_enabled = !!(new_eee_enabled); - if (new_eee_enabled == adapter->eee_enabled) - return (0); - - if (new_eee_enabled > 0 && !hw->mac.ops.setup_eee) - return (ENODEV); - else - adapter->eee_enabled = new_eee_enabled; - - /* Re-initialize hardware if it's already running */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ixgbe_init(adapter); - - return (0); -} - -/* - * Read-only sysctl indicating whether EEE support was negotiated - * on the link. - */ -static int -ixgbe_sysctl_eee_negotiated(SYSCTL_HANDLER_ARGS) -{ - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - bool status; - - status = !!(IXGBE_READ_REG(hw, IXGBE_EEE_STAT) & IXGBE_EEE_STAT_NEG); - - return (sysctl_handle_int(oidp, 0, status, req)); -} - -/* - * Read-only sysctl indicating whether RX Link is in LPI state. - */ -static int -ixgbe_sysctl_eee_rx_lpi_status(SYSCTL_HANDLER_ARGS) -{ - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - bool status; - - status = !!(IXGBE_READ_REG(hw, IXGBE_EEE_STAT) & - IXGBE_EEE_RX_LPI_STATUS); - - return (sysctl_handle_int(oidp, 0, status, req)); -} - -/* - * Read-only sysctl indicating whether TX Link is in LPI state. - */ -static int -ixgbe_sysctl_eee_tx_lpi_status(SYSCTL_HANDLER_ARGS) -{ - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - bool status; - - status = !!(IXGBE_READ_REG(hw, IXGBE_EEE_STAT) & - IXGBE_EEE_TX_LPI_STATUS); - - return (sysctl_handle_int(oidp, 0, status, req)); -} - -/* - * Read-only sysctl indicating TX Link LPI delay - */ -static int -ixgbe_sysctl_eee_tx_lpi_delay(SYSCTL_HANDLER_ARGS) -{ - struct adapter *adapter = (struct adapter *) arg1; - struct ixgbe_hw *hw = &adapter->hw; - u32 reg; - - reg = IXGBE_READ_REG(hw, IXGBE_EEE_SU); - - return (sysctl_handle_int(oidp, 0, reg >> 26, req)); -} - -/* - * Sysctl to enable/disable the types of packets that the - * adapter will wake up on upon receipt. - * WUFC - Wake Up Filter Control - * Flags: - * 0x1 - Link Status Change - * 0x2 - Magic Packet - * 0x4 - Direct Exact - * 0x8 - Directed Multicast - * 0x10 - Broadcast - * 0x20 - ARP/IPv4 Request Packet - * 0x40 - Direct IPv4 Packet - * 0x80 - Direct IPv6 Packet +/************************************************************************ + * ixgbe_sysctl_wufc - Wake Up Filter Control * - * Setting another flag will cause the sysctl to return an - * error. - */ + * Sysctl to enable/disable the types of packets that the + * adapter will wake up on upon receipt. + * Flags: + * 0x1 - Link Status Change + * 0x2 - Magic Packet + * 0x4 - Direct Exact + * 0x8 - Directed Multicast + * 0x10 - Broadcast + * 0x20 - ARP/IPv4 Request Packet + * 0x40 - Direct IPv4 Packet + * 0x80 - Direct IPv6 Packet + * + * Settings not listed above will cause the sysctl to return an error. + ************************************************************************/ static int ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS) { - struct adapter *adapter = (struct adapter *) arg1; - int error = 0; - u32 new_wufc; + struct adapter *adapter = (struct adapter *)arg1; + int error = 0; + u32 new_wufc; new_wufc = adapter->wufc; @@ -5148,25 +4346,27 @@ ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS) if (new_wufc & 0xffffff00) return (EINVAL); - else { - new_wufc &= 0xff; - new_wufc |= (0xffffff & adapter->wufc); - adapter->wufc = new_wufc; - } + + new_wufc &= 0xff; + new_wufc |= (0xffffff & adapter->wufc); + adapter->wufc = new_wufc; return (0); -} +} /* ixgbe_sysctl_wufc */ #ifdef IXGBE_DEBUG +/************************************************************************ + * ixgbe_sysctl_print_rss_config + ************************************************************************/ static int ixgbe_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS) { - struct adapter *adapter = (struct adapter *)arg1; + struct adapter *adapter = (struct adapter *)arg1; struct ixgbe_hw *hw = &adapter->hw; - device_t dev = adapter->dev; - int error = 0, reta_size; - struct sbuf *buf; - u32 reg; + device_t dev = adapter->dev; + struct sbuf *buf; + int error = 0, reta_size; + u32 reg; buf = sbuf_new_for_sysctl(NULL, NULL, 128, req); if (!buf) { @@ -5179,6 +4379,7 @@ ixgbe_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS) switch (adapter->hw.mac.type) { case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: reta_size = 128; break; default: @@ -5205,58 +4406,844 @@ ixgbe_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS) device_printf(dev, "Error finishing sbuf: %d\n", error); sbuf_delete(buf); + return (0); -} +} /* ixgbe_sysctl_print_rss_config */ #endif /* IXGBE_DEBUG */ -/* -** Enable the hardware to drop packets when the buffer is -** full. This is useful when multiqueue,so that no single -** queue being full stalls the entire RX engine. We only -** enable this when Multiqueue AND when Flow Control is -** disabled. -*/ -static void -ixgbe_enable_rx_drop(struct adapter *adapter) +/************************************************************************ + * ixgbe_sysctl_phy_temp - Retrieve temperature of PHY + * + * For X552/X557-AT devices using an external PHY + ************************************************************************/ +static int +ixgbe_sysctl_phy_temp(SYSCTL_HANDLER_ARGS) { - struct ixgbe_hw *hw = &adapter->hw; + struct adapter *adapter = (struct adapter *)arg1; + struct ixgbe_hw *hw = &adapter->hw; + u16 reg; - for (int i = 0; i < adapter->num_queues; i++) { - struct rx_ring *rxr = &adapter->rx_rings[i]; - u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me)); - srrctl |= IXGBE_SRRCTL_DROP_EN; - IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl); + if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) { + device_printf(adapter->dev, + "Device has no supported external thermal sensor.\n"); + return (ENODEV); } -#ifdef PCI_IOV - /* enable drop for each vf */ - for (int i = 0; i < adapter->num_vfs; i++) { - IXGBE_WRITE_REG(hw, IXGBE_QDE, - (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT) | - IXGBE_QDE_ENABLE)); + + if (hw->phy.ops.read_reg(hw, IXGBE_PHY_CURRENT_TEMP, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ®)) { + device_printf(adapter->dev, + "Error reading from PHY's current temperature register\n"); + return (EAGAIN); + } + + /* Shift temp for output */ + reg = reg >> 8; + + return (sysctl_handle_int(oidp, NULL, reg, req)); +} /* ixgbe_sysctl_phy_temp */ + +/************************************************************************ + * ixgbe_sysctl_phy_overtemp_occurred + * + * Reports (directly from the PHY) whether the current PHY + * temperature is over the overtemp threshold. + ************************************************************************/ +static int +ixgbe_sysctl_phy_overtemp_occurred(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *)arg1; + struct ixgbe_hw *hw = &adapter->hw; + u16 reg; + + if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) { + device_printf(adapter->dev, + "Device has no supported external thermal sensor.\n"); + return (ENODEV); + } + + if (hw->phy.ops.read_reg(hw, IXGBE_PHY_OVERTEMP_STATUS, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ®)) { + device_printf(adapter->dev, + "Error reading from PHY's temperature status register\n"); + return (EAGAIN); + } + + /* Get occurrence bit */ + reg = !!(reg & 0x4000); + + return (sysctl_handle_int(oidp, 0, reg, req)); +} /* ixgbe_sysctl_phy_overtemp_occurred */ + +/************************************************************************ + * ixgbe_sysctl_eee_state + * + * Sysctl to set EEE power saving feature + * Values: + * 0 - disable EEE + * 1 - enable EEE + * (none) - get current device EEE state + ************************************************************************/ +static int +ixgbe_sysctl_eee_state(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *)arg1; + device_t dev = adapter->dev; + int curr_eee, new_eee, error = 0; + s32 retval; + + curr_eee = new_eee = !!(adapter->feat_en & IXGBE_FEATURE_EEE); + + error = sysctl_handle_int(oidp, &new_eee, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + /* Nothing to do */ + if (new_eee == curr_eee) + return (0); + + /* Not supported */ + if (!(adapter->feat_cap & IXGBE_FEATURE_EEE)) + return (EINVAL); + + /* Bounds checking */ + if ((new_eee < 0) || (new_eee > 1)) + return (EINVAL); + + retval = adapter->hw.mac.ops.setup_eee(&adapter->hw, new_eee); + if (retval) { + device_printf(dev, "Error in EEE setup: 0x%08X\n", retval); + return (EINVAL); + } + + /* Restart auto-neg */ + ixgbe_init(adapter); + + device_printf(dev, "New EEE state: %d\n", new_eee); + + /* Cache new value */ + if (new_eee) + adapter->feat_en |= IXGBE_FEATURE_EEE; + else + adapter->feat_en &= ~IXGBE_FEATURE_EEE; + + return (error); +} /* ixgbe_sysctl_eee_state */ + +/************************************************************************ + * ixgbe_init_device_features + ************************************************************************/ +static void +ixgbe_init_device_features(struct adapter *adapter) +{ + adapter->feat_cap = IXGBE_FEATURE_NETMAP + | IXGBE_FEATURE_RSS + | IXGBE_FEATURE_MSI + | IXGBE_FEATURE_MSIX + | IXGBE_FEATURE_LEGACY_IRQ + | IXGBE_FEATURE_LEGACY_TX; + + /* Set capabilities first... */ + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + if (adapter->hw.device_id == IXGBE_DEV_ID_82598AT) + adapter->feat_cap |= IXGBE_FEATURE_FAN_FAIL; + break; + case ixgbe_mac_X540: + adapter->feat_cap |= IXGBE_FEATURE_SRIOV; + adapter->feat_cap |= IXGBE_FEATURE_FDIR; + if ((adapter->hw.device_id == IXGBE_DEV_ID_X540_BYPASS) && + (adapter->hw.bus.func == 0)) + adapter->feat_cap |= IXGBE_FEATURE_BYPASS; + break; + case ixgbe_mac_X550: + adapter->feat_cap |= IXGBE_FEATURE_TEMP_SENSOR; + adapter->feat_cap |= IXGBE_FEATURE_SRIOV; + adapter->feat_cap |= IXGBE_FEATURE_FDIR; + break; + case ixgbe_mac_X550EM_x: + adapter->feat_cap |= IXGBE_FEATURE_SRIOV; + adapter->feat_cap |= IXGBE_FEATURE_FDIR; + if (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_X_KR) + adapter->feat_cap |= IXGBE_FEATURE_EEE; + break; + case ixgbe_mac_X550EM_a: + adapter->feat_cap |= IXGBE_FEATURE_SRIOV; + adapter->feat_cap |= IXGBE_FEATURE_FDIR; + adapter->feat_cap &= ~IXGBE_FEATURE_LEGACY_IRQ; + if ((adapter->hw.device_id == IXGBE_DEV_ID_X550EM_A_1G_T) || + (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)) { + adapter->feat_cap |= IXGBE_FEATURE_TEMP_SENSOR; + adapter->feat_cap |= IXGBE_FEATURE_EEE; + } + break; + case ixgbe_mac_82599EB: + adapter->feat_cap |= IXGBE_FEATURE_SRIOV; + adapter->feat_cap |= IXGBE_FEATURE_FDIR; + if ((adapter->hw.device_id == IXGBE_DEV_ID_82599_BYPASS) && + (adapter->hw.bus.func == 0)) + adapter->feat_cap |= IXGBE_FEATURE_BYPASS; + if (adapter->hw.device_id == IXGBE_DEV_ID_82599_QSFP_SF_QP) + adapter->feat_cap &= ~IXGBE_FEATURE_LEGACY_IRQ; + break; + default: + break; + } + + /* Enabled by default... */ + /* Fan failure detection */ + if (adapter->feat_cap & IXGBE_FEATURE_FAN_FAIL) + adapter->feat_en |= IXGBE_FEATURE_FAN_FAIL; + /* Netmap */ + if (adapter->feat_cap & IXGBE_FEATURE_NETMAP) + adapter->feat_en |= IXGBE_FEATURE_NETMAP; + /* EEE */ + if (adapter->feat_cap & IXGBE_FEATURE_EEE) + adapter->feat_en |= IXGBE_FEATURE_EEE; + /* Thermal Sensor */ + if (adapter->feat_cap & IXGBE_FEATURE_TEMP_SENSOR) + adapter->feat_en |= IXGBE_FEATURE_TEMP_SENSOR; + + /* Enabled via global sysctl... */ + /* Flow Director */ + if (ixgbe_enable_fdir) { + if (adapter->feat_cap & IXGBE_FEATURE_FDIR) + adapter->feat_en |= IXGBE_FEATURE_FDIR; + else + device_printf(adapter->dev, "Device does not support Flow Director. Leaving disabled."); + } + /* Legacy (single queue) transmit */ + if ((adapter->feat_cap & IXGBE_FEATURE_LEGACY_TX) && + ixgbe_enable_legacy_tx) + adapter->feat_en |= IXGBE_FEATURE_LEGACY_TX; + /* + * Message Signal Interrupts - Extended (MSI-X) + * Normal MSI is only enabled if MSI-X calls fail. + */ + if (!ixgbe_enable_msix) + adapter->feat_cap &= ~IXGBE_FEATURE_MSIX; + /* Receive-Side Scaling (RSS) */ + if ((adapter->feat_cap & IXGBE_FEATURE_RSS) && ixgbe_enable_rss) + adapter->feat_en |= IXGBE_FEATURE_RSS; + + /* Disable features with unmet dependencies... */ + /* No MSI-X */ + if (!(adapter->feat_cap & IXGBE_FEATURE_MSIX)) { + adapter->feat_cap &= ~IXGBE_FEATURE_RSS; + adapter->feat_cap &= ~IXGBE_FEATURE_SRIOV; + adapter->feat_en &= ~IXGBE_FEATURE_RSS; + adapter->feat_en &= ~IXGBE_FEATURE_SRIOV; + } +} /* ixgbe_init_device_features */ + +/************************************************************************ + * ixgbe_probe - Device identification routine + * + * Determines if the driver should be loaded on + * adapter based on its PCI vendor/device ID. + * + * return BUS_PROBE_DEFAULT on success, positive on failure + ************************************************************************/ +static int +ixgbe_probe(device_t dev) +{ + ixgbe_vendor_info_t *ent; + + u16 pci_vendor_id = 0; + u16 pci_device_id = 0; + u16 pci_subvendor_id = 0; + u16 pci_subdevice_id = 0; + char adapter_name[256]; + + INIT_DEBUGOUT("ixgbe_probe: begin"); + + pci_vendor_id = pci_get_vendor(dev); + if (pci_vendor_id != IXGBE_INTEL_VENDOR_ID) + return (ENXIO); + + pci_device_id = pci_get_device(dev); + pci_subvendor_id = pci_get_subvendor(dev); + pci_subdevice_id = pci_get_subdevice(dev); + + ent = ixgbe_vendor_info_array; + while (ent->vendor_id != 0) { + if ((pci_vendor_id == ent->vendor_id) && + (pci_device_id == ent->device_id) && + ((pci_subvendor_id == ent->subvendor_id) || + (ent->subvendor_id == 0)) && + ((pci_subdevice_id == ent->subdevice_id) || + (ent->subdevice_id == 0))) { + sprintf(adapter_name, "%s, Version - %s", + ixgbe_strings[ent->index], + ixgbe_driver_version); + device_set_desc_copy(dev, adapter_name); + ++ixgbe_total_ports; + return (BUS_PROBE_DEFAULT); + } + ent++; + } + + return (ENXIO); +} /* ixgbe_probe */ + + +/************************************************************************ + * ixgbe_ioctl - Ioctl entry point + * + * Called when the user wants to configure the interface. + * + * return 0 on success, positive on failure + ************************************************************************/ +static int +ixgbe_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct adapter *adapter = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *) data; +#if defined(INET) || defined(INET6) + struct ifaddr *ifa = (struct ifaddr *)data; +#endif + int error = 0; + bool avoid_reset = FALSE; + + switch (command) { + case SIOCSIFADDR: +#ifdef INET + if (ifa->ifa_addr->sa_family == AF_INET) + avoid_reset = TRUE; +#endif +#ifdef INET6 + if (ifa->ifa_addr->sa_family == AF_INET6) + avoid_reset = TRUE; +#endif + /* + * Calling init results in link renegotiation, + * so we avoid doing it when possible. + */ + if (avoid_reset) { + ifp->if_flags |= IFF_UP; + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + ixgbe_init(adapter); +#ifdef INET + if (!(ifp->if_flags & IFF_NOARP)) + arp_ifinit(ifp, ifa); +#endif + } else + error = ether_ioctl(ifp, command, data); + break; + case SIOCSIFMTU: + IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); + if (ifr->ifr_mtu > IXGBE_MAX_MTU) { + error = EINVAL; + } else { + IXGBE_CORE_LOCK(adapter); + ifp->if_mtu = ifr->ifr_mtu; + adapter->max_frame_size = ifp->if_mtu + IXGBE_MTU_HDR; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ixgbe_init_locked(adapter); + ixgbe_recalculate_max_frame(adapter); + IXGBE_CORE_UNLOCK(adapter); + } + break; + case SIOCSIFFLAGS: + IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)"); + IXGBE_CORE_LOCK(adapter); + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if ((ifp->if_flags ^ adapter->if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) { + ixgbe_set_promisc(adapter); + } + } else + ixgbe_init_locked(adapter); + } else + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ixgbe_stop(adapter); + adapter->if_flags = ifp->if_flags; + IXGBE_CORE_UNLOCK(adapter); + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI"); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + IXGBE_CORE_LOCK(adapter); + ixgbe_disable_intr(adapter); + ixgbe_set_multi(adapter); + ixgbe_enable_intr(adapter); + IXGBE_CORE_UNLOCK(adapter); + } + break; + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)"); + error = ifmedia_ioctl(ifp, ifr, &adapter->media, command); + break; + case SIOCSIFCAP: + { + IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)"); + + int mask = ifr->ifr_reqcap ^ ifp->if_capenable; + + if (!mask) + break; + + /* HW cannot turn these on/off separately */ + if (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) { + ifp->if_capenable ^= IFCAP_RXCSUM; + ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; + } + if (mask & IFCAP_TXCSUM) + ifp->if_capenable ^= IFCAP_TXCSUM; + if (mask & IFCAP_TXCSUM_IPV6) + ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; + if (mask & IFCAP_TSO4) + ifp->if_capenable ^= IFCAP_TSO4; + if (mask & IFCAP_TSO6) + ifp->if_capenable ^= IFCAP_TSO6; + if (mask & IFCAP_LRO) + ifp->if_capenable ^= IFCAP_LRO; + if (mask & IFCAP_VLAN_HWTAGGING) + ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; + if (mask & IFCAP_VLAN_HWFILTER) + ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; + if (mask & IFCAP_VLAN_HWTSO) + ifp->if_capenable ^= IFCAP_VLAN_HWTSO; + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + IXGBE_CORE_LOCK(adapter); + ixgbe_init_locked(adapter); + IXGBE_CORE_UNLOCK(adapter); + } + VLAN_CAPABILITIES(ifp); + break; + } +#if __FreeBSD_version >= 1100036 + case SIOCGI2C: + { + struct ixgbe_hw *hw = &adapter->hw; + struct ifi2creq i2c; + int i; + + IOCTL_DEBUGOUT("ioctl: SIOCGI2C (Get I2C Data)"); + error = copyin(ifr->ifr_data, &i2c, sizeof(i2c)); + if (error != 0) + break; + if (i2c.dev_addr != 0xA0 && i2c.dev_addr != 0xA2) { + error = EINVAL; + break; + } + if (i2c.len > sizeof(i2c.data)) { + error = EINVAL; + break; + } + + for (i = 0; i < i2c.len; i++) + hw->phy.ops.read_i2c_byte(hw, i2c.offset + i, + i2c.dev_addr, &i2c.data[i]); + error = copyout(&i2c, ifr->ifr_data, sizeof(i2c)); + break; } #endif -} + default: + IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command); + error = ether_ioctl(ifp, command, data); + break; + } + return (error); +} /* ixgbe_ioctl */ + +/************************************************************************ + * ixgbe_check_fan_failure + ************************************************************************/ static void -ixgbe_disable_rx_drop(struct adapter *adapter) +ixgbe_check_fan_failure(struct adapter *adapter, u32 reg, bool in_interrupt) { - struct ixgbe_hw *hw = &adapter->hw; + u32 mask; - for (int i = 0; i < adapter->num_queues; i++) { - struct rx_ring *rxr = &adapter->rx_rings[i]; - u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me)); - srrctl &= ~IXGBE_SRRCTL_DROP_EN; - IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl); + mask = (in_interrupt) ? IXGBE_EICR_GPI_SDP1_BY_MAC(&adapter->hw) : + IXGBE_ESDP_SDP1; + + if (reg & mask) + device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! REPLACE IMMEDIATELY!!\n"); +} /* ixgbe_check_fan_failure */ + +/************************************************************************ + * ixgbe_handle_que + ************************************************************************/ +static void +ixgbe_handle_que(void *context, int pending) +{ + struct ix_queue *que = context; + struct adapter *adapter = que->adapter; + struct tx_ring *txr = que->txr; + struct ifnet *ifp = adapter->ifp; + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + ixgbe_rxeof(que); + IXGBE_TX_LOCK(txr); + ixgbe_txeof(txr); + if (!ixgbe_ring_empty(ifp, txr->br)) + ixgbe_start_locked(ifp, txr); + IXGBE_TX_UNLOCK(txr); } -#ifdef PCI_IOV - /* disable drop for each vf */ - for (int i = 0; i < adapter->num_vfs; i++) { - IXGBE_WRITE_REG(hw, IXGBE_QDE, - (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT))); + + /* Re-enable this interrupt */ + if (que->res != NULL) + ixgbe_enable_queue(adapter, que->msix); + else + ixgbe_enable_intr(adapter); + + return; +} /* ixgbe_handle_que */ + + + +/************************************************************************ + * ixgbe_allocate_legacy - Setup the Legacy or MSI Interrupt handler + ************************************************************************/ +static int +ixgbe_allocate_legacy(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct ix_queue *que = adapter->queues; + struct tx_ring *txr = adapter->tx_rings; + int error; + + /* We allocate a single interrupt resource */ + adapter->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &adapter->link_rid, RF_SHAREABLE | RF_ACTIVE); + if (adapter->res == NULL) { + device_printf(dev, + "Unable to allocate bus resource: interrupt\n"); + return (ENXIO); } + + /* + * Try allocating a fast interrupt and the associated deferred + * processing contexts. + */ + if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) + TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr); + TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que); + que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT, + taskqueue_thread_enqueue, &que->tq); + taskqueue_start_threads(&que->tq, 1, PI_NET, "%s ixq", + device_get_nameunit(adapter->dev)); + + /* Tasklets for Link, SFP and Multispeed Fiber */ + TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter); + TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter); + TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter); + TASK_INIT(&adapter->phy_task, 0, ixgbe_handle_phy, adapter); + if (adapter->feat_en & IXGBE_FEATURE_FDIR) + TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter); + adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT, + taskqueue_thread_enqueue, &adapter->tq); + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", + device_get_nameunit(adapter->dev)); + + if ((error = bus_setup_intr(dev, adapter->res, + INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_legacy_irq, que, + &adapter->tag)) != 0) { + device_printf(dev, + "Failed to register fast interrupt handler: %d\n", error); + taskqueue_free(que->tq); + taskqueue_free(adapter->tq); + que->tq = NULL; + adapter->tq = NULL; + + return (error); + } + /* For simplicity in the handlers */ + adapter->active_queues = IXGBE_EIMS_ENABLE_MASK; + + return (0); +} /* ixgbe_allocate_legacy */ + + +/************************************************************************ + * ixgbe_allocate_msix - Setup MSI-X Interrupt resources and handlers + ************************************************************************/ +static int +ixgbe_allocate_msix(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct ix_queue *que = adapter->queues; + struct tx_ring *txr = adapter->tx_rings; + int error, rid, vector = 0; + int cpu_id = 0; + unsigned int rss_buckets = 0; + cpuset_t cpu_mask; + + /* + * If we're doing RSS, the number of queues needs to + * match the number of RSS buckets that are configured. + * + * + If there's more queues than RSS buckets, we'll end + * up with queues that get no traffic. + * + * + If there's more RSS buckets than queues, we'll end + * up having multiple RSS buckets map to the same queue, + * so there'll be some contention. + */ + rss_buckets = rss_getnumbuckets(); + if ((adapter->feat_en & IXGBE_FEATURE_RSS) && + (adapter->num_queues != rss_buckets)) { + device_printf(dev, "%s: number of queues (%d) != number of RSS buckets (%d); performance will be impacted.\n", + __func__, adapter->num_queues, rss_buckets); + } + + for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) { + rid = vector + 1; + que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (que->res == NULL) { + device_printf(dev, "Unable to allocate bus resource: que interrupt [%d]\n", + vector); + return (ENXIO); + } + /* Set the handler function */ + error = bus_setup_intr(dev, que->res, + INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_msix_que, que, + &que->tag); + if (error) { + que->res = NULL; + device_printf(dev, "Failed to register QUE handler"); + return (error); + } +#if __FreeBSD_version >= 800504 + bus_describe_intr(dev, que->res, que->tag, "q%d", i); #endif -} + que->msix = vector; + adapter->active_queues |= (u64)(1 << que->msix); + if (adapter->feat_en & IXGBE_FEATURE_RSS) { + /* + * The queue ID is used as the RSS layer bucket ID. + * We look up the queue ID -> RSS CPU ID and select + * that. + */ + cpu_id = rss_getcpu(i % rss_buckets); + CPU_SETOF(cpu_id, &cpu_mask); + } else { + /* + * Bind the MSI-X vector, and thus the + * rings to the corresponding CPU. + * + * This just happens to match the default RSS + * round-robin bucket -> queue -> CPU allocation. + */ + if (adapter->num_queues > 1) + cpu_id = i; + } + if (adapter->num_queues > 1) + bus_bind_intr(dev, que->res, cpu_id); +#ifdef IXGBE_DEBUG + if (adapter->feat_en & IXGBE_FEATURE_RSS) + device_printf(dev, "Bound RSS bucket %d to CPU %d\n", i, + cpu_id); + else + device_printf(dev, "Bound queue %d to cpu %d\n", i, + cpu_id); +#endif /* IXGBE_DEBUG */ + + + if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) + TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, + txr); + TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que); + que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT, + taskqueue_thread_enqueue, &que->tq); +#if __FreeBSD_version < 1100000 + taskqueue_start_threads(&que->tq, 1, PI_NET, "%s:q%d", + device_get_nameunit(adapter->dev), i); +#else + if (adapter->feat_en & IXGBE_FEATURE_RSS) + taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET, + &cpu_mask, "%s (bucket %d)", + device_get_nameunit(adapter->dev), cpu_id); + else + taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET, + NULL, "%s:q%d", device_get_nameunit(adapter->dev), + i); +#endif + } + + /* and Link */ + adapter->link_rid = vector + 1; + adapter->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &adapter->link_rid, RF_SHAREABLE | RF_ACTIVE); + if (!adapter->res) { + device_printf(dev, + "Unable to allocate bus resource: Link interrupt [%d]\n", + adapter->link_rid); + return (ENXIO); + } + /* Set the link handler function */ + error = bus_setup_intr(dev, adapter->res, INTR_TYPE_NET | INTR_MPSAFE, + NULL, ixgbe_msix_link, adapter, &adapter->tag); + if (error) { + adapter->res = NULL; + device_printf(dev, "Failed to register LINK handler"); + return (error); + } +#if __FreeBSD_version >= 800504 + bus_describe_intr(dev, adapter->res, adapter->tag, "link"); +#endif + adapter->vector = vector; + /* Tasklets for Link, SFP and Multispeed Fiber */ + TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter); + TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter); + TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter); + if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) + TASK_INIT(&adapter->mbx_task, 0, ixgbe_handle_mbx, adapter); + TASK_INIT(&adapter->phy_task, 0, ixgbe_handle_phy, adapter); + if (adapter->feat_en & IXGBE_FEATURE_FDIR) + TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter); + adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT, + taskqueue_thread_enqueue, &adapter->tq); + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", + device_get_nameunit(adapter->dev)); + + return (0); +} /* ixgbe_allocate_msix */ + +/************************************************************************ + * ixgbe_configure_interrupts + * + * Setup MSI-X, MSI, or legacy interrupts (in that order). + * This will also depend on user settings. + ************************************************************************/ +static int +ixgbe_configure_interrupts(struct adapter *adapter) +{ + device_t dev = adapter->dev; + int rid, want, queues, msgs; + + /* Default to 1 queue if MSI-X setup fails */ + adapter->num_queues = 1; + + /* Override by tuneable */ + if (!(adapter->feat_cap & IXGBE_FEATURE_MSIX)) + goto msi; + + /* First try MSI-X */ + msgs = pci_msix_count(dev); + if (msgs == 0) + goto msi; + rid = PCIR_BAR(MSIX_82598_BAR); + adapter->msix_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (adapter->msix_mem == NULL) { + rid += 4; /* 82599 maps in higher BAR */ + adapter->msix_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE); + } + if (adapter->msix_mem == NULL) { + /* May not be enabled */ + device_printf(adapter->dev, "Unable to map MSI-X table.\n"); + goto msi; + } + + /* Figure out a reasonable auto config value */ + queues = min(mp_ncpus, msgs - 1); + /* If we're doing RSS, clamp at the number of RSS buckets */ + if (adapter->feat_en & IXGBE_FEATURE_RSS) + queues = min(queues, rss_getnumbuckets()); + if (ixgbe_num_queues > queues) { + device_printf(adapter->dev, "ixgbe_num_queues (%d) is too large, using reduced amount (%d).\n", ixgbe_num_queues, queues); + ixgbe_num_queues = queues; + } + + if (ixgbe_num_queues != 0) + queues = ixgbe_num_queues; + /* Set max queues to 8 when autoconfiguring */ + else + queues = min(queues, 8); + + /* reflect correct sysctl value */ + ixgbe_num_queues = queues; + + /* + * Want one vector (RX/TX pair) per queue + * plus an additional for Link. + */ + want = queues + 1; + if (msgs >= want) + msgs = want; + else { + device_printf(adapter->dev, "MSI-X Configuration Problem, %d vectors but %d queues wanted!\n", + msgs, want); + goto msi; + } + if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) { + device_printf(adapter->dev, + "Using MSI-X interrupts with %d vectors\n", msgs); + adapter->num_queues = queues; + adapter->feat_en |= IXGBE_FEATURE_MSIX; + return (0); + } + /* + * MSI-X allocation failed or provided us with + * less vectors than needed. Free MSI-X resources + * and we'll try enabling MSI. + */ + pci_release_msi(dev); + +msi: + /* Without MSI-X, some features are no longer supported */ + adapter->feat_cap &= ~IXGBE_FEATURE_RSS; + adapter->feat_en &= ~IXGBE_FEATURE_RSS; + adapter->feat_cap &= ~IXGBE_FEATURE_SRIOV; + adapter->feat_en &= ~IXGBE_FEATURE_SRIOV; + + if (adapter->msix_mem != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, rid, + adapter->msix_mem); + adapter->msix_mem = NULL; + } + msgs = 1; + if (pci_alloc_msi(dev, &msgs) == 0) { + adapter->feat_en |= IXGBE_FEATURE_MSI; + adapter->link_rid = 1; + device_printf(adapter->dev, "Using an MSI interrupt\n"); + return (0); + } + + if (!(adapter->feat_cap & IXGBE_FEATURE_LEGACY_IRQ)) { + device_printf(adapter->dev, + "Device does not support legacy interrupts.\n"); + return 1; + } + + adapter->feat_en |= IXGBE_FEATURE_LEGACY_IRQ; + adapter->link_rid = 0; + device_printf(adapter->dev, "Using a Legacy interrupt\n"); + + return (0); +} /* ixgbe_configure_interrupts */ + + +/************************************************************************ + * ixgbe_handle_link - Tasklet for MSI-X Link interrupts + * + * Done outside of interrupt context since the driver might sleep + ************************************************************************/ +static void +ixgbe_handle_link(void *context, int pending) +{ + struct adapter *adapter = context; + struct ixgbe_hw *hw = &adapter->hw; + + ixgbe_check_link(hw, &adapter->link_speed, &adapter->link_up, 0); + ixgbe_update_link_status(adapter); + + /* Re-enable link interrupts */ + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_LSC); +} /* ixgbe_handle_link */ + +/************************************************************************ + * ixgbe_rearm_queues + ************************************************************************/ static void ixgbe_rearm_queues(struct adapter *adapter, u64 queues) { @@ -5271,6 +5258,7 @@ ixgbe_rearm_queues(struct adapter *adapter, u64 queues) case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: mask = (queues & 0xFFFFFFFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); mask = (queues >> 32); @@ -5279,724 +5267,5 @@ ixgbe_rearm_queues(struct adapter *adapter, u64 queues) default: break; } -} - -#ifdef PCI_IOV - -/* -** Support functions for SRIOV/VF management -*/ - -static void -ixgbe_ping_all_vfs(struct adapter *adapter) -{ - struct ixgbe_vf *vf; - - for (int i = 0; i < adapter->num_vfs; i++) { - vf = &adapter->vfs[i]; - if (vf->flags & IXGBE_VF_ACTIVE) - ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG); - } -} - - -static void -ixgbe_vf_set_default_vlan(struct adapter *adapter, struct ixgbe_vf *vf, - uint16_t tag) -{ - struct ixgbe_hw *hw; - uint32_t vmolr, vmvir; - - hw = &adapter->hw; - - vf->vlan_tag = tag; - - vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf->pool)); - - /* Do not receive packets that pass inexact filters. */ - vmolr &= ~(IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE); - - /* Disable Multicast Promicuous Mode. */ - vmolr &= ~IXGBE_VMOLR_MPE; - - /* Accept broadcasts. */ - vmolr |= IXGBE_VMOLR_BAM; - - if (tag == 0) { - /* Accept non-vlan tagged traffic. */ - //vmolr |= IXGBE_VMOLR_AUPE; - - /* Allow VM to tag outgoing traffic; no default tag. */ - vmvir = 0; - } else { - /* Require vlan-tagged traffic. */ - vmolr &= ~IXGBE_VMOLR_AUPE; - - /* Tag all traffic with provided vlan tag. */ - vmvir = (tag | IXGBE_VMVIR_VLANA_DEFAULT); - } - IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf->pool), vmolr); - IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf->pool), vmvir); -} - - -static boolean_t -ixgbe_vf_frame_size_compatible(struct adapter *adapter, struct ixgbe_vf *vf) -{ - - /* - * Frame size compatibility between PF and VF is only a problem on - * 82599-based cards. X540 and later support any combination of jumbo - * frames on PFs and VFs. - */ - if (adapter->hw.mac.type != ixgbe_mac_82599EB) - return (TRUE); - - switch (vf->api_ver) { - case IXGBE_API_VER_1_0: - case IXGBE_API_VER_UNKNOWN: - /* - * On legacy (1.0 and older) VF versions, we don't support jumbo - * frames on either the PF or the VF. - */ - if (adapter->max_frame_size > ETHER_MAX_LEN || - vf->max_frame_size > ETHER_MAX_LEN) - return (FALSE); - - return (TRUE); - - break; - case IXGBE_API_VER_1_1: - default: - /* - * 1.1 or later VF versions always work if they aren't using - * jumbo frames. - */ - if (vf->max_frame_size <= ETHER_MAX_LEN) - return (TRUE); - - /* - * Jumbo frames only work with VFs if the PF is also using jumbo - * frames. - */ - if (adapter->max_frame_size <= ETHER_MAX_LEN) - return (TRUE); - - return (FALSE); - - } -} - - -static void -ixgbe_process_vf_reset(struct adapter *adapter, struct ixgbe_vf *vf) -{ - ixgbe_vf_set_default_vlan(adapter, vf, vf->default_vlan); - - // XXX clear multicast addresses - - ixgbe_clear_rar(&adapter->hw, vf->rar_index); - - vf->api_ver = IXGBE_API_VER_UNKNOWN; -} - - -static void -ixgbe_vf_enable_transmit(struct adapter *adapter, struct ixgbe_vf *vf) -{ - struct ixgbe_hw *hw; - uint32_t vf_index, vfte; - - hw = &adapter->hw; - - vf_index = IXGBE_VF_INDEX(vf->pool); - vfte = IXGBE_READ_REG(hw, IXGBE_VFTE(vf_index)); - vfte |= IXGBE_VF_BIT(vf->pool); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_index), vfte); -} - - -static void -ixgbe_vf_enable_receive(struct adapter *adapter, struct ixgbe_vf *vf) -{ - struct ixgbe_hw *hw; - uint32_t vf_index, vfre; - - hw = &adapter->hw; - - vf_index = IXGBE_VF_INDEX(vf->pool); - vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(vf_index)); - if (ixgbe_vf_frame_size_compatible(adapter, vf)) - vfre |= IXGBE_VF_BIT(vf->pool); - else - vfre &= ~IXGBE_VF_BIT(vf->pool); - IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_index), vfre); -} - - -static void -ixgbe_vf_reset_msg(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) -{ - struct ixgbe_hw *hw; - uint32_t ack; - uint32_t resp[IXGBE_VF_PERMADDR_MSG_LEN]; - - hw = &adapter->hw; - - ixgbe_process_vf_reset(adapter, vf); - - if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) { - ixgbe_set_rar(&adapter->hw, vf->rar_index, - vf->ether_addr, vf->pool, TRUE); - ack = IXGBE_VT_MSGTYPE_ACK; - } else - ack = IXGBE_VT_MSGTYPE_NACK; - - ixgbe_vf_enable_transmit(adapter, vf); - ixgbe_vf_enable_receive(adapter, vf); - - vf->flags |= IXGBE_VF_CTS; - - resp[0] = IXGBE_VF_RESET | ack | IXGBE_VT_MSGTYPE_CTS; - bcopy(vf->ether_addr, &resp[1], ETHER_ADDR_LEN); - resp[3] = hw->mac.mc_filter_type; - ixgbe_write_mbx(hw, resp, IXGBE_VF_PERMADDR_MSG_LEN, vf->pool); -} - - -static void -ixgbe_vf_set_mac(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) -{ - uint8_t *mac; - - mac = (uint8_t*)&msg[1]; - - /* Check that the VF has permission to change the MAC address. */ - if (!(vf->flags & IXGBE_VF_CAP_MAC) && ixgbe_vf_mac_changed(vf, mac)) { - ixgbe_send_vf_nack(adapter, vf, msg[0]); - return; - } - - if (ixgbe_validate_mac_addr(mac) != 0) { - ixgbe_send_vf_nack(adapter, vf, msg[0]); - return; - } - - bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN); - - ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr, - vf->pool, TRUE); - - ixgbe_send_vf_ack(adapter, vf, msg[0]); -} - - -/* -** VF multicast addresses are set by using the appropriate bit in -** 1 of 128 32 bit addresses (4096 possible). -*/ -static void -ixgbe_vf_set_mc_addr(struct adapter *adapter, struct ixgbe_vf *vf, u32 *msg) -{ - u16 *list = (u16*)&msg[1]; - int entries; - u32 vmolr, vec_bit, vec_reg, mta_reg; - - entries = (msg[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; - entries = min(entries, IXGBE_MAX_VF_MC); - - vmolr = IXGBE_READ_REG(&adapter->hw, IXGBE_VMOLR(vf->pool)); - - vf->num_mc_hashes = entries; - - /* Set the appropriate MTA bit */ - for (int i = 0; i < entries; i++) { - vf->mc_hash[i] = list[i]; - vec_reg = (vf->mc_hash[i] >> 5) & 0x7F; - vec_bit = vf->mc_hash[i] & 0x1F; - mta_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_MTA(vec_reg)); - mta_reg |= (1 << vec_bit); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_MTA(vec_reg), mta_reg); - } - - vmolr |= IXGBE_VMOLR_ROMPE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_VMOLR(vf->pool), vmolr); - ixgbe_send_vf_ack(adapter, vf, msg[0]); - return; -} - - -static void -ixgbe_vf_set_vlan(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) -{ - struct ixgbe_hw *hw; - int enable; - uint16_t tag; - - hw = &adapter->hw; - enable = IXGBE_VT_MSGINFO(msg[0]); - tag = msg[1] & IXGBE_VLVF_VLANID_MASK; - - if (!(vf->flags & IXGBE_VF_CAP_VLAN)) { - ixgbe_send_vf_nack(adapter, vf, msg[0]); - return; - } - - /* It is illegal to enable vlan tag 0. */ - if (tag == 0 && enable != 0){ - ixgbe_send_vf_nack(adapter, vf, msg[0]); - return; - } - - ixgbe_set_vfta(hw, tag, vf->pool, enable); - ixgbe_send_vf_ack(adapter, vf, msg[0]); -} - - -static void -ixgbe_vf_set_lpe(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) -{ - struct ixgbe_hw *hw; - uint32_t vf_max_size, pf_max_size, mhadd; - - hw = &adapter->hw; - vf_max_size = msg[1]; - - if (vf_max_size < ETHER_CRC_LEN) { - /* We intentionally ACK invalid LPE requests. */ - ixgbe_send_vf_ack(adapter, vf, msg[0]); - return; - } - - vf_max_size -= ETHER_CRC_LEN; - - if (vf_max_size > IXGBE_MAX_FRAME_SIZE) { - /* We intentionally ACK invalid LPE requests. */ - ixgbe_send_vf_ack(adapter, vf, msg[0]); - return; - } - - vf->max_frame_size = vf_max_size; - ixgbe_update_max_frame(adapter, vf->max_frame_size); - - /* - * We might have to disable reception to this VF if the frame size is - * not compatible with the config on the PF. - */ - ixgbe_vf_enable_receive(adapter, vf); - - mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); - pf_max_size = (mhadd & IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT; - - if (pf_max_size < adapter->max_frame_size) { - mhadd &= ~IXGBE_MHADD_MFS_MASK; - mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT; - IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); - } - - ixgbe_send_vf_ack(adapter, vf, msg[0]); -} - - -static void -ixgbe_vf_set_macvlan(struct adapter *adapter, struct ixgbe_vf *vf, - uint32_t *msg) -{ - //XXX implement this - ixgbe_send_vf_nack(adapter, vf, msg[0]); -} - - -static void -ixgbe_vf_api_negotiate(struct adapter *adapter, struct ixgbe_vf *vf, - uint32_t *msg) -{ - - switch (msg[1]) { - case IXGBE_API_VER_1_0: - case IXGBE_API_VER_1_1: - vf->api_ver = msg[1]; - ixgbe_send_vf_ack(adapter, vf, msg[0]); - break; - default: - vf->api_ver = IXGBE_API_VER_UNKNOWN; - ixgbe_send_vf_nack(adapter, vf, msg[0]); - break; - } -} - - -static void -ixgbe_vf_get_queues(struct adapter *adapter, struct ixgbe_vf *vf, - uint32_t *msg) -{ - struct ixgbe_hw *hw; - uint32_t resp[IXGBE_VF_GET_QUEUES_RESP_LEN]; - int num_queues; - - hw = &adapter->hw; - - /* GET_QUEUES is not supported on pre-1.1 APIs. */ - switch (msg[0]) { - case IXGBE_API_VER_1_0: - case IXGBE_API_VER_UNKNOWN: - ixgbe_send_vf_nack(adapter, vf, msg[0]); - return; - } - - resp[0] = IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_ACK | - IXGBE_VT_MSGTYPE_CTS; - - num_queues = ixgbe_vf_queues(ixgbe_get_iov_mode(adapter)); - resp[IXGBE_VF_TX_QUEUES] = num_queues; - resp[IXGBE_VF_RX_QUEUES] = num_queues; - resp[IXGBE_VF_TRANS_VLAN] = (vf->default_vlan != 0); - resp[IXGBE_VF_DEF_QUEUE] = 0; - - ixgbe_write_mbx(hw, resp, IXGBE_VF_GET_QUEUES_RESP_LEN, vf->pool); -} - - -static void -ixgbe_process_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf) -{ - struct ixgbe_hw *hw; - uint32_t msg[IXGBE_VFMAILBOX_SIZE]; - int error; - - hw = &adapter->hw; - - error = ixgbe_read_mbx(hw, msg, IXGBE_VFMAILBOX_SIZE, vf->pool); - - if (error != 0) - return; - - CTR3(KTR_MALLOC, "%s: received msg %x from %d", - adapter->ifp->if_xname, msg[0], vf->pool); - if (msg[0] == IXGBE_VF_RESET) { - ixgbe_vf_reset_msg(adapter, vf, msg); - return; - } - - if (!(vf->flags & IXGBE_VF_CTS)) { - ixgbe_send_vf_nack(adapter, vf, msg[0]); - return; - } - - switch (msg[0] & IXGBE_VT_MSG_MASK) { - case IXGBE_VF_SET_MAC_ADDR: - ixgbe_vf_set_mac(adapter, vf, msg); - break; - case IXGBE_VF_SET_MULTICAST: - ixgbe_vf_set_mc_addr(adapter, vf, msg); - break; - case IXGBE_VF_SET_VLAN: - ixgbe_vf_set_vlan(adapter, vf, msg); - break; - case IXGBE_VF_SET_LPE: - ixgbe_vf_set_lpe(adapter, vf, msg); - break; - case IXGBE_VF_SET_MACVLAN: - ixgbe_vf_set_macvlan(adapter, vf, msg); - break; - case IXGBE_VF_API_NEGOTIATE: - ixgbe_vf_api_negotiate(adapter, vf, msg); - break; - case IXGBE_VF_GET_QUEUES: - ixgbe_vf_get_queues(adapter, vf, msg); - break; - default: - ixgbe_send_vf_nack(adapter, vf, msg[0]); - } -} - - -/* - * Tasklet for handling VF -> PF mailbox messages. - */ -static void -ixgbe_handle_mbx(void *context, int pending) -{ - struct adapter *adapter; - struct ixgbe_hw *hw; - struct ixgbe_vf *vf; - int i; - - adapter = context; - hw = &adapter->hw; - - IXGBE_CORE_LOCK(adapter); - for (i = 0; i < adapter->num_vfs; i++) { - vf = &adapter->vfs[i]; - - if (vf->flags & IXGBE_VF_ACTIVE) { - if (ixgbe_check_for_rst(hw, vf->pool) == 0) - ixgbe_process_vf_reset(adapter, vf); - - if (ixgbe_check_for_msg(hw, vf->pool) == 0) - ixgbe_process_vf_msg(adapter, vf); - - if (ixgbe_check_for_ack(hw, vf->pool) == 0) - ixgbe_process_vf_ack(adapter, vf); - } - } - IXGBE_CORE_UNLOCK(adapter); -} - - -static int -ixgbe_init_iov(device_t dev, u16 num_vfs, const nvlist_t *config) -{ - struct adapter *adapter; - enum ixgbe_iov_mode mode; - - adapter = device_get_softc(dev); - adapter->num_vfs = num_vfs; - mode = ixgbe_get_iov_mode(adapter); - - if (num_vfs > ixgbe_max_vfs(mode)) { - adapter->num_vfs = 0; - return (ENOSPC); - } - - IXGBE_CORE_LOCK(adapter); - - adapter->vfs = malloc(sizeof(*adapter->vfs) * num_vfs, M_IXGBE, - M_NOWAIT | M_ZERO); - - if (adapter->vfs == NULL) { - adapter->num_vfs = 0; - IXGBE_CORE_UNLOCK(adapter); - return (ENOMEM); - } - - ixgbe_init_locked(adapter); - - IXGBE_CORE_UNLOCK(adapter); - - return (0); -} - - -static void -ixgbe_uninit_iov(device_t dev) -{ - struct ixgbe_hw *hw; - struct adapter *adapter; - uint32_t pf_reg, vf_reg; - - adapter = device_get_softc(dev); - hw = &adapter->hw; - - IXGBE_CORE_LOCK(adapter); - - /* Enable rx/tx for the PF and disable it for all VFs. */ - pf_reg = IXGBE_VF_INDEX(adapter->pool); - IXGBE_WRITE_REG(hw, IXGBE_VFRE(pf_reg), - IXGBE_VF_BIT(adapter->pool)); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(pf_reg), - IXGBE_VF_BIT(adapter->pool)); - - if (pf_reg == 0) - vf_reg = 1; - else - vf_reg = 0; - IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), 0); - - IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0); - - free(adapter->vfs, M_IXGBE); - adapter->vfs = NULL; - adapter->num_vfs = 0; - - IXGBE_CORE_UNLOCK(adapter); -} - - -static void -ixgbe_initialize_iov(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - uint32_t mrqc, mtqc, vt_ctl, vf_reg, gcr_ext, gpie; - enum ixgbe_iov_mode mode; - int i; - - mode = ixgbe_get_iov_mode(adapter); - if (mode == IXGBE_NO_VM) - return; - - IXGBE_CORE_LOCK_ASSERT(adapter); - - mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC); - mrqc &= ~IXGBE_MRQC_MRQE_MASK; - - switch (mode) { - case IXGBE_64_VM: - mrqc |= IXGBE_MRQC_VMDQRSS64EN; - break; - case IXGBE_32_VM: - mrqc |= IXGBE_MRQC_VMDQRSS32EN; - break; - default: - panic("Unexpected SR-IOV mode %d", mode); - } - IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); - - mtqc = IXGBE_MTQC_VT_ENA; - switch (mode) { - case IXGBE_64_VM: - mtqc |= IXGBE_MTQC_64VF; - break; - case IXGBE_32_VM: - mtqc |= IXGBE_MTQC_32VF; - break; - default: - panic("Unexpected SR-IOV mode %d", mode); - } - IXGBE_WRITE_REG(hw, IXGBE_MTQC, mtqc); - - - gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); - gcr_ext |= IXGBE_GCR_EXT_MSIX_EN; - gcr_ext &= ~IXGBE_GCR_EXT_VT_MODE_MASK; - switch (mode) { - case IXGBE_64_VM: - gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64; - break; - case IXGBE_32_VM: - gcr_ext |= IXGBE_GCR_EXT_VT_MODE_32; - break; - default: - panic("Unexpected SR-IOV mode %d", mode); - } - IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); - - - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); - gcr_ext &= ~IXGBE_GPIE_VTMODE_MASK; - switch (mode) { - case IXGBE_64_VM: - gpie |= IXGBE_GPIE_VTMODE_64; - break; - case IXGBE_32_VM: - gpie |= IXGBE_GPIE_VTMODE_32; - break; - default: - panic("Unexpected SR-IOV mode %d", mode); - } - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - - /* Enable rx/tx for the PF. */ - vf_reg = IXGBE_VF_INDEX(adapter->pool); - IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), - IXGBE_VF_BIT(adapter->pool)); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), - IXGBE_VF_BIT(adapter->pool)); - - /* Allow VM-to-VM communication. */ - IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); - - vt_ctl = IXGBE_VT_CTL_VT_ENABLE | IXGBE_VT_CTL_REPLEN; - vt_ctl |= (adapter->pool << IXGBE_VT_CTL_POOL_SHIFT); - IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vt_ctl); - - for (i = 0; i < adapter->num_vfs; i++) - ixgbe_init_vf(adapter, &adapter->vfs[i]); -} - - -/* -** Check the max frame setting of all active VF's -*/ -static void -ixgbe_recalculate_max_frame(struct adapter *adapter) -{ - struct ixgbe_vf *vf; - - IXGBE_CORE_LOCK_ASSERT(adapter); - - for (int i = 0; i < adapter->num_vfs; i++) { - vf = &adapter->vfs[i]; - if (vf->flags & IXGBE_VF_ACTIVE) - ixgbe_update_max_frame(adapter, vf->max_frame_size); - } -} - - -static void -ixgbe_init_vf(struct adapter *adapter, struct ixgbe_vf *vf) -{ - struct ixgbe_hw *hw; - uint32_t vf_index, pfmbimr; - - IXGBE_CORE_LOCK_ASSERT(adapter); - - hw = &adapter->hw; - - if (!(vf->flags & IXGBE_VF_ACTIVE)) - return; - - vf_index = IXGBE_VF_INDEX(vf->pool); - pfmbimr = IXGBE_READ_REG(hw, IXGBE_PFMBIMR(vf_index)); - pfmbimr |= IXGBE_VF_BIT(vf->pool); - IXGBE_WRITE_REG(hw, IXGBE_PFMBIMR(vf_index), pfmbimr); - - ixgbe_vf_set_default_vlan(adapter, vf, vf->vlan_tag); - - // XXX multicast addresses - - if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) { - ixgbe_set_rar(&adapter->hw, vf->rar_index, - vf->ether_addr, vf->pool, TRUE); - } - - ixgbe_vf_enable_transmit(adapter, vf); - ixgbe_vf_enable_receive(adapter, vf); - - ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG); -} - -static int -ixgbe_add_vf(device_t dev, u16 vfnum, const nvlist_t *config) -{ - struct adapter *adapter; - struct ixgbe_vf *vf; - const void *mac; - - adapter = device_get_softc(dev); - - KASSERT(vfnum < adapter->num_vfs, ("VF index %d is out of range %d", - vfnum, adapter->num_vfs)); - - IXGBE_CORE_LOCK(adapter); - vf = &adapter->vfs[vfnum]; - vf->pool= vfnum; - - /* RAR[0] is used by the PF so use vfnum + 1 for VF RAR. */ - vf->rar_index = vfnum + 1; - vf->default_vlan = 0; - vf->max_frame_size = ETHER_MAX_LEN; - ixgbe_update_max_frame(adapter, vf->max_frame_size); - - if (nvlist_exists_binary(config, "mac-addr")) { - mac = nvlist_get_binary(config, "mac-addr", NULL); - bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN); - if (nvlist_get_bool(config, "allow-set-mac")) - vf->flags |= IXGBE_VF_CAP_MAC; - } else - /* - * If the administrator has not specified a MAC address then - * we must allow the VF to choose one. - */ - vf->flags |= IXGBE_VF_CAP_MAC; - - vf->flags |= IXGBE_VF_ACTIVE; - - ixgbe_init_vf(adapter, vf); - IXGBE_CORE_UNLOCK(adapter); - - return (0); -} -#endif /* PCI_IOV */ +} /* ixgbe_rearm_queues */ diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c index 80fb1b34be31..1e5d04289d06 100644 --- a/sys/dev/ixgbe/if_ixv.c +++ b/sys/dev/ixgbe/if_ixv.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -40,108 +40,96 @@ #include "ixgbe.h" -/********************************************************************* - * Driver version - *********************************************************************/ -char ixv_driver_version[] = "1.4.6-k"; +/************************************************************************ + * Driver version + ************************************************************************/ +char ixv_driver_version[] = "1.5.13-k"; -/********************************************************************* - * PCI Device ID Table +/************************************************************************ + * PCI Device ID Table * - * Used by probe to select devices to load on - * Last field stores an index into ixv_strings - * Last entry must be all 0s + * Used by probe to select devices to load on + * Last field stores an index into ixv_strings + * Last entry must be all 0s * - * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index } - *********************************************************************/ - + * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index } + ************************************************************************/ static ixgbe_vendor_info_t ixv_vendor_info_array[] = { {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_VF, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; -/********************************************************************* - * Table of branding strings - *********************************************************************/ - -static char *ixv_strings[] = { +/************************************************************************ + * Table of branding strings + ************************************************************************/ +static char *ixv_strings[] = { "Intel(R) PRO/10GbE Virtual Function Network Driver" }; -/********************************************************************* - * Function prototypes - *********************************************************************/ +/************************************************************************ + * Function prototypes + ************************************************************************/ static int ixv_probe(device_t); static int ixv_attach(device_t); static int ixv_detach(device_t); static int ixv_shutdown(device_t); static int ixv_ioctl(struct ifnet *, u_long, caddr_t); -static void ixv_init(void *); -static void ixv_init_locked(struct adapter *); +static void ixv_init(void *); +static void ixv_init_locked(struct adapter *); static void ixv_stop(void *); +static uint64_t ixv_get_counter(struct ifnet *, ift_counter); +static void ixv_init_device_features(struct adapter *); static void ixv_media_status(struct ifnet *, struct ifmediareq *); static int ixv_media_change(struct ifnet *); -static void ixv_identify_hardware(struct adapter *); static int ixv_allocate_pci_resources(struct adapter *); static int ixv_allocate_msix(struct adapter *); -static int ixv_setup_msix(struct adapter *); -static void ixv_free_pci_resources(struct adapter *); +static int ixv_configure_interrupts(struct adapter *); +static void ixv_free_pci_resources(struct adapter *); static void ixv_local_timer(void *); static void ixv_setup_interface(device_t, struct adapter *); -static void ixv_config_link(struct adapter *); static void ixv_initialize_transmit_units(struct adapter *); static void ixv_initialize_receive_units(struct adapter *); +static void ixv_initialize_rss_mapping(struct adapter *); +static void ixv_check_link(struct adapter *); static void ixv_enable_intr(struct adapter *); static void ixv_disable_intr(struct adapter *); static void ixv_set_multi(struct adapter *); static void ixv_update_link_status(struct adapter *); -static int ixv_sysctl_debug(SYSCTL_HANDLER_ARGS); -static void ixv_set_ivar(struct adapter *, u8, u8, s8); -static void ixv_configure_ivars(struct adapter *); -static u8 * ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); +static int ixv_sysctl_debug(SYSCTL_HANDLER_ARGS); +static void ixv_set_ivar(struct adapter *, u8, u8, s8); +static void ixv_configure_ivars(struct adapter *); +static u8 *ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); -static void ixv_setup_vlan_support(struct adapter *); -static void ixv_register_vlan(void *, struct ifnet *, u16); -static void ixv_unregister_vlan(void *, struct ifnet *, u16); +static void ixv_setup_vlan_support(struct adapter *); +static void ixv_register_vlan(void *, struct ifnet *, u16); +static void ixv_unregister_vlan(void *, struct ifnet *, u16); -static void ixv_save_stats(struct adapter *); -static void ixv_init_stats(struct adapter *); -static void ixv_update_stats(struct adapter *); -static void ixv_add_stats_sysctls(struct adapter *); -static void ixv_set_sysctl_value(struct adapter *, const char *, - const char *, int *, int); +static void ixv_save_stats(struct adapter *); +static void ixv_init_stats(struct adapter *); +static void ixv_update_stats(struct adapter *); +static void ixv_add_stats_sysctls(struct adapter *); +static void ixv_set_sysctl_value(struct adapter *, const char *, + const char *, int *, int); -/* The MSI/X Interrupt handlers */ -static void ixv_msix_que(void *); -static void ixv_msix_mbx(void *); +/* The MSI-X Interrupt handlers */ +static void ixv_msix_que(void *); +static void ixv_msix_mbx(void *); /* Deferred interrupt tasklets */ -static void ixv_handle_que(void *, int); -static void ixv_handle_mbx(void *, int); - -#ifdef DEV_NETMAP -/* - * This is defined in , which is included by - * if_ix.c. - */ -extern void ixgbe_netmap_attach(struct adapter *adapter); - -#include -#include -#include -#endif /* DEV_NETMAP */ - -/********************************************************************* - * FreeBSD Device Interface Entry Points - *********************************************************************/ +static void ixv_handle_que(void *, int); +static void ixv_handle_link(void *, int); +/************************************************************************ + * FreeBSD Device Interface Entry Points + ************************************************************************/ static device_method_t ixv_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ixv_probe), @@ -159,25 +147,22 @@ devclass_t ixv_devclass; DRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0); MODULE_DEPEND(ixv, pci, 1, 1, 1); MODULE_DEPEND(ixv, ether, 1, 1, 1); -#ifdef DEV_NETMAP -MODULE_DEPEND(ix, netmap, 1, 1, 1); -#endif /* DEV_NETMAP */ -/* XXX depend on 'ix' ? */ +MODULE_DEPEND(ixv, netmap, 1, 1, 1); /* -** TUNEABLE PARAMETERS: -*/ + * TUNEABLE PARAMETERS: + */ -/* Number of Queues - do not exceed MSIX vectors - 1 */ +/* Number of Queues - do not exceed MSI-X vectors - 1 */ static int ixv_num_queues = 1; TUNABLE_INT("hw.ixv.num_queues", &ixv_num_queues); /* -** AIM: Adaptive Interrupt Moderation -** which means that the interrupt rate -** is varied over time based on the -** traffic for that interrupt vector -*/ + * AIM: Adaptive Interrupt Moderation + * which means that the interrupt rate + * is varied over time based on the + * traffic for that interrupt vector + */ static int ixv_enable_aim = FALSE; TUNABLE_INT("hw.ixv.enable_aim", &ixv_enable_aim); @@ -203,10 +188,10 @@ static int ixv_header_split = FALSE; TUNABLE_INT("hw.ixv.hdr_split", &ixv_header_split); /* -** Number of TX descriptors per ring, -** setting higher than RX as this seems -** the better performing choice. -*/ + * Number of TX descriptors per ring, + * setting higher than RX as this seems + * the better performing choice. + */ static int ixv_txd = DEFAULT_TXD; TUNABLE_INT("hw.ixv.txd", &ixv_txd); @@ -214,32 +199,37 @@ TUNABLE_INT("hw.ixv.txd", &ixv_txd); static int ixv_rxd = DEFAULT_RXD; TUNABLE_INT("hw.ixv.rxd", &ixv_rxd); +/* Legacy Transmit (single queue) */ +static int ixv_enable_legacy_tx = 0; +TUNABLE_INT("hw.ixv.enable_legacy_tx", &ixv_enable_legacy_tx); + /* -** Shadow VFTA table, this is needed because -** the real filter table gets cleared during -** a soft reset and we need to repopulate it. -*/ + * Shadow VFTA table, this is needed because + * the real filter table gets cleared during + * a soft reset and we need to repopulate it. + */ static u32 ixv_shadow_vfta[IXGBE_VFTA_SIZE]; -/********************************************************************* - * Device identification routine - * - * ixv_probe determines if the driver should be loaded on - * adapter based on PCI vendor/device id of the adapter. - * - * return BUS_PROBE_DEFAULT on success, positive on failure - *********************************************************************/ +static int (*ixv_start_locked)(struct ifnet *, struct tx_ring *); +static int (*ixv_ring_empty)(struct ifnet *, struct buf_ring *); +/************************************************************************ + * ixv_probe - Device identification routine + * + * Determines if the driver should be loaded on + * adapter based on its PCI vendor/device ID. + * + * return BUS_PROBE_DEFAULT on success, positive on failure + ************************************************************************/ static int ixv_probe(device_t dev) { ixgbe_vendor_info_t *ent; - - u16 pci_vendor_id = 0; - u16 pci_device_id = 0; - u16 pci_subvendor_id = 0; - u16 pci_subdevice_id = 0; - char adapter_name[256]; + u16 pci_vendor_id = 0; + u16 pci_device_id = 0; + u16 pci_subvendor_id = 0; + u16 pci_subdevice_id = 0; + char adapter_name[256]; pci_vendor_id = pci_get_vendor(dev); @@ -254,72 +244,57 @@ ixv_probe(device_t dev) while (ent->vendor_id != 0) { if ((pci_vendor_id == ent->vendor_id) && (pci_device_id == ent->device_id) && - ((pci_subvendor_id == ent->subvendor_id) || (ent->subvendor_id == 0)) && - ((pci_subdevice_id == ent->subdevice_id) || (ent->subdevice_id == 0))) { sprintf(adapter_name, "%s, Version - %s", - ixv_strings[ent->index], - ixv_driver_version); + ixv_strings[ent->index], ixv_driver_version); device_set_desc_copy(dev, adapter_name); return (BUS_PROBE_DEFAULT); } ent++; } + return (ENXIO); -} +} /* ixv_probe */ -/********************************************************************* - * Device initialization routine +/************************************************************************ + * ixv_attach - Device initialization routine * - * The attach entry point is called when the driver is being loaded. - * This routine identifies the type of hardware, allocates all resources - * and initializes the hardware. + * Called when the driver is being loaded. + * Identifies the type of hardware, allocates all resources + * and initializes the hardware. * - * return 0 on success, positive on failure - *********************************************************************/ - + * return 0 on success, positive on failure + ************************************************************************/ static int ixv_attach(device_t dev) { - struct adapter *adapter; + struct adapter *adapter; struct ixgbe_hw *hw; int error = 0; INIT_DEBUGOUT("ixv_attach: begin"); + /* + * Make sure BUSMASTER is set, on a VM under + * KVM it may not be and will break things. + */ + pci_enable_busmaster(dev); + /* Allocate, clear, and link in our adapter structure */ adapter = device_get_softc(dev); adapter->dev = dev; + adapter->hw.back = adapter; hw = &adapter->hw; -#ifdef DEV_NETMAP adapter->init_locked = ixv_init_locked; adapter->stop_locked = ixv_stop; -#endif /* Core Lock Init*/ IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); - /* SYSCTL APIs */ - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW, - adapter, 0, ixv_sysctl_debug, "I", "Debug Info"); - - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "enable_aim", CTLFLAG_RW, - &ixv_enable_aim, 1, "Interrupt Moderation"); - - /* Set up the timer callout */ - callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); - - /* Determine hardware revision */ - ixv_identify_hardware(adapter); - /* Do base PCI setup - map BAR0 */ if (ixv_allocate_pci_resources(adapter)) { device_printf(dev, "ixv_allocate_pci_resources() failed!\n"); @@ -327,6 +302,112 @@ ixv_attach(device_t dev) goto err_out; } + /* SYSCTL APIs */ + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixv_sysctl_debug, "I", + "Debug Info"); + + SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "enable_aim", CTLFLAG_RW, &ixv_enable_aim, 1, + "Interrupt Moderation"); + + /* Set up the timer callout */ + callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); + + /* Save off the information about this board */ + hw->vendor_id = pci_get_vendor(dev); + hw->device_id = pci_get_device(dev); + hw->revision_id = pci_get_revid(dev); + hw->subsystem_vendor_id = pci_get_subvendor(dev); + hw->subsystem_device_id = pci_get_subdevice(dev); + + /* A subset of set_mac_type */ + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_VF: + hw->mac.type = ixgbe_mac_82599_vf; + break; + case IXGBE_DEV_ID_X540_VF: + hw->mac.type = ixgbe_mac_X540_vf; + break; + case IXGBE_DEV_ID_X550_VF: + hw->mac.type = ixgbe_mac_X550_vf; + break; + case IXGBE_DEV_ID_X550EM_X_VF: + hw->mac.type = ixgbe_mac_X550EM_x_vf; + break; + case IXGBE_DEV_ID_X550EM_A_VF: + hw->mac.type = ixgbe_mac_X550EM_a_vf; + break; + default: + /* Shouldn't get here since probe succeeded */ + device_printf(dev, "Unknown device ID!\n"); + error = ENXIO; + goto err_out; + break; + } + + ixv_init_device_features(adapter); + + /* Initialize the shared code */ + error = ixgbe_init_ops_vf(hw); + if (error) { + device_printf(dev, "ixgbe_init_ops_vf() failed!\n"); + error = EIO; + goto err_out; + } + + /* Setup the mailbox */ + ixgbe_init_mbx_params_vf(hw); + + /* Set the right number of segments */ + adapter->num_segs = IXGBE_82599_SCATTER; + + error = hw->mac.ops.reset_hw(hw); + if (error == IXGBE_ERR_RESET_FAILED) + device_printf(dev, "...reset_hw() failure: Reset Failed!\n"); + else if (error) + device_printf(dev, "...reset_hw() failed with error %d\n", + error); + if (error) { + error = EIO; + goto err_out; + } + + error = hw->mac.ops.init_hw(hw); + if (error) { + device_printf(dev, "...init_hw() failed with error %d\n", + error); + error = EIO; + goto err_out; + } + + /* Negotiate mailbox API version */ + error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12); + if (error) { + device_printf(dev, "MBX API 1.2 negotiation failed! Error %d\n", + error); + error = EIO; + goto err_out; + } + + /* If no mac address was assigned, make a random one */ + if (!ixv_check_ether_addr(hw->mac.addr)) { + u8 addr[ETHER_ADDR_LEN]; + arc4rand(&addr, sizeof(addr), 0); + addr[0] &= 0xFE; + addr[0] |= 0x02; + bcopy(addr, hw->mac.addr, sizeof(addr)); + bcopy(addr, hw->mac.perm_addr, sizeof(addr)); + } + + /* Register for VLAN events */ + adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, + ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); + adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, + ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); + /* Sysctls for limiting the amount of work done in the taskqueues */ ixv_set_sysctl_value(adapter, "rx_processing_limit", "max number of rx packets to process", @@ -351,6 +432,11 @@ ixv_attach(device_t dev) } else adapter->num_rx_desc = ixv_rxd; + /* Setup MSI-X */ + error = ixv_configure_interrupts(adapter); + if (error) + goto err_out; + /* Allocate our TX/RX Queues */ if (ixgbe_allocate_queues(adapter)) { device_printf(dev, "ixgbe_allocate_queues() failed!\n"); @@ -358,104 +444,51 @@ ixv_attach(device_t dev) goto err_out; } - /* - ** Initialize the shared code: its - ** at this point the mac type is set. - */ - error = ixgbe_init_shared_code(hw); - if (error) { - device_printf(dev, "ixgbe_init_shared_code() failed!\n"); - error = EIO; - goto err_late; - } + /* Setup OS specific network interface */ + ixv_setup_interface(dev, adapter); - /* Setup the mailbox */ - ixgbe_init_mbx_params_vf(hw); - - /* Reset mbox api to 1.0 */ - error = ixgbe_reset_hw(hw); - if (error == IXGBE_ERR_RESET_FAILED) - device_printf(dev, "ixgbe_reset_hw() failure: Reset Failed!\n"); - else if (error) - device_printf(dev, "ixgbe_reset_hw() failed with error %d\n", error); - if (error) { - error = EIO; - goto err_late; - } - - /* Negotiate mailbox API version */ - error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11); - if (error) { - device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error); - error = EIO; - goto err_late; - } - - error = ixgbe_init_hw(hw); - if (error) { - device_printf(dev, "ixgbe_init_hw() failed!\n"); - error = EIO; - goto err_late; - } - - error = ixv_allocate_msix(adapter); + error = ixv_allocate_msix(adapter); if (error) { device_printf(dev, "ixv_allocate_msix() failed!\n"); goto err_late; } - /* If no mac address was assigned, make a random one */ - if (!ixv_check_ether_addr(hw->mac.addr)) { - u8 addr[ETHER_ADDR_LEN]; - arc4rand(&addr, sizeof(addr), 0); - addr[0] &= 0xFE; - addr[0] |= 0x02; - bcopy(addr, hw->mac.addr, sizeof(addr)); - } - - /* Setup OS specific network interface */ - ixv_setup_interface(dev, adapter); - /* Do the stats setup */ ixv_save_stats(adapter); ixv_init_stats(adapter); ixv_add_stats_sysctls(adapter); - /* Register for VLAN events */ - adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, - ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); - adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, - ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); + if (adapter->feat_en & IXGBE_FEATURE_NETMAP) + ixgbe_netmap_attach(adapter); -#ifdef DEV_NETMAP - ixgbe_netmap_attach(adapter); -#endif /* DEV_NETMAP */ INIT_DEBUGOUT("ixv_attach: end"); + return (0); err_late: ixgbe_free_transmit_structures(adapter); ixgbe_free_receive_structures(adapter); + free(adapter->queues, M_DEVBUF); err_out: ixv_free_pci_resources(adapter); + IXGBE_CORE_LOCK_DESTROY(adapter); + return (error); +} /* ixv_attach */ -} - -/********************************************************************* - * Device removal routine +/************************************************************************ + * ixv_detach - Device removal routine * - * The detach entry point is called when the driver is being removed. - * This routine stops the adapter and deallocates all the resources - * that were allocated for driver operation. + * Called when the driver is being removed. + * Stops the adapter and deallocates all the resources + * that were allocated for driver operation. * - * return 0 on success, positive on failure - *********************************************************************/ - + * return 0 on success, positive on failure + ************************************************************************/ static int ixv_detach(device_t dev) { - struct adapter *adapter = device_get_softc(dev); + struct adapter *adapter = device_get_softc(dev); struct ix_queue *que = adapter->queues; INIT_DEBUGOUT("ixv_detach: begin"); @@ -466,6 +499,7 @@ ixv_detach(device_t dev) return (EBUSY); } + ether_ifdetach(adapter->ifp); IXGBE_CORE_LOCK(adapter); ixv_stop(adapter); IXGBE_CORE_UNLOCK(adapter); @@ -491,27 +525,1544 @@ ixv_detach(device_t dev) if (adapter->vlan_detach != NULL) EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); - ether_ifdetach(adapter->ifp); callout_drain(&adapter->timer); -#ifdef DEV_NETMAP - netmap_detach(adapter->ifp); -#endif /* DEV_NETMAP */ + + if (adapter->feat_en & IXGBE_FEATURE_NETMAP) + netmap_detach(adapter->ifp); + ixv_free_pci_resources(adapter); bus_generic_detach(dev); if_free(adapter->ifp); ixgbe_free_transmit_structures(adapter); ixgbe_free_receive_structures(adapter); + free(adapter->queues, M_DEVBUF); IXGBE_CORE_LOCK_DESTROY(adapter); + return (0); +} /* ixv_detach */ + +/************************************************************************ + * ixv_init_locked - Init entry point + * + * Used in two ways: It is used by the stack as an init entry + * point in network interface structure. It is also used + * by the driver as a hw/sw initialization routine to get + * to a consistent state. + * + * return 0 on success, positive on failure + ************************************************************************/ +void +ixv_init_locked(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; + int error = 0; + + INIT_DEBUGOUT("ixv_init_locked: begin"); + mtx_assert(&adapter->core_mtx, MA_OWNED); + hw->adapter_stopped = FALSE; + hw->mac.ops.stop_adapter(hw); + callout_stop(&adapter->timer); + + /* reprogram the RAR[0] in case user changed it. */ + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); + + /* Get the latest mac address, User can use a LAA */ + bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr, + IXGBE_ETH_LENGTH_OF_ADDRESS); + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, 1); + + /* Prepare transmit descriptors and buffers */ + if (ixgbe_setup_transmit_structures(adapter)) { + device_printf(dev, "Could not setup transmit structures\n"); + ixv_stop(adapter); + return; + } + + /* Reset VF and renegotiate mailbox API version */ + hw->mac.ops.reset_hw(hw); + error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12); + if (error) + device_printf(dev, "MBX API 1.2 negotiation failed! Error %d\n", + error); + + ixv_initialize_transmit_units(adapter); + + /* Setup Multicast table */ + ixv_set_multi(adapter); + + /* + * Determine the correct mbuf pool + * for doing jumbo/headersplit + */ + if (ifp->if_mtu > ETHERMTU) + adapter->rx_mbuf_sz = MJUMPAGESIZE; + else + adapter->rx_mbuf_sz = MCLBYTES; + + /* Prepare receive descriptors and buffers */ + if (ixgbe_setup_receive_structures(adapter)) { + device_printf(dev, "Could not setup receive structures\n"); + ixv_stop(adapter); + return; + } + + /* Configure RX settings */ + ixv_initialize_receive_units(adapter); + + /* Set the various hardware offload abilities */ + ifp->if_hwassist = 0; + if (ifp->if_capenable & IFCAP_TSO4) + ifp->if_hwassist |= CSUM_TSO; + if (ifp->if_capenable & IFCAP_TXCSUM) { + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); +#if __FreeBSD_version >= 800000 + ifp->if_hwassist |= CSUM_SCTP; +#endif + } + + /* Set up VLAN offload and filter */ + ixv_setup_vlan_support(adapter); + + /* Set up MSI-X routing */ + ixv_configure_ivars(adapter); + + /* Set up auto-mask */ + IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, IXGBE_EICS_RTX_QUEUE); + + /* Set moderation on the Link interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR); + + /* Stats init */ + ixv_init_stats(adapter); + + /* Config/Enable Link */ + hw->mac.ops.check_link(hw, &adapter->link_speed, &adapter->link_up, + FALSE); + + /* Start watchdog */ + callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); + + /* And now turn on interrupts */ + ixv_enable_intr(adapter); + + /* Now inform the stack we're ready */ + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + return; +} /* ixv_init_locked */ + +/* + * MSI-X Interrupt Handlers and Tasklets + */ + +static inline void +ixv_enable_queue(struct adapter *adapter, u32 vector) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 queue = 1 << vector; + u32 mask; + + mask = (IXGBE_EIMS_RTX_QUEUE & queue); + IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); +} /* ixv_enable_queue */ + +static inline void +ixv_disable_queue(struct adapter *adapter, u32 vector) +{ + struct ixgbe_hw *hw = &adapter->hw; + u64 queue = (u64)(1 << vector); + u32 mask; + + mask = (IXGBE_EIMS_RTX_QUEUE & queue); + IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask); +} /* ixv_disable_queue */ + +static inline void +ixv_rearm_queues(struct adapter *adapter, u64 queues) +{ + u32 mask = (IXGBE_EIMS_RTX_QUEUE & queues); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEICS, mask); +} /* ixv_rearm_queues */ + + +/************************************************************************ + * ixv_msix_que - MSI Queue Interrupt Service routine + ************************************************************************/ +void +ixv_msix_que(void *arg) +{ + struct ix_queue *que = arg; + struct adapter *adapter = que->adapter; + struct ifnet *ifp = adapter->ifp; + struct tx_ring *txr = que->txr; + struct rx_ring *rxr = que->rxr; + bool more; + u32 newitr = 0; + + ixv_disable_queue(adapter, que->msix); + ++que->irqs; + + more = ixgbe_rxeof(que); + + IXGBE_TX_LOCK(txr); + ixgbe_txeof(txr); + /* + * Make certain that if the stack + * has anything queued the task gets + * scheduled to handle it. + */ + if (!ixv_ring_empty(adapter->ifp, txr->br)) + ixv_start_locked(ifp, txr); + IXGBE_TX_UNLOCK(txr); + + /* Do AIM now? */ + + if (ixv_enable_aim == FALSE) + goto no_calc; + /* + * Do Adaptive Interrupt Moderation: + * - Write out last calculated setting + * - Calculate based on average size over + * the last interval. + */ + if (que->eitr_setting) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEITR(que->msix), + que->eitr_setting); + + que->eitr_setting = 0; + + /* Idle, do nothing */ + if ((txr->bytes == 0) && (rxr->bytes == 0)) + goto no_calc; + + if ((txr->bytes) && (txr->packets)) + newitr = txr->bytes/txr->packets; + if ((rxr->bytes) && (rxr->packets)) + newitr = max(newitr, (rxr->bytes / rxr->packets)); + newitr += 24; /* account for hardware frame, crc */ + + /* set an upper boundary */ + newitr = min(newitr, 3000); + + /* Be nice to the mid range */ + if ((newitr > 300) && (newitr < 1200)) + newitr = (newitr / 3); + else + newitr = (newitr / 2); + + newitr |= newitr << 16; + + /* save for next interrupt */ + que->eitr_setting = newitr; + + /* Reset state */ + txr->bytes = 0; + txr->packets = 0; + rxr->bytes = 0; + rxr->packets = 0; + +no_calc: + if (more) + taskqueue_enqueue(que->tq, &que->que_task); + else /* Re-enable this interrupt */ + ixv_enable_queue(adapter, que->msix); + + return; +} /* ixv_msix_que */ + +/************************************************************************ + * ixv_msix_mbx + ************************************************************************/ +static void +ixv_msix_mbx(void *arg) +{ + struct adapter *adapter = arg; + struct ixgbe_hw *hw = &adapter->hw; + u32 reg; + + ++adapter->link_irq; + + /* First get the cause */ + reg = IXGBE_READ_REG(hw, IXGBE_VTEICS); + /* Clear interrupt with write */ + IXGBE_WRITE_REG(hw, IXGBE_VTEICR, reg); + + /* Link status change */ + if (reg & IXGBE_EICR_LSC) + taskqueue_enqueue(adapter->tq, &adapter->link_task); + + IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, IXGBE_EIMS_OTHER); + + return; +} /* ixv_msix_mbx */ + +/************************************************************************ + * ixv_media_status - Media Ioctl callback + * + * Called whenever the user queries the status of + * the interface using ifconfig. + ************************************************************************/ +static void +ixv_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct adapter *adapter = ifp->if_softc; + + INIT_DEBUGOUT("ixv_media_status: begin"); + IXGBE_CORE_LOCK(adapter); + ixv_update_link_status(adapter); + + ifmr->ifm_status = IFM_AVALID; + ifmr->ifm_active = IFM_ETHER; + + if (!adapter->link_active) { + IXGBE_CORE_UNLOCK(adapter); + return; + } + + ifmr->ifm_status |= IFM_ACTIVE; + + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_1GB_FULL: + ifmr->ifm_active |= IFM_1000_T | IFM_FDX; + break; + case IXGBE_LINK_SPEED_10GB_FULL: + ifmr->ifm_active |= IFM_10G_T | IFM_FDX; + break; + case IXGBE_LINK_SPEED_100_FULL: + ifmr->ifm_active |= IFM_100_TX | IFM_FDX; + break; + case IXGBE_LINK_SPEED_10_FULL: + ifmr->ifm_active |= IFM_10_T | IFM_FDX; + break; + } + + IXGBE_CORE_UNLOCK(adapter); + + return; +} /* ixv_media_status */ + +/************************************************************************ + * ixv_media_change - Media Ioctl callback + * + * Called when the user changes speed/duplex using + * media/mediopt option with ifconfig. + ************************************************************************/ +static int +ixv_media_change(struct ifnet *ifp) +{ + struct adapter *adapter = ifp->if_softc; + struct ifmedia *ifm = &adapter->media; + + INIT_DEBUGOUT("ixv_media_change: begin"); + + if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) + return (EINVAL); + + switch (IFM_SUBTYPE(ifm->ifm_media)) { + case IFM_AUTO: + break; + default: + device_printf(adapter->dev, "Only auto media type\n"); + return (EINVAL); + } + + return (0); +} /* ixv_media_change */ + + +/************************************************************************ + * ixv_set_multi - Multicast Update + * + * Called whenever multicast address list is updated. + ************************************************************************/ +static void +ixv_set_multi(struct adapter *adapter) +{ + u8 mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS]; + u8 *update_ptr; + struct ifmultiaddr *ifma; + struct ifnet *ifp = adapter->ifp; + int mcnt = 0; + + IOCTL_DEBUGOUT("ixv_set_multi: begin"); + +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else + if_maddr_rlock(ifp); +#endif + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), + &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS], + IXGBE_ETH_LENGTH_OF_ADDRESS); + mcnt++; + } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else + if_maddr_runlock(ifp); +#endif + + update_ptr = mta; + + adapter->hw.mac.ops.update_mc_addr_list(&adapter->hw, update_ptr, mcnt, + ixv_mc_array_itr, TRUE); + + return; +} /* ixv_set_multi */ + +/************************************************************************ + * ixv_mc_array_itr + * + * An iterator function needed by the multicast shared code. + * It feeds the shared code routine the addresses in the + * array of ixv_set_multi() one by one. + ************************************************************************/ +static u8 * +ixv_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq) +{ + u8 *addr = *update_ptr; + u8 *newptr; + *vmdq = 0; + + newptr = addr + IXGBE_ETH_LENGTH_OF_ADDRESS; + *update_ptr = newptr; + + return addr; +} /* ixv_mc_array_itr */ + +/************************************************************************ + * ixv_local_timer - Timer routine + * + * Checks for link status, updates statistics, + * and runs the watchdog check. + ************************************************************************/ +static void +ixv_local_timer(void *arg) +{ + struct adapter *adapter = arg; + device_t dev = adapter->dev; + struct ix_queue *que = adapter->queues; + u64 queues = 0; + int hung = 0; + + mtx_assert(&adapter->core_mtx, MA_OWNED); + + ixv_check_link(adapter); + + /* Stats Update */ + ixv_update_stats(adapter); + + /* + * Check the TX queues status + * - mark hung queues so we don't schedule on them + * - watchdog only if all queues show hung + */ + for (int i = 0; i < adapter->num_queues; i++, que++) { + /* Keep track of queues with work for soft irq */ + if (que->txr->busy) + queues |= ((u64)1 << que->me); + /* + * Each time txeof runs without cleaning, but there + * are uncleaned descriptors it increments busy. If + * we get to the MAX we declare it hung. + */ + if (que->busy == IXGBE_QUEUE_HUNG) { + ++hung; + /* Mark the queue as inactive */ + adapter->active_queues &= ~((u64)1 << que->me); + continue; + } else { + /* Check if we've come back from hung */ + if ((adapter->active_queues & ((u64)1 << que->me)) == 0) + adapter->active_queues |= ((u64)1 << que->me); + } + if (que->busy >= IXGBE_MAX_TX_BUSY) { + device_printf(dev, + "Warning queue %d appears to be hung!\n", i); + que->txr->busy = IXGBE_QUEUE_HUNG; + ++hung; + } + + } + + /* Only truly watchdog if all queues show hung */ + if (hung == adapter->num_queues) + goto watchdog; + else if (queues != 0) { /* Force an IRQ on queues with work */ + ixv_rearm_queues(adapter, queues); + } + + callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); + + return; + +watchdog: + + device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); + adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + adapter->watchdog_events++; + ixv_init_locked(adapter); +} /* ixv_local_timer */ + +/************************************************************************ + * ixv_update_link_status - Update OS on link state + * + * Note: Only updates the OS on the cached link state. + * The real check of the hardware only happens with + * a link interrupt. + ************************************************************************/ +static void +ixv_update_link_status(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; + + if (adapter->link_up) { + if (adapter->link_active == FALSE) { + if (bootverbose) + device_printf(dev,"Link is up %d Gbps %s \n", + ((adapter->link_speed == 128) ? 10 : 1), + "Full Duplex"); + adapter->link_active = TRUE; + if_link_state_change(ifp, LINK_STATE_UP); + } + } else { /* Link down */ + if (adapter->link_active == TRUE) { + if (bootverbose) + device_printf(dev,"Link is Down\n"); + if_link_state_change(ifp, LINK_STATE_DOWN); + adapter->link_active = FALSE; + } + } + + return; +} /* ixv_update_link_status */ + + +/************************************************************************ + * ixv_stop - Stop the hardware + * + * Disables all traffic on the adapter by issuing a + * global reset on the MAC and deallocates TX/RX buffers. + ************************************************************************/ +static void +ixv_stop(void *arg) +{ + struct ifnet *ifp; + struct adapter *adapter = arg; + struct ixgbe_hw *hw = &adapter->hw; + + ifp = adapter->ifp; + + mtx_assert(&adapter->core_mtx, MA_OWNED); + + INIT_DEBUGOUT("ixv_stop: begin\n"); + ixv_disable_intr(adapter); + + /* Tell the stack that the interface is no longer active */ + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + hw->mac.ops.reset_hw(hw); + adapter->hw.adapter_stopped = FALSE; + hw->mac.ops.stop_adapter(hw); + callout_stop(&adapter->timer); + + /* reprogram the RAR[0] in case user changed it. */ + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); + + return; +} /* ixv_stop */ + + +/************************************************************************ + * ixv_allocate_pci_resources + ************************************************************************/ +static int +ixv_allocate_pci_resources(struct adapter *adapter) +{ + device_t dev = adapter->dev; + int rid; + + rid = PCIR_BAR(0); + adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + + if (!(adapter->pci_mem)) { + device_printf(dev, "Unable to allocate bus resource: memory\n"); + return (ENXIO); + } + + adapter->osdep.mem_bus_space_tag = rman_get_bustag(adapter->pci_mem); + adapter->osdep.mem_bus_space_handle = + rman_get_bushandle(adapter->pci_mem); + adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle; + + /* Pick up the tuneable queues */ + adapter->num_queues = ixv_num_queues; + + return (0); +} /* ixv_allocate_pci_resources */ + +/************************************************************************ + * ixv_free_pci_resources + ************************************************************************/ +static void +ixv_free_pci_resources(struct adapter * adapter) +{ + struct ix_queue *que = adapter->queues; + device_t dev = adapter->dev; + int rid, memrid; + + memrid = PCIR_BAR(MSIX_82598_BAR); + + /* + * There is a slight possibility of a failure mode + * in attach that will result in entering this function + * before interrupt resources have been initialized, and + * in that case we do not want to execute the loops below + * We can detect this reliably by the state of the adapter + * res pointer. + */ + if (adapter->res == NULL) + goto mem; + + /* + * Release all msix queue resources: + */ + for (int i = 0; i < adapter->num_queues; i++, que++) { + rid = que->msix + 1; + if (que->tag != NULL) { + bus_teardown_intr(dev, que->res, que->tag); + que->tag = NULL; + } + if (que->res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, rid, que->res); + } + + + /* Clean the Mailbox interrupt last */ + rid = adapter->vector + 1; + + if (adapter->tag != NULL) { + bus_teardown_intr(dev, adapter->res, adapter->tag); + adapter->tag = NULL; + } + if (adapter->res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res); + +mem: + pci_release_msi(dev); + + if (adapter->msix_mem != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, memrid, + adapter->msix_mem); + + if (adapter->pci_mem != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), + adapter->pci_mem); + + return; +} /* ixv_free_pci_resources */ + +/************************************************************************ + * ixv_setup_interface + * + * Setup networking device structure and register an interface. + ************************************************************************/ +static void +ixv_setup_interface(device_t dev, struct adapter *adapter) +{ + struct ifnet *ifp; + + INIT_DEBUGOUT("ixv_setup_interface: begin"); + + ifp = adapter->ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) + panic("%s: can not if_alloc()\n", device_get_nameunit(dev)); + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_baudrate = 1000000000; + ifp->if_init = ixv_init; + ifp->if_softc = adapter; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = ixv_ioctl; + if_setgetcounterfn(ifp, ixv_get_counter); + /* TSO parameters */ + ifp->if_hw_tsomax = 65518; + ifp->if_hw_tsomaxsegcount = IXGBE_82599_SCATTER; + ifp->if_hw_tsomaxsegsize = 2048; + if (adapter->feat_en & IXGBE_FEATURE_LEGACY_TX) { + ifp->if_start = ixgbe_legacy_start; + ixv_start_locked = ixgbe_legacy_start_locked; + ixv_ring_empty = ixgbe_legacy_ring_empty; + } else { + ifp->if_transmit = ixgbe_mq_start; + ifp->if_qflush = ixgbe_qflush; + ixv_start_locked = ixgbe_mq_start_locked; + ixv_ring_empty = drbr_empty; + } + IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2); + + ether_ifattach(ifp, adapter->hw.mac.addr); + + adapter->max_frame_size = ifp->if_mtu + IXGBE_MTU_HDR; + + /* + * Tell the upper layer(s) we support long frames. + */ + ifp->if_hdrlen = sizeof(struct ether_vlan_header); + + /* Set capability flags */ + ifp->if_capabilities |= IFCAP_HWCSUM + | IFCAP_HWCSUM_IPV6 + | IFCAP_TSO + | IFCAP_LRO + | IFCAP_VLAN_HWTAGGING + | IFCAP_VLAN_HWTSO + | IFCAP_VLAN_HWCSUM + | IFCAP_JUMBO_MTU + | IFCAP_VLAN_MTU; + + /* Enable the above capabilities by default */ + ifp->if_capenable = ifp->if_capabilities; + + /* + * Specify the media types supported by this adapter and register + * callbacks to update media and link information + */ + ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change, + ixv_media_status); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); + + return; +} /* ixv_setup_interface */ + + +/************************************************************************ + * ixv_initialize_transmit_units - Enable transmit unit. + ************************************************************************/ +static void +ixv_initialize_transmit_units(struct adapter *adapter) +{ + struct tx_ring *txr = adapter->tx_rings; + struct ixgbe_hw *hw = &adapter->hw; + + + for (int i = 0; i < adapter->num_queues; i++, txr++) { + u64 tdba = txr->txdma.dma_paddr; + u32 txctrl, txdctl; + + /* Set WTHRESH to 8, burst writeback */ + txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); + txdctl |= (8 << 16); + IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl); + + /* Set the HW Tx Head and Tail indices */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(i), 0); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(i), 0); + + /* Set Tx Tail register */ + txr->tail = IXGBE_VFTDT(i); + + /* Set Ring parameters */ + IXGBE_WRITE_REG(hw, IXGBE_VFTDBAL(i), + (tdba & 0x00000000ffffffffULL)); + IXGBE_WRITE_REG(hw, IXGBE_VFTDBAH(i), (tdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_VFTDLEN(i), + adapter->num_tx_desc * sizeof(struct ixgbe_legacy_tx_desc)); + txctrl = IXGBE_READ_REG(hw, IXGBE_VFDCA_TXCTRL(i)); + txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; + IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(i), txctrl); + + /* Now enable */ + txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); + txdctl |= IXGBE_TXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl); + } + + return; +} /* ixv_initialize_transmit_units */ + + +/************************************************************************ + * ixv_initialize_rss_mapping + ************************************************************************/ +static void +ixv_initialize_rss_mapping(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 reta = 0, mrqc, rss_key[10]; + int queue_id; + int i, j; + u32 rss_hash_config; + + if (adapter->feat_en & IXGBE_FEATURE_RSS) { + /* Fetch the configured RSS key */ + rss_getkey((uint8_t *)&rss_key); + } else { + /* set up random bits */ + arc4rand(&rss_key, sizeof(rss_key), 0); + } + + /* Now fill out hash function seeds */ + for (i = 0; i < 10; i++) + IXGBE_WRITE_REG(hw, IXGBE_VFRSSRK(i), rss_key[i]); + + /* Set up the redirection table */ + for (i = 0, j = 0; i < 64; i++, j++) { + if (j == adapter->num_queues) + j = 0; + + if (adapter->feat_en & IXGBE_FEATURE_RSS) { + /* + * Fetch the RSS bucket id for the given indirection + * entry. Cap it at the number of configured buckets + * (which is num_queues.) + */ + queue_id = rss_get_indirection_to_bucket(i); + queue_id = queue_id % adapter->num_queues; + } else + queue_id = j; + + /* + * The low 8 bits are for hash value (n+0); + * The next 8 bits are for hash value (n+1), etc. + */ + reta >>= 8; + reta |= ((uint32_t)queue_id) << 24; + if ((i & 3) == 3) { + IXGBE_WRITE_REG(hw, IXGBE_VFRETA(i >> 2), reta); + reta = 0; + } + } + + /* Perform hash on these packet types */ + if (adapter->feat_en & IXGBE_FEATURE_RSS) + rss_hash_config = rss_gethashconfig(); + else { + /* + * Disable UDP - IP fragments aren't currently being handled + * and so we end up with a mix of 2-tuple and 4-tuple + * traffic. + */ + rss_hash_config = RSS_HASHTYPE_RSS_IPV4 + | RSS_HASHTYPE_RSS_TCP_IPV4 + | RSS_HASHTYPE_RSS_IPV6 + | RSS_HASHTYPE_RSS_TCP_IPV6; + } + + mrqc = IXGBE_MRQC_RSSEN; + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4; + if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP; + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6; + if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP; + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) + device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_IPV6_EX defined, but not supported\n", + __func__); + if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX) + device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_TCP_IPV6_EX defined, but not supported\n", + __func__); + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4_EX) + device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV4_EX defined, but not supported\n", + __func__); + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; + if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX) + device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV6_EX defined, but not supported\n", + __func__); + IXGBE_WRITE_REG(hw, IXGBE_VFMRQC, mrqc); +} /* ixv_initialize_rss_mapping */ + + +/************************************************************************ + * ixv_initialize_receive_units - Setup receive registers and features. + ************************************************************************/ +static void +ixv_initialize_receive_units(struct adapter *adapter) +{ + struct rx_ring *rxr = adapter->rx_rings; + struct ixgbe_hw *hw = &adapter->hw; + struct ifnet *ifp = adapter->ifp; + u32 bufsz, rxcsum, psrtype; + + if (ifp->if_mtu > ETHERMTU) + bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + else + bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + + psrtype = IXGBE_PSRTYPE_TCPHDR + | IXGBE_PSRTYPE_UDPHDR + | IXGBE_PSRTYPE_IPV4HDR + | IXGBE_PSRTYPE_IPV6HDR + | IXGBE_PSRTYPE_L2HDR; + + if (adapter->num_queues > 1) + psrtype |= 1 << 29; + + IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); + + /* Tell PF our max_frame size */ + if (ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size) != 0) { + device_printf(adapter->dev, "There is a problem with the PF setup. It is likely the receive unit for this VF will not function correctly.\n"); + } + + for (int i = 0; i < adapter->num_queues; i++, rxr++) { + u64 rdba = rxr->rxdma.dma_paddr; + u32 reg, rxdctl; + + /* Disable the queue */ + rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); + rxdctl &= ~IXGBE_RXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); + for (int j = 0; j < 10; j++) { + if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & + IXGBE_RXDCTL_ENABLE) + msec_delay(1); + else + break; + } + wmb(); + /* Setup the Base and Length of the Rx Descriptor Ring */ + IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(i), + (rdba & 0x00000000ffffffffULL)); + IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(i), (rdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(i), + adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc)); + + /* Reset the ring indices */ + IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0); + IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 0); + + /* Set up the SRRCTL register */ + reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); + reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; + reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; + reg |= bufsz; + reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; + IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), reg); + + /* Capture Rx Tail index */ + rxr->tail = IXGBE_VFRDT(rxr->me); + + /* Do the queue enabling last */ + rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; + IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); + for (int k = 0; k < 10; k++) { + if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & + IXGBE_RXDCTL_ENABLE) + break; + msec_delay(1); + } + wmb(); + + /* Set the Tail Pointer */ + /* + * In netmap mode, we must preserve the buffers made + * available to userspace before the if_init() + * (this is true by default on the TX side, because + * init makes all buffers available to userspace). + * + * netmap_reset() and the device specific routines + * (e.g. ixgbe_setup_receive_rings()) map these + * buffers at the end of the NIC ring, so here we + * must set the RDT (tail) register to make sure + * they are not overwritten. + * + * In this driver the NIC ring starts at RDH = 0, + * RDT points to the last slot available for reception (?), + * so RDT = num_rx_desc - 1 means the whole ring is available. + */ +#ifdef DEV_NETMAP + if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) && + (ifp->if_capenable & IFCAP_NETMAP)) { + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_kring *kring = &na->rx_rings[i]; + int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring); + + IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t); + } else +#endif /* DEV_NETMAP */ + IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), + adapter->num_rx_desc - 1); + } + + rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); + + ixv_initialize_rss_mapping(adapter); + + if (adapter->num_queues > 1) { + /* RSS and RX IPP Checksum are mutually exclusive */ + rxcsum |= IXGBE_RXCSUM_PCSD; + } + + if (ifp->if_capenable & IFCAP_RXCSUM) + rxcsum |= IXGBE_RXCSUM_PCSD; + + if (!(rxcsum & IXGBE_RXCSUM_PCSD)) + rxcsum |= IXGBE_RXCSUM_IPPCSE; + + IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); + + return; +} /* ixv_initialize_receive_units */ + +/************************************************************************ + * ixv_setup_vlan_support + ************************************************************************/ +static void +ixv_setup_vlan_support(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 ctrl, vid, vfta, retry; + + /* + * We get here thru init_locked, meaning + * a soft reset, this has already cleared + * the VFTA and other state, so if there + * have been no vlan's registered do nothing. + */ + if (adapter->num_vlans == 0) + return; + + /* Enable the queues */ + for (int i = 0; i < adapter->num_queues; i++) { + ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); + ctrl |= IXGBE_RXDCTL_VME; + IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl); + /* + * Let Rx path know that it needs to store VLAN tag + * as part of extra mbuf info. + */ + adapter->rx_rings[i].vtag_strip = TRUE; + } + + /* + * A soft reset zero's out the VFTA, so + * we need to repopulate it now. + */ + for (int i = 0; i < IXGBE_VFTA_SIZE; i++) { + if (ixv_shadow_vfta[i] == 0) + continue; + vfta = ixv_shadow_vfta[i]; + /* + * Reconstruct the vlan id's + * based on the bits set in each + * of the array ints. + */ + for (int j = 0; j < 32; j++) { + retry = 0; + if ((vfta & (1 << j)) == 0) + continue; + vid = (i * 32) + j; + /* Call the shared code mailbox routine */ + while (hw->mac.ops.set_vfta(hw, vid, 0, TRUE, FALSE)) { + if (++retry > 5) + break; + } + } + } +} /* ixv_setup_vlan_support */ + +/************************************************************************ + * ixv_register_vlan + * + * Run via a vlan config EVENT, it enables us to use the + * HW Filter table since we can get the vlan id. This just + * creates the entry in the soft version of the VFTA, init + * will repopulate the real table. + ************************************************************************/ +static void +ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) +{ + struct adapter *adapter = ifp->if_softc; + u16 index, bit; + + if (ifp->if_softc != arg) /* Not our event */ + return; + + if ((vtag == 0) || (vtag > 4095)) /* Invalid */ + return; + + IXGBE_CORE_LOCK(adapter); + index = (vtag >> 5) & 0x7F; + bit = vtag & 0x1F; + ixv_shadow_vfta[index] |= (1 << bit); + ++adapter->num_vlans; + /* Re-init to load the changes */ + ixv_init_locked(adapter); + IXGBE_CORE_UNLOCK(adapter); +} /* ixv_register_vlan */ + +/************************************************************************ + * ixv_unregister_vlan + * + * Run via a vlan unconfig EVENT, remove our entry + * in the soft vfta. + ************************************************************************/ +static void +ixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) +{ + struct adapter *adapter = ifp->if_softc; + u16 index, bit; + + if (ifp->if_softc != arg) + return; + + if ((vtag == 0) || (vtag > 4095)) /* Invalid */ + return; + + IXGBE_CORE_LOCK(adapter); + index = (vtag >> 5) & 0x7F; + bit = vtag & 0x1F; + ixv_shadow_vfta[index] &= ~(1 << bit); + --adapter->num_vlans; + /* Re-init to load the changes */ + ixv_init_locked(adapter); + IXGBE_CORE_UNLOCK(adapter); +} /* ixv_unregister_vlan */ + +/************************************************************************ + * ixv_enable_intr + ************************************************************************/ +static void +ixv_enable_intr(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ix_queue *que = adapter->queues; + u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); + + + IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); + + mask = IXGBE_EIMS_ENABLE_MASK; + mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC); + IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask); + + for (int i = 0; i < adapter->num_queues; i++, que++) + ixv_enable_queue(adapter, que->msix); + + IXGBE_WRITE_FLUSH(hw); + + return; +} /* ixv_enable_intr */ + +/************************************************************************ + * ixv_disable_intr + ************************************************************************/ +static void +ixv_disable_intr(struct adapter *adapter) +{ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIAC, 0); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, ~0); + IXGBE_WRITE_FLUSH(&adapter->hw); + + return; +} /* ixv_disable_intr */ + +/************************************************************************ + * ixv_set_ivar + * + * Setup the correct IVAR register for a particular MSI-X interrupt + * - entry is the register array entry + * - vector is the MSI-X vector for this queue + * - type is RX/TX/MISC + ************************************************************************/ +static void +ixv_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 ivar, index; + + vector |= IXGBE_IVAR_ALLOC_VAL; + + if (type == -1) { /* MISC IVAR */ + ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC); + ivar &= ~0xFF; + ivar |= vector; + IXGBE_WRITE_REG(hw, IXGBE_VTIVAR_MISC, ivar); + } else { /* RX/TX IVARS */ + index = (16 * (entry & 1)) + (8 * type); + ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR(entry >> 1)); + ivar &= ~(0xFF << index); + ivar |= (vector << index); + IXGBE_WRITE_REG(hw, IXGBE_VTIVAR(entry >> 1), ivar); + } +} /* ixv_set_ivar */ + +/************************************************************************ + * ixv_configure_ivars + ************************************************************************/ +static void +ixv_configure_ivars(struct adapter *adapter) +{ + struct ix_queue *que = adapter->queues; + + for (int i = 0; i < adapter->num_queues; i++, que++) { + /* First the RX queue entry */ + ixv_set_ivar(adapter, i, que->msix, 0); + /* ... and the TX */ + ixv_set_ivar(adapter, i, que->msix, 1); + /* Set an initial value in EITR */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEITR(que->msix), + IXGBE_EITR_DEFAULT); + } + + /* For the mailbox interrupt */ + ixv_set_ivar(adapter, 1, adapter->vector, -1); +} /* ixv_configure_ivars */ + + +/************************************************************************ + * ixv_get_counter + ************************************************************************/ +static uint64_t +ixv_get_counter(struct ifnet *ifp, ift_counter cnt) +{ + struct adapter *adapter; + + adapter = if_getsoftc(ifp); + + switch (cnt) { + case IFCOUNTER_IPACKETS: + return (adapter->ipackets); + case IFCOUNTER_OPACKETS: + return (adapter->opackets); + case IFCOUNTER_IBYTES: + return (adapter->ibytes); + case IFCOUNTER_OBYTES: + return (adapter->obytes); + case IFCOUNTER_IMCASTS: + return (adapter->imcasts); + default: + return (if_get_counter_default(ifp, cnt)); + } +} /* ixv_get_counter */ + +/************************************************************************ + * ixv_save_stats + * + * The VF stats registers never have a truly virgin + * starting point, so this routine tries to make an + * artificial one, marking ground zero on attach as + * it were. + ************************************************************************/ +static void +ixv_save_stats(struct adapter *adapter) +{ + if (adapter->stats.vf.vfgprc || adapter->stats.vf.vfgptc) { + adapter->stats.vf.saved_reset_vfgprc += + adapter->stats.vf.vfgprc - adapter->stats.vf.base_vfgprc; + adapter->stats.vf.saved_reset_vfgptc += + adapter->stats.vf.vfgptc - adapter->stats.vf.base_vfgptc; + adapter->stats.vf.saved_reset_vfgorc += + adapter->stats.vf.vfgorc - adapter->stats.vf.base_vfgorc; + adapter->stats.vf.saved_reset_vfgotc += + adapter->stats.vf.vfgotc - adapter->stats.vf.base_vfgotc; + adapter->stats.vf.saved_reset_vfmprc += + adapter->stats.vf.vfmprc - adapter->stats.vf.base_vfmprc; + } +} /* ixv_save_stats */ + +/************************************************************************ + * ixv_init_stats + ************************************************************************/ +static void +ixv_init_stats(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + adapter->stats.vf.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC); + adapter->stats.vf.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB); + adapter->stats.vf.last_vfgorc |= + (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32); + + adapter->stats.vf.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC); + adapter->stats.vf.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB); + adapter->stats.vf.last_vfgotc |= + (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32); + + adapter->stats.vf.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC); + + adapter->stats.vf.base_vfgprc = adapter->stats.vf.last_vfgprc; + adapter->stats.vf.base_vfgorc = adapter->stats.vf.last_vfgorc; + adapter->stats.vf.base_vfgptc = adapter->stats.vf.last_vfgptc; + adapter->stats.vf.base_vfgotc = adapter->stats.vf.last_vfgotc; + adapter->stats.vf.base_vfmprc = adapter->stats.vf.last_vfmprc; +} /* ixv_init_stats */ + +#define UPDATE_STAT_32(reg, last, count) \ +{ \ + u32 current = IXGBE_READ_REG(hw, reg); \ + if (current < last) \ + count += 0x100000000LL; \ + last = current; \ + count &= 0xFFFFFFFF00000000LL; \ + count |= current; \ } -/********************************************************************* +#define UPDATE_STAT_36(lsb, msb, last, count) \ +{ \ + u64 cur_lsb = IXGBE_READ_REG(hw, lsb); \ + u64 cur_msb = IXGBE_READ_REG(hw, msb); \ + u64 current = ((cur_msb << 32) | cur_lsb); \ + if (current < last) \ + count += 0x1000000000LL; \ + last = current; \ + count &= 0xFFFFFFF000000000LL; \ + count |= current; \ +} + +/************************************************************************ + * ixv_update_stats - Update the board statistics counters. + ************************************************************************/ +void +ixv_update_stats(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbevf_hw_stats *stats = &adapter->stats.vf; + + UPDATE_STAT_32(IXGBE_VFGPRC, adapter->stats.vf.last_vfgprc, + adapter->stats.vf.vfgprc); + UPDATE_STAT_32(IXGBE_VFGPTC, adapter->stats.vf.last_vfgptc, + adapter->stats.vf.vfgptc); + UPDATE_STAT_36(IXGBE_VFGORC_LSB, IXGBE_VFGORC_MSB, + adapter->stats.vf.last_vfgorc, adapter->stats.vf.vfgorc); + UPDATE_STAT_36(IXGBE_VFGOTC_LSB, IXGBE_VFGOTC_MSB, + adapter->stats.vf.last_vfgotc, adapter->stats.vf.vfgotc); + UPDATE_STAT_32(IXGBE_VFMPRC, adapter->stats.vf.last_vfmprc, + adapter->stats.vf.vfmprc); + + /* Fill out the OS statistics structure */ + IXGBE_SET_IPACKETS(adapter, stats->vfgprc); + IXGBE_SET_OPACKETS(adapter, stats->vfgptc); + IXGBE_SET_IBYTES(adapter, stats->vfgorc); + IXGBE_SET_OBYTES(adapter, stats->vfgotc); + IXGBE_SET_IMCASTS(adapter, stats->vfmprc); +} /* ixv_update_stats */ + +/************************************************************************ + * ixv_add_stats_sysctls - Add statistic sysctls for the VF. + ************************************************************************/ +static void +ixv_add_stats_sysctls(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct tx_ring *txr = adapter->tx_rings; + struct rx_ring *rxr = adapter->rx_rings; + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); + struct sysctl_oid *tree = device_get_sysctl_tree(dev); + struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); + struct ixgbevf_hw_stats *stats = &adapter->stats.vf; + struct sysctl_oid *stat_node, *queue_node; + struct sysctl_oid_list *stat_list, *queue_list; + +#define QUEUE_NAME_LEN 32 + char namebuf[QUEUE_NAME_LEN]; + + /* Driver Statistics */ + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped", + CTLFLAG_RD, &adapter->dropped_pkts, "Driver dropped packets"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_failed", + CTLFLAG_RD, &adapter->mbuf_defrag_failed, "m_defrag() failed"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_events", + CTLFLAG_RD, &adapter->watchdog_events, "Watchdog timeouts"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq", + CTLFLAG_RD, &adapter->link_irq, "Link MSI-X IRQ Handled"); + + for (int i = 0; i < adapter->num_queues; i++, txr++) { + snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); + queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, + CTLFLAG_RD, NULL, "Queue Name"); + queue_list = SYSCTL_CHILDREN(queue_node); + + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs", + CTLFLAG_RD, &(adapter->queues[i].irqs), "IRQs on queue"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "no_tx_dma_setup", + CTLFLAG_RD, &(txr->no_tx_dma_setup), + "Driver Tx DMA failure in Tx"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc", + CTLFLAG_RD, &(txr->no_desc_avail), + "Not-enough-descriptors count: TX"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets", + CTLFLAG_RD, &(txr->total_packets), "TX Packets"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "br_drops", + CTLFLAG_RD, &(txr->br->br_drops), + "Packets dropped in buf_ring"); + } + + for (int i = 0; i < adapter->num_queues; i++, rxr++) { + snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); + queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, + CTLFLAG_RD, NULL, "Queue Name"); + queue_list = SYSCTL_CHILDREN(queue_node); + + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets", + CTLFLAG_RD, &(rxr->rx_packets), "RX packets"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes", + CTLFLAG_RD, &(rxr->rx_bytes), "RX bytes"); + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_discarded", + CTLFLAG_RD, &(rxr->rx_discarded), "Discarded RX packets"); + } + + stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac", + CTLFLAG_RD, NULL, "VF Statistics (read from HW registers)"); + stat_list = SYSCTL_CHILDREN(stat_node); + + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd", + CTLFLAG_RD, &stats->vfgprc, "Good Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd", + CTLFLAG_RD, &stats->vfgorc, "Good Octets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd", + CTLFLAG_RD, &stats->vfmprc, "Multicast Packets Received"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd", + CTLFLAG_RD, &stats->vfgptc, "Good Packets Transmitted"); + SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", + CTLFLAG_RD, &stats->vfgotc, "Good Octets Transmitted"); +} /* ixv_add_stats_sysctls */ + +/************************************************************************ + * ixv_set_sysctl_value + ************************************************************************/ +static void +ixv_set_sysctl_value(struct adapter *adapter, const char *name, + const char *description, int *limit, int value) +{ + *limit = value; + SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), + OID_AUTO, name, CTLFLAG_RW, limit, value, description); +} /* ixv_set_sysctl_value */ + +/************************************************************************ + * ixv_print_debug_info * - * Shutdown entry point - * - **********************************************************************/ + * Called only when em_display_debug_stats is enabled. + * Provides a way to take a look at important statistics + * maintained by the driver and hardware. + ************************************************************************/ +static void +ixv_print_debug_info(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; + struct ix_queue *que = adapter->queues; + struct rx_ring *rxr; + struct tx_ring *txr; + struct lro_ctrl *lro; + + device_printf(dev, "Error Byte Count = %u \n", + IXGBE_READ_REG(hw, IXGBE_ERRBC)); + + for (int i = 0; i < adapter->num_queues; i++, que++) { + txr = que->txr; + rxr = que->rxr; + lro = &rxr->lro; + device_printf(dev, "QUE(%d) IRQs Handled: %lu\n", + que->msix, (long)que->irqs); + device_printf(dev, "RX(%d) Packets Received: %lld\n", + rxr->me, (long long)rxr->rx_packets); + device_printf(dev, "RX(%d) Bytes Received: %lu\n", + rxr->me, (long)rxr->rx_bytes); + device_printf(dev, "RX(%d) LRO Queued= %lld\n", + rxr->me, (long long)lro->lro_queued); + device_printf(dev, "RX(%d) LRO Flushed= %lld\n", + rxr->me, (long long)lro->lro_flushed); + device_printf(dev, "TX(%d) Packets Sent: %lu\n", + txr->me, (long)txr->total_packets); + device_printf(dev, "TX(%d) NO Desc Avail: %lu\n", + txr->me, (long)txr->no_desc_avail); + } + + device_printf(dev, "MBX IRQ Handled: %lu\n", (long)adapter->link_irq); +} /* ixv_print_debug_info */ + +/************************************************************************ + * ixv_sysctl_debug + ************************************************************************/ +static int +ixv_sysctl_debug(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter; + int error, result; + + result = -1; + error = sysctl_handle_int(oidp, &result, 0, req); + + if (error || !req->newptr) + return (error); + + if (result == 1) { + adapter = (struct adapter *)arg1; + ixv_print_debug_info(adapter); + } + + return error; +} /* ixv_sysctl_debug */ + +/************************************************************************ + * ixv_init_device_features + ************************************************************************/ +static void +ixv_init_device_features(struct adapter *adapter) +{ + adapter->feat_cap = IXGBE_FEATURE_NETMAP + | IXGBE_FEATURE_VF + | IXGBE_FEATURE_RSS + | IXGBE_FEATURE_LEGACY_TX; + + /* A tad short on feature flags for VFs, atm. */ + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599_vf: + break; + case ixgbe_mac_X540_vf: + break; + case ixgbe_mac_X550_vf: + case ixgbe_mac_X550EM_x_vf: + case ixgbe_mac_X550EM_a_vf: + adapter->feat_cap |= IXGBE_FEATURE_NEEDS_CTXD; + break; + default: + break; + } + + /* Enabled by default... */ + /* Is a virtual function (VF) */ + if (adapter->feat_cap & IXGBE_FEATURE_VF) + adapter->feat_en |= IXGBE_FEATURE_VF; + /* Netmap */ + if (adapter->feat_cap & IXGBE_FEATURE_NETMAP) + adapter->feat_en |= IXGBE_FEATURE_NETMAP; + /* Receive-Side Scaling (RSS) */ + if (adapter->feat_cap & IXGBE_FEATURE_RSS) + adapter->feat_en |= IXGBE_FEATURE_RSS; + /* Needs advanced context descriptor regardless of offloads req'd */ + if (adapter->feat_cap & IXGBE_FEATURE_NEEDS_CTXD) + adapter->feat_en |= IXGBE_FEATURE_NEEDS_CTXD; + + /* Enabled via sysctl... */ + /* Legacy (single queue) transmit */ + if ((adapter->feat_cap & IXGBE_FEATURE_LEGACY_TX) && + ixv_enable_legacy_tx) + adapter->feat_en |= IXGBE_FEATURE_LEGACY_TX; +} /* ixv_init_device_features */ + +/************************************************************************ + * ixv_shutdown - Shutdown entry point + ************************************************************************/ static int ixv_shutdown(device_t dev) { @@ -519,29 +2070,28 @@ ixv_shutdown(device_t dev) IXGBE_CORE_LOCK(adapter); ixv_stop(adapter); IXGBE_CORE_UNLOCK(adapter); + return (0); -} +} /* ixv_shutdown */ -/********************************************************************* - * Ioctl entry point +/************************************************************************ + * ixv_ioctl - Ioctl entry point * - * ixv_ioctl is called when the user wants to configure the - * interface. + * Called when the user wants to configure the interface. * - * return 0 on success, positive on failure - **********************************************************************/ - + * return 0 on success, positive on failure + ************************************************************************/ static int -ixv_ioctl(struct ifnet * ifp, u_long command, caddr_t data) +ixv_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { - struct adapter *adapter = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *) data; + struct adapter *adapter = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *)data; #if defined(INET) || defined(INET6) - struct ifaddr *ifa = (struct ifaddr *) data; - bool avoid_reset = FALSE; + struct ifaddr *ifa = (struct ifaddr *)data; + bool avoid_reset = FALSE; #endif - int error = 0; + int error = 0; switch (command) { @@ -556,9 +2106,9 @@ ixv_ioctl(struct ifnet * ifp, u_long command, caddr_t data) #endif #if defined(INET) || defined(INET6) /* - ** Calling init results in link renegotiation, - ** so we avoid doing it when possible. - */ + * Calling init results in link renegotiation, + * so we avoid doing it when possible. + */ if (avoid_reset) { ifp->if_flags |= IFF_UP; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) @@ -571,13 +2121,12 @@ ixv_ioctl(struct ifnet * ifp, u_long command, caddr_t data) #endif case SIOCSIFMTU: IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); - if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR) { + if (ifr->ifr_mtu > IXGBE_MAX_MTU) { error = EINVAL; } else { IXGBE_CORE_LOCK(adapter); ifp->if_mtu = ifr->ifr_mtu; - adapter->max_frame_size = - ifp->if_mtu + IXGBE_MTU_HDR; + adapter->max_frame_size = ifp->if_mtu + IXGBE_MTU_HDR; if (ifp->if_drv_flags & IFF_DRV_RUNNING) ixv_init_locked(adapter); IXGBE_CORE_UNLOCK(adapter); @@ -639,122 +2188,11 @@ ixv_ioctl(struct ifnet * ifp, u_long command, caddr_t data) } return (error); -} - -/********************************************************************* - * Init entry point - * - * This routine is used in two ways. It is used by the stack as - * init entry point in network interface structure. It is also used - * by the driver as a hw/sw initialization routine to get to a - * consistent state. - * - * return 0 on success, positive on failure - **********************************************************************/ -#define IXGBE_MHADD_MFS_SHIFT 16 - -static void -ixv_init_locked(struct adapter *adapter) -{ - struct ifnet *ifp = adapter->ifp; - device_t dev = adapter->dev; - struct ixgbe_hw *hw = &adapter->hw; - int error = 0; - - INIT_DEBUGOUT("ixv_init_locked: begin"); - mtx_assert(&adapter->core_mtx, MA_OWNED); - hw->adapter_stopped = FALSE; - ixgbe_stop_adapter(hw); - callout_stop(&adapter->timer); - - /* reprogram the RAR[0] in case user changed it. */ - ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); - - /* Get the latest mac address, User can use a LAA */ - bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr, - IXGBE_ETH_LENGTH_OF_ADDRESS); - ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1); - hw->addr_ctrl.rar_used_count = 1; - - /* Prepare transmit descriptors and buffers */ - if (ixgbe_setup_transmit_structures(adapter)) { - device_printf(dev, "Could not setup transmit structures\n"); - ixv_stop(adapter); - return; - } - - /* Reset VF and renegotiate mailbox API version */ - ixgbe_reset_hw(hw); - error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11); - if (error) - device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error); - - ixv_initialize_transmit_units(adapter); - - /* Setup Multicast table */ - ixv_set_multi(adapter); - - /* - ** Determine the correct mbuf pool - ** for doing jumbo/headersplit - */ - if (ifp->if_mtu > ETHERMTU) - adapter->rx_mbuf_sz = MJUMPAGESIZE; - else - adapter->rx_mbuf_sz = MCLBYTES; - - /* Prepare receive descriptors and buffers */ - if (ixgbe_setup_receive_structures(adapter)) { - device_printf(dev, "Could not setup receive structures\n"); - ixv_stop(adapter); - return; - } - - /* Configure RX settings */ - ixv_initialize_receive_units(adapter); - - /* Set the various hardware offload abilities */ - ifp->if_hwassist = 0; - if (ifp->if_capenable & IFCAP_TSO4) - ifp->if_hwassist |= CSUM_TSO; - if (ifp->if_capenable & IFCAP_TXCSUM) { - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); -#if __FreeBSD_version >= 800000 - ifp->if_hwassist |= CSUM_SCTP; -#endif - } - - /* Set up VLAN offload and filter */ - ixv_setup_vlan_support(adapter); - - /* Set up MSI/X routing */ - ixv_configure_ivars(adapter); - - /* Set up auto-mask */ - IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, IXGBE_EICS_RTX_QUEUE); - - /* Set moderation on the Link interrupt */ - IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR); - - /* Stats init */ - ixv_init_stats(adapter); - - /* Config/Enable Link */ - ixv_config_link(adapter); - - /* Start watchdog */ - callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); - - /* And now turn on interrupts */ - ixv_enable_intr(adapter); - - /* Now inform the stack we're ready */ - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - return; -} +} /* ixv_ioctl */ +/************************************************************************ + * ixv_init + ************************************************************************/ static void ixv_init(void *arg) { @@ -763,66 +2201,29 @@ ixv_init(void *arg) IXGBE_CORE_LOCK(adapter); ixv_init_locked(adapter); IXGBE_CORE_UNLOCK(adapter); + return; -} - - -/* -** -** MSIX Interrupt Handlers and Tasklets -** -*/ - -static inline void -ixv_enable_queue(struct adapter *adapter, u32 vector) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 queue = 1 << vector; - u32 mask; - - mask = (IXGBE_EIMS_RTX_QUEUE & queue); - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); -} - -static inline void -ixv_disable_queue(struct adapter *adapter, u32 vector) -{ - struct ixgbe_hw *hw = &adapter->hw; - u64 queue = (u64)(1 << vector); - u32 mask; - - mask = (IXGBE_EIMS_RTX_QUEUE & queue); - IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask); -} - -static inline void -ixv_rearm_queues(struct adapter *adapter, u64 queues) -{ - u32 mask = (IXGBE_EIMS_RTX_QUEUE & queues); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEICS, mask); -} +} /* ixv_init */ +/************************************************************************ + * ixv_handle_que + ************************************************************************/ static void ixv_handle_que(void *context, int pending) { struct ix_queue *que = context; struct adapter *adapter = que->adapter; - struct tx_ring *txr = que->txr; + struct tx_ring *txr = que->txr; struct ifnet *ifp = adapter->ifp; - bool more; + bool more; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { more = ixgbe_rxeof(que); IXGBE_TX_LOCK(txr); ixgbe_txeof(txr); -#if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, txr->br)) - ixgbe_mq_start_locked(ifp, txr); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - ixgbe_start_locked(txr, ifp); -#endif + if (!ixv_ring_empty(ifp, txr->br)) + ixv_start_locked(ifp, txr); IXGBE_TX_UNLOCK(txr); if (more) { taskqueue_enqueue(que->tq, &que->que_task); @@ -830,458 +2231,30 @@ ixv_handle_que(void *context, int pending) } } - /* Reenable this interrupt */ + /* Re-enable this interrupt */ ixv_enable_queue(adapter, que->msix); - return; -} - -/********************************************************************* - * - * MSI Queue Interrupt Service routine - * - **********************************************************************/ -void -ixv_msix_que(void *arg) -{ - struct ix_queue *que = arg; - struct adapter *adapter = que->adapter; - struct ifnet *ifp = adapter->ifp; - struct tx_ring *txr = que->txr; - struct rx_ring *rxr = que->rxr; - bool more; - u32 newitr = 0; - - ixv_disable_queue(adapter, que->msix); - ++que->irqs; - - more = ixgbe_rxeof(que); - - IXGBE_TX_LOCK(txr); - ixgbe_txeof(txr); - /* - ** Make certain that if the stack - ** has anything queued the task gets - ** scheduled to handle it. - */ -#ifdef IXGBE_LEGACY_TX - if (!IFQ_DRV_IS_EMPTY(&adapter->ifp->if_snd)) - ixgbe_start_locked(txr, ifp); -#else - if (!drbr_empty(adapter->ifp, txr->br)) - ixgbe_mq_start_locked(ifp, txr); -#endif - IXGBE_TX_UNLOCK(txr); - - /* Do AIM now? */ - - if (ixv_enable_aim == FALSE) - goto no_calc; - /* - ** Do Adaptive Interrupt Moderation: - ** - Write out last calculated setting - ** - Calculate based on average size over - ** the last interval. - */ - if (que->eitr_setting) - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_VTEITR(que->msix), - que->eitr_setting); - - que->eitr_setting = 0; - - /* Idle, do nothing */ - if ((txr->bytes == 0) && (rxr->bytes == 0)) - goto no_calc; - - if ((txr->bytes) && (txr->packets)) - newitr = txr->bytes/txr->packets; - if ((rxr->bytes) && (rxr->packets)) - newitr = max(newitr, - (rxr->bytes / rxr->packets)); - newitr += 24; /* account for hardware frame, crc */ - - /* set an upper boundary */ - newitr = min(newitr, 3000); - - /* Be nice to the mid range */ - if ((newitr > 300) && (newitr < 1200)) - newitr = (newitr / 3); - else - newitr = (newitr / 2); - - newitr |= newitr << 16; - - /* save for next interrupt */ - que->eitr_setting = newitr; - - /* Reset state */ - txr->bytes = 0; - txr->packets = 0; - rxr->bytes = 0; - rxr->packets = 0; - -no_calc: - if (more) - taskqueue_enqueue(que->tq, &que->que_task); - else /* Reenable this interrupt */ - ixv_enable_queue(adapter, que->msix); - return; -} - -static void -ixv_msix_mbx(void *arg) -{ - struct adapter *adapter = arg; - struct ixgbe_hw *hw = &adapter->hw; - u32 reg; - - ++adapter->link_irq; - - /* First get the cause */ - reg = IXGBE_READ_REG(hw, IXGBE_VTEICS); - /* Clear interrupt with write */ - IXGBE_WRITE_REG(hw, IXGBE_VTEICR, reg); - - /* Link status change */ - if (reg & IXGBE_EICR_LSC) - taskqueue_enqueue(adapter->tq, &adapter->link_task); - - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, IXGBE_EIMS_OTHER); - return; -} - -/********************************************************************* - * - * Media Ioctl callback - * - * This routine is called whenever the user queries the status of - * the interface using ifconfig. - * - **********************************************************************/ -static void -ixv_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) -{ - struct adapter *adapter = ifp->if_softc; - - INIT_DEBUGOUT("ixv_media_status: begin"); - IXGBE_CORE_LOCK(adapter); - ixv_update_link_status(adapter); - - ifmr->ifm_status = IFM_AVALID; - ifmr->ifm_active = IFM_ETHER; - - if (!adapter->link_active) { - IXGBE_CORE_UNLOCK(adapter); - return; - } - - ifmr->ifm_status |= IFM_ACTIVE; - - switch (adapter->link_speed) { - case IXGBE_LINK_SPEED_1GB_FULL: - ifmr->ifm_active |= IFM_1000_T | IFM_FDX; - break; - case IXGBE_LINK_SPEED_10GB_FULL: - ifmr->ifm_active |= IFM_FDX; - break; - } - - IXGBE_CORE_UNLOCK(adapter); return; -} +} /* ixv_handle_que */ -/********************************************************************* - * - * Media Ioctl callback - * - * This routine is called when the user changes speed/duplex using - * media/mediopt option with ifconfig. - * - **********************************************************************/ -static int -ixv_media_change(struct ifnet * ifp) -{ - struct adapter *adapter = ifp->if_softc; - struct ifmedia *ifm = &adapter->media; - - INIT_DEBUGOUT("ixv_media_change: begin"); - - if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) - return (EINVAL); - - switch (IFM_SUBTYPE(ifm->ifm_media)) { - case IFM_AUTO: - break; - default: - device_printf(adapter->dev, "Only auto media type\n"); - return (EINVAL); - } - - return (0); -} - - -/********************************************************************* - * Multicast Update - * - * This routine is called whenever multicast address list is updated. - * - **********************************************************************/ -#define IXGBE_RAR_ENTRIES 16 - -static void -ixv_set_multi(struct adapter *adapter) -{ - u8 mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS]; - u8 *update_ptr; - struct ifmultiaddr *ifma; - int mcnt = 0; - struct ifnet *ifp = adapter->ifp; - - IOCTL_DEBUGOUT("ixv_set_multi: begin"); - -#if __FreeBSD_version < 800000 - IF_ADDR_LOCK(ifp); -#else - if_maddr_rlock(ifp); -#endif - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), - &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS], - IXGBE_ETH_LENGTH_OF_ADDRESS); - mcnt++; - } -#if __FreeBSD_version < 800000 - IF_ADDR_UNLOCK(ifp); -#else - if_maddr_runlock(ifp); -#endif - - update_ptr = mta; - - ixgbe_update_mc_addr_list(&adapter->hw, - update_ptr, mcnt, ixv_mc_array_itr, TRUE); - - return; -} - -/* - * This is an iterator function now needed by the multicast - * shared code. It simply feeds the shared code routine the - * addresses in the array of ixv_set_multi() one by one. - */ -static u8 * -ixv_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq) -{ - u8 *addr = *update_ptr; - u8 *newptr; - *vmdq = 0; - - newptr = addr + IXGBE_ETH_LENGTH_OF_ADDRESS; - *update_ptr = newptr; - return addr; -} - -/********************************************************************* - * Timer routine - * - * This routine checks for link status,updates statistics, - * and runs the watchdog check. - * - **********************************************************************/ - -static void -ixv_local_timer(void *arg) -{ - struct adapter *adapter = arg; - device_t dev = adapter->dev; - struct ix_queue *que = adapter->queues; - u64 queues = 0; - int hung = 0; - - mtx_assert(&adapter->core_mtx, MA_OWNED); - - ixv_update_link_status(adapter); - - /* Stats Update */ - ixv_update_stats(adapter); - - /* - ** Check the TX queues status - ** - mark hung queues so we don't schedule on them - ** - watchdog only if all queues show hung - */ - for (int i = 0; i < adapter->num_queues; i++, que++) { - /* Keep track of queues with work for soft irq */ - if (que->txr->busy) - queues |= ((u64)1 << que->me); - /* - ** Each time txeof runs without cleaning, but there - ** are uncleaned descriptors it increments busy. If - ** we get to the MAX we declare it hung. - */ - if (que->busy == IXGBE_QUEUE_HUNG) { - ++hung; - /* Mark the queue as inactive */ - adapter->active_queues &= ~((u64)1 << que->me); - continue; - } else { - /* Check if we've come back from hung */ - if ((adapter->active_queues & ((u64)1 << que->me)) == 0) - adapter->active_queues |= ((u64)1 << que->me); - } - if (que->busy >= IXGBE_MAX_TX_BUSY) { - device_printf(dev,"Warning queue %d " - "appears to be hung!\n", i); - que->txr->busy = IXGBE_QUEUE_HUNG; - ++hung; - } - - } - - /* Only truly watchdog if all queues show hung */ - if (hung == adapter->num_queues) - goto watchdog; - else if (queues != 0) { /* Force an IRQ on queues with work */ - ixv_rearm_queues(adapter, queues); - } - - callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); - return; - -watchdog: - device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); - adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - adapter->watchdog_events++; - ixv_init_locked(adapter); -} - -/* -** Note: this routine updates the OS on the link state -** the real check of the hardware only happens with -** a link interrupt. -*/ -static void -ixv_update_link_status(struct adapter *adapter) -{ - struct ifnet *ifp = adapter->ifp; - device_t dev = adapter->dev; - - if (adapter->link_up){ - if (adapter->link_active == FALSE) { - if (bootverbose) - device_printf(dev,"Link is up %d Gbps %s \n", - ((adapter->link_speed == 128)? 10:1), - "Full Duplex"); - adapter->link_active = TRUE; - if_link_state_change(ifp, LINK_STATE_UP); - } - } else { /* Link down */ - if (adapter->link_active == TRUE) { - if (bootverbose) - device_printf(dev,"Link is Down\n"); - if_link_state_change(ifp, LINK_STATE_DOWN); - adapter->link_active = FALSE; - } - } - - return; -} - - -/********************************************************************* - * - * This routine disables all traffic on the adapter by issuing a - * global reset on the MAC and deallocates TX/RX buffers. - * - **********************************************************************/ - -static void -ixv_stop(void *arg) -{ - struct ifnet *ifp; - struct adapter *adapter = arg; - struct ixgbe_hw *hw = &adapter->hw; - ifp = adapter->ifp; - - mtx_assert(&adapter->core_mtx, MA_OWNED); - - INIT_DEBUGOUT("ixv_stop: begin\n"); - ixv_disable_intr(adapter); - - /* Tell the stack that the interface is no longer active */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - ixgbe_reset_hw(hw); - adapter->hw.adapter_stopped = FALSE; - ixgbe_stop_adapter(hw); - callout_stop(&adapter->timer); - - /* reprogram the RAR[0] in case user changed it. */ - ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); - - return; -} - - -/********************************************************************* - * - * Determine hardware revision. - * - **********************************************************************/ -static void -ixv_identify_hardware(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct ixgbe_hw *hw = &adapter->hw; - - /* - ** Make sure BUSMASTER is set, on a VM under - ** KVM it may not be and will break things. - */ - pci_enable_busmaster(dev); - - /* Save off the information about this board */ - hw->vendor_id = pci_get_vendor(dev); - hw->device_id = pci_get_device(dev); - hw->revision_id = pci_read_config(dev, PCIR_REVID, 1); - hw->subsystem_vendor_id = - pci_read_config(dev, PCIR_SUBVEND_0, 2); - hw->subsystem_device_id = - pci_read_config(dev, PCIR_SUBDEV_0, 2); - - /* We need this to determine device-specific things */ - ixgbe_set_mac_type(hw); - - /* Set the right number of segments */ - adapter->num_segs = IXGBE_82599_SCATTER; - - return; -} - -/********************************************************************* - * - * Setup MSIX Interrupt resources and handlers - * - **********************************************************************/ +/************************************************************************ + * ixv_allocate_msix - Setup MSI-X Interrupt resources and handlers + ************************************************************************/ static int ixv_allocate_msix(struct adapter *adapter) { - device_t dev = adapter->dev; - struct ix_queue *que = adapter->queues; - struct tx_ring *txr = adapter->tx_rings; - int error, rid, vector = 0; + device_t dev = adapter->dev; + struct ix_queue *que = adapter->queues; + struct tx_ring *txr = adapter->tx_rings; + int error, msix_ctrl, rid, vector = 0; for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) { rid = vector + 1; que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (que->res == NULL) { - device_printf(dev,"Unable to allocate" - " bus resource: que interrupt [%d]\n", vector); + device_printf(dev, "Unable to allocate bus resource: que interrupt [%d]\n", + vector); return (ENXIO); } /* Set the handler function */ @@ -1297,11 +2270,11 @@ ixv_allocate_msix(struct adapter *adapter) bus_describe_intr(dev, que->res, que->tag, "que %d", i); #endif que->msix = vector; - adapter->active_queues |= (u64)(1 << que->msix); + adapter->active_queues |= (u64)(1 << que->msix); /* - ** Bind the msix vector, and thus the - ** ring to the corresponding cpu. - */ + * Bind the MSI-X vector, and thus the + * ring to the corresponding CPU. + */ if (adapter->num_queues > 1) bus_bind_intr(dev, que->res, i); TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr); @@ -1314,17 +2287,17 @@ ixv_allocate_msix(struct adapter *adapter) /* and Mailbox */ rid = vector + 1; - adapter->res = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); + adapter->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); if (!adapter->res) { - device_printf(dev,"Unable to allocate" - " bus resource: MBX interrupt [%d]\n", rid); + device_printf(dev, + "Unable to allocate bus resource: MBX interrupt [%d]\n", + rid); return (ENXIO); } /* Set the mbx handler function */ - error = bus_setup_intr(dev, adapter->res, - INTR_TYPE_NET | INTR_MPSAFE, NULL, - ixv_msix_mbx, adapter, &adapter->tag); + error = bus_setup_intr(dev, adapter->res, INTR_TYPE_NET | INTR_MPSAFE, + NULL, ixv_msix_mbx, adapter, &adapter->tag); if (error) { adapter->res = NULL; device_printf(dev, "Failed to register LINK handler"); @@ -1335,20 +2308,19 @@ ixv_allocate_msix(struct adapter *adapter) #endif adapter->vector = vector; /* Tasklets for Mailbox */ - TASK_INIT(&adapter->link_task, 0, ixv_handle_mbx, adapter); + TASK_INIT(&adapter->link_task, 0, ixv_handle_link, adapter); adapter->tq = taskqueue_create_fast("ixv_mbx", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s mbxq", device_get_nameunit(adapter->dev)); /* - ** Due to a broken design QEMU will fail to properly - ** enable the guest for MSIX unless the vectors in - ** the table are all set up, so we must rewrite the - ** ENABLE in the MSIX control register again at this - ** point to cause it to successfully initialize us. - */ + * Due to a broken design QEMU will fail to properly + * enable the guest for MSI-X unless the vectors in + * the table are all set up, so we must rewrite the + * ENABLE in the MSI-X control register again at this + * point to cause it to successfully initialize us. + */ if (adapter->hw.mac.type == ixgbe_mac_82599_vf) { - int msix_ctrl; pci_find_cap(dev, PCIY_MSIX, &rid); rid += PCIR_MSIX_CTRL; msix_ctrl = pci_read_config(dev, rid, 2); @@ -1357,36 +2329,35 @@ ixv_allocate_msix(struct adapter *adapter) } return (0); -} +} /* ixv_allocate_msix */ -/* - * Setup MSIX resources, note that the VF - * device MUST use MSIX, there is no fallback. - */ +/************************************************************************ + * ixv_configure_interrupts - Setup MSI-X resources + * + * Note: The VF device MUST use MSI-X, there is no fallback. + ************************************************************************/ static int -ixv_setup_msix(struct adapter *adapter) +ixv_configure_interrupts(struct adapter *adapter) { device_t dev = adapter->dev; - int rid, want, msgs; + int rid, want, msgs; - - /* Must have at least 2 MSIX vectors */ + /* Must have at least 2 MSI-X vectors */ msgs = pci_msix_count(dev); if (msgs < 2) goto out; rid = PCIR_BAR(3); - adapter->msix_mem = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (adapter->msix_mem == NULL) { - device_printf(adapter->dev, - "Unable to map MSIX table \n"); + adapter->msix_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (adapter->msix_mem == NULL) { + device_printf(adapter->dev, "Unable to map MSI-X table \n"); goto out; } /* - ** Want vectors for the queues, - ** plus an additional for mailbox. - */ + * Want vectors for the queues, + * plus an additional for mailbox. + */ want = adapter->num_queues + 1; if (want > msgs) { want = msgs; @@ -1394,811 +2365,52 @@ ixv_setup_msix(struct adapter *adapter) } else msgs = want; if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) { - device_printf(adapter->dev, - "Using MSIX interrupts with %d vectors\n", want); - return (want); + device_printf(adapter->dev, + "Using MSI-X interrupts with %d vectors\n", want); + /* reflect correct sysctl value */ + ixv_num_queues = adapter->num_queues; + + return (0); } /* Release in case alloc was insufficient */ pci_release_msi(dev); out: - if (adapter->msix_mem != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - rid, adapter->msix_mem); + if (adapter->msix_mem != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, rid, + adapter->msix_mem); adapter->msix_mem = NULL; } - device_printf(adapter->dev,"MSIX config error\n"); + device_printf(adapter->dev, "MSI-X config error\n"); + return (ENXIO); -} +} /* ixv_configure_interrupts */ -static int -ixv_allocate_pci_resources(struct adapter *adapter) -{ - int rid; - device_t dev = adapter->dev; - - rid = PCIR_BAR(0); - adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, RF_ACTIVE); - - if (!(adapter->pci_mem)) { - device_printf(dev, "Unable to allocate bus resource: memory\n"); - return (ENXIO); - } - - adapter->osdep.mem_bus_space_tag = - rman_get_bustag(adapter->pci_mem); - adapter->osdep.mem_bus_space_handle = - rman_get_bushandle(adapter->pci_mem); - adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle; - - /* Pick up the tuneable queues */ - adapter->num_queues = ixv_num_queues; - adapter->hw.back = adapter; - - /* - ** Now setup MSI/X, should - ** return us the number of - ** configured vectors. - */ - adapter->msix = ixv_setup_msix(adapter); - if (adapter->msix == ENXIO) - return (ENXIO); - else - return (0); -} - -static void -ixv_free_pci_resources(struct adapter * adapter) -{ - struct ix_queue *que = adapter->queues; - device_t dev = adapter->dev; - int rid, memrid; - - memrid = PCIR_BAR(MSIX_82598_BAR); - - /* - ** There is a slight possibility of a failure mode - ** in attach that will result in entering this function - ** before interrupt resources have been initialized, and - ** in that case we do not want to execute the loops below - ** We can detect this reliably by the state of the adapter - ** res pointer. - */ - if (adapter->res == NULL) - goto mem; - - /* - ** Release all msix queue resources: - */ - for (int i = 0; i < adapter->num_queues; i++, que++) { - rid = que->msix + 1; - if (que->tag != NULL) { - bus_teardown_intr(dev, que->res, que->tag); - que->tag = NULL; - } - if (que->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, que->res); - } - - - /* Clean the Legacy or Link interrupt last */ - if (adapter->vector) /* we are doing MSIX */ - rid = adapter->vector + 1; - else - (adapter->msix != 0) ? (rid = 1):(rid = 0); - - if (adapter->tag != NULL) { - bus_teardown_intr(dev, adapter->res, adapter->tag); - adapter->tag = NULL; - } - if (adapter->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res); - -mem: - if (adapter->msix) - pci_release_msi(dev); - - if (adapter->msix_mem != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, - memrid, adapter->msix_mem); - - if (adapter->pci_mem != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, - PCIR_BAR(0), adapter->pci_mem); - - return; -} - -/********************************************************************* +/************************************************************************ + * ixv_handle_link - Tasklet handler for MSI-X MBX interrupts * - * Setup networking device structure and register an interface. - * - **********************************************************************/ + * Done outside of interrupt context since the driver might sleep + ************************************************************************/ static void -ixv_setup_interface(device_t dev, struct adapter *adapter) +ixv_handle_link(void *context, int pending) { - struct ifnet *ifp; + struct adapter *adapter = context; - INIT_DEBUGOUT("ixv_setup_interface: begin"); - - ifp = adapter->ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) - panic("%s: can not if_alloc()\n", device_get_nameunit(dev)); - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_baudrate = 1000000000; - ifp->if_init = ixv_init; - ifp->if_softc = adapter; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = ixv_ioctl; -#if __FreeBSD_version >= 800000 - ifp->if_transmit = ixgbe_mq_start; - ifp->if_qflush = ixgbe_qflush; -#else - ifp->if_start = ixgbe_start; -#endif - ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2; - - ether_ifattach(ifp, adapter->hw.mac.addr); - - adapter->max_frame_size = - ifp->if_mtu + IXGBE_MTU_HDR_VLAN; - - /* - * Tell the upper layer(s) we support long frames. - */ - ifp->if_hdrlen = sizeof(struct ether_vlan_header); - - ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM; - ifp->if_capabilities |= IFCAP_JUMBO_MTU; - ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING - | IFCAP_VLAN_HWTSO - | IFCAP_VLAN_MTU; - ifp->if_capabilities |= IFCAP_LRO; - ifp->if_capenable = ifp->if_capabilities; - - /* - * Specify the media types supported by this adapter and register - * callbacks to update media and link information - */ - ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change, - ixv_media_status); - ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); - ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); - - return; -} - -static void -ixv_config_link(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 autoneg; - - if (hw->mac.ops.check_link) - hw->mac.ops.check_link(hw, &autoneg, - &adapter->link_up, FALSE); -} - - -/********************************************************************* - * - * Enable transmit unit. - * - **********************************************************************/ -static void -ixv_initialize_transmit_units(struct adapter *adapter) -{ - struct tx_ring *txr = adapter->tx_rings; - struct ixgbe_hw *hw = &adapter->hw; - - - for (int i = 0; i < adapter->num_queues; i++, txr++) { - u64 tdba = txr->txdma.dma_paddr; - u32 txctrl, txdctl; - - /* Set WTHRESH to 8, burst writeback */ - txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); - txdctl |= (8 << 16); - IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl); - - /* Set the HW Tx Head and Tail indices */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(i), 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(i), 0); - - /* Set Tx Tail register */ - txr->tail = IXGBE_VFTDT(i); - - /* Set Ring parameters */ - IXGBE_WRITE_REG(hw, IXGBE_VFTDBAL(i), - (tdba & 0x00000000ffffffffULL)); - IXGBE_WRITE_REG(hw, IXGBE_VFTDBAH(i), (tdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_VFTDLEN(i), - adapter->num_tx_desc * - sizeof(struct ixgbe_legacy_tx_desc)); - txctrl = IXGBE_READ_REG(hw, IXGBE_VFDCA_TXCTRL(i)); - txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; - IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(i), txctrl); - - /* Now enable */ - txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); - txdctl |= IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl); - } - - return; -} - - -/********************************************************************* - * - * Setup receive registers and features. - * - **********************************************************************/ -#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 - -static void -ixv_initialize_receive_units(struct adapter *adapter) -{ - struct rx_ring *rxr = adapter->rx_rings; - struct ixgbe_hw *hw = &adapter->hw; - struct ifnet *ifp = adapter->ifp; - u32 bufsz, rxcsum, psrtype; - - if (ifp->if_mtu > ETHERMTU) - bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; - else - bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; - - psrtype = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR | - IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR | - IXGBE_PSRTYPE_L2HDR; - - IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); - - /* Tell PF our max_frame size */ - ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size); - - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - u64 rdba = rxr->rxdma.dma_paddr; - u32 reg, rxdctl; - - /* Disable the queue */ - rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); - rxdctl &= ~IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); - for (int j = 0; j < 10; j++) { - if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & - IXGBE_RXDCTL_ENABLE) - msec_delay(1); - else - break; - } - wmb(); - /* Setup the Base and Length of the Rx Descriptor Ring */ - IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(i), - (rdba & 0x00000000ffffffffULL)); - IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(i), - (rdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(i), - adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc)); - - /* Reset the ring indices */ - IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 0); - - /* Set up the SRRCTL register */ - reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); - reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; - reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; - reg |= bufsz; - reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; - IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), reg); - - /* Capture Rx Tail index */ - rxr->tail = IXGBE_VFRDT(rxr->me); - - /* Do the queue enabling last */ - rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; - IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); - for (int k = 0; k < 10; k++) { - if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & - IXGBE_RXDCTL_ENABLE) - break; - else - msec_delay(1); - } - wmb(); - - /* Set the Tail Pointer */ -#ifdef DEV_NETMAP - /* - * In netmap mode, we must preserve the buffers made - * available to userspace before the if_init() - * (this is true by default on the TX side, because - * init makes all buffers available to userspace). - * - * netmap_reset() and the device specific routines - * (e.g. ixgbe_setup_receive_rings()) map these - * buffers at the end of the NIC ring, so here we - * must set the RDT (tail) register to make sure - * they are not overwritten. - * - * In this driver the NIC ring starts at RDH = 0, - * RDT points to the last slot available for reception (?), - * so RDT = num_rx_desc - 1 means the whole ring is available. - */ - if (ifp->if_capenable & IFCAP_NETMAP) { - struct netmap_adapter *na = NA(adapter->ifp); - struct netmap_kring *kring = &na->rx_rings[i]; - int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring); - - IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t); - } else -#endif /* DEV_NETMAP */ - IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), - adapter->num_rx_desc - 1); - } - - rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); - - if (ifp->if_capenable & IFCAP_RXCSUM) - rxcsum |= IXGBE_RXCSUM_PCSD; - - if (!(rxcsum & IXGBE_RXCSUM_PCSD)) - rxcsum |= IXGBE_RXCSUM_IPPCSE; - - IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); - - return; -} - -static void -ixv_setup_vlan_support(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 ctrl, vid, vfta, retry; - struct rx_ring *rxr; - - /* - ** We get here thru init_locked, meaning - ** a soft reset, this has already cleared - ** the VFTA and other state, so if there - ** have been no vlan's registered do nothing. - */ - if (adapter->num_vlans == 0) - return; - - /* Enable the queues */ - for (int i = 0; i < adapter->num_queues; i++) { - ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); - ctrl |= IXGBE_RXDCTL_VME; - IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl); - /* - * Let Rx path know that it needs to store VLAN tag - * as part of extra mbuf info. - */ - rxr = &adapter->rx_rings[i]; - rxr->vtag_strip = TRUE; - } - - /* - ** A soft reset zero's out the VFTA, so - ** we need to repopulate it now. - */ - for (int i = 0; i < IXGBE_VFTA_SIZE; i++) { - if (ixv_shadow_vfta[i] == 0) - continue; - vfta = ixv_shadow_vfta[i]; - /* - ** Reconstruct the vlan id's - ** based on the bits set in each - ** of the array ints. - */ - for (int j = 0; j < 32; j++) { - retry = 0; - if ((vfta & (1 << j)) == 0) - continue; - vid = (i * 32) + j; - /* Call the shared code mailbox routine */ - while (ixgbe_set_vfta(hw, vid, 0, TRUE)) { - if (++retry > 5) - break; - } - } - } -} - -/* -** This routine is run via an vlan config EVENT, -** it enables us to use the HW Filter table since -** we can get the vlan id. This just creates the -** entry in the soft version of the VFTA, init will -** repopulate the real table. -*/ -static void -ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) -{ - struct adapter *adapter = ifp->if_softc; - u16 index, bit; - - if (ifp->if_softc != arg) /* Not our event */ - return; - - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ - return; - - IXGBE_CORE_LOCK(adapter); - index = (vtag >> 5) & 0x7F; - bit = vtag & 0x1F; - ixv_shadow_vfta[index] |= (1 << bit); - ++adapter->num_vlans; - /* Re-init to load the changes */ - ixv_init_locked(adapter); - IXGBE_CORE_UNLOCK(adapter); -} - -/* -** This routine is run via an vlan -** unconfig EVENT, remove our entry -** in the soft vfta. -*/ -static void -ixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) -{ - struct adapter *adapter = ifp->if_softc; - u16 index, bit; - - if (ifp->if_softc != arg) - return; - - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ - return; - - IXGBE_CORE_LOCK(adapter); - index = (vtag >> 5) & 0x7F; - bit = vtag & 0x1F; - ixv_shadow_vfta[index] &= ~(1 << bit); - --adapter->num_vlans; - /* Re-init to load the changes */ - ixv_init_locked(adapter); - IXGBE_CORE_UNLOCK(adapter); -} - -static void -ixv_enable_intr(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct ix_queue *que = adapter->queues; - u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); - - - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); - - mask = IXGBE_EIMS_ENABLE_MASK; - mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC); - IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask); - - for (int i = 0; i < adapter->num_queues; i++, que++) - ixv_enable_queue(adapter, que->msix); - - IXGBE_WRITE_FLUSH(hw); - - return; -} - -static void -ixv_disable_intr(struct adapter *adapter) -{ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIAC, 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, ~0); - IXGBE_WRITE_FLUSH(&adapter->hw); - return; -} - -/* -** Setup the correct IVAR register for a particular MSIX interrupt -** - entry is the register array entry -** - vector is the MSIX vector for this queue -** - type is RX/TX/MISC -*/ -static void -ixv_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 ivar, index; - - vector |= IXGBE_IVAR_ALLOC_VAL; - - if (type == -1) { /* MISC IVAR */ - ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC); - ivar &= ~0xFF; - ivar |= vector; - IXGBE_WRITE_REG(hw, IXGBE_VTIVAR_MISC, ivar); - } else { /* RX/TX IVARS */ - index = (16 * (entry & 1)) + (8 * type); - ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR(entry >> 1)); - ivar &= ~(0xFF << index); - ivar |= (vector << index); - IXGBE_WRITE_REG(hw, IXGBE_VTIVAR(entry >> 1), ivar); - } -} - -static void -ixv_configure_ivars(struct adapter *adapter) -{ - struct ix_queue *que = adapter->queues; - - for (int i = 0; i < adapter->num_queues; i++, que++) { - /* First the RX queue entry */ - ixv_set_ivar(adapter, i, que->msix, 0); - /* ... and the TX */ - ixv_set_ivar(adapter, i, que->msix, 1); - /* Set an initial value in EITR */ - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_VTEITR(que->msix), IXV_EITR_DEFAULT); - } - - /* For the mailbox interrupt */ - ixv_set_ivar(adapter, 1, adapter->vector, -1); -} - - -/* -** Tasklet handler for MSIX MBX interrupts -** - do outside interrupt since it might sleep -*/ -static void -ixv_handle_mbx(void *context, int pending) -{ - struct adapter *adapter = context; - - ixgbe_check_link(&adapter->hw, - &adapter->link_speed, &adapter->link_up, 0); + adapter->hw.mac.ops.check_link(&adapter->hw, &adapter->link_speed, + &adapter->link_up, FALSE); ixv_update_link_status(adapter); -} +} /* ixv_handle_link */ -/* -** The VF stats registers never have a truly virgin -** starting point, so this routine tries to make an -** artificial one, marking ground zero on attach as -** it were. -*/ +/************************************************************************ + * ixv_check_link - Used in the local timer to poll for link changes + ************************************************************************/ static void -ixv_save_stats(struct adapter *adapter) +ixv_check_link(struct adapter *adapter) { - if (adapter->stats.vf.vfgprc || adapter->stats.vf.vfgptc) { - adapter->stats.vf.saved_reset_vfgprc += - adapter->stats.vf.vfgprc - adapter->stats.vf.base_vfgprc; - adapter->stats.vf.saved_reset_vfgptc += - adapter->stats.vf.vfgptc - adapter->stats.vf.base_vfgptc; - adapter->stats.vf.saved_reset_vfgorc += - adapter->stats.vf.vfgorc - adapter->stats.vf.base_vfgorc; - adapter->stats.vf.saved_reset_vfgotc += - adapter->stats.vf.vfgotc - adapter->stats.vf.base_vfgotc; - adapter->stats.vf.saved_reset_vfmprc += - adapter->stats.vf.vfmprc - adapter->stats.vf.base_vfmprc; - } -} - -static void -ixv_init_stats(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - - adapter->stats.vf.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC); - adapter->stats.vf.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB); - adapter->stats.vf.last_vfgorc |= - (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32); + adapter->hw.mac.get_link_status = TRUE; - adapter->stats.vf.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC); - adapter->stats.vf.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB); - adapter->stats.vf.last_vfgotc |= - (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32); - - adapter->stats.vf.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC); - - adapter->stats.vf.base_vfgprc = adapter->stats.vf.last_vfgprc; - adapter->stats.vf.base_vfgorc = adapter->stats.vf.last_vfgorc; - adapter->stats.vf.base_vfgptc = adapter->stats.vf.last_vfgptc; - adapter->stats.vf.base_vfgotc = adapter->stats.vf.last_vfgotc; - adapter->stats.vf.base_vfmprc = adapter->stats.vf.last_vfmprc; -} - -#define UPDATE_STAT_32(reg, last, count) \ -{ \ - u32 current = IXGBE_READ_REG(hw, reg); \ - if (current < last) \ - count += 0x100000000LL; \ - last = current; \ - count &= 0xFFFFFFFF00000000LL; \ - count |= current; \ -} - -#define UPDATE_STAT_36(lsb, msb, last, count) \ -{ \ - u64 cur_lsb = IXGBE_READ_REG(hw, lsb); \ - u64 cur_msb = IXGBE_READ_REG(hw, msb); \ - u64 current = ((cur_msb << 32) | cur_lsb); \ - if (current < last) \ - count += 0x1000000000LL; \ - last = current; \ - count &= 0xFFFFFFF000000000LL; \ - count |= current; \ -} - -/* -** ixv_update_stats - Update the board statistics counters. -*/ -void -ixv_update_stats(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - - UPDATE_STAT_32(IXGBE_VFGPRC, adapter->stats.vf.last_vfgprc, - adapter->stats.vf.vfgprc); - UPDATE_STAT_32(IXGBE_VFGPTC, adapter->stats.vf.last_vfgptc, - adapter->stats.vf.vfgptc); - UPDATE_STAT_36(IXGBE_VFGORC_LSB, IXGBE_VFGORC_MSB, - adapter->stats.vf.last_vfgorc, adapter->stats.vf.vfgorc); - UPDATE_STAT_36(IXGBE_VFGOTC_LSB, IXGBE_VFGOTC_MSB, - adapter->stats.vf.last_vfgotc, adapter->stats.vf.vfgotc); - UPDATE_STAT_32(IXGBE_VFMPRC, adapter->stats.vf.last_vfmprc, - adapter->stats.vf.vfmprc); -} - -/* - * Add statistic sysctls for the VF. - */ -static void -ixv_add_stats_sysctls(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct ix_queue *que = &adapter->queues[0]; - struct tx_ring *txr = que->txr; - struct rx_ring *rxr = que->rxr; - - struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); - struct sysctl_oid *tree = device_get_sysctl_tree(dev); - struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); - struct ixgbevf_hw_stats *stats = &adapter->stats.vf; - - struct sysctl_oid *stat_node, *queue_node; - struct sysctl_oid_list *stat_list, *queue_list; - - /* Driver Statistics */ - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped", - CTLFLAG_RD, &adapter->dropped_pkts, - "Driver dropped packets"); - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_failed", - CTLFLAG_RD, &adapter->mbuf_defrag_failed, - "m_defrag() failed"); - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_events", - CTLFLAG_RD, &adapter->watchdog_events, - "Watchdog timeouts"); - - stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac", - CTLFLAG_RD, NULL, - "VF Statistics (read from HW registers)"); - stat_list = SYSCTL_CHILDREN(stat_node); - - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd", - CTLFLAG_RD, &stats->vfgprc, - "Good Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd", - CTLFLAG_RD, &stats->vfgorc, - "Good Octets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd", - CTLFLAG_RD, &stats->vfmprc, - "Multicast Packets Received"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd", - CTLFLAG_RD, &stats->vfgptc, - "Good Packets Transmitted"); - SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", - CTLFLAG_RD, &stats->vfgotc, - "Good Octets Transmitted"); - - queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "que", - CTLFLAG_RD, NULL, - "Queue Statistics (collected by SW)"); - queue_list = SYSCTL_CHILDREN(queue_node); - - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs", - CTLFLAG_RD, &(que->irqs), - "IRQs on queue"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_irqs", - CTLFLAG_RD, &(rxr->rx_irq), - "RX irqs on queue"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets", - CTLFLAG_RD, &(rxr->rx_packets), - "RX packets"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes", - CTLFLAG_RD, &(rxr->rx_bytes), - "RX bytes"); - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_discarded", - CTLFLAG_RD, &(rxr->rx_discarded), - "Discarded RX packets"); - - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets", - CTLFLAG_RD, &(txr->total_packets), - "TX Packets"); - - SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc", - CTLFLAG_RD, &(txr->no_desc_avail), - "# of times not enough descriptors were available during TX"); -} - -static void -ixv_set_sysctl_value(struct adapter *adapter, const char *name, - const char *description, int *limit, int value) -{ - *limit = value; - SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), - OID_AUTO, name, CTLFLAG_RW, limit, value, description); -} - -/********************************************************************** - * - * This routine is called only when em_display_debug_stats is enabled. - * This routine provides a way to take a look at important statistics - * maintained by the driver and hardware. - * - **********************************************************************/ -static void -ixv_print_debug_info(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct ixgbe_hw *hw = &adapter->hw; - struct ix_queue *que = adapter->queues; - struct rx_ring *rxr; - struct tx_ring *txr; - struct lro_ctrl *lro; - - device_printf(dev,"Error Byte Count = %u \n", - IXGBE_READ_REG(hw, IXGBE_ERRBC)); - - for (int i = 0; i < adapter->num_queues; i++, que++) { - txr = que->txr; - rxr = que->rxr; - lro = &rxr->lro; - device_printf(dev,"QUE(%d) IRQs Handled: %lu\n", - que->msix, (long)que->irqs); - device_printf(dev,"RX(%d) Packets Received: %lld\n", - rxr->me, (long long)rxr->rx_packets); - device_printf(dev,"RX(%d) Bytes Received: %lu\n", - rxr->me, (long)rxr->rx_bytes); - device_printf(dev,"RX(%d) LRO Queued= %lld\n", - rxr->me, (long long)lro->lro_queued); - device_printf(dev,"RX(%d) LRO Flushed= %lld\n", - rxr->me, (long long)lro->lro_flushed); - device_printf(dev,"TX(%d) Packets Sent: %lu\n", - txr->me, (long)txr->total_packets); - device_printf(dev,"TX(%d) NO Desc Avail: %lu\n", - txr->me, (long)txr->no_desc_avail); - } - - device_printf(dev,"MBX IRQ Handled: %lu\n", - (long)adapter->link_irq); - return; -} - -static int -ixv_sysctl_debug(SYSCTL_HANDLER_ARGS) -{ - int error, result; - struct adapter *adapter; - - result = -1; - error = sysctl_handle_int(oidp, &result, 0, req); - - if (error || !req->newptr) - return (error); - - if (result == 1) { - adapter = (struct adapter *) arg1; - ixv_print_debug_info(adapter); - } - return error; -} + adapter->hw.mac.ops.check_link(&adapter->hw, &adapter->link_speed, + &adapter->link_up, FALSE); + ixv_update_link_status(adapter); +} /* ixv_check_link */ diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c new file mode 100644 index 000000000000..8653fceec14b --- /dev/null +++ b/sys/dev/ixgbe/if_sriov.c @@ -0,0 +1,914 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#include "ixgbe.h" + +#ifdef PCI_IOV + +MALLOC_DEFINE(M_IXGBE_SRIOV, "ix_sriov", "ix SR-IOV allocations"); + +/************************************************************************ + * ixgbe_pci_iov_detach + ************************************************************************/ +int +ixgbe_pci_iov_detach(device_t dev) +{ + return pci_iov_detach(dev); +} + +/************************************************************************ + * ixgbe_define_iov_schemas + ************************************************************************/ +void +ixgbe_define_iov_schemas(device_t dev, int *error) +{ + nvlist_t *pf_schema, *vf_schema; + + pf_schema = pci_iov_schema_alloc_node(); + vf_schema = pci_iov_schema_alloc_node(); + pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL); + pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof", + IOV_SCHEMA_HASDEFAULT, TRUE); + pci_iov_schema_add_bool(vf_schema, "allow-set-mac", + IOV_SCHEMA_HASDEFAULT, FALSE); + pci_iov_schema_add_bool(vf_schema, "allow-promisc", + IOV_SCHEMA_HASDEFAULT, FALSE); + *error = pci_iov_attach(dev, pf_schema, vf_schema); + if (*error != 0) { + device_printf(dev, + "Error %d setting up SR-IOV\n", *error); + } +} /* ixgbe_define_iov_schemas */ + +/************************************************************************ + * ixgbe_align_all_queue_indices + ************************************************************************/ +inline void +ixgbe_align_all_queue_indices(struct adapter *adapter) +{ + int i; + int index; + + for (i = 0; i < adapter->num_queues; i++) { + index = ixgbe_vf_que_index(adapter->iov_mode, adapter->pool, i); + adapter->rx_rings[i].me = index; + adapter->tx_rings[i].me = index; + } +} + +/* Support functions for SR-IOV/VF management */ +static inline void +ixgbe_send_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) +{ + if (vf->flags & IXGBE_VF_CTS) + msg |= IXGBE_VT_MSGTYPE_CTS; + + adapter->hw.mbx.ops.write(&adapter->hw, &msg, 1, vf->pool); +} + +static inline void +ixgbe_send_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) +{ + msg &= IXGBE_VT_MSG_MASK; + ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_ACK); +} + +static inline void +ixgbe_send_vf_nack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) +{ + msg &= IXGBE_VT_MSG_MASK; + ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_NACK); +} + +static inline void +ixgbe_process_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf) +{ + if (!(vf->flags & IXGBE_VF_CTS)) + ixgbe_send_vf_nack(adapter, vf, 0); +} + +static inline boolean_t +ixgbe_vf_mac_changed(struct ixgbe_vf *vf, const uint8_t *mac) +{ + return (bcmp(mac, vf->ether_addr, ETHER_ADDR_LEN) != 0); +} + +static inline int +ixgbe_vf_queues(int mode) +{ + switch (mode) { + case IXGBE_64_VM: + return (2); + case IXGBE_32_VM: + return (4); + case IXGBE_NO_VM: + default: + return (0); + } +} + +inline int +ixgbe_vf_que_index(int mode, int vfnum, int num) +{ + return ((vfnum * ixgbe_vf_queues(mode)) + num); +} + +static inline void +ixgbe_update_max_frame(struct adapter * adapter, int max_frame) +{ + if (adapter->max_frame_size < max_frame) + adapter->max_frame_size = max_frame; +} + +inline u32 +ixgbe_get_mrqc(int iov_mode) +{ + u32 mrqc; + + switch (iov_mode) { + case IXGBE_64_VM: + mrqc = IXGBE_MRQC_VMDQRSS64EN; + break; + case IXGBE_32_VM: + mrqc = IXGBE_MRQC_VMDQRSS32EN; + break; + case IXGBE_NO_VM: + mrqc = 0; + break; + default: + panic("Unexpected SR-IOV mode %d", iov_mode); + } + + return mrqc; +} + + +inline u32 +ixgbe_get_mtqc(int iov_mode) +{ + uint32_t mtqc; + + switch (iov_mode) { + case IXGBE_64_VM: + mtqc = IXGBE_MTQC_64VF | IXGBE_MTQC_VT_ENA; + break; + case IXGBE_32_VM: + mtqc = IXGBE_MTQC_32VF | IXGBE_MTQC_VT_ENA; + break; + case IXGBE_NO_VM: + mtqc = IXGBE_MTQC_64Q_1PB; + break; + default: + panic("Unexpected SR-IOV mode %d", iov_mode); + } + + return mtqc; +} + +void +ixgbe_ping_all_vfs(struct adapter *adapter) +{ + struct ixgbe_vf *vf; + + for (int i = 0; i < adapter->num_vfs; i++) { + vf = &adapter->vfs[i]; + if (vf->flags & IXGBE_VF_ACTIVE) + ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG); + } +} /* ixgbe_ping_all_vfs */ + + +static void +ixgbe_vf_set_default_vlan(struct adapter *adapter, struct ixgbe_vf *vf, + uint16_t tag) +{ + struct ixgbe_hw *hw; + uint32_t vmolr, vmvir; + + hw = &adapter->hw; + + vf->vlan_tag = tag; + + vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf->pool)); + + /* Do not receive packets that pass inexact filters. */ + vmolr &= ~(IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE); + + /* Disable Multicast Promicuous Mode. */ + vmolr &= ~IXGBE_VMOLR_MPE; + + /* Accept broadcasts. */ + vmolr |= IXGBE_VMOLR_BAM; + + if (tag == 0) { + /* Accept non-vlan tagged traffic. */ + //vmolr |= IXGBE_VMOLR_AUPE; + + /* Allow VM to tag outgoing traffic; no default tag. */ + vmvir = 0; + } else { + /* Require vlan-tagged traffic. */ + vmolr &= ~IXGBE_VMOLR_AUPE; + + /* Tag all traffic with provided vlan tag. */ + vmvir = (tag | IXGBE_VMVIR_VLANA_DEFAULT); + } + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf->pool), vmolr); + IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf->pool), vmvir); +} /* ixgbe_vf_set_default_vlan */ + + +static boolean_t +ixgbe_vf_frame_size_compatible(struct adapter *adapter, struct ixgbe_vf *vf) +{ + + /* + * Frame size compatibility between PF and VF is only a problem on + * 82599-based cards. X540 and later support any combination of jumbo + * frames on PFs and VFs. + */ + if (adapter->hw.mac.type != ixgbe_mac_82599EB) + return (TRUE); + + switch (vf->api_ver) { + case IXGBE_API_VER_1_0: + case IXGBE_API_VER_UNKNOWN: + /* + * On legacy (1.0 and older) VF versions, we don't support jumbo + * frames on either the PF or the VF. + */ + if (adapter->max_frame_size > ETHER_MAX_LEN || + vf->max_frame_size > ETHER_MAX_LEN) + return (FALSE); + + return (TRUE); + + break; + case IXGBE_API_VER_1_1: + default: + /* + * 1.1 or later VF versions always work if they aren't using + * jumbo frames. + */ + if (vf->max_frame_size <= ETHER_MAX_LEN) + return (TRUE); + + /* + * Jumbo frames only work with VFs if the PF is also using jumbo + * frames. + */ + if (adapter->max_frame_size <= ETHER_MAX_LEN) + return (TRUE); + + return (FALSE); + + } +} /* ixgbe_vf_frame_size_compatible */ + + +static void +ixgbe_process_vf_reset(struct adapter *adapter, struct ixgbe_vf *vf) +{ + ixgbe_vf_set_default_vlan(adapter, vf, vf->default_vlan); + + // XXX clear multicast addresses + + ixgbe_clear_rar(&adapter->hw, vf->rar_index); + + vf->api_ver = IXGBE_API_VER_UNKNOWN; +} /* ixgbe_process_vf_reset */ + + +static void +ixgbe_vf_enable_transmit(struct adapter *adapter, struct ixgbe_vf *vf) +{ + struct ixgbe_hw *hw; + uint32_t vf_index, vfte; + + hw = &adapter->hw; + + vf_index = IXGBE_VF_INDEX(vf->pool); + vfte = IXGBE_READ_REG(hw, IXGBE_VFTE(vf_index)); + vfte |= IXGBE_VF_BIT(vf->pool); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_index), vfte); +} /* ixgbe_vf_enable_transmit */ + + +static void +ixgbe_vf_enable_receive(struct adapter *adapter, struct ixgbe_vf *vf) +{ + struct ixgbe_hw *hw; + uint32_t vf_index, vfre; + + hw = &adapter->hw; + + vf_index = IXGBE_VF_INDEX(vf->pool); + vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(vf_index)); + if (ixgbe_vf_frame_size_compatible(adapter, vf)) + vfre |= IXGBE_VF_BIT(vf->pool); + else + vfre &= ~IXGBE_VF_BIT(vf->pool); + IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_index), vfre); +} /* ixgbe_vf_enable_receive */ + + +static void +ixgbe_vf_reset_msg(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) +{ + struct ixgbe_hw *hw; + uint32_t ack; + uint32_t resp[IXGBE_VF_PERMADDR_MSG_LEN]; + + hw = &adapter->hw; + + ixgbe_process_vf_reset(adapter, vf); + + if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) { + ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr, + vf->pool, TRUE); + ack = IXGBE_VT_MSGTYPE_ACK; + } else + ack = IXGBE_VT_MSGTYPE_NACK; + + ixgbe_vf_enable_transmit(adapter, vf); + ixgbe_vf_enable_receive(adapter, vf); + + vf->flags |= IXGBE_VF_CTS; + + resp[0] = IXGBE_VF_RESET | ack | IXGBE_VT_MSGTYPE_CTS; + bcopy(vf->ether_addr, &resp[1], ETHER_ADDR_LEN); + resp[3] = hw->mac.mc_filter_type; + hw->mbx.ops.write(hw, resp, IXGBE_VF_PERMADDR_MSG_LEN, vf->pool); +} /* ixgbe_vf_reset_msg */ + + +static void +ixgbe_vf_set_mac(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) +{ + uint8_t *mac; + + mac = (uint8_t*)&msg[1]; + + /* Check that the VF has permission to change the MAC address. */ + if (!(vf->flags & IXGBE_VF_CAP_MAC) && ixgbe_vf_mac_changed(vf, mac)) { + ixgbe_send_vf_nack(adapter, vf, msg[0]); + return; + } + + if (ixgbe_validate_mac_addr(mac) != 0) { + ixgbe_send_vf_nack(adapter, vf, msg[0]); + return; + } + + bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN); + + ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr, vf->pool, + TRUE); + + ixgbe_send_vf_ack(adapter, vf, msg[0]); +} /* ixgbe_vf_set_mac */ + + +/* + * VF multicast addresses are set by using the appropriate bit in + * 1 of 128 32 bit addresses (4096 possible). + */ +static void +ixgbe_vf_set_mc_addr(struct adapter *adapter, struct ixgbe_vf *vf, u32 *msg) +{ + u16 *list = (u16*)&msg[1]; + int entries; + u32 vmolr, vec_bit, vec_reg, mta_reg; + + entries = (msg[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; + entries = min(entries, IXGBE_MAX_VF_MC); + + vmolr = IXGBE_READ_REG(&adapter->hw, IXGBE_VMOLR(vf->pool)); + + vf->num_mc_hashes = entries; + + /* Set the appropriate MTA bit */ + for (int i = 0; i < entries; i++) { + vf->mc_hash[i] = list[i]; + vec_reg = (vf->mc_hash[i] >> 5) & 0x7F; + vec_bit = vf->mc_hash[i] & 0x1F; + mta_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_MTA(vec_reg)); + mta_reg |= (1 << vec_bit); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_MTA(vec_reg), mta_reg); + } + + vmolr |= IXGBE_VMOLR_ROMPE; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_VMOLR(vf->pool), vmolr); + ixgbe_send_vf_ack(adapter, vf, msg[0]); +} /* ixgbe_vf_set_mc_addr */ + + +static void +ixgbe_vf_set_vlan(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) +{ + struct ixgbe_hw *hw; + int enable; + uint16_t tag; + + hw = &adapter->hw; + enable = IXGBE_VT_MSGINFO(msg[0]); + tag = msg[1] & IXGBE_VLVF_VLANID_MASK; + + if (!(vf->flags & IXGBE_VF_CAP_VLAN)) { + ixgbe_send_vf_nack(adapter, vf, msg[0]); + return; + } + + /* It is illegal to enable vlan tag 0. */ + if (tag == 0 && enable != 0){ + ixgbe_send_vf_nack(adapter, vf, msg[0]); + return; + } + + ixgbe_set_vfta(hw, tag, vf->pool, enable, false); + ixgbe_send_vf_ack(adapter, vf, msg[0]); +} /* ixgbe_vf_set_vlan */ + + +static void +ixgbe_vf_set_lpe(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) +{ + struct ixgbe_hw *hw; + uint32_t vf_max_size, pf_max_size, mhadd; + + hw = &adapter->hw; + vf_max_size = msg[1]; + + if (vf_max_size < ETHER_CRC_LEN) { + /* We intentionally ACK invalid LPE requests. */ + ixgbe_send_vf_ack(adapter, vf, msg[0]); + return; + } + + vf_max_size -= ETHER_CRC_LEN; + + if (vf_max_size > IXGBE_MAX_FRAME_SIZE) { + /* We intentionally ACK invalid LPE requests. */ + ixgbe_send_vf_ack(adapter, vf, msg[0]); + return; + } + + vf->max_frame_size = vf_max_size; + ixgbe_update_max_frame(adapter, vf->max_frame_size); + + /* + * We might have to disable reception to this VF if the frame size is + * not compatible with the config on the PF. + */ + ixgbe_vf_enable_receive(adapter, vf); + + mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); + pf_max_size = (mhadd & IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT; + + if (pf_max_size < adapter->max_frame_size) { + mhadd &= ~IXGBE_MHADD_MFS_MASK; + mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); + } + + ixgbe_send_vf_ack(adapter, vf, msg[0]); +} /* ixgbe_vf_set_lpe */ + + +static void +ixgbe_vf_set_macvlan(struct adapter *adapter, struct ixgbe_vf *vf, + uint32_t *msg) +{ + //XXX implement this + ixgbe_send_vf_nack(adapter, vf, msg[0]); +} /* ixgbe_vf_set_macvlan */ + + +static void +ixgbe_vf_api_negotiate(struct adapter *adapter, struct ixgbe_vf *vf, + uint32_t *msg) +{ + + switch (msg[1]) { + case IXGBE_API_VER_1_0: + case IXGBE_API_VER_1_1: + vf->api_ver = msg[1]; + ixgbe_send_vf_ack(adapter, vf, msg[0]); + break; + default: + vf->api_ver = IXGBE_API_VER_UNKNOWN; + ixgbe_send_vf_nack(adapter, vf, msg[0]); + break; + } +} /* ixgbe_vf_api_negotiate */ + + +static void +ixgbe_vf_get_queues(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) +{ + struct ixgbe_hw *hw; + uint32_t resp[IXGBE_VF_GET_QUEUES_RESP_LEN]; + int num_queues; + + hw = &adapter->hw; + + /* GET_QUEUES is not supported on pre-1.1 APIs. */ + switch (msg[0]) { + case IXGBE_API_VER_1_0: + case IXGBE_API_VER_UNKNOWN: + ixgbe_send_vf_nack(adapter, vf, msg[0]); + return; + } + + resp[0] = IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_ACK | + IXGBE_VT_MSGTYPE_CTS; + + num_queues = ixgbe_vf_queues(adapter->iov_mode); + resp[IXGBE_VF_TX_QUEUES] = num_queues; + resp[IXGBE_VF_RX_QUEUES] = num_queues; + resp[IXGBE_VF_TRANS_VLAN] = (vf->default_vlan != 0); + resp[IXGBE_VF_DEF_QUEUE] = 0; + + hw->mbx.ops.write(hw, resp, IXGBE_VF_GET_QUEUES_RESP_LEN, vf->pool); +} /* ixgbe_vf_get_queues */ + + +static void +ixgbe_process_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf) +{ + struct ixgbe_hw *hw; + uint32_t msg[IXGBE_VFMAILBOX_SIZE]; + int error; + + hw = &adapter->hw; + + error = hw->mbx.ops.read(hw, msg, IXGBE_VFMAILBOX_SIZE, vf->pool); + + if (error != 0) + return; + + CTR3(KTR_MALLOC, "%s: received msg %x from %d", + adapter->ifp->if_xname, msg[0], vf->pool); + if (msg[0] == IXGBE_VF_RESET) { + ixgbe_vf_reset_msg(adapter, vf, msg); + return; + } + + if (!(vf->flags & IXGBE_VF_CTS)) { + ixgbe_send_vf_nack(adapter, vf, msg[0]); + return; + } + + switch (msg[0] & IXGBE_VT_MSG_MASK) { + case IXGBE_VF_SET_MAC_ADDR: + ixgbe_vf_set_mac(adapter, vf, msg); + break; + case IXGBE_VF_SET_MULTICAST: + ixgbe_vf_set_mc_addr(adapter, vf, msg); + break; + case IXGBE_VF_SET_VLAN: + ixgbe_vf_set_vlan(adapter, vf, msg); + break; + case IXGBE_VF_SET_LPE: + ixgbe_vf_set_lpe(adapter, vf, msg); + break; + case IXGBE_VF_SET_MACVLAN: + ixgbe_vf_set_macvlan(adapter, vf, msg); + break; + case IXGBE_VF_API_NEGOTIATE: + ixgbe_vf_api_negotiate(adapter, vf, msg); + break; + case IXGBE_VF_GET_QUEUES: + ixgbe_vf_get_queues(adapter, vf, msg); + break; + default: + ixgbe_send_vf_nack(adapter, vf, msg[0]); + } +} /* ixgbe_process_vf_msg */ + + +/* Tasklet for handling VF -> PF mailbox messages */ +void +ixgbe_handle_mbx(void *context, int pending) +{ + struct adapter *adapter; + struct ixgbe_hw *hw; + struct ixgbe_vf *vf; + int i; + + adapter = context; + hw = &adapter->hw; + + IXGBE_CORE_LOCK(adapter); + for (i = 0; i < adapter->num_vfs; i++) { + vf = &adapter->vfs[i]; + + if (vf->flags & IXGBE_VF_ACTIVE) { + if (hw->mbx.ops.check_for_rst(hw, vf->pool) == 0) + ixgbe_process_vf_reset(adapter, vf); + + if (hw->mbx.ops.check_for_msg(hw, vf->pool) == 0) + ixgbe_process_vf_msg(adapter, vf); + + if (hw->mbx.ops.check_for_ack(hw, vf->pool) == 0) + ixgbe_process_vf_ack(adapter, vf); + } + } + IXGBE_CORE_UNLOCK(adapter); +} /* ixgbe_handle_mbx */ + +int +ixgbe_init_iov(device_t dev, u16 num_vfs, const nvlist_t *config) +{ + struct adapter *adapter; + int retval = 0; + + adapter = device_get_softc(dev); + adapter->iov_mode = IXGBE_NO_VM; + + if (num_vfs == 0) { + /* Would we ever get num_vfs = 0? */ + retval = EINVAL; + goto err_init_iov; + } + + /* + * We've got to reserve a VM's worth of queues for the PF, + * thus we go into "64 VF mode" if 32+ VFs are requested. + * With 64 VFs, you can only have two queues per VF. + * With 32 VFs, you can have up to four queues per VF. + */ + if (num_vfs >= IXGBE_32_VM) + adapter->iov_mode = IXGBE_64_VM; + else + adapter->iov_mode = IXGBE_32_VM; + + /* Again, reserving 1 VM's worth of queues for the PF */ + adapter->pool = adapter->iov_mode - 1; + + if ((num_vfs > adapter->pool) || (num_vfs >= IXGBE_64_VM)) { + retval = ENOSPC; + goto err_init_iov; + } + + IXGBE_CORE_LOCK(adapter); + + adapter->vfs = malloc(sizeof(*adapter->vfs) * num_vfs, M_IXGBE_SRIOV, + M_NOWAIT | M_ZERO); + + if (adapter->vfs == NULL) { + retval = ENOMEM; + IXGBE_CORE_UNLOCK(adapter); + goto err_init_iov; + } + + adapter->num_vfs = num_vfs; + adapter->init_locked(adapter); + adapter->feat_en |= IXGBE_FEATURE_SRIOV; + + IXGBE_CORE_UNLOCK(adapter); + + return retval; + +err_init_iov: + adapter->num_vfs = 0; + adapter->pool = 0; + adapter->iov_mode = IXGBE_NO_VM; + + return retval; +} /* ixgbe_init_iov */ + +void +ixgbe_uninit_iov(device_t dev) +{ + struct ixgbe_hw *hw; + struct adapter *adapter; + uint32_t pf_reg, vf_reg; + + adapter = device_get_softc(dev); + hw = &adapter->hw; + + IXGBE_CORE_LOCK(adapter); + + /* Enable rx/tx for the PF and disable it for all VFs. */ + pf_reg = IXGBE_VF_INDEX(adapter->pool); + IXGBE_WRITE_REG(hw, IXGBE_VFRE(pf_reg), IXGBE_VF_BIT(adapter->pool)); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(pf_reg), IXGBE_VF_BIT(adapter->pool)); + + if (pf_reg == 0) + vf_reg = 1; + else + vf_reg = 0; + IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), 0); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), 0); + + IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0); + + free(adapter->vfs, M_IXGBE_SRIOV); + adapter->vfs = NULL; + adapter->num_vfs = 0; + adapter->feat_en &= ~IXGBE_FEATURE_SRIOV; + + IXGBE_CORE_UNLOCK(adapter); +} /* ixgbe_uninit_iov */ + +static void +ixgbe_init_vf(struct adapter *adapter, struct ixgbe_vf *vf) +{ + struct ixgbe_hw *hw; + uint32_t vf_index, pfmbimr; + + IXGBE_CORE_LOCK_ASSERT(adapter); + + hw = &adapter->hw; + + if (!(vf->flags & IXGBE_VF_ACTIVE)) + return; + + vf_index = IXGBE_VF_INDEX(vf->pool); + pfmbimr = IXGBE_READ_REG(hw, IXGBE_PFMBIMR(vf_index)); + pfmbimr |= IXGBE_VF_BIT(vf->pool); + IXGBE_WRITE_REG(hw, IXGBE_PFMBIMR(vf_index), pfmbimr); + + ixgbe_vf_set_default_vlan(adapter, vf, vf->vlan_tag); + + // XXX multicast addresses + + if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) { + ixgbe_set_rar(&adapter->hw, vf->rar_index, + vf->ether_addr, vf->pool, TRUE); + } + + ixgbe_vf_enable_transmit(adapter, vf); + ixgbe_vf_enable_receive(adapter, vf); + + ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG); +} /* ixgbe_init_vf */ + +void +ixgbe_initialize_iov(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + uint32_t mrqc, mtqc, vt_ctl, vf_reg, gcr_ext, gpie; + int i; + + if (adapter->iov_mode == IXGBE_NO_VM) + return; + + IXGBE_CORE_LOCK_ASSERT(adapter); + + /* RMW appropriate registers based on IOV mode */ + /* Read... */ + mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC); + gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); + gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + /* Modify... */ + mrqc &= ~IXGBE_MRQC_MRQE_MASK; + mtqc = IXGBE_MTQC_VT_ENA; /* No initial MTQC read needed */ + gcr_ext |= IXGBE_GCR_EXT_MSIX_EN; + gcr_ext &= ~IXGBE_GCR_EXT_VT_MODE_MASK; + gpie &= ~IXGBE_GPIE_VTMODE_MASK; + switch (adapter->iov_mode) { + case IXGBE_64_VM: + mrqc |= IXGBE_MRQC_VMDQRSS64EN; + mtqc |= IXGBE_MTQC_64VF; + gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64; + gpie |= IXGBE_GPIE_VTMODE_64; + break; + case IXGBE_32_VM: + mrqc |= IXGBE_MRQC_VMDQRSS32EN; + mtqc |= IXGBE_MTQC_32VF; + gcr_ext |= IXGBE_GCR_EXT_VT_MODE_32; + gpie |= IXGBE_GPIE_VTMODE_32; + break; + default: + panic("Unexpected SR-IOV mode %d", adapter->iov_mode); + } + /* Write... */ + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + IXGBE_WRITE_REG(hw, IXGBE_MTQC, mtqc); + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); + + /* Enable rx/tx for the PF. */ + vf_reg = IXGBE_VF_INDEX(adapter->pool); + IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), IXGBE_VF_BIT(adapter->pool)); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), IXGBE_VF_BIT(adapter->pool)); + + /* Allow VM-to-VM communication. */ + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); + + vt_ctl = IXGBE_VT_CTL_VT_ENABLE | IXGBE_VT_CTL_REPLEN; + vt_ctl |= (adapter->pool << IXGBE_VT_CTL_POOL_SHIFT); + IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vt_ctl); + + for (i = 0; i < adapter->num_vfs; i++) + ixgbe_init_vf(adapter, &adapter->vfs[i]); +} /* ixgbe_initialize_iov */ + + +/* Check the max frame setting of all active VF's */ +void +ixgbe_recalculate_max_frame(struct adapter *adapter) +{ + struct ixgbe_vf *vf; + + IXGBE_CORE_LOCK_ASSERT(adapter); + + for (int i = 0; i < adapter->num_vfs; i++) { + vf = &adapter->vfs[i]; + if (vf->flags & IXGBE_VF_ACTIVE) + ixgbe_update_max_frame(adapter, vf->max_frame_size); + } +} /* ixgbe_recalculate_max_frame */ + +int +ixgbe_add_vf(device_t dev, u16 vfnum, const nvlist_t *config) +{ + struct adapter *adapter; + struct ixgbe_vf *vf; + const void *mac; + + adapter = device_get_softc(dev); + + KASSERT(vfnum < adapter->num_vfs, ("VF index %d is out of range %d", + vfnum, adapter->num_vfs)); + + IXGBE_CORE_LOCK(adapter); + vf = &adapter->vfs[vfnum]; + vf->pool= vfnum; + + /* RAR[0] is used by the PF so use vfnum + 1 for VF RAR. */ + vf->rar_index = vfnum + 1; + vf->default_vlan = 0; + vf->max_frame_size = ETHER_MAX_LEN; + ixgbe_update_max_frame(adapter, vf->max_frame_size); + + if (nvlist_exists_binary(config, "mac-addr")) { + mac = nvlist_get_binary(config, "mac-addr", NULL); + bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN); + if (nvlist_get_bool(config, "allow-set-mac")) + vf->flags |= IXGBE_VF_CAP_MAC; + } else + /* + * If the administrator has not specified a MAC address then + * we must allow the VF to choose one. + */ + vf->flags |= IXGBE_VF_CAP_MAC; + + vf->flags |= IXGBE_VF_ACTIVE; + + ixgbe_init_vf(adapter, vf); + IXGBE_CORE_UNLOCK(adapter); + + return (0); +} /* ixgbe_add_vf */ + +#else + +void +ixgbe_handle_mbx(void *context, int pending) +{ + UNREFERENCED_2PARAMETER(context, pending); +} /* ixgbe_handle_mbx */ + +inline int +ixgbe_vf_que_index(int mode, int vfnum, int num) +{ + UNREFERENCED_2PARAMETER(mode, vfnum); + + return num; +} /* ixgbe_vf_que_index */ + +#endif diff --git a/sys/dev/ixgbe/ix_txrx.c b/sys/dev/ixgbe/ix_txrx.c index 751c6f429424..0597493a7ca7 100644 --- a/sys/dev/ixgbe/ix_txrx.c +++ b/sys/dev/ixgbe/ix_txrx.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -41,81 +41,63 @@ #include "ixgbe.h" -#ifdef RSS -#include -#include -#endif - -#ifdef DEV_NETMAP -#include -#include -#include - -extern int ix_crcstrip; -#endif - /* -** HW RSC control: -** this feature only works with -** IPv4, and only on 82599 and later. -** Also this will cause IP forwarding to -** fail and that can't be controlled by -** the stack as LRO can. For all these -** reasons I've deemed it best to leave -** this off and not bother with a tuneable -** interface, this would need to be compiled -** to enable. -*/ + * HW RSC control: + * this feature only works with + * IPv4, and only on 82599 and later. + * Also this will cause IP forwarding to + * fail and that can't be controlled by + * the stack as LRO can. For all these + * reasons I've deemed it best to leave + * this off and not bother with a tuneable + * interface, this would need to be compiled + * to enable. + */ static bool ixgbe_rsc_enable = FALSE; -#ifdef IXGBE_FDIR /* -** For Flow Director: this is the -** number of TX packets we sample -** for the filter pool, this means -** every 20th packet will be probed. -** -** This feature can be disabled by -** setting this to 0. -*/ + * For Flow Director: this is the + * number of TX packets we sample + * for the filter pool, this means + * every 20th packet will be probed. + * + * This feature can be disabled by + * setting this to 0. + */ static int atr_sample_rate = 20; -#endif -/********************************************************************* +/************************************************************************ * Local Function prototypes - *********************************************************************/ -static void ixgbe_setup_transmit_ring(struct tx_ring *); -static void ixgbe_free_transmit_buffers(struct tx_ring *); -static int ixgbe_setup_receive_ring(struct rx_ring *); -static void ixgbe_free_receive_buffers(struct rx_ring *); - -static void ixgbe_rx_checksum(u32, struct mbuf *, u32); -static void ixgbe_refresh_mbufs(struct rx_ring *, int); -static int ixgbe_xmit(struct tx_ring *, struct mbuf **); -static int ixgbe_tx_ctx_setup(struct tx_ring *, - struct mbuf *, u32 *, u32 *); -static int ixgbe_tso_setup(struct tx_ring *, - struct mbuf *, u32 *, u32 *); -#ifdef IXGBE_FDIR -static void ixgbe_atr(struct tx_ring *, struct mbuf *); -#endif + ************************************************************************/ +static void ixgbe_setup_transmit_ring(struct tx_ring *); +static void ixgbe_free_transmit_buffers(struct tx_ring *); +static int ixgbe_setup_receive_ring(struct rx_ring *); +static void ixgbe_free_receive_buffers(struct rx_ring *); +static void ixgbe_rx_checksum(u32, struct mbuf *, u32); +static void ixgbe_refresh_mbufs(struct rx_ring *, int); +static int ixgbe_xmit(struct tx_ring *, struct mbuf **); +static int ixgbe_tx_ctx_setup(struct tx_ring *, + struct mbuf *, u32 *, u32 *); +static int ixgbe_tso_setup(struct tx_ring *, + struct mbuf *, u32 *, u32 *); static __inline void ixgbe_rx_discard(struct rx_ring *, int); static __inline void ixgbe_rx_input(struct rx_ring *, struct ifnet *, - struct mbuf *, u32); + struct mbuf *, u32); +static int ixgbe_dma_malloc(struct adapter *, bus_size_t, + struct ixgbe_dma_alloc *, int); +static void ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *); -#ifdef IXGBE_LEGACY_TX -/********************************************************************* - * Transmit entry point +/************************************************************************ + * ixgbe_legacy_start_locked - Transmit entry point * - * ixgbe_start is called by the stack to initiate a transmit. - * The driver will remain in this routine as long as there are - * packets to transmit and transmit resources are available. - * In case resources are not available stack is notified and - * the packet is requeued. - **********************************************************************/ - -void -ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp) + * Called by the stack to initiate a transmit. + * The driver will remain in this routine as long as there are + * packets to transmit and transmit resources are available. + * In case resources are not available, the stack is notified + * and the packet is requeued. + ************************************************************************/ +int +ixgbe_legacy_start_locked(struct ifnet *ifp, struct tx_ring *txr) { struct mbuf *m_head; struct adapter *adapter = txr->adapter; @@ -123,9 +105,9 @@ ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp) IXGBE_TX_LOCK_ASSERT(txr); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; + return (ENETDOWN); if (!adapter->link_active) - return; + return (ENETDOWN); while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { if (txr->tx_avail <= IXGBE_QUEUE_MIN_FREE) @@ -143,44 +125,42 @@ ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp) /* Send a copy of the frame to the BPF listener */ ETHER_BPF_MTAP(ifp, m_head); } - return; -} -/* - * Legacy TX start - called by the stack, this - * always uses the first tx ring, and should - * not be used with multiqueue tx enabled. - */ + return IXGBE_SUCCESS; +} /* ixgbe_legacy_start_locked */ + +/************************************************************************ + * ixgbe_legacy_start + * + * Called by the stack, this always uses the first tx ring, + * and should not be used with multiqueue tx enabled. + ************************************************************************/ void -ixgbe_start(struct ifnet *ifp) +ixgbe_legacy_start(struct ifnet *ifp) { struct adapter *adapter = ifp->if_softc; - struct tx_ring *txr = adapter->tx_rings; + struct tx_ring *txr = adapter->tx_rings; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { IXGBE_TX_LOCK(txr); - ixgbe_start_locked(txr, ifp); + ixgbe_legacy_start_locked(ifp, txr); IXGBE_TX_UNLOCK(txr); } - return; -} +} /* ixgbe_legacy_start */ -#else /* ! IXGBE_LEGACY_TX */ - -/* -** Multiqueue Transmit Entry Point -** (if_transmit function) -*/ +/************************************************************************ + * ixgbe_mq_start - Multiqueue Transmit Entry Point + * + * (if_transmit function) + ************************************************************************/ int ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m) { - struct adapter *adapter = ifp->if_softc; - struct ix_queue *que; - struct tx_ring *txr; - int i, err = 0; -#ifdef RSS - uint32_t bucket_id; -#endif + struct adapter *adapter = ifp->if_softc; + struct ix_queue *que; + struct tx_ring *txr; + int i, err = 0; + uint32_t bucket_id; /* * When doing RSS, map it to the same outbound queue @@ -190,17 +170,17 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m) * same bucket that the current CPU we're on is. */ if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) { -#ifdef RSS - if (rss_hash2bucket(m->m_pkthdr.flowid, - M_HASHTYPE_GET(m), &bucket_id) == 0) { + if ((adapter->feat_en & IXGBE_FEATURE_RSS) && + (rss_hash2bucket(m->m_pkthdr.flowid, M_HASHTYPE_GET(m), + &bucket_id) == 0)) { i = bucket_id % adapter->num_queues; #ifdef IXGBE_DEBUG if (bucket_id > adapter->num_queues) - if_printf(ifp, "bucket_id (%d) > num_queues " - "(%d)\n", bucket_id, adapter->num_queues); -#endif - } else + if_printf(ifp, + "bucket_id (%d) > num_queues (%d)\n", + bucket_id, adapter->num_queues); #endif + } else i = m->m_pkthdr.flowid % adapter->num_queues; } else i = curcpu % adapter->num_queues; @@ -222,17 +202,20 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m) taskqueue_enqueue(que->tq, &txr->txq_task); return (0); -} +} /* ixgbe_mq_start */ +/************************************************************************ + * ixgbe_mq_start_locked + ************************************************************************/ int ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) { - struct adapter *adapter = txr->adapter; - struct mbuf *next; - int enqueued = 0, err = 0; + struct mbuf *next; + int enqueued = 0, err = 0; - if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) || - adapter->link_active == 0) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return (ENETDOWN); + if (txr->adapter->link_active == 0) return (ENETDOWN); /* Process the queue */ @@ -244,12 +227,12 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) err = drbr_enqueue(ifp, txr->br, next); #else while ((next = drbr_peek(ifp, txr->br)) != NULL) { - if ((err = ixgbe_xmit(txr, &next)) != 0) { - if (next == NULL) { + err = ixgbe_xmit(txr, &next); + if (err != 0) { + if (next == NULL) drbr_advance(ifp, txr->br); - } else { + else drbr_putback(ifp, txr->br, next); - } #endif break; } @@ -257,16 +240,15 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) drbr_advance(ifp, txr->br); #endif enqueued++; -#if 0 // this is VF-only #if __FreeBSD_version >= 1100036 /* * Since we're looking at the tx ring, we can check * to see if we're a VF by examing our tail register * address. */ - if (txr->tail < IXGBE_TDT(0) && next->m_flags & M_MCAST) + if ((txr->adapter->feat_en & IXGBE_FEATURE_VF) && + (next->m_flags & M_MCAST)) if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); -#endif #endif /* Send a copy of the frame to the BPF listener */ ETHER_BPF_MTAP(ifp, next); @@ -277,37 +259,39 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) #endif } - if (txr->tx_avail < IXGBE_TX_CLEANUP_THRESHOLD) + if (txr->tx_avail < IXGBE_TX_CLEANUP_THRESHOLD(txr->adapter)) ixgbe_txeof(txr); return (err); -} +} /* ixgbe_mq_start_locked */ -/* - * Called from a taskqueue to drain queued transmit packets. - */ +/************************************************************************ + * ixgbe_deferred_mq_start + * + * Called from a taskqueue to drain queued transmit packets. + ************************************************************************/ void ixgbe_deferred_mq_start(void *arg, int pending) { struct tx_ring *txr = arg; struct adapter *adapter = txr->adapter; - struct ifnet *ifp = adapter->ifp; + struct ifnet *ifp = adapter->ifp; IXGBE_TX_LOCK(txr); if (!drbr_empty(ifp, txr->br)) ixgbe_mq_start_locked(ifp, txr); IXGBE_TX_UNLOCK(txr); -} +} /* ixgbe_deferred_mq_start */ -/* - * Flush all ring buffers - */ +/************************************************************************ + * ixgbe_qflush - Flush all ring buffers + ************************************************************************/ void ixgbe_qflush(struct ifnet *ifp) { - struct adapter *adapter = ifp->if_softc; - struct tx_ring *txr = adapter->tx_rings; - struct mbuf *m; + struct adapter *adapter = ifp->if_softc; + struct tx_ring *txr = adapter->tx_rings; + struct mbuf *m; for (int i = 0; i < adapter->num_queues; i++, txr++) { IXGBE_TX_LOCK(txr); @@ -316,47 +300,46 @@ ixgbe_qflush(struct ifnet *ifp) IXGBE_TX_UNLOCK(txr); } if_qflush(ifp); -} -#endif /* IXGBE_LEGACY_TX */ +} /* ixgbe_qflush */ -/********************************************************************* +/************************************************************************ + * ixgbe_xmit * - * This routine maps the mbufs to tx descriptors, allowing the - * TX engine to transmit the packets. - * - return 0 on success, positive on failure + * Maps the mbufs to tx descriptors, allowing the + * TX engine to transmit the packets. * - **********************************************************************/ - + * Return 0 on success, positive on failure + ************************************************************************/ static int ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) { - struct adapter *adapter = txr->adapter; - u32 olinfo_status = 0, cmd_type_len; - int i, j, error, nsegs; - int first; - bool remap = TRUE; - struct mbuf *m_head; - bus_dma_segment_t segs[adapter->num_segs]; - bus_dmamap_t map; - struct ixgbe_tx_buf *txbuf; + struct adapter *adapter = txr->adapter; + struct ixgbe_tx_buf *txbuf; union ixgbe_adv_tx_desc *txd = NULL; + struct mbuf *m_head; + int i, j, error, nsegs; + int first; + u32 olinfo_status = 0, cmd_type_len; + bool remap = TRUE; + bus_dma_segment_t segs[adapter->num_segs]; + bus_dmamap_t map; m_head = *m_headp; /* Basic descriptor defines */ - cmd_type_len = (IXGBE_ADVTXD_DTYP_DATA | + cmd_type_len = (IXGBE_ADVTXD_DTYP_DATA | IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT); if (m_head->m_flags & M_VLANTAG) - cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE; + cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE; - /* - * Important to capture the first descriptor - * used because it will contain the index of - * the one we tell the hardware to report back - */ - first = txr->next_avail_desc; + /* + * Important to capture the first descriptor + * used because it will contain the index of + * the one we tell the hardware to report back + */ + first = txr->next_avail_desc; txbuf = &txr->tx_buffers[first]; map = txbuf->map; @@ -364,8 +347,8 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) * Map the packet for DMA. */ retry: - error = bus_dmamap_load_mbuf_sg(txr->txtag, map, - *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf_sg(txr->txtag, map, *m_headp, segs, + &nsegs, BUS_DMA_NOWAIT); if (__predict_false(error)) { struct mbuf *m; @@ -420,16 +403,15 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) return (error); } -#ifdef IXGBE_FDIR /* Do the flow director magic */ - if ((txr->atr_sample) && (!adapter->fdir_reinit)) { + if ((adapter->feat_en & IXGBE_FEATURE_FDIR) && + (txr->atr_sample) && (!adapter->fdir_reinit)) { ++txr->atr_count; if (txr->atr_count >= atr_sample_rate) { ixgbe_atr(txr, m_head); txr->atr_count = 0; } } -#endif olinfo_status |= IXGBE_ADVTXD_CC; i = txr->next_avail_desc; @@ -444,15 +426,14 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) txd->read.buffer_addr = segaddr; txd->read.cmd_type_len = htole32(txr->txd_cmd | - cmd_type_len |seglen); + cmd_type_len | seglen); txd->read.olinfo_status = htole32(olinfo_status); if (++i == txr->num_desc) i = 0; } - txd->read.cmd_type_len |= - htole32(IXGBE_TXD_CMD_EOP | IXGBE_TXD_CMD_RS); + txd->read.cmd_type_len |= htole32(IXGBE_TXD_CMD_EOP | IXGBE_TXD_CMD_RS); txr->tx_avail -= nsegs; txr->next_avail_desc = i; @@ -467,12 +448,12 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) txbuf->map = map; bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE); - /* Set the EOP descriptor that will be marked done */ - txbuf = &txr->tx_buffers[first]; + /* Set the EOP descriptor that will be marked done */ + txbuf = &txr->tx_buffers[first]; txbuf->eop = txd; - bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* * Advance the Transmit Descriptor Tail (Tdt), this tells the * hardware that this frame is available to transmit. @@ -485,53 +466,57 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) txr->busy = 1; return (0); -} +} /* ixgbe_xmit */ -/********************************************************************* +/************************************************************************ + * ixgbe_allocate_transmit_buffers * - * Allocate memory for tx_buffer structures. The tx_buffer stores all - * the information needed to transmit a packet on the wire. This is - * called only once at attach, setup is done every reset. - * - **********************************************************************/ -int + * Allocate memory for tx_buffer structures. The tx_buffer stores all + * the information needed to transmit a packet on the wire. This is + * called only once at attach, setup is done every reset. + ************************************************************************/ +static int ixgbe_allocate_transmit_buffers(struct tx_ring *txr) { - struct adapter *adapter = txr->adapter; - device_t dev = adapter->dev; + struct adapter *adapter = txr->adapter; + device_t dev = adapter->dev; struct ixgbe_tx_buf *txbuf; - int error, i; + int error, i; /* * Setup DMA descriptor areas. */ - if ((error = bus_dma_tag_create( - bus_get_dma_tag(adapter->dev), /* parent */ - 1, 0, /* alignment, bounds */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - IXGBE_TSO_SIZE, /* maxsize */ - adapter->num_segs, /* nsegments */ - PAGE_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockfuncarg */ - &txr->txtag))) { - device_printf(dev,"Unable to allocate TX DMA tag\n"); + error = bus_dma_tag_create( + /* parent */ bus_get_dma_tag(adapter->dev), + /* alignment */ 1, + /* bounds */ 0, + /* lowaddr */ BUS_SPACE_MAXADDR, + /* highaddr */ BUS_SPACE_MAXADDR, + /* filter */ NULL, + /* filterarg */ NULL, + /* maxsize */ IXGBE_TSO_SIZE, + /* nsegments */ adapter->num_segs, + /* maxsegsize */ PAGE_SIZE, + /* flags */ 0, + /* lockfunc */ NULL, + /* lockfuncarg */ NULL, + &txr->txtag); + if (error != 0) { + device_printf(dev, "Unable to allocate TX DMA tag\n"); goto fail; } - if (!(txr->tx_buffers = - (struct ixgbe_tx_buf *) malloc(sizeof(struct ixgbe_tx_buf) * - adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO))) { + txr->tx_buffers = + (struct ixgbe_tx_buf *)malloc(sizeof(struct ixgbe_tx_buf) * + adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); + if (txr->tx_buffers == NULL) { device_printf(dev, "Unable to allocate tx_buffer memory\n"); error = ENOMEM; goto fail; } - /* Create the descriptor buffer dma maps */ + /* Create the descriptor buffer dma maps */ txbuf = txr->tx_buffers; for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) { error = bus_dmamap_create(txr->txtag, 0, &txbuf->map); @@ -545,41 +530,44 @@ ixgbe_allocate_transmit_buffers(struct tx_ring *txr) fail: /* We free all, it handles case where we are in the middle */ ixgbe_free_transmit_structures(adapter); - return (error); -} -/********************************************************************* - * - * Initialize a transmit ring. - * - **********************************************************************/ + return (error); +} /* ixgbe_allocate_transmit_buffers */ + +/************************************************************************ + * ixgbe_setup_transmit_ring - Initialize a transmit ring. + ************************************************************************/ static void ixgbe_setup_transmit_ring(struct tx_ring *txr) { - struct adapter *adapter = txr->adapter; - struct ixgbe_tx_buf *txbuf; + struct adapter *adapter = txr->adapter; + struct ixgbe_tx_buf *txbuf; #ifdef DEV_NETMAP struct netmap_adapter *na = NA(adapter->ifp); - struct netmap_slot *slot; + struct netmap_slot *slot; #endif /* DEV_NETMAP */ /* Clear the old ring contents */ IXGBE_TX_LOCK(txr); + #ifdef DEV_NETMAP - /* - * (under lock): if in netmap mode, do some consistency - * checks and set slot to entry 0 of the netmap ring. - */ - slot = netmap_reset(na, NR_TX, txr->me, 0); + if (adapter->feat_en & IXGBE_FEATURE_NETMAP) { + /* + * (under lock): if in netmap mode, do some consistency + * checks and set slot to entry 0 of the netmap ring. + */ + slot = netmap_reset(na, NR_TX, txr->me, 0); + } #endif /* DEV_NETMAP */ + bzero((void *)txr->tx_base, - (sizeof(union ixgbe_adv_tx_desc)) * adapter->num_tx_desc); + (sizeof(union ixgbe_adv_tx_desc)) * adapter->num_tx_desc); /* Reset indices */ txr->next_avail_desc = 0; txr->next_to_clean = 0; /* Free any existing tx buffers. */ - txbuf = txr->tx_buffers; + txbuf = txr->tx_buffers; for (int i = 0; i < txr->num_desc; i++, txbuf++) { if (txbuf->m_head != NULL) { bus_dmamap_sync(txr->txtag, txbuf->map, @@ -588,6 +576,7 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) m_freem(txbuf->m_head); txbuf->m_head = NULL; } + #ifdef DEV_NETMAP /* * In netmap mode, set the map for the packet buffer. @@ -599,21 +588,20 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) * (not here) nkr_hwofs can be negative. Function * netmap_idx_n2k() handles wraparounds properly. */ - if (slot) { + if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) && slot) { int si = netmap_idx_n2k(&na->tx_rings[txr->me], i); netmap_load_map(na, txr->txtag, txbuf->map, NMB(na, slot + si)); } #endif /* DEV_NETMAP */ + /* Clear the EOP descriptor pointer */ txbuf->eop = NULL; - } + } -#ifdef IXGBE_FDIR /* Set the rate at which we sample packets */ - if (adapter->hw.mac.type != ixgbe_mac_82598EB) + if (adapter->feat_en & IXGBE_FEATURE_FDIR) txr->atr_sample = atr_sample_rate; -#endif /* Set number of descriptors available */ txr->tx_avail = adapter->num_tx_desc; @@ -621,13 +609,11 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); IXGBE_TX_UNLOCK(txr); -} +} /* ixgbe_setup_transmit_ring */ -/********************************************************************* - * - * Initialize all transmit rings. - * - **********************************************************************/ +/************************************************************************ + * ixgbe_setup_transmit_structures - Initialize all transmit rings. + ************************************************************************/ int ixgbe_setup_transmit_structures(struct adapter *adapter) { @@ -637,13 +623,11 @@ ixgbe_setup_transmit_structures(struct adapter *adapter) ixgbe_setup_transmit_ring(txr); return (0); -} +} /* ixgbe_setup_transmit_structures */ -/********************************************************************* - * - * Free all transmit rings. - * - **********************************************************************/ +/************************************************************************ + * ixgbe_free_transmit_structures - Free all transmit rings. + ************************************************************************/ void ixgbe_free_transmit_structures(struct adapter *adapter) { @@ -657,19 +641,19 @@ ixgbe_free_transmit_structures(struct adapter *adapter) IXGBE_TX_LOCK_DESTROY(txr); } free(adapter->tx_rings, M_DEVBUF); -} +} /* ixgbe_free_transmit_structures */ -/********************************************************************* +/************************************************************************ + * ixgbe_free_transmit_buffers * - * Free transmit ring related data structures. - * - **********************************************************************/ + * Free transmit ring related data structures. + ************************************************************************/ static void ixgbe_free_transmit_buffers(struct tx_ring *txr) { - struct adapter *adapter = txr->adapter; + struct adapter *adapter = txr->adapter; struct ixgbe_tx_buf *tx_buffer; - int i; + int i; INIT_DEBUGOUT("ixgbe_free_transmit_ring: begin"); @@ -681,27 +665,21 @@ ixgbe_free_transmit_buffers(struct tx_ring *txr) if (tx_buffer->m_head != NULL) { bus_dmamap_sync(txr->txtag, tx_buffer->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(txr->txtag, - tx_buffer->map); + bus_dmamap_unload(txr->txtag, tx_buffer->map); m_freem(tx_buffer->m_head); tx_buffer->m_head = NULL; if (tx_buffer->map != NULL) { - bus_dmamap_destroy(txr->txtag, - tx_buffer->map); + bus_dmamap_destroy(txr->txtag, tx_buffer->map); tx_buffer->map = NULL; } } else if (tx_buffer->map != NULL) { - bus_dmamap_unload(txr->txtag, - tx_buffer->map); - bus_dmamap_destroy(txr->txtag, - tx_buffer->map); + bus_dmamap_unload(txr->txtag, tx_buffer->map); + bus_dmamap_destroy(txr->txtag, tx_buffer->map); tx_buffer->map = NULL; } } -#ifdef IXGBE_LEGACY_TX if (txr->br != NULL) buf_ring_free(txr->br, M_DEVBUF); -#endif if (txr->tx_buffers != NULL) { free(txr->tx_buffers, M_DEVBUF); txr->tx_buffers = NULL; @@ -710,60 +688,59 @@ ixgbe_free_transmit_buffers(struct tx_ring *txr) bus_dma_tag_destroy(txr->txtag); txr->txtag = NULL; } - return; -} +} /* ixgbe_free_transmit_buffers */ -/********************************************************************* +/************************************************************************ + * ixgbe_tx_ctx_setup * - * Advanced Context Descriptor setup for VLAN, CSUM or TSO - * - **********************************************************************/ - + * Advanced Context Descriptor setup for VLAN, CSUM or TSO + ************************************************************************/ static int ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, u32 *cmd_type_len, u32 *olinfo_status) { - struct adapter *adapter = txr->adapter; struct ixgbe_adv_tx_context_desc *TXD; - struct ether_vlan_header *eh; + struct ether_vlan_header *eh; #ifdef INET - struct ip *ip; + struct ip *ip; #endif #ifdef INET6 - struct ip6_hdr *ip6; + struct ip6_hdr *ip6; #endif - u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; - int ehdrlen, ip_hlen = 0; - u16 etype; - u8 ipproto = 0; - int offload = TRUE; - int ctxd = txr->next_avail_desc; - u16 vtag = 0; - caddr_t l3d; + int ehdrlen, ip_hlen = 0; + int offload = TRUE; + int ctxd = txr->next_avail_desc; + u32 vlan_macip_lens = 0; + u32 type_tucmd_mlhl = 0; + u16 vtag = 0; + u16 etype; + u8 ipproto = 0; + caddr_t l3d; /* First check if TSO is to be used */ - if (mp->m_pkthdr.csum_flags & (CSUM_IP_TSO|CSUM_IP6_TSO)) + if (mp->m_pkthdr.csum_flags & (CSUM_IP_TSO | CSUM_IP6_TSO)) return (ixgbe_tso_setup(txr, mp, cmd_type_len, olinfo_status)); if ((mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) == 0) offload = FALSE; /* Indicate the whole packet as payload when not doing TSO */ - *olinfo_status |= mp->m_pkthdr.len << IXGBE_ADVTXD_PAYLEN_SHIFT; + *olinfo_status |= mp->m_pkthdr.len << IXGBE_ADVTXD_PAYLEN_SHIFT; /* Now ready a context descriptor */ - TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd]; + TXD = (struct ixgbe_adv_tx_context_desc *)&txr->tx_base[ctxd]; /* - ** In advanced descriptors the vlan tag must - ** be placed into the context descriptor. Hence - ** we need to make one even if not doing offloads. - */ + * In advanced descriptors the vlan tag must + * be placed into the context descriptor. Hence + * we need to make one even if not doing offloads. + */ if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT); - } else if (!IXGBE_IS_X550VF(adapter) && (offload == FALSE)) + } else if (!(txr->adapter->feat_en & IXGBE_FEATURE_NEEDS_CTXD) && + (offload == FALSE)) return (0); /* @@ -787,8 +764,10 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, goto no_offloads; /* - * If the first mbuf only includes the ethernet header, jump to the next one - * XXX: This assumes the stack splits mbufs containing headers on header boundaries + * If the first mbuf only includes the ethernet header, + * jump to the next one + * XXX: This assumes the stack splits mbufs containing headers + * on header boundaries * XXX: And assumes the entire IP header is contained in one mbuf */ if (mp->m_len == ehdrlen && mp->m_next) @@ -828,19 +807,22 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, /* No support for offloads for non-L4 next headers */ switch (ipproto) { case IPPROTO_TCP: - if (mp->m_pkthdr.csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP)) + if (mp->m_pkthdr.csum_flags & + (CSUM_IP_TCP | CSUM_IP6_TCP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; else offload = false; break; case IPPROTO_UDP: - if (mp->m_pkthdr.csum_flags & (CSUM_IP_UDP | CSUM_IP6_UDP)) + if (mp->m_pkthdr.csum_flags & + (CSUM_IP_UDP | CSUM_IP6_UDP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP; else offload = false; break; case IPPROTO_SCTP: - if (mp->m_pkthdr.csum_flags & (CSUM_IP_SCTP | CSUM_IP6_SCTP)) + if (mp->m_pkthdr.csum_flags & + (CSUM_IP_SCTP | CSUM_IP6_SCTP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; else offload = false; @@ -868,32 +850,33 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, txr->next_avail_desc = ctxd; --txr->tx_avail; - return (0); -} + return (0); +} /* ixgbe_tx_ctx_setup */ -/********************************************************************** +/************************************************************************ + * ixgbe_tso_setup * - * Setup work for hardware segmentation offload (TSO) on - * adapters using advanced tx descriptors - * - **********************************************************************/ + * Setup work for hardware segmentation offload (TSO) on + * adapters using advanced tx descriptors + ************************************************************************/ static int -ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, - u32 *cmd_type_len, u32 *olinfo_status) +ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *cmd_type_len, + u32 *olinfo_status) { struct ixgbe_adv_tx_context_desc *TXD; - u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; - u32 mss_l4len_idx = 0, paylen; - u16 vtag = 0, eh_type; - int ctxd, ehdrlen, ip_hlen, tcp_hlen; - struct ether_vlan_header *eh; + struct ether_vlan_header *eh; #ifdef INET6 - struct ip6_hdr *ip6; + struct ip6_hdr *ip6; #endif #ifdef INET - struct ip *ip; + struct ip *ip; #endif - struct tcphdr *th; + struct tcphdr *th; + int ctxd, ehdrlen, ip_hlen, tcp_hlen; + u32 vlan_macip_lens = 0; + u32 type_tucmd_mlhl = 0; + u32 mss_l4len_idx = 0, paylen; + u16 vtag = 0, eh_type; /* * Determine where frame payload starts. @@ -909,19 +892,6 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, } switch (ntohs(eh_type)) { -#ifdef INET6 - case ETHERTYPE_IPV6: - ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); - /* XXX-BZ For now we do not pretend to support ext. hdrs. */ - if (ip6->ip6_nxt != IPPROTO_TCP) - return (ENXIO); - ip_hlen = sizeof(struct ip6_hdr); - ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); - th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen); - th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); - type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6; - break; -#endif #ifdef INET case ETHERTYPE_IP: ip = (struct ip *)(mp->m_data + ehdrlen); @@ -936,6 +906,18 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, /* Tell transmit desc to also do IPv4 checksum. */ *olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8; break; +#endif +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); + /* XXX-BZ For now we do not pretend to support ext. hdrs. */ + if (ip6->ip6_nxt != IPPROTO_TCP) + return (ENXIO); + ip_hlen = sizeof(struct ip6_hdr); + th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen); + th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); + type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6; + break; #endif default: panic("%s: CSUM_TSO but no supported IP version (0x%04x)", @@ -944,7 +926,7 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, } ctxd = txr->next_avail_desc; - TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd]; + TXD = (struct ixgbe_adv_tx_context_desc *)&txr->tx_base[ctxd]; tcp_hlen = th->th_off << 2; @@ -954,7 +936,7 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, /* VLAN MACLEN IPLEN */ if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); - vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT); + vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT); } vlan_macip_lens |= ehdrlen << IXGBE_ADVTXD_MACLEN_SHIFT; @@ -982,34 +964,33 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; *olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT; ++txr->tso_tx; + return (0); -} +} /* ixgbe_tso_setup */ -/********************************************************************** +/************************************************************************ + * ixgbe_txeof * - * Examine each tx_buffer in the used queue. If the hardware is done - * processing the packet then free associated resources. The - * tx_buffer is put back on the free queue. - * - **********************************************************************/ + * Examine each tx_buffer in the used queue. If the hardware is done + * processing the packet then free associated resources. The + * tx_buffer is put back on the free queue. + ************************************************************************/ void ixgbe_txeof(struct tx_ring *txr) { - struct adapter *adapter = txr->adapter; -#ifdef DEV_NETMAP - struct ifnet *ifp = adapter->ifp; -#endif - u32 work, processed = 0; - u32 limit = adapter->tx_process_limit; - struct ixgbe_tx_buf *buf; + struct adapter *adapter = txr->adapter; + struct ixgbe_tx_buf *buf; union ixgbe_adv_tx_desc *txd; + u32 work, processed = 0; + u32 limit = adapter->tx_process_limit; mtx_assert(&txr->tx_mtx, MA_OWNED); #ifdef DEV_NETMAP - if (ifp->if_capenable & IFCAP_NETMAP) { - struct netmap_adapter *na = NA(ifp); + if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) && + (adapter->ifp->if_capenable & IFCAP_NETMAP)) { + struct netmap_adapter *na = NA(adapter->ifp); struct netmap_kring *kring = &na->tx_rings[txr->me]; txd = txr->tx_base; bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, @@ -1030,8 +1011,8 @@ ixgbe_txeof(struct tx_ring *txr) */ if (!netmap_mitigate || (kring->nr_kflags < kring->nkr_num_slots && - txd[kring->nr_kflags].wb.status & IXGBE_TXD_STAT_DD)) { - netmap_tx_irq(ifp, txr->me); + txd[kring->nr_kflags].wb.status & IXGBE_TXD_STAT_DD)) { + netmap_tx_irq(adapter->ifp, txr->me); } return; } @@ -1047,8 +1028,8 @@ ixgbe_txeof(struct tx_ring *txr) buf = &txr->tx_buffers[work]; txd = &txr->tx_base[work]; work -= txr->num_desc; /* The distance to ring end */ - bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, - BUS_DMASYNC_POSTREAD); + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, + BUS_DMASYNC_POSTREAD); do { union ixgbe_adv_tx_desc *eop = buf->eop; @@ -1059,13 +1040,10 @@ ixgbe_txeof(struct tx_ring *txr) break; /* I/O not complete */ if (buf->m_head) { - txr->bytes += - buf->m_head->m_pkthdr.len; - bus_dmamap_sync(txr->txtag, - buf->map, + txr->bytes += buf->m_head->m_pkthdr.len; + bus_dmamap_sync(txr->txtag, buf->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(txr->txtag, - buf->map); + bus_dmamap_unload(txr->txtag, buf->map); m_freem(buf->m_head); buf->m_head = NULL; } @@ -1084,13 +1062,10 @@ ixgbe_txeof(struct tx_ring *txr) txd = txr->tx_base; } if (buf->m_head) { - txr->bytes += - buf->m_head->m_pkthdr.len; - bus_dmamap_sync(txr->txtag, - buf->map, + txr->bytes += buf->m_head->m_pkthdr.len; + bus_dmamap_sync(txr->txtag, buf->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(txr->txtag, - buf->map); + bus_dmamap_unload(txr->txtag, buf->map); m_freem(buf->m_head); buf->m_head = NULL; } @@ -1121,19 +1096,19 @@ ixgbe_txeof(struct tx_ring *txr) txr->next_to_clean = work; /* - ** Queue Hang detection, we know there's - ** work outstanding or the first return - ** would have been taken, so increment busy - ** if nothing managed to get cleaned, then - ** in local_timer it will be checked and - ** marked as HUNG if it exceeds a MAX attempt. - */ + * Queue Hang detection, we know there's + * work outstanding or the first return + * would have been taken, so increment busy + * if nothing managed to get cleaned, then + * in local_timer it will be checked and + * marked as HUNG if it exceeds a MAX attempt. + */ if ((processed == 0) && (txr->busy != IXGBE_QUEUE_HUNG)) ++txr->busy; /* - ** If anything gets cleaned we reset state to 1, - ** note this will turn off HUNG if its set. - */ + * If anything gets cleaned we reset state to 1, + * note this will turn off HUNG if its set. + */ if (processed) txr->busy = 1; @@ -1141,113 +1116,37 @@ ixgbe_txeof(struct tx_ring *txr) txr->busy = 0; return; -} +} /* ixgbe_txeof */ - -#ifdef IXGBE_FDIR -/* -** This routine parses packet headers so that Flow -** Director can make a hashed filter table entry -** allowing traffic flows to be identified and kept -** on the same cpu. This would be a performance -** hit, but we only do it at IXGBE_FDIR_RATE of -** packets. -*/ -static void -ixgbe_atr(struct tx_ring *txr, struct mbuf *mp) -{ - struct adapter *adapter = txr->adapter; - struct ix_queue *que; - struct ip *ip; - struct tcphdr *th; - struct udphdr *uh; - struct ether_vlan_header *eh; - union ixgbe_atr_hash_dword input = {.dword = 0}; - union ixgbe_atr_hash_dword common = {.dword = 0}; - int ehdrlen, ip_hlen; - u16 etype; - - eh = mtod(mp, struct ether_vlan_header *); - if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { - ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; - etype = eh->evl_proto; - } else { - ehdrlen = ETHER_HDR_LEN; - etype = eh->evl_encap_proto; - } - - /* Only handling IPv4 */ - if (etype != htons(ETHERTYPE_IP)) - return; - - ip = (struct ip *)(mp->m_data + ehdrlen); - ip_hlen = ip->ip_hl << 2; - - /* check if we're UDP or TCP */ - switch (ip->ip_p) { - case IPPROTO_TCP: - th = (struct tcphdr *)((caddr_t)ip + ip_hlen); - /* src and dst are inverted */ - common.port.dst ^= th->th_sport; - common.port.src ^= th->th_dport; - input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_TCPV4; - break; - case IPPROTO_UDP: - uh = (struct udphdr *)((caddr_t)ip + ip_hlen); - /* src and dst are inverted */ - common.port.dst ^= uh->uh_sport; - common.port.src ^= uh->uh_dport; - input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_UDPV4; - break; - default: - return; - } - - input.formatted.vlan_id = htobe16(mp->m_pkthdr.ether_vtag); - if (mp->m_pkthdr.ether_vtag) - common.flex_bytes ^= htons(ETHERTYPE_VLAN); - else - common.flex_bytes ^= etype; - common.ip ^= ip->ip_src.s_addr ^ ip->ip_dst.s_addr; - - que = &adapter->queues[txr->me]; - /* - ** This assumes the Rx queue and Tx - ** queue are bound to the same CPU - */ - ixgbe_fdir_add_signature_filter_82599(&adapter->hw, - input, common, que->msix); -} -#endif /* IXGBE_FDIR */ - -/* -** Used to detect a descriptor that has -** been merged by Hardware RSC. -*/ +/************************************************************************ + * ixgbe_rsc_count + * + * Used to detect a descriptor that has been merged by Hardware RSC. + ************************************************************************/ static inline u32 ixgbe_rsc_count(union ixgbe_adv_rx_desc *rx) { return (le32toh(rx->wb.lower.lo_dword.data) & IXGBE_RXDADV_RSCCNT_MASK) >> IXGBE_RXDADV_RSCCNT_SHIFT; -} +} /* ixgbe_rsc_count */ -/********************************************************************* +/************************************************************************ + * ixgbe_setup_hw_rsc * - * Initialize Hardware RSC (LRO) feature on 82599 - * for an RX ring, this is toggled by the LRO capability - * even though it is transparent to the stack. + * Initialize Hardware RSC (LRO) feature on 82599 + * for an RX ring, this is toggled by the LRO capability + * even though it is transparent to the stack. * - * NOTE: since this HW feature only works with IPV4 and - * our testing has shown soft LRO to be as effective - * I have decided to disable this by default. - * - **********************************************************************/ + * NOTE: Since this HW feature only works with IPv4 and + * testing has shown soft LRO to be as effective, + * this feature will be disabled by default. + ************************************************************************/ static void ixgbe_setup_hw_rsc(struct rx_ring *rxr) { - struct adapter *adapter = rxr->adapter; - struct ixgbe_hw *hw = &adapter->hw; - u32 rscctrl, rdrxctl; + struct adapter *adapter = rxr->adapter; + struct ixgbe_hw *hw = &adapter->hw; + u32 rscctrl, rdrxctl; /* If turning LRO/RSC off we need to disable it */ if ((adapter->ifp->if_capenable & IFCAP_LRO) == 0) { @@ -1258,19 +1157,22 @@ ixgbe_setup_hw_rsc(struct rx_ring *rxr) rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; -#ifdef DEV_NETMAP /* crcstrip is optional in netmap */ - if (adapter->ifp->if_capenable & IFCAP_NETMAP && !ix_crcstrip) +#ifdef DEV_NETMAP + /* Always strip CRC unless Netmap disabled it */ + if (!(adapter->feat_en & IXGBE_FEATURE_NETMAP) || + !(adapter->ifp->if_capenable & IFCAP_NETMAP) || + ix_crcstrip) #endif /* DEV_NETMAP */ - rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; + rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; rdrxctl |= IXGBE_RDRXCTL_RSCACKC; IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(rxr->me)); rscctrl |= IXGBE_RSCCTL_RSCEN; /* - ** Limit the total number of descriptors that - ** can be combined, so it does not exceed 64K - */ + * Limit the total number of descriptors that + * can be combined, so it does not exceed 64K + */ if (rxr->mbuf_sz == MCLBYTES) rscctrl |= IXGBE_RSCCTL_MAXDESC_16; else if (rxr->mbuf_sz == MJUMPAGESIZE) @@ -1284,34 +1186,33 @@ ixgbe_setup_hw_rsc(struct rx_ring *rxr) /* Enable TCP header recognition */ IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), - (IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0)) | - IXGBE_PSRTYPE_TCPHDR)); + (IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0)) | IXGBE_PSRTYPE_TCPHDR)); /* Disable RSC for ACK packets */ IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); rxr->hw_rsc = TRUE; -} +} /* ixgbe_setup_hw_rsc */ -/********************************************************************* +/************************************************************************ + * ixgbe_refresh_mbufs * - * Refresh mbuf buffers for RX descriptor rings - * - now keeps its own state so discards due to resource - * exhaustion are unnecessary, if an mbuf cannot be obtained - * it just returns, keeping its placeholder, thus it can simply - * be recalled to try again. - * - **********************************************************************/ + * Refresh mbuf buffers for RX descriptor rings + * - now keeps its own state so discards due to resource + * exhaustion are unnecessary, if an mbuf cannot be obtained + * it just returns, keeping its placeholder, thus it can simply + * be recalled to try again. + ************************************************************************/ static void ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit) { - struct adapter *adapter = rxr->adapter; - bus_dma_segment_t seg[1]; - struct ixgbe_rx_buf *rxbuf; - struct mbuf *mp; - int i, j, nsegs, error; - bool refreshed = FALSE; + struct adapter *adapter = rxr->adapter; + struct ixgbe_rx_buf *rxbuf; + struct mbuf *mp; + bus_dma_segment_t seg[1]; + int i, j, nsegs, error; + bool refreshed = FALSE; i = j = rxr->next_to_refresh; /* Control the loop with one beyond */ @@ -1321,8 +1222,8 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit) while (j != limit) { rxbuf = &rxr->rx_buffers[i]; if (rxbuf->buf == NULL) { - mp = m_getjcl(M_NOWAIT, MT_DATA, - M_PKTHDR, rxr->mbuf_sz); + mp = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, + rxr->mbuf_sz); if (mp == NULL) goto update; if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN)) @@ -1338,11 +1239,10 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit) if ((rxbuf->flags & IXGBE_RX_COPY) == 0) { /* Get the memory mapping */ bus_dmamap_unload(rxr->ptag, rxbuf->pmap); - error = bus_dmamap_load_mbuf_sg(rxr->ptag, - rxbuf->pmap, mp, seg, &nsegs, BUS_DMA_NOWAIT); + error = bus_dmamap_load_mbuf_sg(rxr->ptag, rxbuf->pmap, + mp, seg, &nsegs, BUS_DMA_NOWAIT); if (error != 0) { - printf("Refresh mbufs: payload dmamap load" - " failure - %d\n", error); + printf("Refresh mbufs: payload dmamap load failure - %d\n", error); m_free(mp); rxbuf->buf = NULL; goto update; @@ -1364,50 +1264,55 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit) if (++j == rxr->num_desc) j = 0; } + update: if (refreshed) /* Update hardware tail index */ - IXGBE_WRITE_REG(&adapter->hw, - rxr->tail, rxr->next_to_refresh); - return; -} + IXGBE_WRITE_REG(&adapter->hw, rxr->tail, rxr->next_to_refresh); -/********************************************************************* + return; +} /* ixgbe_refresh_mbufs */ + +/************************************************************************ + * ixgbe_allocate_receive_buffers * - * Allocate memory for rx_buffer structures. Since we use one - * rx_buffer per received packet, the maximum number of rx_buffer's - * that we'll need is equal to the number of receive descriptors - * that we've allocated. - * - **********************************************************************/ -int + * Allocate memory for rx_buffer structures. Since we use one + * rx_buffer per received packet, the maximum number of rx_buffer's + * that we'll need is equal to the number of receive descriptors + * that we've allocated. + ************************************************************************/ +static int ixgbe_allocate_receive_buffers(struct rx_ring *rxr) { - struct adapter *adapter = rxr->adapter; - device_t dev = adapter->dev; - struct ixgbe_rx_buf *rxbuf; - int bsize, error; + struct adapter *adapter = rxr->adapter; + device_t dev = adapter->dev; + struct ixgbe_rx_buf *rxbuf; + int bsize, error; bsize = sizeof(struct ixgbe_rx_buf) * rxr->num_desc; - if (!(rxr->rx_buffers = - (struct ixgbe_rx_buf *) malloc(bsize, - M_DEVBUF, M_NOWAIT | M_ZERO))) { + rxr->rx_buffers = (struct ixgbe_rx_buf *)malloc(bsize, M_DEVBUF, + M_NOWAIT | M_ZERO); + if (rxr->rx_buffers == NULL) { device_printf(dev, "Unable to allocate rx_buffer memory\n"); error = ENOMEM; goto fail; } - if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ - 1, 0, /* alignment, bounds */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - MJUM16BYTES, /* maxsize */ - 1, /* nsegments */ - MJUM16BYTES, /* maxsegsize */ - 0, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockfuncarg */ - &rxr->ptag))) { + error = bus_dma_tag_create( + /* parent */ bus_get_dma_tag(dev), + /* alignment */ 1, + /* bounds */ 0, + /* lowaddr */ BUS_SPACE_MAXADDR, + /* highaddr */ BUS_SPACE_MAXADDR, + /* filter */ NULL, + /* filterarg */ NULL, + /* maxsize */ MJUM16BYTES, + /* nsegments */ 1, + /* maxsegsize */ MJUM16BYTES, + /* flags */ 0, + /* lockfunc */ NULL, + /* lockfuncarg */ NULL, + &rxr->ptag); + if (error != 0) { device_printf(dev, "Unable to create RX DMA tag\n"); goto fail; } @@ -1426,37 +1331,40 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr) fail: /* Frees all, but can handle partial completion */ ixgbe_free_receive_structures(adapter); - return (error); -} -static void + return (error); +} /* ixgbe_allocate_receive_buffers */ + +/************************************************************************ + * ixgbe_free_receive_ring + ************************************************************************/ +static void ixgbe_free_receive_ring(struct rx_ring *rxr) { - for (int i = 0; i < rxr->num_desc; i++) { ixgbe_rx_discard(rxr, i); } -} +} /* ixgbe_free_receive_ring */ -/********************************************************************* +/************************************************************************ + * ixgbe_setup_receive_ring * - * Initialize a receive ring and its buffers. - * - **********************************************************************/ + * Initialize a receive ring and its buffers. + ************************************************************************/ static int ixgbe_setup_receive_ring(struct rx_ring *rxr) { - struct adapter *adapter; - struct ifnet *ifp; - device_t dev; - struct ixgbe_rx_buf *rxbuf; - bus_dma_segment_t seg[1]; - struct lro_ctrl *lro = &rxr->lro; - int rsize, nsegs, error = 0; + struct adapter *adapter; + struct ifnet *ifp; + device_t dev; + struct ixgbe_rx_buf *rxbuf; + struct lro_ctrl *lro = &rxr->lro; #ifdef DEV_NETMAP struct netmap_adapter *na = NA(rxr->adapter->ifp); - struct netmap_slot *slot; + struct netmap_slot *slot; #endif /* DEV_NETMAP */ + bus_dma_segment_t seg[1]; + int rsize, nsegs, error = 0; adapter = rxr->adapter; ifp = adapter->ifp; @@ -1464,10 +1372,12 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) /* Clear the ring contents */ IXGBE_RX_LOCK(rxr); + #ifdef DEV_NETMAP - /* same as in ixgbe_setup_transmit_ring() */ - slot = netmap_reset(na, NR_RX, rxr->me, 0); + if (adapter->feat_en & IXGBE_FEATURE_NETMAP) + slot = netmap_reset(na, NR_RX, rxr->me, 0); #endif /* DEV_NETMAP */ + rsize = roundup2(adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN); bzero((void *)rxr->rx_base, rsize); @@ -1479,9 +1389,10 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) /* Now replenish the mbufs */ for (int j = 0; j != rxr->num_desc; ++j) { - struct mbuf *mp; + struct mbuf *mp; rxbuf = &rxr->rx_buffers[j]; + #ifdef DEV_NETMAP /* * In netmap mode, fill the map and set the buffer @@ -1490,7 +1401,7 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) * ixgbe_setup_transmit_ring() ). No need to allocate * an mbuf, so end the block with a continue; */ - if (slot) { + if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) && slot) { int sj = netmap_idx_n2k(&na->rx_rings[rxr->me], j); uint64_t paddr; void *addr; @@ -1503,23 +1414,22 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) continue; } #endif /* DEV_NETMAP */ - rxbuf->flags = 0; - rxbuf->buf = m_getjcl(M_NOWAIT, MT_DATA, - M_PKTHDR, adapter->rx_mbuf_sz); + + rxbuf->flags = 0; + rxbuf->buf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, + adapter->rx_mbuf_sz); if (rxbuf->buf == NULL) { error = ENOBUFS; - goto fail; + goto fail; } mp = rxbuf->buf; mp->m_pkthdr.len = mp->m_len = rxr->mbuf_sz; /* Get the memory mapping */ - error = bus_dmamap_load_mbuf_sg(rxr->ptag, - rxbuf->pmap, mp, seg, + error = bus_dmamap_load_mbuf_sg(rxr->ptag, rxbuf->pmap, mp, seg, &nsegs, BUS_DMA_NOWAIT); if (error != 0) - goto fail; - bus_dmamap_sync(rxr->ptag, - rxbuf->pmap, BUS_DMASYNC_PREREAD); + goto fail; + bus_dmamap_sync(rxr->ptag, rxbuf->pmap, BUS_DMASYNC_PREREAD); /* Update the descriptor and the cached value */ rxr->rx_base[j].read.pkt_addr = htole64(seg[0].ds_addr); rxbuf->addr = htole64(seg[0].ds_addr); @@ -1538,8 +1448,8 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* - ** Now set up the LRO interface: - */ + * Now set up the LRO interface + */ if (ixgbe_rsc_enable) ixgbe_setup_hw_rsc(rxr); else if (ifp->if_capenable & IFCAP_LRO) { @@ -1554,24 +1464,24 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) } IXGBE_RX_UNLOCK(rxr); + return (0); fail: ixgbe_free_receive_ring(rxr); IXGBE_RX_UNLOCK(rxr); - return (error); -} -/********************************************************************* - * - * Initialize all receive rings. - * - **********************************************************************/ + return (error); +} /* ixgbe_setup_receive_ring */ + +/************************************************************************ + * ixgbe_setup_receive_structures - Initialize all receive rings. + ************************************************************************/ int ixgbe_setup_receive_structures(struct adapter *adapter) { struct rx_ring *rxr = adapter->rx_rings; - int j; + int j; for (j = 0; j < adapter->num_queues; j++, rxr++) if (ixgbe_setup_receive_ring(rxr)) @@ -1592,14 +1502,12 @@ ixgbe_setup_receive_structures(struct adapter *adapter) } return (ENOBUFS); -} +} /* ixgbe_setup_receive_structures */ -/********************************************************************* - * - * Free all receive rings. - * - **********************************************************************/ +/************************************************************************ + * ixgbe_free_receive_structures - Free all receive rings. + ************************************************************************/ void ixgbe_free_receive_structures(struct adapter *adapter) { @@ -1608,28 +1516,25 @@ ixgbe_free_receive_structures(struct adapter *adapter) INIT_DEBUGOUT("ixgbe_free_receive_structures: begin"); for (int i = 0; i < adapter->num_queues; i++, rxr++) { - struct lro_ctrl *lro = &rxr->lro; ixgbe_free_receive_buffers(rxr); /* Free LRO memory */ - tcp_lro_free(lro); + tcp_lro_free(&rxr->lro); /* Free the ring memory as well */ ixgbe_dma_free(adapter, &rxr->rxdma); } free(adapter->rx_rings, M_DEVBUF); -} +} /* ixgbe_free_receive_structures */ -/********************************************************************* - * - * Free receive ring data structures - * - **********************************************************************/ -void +/************************************************************************ + * ixgbe_free_receive_buffers - Free receive ring data structures + ************************************************************************/ +static void ixgbe_free_receive_buffers(struct rx_ring *rxr) { - struct adapter *adapter = rxr->adapter; - struct ixgbe_rx_buf *rxbuf; + struct adapter *adapter = rxr->adapter; + struct ixgbe_rx_buf *rxbuf; INIT_DEBUGOUT("ixgbe_free_receive_buffers: begin"); @@ -1655,56 +1560,61 @@ ixgbe_free_receive_buffers(struct rx_ring *rxr) } return; -} +} /* ixgbe_free_receive_buffers */ +/************************************************************************ + * ixgbe_rx_input + ************************************************************************/ static __inline void -ixgbe_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype) +ixgbe_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, + u32 ptype) { - - /* - * ATM LRO is only for IP/TCP packets and TCP checksum of the packet - * should be computed by hardware. Also it should not have VLAN tag in - * ethernet header. In case of IPv6 we do not yet support ext. hdrs. - */ - if (rxr->lro_enabled && - (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 && - (ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 && - ((ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) == - (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) || - (ptype & (IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) == - (IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) && - (m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) == - (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) { - /* - * Send to the stack if: - ** - LRO not enabled, or - ** - no LRO resources, or - ** - lro enqueue fails - */ - if (rxr->lro.lro_cnt != 0) - if (tcp_lro_rx(&rxr->lro, m, 0) == 0) - return; - } + /* + * ATM LRO is only for IP/TCP packets and TCP checksum of the packet + * should be computed by hardware. Also it should not have VLAN tag in + * ethernet header. In case of IPv6 we do not yet support ext. hdrs. + */ + if (rxr->lro_enabled && + (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 && + (ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 && + ((ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) == + (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) || + (ptype & (IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) == + (IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) && + (m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) == + (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) { + /* + * Send to the stack if: + * - LRO not enabled, or + * - no LRO resources, or + * - lro enqueue fails + */ + if (rxr->lro.lro_cnt != 0) + if (tcp_lro_rx(&rxr->lro, m, 0) == 0) + return; + } IXGBE_RX_UNLOCK(rxr); - (*ifp->if_input)(ifp, m); + (*ifp->if_input)(ifp, m); IXGBE_RX_LOCK(rxr); -} +} /* ixgbe_rx_input */ +/************************************************************************ + * ixgbe_rx_discard + ************************************************************************/ static __inline void ixgbe_rx_discard(struct rx_ring *rxr, int i) { - struct ixgbe_rx_buf *rbuf; + struct ixgbe_rx_buf *rbuf; rbuf = &rxr->rx_buffers[i]; - /* - ** With advanced descriptors the writeback - ** clobbers the buffer addrs, so its easier - ** to just free the existing mbufs and take - ** the normal refresh path to get new buffers - ** and mapping. - */ + * With advanced descriptors the writeback + * clobbers the buffer addrs, so its easier + * to just free the existing mbufs and take + * the normal refresh path to get new buffers + * and mapping. + */ if (rbuf->fmp != NULL) {/* Partial chain ? */ bus_dmamap_sync(rxr->ptag, rbuf->pmap, BUS_DMASYNC_POSTREAD); @@ -1719,50 +1629,53 @@ ixgbe_rx_discard(struct rx_ring *rxr, int i) bus_dmamap_unload(rxr->ptag, rbuf->pmap); rbuf->flags = 0; - + return; -} +} /* ixgbe_rx_discard */ -/********************************************************************* +/************************************************************************ + * ixgbe_rxeof * - * This routine executes in interrupt context. It replenishes - * the mbufs in the descriptor and sends data which has been - * dma'ed into host memory to upper layer. + * Executes in interrupt context. It replenishes the + * mbufs in the descriptor and sends data which has + * been dma'ed into host memory to upper layer. * - * Return TRUE for more work, FALSE for all clean. - *********************************************************************/ + * Return TRUE for more work, FALSE for all clean. + ************************************************************************/ bool ixgbe_rxeof(struct ix_queue *que) { - struct adapter *adapter = que->adapter; - struct rx_ring *rxr = que->rxr; - struct ifnet *ifp = adapter->ifp; - struct lro_ctrl *lro = &rxr->lro; - int i, nextp, processed = 0; - u32 staterr = 0; - u32 count = adapter->rx_process_limit; - union ixgbe_adv_rx_desc *cur; - struct ixgbe_rx_buf *rbuf, *nbuf; - u16 pkt_info; + struct adapter *adapter = que->adapter; + struct rx_ring *rxr = que->rxr; + struct ifnet *ifp = adapter->ifp; + struct lro_ctrl *lro = &rxr->lro; + union ixgbe_adv_rx_desc *cur; + struct ixgbe_rx_buf *rbuf, *nbuf; + int i, nextp, processed = 0; + u32 staterr = 0; + u32 count = adapter->rx_process_limit; + u16 pkt_info; IXGBE_RX_LOCK(rxr); #ifdef DEV_NETMAP - /* Same as the txeof routine: wakeup clients on intr. */ - if (netmap_rx_irq(ifp, rxr->me, &processed)) { - IXGBE_RX_UNLOCK(rxr); - return (FALSE); + if (adapter->feat_en & IXGBE_FEATURE_NETMAP) { + /* Same as the txeof routine: wakeup clients on intr. */ + if (netmap_rx_irq(ifp, rxr->me, &processed)) { + IXGBE_RX_UNLOCK(rxr); + return (FALSE); + } } #endif /* DEV_NETMAP */ for (i = rxr->next_to_check; count != 0;) { - struct mbuf *sendmp, *mp; - u32 rsc, ptype; - u16 len; - u16 vtag = 0; - bool eop; - + struct mbuf *sendmp, *mp; + u32 rsc, ptype; + u16 len; + u16 vtag = 0; + bool eop; + /* Sync the ring. */ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); @@ -1792,7 +1705,7 @@ ixgbe_rxeof(struct ix_queue *que) /* Make sure bad packets are discarded */ if (eop && (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) { #if __FreeBSD_version >= 1100036 - if (IXGBE_IS_VF(adapter)) + if (adapter->feat_en & IXGBE_FEATURE_VF) if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); #endif rxr->rx_discarded++; @@ -1803,29 +1716,28 @@ ixgbe_rxeof(struct ix_queue *que) bus_dmamap_sync(rxr->ptag, rbuf->pmap, BUS_DMASYNC_POSTREAD); /* - ** On 82599 which supports a hardware - ** LRO (called HW RSC), packets need - ** not be fragmented across sequential - ** descriptors, rather the next descriptor - ** is indicated in bits of the descriptor. - ** This also means that we might proceses - ** more than one packet at a time, something - ** that has never been true before, it - ** required eliminating global chain pointers - ** in favor of what we are doing here. -jfv - */ + * On 82599 which supports a hardware + * LRO (called HW RSC), packets need + * not be fragmented across sequential + * descriptors, rather the next descriptor + * is indicated in bits of the descriptor. + * This also means that we might proceses + * more than one packet at a time, something + * that has never been true before, it + * required eliminating global chain pointers + * in favor of what we are doing here. -jfv + */ if (!eop) { /* - ** Figure out the next descriptor - ** of this frame. - */ + * Figure out the next descriptor + * of this frame. + */ if (rxr->hw_rsc == TRUE) { rsc = ixgbe_rsc_count(cur); rxr->rsc_num += (rsc - 1); } if (rsc) { /* Get hardware index */ - nextp = ((staterr & - IXGBE_RXDADV_NEXTP_MASK) >> + nextp = ((staterr & IXGBE_RXDADV_NEXTP_MASK) >> IXGBE_RXDADV_NEXTP_SHIFT); } else { /* Just sequential */ nextp = i + 1; @@ -1836,16 +1748,16 @@ ixgbe_rxeof(struct ix_queue *que) prefetch(nbuf); } /* - ** Rather than using the fmp/lmp global pointers - ** we now keep the head of a packet chain in the - ** buffer struct and pass this along from one - ** descriptor to the next, until we get EOP. - */ + * Rather than using the fmp/lmp global pointers + * we now keep the head of a packet chain in the + * buffer struct and pass this along from one + * descriptor to the next, until we get EOP. + */ mp->m_len = len; /* - ** See if there is a stored head - ** that determines what we are - */ + * See if there is a stored head + * that determines what we are + */ sendmp = rbuf->fmp; if (sendmp != NULL) { /* secondary frag */ rbuf->buf = rbuf->fmp = NULL; @@ -1861,10 +1773,9 @@ ixgbe_rxeof(struct ix_queue *que) if (eop && len <= IXGBE_RX_COPY_LEN) { sendmp = m_gethdr(M_NOWAIT, MT_DATA); if (sendmp != NULL) { - sendmp->m_data += - IXGBE_RX_COPY_ALIGN; - ixgbe_bcopy(mp->m_data, - sendmp->m_data, len); + sendmp->m_data += IXGBE_RX_COPY_ALIGN; + ixgbe_bcopy(mp->m_data, sendmp->m_data, + len); sendmp->m_len = len; rxr->rx_copies++; rbuf->flags |= IXGBE_RX_COPY; @@ -1893,8 +1804,7 @@ ixgbe_rxeof(struct ix_queue *que) rxr->bytes += sendmp->m_pkthdr.len; rxr->rx_bytes += sendmp->m_pkthdr.len; /* Process vlan info */ - if ((rxr->vtag_strip) && - (staterr & IXGBE_RXD_STAT_VP)) + if ((rxr->vtag_strip) && (staterr & IXGBE_RXD_STAT_VP)) vtag = le16toh(cur->wb.upper.vlan); if (vtag) { sendmp->m_pkthdr.ether_vtag = vtag; @@ -1903,59 +1813,59 @@ ixgbe_rxeof(struct ix_queue *que) if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) ixgbe_rx_checksum(staterr, sendmp, ptype); - /* - * In case of multiqueue, we have RXCSUM.PCSD bit set - * and never cleared. This means we have RSS hash - * available to be used. - */ - if (adapter->num_queues > 1) { - sendmp->m_pkthdr.flowid = - le32toh(cur->wb.lower.hi_dword.rss); - switch (pkt_info & IXGBE_RXDADV_RSSTYPE_MASK) { - case IXGBE_RXDADV_RSSTYPE_IPV4: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_IPV4); - break; - case IXGBE_RXDADV_RSSTYPE_IPV4_TCP: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_TCP_IPV4); - break; - case IXGBE_RXDADV_RSSTYPE_IPV6: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_IPV6); - break; - case IXGBE_RXDADV_RSSTYPE_IPV6_TCP: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_TCP_IPV6); - break; - case IXGBE_RXDADV_RSSTYPE_IPV6_EX: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_IPV6_EX); - break; - case IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_TCP_IPV6_EX); - break; + /* + * In case of multiqueue, we have RXCSUM.PCSD bit set + * and never cleared. This means we have RSS hash + * available to be used. + */ + if (adapter->num_queues > 1) { + sendmp->m_pkthdr.flowid = + le32toh(cur->wb.lower.hi_dword.rss); + switch (pkt_info & IXGBE_RXDADV_RSSTYPE_MASK) { + case IXGBE_RXDADV_RSSTYPE_IPV4: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_IPV4); + break; + case IXGBE_RXDADV_RSSTYPE_IPV4_TCP: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_TCP_IPV4); + break; + case IXGBE_RXDADV_RSSTYPE_IPV6: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_IPV6); + break; + case IXGBE_RXDADV_RSSTYPE_IPV6_TCP: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_TCP_IPV6); + break; + case IXGBE_RXDADV_RSSTYPE_IPV6_EX: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_IPV6_EX); + break; + case IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_TCP_IPV6_EX); + break; #if __FreeBSD_version > 1100000 - case IXGBE_RXDADV_RSSTYPE_IPV4_UDP: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_UDP_IPV4); - break; - case IXGBE_RXDADV_RSSTYPE_IPV6_UDP: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_UDP_IPV6); - break; - case IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_RSS_UDP_IPV6_EX); - break; + case IXGBE_RXDADV_RSSTYPE_IPV4_UDP: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_UDP_IPV4); + break; + case IXGBE_RXDADV_RSSTYPE_IPV6_UDP: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_UDP_IPV6); + break; + case IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_RSS_UDP_IPV6_EX); + break; #endif - default: - M_HASHTYPE_SET(sendmp, - M_HASHTYPE_OPAQUE_HASH); - } - } else { - sendmp->m_pkthdr.flowid = que->msix; + default: + M_HASHTYPE_SET(sendmp, + M_HASHTYPE_OPAQUE_HASH); + } + } else { + sendmp->m_pkthdr.flowid = que->msix; M_HASHTYPE_SET(sendmp, M_HASHTYPE_OPAQUE); } } @@ -1974,7 +1884,7 @@ ixgbe_rxeof(struct ix_queue *que) i = rxr->next_to_check; } - /* Every 8 descriptors we go to refresh mbufs */ + /* Every 8 descriptors we go to refresh mbufs */ if (processed == 8) { ixgbe_refresh_mbufs(rxr, i); processed = 0; @@ -1995,28 +1905,28 @@ ixgbe_rxeof(struct ix_queue *que) IXGBE_RX_UNLOCK(rxr); /* - ** Still have cleaning to do? - */ + * Still have cleaning to do? + */ if ((staterr & IXGBE_RXD_STAT_DD) != 0) return (TRUE); - else - return (FALSE); -} + + return (FALSE); +} /* ixgbe_rxeof */ -/********************************************************************* +/************************************************************************ + * ixgbe_rx_checksum * - * Verify that the hardware indicated that the checksum is valid. - * Inform the stack about the status of checksum so that stack - * doesn't spend time verifying the checksum. - * - *********************************************************************/ + * Verify that the hardware indicated that the checksum is valid. + * Inform the stack about the status of checksum so that stack + * doesn't spend time verifying the checksum. + ************************************************************************/ static void ixgbe_rx_checksum(u32 staterr, struct mbuf * mp, u32 ptype) { - u16 status = (u16) staterr; - u8 errors = (u8) (staterr >> 24); - bool sctp = false; + u16 status = (u16)staterr; + u8 errors = (u8)(staterr >> 24); + bool sctp = false; if ((ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 && (ptype & IXGBE_RXDADV_PKTTYPE_SCTP) != 0) @@ -2038,62 +1948,68 @@ ixgbe_rx_checksum(u32 staterr, struct mbuf * mp, u32 ptype) mp->m_pkthdr.csum_data = htons(0xffff); } } -} +} /* ixgbe_rx_checksum */ -/******************************************************************** - * Manage DMA'able memory. - *******************************************************************/ +/************************************************************************ + * ixgbe_dmamap_cb - Manage DMA'able memory. + ************************************************************************/ static void ixgbe_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error) { if (error) return; - *(bus_addr_t *) arg = segs->ds_addr; - return; -} + *(bus_addr_t *)arg = segs->ds_addr; -int + return; +} /* ixgbe_dmamap_cb */ + +/************************************************************************ + * ixgbe_dma_malloc + ************************************************************************/ +static int ixgbe_dma_malloc(struct adapter *adapter, bus_size_t size, - struct ixgbe_dma_alloc *dma, int mapflags) + struct ixgbe_dma_alloc *dma, int mapflags) { device_t dev = adapter->dev; - int r; + int r; - r = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */ - DBA_ALIGN, 0, /* alignment, bounds */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - size, /* maxsize */ - 1, /* nsegments */ - size, /* maxsegsize */ - BUS_DMA_ALLOCNOW, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockfuncarg */ - &dma->dma_tag); + r = bus_dma_tag_create( + /* parent */ bus_get_dma_tag(adapter->dev), + /* alignment */ DBA_ALIGN, + /* bounds */ 0, + /* lowaddr */ BUS_SPACE_MAXADDR, + /* highaddr */ BUS_SPACE_MAXADDR, + /* filter */ NULL, + /* filterarg */ NULL, + /* maxsize */ size, + /* nsegments */ 1, + /* maxsegsize */ size, + /* flags */ BUS_DMA_ALLOCNOW, + /* lockfunc */ NULL, + /* lockfuncarg */ NULL, + &dma->dma_tag); if (r != 0) { - device_printf(dev,"ixgbe_dma_malloc: bus_dma_tag_create failed; " - "error %u\n", r); + device_printf(dev, + "ixgbe_dma_malloc: bus_dma_tag_create failed; error %u\n", + r); goto fail_0; } r = bus_dmamem_alloc(dma->dma_tag, (void **)&dma->dma_vaddr, - BUS_DMA_NOWAIT, &dma->dma_map); + BUS_DMA_NOWAIT, &dma->dma_map); if (r != 0) { - device_printf(dev,"ixgbe_dma_malloc: bus_dmamem_alloc failed; " - "error %u\n", r); + device_printf(dev, + "ixgbe_dma_malloc: bus_dmamem_alloc failed; error %u\n", r); goto fail_1; } - r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr, - size, - ixgbe_dmamap_cb, - &dma->dma_paddr, - mapflags | BUS_DMA_NOWAIT); + r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr, size, + ixgbe_dmamap_cb, &dma->dma_paddr, mapflags | BUS_DMA_NOWAIT); if (r != 0) { - device_printf(dev,"ixgbe_dma_malloc: bus_dmamap_load failed; " - "error %u\n", r); + device_printf(dev, + "ixgbe_dma_malloc: bus_dmamap_load failed; error %u\n", r); goto fail_2; } dma->dma_size = size; + return (0); fail_2: bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); @@ -2101,10 +2017,14 @@ ixgbe_dma_malloc(struct adapter *adapter, bus_size_t size, bus_dma_tag_destroy(dma->dma_tag); fail_0: dma->dma_tag = NULL; - return (r); -} -void + return (r); +} /* ixgbe_dma_malloc */ + +/************************************************************************ + * ixgbe_dma_free + ************************************************************************/ +static void ixgbe_dma_free(struct adapter *adapter, struct ixgbe_dma_alloc *dma) { bus_dmamap_sync(dma->dma_tag, dma->dma_map, @@ -2112,79 +2032,69 @@ ixgbe_dma_free(struct adapter *adapter, struct ixgbe_dma_alloc *dma) bus_dmamap_unload(dma->dma_tag, dma->dma_map); bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); bus_dma_tag_destroy(dma->dma_tag); -} +} /* ixgbe_dma_free */ -/********************************************************************* +/************************************************************************ + * ixgbe_allocate_queues * - * Allocate memory for the transmit and receive rings, and then - * the descriptors associated with each, called only once at attach. - * - **********************************************************************/ + * Allocate memory for the transmit and receive rings, and then + * the descriptors associated with each, called only once at attach. + ************************************************************************/ int ixgbe_allocate_queues(struct adapter *adapter) { - device_t dev = adapter->dev; - struct ix_queue *que; - struct tx_ring *txr; - struct rx_ring *rxr; - int rsize, tsize, error = IXGBE_SUCCESS; - int txconf = 0, rxconf = 0; -#ifdef PCI_IOV - enum ixgbe_iov_mode iov_mode; -#endif + device_t dev = adapter->dev; + struct ix_queue *que; + struct tx_ring *txr; + struct rx_ring *rxr; + int rsize, tsize, error = IXGBE_SUCCESS; + int txconf = 0, rxconf = 0; - /* First allocate the top level queue structs */ - if (!(adapter->queues = - (struct ix_queue *) malloc(sizeof(struct ix_queue) * - adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { - device_printf(dev, "Unable to allocate queue memory\n"); - error = ENOMEM; - goto fail; - } + /* First, allocate the top level queue structs */ + adapter->queues = (struct ix_queue *)malloc(sizeof(struct ix_queue) * + adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO); + if (adapter->queues == NULL) { + device_printf(dev, "Unable to allocate queue memory\n"); + error = ENOMEM; + goto fail; + } - /* First allocate the TX ring struct memory */ - if (!(adapter->tx_rings = - (struct tx_ring *) malloc(sizeof(struct tx_ring) * - adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { + /* Second, allocate the TX ring struct memory */ + adapter->tx_rings = (struct tx_ring *)malloc(sizeof(struct tx_ring) * + adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO); + if (adapter->tx_rings == NULL) { device_printf(dev, "Unable to allocate TX ring memory\n"); error = ENOMEM; goto tx_fail; } - /* Next allocate the RX */ - if (!(adapter->rx_rings = - (struct rx_ring *) malloc(sizeof(struct rx_ring) * - adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { + /* Third, allocate the RX ring */ + adapter->rx_rings = (struct rx_ring *)malloc(sizeof(struct rx_ring) * + adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO); + if (adapter->rx_rings == NULL) { device_printf(dev, "Unable to allocate RX ring memory\n"); error = ENOMEM; goto rx_fail; } /* For the ring itself */ - tsize = roundup2(adapter->num_tx_desc * - sizeof(union ixgbe_adv_tx_desc), DBA_ALIGN); + tsize = roundup2(adapter->num_tx_desc * sizeof(union ixgbe_adv_tx_desc), + DBA_ALIGN); -#ifdef PCI_IOV - iov_mode = ixgbe_get_iov_mode(adapter); - adapter->pool = ixgbe_max_vfs(iov_mode); -#else - adapter->pool = 0; -#endif /* * Now set up the TX queues, txconf is needed to handle the * possibility that things fail midcourse and we need to * undo memory gracefully - */ + */ for (int i = 0; i < adapter->num_queues; i++, txconf++) { /* Set up some basics */ txr = &adapter->tx_rings[i]; txr->adapter = adapter; -#ifdef PCI_IOV - txr->me = ixgbe_pf_que_index(iov_mode, i); -#else - txr->me = i; -#endif + txr->br = NULL; + /* In case SR-IOV is enabled, align the index properly */ + txr->me = ixgbe_vf_que_index(adapter->iov_mode, adapter->pool, + i); txr->num_desc = adapter->num_tx_desc; /* Initialize the TX side lock */ @@ -2192,8 +2102,8 @@ ixgbe_allocate_queues(struct adapter *adapter) device_get_nameunit(dev), txr->me); mtx_init(&txr->tx_mtx, txr->mtx_name, NULL, MTX_DEF); - if (ixgbe_dma_malloc(adapter, tsize, - &txr->txdma, BUS_DMA_NOWAIT)) { + if (ixgbe_dma_malloc(adapter, tsize, &txr->txdma, + BUS_DMA_NOWAIT)) { device_printf(dev, "Unable to allocate TX Descriptor memory\n"); error = ENOMEM; @@ -2202,40 +2112,38 @@ ixgbe_allocate_queues(struct adapter *adapter) txr->tx_base = (union ixgbe_adv_tx_desc *)txr->txdma.dma_vaddr; bzero((void *)txr->tx_base, tsize); - /* Now allocate transmit buffers for the ring */ - if (ixgbe_allocate_transmit_buffers(txr)) { + /* Now allocate transmit buffers for the ring */ + if (ixgbe_allocate_transmit_buffers(txr)) { device_printf(dev, "Critical Failure setting up transmit buffers\n"); error = ENOMEM; goto err_tx_desc; - } -#ifndef IXGBE_LEGACY_TX - /* Allocate a buf ring */ - txr->br = buf_ring_alloc(IXGBE_BR_SIZE, M_DEVBUF, - M_WAITOK, &txr->tx_mtx); - if (txr->br == NULL) { - device_printf(dev, - "Critical Failure setting up buf ring\n"); - error = ENOMEM; - goto err_tx_desc; - } -#endif + } + if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) { + /* Allocate a buf ring */ + txr->br = buf_ring_alloc(IXGBE_BR_SIZE, M_DEVBUF, + M_WAITOK, &txr->tx_mtx); + if (txr->br == NULL) { + device_printf(dev, + "Critical Failure setting up buf ring\n"); + error = ENOMEM; + goto err_tx_desc; + } + } } /* * Next the RX queues... - */ - rsize = roundup2(adapter->num_rx_desc * - sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN); + */ + rsize = roundup2(adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc), + DBA_ALIGN); for (int i = 0; i < adapter->num_queues; i++, rxconf++) { rxr = &adapter->rx_rings[i]; /* Set up some basics */ rxr->adapter = adapter; -#ifdef PCI_IOV - rxr->me = ixgbe_pf_que_index(iov_mode, i); -#else - rxr->me = i; -#endif + /* In case SR-IOV is enabled, align the index properly */ + rxr->me = ixgbe_vf_que_index(adapter->iov_mode, adapter->pool, + i); rxr->num_desc = adapter->num_rx_desc; /* Initialize the RX side lock */ @@ -2243,8 +2151,8 @@ ixgbe_allocate_queues(struct adapter *adapter) device_get_nameunit(dev), rxr->me); mtx_init(&rxr->rx_mtx, rxr->mtx_name, NULL, MTX_DEF); - if (ixgbe_dma_malloc(adapter, rsize, - &rxr->rxdma, BUS_DMA_NOWAIT)) { + if (ixgbe_dma_malloc(adapter, rsize, &rxr->rxdma, + BUS_DMA_NOWAIT)) { device_printf(dev, "Unable to allocate RxDescriptor memory\n"); error = ENOMEM; @@ -2253,7 +2161,7 @@ ixgbe_allocate_queues(struct adapter *adapter) rxr->rx_base = (union ixgbe_adv_rx_desc *)rxr->rxdma.dma_vaddr; bzero((void *)rxr->rx_base, rsize); - /* Allocate receive buffers for the ring*/ + /* Allocate receive buffers for the ring */ if (ixgbe_allocate_receive_buffers(rxr)) { device_printf(dev, "Critical Failure setting up receive buffers\n"); @@ -2263,8 +2171,8 @@ ixgbe_allocate_queues(struct adapter *adapter) } /* - ** Finally set up the queue holding structs - */ + * Finally set up the queue holding structs + */ for (int i = 0; i < adapter->num_queues; i++) { que = &adapter->queues[i]; que->adapter = adapter; @@ -2288,4 +2196,4 @@ ixgbe_allocate_queues(struct adapter *adapter) free(adapter->queues, M_DEVBUF); fail: return (error); -} +} /* ixgbe_allocate_queues */ diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h index 68f2edb57eef..bcd053679309 100644 --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -39,9 +39,7 @@ #include #include -#ifndef IXGBE_LEGACY_TX #include -#endif #include #include #include @@ -92,21 +90,11 @@ #include #include -#ifdef PCI_IOV -#include -#include -#include -#endif - #include "ixgbe_api.h" #include "ixgbe_common.h" #include "ixgbe_phy.h" #include "ixgbe_vf.h" - -#ifdef PCI_IOV -#include "ixgbe_common.h" -#include "ixgbe_mbx.h" -#endif +#include "ixgbe_features.h" /* Tunables */ @@ -117,60 +105,60 @@ * bytes. Performance tests have show the 2K value to be optimal for top * performance. */ -#define DEFAULT_TXD 1024 -#define PERFORM_TXD 2048 -#define MAX_TXD 4096 -#define MIN_TXD 64 +#define DEFAULT_TXD 1024 +#define PERFORM_TXD 2048 +#define MAX_TXD 4096 +#define MIN_TXD 64 /* * RxDescriptors Valid Range: 64-4096 Default Value: 256 This value is the * number of receive descriptors allocated for each RX queue. Increasing this * value allows the driver to buffer more incoming packets. Each descriptor - * is 16 bytes. A receive buffer is also allocated for each descriptor. - * - * Note: with 8 rings and a dual port card, it is possible to bump up - * against the system mbuf pool limit, you can tune nmbclusters - * to adjust for this. + * is 16 bytes. A receive buffer is also allocated for each descriptor. + * + * Note: with 8 rings and a dual port card, it is possible to bump up + * against the system mbuf pool limit, you can tune nmbclusters + * to adjust for this. */ -#define DEFAULT_RXD 1024 -#define PERFORM_RXD 2048 -#define MAX_RXD 4096 -#define MIN_RXD 64 +#define DEFAULT_RXD 1024 +#define PERFORM_RXD 2048 +#define MAX_RXD 4096 +#define MIN_RXD 64 /* Alignment for rings */ -#define DBA_ALIGN 128 +#define DBA_ALIGN 128 /* * This is the max watchdog interval, ie. the time that can * pass between any two TX clean operations, such only happening * when the TX hardware is functioning. */ -#define IXGBE_WATCHDOG (10 * hz) +#define IXGBE_WATCHDOG (10 * hz) /* * This parameters control when the driver calls the routine to reclaim * transmit descriptors. */ -#define IXGBE_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8) -#define IXGBE_TX_OP_THRESHOLD (adapter->num_tx_desc / 32) +#define IXGBE_TX_CLEANUP_THRESHOLD(_a) ((_a)->num_tx_desc / 8) +#define IXGBE_TX_OP_THRESHOLD(_a) ((_a)->num_tx_desc / 32) /* These defines are used in MTU calculations */ -#define IXGBE_MAX_FRAME_SIZE 9728 -#define IXGBE_MTU_HDR (ETHER_HDR_LEN + ETHER_CRC_LEN) -#define IXGBE_MTU_HDR_VLAN (ETHER_HDR_LEN + ETHER_CRC_LEN + \ - ETHER_VLAN_ENCAP_LEN) -#define IXGBE_MAX_MTU (IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR) -#define IXGBE_MAX_MTU_VLAN (IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR_VLAN) +#define IXGBE_MAX_FRAME_SIZE 9728 +#define IXGBE_MTU_HDR (ETHER_HDR_LEN + ETHER_CRC_LEN) +#define IXGBE_MTU_HDR_VLAN (ETHER_HDR_LEN + ETHER_CRC_LEN + \ + ETHER_VLAN_ENCAP_LEN) +#define IXGBE_MAX_MTU (IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR) +#define IXGBE_MAX_MTU_VLAN (IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR_VLAN) /* Flow control constants */ -#define IXGBE_FC_PAUSE 0xFFFF -#define IXGBE_FC_HI 0x20000 -#define IXGBE_FC_LO 0x10000 +#define IXGBE_FC_PAUSE 0xFFFF +#define IXGBE_FC_HI 0x20000 +#define IXGBE_FC_LO 0x10000 /* * Used for optimizing small rx mbufs. Effort is made to keep the copy * small and aligned for the CPU L1 cache. - * + * * MHLEN is typically 168 bytes, giving us 8-byte alignment. Getting * 32 byte alignment needed for the fast bcopy results in 8 bytes being * wasted. Getting 64 byte alignment, which _should_ be ideal for @@ -178,11 +166,11 @@ * in observed efficiency of the optimization, 97.9% -> 81.8%. */ #if __FreeBSD_version < 1002000 -#define MPKTHSIZE (sizeof(struct m_hdr) + sizeof(struct pkthdr)) +#define MPKTHSIZE (sizeof(struct m_hdr) + sizeof(struct pkthdr)) #endif -#define IXGBE_RX_COPY_HDR_PADDED ((((MPKTHSIZE - 1) / 32) + 1) * 32) -#define IXGBE_RX_COPY_LEN (MSIZE - IXGBE_RX_COPY_HDR_PADDED) -#define IXGBE_RX_COPY_ALIGN (IXGBE_RX_COPY_HDR_PADDED - MPKTHSIZE) +#define IXGBE_RX_COPY_HDR_PADDED ((((MPKTHSIZE - 1) / 32) + 1) * 32) +#define IXGBE_RX_COPY_LEN (MSIZE - IXGBE_RX_COPY_HDR_PADDED) +#define IXGBE_RX_COPY_ALIGN (IXGBE_RX_COPY_HDR_PADDED - MPKTHSIZE) /* Keep older OS drivers building... */ #if !defined(SYSCTL_ADD_UQUAD) @@ -205,29 +193,29 @@ #define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B) #define MAX_NUM_MULTICAST_ADDRESSES 128 -#define IXGBE_82598_SCATTER 100 -#define IXGBE_82599_SCATTER 32 -#define MSIX_82598_BAR 3 -#define MSIX_82599_BAR 4 -#define IXGBE_TSO_SIZE 262140 -#define IXGBE_RX_HDR 128 -#define IXGBE_VFTA_SIZE 128 -#define IXGBE_BR_SIZE 4096 -#define IXGBE_QUEUE_MIN_FREE 32 -#define IXGBE_MAX_TX_BUSY 10 -#define IXGBE_QUEUE_HUNG 0x80000000 +#define IXGBE_82598_SCATTER 100 +#define IXGBE_82599_SCATTER 32 +#define MSIX_82598_BAR 3 +#define MSIX_82599_BAR 4 +#define IXGBE_TSO_SIZE 262140 +#define IXGBE_RX_HDR 128 +#define IXGBE_VFTA_SIZE 128 +#define IXGBE_BR_SIZE 4096 +#define IXGBE_QUEUE_MIN_FREE 32 +#define IXGBE_MAX_TX_BUSY 10 +#define IXGBE_QUEUE_HUNG 0x80000000 -#define IXV_EITR_DEFAULT 128 +#define IXGBE_EITR_DEFAULT 128 /* Supported offload bits in mbuf flag */ #if __FreeBSD_version >= 1000000 -#define CSUM_OFFLOAD (CSUM_IP_TSO|CSUM_IP6_TSO|CSUM_IP| \ - CSUM_IP_UDP|CSUM_IP_TCP|CSUM_IP_SCTP| \ - CSUM_IP6_UDP|CSUM_IP6_TCP|CSUM_IP6_SCTP) +#define CSUM_OFFLOAD (CSUM_IP_TSO|CSUM_IP6_TSO|CSUM_IP| \ + CSUM_IP_UDP|CSUM_IP_TCP|CSUM_IP_SCTP| \ + CSUM_IP6_UDP|CSUM_IP6_TCP|CSUM_IP6_SCTP) #elif __FreeBSD_version >= 800000 -#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP) +#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP) #else -#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP) +#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP) #endif /* Backward compatibility items for very old versions */ @@ -240,157 +228,126 @@ #endif /* - * Interrupt Moderation parameters + * Interrupt Moderation parameters */ -#define IXGBE_LOW_LATENCY 128 -#define IXGBE_AVE_LATENCY 400 -#define IXGBE_BULK_LATENCY 1200 +#define IXGBE_LOW_LATENCY 128 +#define IXGBE_AVE_LATENCY 400 +#define IXGBE_BULK_LATENCY 1200 /* Using 1FF (the max value), the interval is ~1.05ms */ -#define IXGBE_LINK_ITR_QUANTA 0x1FF -#define IXGBE_LINK_ITR ((IXGBE_LINK_ITR_QUANTA << 3) & \ - IXGBE_EITR_ITR_INT_MASK) - -/* MAC type macros */ -#define IXGBE_IS_X550VF(_adapter) \ - ((_adapter->hw.mac.type == ixgbe_mac_X550_vf) || \ - (_adapter->hw.mac.type == ixgbe_mac_X550EM_x_vf)) - -#define IXGBE_IS_VF(_adapter) \ - (IXGBE_IS_X550VF(_adapter) || \ - (_adapter->hw.mac.type == ixgbe_mac_X540_vf) || \ - (_adapter->hw.mac.type == ixgbe_mac_82599_vf)) - -#ifdef PCI_IOV -#define IXGBE_VF_INDEX(vmdq) ((vmdq) / 32) -#define IXGBE_VF_BIT(vmdq) (1 << ((vmdq) % 32)) - -#define IXGBE_VT_MSG_MASK 0xFFFF - -#define IXGBE_VT_MSGINFO(msg) \ - (((msg) & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT) - -#define IXGBE_VF_GET_QUEUES_RESP_LEN 5 - -#define IXGBE_API_VER_1_0 0 -#define IXGBE_API_VER_2_0 1 /* Solaris API. Not supported. */ -#define IXGBE_API_VER_1_1 2 -#define IXGBE_API_VER_UNKNOWN UINT16_MAX - -enum ixgbe_iov_mode { - IXGBE_64_VM, - IXGBE_32_VM, - IXGBE_NO_VM -}; -#endif /* PCI_IOV */ +#define IXGBE_LINK_ITR_QUANTA 0x1FF +#define IXGBE_LINK_ITR ((IXGBE_LINK_ITR_QUANTA << 3) & \ + IXGBE_EITR_ITR_INT_MASK) -/* - ***************************************************************************** + +/************************************************************************ * vendor_info_array - * - * This array contains the list of Subvendor/Subdevice IDs on which the driver - * should load. - * - ***************************************************************************** - */ + * + * Contains the list of Subvendor/Subdevice IDs on + * which the driver should load. + ************************************************************************/ typedef struct _ixgbe_vendor_info_t { - unsigned int vendor_id; - unsigned int device_id; - unsigned int subvendor_id; - unsigned int subdevice_id; - unsigned int index; + unsigned int vendor_id; + unsigned int device_id; + unsigned int subvendor_id; + unsigned int subdevice_id; + unsigned int index; } ixgbe_vendor_info_t; +struct ixgbe_bp_data { + u32 low; + u32 high; + u32 log; +}; struct ixgbe_tx_buf { - union ixgbe_adv_tx_desc *eop; - struct mbuf *m_head; - bus_dmamap_t map; + union ixgbe_adv_tx_desc *eop; + struct mbuf *m_head; + bus_dmamap_t map; }; struct ixgbe_rx_buf { - struct mbuf *buf; - struct mbuf *fmp; - bus_dmamap_t pmap; - u_int flags; -#define IXGBE_RX_COPY 0x01 - uint64_t addr; + struct mbuf *buf; + struct mbuf *fmp; + bus_dmamap_t pmap; + u_int flags; +#define IXGBE_RX_COPY 0x01 + uint64_t addr; }; /* - * Bus dma allocation structure used by ixgbe_dma_malloc and ixgbe_dma_free. + * Bus dma allocation structure used by ixgbe_dma_malloc and ixgbe_dma_free */ struct ixgbe_dma_alloc { - bus_addr_t dma_paddr; - caddr_t dma_vaddr; - bus_dma_tag_t dma_tag; - bus_dmamap_t dma_map; - bus_dma_segment_t dma_seg; - bus_size_t dma_size; - int dma_nseg; + bus_addr_t dma_paddr; + caddr_t dma_vaddr; + bus_dma_tag_t dma_tag; + bus_dmamap_t dma_map; + bus_dma_segment_t dma_seg; + bus_size_t dma_size; + int dma_nseg; }; struct ixgbe_mc_addr { - u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; u32 vmdq; }; /* -** Driver queue struct: this is the interrupt container -** for the associated tx and rx ring. -*/ + * Driver queue struct: this is the interrupt container + * for the associated tx and rx ring. + */ struct ix_queue { - struct adapter *adapter; - u32 msix; /* This queue's MSIX vector */ - u32 eims; /* This queue's EIMS bit */ - u32 eitr_setting; - u32 me; - struct resource *res; - void *tag; - int busy; - struct tx_ring *txr; - struct rx_ring *rxr; - struct task que_task; - struct taskqueue *tq; - u64 irqs; + struct adapter *adapter; + u32 msix; /* This queue's MSI-X vector */ + u32 eims; /* This queue's EIMS bit */ + u32 eitr_setting; + u32 me; + struct resource *res; + void *tag; + int busy; + struct tx_ring *txr; + struct rx_ring *rxr; + struct task que_task; + struct taskqueue *tq; + u64 irqs; }; /* * The transmit ring, one per queue */ struct tx_ring { - struct adapter *adapter; - struct mtx tx_mtx; - u32 me; - u32 tail; - int busy; - union ixgbe_adv_tx_desc *tx_base; - struct ixgbe_tx_buf *tx_buffers; - struct ixgbe_dma_alloc txdma; - volatile u16 tx_avail; - u16 next_avail_desc; - u16 next_to_clean; - u16 num_desc; - u32 txd_cmd; - bus_dma_tag_t txtag; - char mtx_name[16]; -#ifndef IXGBE_LEGACY_TX - struct buf_ring *br; - struct task txq_task; -#endif -#ifdef IXGBE_FDIR - u16 atr_sample; - u16 atr_count; -#endif - u32 bytes; /* used for AIM */ - u32 packets; + struct adapter *adapter; + struct mtx tx_mtx; + u32 me; + u32 tail; + int busy; + union ixgbe_adv_tx_desc *tx_base; + struct ixgbe_tx_buf *tx_buffers; + struct ixgbe_dma_alloc txdma; + volatile u16 tx_avail; + u16 next_avail_desc; + u16 next_to_clean; + u16 num_desc; + u32 txd_cmd; + bus_dma_tag_t txtag; + char mtx_name[16]; + struct buf_ring *br; + struct task txq_task; + + /* Flow Director */ + u16 atr_sample; + u16 atr_count; + + u32 bytes; /* used for AIM */ + u32 packets; /* Soft Stats */ - unsigned long tso_tx; - unsigned long no_tx_map_avail; - unsigned long no_tx_dma_setup; - u64 no_desc_avail; - u64 total_packets; + u64 tso_tx; + u64 no_tx_map_avail; + u64 no_tx_dma_setup; + u64 no_desc_avail; + u64 total_packets; }; @@ -398,199 +355,195 @@ struct tx_ring { * The Receive ring, one per rx queue */ struct rx_ring { - struct adapter *adapter; - struct mtx rx_mtx; - u32 me; - u32 tail; - union ixgbe_adv_rx_desc *rx_base; - struct ixgbe_dma_alloc rxdma; - struct lro_ctrl lro; - bool lro_enabled; - bool hw_rsc; - bool vtag_strip; - u16 next_to_refresh; - u16 next_to_check; - u16 num_desc; - u16 mbuf_sz; - char mtx_name[16]; - struct ixgbe_rx_buf *rx_buffers; - bus_dma_tag_t ptag; + struct adapter *adapter; + struct mtx rx_mtx; + u32 me; + u32 tail; + union ixgbe_adv_rx_desc *rx_base; + struct ixgbe_dma_alloc rxdma; + struct lro_ctrl lro; + bool lro_enabled; + bool hw_rsc; + bool vtag_strip; + u16 next_to_refresh; + u16 next_to_check; + u16 num_desc; + u16 mbuf_sz; + char mtx_name[16]; + struct ixgbe_rx_buf *rx_buffers; + bus_dma_tag_t ptag; - u32 bytes; /* Used for AIM calc */ - u32 packets; + u32 bytes; /* Used for AIM calc */ + u32 packets; /* Soft stats */ - u64 rx_irq; - u64 rx_copies; - u64 rx_packets; - u64 rx_bytes; - u64 rx_discarded; - u64 rsc_num; -#ifdef IXGBE_FDIR - u64 flm; -#endif -}; + u64 rx_irq; + u64 rx_copies; + u64 rx_packets; + u64 rx_bytes; + u64 rx_discarded; + u64 rsc_num; -#ifdef PCI_IOV -#define IXGBE_VF_CTS (1 << 0) /* VF is clear to send. */ -#define IXGBE_VF_CAP_MAC (1 << 1) /* VF is permitted to change MAC. */ -#define IXGBE_VF_CAP_VLAN (1 << 2) /* VF is permitted to join vlans. */ -#define IXGBE_VF_ACTIVE (1 << 3) /* VF is active. */ + /* Flow Director */ + u64 flm; +}; #define IXGBE_MAX_VF_MC 30 /* Max number of multicast entries */ struct ixgbe_vf { - u_int pool; - u_int rar_index; - u_int max_frame_size; - uint32_t flags; - uint8_t ether_addr[ETHER_ADDR_LEN]; - uint16_t mc_hash[IXGBE_MAX_VF_MC]; - uint16_t num_mc_hashes; - uint16_t default_vlan; - uint16_t vlan_tag; - uint16_t api_ver; + u_int pool; + u_int rar_index; + u_int max_frame_size; + uint32_t flags; + uint8_t ether_addr[ETHER_ADDR_LEN]; + uint16_t mc_hash[IXGBE_MAX_VF_MC]; + uint16_t num_mc_hashes; + uint16_t default_vlan; + uint16_t vlan_tag; + uint16_t api_ver; }; -#endif /* PCI_IOV */ /* Our adapter structure */ struct adapter { - struct ixgbe_hw hw; - struct ixgbe_osdep osdep; + struct ixgbe_hw hw; + struct ixgbe_osdep osdep; - device_t dev; - struct ifnet *ifp; + device_t dev; + struct ifnet *ifp; - struct resource *pci_mem; - struct resource *msix_mem; + struct resource *pci_mem; + struct resource *msix_mem; /* * Interrupt resources: this set is * either used for legacy, or for Link - * when doing MSIX + * when doing MSI-X */ - void *tag; - struct resource *res; + void *tag; + struct resource *res; - struct ifmedia media; - struct callout timer; - int msix; - int if_flags; + struct ifmedia media; + struct callout timer; + int link_rid; + int if_flags; - struct mtx core_mtx; + struct mtx core_mtx; - eventhandler_tag vlan_attach; - eventhandler_tag vlan_detach; + eventhandler_tag vlan_attach; + eventhandler_tag vlan_detach; - u16 num_vlans; - u16 num_queues; + u16 num_vlans; + u16 num_queues; /* - ** Shadow VFTA table, this is needed because - ** the real vlan filter table gets cleared during - ** a soft reset and the driver needs to be able - ** to repopulate it. - */ - u32 shadow_vfta[IXGBE_VFTA_SIZE]; + * Shadow VFTA table, this is needed because + * the real vlan filter table gets cleared during + * a soft reset and the driver needs to be able + * to repopulate it. + */ + u32 shadow_vfta[IXGBE_VFTA_SIZE]; /* Info about the interface */ - u32 optics; - u32 fc; /* local flow ctrl setting */ - int advertise; /* link speeds */ - bool enable_aim; /* adaptive interrupt moderation */ - bool link_active; - u16 max_frame_size; - u16 num_segs; - u32 link_speed; - bool link_up; - u32 vector; - u16 dmac; - bool eee_enabled; - u32 phy_layer; + int advertise; /* link speeds */ + int enable_aim; /* adaptive interrupt moderation */ + bool link_active; + u16 max_frame_size; + u16 num_segs; + u32 link_speed; + bool link_up; + u32 vector; + u16 dmac; + u32 phy_layer; /* Power management-related */ - bool wol_support; - u32 wufc; + bool wol_support; + u32 wufc; /* Mbuf cluster size */ - u32 rx_mbuf_sz; + u32 rx_mbuf_sz; /* Support for pluggable optics */ - bool sfp_probe; - struct task link_task; /* Link tasklet */ - struct task mod_task; /* SFP tasklet */ - struct task msf_task; /* Multispeed Fiber */ -#ifdef PCI_IOV - struct task mbx_task; /* VF -> PF mailbox interrupt */ -#endif /* PCI_IOV */ -#ifdef IXGBE_FDIR - int fdir_reinit; - struct task fdir_task; -#endif - struct task phy_task; /* PHY intr tasklet */ - struct taskqueue *tq; + bool sfp_probe; + struct task link_task; /* Link tasklet */ + struct task mod_task; /* SFP tasklet */ + struct task msf_task; /* Multispeed Fiber */ + struct task mbx_task; /* VF -> PF mailbox interrupt */ + + /* Flow Director */ + int fdir_reinit; + struct task fdir_task; + + struct task phy_task; /* PHY intr tasklet */ + struct taskqueue *tq; /* - ** Queues: - ** This is the irq holder, it has - ** and RX/TX pair or rings associated - ** with it. - */ - struct ix_queue *queues; - - /* - * Transmit rings: - * Allocated at run time, an array of rings. + * Queues: + * This is the irq holder, it has + * and RX/TX pair or rings associated + * with it. */ - struct tx_ring *tx_rings; - u32 num_tx_desc; - u32 tx_process_limit; + struct ix_queue *queues; /* - * Receive rings: - * Allocated at run time, an array of rings. + * Transmit rings + * Allocated at run time, an array of rings */ - struct rx_ring *rx_rings; - u64 active_queues; - u32 num_rx_desc; - u32 rx_process_limit; + struct tx_ring *tx_rings; + u32 num_tx_desc; + u32 tx_process_limit; + + /* + * Receive rings + * Allocated at run time, an array of rings + */ + struct rx_ring *rx_rings; + u64 active_queues; + u32 num_rx_desc; + u32 rx_process_limit; /* Multicast array memory */ - struct ixgbe_mc_addr *mta; - int num_vfs; - int pool; -#ifdef PCI_IOV - struct ixgbe_vf *vfs; -#endif -#ifdef DEV_NETMAP - void (*init_locked)(struct adapter *); - void (*stop_locked)(void *); -#endif + struct ixgbe_mc_addr *mta; + + /* SR-IOV */ + int iov_mode; + int num_vfs; + int pool; + struct ixgbe_vf *vfs; + + /* Bypass */ + struct ixgbe_bp_data bypass; + + /* Netmap */ + void (*init_locked)(struct adapter *); + void (*stop_locked)(void *); /* Misc stats maintained by the driver */ - unsigned long dropped_pkts; - unsigned long mbuf_defrag_failed; - unsigned long mbuf_header_failed; - unsigned long mbuf_packet_failed; - unsigned long watchdog_events; - unsigned long link_irq; + unsigned long dropped_pkts; + unsigned long mbuf_defrag_failed; + unsigned long mbuf_header_failed; + unsigned long mbuf_packet_failed; + unsigned long watchdog_events; + unsigned long link_irq; union { struct ixgbe_hw_stats pf; struct ixgbevf_hw_stats vf; } stats; #if __FreeBSD_version >= 1100036 /* counter(9) stats */ - u64 ipackets; - u64 ierrors; - u64 opackets; - u64 oerrors; - u64 ibytes; - u64 obytes; - u64 imcasts; - u64 omcasts; - u64 iqdrops; - u64 noproto; + u64 ipackets; + u64 ierrors; + u64 opackets; + u64 oerrors; + u64 ibytes; + u64 obytes; + u64 imcasts; + u64 omcasts; + u64 iqdrops; + u64 noproto; #endif + /* Feature capable/enabled flags. See ixgbe_features.h */ + u32 feat_cap; + u32 feat_en; }; @@ -598,7 +551,7 @@ struct adapter { #define ETHERTYPE_IEEE1588 0x88F7 #define PICOSECS_PER_TICK 20833 #define TSYNC_UDP_PORT 319 /* UDP port for the protocol */ -#define IXGBE_ADVTXD_TSTAMP 0x00080000 +#define IXGBE_ADVTXD_TSTAMP 0x00080000 #define IXGBE_CORE_LOCK_INIT(_sc, _name) \ @@ -647,43 +600,24 @@ struct adapter { #endif /* External PHY register addresses */ -#define IXGBE_PHY_CURRENT_TEMP 0xC820 -#define IXGBE_PHY_OVERTEMP_STATUS 0xC830 +#define IXGBE_PHY_CURRENT_TEMP 0xC820 +#define IXGBE_PHY_OVERTEMP_STATUS 0xC830 /* Sysctl help messages; displayed with sysctl -d */ #define IXGBE_SYSCTL_DESC_ADV_SPEED \ - "\nControl advertised link speed using these flags:\n" \ - "\t0x1 - advertise 100M\n" \ - "\t0x2 - advertise 1G\n" \ - "\t0x4 - advertise 10G\n\n" \ - "\t100M is only supported on certain 10GBaseT adapters.\n" + "\nControl advertised link speed using these flags:\n" \ + "\t0x1 - advertise 100M\n" \ + "\t0x2 - advertise 1G\n" \ + "\t0x4 - advertise 10G\n" \ + "\t0x8 - advertise 10M\n\n" \ + "\t100M and 10M are only supported on certain adapters.\n" #define IXGBE_SYSCTL_DESC_SET_FC \ - "\nSet flow control mode using these values:\n" \ - "\t0 - off\n" \ - "\t1 - rx pause\n" \ - "\t2 - tx pause\n" \ - "\t3 - tx and rx pause" - -static inline bool -ixgbe_is_sfp(struct ixgbe_hw *hw) -{ - switch (hw->phy.type) { - case ixgbe_phy_sfp_avago: - case ixgbe_phy_sfp_ftl: - case ixgbe_phy_sfp_intel: - case ixgbe_phy_sfp_unknown: - case ixgbe_phy_sfp_passive_tyco: - case ixgbe_phy_sfp_passive_unknown: - case ixgbe_phy_qsfp_passive_unknown: - case ixgbe_phy_qsfp_active_unknown: - case ixgbe_phy_qsfp_intel: - case ixgbe_phy_qsfp_unknown: - return TRUE; - default: - return FALSE; - } -} + "\nSet flow control mode using these values:\n" \ + "\t0 - off\n" \ + "\t1 - rx pause\n" \ + "\t2 - tx pause\n" \ + "\t3 - tx and rx pause" /* Workaround to make 8.0 buildable */ #if __FreeBSD_version >= 800000 && __FreeBSD_version < 800504 @@ -699,22 +633,30 @@ drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br) #endif /* -** Find the number of unrefreshed RX descriptors -*/ + * Find the number of unrefreshed RX descriptors + */ static inline u16 ixgbe_rx_unrefreshed(struct rx_ring *rxr) -{ +{ if (rxr->next_to_check > rxr->next_to_refresh) return (rxr->next_to_check - rxr->next_to_refresh - 1); else return ((rxr->num_desc + rxr->next_to_check) - rxr->next_to_refresh - 1); -} +} + +static inline int +ixgbe_legacy_ring_empty(struct ifnet *ifp, struct buf_ring *dummy) +{ + UNREFERENCED_1PARAMETER(dummy); + + return IFQ_DRV_IS_EMPTY(&ifp->if_snd); +} /* -** This checks for a zero mac addr, something that will be likely -** unless the Admin on the Host has created one. -*/ + * This checks for a zero mac addr, something that will be likely + * unless the Admin on the Host has created one. + */ static inline bool ixv_check_ether_addr(u8 *addr) { @@ -723,178 +665,30 @@ ixv_check_ether_addr(u8 *addr) if ((addr[0] == 0 && addr[1]== 0 && addr[2] == 0 && addr[3] == 0 && addr[4]== 0 && addr[5] == 0)) status = FALSE; + return (status); } /* Shared Prototypes */ +void ixgbe_legacy_start(struct ifnet *); +int ixgbe_legacy_start_locked(struct ifnet *, struct tx_ring *); +int ixgbe_mq_start(struct ifnet *, struct mbuf *); +int ixgbe_mq_start_locked(struct ifnet *, struct tx_ring *); +void ixgbe_qflush(struct ifnet *); +void ixgbe_deferred_mq_start(void *, int); -#ifdef IXGBE_LEGACY_TX -void ixgbe_start(struct ifnet *); -void ixgbe_start_locked(struct tx_ring *, struct ifnet *); -#else /* ! IXGBE_LEGACY_TX */ -int ixgbe_mq_start(struct ifnet *, struct mbuf *); -int ixgbe_mq_start_locked(struct ifnet *, struct tx_ring *); -void ixgbe_qflush(struct ifnet *); -void ixgbe_deferred_mq_start(void *, int); -#endif /* IXGBE_LEGACY_TX */ +int ixgbe_allocate_queues(struct adapter *); +int ixgbe_setup_transmit_structures(struct adapter *); +void ixgbe_free_transmit_structures(struct adapter *); +int ixgbe_setup_receive_structures(struct adapter *); +void ixgbe_free_receive_structures(struct adapter *); +void ixgbe_txeof(struct tx_ring *); +bool ixgbe_rxeof(struct ix_queue *); -int ixgbe_allocate_queues(struct adapter *); -int ixgbe_allocate_transmit_buffers(struct tx_ring *); -int ixgbe_setup_transmit_structures(struct adapter *); -void ixgbe_free_transmit_structures(struct adapter *); -int ixgbe_allocate_receive_buffers(struct rx_ring *); -int ixgbe_setup_receive_structures(struct adapter *); -void ixgbe_free_receive_structures(struct adapter *); -void ixgbe_txeof(struct tx_ring *); -bool ixgbe_rxeof(struct ix_queue *); - -int ixgbe_dma_malloc(struct adapter *, - bus_size_t, struct ixgbe_dma_alloc *, int); -void ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *); - -#ifdef PCI_IOV - -static inline boolean_t -ixgbe_vf_mac_changed(struct ixgbe_vf *vf, const uint8_t *mac) -{ - return (bcmp(mac, vf->ether_addr, ETHER_ADDR_LEN) != 0); -} - -static inline void -ixgbe_send_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) -{ - - if (vf->flags & IXGBE_VF_CTS) - msg |= IXGBE_VT_MSGTYPE_CTS; - - ixgbe_write_mbx(&adapter->hw, &msg, 1, vf->pool); -} - -static inline void -ixgbe_send_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) -{ - msg &= IXGBE_VT_MSG_MASK; - ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_ACK); -} - -static inline void -ixgbe_send_vf_nack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) -{ - msg &= IXGBE_VT_MSG_MASK; - ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_NACK); -} - -static inline void -ixgbe_process_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf) -{ - if (!(vf->flags & IXGBE_VF_CTS)) - ixgbe_send_vf_nack(adapter, vf, 0); -} - -static inline enum ixgbe_iov_mode -ixgbe_get_iov_mode(struct adapter *adapter) -{ - if (adapter->num_vfs == 0) - return (IXGBE_NO_VM); - if (adapter->num_queues <= 2) - return (IXGBE_64_VM); - else if (adapter->num_queues <= 4) - return (IXGBE_32_VM); - else - return (IXGBE_NO_VM); -} - -static inline u16 -ixgbe_max_vfs(enum ixgbe_iov_mode mode) -{ - /* - * We return odd numbers below because we - * reserve 1 VM's worth of queues for the PF. - */ - switch (mode) { - case IXGBE_64_VM: - return (63); - case IXGBE_32_VM: - return (31); - case IXGBE_NO_VM: - default: - return (0); - } -} - -static inline int -ixgbe_vf_queues(enum ixgbe_iov_mode mode) -{ - switch (mode) { - case IXGBE_64_VM: - return (2); - case IXGBE_32_VM: - return (4); - case IXGBE_NO_VM: - default: - return (0); - } -} - -static inline int -ixgbe_vf_que_index(enum ixgbe_iov_mode mode, u32 vfnum, int num) -{ - return ((vfnum * ixgbe_vf_queues(mode)) + num); -} - -static inline int -ixgbe_pf_que_index(enum ixgbe_iov_mode mode, int num) -{ - return (ixgbe_vf_que_index(mode, ixgbe_max_vfs(mode), num)); -} - -static inline void -ixgbe_update_max_frame(struct adapter * adapter, int max_frame) -{ - if (adapter->max_frame_size < max_frame) - adapter->max_frame_size = max_frame; -} - -static inline u32 -ixgbe_get_mrqc(enum ixgbe_iov_mode mode) -{ - u32 mrqc = 0; - switch (mode) { - case IXGBE_64_VM: - mrqc = IXGBE_MRQC_VMDQRSS64EN; - break; - case IXGBE_32_VM: - mrqc = IXGBE_MRQC_VMDQRSS32EN; - break; - case IXGBE_NO_VM: - mrqc = 0; - break; - default: - panic("Unexpected SR-IOV mode %d", mode); - } - return(mrqc); -} - - -static inline u32 -ixgbe_get_mtqc(enum ixgbe_iov_mode mode) -{ - uint32_t mtqc = 0; - switch (mode) { - case IXGBE_64_VM: - mtqc |= IXGBE_MTQC_64VF | IXGBE_MTQC_VT_ENA; - break; - case IXGBE_32_VM: - mtqc |= IXGBE_MTQC_32VF | IXGBE_MTQC_VT_ENA; - break; - case IXGBE_NO_VM: - mtqc = IXGBE_MTQC_64Q_1PB; - break; - default: - panic("Unexpected SR-IOV mode %d", mode); - } - return(mtqc); -} -#endif /* PCI_IOV */ +#include "ixgbe_bypass.h" +#include "ixgbe_sriov.h" +#include "ixgbe_fdir.h" +#include "ixgbe_rss.h" +#include "ixgbe_netmap.h" #endif /* _IXGBE_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_82598.c b/sys/dev/ixgbe/ixgbe_82598.c index c10e23a8a6ff..2c6254969630 100644 --- a/sys/dev/ixgbe/ixgbe_82598.c +++ b/sys/dev/ixgbe/ixgbe_82598.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -996,17 +996,20 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) * @vlan: VLAN id to write to VLAN filter * @vind: VMDq output index that maps queue to VLAN id in VFTA * @vlan_on: boolean flag to turn on/off VLAN in VFTA + * @vlvf_bypass: boolean flag - unused * * Turn on/off specified VLAN in the VLAN filter table. **/ s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, - bool vlan_on) + bool vlan_on, bool vlvf_bypass) { u32 regindex; u32 bitindex; u32 bits; u32 vftabyte; + UNREFERENCED_1PARAMETER(vlvf_bypass); + DEBUGFUNC("ixgbe_set_vfta_82598"); if (vlan > 4095) @@ -1220,9 +1223,9 @@ static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset, * * Determines physical layer capabilities of the current configuration. **/ -u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) +u64 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) { - u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; diff --git a/sys/dev/ixgbe/ixgbe_82598.h b/sys/dev/ixgbe/ixgbe_82598.h index d2241c70cd14..725d8ec3a115 100644 --- a/sys/dev/ixgbe/ixgbe_82598.h +++ b/sys/dev/ixgbe/ixgbe_82598.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -40,12 +40,13 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw); s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw); void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw); s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); -s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on); +s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on, + bool vlvf_bypass); s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data); -u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw); s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw); void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw); void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw); diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c index 109ed955441b..736872460b88 100644 --- a/sys/dev/ixgbe/ixgbe_82599.c +++ b/sys/dev/ixgbe/ixgbe_82599.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -394,6 +394,10 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) /* Manageability interface */ mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic; + mac->ops.bypass_rw = ixgbe_bypass_rw_generic; + mac->ops.bypass_valid_rd = ixgbe_bypass_valid_rd_generic; + mac->ops.bypass_set = ixgbe_bypass_set_generic; + mac->ops.bypass_rd_eep = ixgbe_bypass_rd_eep_generic; mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic; @@ -1177,12 +1181,16 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) /* Add the SAN MAC address to the RAR only if it's a valid address */ if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { - hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, - hw->mac.san_addr, 0, IXGBE_RAH_AV); - /* Save the SAN MAC RAR index */ hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; + hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index, + hw->mac.san_addr, 0, IXGBE_RAH_AV); + + /* clear VMDq pool/queue selection for this RAR */ + hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index, + IXGBE_CLEAR_VMDQ_ALL); + /* Reserve the last RAR for the SAN MAC address */ hw->mac.num_rar_entries--; } @@ -1381,9 +1389,6 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl, (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) | (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) | (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT); - if ((hw->mac.type == ixgbe_mac_X550) || - (hw->mac.type == ixgbe_mac_X550EM_x)) - fdirctrl |= IXGBE_FDIRCTRL_DROP_NO_MATCH; if (cloud_mode) fdirctrl |=(IXGBE_FDIRCTRL_FILTERMODE_CLOUD << @@ -1412,7 +1417,8 @@ void ixgbe_set_fdir_drop_queue_82599(struct ixgbe_hw *hw, u8 dropqueue) /* Set drop queue */ fdirctrl |= (dropqueue << IXGBE_FDIRCTRL_DROP_Q_SHIFT); if ((hw->mac.type == ixgbe_mac_X550) || - (hw->mac.type == ixgbe_mac_X550EM_x)) + (hw->mac.type == ixgbe_mac_X550EM_x) || + (hw->mac.type == ixgbe_mac_X550EM_a)) fdirctrl |= IXGBE_FDIRCTRL_DROP_NO_MATCH; IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, @@ -1738,15 +1744,17 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, switch (IXGBE_NTOHS(input_mask->formatted.vlan_id) & 0xEFFF) { case 0x0000: - /* mask VLAN ID, fall through to mask VLAN priority */ + /* mask VLAN ID */ fdirm |= IXGBE_FDIRM_VLANID; + /* fall through */ case 0x0FFF: /* mask VLAN priority */ fdirm |= IXGBE_FDIRM_VLANP; break; case 0xE000: - /* mask VLAN ID only, fall through */ + /* mask VLAN ID only */ fdirm |= IXGBE_FDIRM_VLANID; + /* fall through */ case 0xEFFF: /* no VLAN fields masked */ break; @@ -1757,8 +1765,9 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, switch (input_mask->formatted.flex_bytes & 0xFFFF) { case 0x0000: - /* Mask Flex Bytes, fall through */ + /* Mask Flex Bytes */ fdirm |= IXGBE_FDIRM_FLEX; + /* fall through */ case 0xFFFF: break; default: @@ -1809,14 +1818,23 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, } IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIP6M, fdirip6m); - /* Set all bits in FDIRTCPM, FDIRUDPM, FDIRSIP4M and - * FDIRDIP4M in cloud mode to allow L3/L3 packets to - * tunnel. + /* Set all bits in FDIRTCPM, FDIRUDPM, FDIRSCTPM, + * FDIRSIP4M and FDIRDIP4M in cloud mode to allow + * L3/L3 packets to tunnel. */ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xFFFFFFFF); IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xFFFFFFFF); IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M, 0xFFFFFFFF); IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M, 0xFFFFFFFF); + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, 0xFFFFFFFF); + break; + default: + break; + } } /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ @@ -1834,6 +1852,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, switch (hw->mac.type) { case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm); break; default: @@ -2013,6 +2032,7 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, DEBUGOUT(" Error on src/dst port\n"); return IXGBE_ERR_CONFIG; } + /* fall through */ case IXGBE_ATR_FLOW_TYPE_TCPV4: case IXGBE_ATR_FLOW_TYPE_TUNNELED_TCPV4: case IXGBE_ATR_FLOW_TYPE_UDPV4: @@ -2158,9 +2178,9 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) * * Determines physical layer capabilities of the current configuration. **/ -u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) +u64 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) { - u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK; diff --git a/sys/dev/ixgbe/ixgbe_82599.h b/sys/dev/ixgbe/ixgbe_82599.h index bcfb0431bc5b..90c45db5c13e 100644 --- a/sys/dev/ixgbe/ixgbe_82599.h +++ b/sys/dev/ixgbe/ixgbe_82599.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -58,7 +58,7 @@ s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw); s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw); s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw); -u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval); s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val); s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 reg_val, bool locked); diff --git a/sys/dev/ixgbe/ixgbe_api.c b/sys/dev/ixgbe/ixgbe_api.c index 894d0b2ac9d7..1dabc8beab5b 100644 --- a/sys/dev/ixgbe/ixgbe_api.c +++ b/sys/dev/ixgbe/ixgbe_api.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -53,6 +53,10 @@ static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = { IXGBE_MVALS_INIT(_X550EM_x) }; +static const u32 ixgbe_mvals_X550EM_a[IXGBE_MVALS_IDX_LIMIT] = { + IXGBE_MVALS_INIT(_X550EM_a) +}; + /** * ixgbe_dcb_get_rtrup2tc - read rtrup2tc reg * @hw: pointer to hardware structure @@ -103,13 +107,10 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw) status = ixgbe_init_ops_X550(hw); break; case ixgbe_mac_X550EM_x: - status = ixgbe_init_ops_X550EM(hw); + status = ixgbe_init_ops_X550EM_x(hw); break; - case ixgbe_mac_82599_vf: - case ixgbe_mac_X540_vf: - case ixgbe_mac_X550_vf: - case ixgbe_mac_X550EM_x_vf: - status = ixgbe_init_ops_vf(hw); + case ixgbe_mac_X550EM_a: + status = ixgbe_init_ops_X550EM_a(hw); break; default: status = IXGBE_ERR_DEVICE_NOT_SUPPORTED; @@ -174,15 +175,6 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82599_T3_LOM: hw->mac.type = ixgbe_mac_82599EB; break; - case IXGBE_DEV_ID_82599_VF: - case IXGBE_DEV_ID_82599_VF_HV: - hw->mac.type = ixgbe_mac_82599_vf; - break; - case IXGBE_DEV_ID_X540_VF: - case IXGBE_DEV_ID_X540_VF_HV: - hw->mac.type = ixgbe_mac_X540_vf; - hw->mvals = ixgbe_mvals_X540; - break; case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: case IXGBE_DEV_ID_X540_BYPASS: @@ -199,18 +191,23 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) case IXGBE_DEV_ID_X550EM_X_10G_T: case IXGBE_DEV_ID_X550EM_X_1G_T: case IXGBE_DEV_ID_X550EM_X_SFP: + case IXGBE_DEV_ID_X550EM_X_XFI: hw->mac.type = ixgbe_mac_X550EM_x; hw->mvals = ixgbe_mvals_X550EM_x; break; - case IXGBE_DEV_ID_X550_VF: - case IXGBE_DEV_ID_X550_VF_HV: - hw->mac.type = ixgbe_mac_X550_vf; - hw->mvals = ixgbe_mvals_X550; - break; - case IXGBE_DEV_ID_X550EM_X_VF: - case IXGBE_DEV_ID_X550EM_X_VF_HV: - hw->mac.type = ixgbe_mac_X550EM_x_vf; - hw->mvals = ixgbe_mvals_X550EM_x; + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + case IXGBE_DEV_ID_X550EM_A_SFP_N: + case IXGBE_DEV_ID_X550EM_A_SGMII: + case IXGBE_DEV_ID_X550EM_A_SGMII_L: + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_QSFP: + case IXGBE_DEV_ID_X550EM_A_QSFP_N: + case IXGBE_DEV_ID_X550EM_A_SFP: + hw->mac.type = ixgbe_mac_X550EM_a; + hw->mvals = ixgbe_mvals_X550EM_a; break; default: ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED; @@ -1057,33 +1054,38 @@ s32 ixgbe_clear_vfta(struct ixgbe_hw *hw) * ixgbe_set_vfta - Set VLAN filter table * @hw: pointer to hardware structure * @vlan: VLAN id to write to VLAN filter - * @vind: VMDq output index that maps queue to VLAN id in VFTA - * @vlan_on: boolean flag to turn on/off VLAN in VFTA + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN + * @vlvf_bypass: boolean flag indicating updating the default pool is okay * * Turn on/off specified VLAN in the VLAN filter table. **/ -s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on) +s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on, + bool vlvf_bypass) { return ixgbe_call_func(hw, hw->mac.ops.set_vfta, (hw, vlan, vind, - vlan_on), IXGBE_NOT_IMPLEMENTED); + vlan_on, vlvf_bypass), IXGBE_NOT_IMPLEMENTED); } /** * ixgbe_set_vlvf - Set VLAN Pool Filter * @hw: pointer to hardware structure * @vlan: VLAN id to write to VLAN filter - * @vind: VMDq output index that maps queue to VLAN id in VFVFB - * @vlan_on: boolean flag to turn on/off VLAN in VFVF - * @vfta_changed: pointer to boolean flag which indicates whether VFTA - * should be changed + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN in VLVF + * @vfta_delta: pointer to the difference between the current value of VFTA + * and the desired value + * @vfta: the desired value of the VFTA + * @vlvf_bypass: boolean flag indicating updating the default pool is okay * * Turn on/off specified bit in VLVF table. **/ s32 ixgbe_set_vlvf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on, - bool *vfta_changed) + u32 *vfta_delta, u32 vfta, bool vlvf_bypass) { return ixgbe_call_func(hw, hw->mac.ops.set_vlvf, (hw, vlan, vind, - vlan_on, vfta_changed), IXGBE_NOT_IMPLEMENTED); + vlan_on, vfta_delta, vfta, vlvf_bypass), + IXGBE_NOT_IMPLEMENTED); } /** @@ -1117,12 +1119,15 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw) * @min: driver minor number to be sent to firmware * @build: driver build number to be sent to firmware * @ver: driver version number to be sent to firmware + * @len: length of driver_ver string + * @driver_ver: driver string **/ s32 ixgbe_set_fw_drv_ver(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, - u8 ver) + u8 ver, u16 len, char *driver_ver) { return ixgbe_call_func(hw, hw->mac.ops.set_fw_drv_ver, (hw, maj, min, - build, ver), IXGBE_NOT_IMPLEMENTED); + build, ver, len, driver_ver), + IXGBE_NOT_IMPLEMENTED); } @@ -1316,6 +1321,69 @@ s32 ixgbe_handle_lasi(struct ixgbe_hw *hw) IXGBE_NOT_IMPLEMENTED); } +/** + * ixgbe_bypass_rw - Bit bang data into by_pass FW + * @hw: pointer to hardware structure + * @cmd: Command we send to the FW + * @status: The reply from the FW + * + * Bit-bangs the cmd to the by_pass FW status points to what is returned. + **/ +s32 ixgbe_bypass_rw(struct ixgbe_hw *hw, u32 cmd, u32 *status) +{ + return ixgbe_call_func(hw, hw->mac.ops.bypass_rw, (hw, cmd, status), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_bypass_valid_rd - Verify valid return from bit-bang. + * + * If we send a write we can't be sure it took until we can read back + * that same register. It can be a problem as some of the feilds may + * for valid reasons change inbetween the time wrote the register and + * we read it again to verify. So this function check everything we + * can check and then assumes it worked. + * + * @u32 in_reg - The register cmd for the bit-bang read. + * @u32 out_reg - The register returned from a bit-bang read. + **/ +bool ixgbe_bypass_valid_rd(struct ixgbe_hw *hw, u32 in_reg, u32 out_reg) +{ + return ixgbe_call_func(hw, hw->mac.ops.bypass_valid_rd, + (in_reg, out_reg), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_bypass_set - Set a bypass field in the FW CTRL Regiter. + * @hw: pointer to hardware structure + * @cmd: The control word we are setting. + * @event: The event we are setting in the FW. This also happens to + * be the mask for the event we are setting (handy) + * @action: The action we set the event to in the FW. This is in a + * bit field that happens to be what we want to put in + * the event spot (also handy) + * + * Writes to the cmd control the bits in actions. + **/ +s32 ixgbe_bypass_set(struct ixgbe_hw *hw, u32 cmd, u32 event, u32 action) +{ + return ixgbe_call_func(hw, hw->mac.ops.bypass_set, + (hw, cmd, event, action), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_bypass_rd_eep - Read the bypass FW eeprom address + * @hw: pointer to hardware structure + * @addr: The bypass eeprom address to read. + * @value: The 8b of data at the address above. + **/ +s32 ixgbe_bypass_rd_eep(struct ixgbe_hw *hw, u32 addr, u8 *value) +{ + return ixgbe_call_func(hw, hw->mac.ops.bypass_rd_eep, + (hw, addr, value), IXGBE_NOT_IMPLEMENTED); +} + /** * ixgbe_read_analog_reg8 - Reads 8 bit analog register * @hw: pointer to hardware structure @@ -1391,35 +1459,33 @@ s32 ixgbe_read_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, } /** - * ixgbe_read_i2c_combined - Perform I2C read combined operation + * ixgbe_read_link - Perform read operation on link device * @hw: pointer to the hardware structure - * @addr: I2C bus address to read from - * @reg: I2C device register to read from + * @addr: bus address to read from + * @reg: device register to read from * @val: pointer to location to receive read value * * Returns an error code on error. */ -s32 ixgbe_read_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val) +s32 ixgbe_read_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val) { - return ixgbe_call_func(hw, hw->phy.ops.read_i2c_combined, (hw, addr, + return ixgbe_call_func(hw, hw->link.ops.read_link, (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED); } /** - * ixgbe_read_i2c_combined_unlocked - Perform I2C read combined operation + * ixgbe_read_link_unlocked - Perform read operation on link device * @hw: pointer to the hardware structure - * @addr: I2C bus address to read from - * @reg: I2C device register to read from + * @addr: bus address to read from + * @reg: device register to read from * @val: pointer to location to receive read value * * Returns an error code on error. **/ -s32 ixgbe_read_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, - u16 *val) +s32 ixgbe_read_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val) { - return ixgbe_call_func(hw, hw->phy.ops.read_i2c_combined_unlocked, - (hw, addr, reg, val), - IXGBE_NOT_IMPLEMENTED); + return ixgbe_call_func(hw, hw->link.ops.read_link_unlocked, + (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED); } /** @@ -1458,33 +1524,32 @@ s32 ixgbe_write_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, } /** - * ixgbe_write_i2c_combined - Perform I2C write combined operation + * ixgbe_write_link - Perform write operation on link device * @hw: pointer to the hardware structure - * @addr: I2C bus address to write to - * @reg: I2C device register to write to + * @addr: bus address to write to + * @reg: device register to write to * @val: value to write * * Returns an error code on error. */ -s32 ixgbe_write_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val) +s32 ixgbe_write_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val) { - return ixgbe_call_func(hw, hw->phy.ops.write_i2c_combined, (hw, addr, - reg, val), IXGBE_NOT_IMPLEMENTED); + return ixgbe_call_func(hw, hw->link.ops.write_link, + (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED); } /** - * ixgbe_write_i2c_combined_unlocked - Perform I2C write combined operation + * ixgbe_write_link_unlocked - Perform write operation on link device * @hw: pointer to the hardware structure - * @addr: I2C bus address to write to - * @reg: I2C device register to write to + * @addr: bus address to write to + * @reg: device register to write to * @val: value to write * * Returns an error code on error. **/ -s32 ixgbe_write_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, - u16 val) +s32 ixgbe_write_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val) { - return ixgbe_call_func(hw, hw->phy.ops.write_i2c_combined_unlocked, + return ixgbe_call_func(hw, hw->link.ops.write_link_unlocked, (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED); } @@ -1525,7 +1590,7 @@ s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data) * * Determines physical layer capabilities of the current configuration. **/ -u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw) +u64 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw) { return ixgbe_call_func(hw, hw->mac.ops.get_supported_physical_layer, (hw), IXGBE_PHYSICAL_LAYER_UNKNOWN); @@ -1596,6 +1661,21 @@ void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask) hw->mac.ops.release_swfw_sync(hw, mask); } +/** + * ixgbe_init_swfw_semaphore - Clean up SWFW semaphore + * @hw: pointer to hardware structure + * + * Attempts to acquire the SWFW semaphore through SW_FW_SYNC register. + * Regardless of whether is succeeds or not it then release the semaphore. + * This is function is called to recover from catastrophic failures that + * may have left the semaphore locked. + **/ +void ixgbe_init_swfw_semaphore(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.init_swfw_sync) + hw->mac.ops.init_swfw_sync(hw); +} + void ixgbe_disable_rx(struct ixgbe_hw *hw) { diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h index 24d507039d87..926273405b05 100644 --- a/sys/dev/ixgbe/ixgbe_api.h +++ b/sys/dev/ixgbe/ixgbe_api.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -46,7 +46,8 @@ extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw); extern s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw); extern s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw); extern s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw); -extern s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw); s32 ixgbe_set_mac_type(struct ixgbe_hw *hw); s32 ixgbe_init_hw(struct ixgbe_hw *hw); @@ -125,13 +126,14 @@ s32 ixgbe_enable_mc(struct ixgbe_hw *hw); s32 ixgbe_disable_mc(struct ixgbe_hw *hw); s32 ixgbe_clear_vfta(struct ixgbe_hw *hw); s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, - u32 vind, bool vlan_on); + u32 vind, bool vlan_on, bool vlvf_bypass); s32 ixgbe_set_vlvf(struct ixgbe_hw *hw, u32 vlan, u32 vind, - bool vlan_on, bool *vfta_changed); + bool vlan_on, u32 *vfta_delta, u32 vfta, + bool vlvf_bypass); s32 ixgbe_fc_enable(struct ixgbe_hw *hw); s32 ixgbe_setup_fc(struct ixgbe_hw *hw); s32 ixgbe_set_fw_drv_ver(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, - u8 ver); + u8 ver, u16 len, char *driver_ver); void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr); s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw, u16 *firmware_version); @@ -139,7 +141,7 @@ s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw); s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data); -u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval); s32 ixgbe_disable_sec_rx_path(struct ixgbe_hw *hw); s32 ixgbe_enable_sec_rx_path(struct ixgbe_hw *hw); @@ -175,26 +177,29 @@ s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); s32 ixgbe_read_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); -s32 ixgbe_read_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val); -s32 ixgbe_read_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, - u16 *val); +s32 ixgbe_read_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val); +s32 ixgbe_read_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val); s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 data); void ixgbe_set_fdir_drop_queue_82599(struct ixgbe_hw *hw, u8 dropqueue); s32 ixgbe_write_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 data); -s32 ixgbe_write_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val); -s32 ixgbe_write_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, - u16 val); +s32 ixgbe_write_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val); +s32 ixgbe_write_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val); s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data); s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps); s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u32 mask); void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask); +void ixgbe_init_swfw_semaphore(struct ixgbe_hw *hw); s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix, u16 *wwpn_prefix); s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs); +s32 ixgbe_bypass_rw(struct ixgbe_hw *hw, u32 cmd, u32 *status); +s32 ixgbe_bypass_set(struct ixgbe_hw *hw, u32 cmd, u32 event, u32 action); +s32 ixgbe_bypass_rd_eep(struct ixgbe_hw *hw, u32 addr, u8 *value); +bool ixgbe_bypass_valid_rd(struct ixgbe_hw *hw, u32 in_reg, u32 out_reg); s32 ixgbe_dmac_config(struct ixgbe_hw *hw); s32 ixgbe_dmac_update_tcs(struct ixgbe_hw *hw); s32 ixgbe_dmac_config_tcs(struct ixgbe_hw *hw); @@ -216,5 +221,7 @@ s32 ixgbe_handle_lasi(struct ixgbe_hw *hw); void ixgbe_set_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed); void ixgbe_disable_rx(struct ixgbe_hw *hw); void ixgbe_enable_rx(struct ixgbe_hw *hw); +s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); #endif /* _IXGBE_API_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_bypass.h b/sys/dev/ixgbe/ixgbe_bypass.h new file mode 100644 index 000000000000..9a8d6d259cae --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_bypass.h @@ -0,0 +1,51 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#ifndef _IXGBE_BYPASS_H_ +#define _IXGBE_BYPASS_H_ + + +/* + * The bypass driver needs to set FW to a epoc of the number of + * seconds we are into this year. This macro's help support that. + */ +#define SEC_PER_DAY (60 * 60 * 24) +#define SEC_PER_YEAR (SEC_PER_DAY * 365) +#define SEC_PER_LYEAR (SEC_PER_DAY * 366) +#define LEAP_YR(y) ((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0))) +#define SEC_THIS_YEAR(y) (LEAP_YR(y) ? SEC_PER_LYEAR : SEC_PER_YEAR) + +void ixgbe_bypass_init(struct adapter *); + +#endif /* _IXGBE_BYPASS_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c index cad2a855942b..8e21d5ec66d8 100644 --- a/sys/dev/ixgbe/ixgbe_common.c +++ b/sys/dev/ixgbe/ixgbe_common.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -114,6 +114,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) mac->ops.led_off = ixgbe_led_off_generic; mac->ops.blink_led_start = ixgbe_blink_led_start_generic; mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic; + mac->ops.init_led_link_act = ixgbe_init_led_link_act_generic; /* RAR, Multicast, VLAN */ mac->ops.set_rar = ixgbe_set_rar_generic; @@ -136,6 +137,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) /* Flow Control */ mac->ops.fc_enable = ixgbe_fc_enable_generic; mac->ops.setup_fc = ixgbe_setup_fc_generic; + mac->ops.fc_autoneg = ixgbe_fc_autoneg; /* Link */ mac->ops.get_link_capabilities = NULL; @@ -169,16 +171,30 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) case ixgbe_media_type_fiber_fixed: case ixgbe_media_type_fiber_qsfp: case ixgbe_media_type_fiber: - hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); - /* if link is down, assume supported */ - if (link_up) - supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? + /* flow control autoneg black list */ + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_SFP: + case IXGBE_DEV_ID_X550EM_A_SFP_N: + case IXGBE_DEV_ID_X550EM_A_QSFP: + case IXGBE_DEV_ID_X550EM_A_QSFP_N: + supported = FALSE; + break; + default: + hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); + /* if link is down, assume supported */ + if (link_up) + supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? TRUE : FALSE; - else - supported = TRUE; + else + supported = TRUE; + } + break; case ixgbe_media_type_backplane: - supported = TRUE; + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_XFI) + supported = FALSE; + else + supported = TRUE; break; case ixgbe_media_type_copper: /* only some copper devices support flow control autoneg */ @@ -190,6 +206,9 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) case IXGBE_DEV_ID_X550T: case IXGBE_DEV_ID_X550T1: case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: supported = TRUE; break; default: @@ -199,12 +218,10 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) break; } - if (!supported) { + if (!supported) ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, - "Device %x does not support flow control autoneg", - hw->device_id); - } - + "Device %x does not support flow control autoneg", + hw->device_id); return supported; } @@ -250,7 +267,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw) if (ret_val != IXGBE_SUCCESS) goto out; - /* only backplane uses autoc so fall though */ + /* fall through - only backplane uses autoc */ case ixgbe_media_type_fiber_fixed: case ixgbe_media_type_fiber_qsfp: case ixgbe_media_type_fiber: @@ -377,6 +394,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) { s32 ret_val; u32 ctrl_ext; + u16 device_caps; DEBUGFUNC("ixgbe_start_hw_generic"); @@ -399,14 +417,31 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) /* Setup flow control */ ret_val = ixgbe_setup_fc(hw); - if (ret_val != IXGBE_SUCCESS) - goto out; + if (ret_val != IXGBE_SUCCESS && ret_val != IXGBE_NOT_IMPLEMENTED) { + DEBUGOUT1("Flow control setup failed, returning %d\n", ret_val); + return ret_val; + } + + /* Cache bit indicating need for crosstalk fix */ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + hw->mac.ops.get_device_caps(hw, &device_caps); + if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR) + hw->need_crosstalk_fix = FALSE; + else + hw->need_crosstalk_fix = TRUE; + break; + default: + hw->need_crosstalk_fix = FALSE; + break; + } /* Clear adapter stopped flag */ hw->adapter_stopped = FALSE; -out: - return ret_val; + return IXGBE_SUCCESS; } /** @@ -467,11 +502,18 @@ s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) /* Reset the hardware */ status = hw->mac.ops.reset_hw(hw); - if (status == IXGBE_SUCCESS) { + if (status == IXGBE_SUCCESS || status == IXGBE_ERR_SFP_NOT_PRESENT) { /* Start the HW */ status = hw->mac.ops.start_hw(hw); } + /* Initialize the LED link active for LED blink support */ + if (hw->mac.ops.init_led_link_act) + hw->mac.ops.init_led_link_act(hw); + + if (status != IXGBE_SUCCESS) + DEBUGOUT1("Failed to initialize HW, STATUS = %d\n", status); + return status; } @@ -1027,24 +1069,33 @@ s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices * @hw: pointer to the HW structure * - * Determines the LAN function id by reading memory-mapped registers - * and swaps the port value if requested. + * Determines the LAN function id by reading memory-mapped registers and swaps + * the port value if requested, and set MAC instance for devices that share + * CS4227. **/ void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) { struct ixgbe_bus_info *bus = &hw->bus; u32 reg; + u16 ee_ctrl_4; DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); reg = IXGBE_READ_REG(hw, IXGBE_STATUS); bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; - bus->lan_id = bus->func; + bus->lan_id = (u8)bus->func; /* check for a port swap */ reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); if (reg & IXGBE_FACTPS_LFS) bus->func ^= 0x1; + + /* Get MAC instance from EEPROM for configuring CS4227 */ + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP) { + hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_4, &ee_ctrl_4); + bus->instance_id = (ee_ctrl_4 & IXGBE_EE_CTRL_4_INST_ID) >> + IXGBE_EE_CTRL_4_INST_ID_SHIFT; + } } /** @@ -1101,6 +1152,47 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) return ixgbe_disable_pcie_master(hw); } +/** + * ixgbe_init_led_link_act_generic - Store the LED index link/activity. + * @hw: pointer to hardware structure + * + * Store the index for the link active LED. This will be used to support + * blinking the LED. + **/ +s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + u32 led_reg, led_mode; + u8 i; + + led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + /* Get LED link active from the LEDCTL register */ + for (i = 0; i < 4; i++) { + led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i); + + if ((led_mode & IXGBE_LED_MODE_MASK_BASE) == + IXGBE_LED_LINK_ACTIVE) { + mac->led_link_act = i; + return IXGBE_SUCCESS; + } + } + + /* + * If LEDCTL register does not have the LED link active set, then use + * known MAC defaults. + */ + switch (hw->mac.type) { + case ixgbe_mac_X550EM_a: + case ixgbe_mac_X550EM_x: + mac->led_link_act = 1; + break; + default: + mac->led_link_act = 2; + } + return IXGBE_SUCCESS; +} + /** * ixgbe_led_on_generic - Turns on the software controllable LEDs. * @hw: pointer to hardware structure @@ -1112,6 +1204,9 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) DEBUGFUNC("ixgbe_led_on_generic"); + if (index > 3) + return IXGBE_ERR_PARAM; + /* To turn on the LED, set mode to ON. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); @@ -1132,6 +1227,9 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) DEBUGFUNC("ixgbe_led_off_generic"); + if (index > 3) + return IXGBE_ERR_PARAM; + /* To turn off the LED, set mode to OFF. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); @@ -1902,7 +2000,7 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) usec_delay(5); ixgbe_standby_eeprom(hw); - } + }; /* * On some parts, SPI write time could vary from 0-20mSec on 3.3V @@ -1988,7 +2086,7 @@ static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, * EEPROM */ mask = mask >> 1; - } + }; /* We leave the "DI" bit set to "0" when we leave this routine. */ eec &= ~IXGBE_EEC_DI; @@ -2250,7 +2348,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) * ixgbe_validate_mac_addr - Validate MAC address * @mac_addr: pointer to MAC address. * - * Tests a MAC address to ensure it is a valid Individual Address + * Tests a MAC address to ensure it is a valid Individual Address. **/ s32 ixgbe_validate_mac_addr(u8 *mac_addr) { @@ -2260,16 +2358,13 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr) /* Make sure it is not a multicast address */ if (IXGBE_IS_MULTICAST(mac_addr)) { - DEBUGOUT("MAC address is multicast\n"); status = IXGBE_ERR_INVALID_MAC_ADDR; /* Not a broadcast address */ } else if (IXGBE_IS_BROADCAST(mac_addr)) { - DEBUGOUT("MAC address is broadcast\n"); status = IXGBE_ERR_INVALID_MAC_ADDR; /* Reject the zero address */ } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { - DEBUGOUT("MAC address is all zeros\n"); status = IXGBE_ERR_INVALID_MAC_ADDR; } return status; @@ -2407,10 +2502,11 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) hw->mac.addr[4], hw->mac.addr[5]); hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); - - /* clear VMDq pool/queue selection for RAR 0 */ - hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); } + + /* clear VMDq pool/queue selection for RAR 0 */ + hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); + hw->addr_ctrl.overflow_promisc = 0; hw->addr_ctrl.rar_used_count = 1; @@ -2739,7 +2835,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) } /* Negotiate the fc mode to use */ - ixgbe_fc_autoneg(hw); + hw->mac.ops.fc_autoneg(hw); /* Disable any previous flow control settings */ mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); @@ -2849,8 +2945,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) * Find the intersection between advertised settings and link partner's * advertised settings **/ -static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, - u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) +s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) { if ((!(adv_reg)) || (!(lp_reg))) { ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED, @@ -3323,7 +3419,7 @@ s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked) **/ s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw) { - int secrxreg; + u32 secrxreg; DEBUGFUNC("ixgbe_enable_sec_rx_path_generic"); @@ -3370,6 +3466,9 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) DEBUGFUNC("ixgbe_blink_led_start_generic"); + if (index > 3) + return IXGBE_ERR_PARAM; + /* * Link must be up to auto-blink the LEDs; * Force it if link is down. @@ -3415,6 +3514,10 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) DEBUGFUNC("ixgbe_blink_led_stop_generic"); + if (index > 3) + return IXGBE_ERR_PARAM; + + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); if (ret_val != IXGBE_SUCCESS) goto out; @@ -3581,6 +3684,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; break; @@ -3610,7 +3714,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) * @vmdq: VMDq pool to assign * * Puts an ethernet address into a receive address register, or - * finds the rar that it is already in; adds to the pool list + * finds the rar that it is aleady in; adds to the pool list **/ s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) { @@ -3719,7 +3823,8 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) } /* was that the last pool using this rar? */ - if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) + if (mpsar_lo == 0 && mpsar_hi == 0 && + rar != 0 && rar != hw->mac.san_mac_rar_index) hw->mac.ops.clear_rar(hw, rar); done: return IXGBE_SUCCESS; @@ -3809,68 +3914,65 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) * return the VLVF index where this VLAN id should be placed * **/ -s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) +s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass) { - u32 bits = 0; - u32 first_empty_slot = 0; - s32 regindex; + s32 regindex, first_empty_slot; + u32 bits; /* short cut the special case */ if (vlan == 0) return 0; - /* - * Search for the vlan id in the VLVF entries. Save off the first empty - * slot found along the way - */ - for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { + /* if vlvf_bypass is set we don't want to use an empty slot, we + * will simply bypass the VLVF if there are no entries present in the + * VLVF that contain our VLAN + */ + first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0; + + /* add VLAN enable bit for comparison */ + vlan |= IXGBE_VLVF_VIEN; + + /* Search for the vlan id in the VLVF entries. Save off the first empty + * slot found along the way. + * + * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1 + */ + for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) { bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); - if (!bits && !(first_empty_slot)) + if (bits == vlan) + return regindex; + if (!first_empty_slot && !bits) first_empty_slot = regindex; - else if ((bits & 0x0FFF) == vlan) - break; } - /* - * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan - * in the VLVF. Else use the first empty VLVF register for this - * vlan id. - */ - if (regindex >= IXGBE_VLVF_ENTRIES) { - if (first_empty_slot) - regindex = first_empty_slot; - else { - ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, - "No space in VLVF.\n"); - regindex = IXGBE_ERR_NO_SPACE; - } - } + /* If we are here then we didn't find the VLAN. Return first empty + * slot we found during our search, else error. + */ + if (!first_empty_slot) + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "No space in VLVF.\n"); - return regindex; + return first_empty_slot ? first_empty_slot : IXGBE_ERR_NO_SPACE; } /** * ixgbe_set_vfta_generic - Set VLAN filter table * @hw: pointer to hardware structure * @vlan: VLAN id to write to VLAN filter - * @vind: VMDq output index that maps queue to VLAN id in VFVFB - * @vlan_on: boolean flag to turn on/off VLAN in VFVF + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN + * @vlvf_bypass: boolean flag indicating updating default pool is okay * * Turn on/off specified VLAN in the VLAN filter table. **/ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, - bool vlan_on) + bool vlan_on, bool vlvf_bypass) { - s32 regindex; - u32 bitindex; - u32 vfta; - u32 targetbit; - s32 ret_val = IXGBE_SUCCESS; - bool vfta_changed = FALSE; + u32 regidx, vfta_delta, vfta; + s32 ret_val; DEBUGFUNC("ixgbe_set_vfta_generic"); - if (vlan > 4095) + if (vlan > 4095 || vind > 63) return IXGBE_ERR_PARAM; /* @@ -3885,33 +3987,33 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, * bits[11-5]: which register * bits[4-0]: which bit in the register */ - regindex = (vlan >> 5) & 0x7F; - bitindex = vlan & 0x1F; - targetbit = (1 << bitindex); - vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); + regidx = vlan / 32; + vfta_delta = 1 << (vlan % 32); + vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx)); - if (vlan_on) { - if (!(vfta & targetbit)) { - vfta |= targetbit; - vfta_changed = TRUE; - } - } else { - if ((vfta & targetbit)) { - vfta &= ~targetbit; - vfta_changed = TRUE; - } - } + /* + * vfta_delta represents the difference between the current value + * of vfta and the value we want in the register. Since the diff + * is an XOR mask we can just update the vfta using an XOR + */ + vfta_delta &= vlan_on ? ~vfta : vfta; + vfta ^= vfta_delta; /* Part 2 * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF */ - ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, - &vfta_changed); - if (ret_val != IXGBE_SUCCESS) + ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, &vfta_delta, + vfta, vlvf_bypass); + if (ret_val != IXGBE_SUCCESS) { + if (vlvf_bypass) + goto vfta_update; return ret_val; + } - if (vfta_changed) - IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); +vfta_update: + /* Update VFTA now that we are ready for traffic */ + if (vfta_delta) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta); return IXGBE_SUCCESS; } @@ -3920,21 +4022,25 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, * ixgbe_set_vlvf_generic - Set VLAN Pool Filter * @hw: pointer to hardware structure * @vlan: VLAN id to write to VLAN filter - * @vind: VMDq output index that maps queue to VLAN id in VFVFB - * @vlan_on: boolean flag to turn on/off VLAN in VFVF - * @vfta_changed: pointer to boolean flag which indicates whether VFTA - * should be changed + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN in VLVF + * @vfta_delta: pointer to the difference between the current value of VFTA + * and the desired value + * @vfta: the desired value of the VFTA + * @vlvf_bypass: boolean flag indicating updating default pool is okay * * Turn on/off specified bit in VLVF table. **/ s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, - bool vlan_on, bool *vfta_changed) + bool vlan_on, u32 *vfta_delta, u32 vfta, + bool vlvf_bypass) { - u32 vt; + u32 bits; + s32 vlvf_index; DEBUGFUNC("ixgbe_set_vlvf_generic"); - if (vlan > 4095) + if (vlan > 4095 || vind > 63) return IXGBE_ERR_PARAM; /* If VT Mode is set @@ -3944,83 +4050,60 @@ s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, * Or !vlan_on * clear the pool bit and possibly the vind */ - vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); - if (vt & IXGBE_VT_CTL_VT_ENABLE) { - s32 vlvf_index; - u32 bits; + if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE)) + return IXGBE_SUCCESS; - vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); - if (vlvf_index < 0) - return vlvf_index; + vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass); + if (vlvf_index < 0) + return vlvf_index; - if (vlan_on) { - /* set the pool bit */ - if (vind < 32) { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB(vlvf_index * 2)); - bits |= (1 << vind); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB(vlvf_index * 2), - bits); - } else { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB((vlvf_index * 2) + 1)); - bits |= (1 << (vind - 32)); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB((vlvf_index * 2) + 1), - bits); - } - } else { - /* clear the pool bit */ - if (vind < 32) { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB(vlvf_index * 2)); - bits &= ~(1 << vind); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB(vlvf_index * 2), - bits); - bits |= IXGBE_READ_REG(hw, - IXGBE_VLVFB((vlvf_index * 2) + 1)); - } else { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB((vlvf_index * 2) + 1)); - bits &= ~(1 << (vind - 32)); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB((vlvf_index * 2) + 1), - bits); - bits |= IXGBE_READ_REG(hw, - IXGBE_VLVFB(vlvf_index * 2)); - } - } + bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32)); - /* - * If there are still bits set in the VLVFB registers - * for the VLAN ID indicated we need to see if the - * caller is requesting that we clear the VFTA entry bit. - * If the caller has requested that we clear the VFTA - * entry bit but there are still pools/VFs using this VLAN - * ID entry then ignore the request. We're not worried - * about the case where we're turning the VFTA VLAN ID - * entry bit on, only when requested to turn it off as - * there may be multiple pools and/or VFs using the - * VLAN ID entry. In that case we cannot clear the - * VFTA bit until all pools/VFs using that VLAN ID have also - * been cleared. This will be indicated by "bits" being - * zero. + /* set the pool bit */ + bits |= 1 << (vind % 32); + if (vlan_on) + goto vlvf_update; + + /* clear the pool bit */ + bits ^= 1 << (vind % 32); + + if (!bits && + !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) { + /* Clear VFTA first, then disable VLVF. Otherwise + * we run the risk of stray packets leaking into + * the PF via the default pool */ - if (bits) { - IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), - (IXGBE_VLVF_VIEN | vlan)); - if ((!vlan_on) && (vfta_changed != NULL)) { - /* someone wants to clear the vfta entry - * but some pools/VFs are still using it. - * Ignore it. */ - *vfta_changed = FALSE; - } - } else - IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); + if (*vfta_delta) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(vlan / 32), vfta); + + /* disable VLVF and clear remaining bit from pool */ + IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0); + + return IXGBE_SUCCESS; } + /* If there are still bits set in the VLVFB registers + * for the VLAN ID indicated we need to see if the + * caller is requesting that we clear the VFTA entry bit. + * If the caller has requested that we clear the VFTA + * entry bit but there are still pools/VFs using this VLAN + * ID entry then ignore the request. We're not worried + * about the case where we're turning the VFTA VLAN ID + * entry bit on, only when requested to turn it off as + * there may be multiple pools and/or VFs using the + * VLAN ID entry. In that case we cannot clear the + * VFTA bit until all pools/VFs using that VLAN ID have also + * been cleared. This will be indicated by "bits" being + * zero. + */ + *vfta_delta = 0; + +vlvf_update: + /* record pool change and enable VLAN ID if not already enabled */ + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits); + IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan); + return IXGBE_SUCCESS; } @@ -4042,12 +4125,38 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0); - IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0); } return IXGBE_SUCCESS; } +/** + * ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix + * @hw: pointer to hardware structure + * + * Contains the logic to identify if we need to verify link for the + * crosstalk fix + **/ +static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw) +{ + + /* Does FW say we need the fix */ + if (!hw->need_crosstalk_fix) + return FALSE; + + /* Only consider SFP+ PHYs i.e. media type fiber */ + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + case ixgbe_media_type_fiber_qsfp: + break; + default: + return FALSE; + } + + return TRUE; +} + /** * ixgbe_check_mac_link_generic - Determine link and speed status * @hw: pointer to hardware structure @@ -4065,6 +4174,35 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, DEBUGFUNC("ixgbe_check_mac_link_generic"); + /* If Crosstalk fix enabled do the sanity check of making sure + * the SFP+ cage is full. + */ + if (ixgbe_need_crosstalk_fix(hw)) { + u32 sfp_cage_full; + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP2; + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP0; + break; + default: + /* sanity check - No SFP+ devices here */ + sfp_cage_full = FALSE; + break; + } + + if (!sfp_cage_full) { + *link_up = FALSE; + *speed = IXGBE_LINK_SPEED_UNKNOWN; + return IXGBE_SUCCESS; + } + } + /* clear the old state */ links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); @@ -4106,11 +4244,18 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, break; case IXGBE_LINKS_SPEED_100_82599: *speed = IXGBE_LINK_SPEED_100_FULL; - if (hw->mac.type >= ixgbe_mac_X550) { + if (hw->mac.type == ixgbe_mac_X550) { if (links_reg & IXGBE_LINKS_SPEED_NON_STD) *speed = IXGBE_LINK_SPEED_5GB_FULL; } break; + case IXGBE_LINKS_SPEED_10_X550EM_A: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || + hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) { + *speed = IXGBE_LINK_SPEED_10_FULL; + } + break; default: *speed = IXGBE_LINK_SPEED_UNKNOWN; } @@ -4228,43 +4373,25 @@ s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs) /** * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing * @hw: pointer to hardware structure - * @enable: enable or disable switch for anti-spoofing - * @pf: Physical Function pool - do not enable anti-spoofing for the PF + * @enable: enable or disable switch for MAC anti-spoofing + * @vf: Virtual Function pool - VF Pool to set for MAC anti-spoofing * **/ -void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf) +void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) { - int j; - int pf_target_reg = pf >> 3; - int pf_target_shift = pf % 8; - u32 pfvfspoof = 0; + int vf_target_reg = vf >> 3; + int vf_target_shift = vf % 8; + u32 pfvfspoof; if (hw->mac.type == ixgbe_mac_82598EB) return; + pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); if (enable) - pfvfspoof = IXGBE_SPOOF_MACAS_MASK; - - /* - * PFVFSPOOF register array is size 8 with 8 bits assigned to - * MAC anti-spoof enables in each register array element. - */ - for (j = 0; j < pf_target_reg; j++) - IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); - - /* - * The PF should be allowed to spoof so that it can support - * emulation mode NICs. Do not set the bits assigned to the PF - */ - pfvfspoof &= (1 << pf_target_shift) - 1; - IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); - - /* - * Remaining pools belong to the PF so they do not need to have - * anti-spoofing enabled. - */ - for (j++; j < IXGBE_PFVFSPOOF_REG_COUNT; j++) - IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), 0); + pfvfspoof |= (1 << vf_target_shift); + else + pfvfspoof &= ~(1 << vf_target_shift); + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); } /** @@ -4360,49 +4487,45 @@ u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) } /** - * ixgbe_host_interface_command - Issue command to manageability block + * ixgbe_hic_unlocked - Issue command to manageability block unlocked * @hw: pointer to the HW structure - * @buffer: contains the command to write and where the return status will - * be placed + * @buffer: command to write and where the return status will be placed * @length: length of buffer, must be multiple of 4 bytes * @timeout: time in ms to wait for command completion - * @return_data: read and return data from the buffer (TRUE) or not (FALSE) - * Needed because FW structures are big endian and decoding of - * these fields can be 8 bit or 16 bit based on command. Decoding - * is not easily understood without making a table of commands. - * So we will leave this up to the caller to read back the data - * in these cases. * - * Communicates with the manageability block. On success return IXGBE_SUCCESS - * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. + * Communicates with the manageability block. On success return IXGBE_SUCCESS + * else returns semaphore error when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * + * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held + * by the caller. **/ -s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, - u32 length, u32 timeout, bool return_data) +s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, + u32 timeout) { - u32 hicr, i, bi, fwsts; - u32 hdr_size = sizeof(struct ixgbe_hic_hdr); - u16 buf_len; + u32 hicr, i, fwsts; u16 dword_len; - DEBUGFUNC("ixgbe_host_interface_command"); + DEBUGFUNC("ixgbe_hic_unlocked"); - if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); return IXGBE_ERR_HOST_INTERFACE_COMMAND; } + /* Set bit 9 of FWSTS clearing FW reset indication */ fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS); IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI); /* Check that the host interface is enabled. */ hicr = IXGBE_READ_REG(hw, IXGBE_HICR); - if ((hicr & IXGBE_HICR_EN) == 0) { + if (!(hicr & IXGBE_HICR_EN)) { DEBUGOUT("IXGBE_HOST_EN bit disabled.\n"); return IXGBE_ERR_HOST_INTERFACE_COMMAND; } /* Calculate length in DWORDs. We must be DWORD aligned */ - if ((length % (sizeof(u32))) != 0) { + if (length % sizeof(u32)) { DEBUGOUT("Buffer length failure, not aligned to dword"); return IXGBE_ERR_INVALID_ARGUMENT; } @@ -4427,15 +4550,61 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, } /* Check command completion */ - if ((timeout != 0 && i == timeout) || + if ((timeout && i == timeout) || !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { ERROR_REPORT1(IXGBE_ERROR_CAUTION, "Command has failed with no status valid.\n"); return IXGBE_ERR_HOST_INTERFACE_COMMAND; } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_host_interface_command - Issue command to manageability block + * @hw: pointer to the HW structure + * @buffer: contains the command to write and where the return status will + * be placed + * @length: length of buffer, must be multiple of 4 bytes + * @timeout: time in ms to wait for command completion + * @return_data: read and return data from the buffer (TRUE) or not (FALSE) + * Needed because FW structures are big endian and decoding of + * these fields can be 8 bit or 16 bit based on command. Decoding + * is not easily understood without making a table of commands. + * So we will leave this up to the caller to read back the data + * in these cases. + * + * Communicates with the manageability block. On success return IXGBE_SUCCESS + * else returns semaphore error when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ +s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, + u32 length, u32 timeout, bool return_data) +{ + u32 hdr_size = sizeof(struct ixgbe_hic_hdr); + u16 dword_len; + u16 buf_len; + s32 status; + u32 bi; + + DEBUGFUNC("ixgbe_host_interface_command"); + + if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); + return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } + + /* Take management host interface semaphore */ + status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); + if (status) + return status; + + status = ixgbe_hic_unlocked(hw, buffer, length, timeout); + if (status) + goto rel_out; + if (!return_data) - return 0; + goto rel_out; /* Calculate length in DWORDs */ dword_len = hdr_size >> 2; @@ -4448,12 +4617,13 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, /* If there is any thing in data position pull it in */ buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; - if (buf_len == 0) - return 0; + if (!buf_len) + goto rel_out; if (length < buf_len + hdr_size) { DEBUGOUT("Buffer not large enough for reply message.\n"); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + status = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto rel_out; } /* Calculate length in DWORDs, add 3 for odd lengths */ @@ -4465,7 +4635,10 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, IXGBE_LE32_TO_CPUS(&buffer[bi]); } - return 0; +rel_out: + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); + + return status; } /** @@ -4482,19 +4655,15 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. **/ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, - u8 build, u8 sub) + u8 build, u8 sub, u16 len, + const char *driver_ver) { struct ixgbe_hic_drv_info fw_cmd; int i; s32 ret_val = IXGBE_SUCCESS; DEBUGFUNC("ixgbe_set_fw_drv_ver_generic"); - - if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM) - != IXGBE_SUCCESS) { - ret_val = IXGBE_ERR_SWFW_SYNC; - goto out; - } + UNREFERENCED_2PARAMETER(len, driver_ver); fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; @@ -4527,8 +4696,6 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, break; } - hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); -out: return ret_val; } @@ -4565,7 +4732,7 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom, rxpktsize <<= IXGBE_RXPBSIZE_SHIFT; for (; i < (num_pb / 2); i++) IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); - /* Fall through to configure remaining packet buffers */ + /* fall through - configure remaining packet buffers */ case PBA_STRATEGY_EQUAL: rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT; for (; i < num_pb; i++) @@ -4652,6 +4819,253 @@ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); } +/** + * ixgbe_bypass_rw_generic - Bit bang data into by_pass FW + * + * @hw: pointer to hardware structure + * @cmd: Command we send to the FW + * @status: The reply from the FW + * + * Bit-bangs the cmd to the by_pass FW status points to what is returned. + **/ +#define IXGBE_BYPASS_BB_WAIT 1 +s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status) +{ + int i; + u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo; + u32 esdp; + + if (!status) + return IXGBE_ERR_PARAM; + + *status = 0; + + /* SDP vary by MAC type */ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + sck = IXGBE_ESDP_SDP7; + sdi = IXGBE_ESDP_SDP0; + sdo = IXGBE_ESDP_SDP6; + dir_sck = IXGBE_ESDP_SDP7_DIR; + dir_sdi = IXGBE_ESDP_SDP0_DIR; + dir_sdo = IXGBE_ESDP_SDP6_DIR; + break; + case ixgbe_mac_X540: + sck = IXGBE_ESDP_SDP2; + sdi = IXGBE_ESDP_SDP0; + sdo = IXGBE_ESDP_SDP1; + dir_sck = IXGBE_ESDP_SDP2_DIR; + dir_sdi = IXGBE_ESDP_SDP0_DIR; + dir_sdo = IXGBE_ESDP_SDP1_DIR; + break; + default: + return IXGBE_ERR_DEVICE_NOT_SUPPORTED; + } + + /* Set SDP pins direction */ + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + esdp |= dir_sck; /* SCK as output */ + esdp |= dir_sdi; /* SDI as output */ + esdp &= ~dir_sdo; /* SDO as input */ + esdp |= sck; + esdp |= sdi; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + msec_delay(IXGBE_BYPASS_BB_WAIT); + + /* Generate start condition */ + esdp &= ~sdi; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + msec_delay(IXGBE_BYPASS_BB_WAIT); + + esdp &= ~sck; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + msec_delay(IXGBE_BYPASS_BB_WAIT); + + /* Clock out the new control word and clock in the status */ + for (i = 0; i < 32; i++) { + if ((cmd >> (31 - i)) & 0x01) { + esdp |= sdi; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + } else { + esdp &= ~sdi; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + } + IXGBE_WRITE_FLUSH(hw); + msec_delay(IXGBE_BYPASS_BB_WAIT); + + esdp |= sck; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + msec_delay(IXGBE_BYPASS_BB_WAIT); + + esdp &= ~sck; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + msec_delay(IXGBE_BYPASS_BB_WAIT); + + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + if (esdp & sdo) + *status = (*status << 1) | 0x01; + else + *status = (*status << 1) | 0x00; + msec_delay(IXGBE_BYPASS_BB_WAIT); + } + + /* stop condition */ + esdp |= sck; + esdp &= ~sdi; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + msec_delay(IXGBE_BYPASS_BB_WAIT); + + esdp |= sdi; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + + /* set the page bits to match the cmd that the status it belongs to */ + *status = (*status & 0x3fffffff) | (cmd & 0xc0000000); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang. + * + * If we send a write we can't be sure it took until we can read back + * that same register. It can be a problem as some of the feilds may + * for valid reasons change inbetween the time wrote the register and + * we read it again to verify. So this function check everything we + * can check and then assumes it worked. + * + * @u32 in_reg - The register cmd for the bit-bang read. + * @u32 out_reg - The register returned from a bit-bang read. + **/ +bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg) +{ + u32 mask; + + /* Page must match for all control pages */ + if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M)) + return FALSE; + + switch (in_reg & BYPASS_PAGE_M) { + case BYPASS_PAGE_CTL0: + /* All the following can't change since the last write + * - All the event actions + * - The timeout value + */ + mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M | + BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M | + BYPASS_WDTIMEOUT_M | + BYPASS_WDT_VALUE_M; + if ((out_reg & mask) != (in_reg & mask)) + return FALSE; + + /* 0x0 is never a valid value for bypass status */ + if (!(out_reg & BYPASS_STATUS_OFF_M)) + return FALSE; + break; + case BYPASS_PAGE_CTL1: + /* All the following can't change since the last write + * - time valid bit + * - time we last sent + */ + mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M; + if ((out_reg & mask) != (in_reg & mask)) + return FALSE; + break; + case BYPASS_PAGE_CTL2: + /* All we can check in this page is control number + * which is already done above. + */ + break; + } + + /* We are as sure as we can be return TRUE */ + return TRUE; +} + +/** + * ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Regiter. + * + * @hw: pointer to hardware structure + * @cmd: The control word we are setting. + * @event: The event we are setting in the FW. This also happens to + * be the mask for the event we are setting (handy) + * @action: The action we set the event to in the FW. This is in a + * bit field that happens to be what we want to put in + * the event spot (also handy) + **/ +s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event, + u32 action) +{ + u32 by_ctl = 0; + u32 cmd, verify; + u32 count = 0; + + /* Get current values */ + cmd = ctrl; /* just reading only need control number */ + if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl)) + return IXGBE_ERR_INVALID_ARGUMENT; + + /* Set to new action */ + cmd = (by_ctl & ~event) | BYPASS_WE | action; + if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl)) + return IXGBE_ERR_INVALID_ARGUMENT; + + /* Page 0 force a FW eeprom write which is slow so verify */ + if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) { + verify = BYPASS_PAGE_CTL0; + do { + if (count++ > 5) + return IXGBE_BYPASS_FW_WRITE_FAILURE; + + if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl)) + return IXGBE_ERR_INVALID_ARGUMENT; + } while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl)); + } else { + /* We have give the FW time for the write to stick */ + msec_delay(100); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom addres. + * + * @hw: pointer to hardware structure + * @addr: The bypass eeprom address to read. + * @value: The 8b of data at the address above. + **/ +s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value) +{ + u32 cmd; + u32 status; + + + /* send the request */ + cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; + cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; + if (ixgbe_bypass_rw_generic(hw, cmd, &status)) + return IXGBE_ERR_INVALID_ARGUMENT; + + /* We have give the FW time for the write to stick */ + msec_delay(100); + + /* now read the results */ + cmd &= ~BYPASS_WE; + if (ixgbe_bypass_rw_generic(hw, cmd, &status)) + return IXGBE_ERR_INVALID_ARGUMENT; + + *value = status & BYPASS_CTL2_DATA_M; + + return IXGBE_SUCCESS; +} + /** * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg @@ -4789,14 +5203,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, speedcnt++; highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; - /* If we already have link at this speed, just jump out */ - status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); - if (status != IXGBE_SUCCESS) - return status; - - if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up) - goto out; - /* Set the module link speed */ switch (hw->phy.media_type) { case ixgbe_media_type_fiber_fixed: @@ -4848,14 +5254,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; - /* If we already have link at this speed, just jump out */ - status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); - if (status != IXGBE_SUCCESS) - return status; - - if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up) - goto out; - /* Set the module link speed */ switch (hw->phy.media_type) { case ixgbe_media_type_fiber_fixed: diff --git a/sys/dev/ixgbe/ixgbe_common.h b/sys/dev/ixgbe/ixgbe_common.h index e685f5b32a39..f508410ed180 100644 --- a/sys/dev/ixgbe/ixgbe_common.h +++ b/sys/dev/ixgbe/ixgbe_common.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -75,6 +75,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw); s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw); s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw); s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data); @@ -136,11 +137,12 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw); s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, - u32 vind, bool vlan_on); + u32 vind, bool vlan_on, bool vlvf_bypass); s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, - bool vlan_on, bool *vfta_changed); + bool vlan_on, u32 *vfta_delta, u32 vfta, + bool vlvf_bypass); s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); -s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan); +s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass); s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, @@ -150,19 +152,27 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, u16 *wwpn_prefix); s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs); -void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf); +void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom, int strategy); void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw); s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, - u8 build, u8 ver); + u8 build, u8 ver, u16 len, const char *str); u8 ixgbe_calculate_checksum(u8 *buffer, u32 length); s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, u32 length, u32 timeout, bool return_data); - +s32 ixgbe_hic_unlocked(struct ixgbe_hw *, u32 *buffer, u32 length, u32 timeout); +s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *); +s32 ixgbe_fw_phy_activity(struct ixgbe_hw *, u16 activity, + u32 (*data)[FW_PHY_ACT_DATA_COUNT]); void ixgbe_clear_tx_pending(struct ixgbe_hw *hw); +s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status); +bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg); +s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event, + u32 action); +s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value); extern s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw); extern void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw); diff --git a/sys/dev/ixgbe/ixgbe_dcb.c b/sys/dev/ixgbe/ixgbe_dcb.c index 437d3365e914..8aef8501958b 100644 --- a/sys/dev/ixgbe/ixgbe_dcb.c +++ b/sys/dev/ixgbe/ixgbe_dcb.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -401,6 +401,7 @@ s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); break; @@ -431,6 +432,7 @@ s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); break; @@ -472,6 +474,7 @@ s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid, tsa, map); @@ -513,6 +516,7 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwgid, tsa); @@ -556,6 +560,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwgid, tsa, @@ -593,6 +598,7 @@ s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); break; @@ -621,6 +627,7 @@ s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL); break; @@ -668,6 +675,7 @@ s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ixgbe_dcb_config_82599(hw, dcb_config); ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed, @@ -702,6 +710,7 @@ s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map) case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); break; @@ -727,6 +736,7 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max, case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, tsa, map); diff --git a/sys/dev/ixgbe/ixgbe_dcb.h b/sys/dev/ixgbe/ixgbe_dcb.h index 871b7842e30c..86010d4417a5 100644 --- a/sys/dev/ixgbe/ixgbe_dcb.h +++ b/sys/dev/ixgbe/ixgbe_dcb.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sys/dev/ixgbe/ixgbe_dcb_82598.c b/sys/dev/ixgbe/ixgbe_dcb_82598.c index fb946c94097c..f0642e4abf07 100644 --- a/sys/dev/ixgbe/ixgbe_dcb_82598.c +++ b/sys/dev/ixgbe/ixgbe_dcb_82598.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sys/dev/ixgbe/ixgbe_dcb_82598.h b/sys/dev/ixgbe/ixgbe_dcb_82598.h index 35974f709e02..ea8d825e516e 100644 --- a/sys/dev/ixgbe/ixgbe_dcb_82598.h +++ b/sys/dev/ixgbe/ixgbe_dcb_82598.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sys/dev/ixgbe/ixgbe_dcb_82599.c b/sys/dev/ixgbe/ixgbe_dcb_82599.c index 4443411f4be3..4c328aeab8eb 100644 --- a/sys/dev/ixgbe/ixgbe_dcb_82599.c +++ b/sys/dev/ixgbe/ixgbe_dcb_82599.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sys/dev/ixgbe/ixgbe_dcb_82599.h b/sys/dev/ixgbe/ixgbe_dcb_82599.h index bab7628ecf43..a8dfa0980c74 100644 --- a/sys/dev/ixgbe/ixgbe_dcb_82599.h +++ b/sys/dev/ixgbe/ixgbe_dcb_82599.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sys/dev/ixgbe/ixgbe_fdir.h b/sys/dev/ixgbe/ixgbe_fdir.h new file mode 100644 index 000000000000..1b106eef6d17 --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_fdir.h @@ -0,0 +1,58 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#ifndef _IXGBE_FDIR_H_ +#define _IXGBE_FDIR_H_ + +#ifdef IXGBE_FDIR + +/* + * Flow Director actually 'steals' part of the packet buffer + * as its filter pool, this variable controls how much it uses: + * 0 = 64K, 1 = 128K, 2 = 256K + */ +int fdir_pballoc = 1; + +void ixgbe_init_fdir(struct adapter *); + +#else + +#define ixgbe_init_fdir(_a) + +#endif + +void ixgbe_reinit_fdir(void *, int); +void ixgbe_atr(struct tx_ring *, struct mbuf *); + +#endif /* _IXGBE_FDIR_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_features.h b/sys/dev/ixgbe/ixgbe_features.h new file mode 100644 index 000000000000..bb05885497dd --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_features.h @@ -0,0 +1,77 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + + +#ifndef _IXGBE_FEATURES_H_ +#define _IXGBE_FEATURES_H_ + +/* + * Feature defines. Eventually, we'd like to get to a point where we + * can remove MAC/Phy type checks scattered throughout the code in + * favor of checking these feature flags. If the feature expects OS + * support, make sure to add an #undef below if expected to run on + * OSs that don't support said feature. + */ +#define IXGBE_FEATURE_VF (u32)(1 << 0) +#define IXGBE_FEATURE_SRIOV (u32)(1 << 1) +#define IXGBE_FEATURE_RSS (u32)(1 << 2) +#define IXGBE_FEATURE_NETMAP (u32)(1 << 3) +#define IXGBE_FEATURE_FAN_FAIL (u32)(1 << 4) +#define IXGBE_FEATURE_TEMP_SENSOR (u32)(1 << 5) +#define IXGBE_FEATURE_BYPASS (u32)(1 << 6) +#define IXGBE_FEATURE_LEGACY_TX (u32)(1 << 7) +#define IXGBE_FEATURE_FDIR (u32)(1 << 8) +#define IXGBE_FEATURE_MSI (u32)(1 << 9) +#define IXGBE_FEATURE_MSIX (u32)(1 << 10) +#define IXGBE_FEATURE_EEE (u32)(1 << 11) +#define IXGBE_FEATURE_LEGACY_IRQ (u32)(1 << 12) +#define IXGBE_FEATURE_NEEDS_CTXD (u32)(1 << 13) + +/* Check for OS support. Undefine features if not included in the OS */ +#ifndef PCI_IOV +#undef IXGBE_FEATURE_SRIOV +#define IXGBE_FEATURE_SRIOV 0 +#endif + +#ifndef RSS +#undef IXGBE_FEATURE_RSS +#define IXGBE_FEATURE_RSS 0 +#endif + +#ifndef DEV_NETMAP +#undef IXGBE_FEATURE_NETMAP +#define IXGBE_FEATURE_NETMAP 0 +#endif + +#endif /* _IXGBE_FEATURES_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_mbx.c b/sys/dev/ixgbe/ixgbe_mbx.c index 3e9b78ac86d3..071ccba9d5be 100644 --- a/sys/dev/ixgbe/ixgbe_mbx.c +++ b/sys/dev/ixgbe/ixgbe_mbx.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -35,118 +35,6 @@ #include "ixgbe_type.h" #include "ixgbe_mbx.h" -/** - * ixgbe_read_mbx - Reads a message from the mailbox - * @hw: pointer to the HW structure - * @msg: The message buffer - * @size: Length of buffer - * @mbx_id: id of mailbox to read - * - * returns SUCCESS if it successfully read message from buffer - **/ -s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_MBX; - - DEBUGFUNC("ixgbe_read_mbx"); - - /* limit read to size of mailbox */ - if (size > mbx->size) - size = mbx->size; - - if (mbx->ops.read) - ret_val = mbx->ops.read(hw, msg, size, mbx_id); - - return ret_val; -} - -/** - * ixgbe_write_mbx - Write a message to the mailbox - * @hw: pointer to the HW structure - * @msg: The message buffer - * @size: Length of buffer - * @mbx_id: id of mailbox to write - * - * returns SUCCESS if it successfully copied message into the buffer - **/ -s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_SUCCESS; - - DEBUGFUNC("ixgbe_write_mbx"); - - if (size > mbx->size) { - ret_val = IXGBE_ERR_MBX; - ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, - "Invalid mailbox message size %d", size); - } else if (mbx->ops.write) - ret_val = mbx->ops.write(hw, msg, size, mbx_id); - - return ret_val; -} - -/** - * ixgbe_check_for_msg - checks to see if someone sent us mail - * @hw: pointer to the HW structure - * @mbx_id: id of mailbox to check - * - * returns SUCCESS if the Status bit was found or else ERR_MBX - **/ -s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_MBX; - - DEBUGFUNC("ixgbe_check_for_msg"); - - if (mbx->ops.check_for_msg) - ret_val = mbx->ops.check_for_msg(hw, mbx_id); - - return ret_val; -} - -/** - * ixgbe_check_for_ack - checks to see if someone sent us ACK - * @hw: pointer to the HW structure - * @mbx_id: id of mailbox to check - * - * returns SUCCESS if the Status bit was found or else ERR_MBX - **/ -s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_MBX; - - DEBUGFUNC("ixgbe_check_for_ack"); - - if (mbx->ops.check_for_ack) - ret_val = mbx->ops.check_for_ack(hw, mbx_id); - - return ret_val; -} - -/** - * ixgbe_check_for_rst - checks to see if other side has reset - * @hw: pointer to the HW structure - * @mbx_id: id of mailbox to check - * - * returns SUCCESS if the Status bit was found or else ERR_MBX - **/ -s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_MBX; - - DEBUGFUNC("ixgbe_check_for_rst"); - - if (mbx->ops.check_for_rst) - ret_val = mbx->ops.check_for_rst(hw, mbx_id); - - return ret_val; -} - /** * ixgbe_poll_for_msg - Wait for message notification * @hw: pointer to the HW structure @@ -221,7 +109,8 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) * returns SUCCESS if it successfully received a message notification and * copied it into the receive buffer. **/ -s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) +static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; s32 ret_val = IXGBE_ERR_MBX; @@ -250,8 +139,8 @@ s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) * returns SUCCESS if it successfully copied message into the buffer and * received an ack to that message within delay * timeout period **/ -s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 mbx_id) +static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; s32 ret_val = IXGBE_ERR_MBX; @@ -607,6 +496,7 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) break; case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: case ixgbe_mac_X540: vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); break; @@ -744,6 +634,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) if (hw->mac.type != ixgbe_mac_82599EB && hw->mac.type != ixgbe_mac_X550 && hw->mac.type != ixgbe_mac_X550EM_x && + hw->mac.type != ixgbe_mac_X550EM_a && hw->mac.type != ixgbe_mac_X540) return; diff --git a/sys/dev/ixgbe/ixgbe_mbx.h b/sys/dev/ixgbe/ixgbe_mbx.h index a4a78eb6ede2..9ea1685f3c49 100644 --- a/sys/dev/ixgbe/ixgbe_mbx.h +++ b/sys/dev/ixgbe/ixgbe_mbx.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -90,6 +90,8 @@ enum ixgbe_pfvf_api_rev { ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ + ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */ + ixgbe_mbox_api_13, /* API version 1.3, linux/freebsd VF driver */ /* This value should always be last */ ixgbe_mbox_api_unknown, /* indicates that API version is not known */ }; @@ -108,6 +110,19 @@ enum ixgbe_pfvf_api_rev { /* mailbox API, version 1.1 VF requests */ #define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */ +/* mailbox API, version 1.2 VF requests */ +#define IXGBE_VF_GET_RETA 0x0a /* VF request for RETA */ +#define IXGBE_VF_GET_RSS_KEY 0x0b /* get RSS key */ +#define IXGBE_VF_UPDATE_XCAST_MODE 0x0c + +/* mode choices for IXGBE_VF_UPDATE_XCAST_MODE */ +enum ixgbevf_xcast_modes { + IXGBEVF_XCAST_MODE_NONE = 0, + IXGBEVF_XCAST_MODE_MULTI, + IXGBEVF_XCAST_MODE_ALLMULTI, + IXGBEVF_XCAST_MODE_PROMISC, +}; + /* GET_QUEUES return data indices within the mailbox */ #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */ #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */ @@ -137,13 +152,6 @@ enum ixgbe_pfvf_api_rev { #define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */ #define IXGBE_VF_MBX_INIT_DELAY 500 /* microseconds between retries */ -s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16); -s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16); -s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw); void ixgbe_init_mbx_params_vf(struct ixgbe_hw *); void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); diff --git a/sys/dev/ixgbe/ixgbe_netmap.c b/sys/dev/ixgbe/ixgbe_netmap.c new file mode 100644 index 000000000000..fd37ba8f7fb1 --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_netmap.c @@ -0,0 +1,521 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +/* + * Copyright (C) 2011-2014 Matteo Landi, Luigi Rizzo. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $FreeBSD$ + * + * netmap support for: ixgbe + * + * This file is meant to be a reference on how to implement + * netmap support for a network driver. + * This file contains code but only static or inline functions used + * by a single driver. To avoid replication of code we just #include + * it near the beginning of the standard driver. + */ + +#ifdef DEV_NETMAP +/* + * Some drivers may need the following headers. Others + * already include them by default + +#include +#include + + */ +#include "ixgbe.h" + +/* + * device-specific sysctl variables: + * + * ix_crcstrip: 0: keep CRC in rx frames (default), 1: strip it. + * During regular operations the CRC is stripped, but on some + * hardware reception of frames not multiple of 64 is slower, + * so using crcstrip=0 helps in benchmarks. + * + * ix_rx_miss, ix_rx_miss_bufs: + * count packets that might be missed due to lost interrupts. + */ +SYSCTL_DECL(_dev_netmap); +static int ix_rx_miss, ix_rx_miss_bufs; +int ix_crcstrip; +SYSCTL_INT(_dev_netmap, OID_AUTO, ix_crcstrip, + CTLFLAG_RW, &ix_crcstrip, 0, "strip CRC on rx frames"); +SYSCTL_INT(_dev_netmap, OID_AUTO, ix_rx_miss, + CTLFLAG_RW, &ix_rx_miss, 0, "potentially missed rx intr"); +SYSCTL_INT(_dev_netmap, OID_AUTO, ix_rx_miss_bufs, + CTLFLAG_RW, &ix_rx_miss_bufs, 0, "potentially missed rx intr bufs"); + + +static void +set_crcstrip(struct ixgbe_hw *hw, int onoff) +{ + /* crc stripping is set in two places: + * IXGBE_HLREG0 (modified on init_locked and hw reset) + * IXGBE_RDRXCTL (set by the original driver in + * ixgbe_setup_hw_rsc() called in init_locked. + * We disable the setting when netmap is compiled in). + * We update the values here, but also in ixgbe.c because + * init_locked sometimes is called outside our control. + */ + uint32_t hl, rxc; + + hl = IXGBE_READ_REG(hw, IXGBE_HLREG0); + rxc = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + if (netmap_verbose) + D("%s read HLREG 0x%x rxc 0x%x", + onoff ? "enter" : "exit", hl, rxc); + /* hw requirements ... */ + rxc &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; + rxc |= IXGBE_RDRXCTL_RSCACKC; + if (onoff && !ix_crcstrip) { + /* keep the crc. Fast rx */ + hl &= ~IXGBE_HLREG0_RXCRCSTRP; + rxc &= ~IXGBE_RDRXCTL_CRCSTRIP; + } else { + /* reset default mode */ + hl |= IXGBE_HLREG0_RXCRCSTRP; + rxc |= IXGBE_RDRXCTL_CRCSTRIP; + } + if (netmap_verbose) + D("%s write HLREG 0x%x rxc 0x%x", + onoff ? "enter" : "exit", hl, rxc); + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hl); + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rxc); +} + + +/* + * Register/unregister. We are already under netmap lock. + * Only called on the first register or the last unregister. + */ +static int +ixgbe_netmap_reg(struct netmap_adapter *na, int onoff) +{ + struct ifnet *ifp = na->ifp; + struct adapter *adapter = ifp->if_softc; + + IXGBE_CORE_LOCK(adapter); + adapter->stop_locked(adapter); + + set_crcstrip(&adapter->hw, onoff); + /* enable or disable flags and callbacks in na and ifp */ + if (onoff) { + nm_set_native_flags(na); + } else { + nm_clear_native_flags(na); + } + adapter->init_locked(adapter); /* also enables intr */ + set_crcstrip(&adapter->hw, onoff); // XXX why twice ? + IXGBE_CORE_UNLOCK(adapter); + return (ifp->if_drv_flags & IFF_DRV_RUNNING ? 0 : 1); +} + + +/* + * Reconcile kernel and user view of the transmit ring. + * + * All information is in the kring. + * Userspace wants to send packets up to the one before kring->rhead, + * kernel knows kring->nr_hwcur is the first unsent packet. + * + * Here we push packets out (as many as possible), and possibly + * reclaim buffers from previously completed transmission. + * + * The caller (netmap) guarantees that there is only one instance + * running at any time. Any interference with other driver + * methods should be handled by the individual drivers. + */ +static int +ixgbe_netmap_txsync(struct netmap_kring *kring, int flags) +{ + struct netmap_adapter *na = kring->na; + struct ifnet *ifp = na->ifp; + struct netmap_ring *ring = kring->ring; + u_int nm_i; /* index into the netmap ring */ + u_int nic_i; /* index into the NIC ring */ + u_int n; + u_int const lim = kring->nkr_num_slots - 1; + u_int const head = kring->rhead; + /* + * interrupts on every tx packet are expensive so request + * them every half ring, or where NS_REPORT is set + */ + u_int report_frequency = kring->nkr_num_slots >> 1; + + /* device-specific */ + struct adapter *adapter = ifp->if_softc; + struct tx_ring *txr = &adapter->tx_rings[kring->ring_id]; + int reclaim_tx; + + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, + BUS_DMASYNC_POSTREAD); + + /* + * First part: process new packets to send. + * nm_i is the current index in the netmap ring, + * nic_i is the corresponding index in the NIC ring. + * The two numbers differ because upon a *_init() we reset + * the NIC ring but leave the netmap ring unchanged. + * For the transmit ring, we have + * + * nm_i = kring->nr_hwcur + * nic_i = IXGBE_TDT (not tracked in the driver) + * and + * nm_i == (nic_i + kring->nkr_hwofs) % ring_size + * + * In this driver kring->nkr_hwofs >= 0, but for other + * drivers it might be negative as well. + */ + + /* + * If we have packets to send (kring->nr_hwcur != kring->rhead) + * iterate over the netmap ring, fetch length and update + * the corresponding slot in the NIC ring. Some drivers also + * need to update the buffer's physical address in the NIC slot + * even NS_BUF_CHANGED is not set (PNMB computes the addresses). + * + * The netmap_reload_map() calls is especially expensive, + * even when (as in this case) the tag is 0, so do only + * when the buffer has actually changed. + * + * If possible do not set the report/intr bit on all slots, + * but only a few times per ring or when NS_REPORT is set. + * + * Finally, on 10G and faster drivers, it might be useful + * to prefetch the next slot and txr entry. + */ + + nm_i = kring->nr_hwcur; + if (nm_i != head) { /* we have new packets to send */ + nic_i = netmap_idx_k2n(kring, nm_i); + + __builtin_prefetch(&ring->slot[nm_i]); + __builtin_prefetch(&txr->tx_buffers[nic_i]); + + for (n = 0; nm_i != head; n++) { + struct netmap_slot *slot = &ring->slot[nm_i]; + u_int len = slot->len; + uint64_t paddr; + void *addr = PNMB(na, slot, &paddr); + + /* device-specific */ + union ixgbe_adv_tx_desc *curr = &txr->tx_base[nic_i]; + struct ixgbe_tx_buf *txbuf = &txr->tx_buffers[nic_i]; + int flags = (slot->flags & NS_REPORT || + nic_i == 0 || nic_i == report_frequency) ? + IXGBE_TXD_CMD_RS : 0; + + /* prefetch for next round */ + __builtin_prefetch(&ring->slot[nm_i + 1]); + __builtin_prefetch(&txr->tx_buffers[nic_i + 1]); + + NM_CHECK_ADDR_LEN(na, addr, len); + + if (slot->flags & NS_BUF_CHANGED) { + /* buffer has changed, reload map */ + netmap_reload_map(na, txr->txtag, txbuf->map, addr); + } + slot->flags &= ~(NS_REPORT | NS_BUF_CHANGED); + + /* Fill the slot in the NIC ring. */ + /* Use legacy descriptor, they are faster? */ + curr->read.buffer_addr = htole64(paddr); + curr->read.olinfo_status = 0; + curr->read.cmd_type_len = htole32(len | flags | + IXGBE_ADVTXD_DCMD_IFCS | IXGBE_TXD_CMD_EOP); + + /* make sure changes to the buffer are synced */ + bus_dmamap_sync(txr->txtag, txbuf->map, + BUS_DMASYNC_PREWRITE); + + nm_i = nm_next(nm_i, lim); + nic_i = nm_next(nic_i, lim); + } + kring->nr_hwcur = head; + + /* synchronize the NIC ring */ + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + /* (re)start the tx unit up to slot nic_i (excluded) */ + IXGBE_WRITE_REG(&adapter->hw, txr->tail, nic_i); + } + + /* + * Second part: reclaim buffers for completed transmissions. + * Because this is expensive (we read a NIC register etc.) + * we only do it in specific cases (see below). + */ + if (flags & NAF_FORCE_RECLAIM) { + reclaim_tx = 1; /* forced reclaim */ + } else if (!nm_kr_txempty(kring)) { + reclaim_tx = 0; /* have buffers, no reclaim */ + } else { + /* + * No buffers available. Locate previous slot with + * REPORT_STATUS set. + * If the slot has DD set, we can reclaim space, + * otherwise wait for the next interrupt. + * This enables interrupt moderation on the tx + * side though it might reduce throughput. + */ + struct ixgbe_legacy_tx_desc *txd = + (struct ixgbe_legacy_tx_desc *)txr->tx_base; + + nic_i = txr->next_to_clean + report_frequency; + if (nic_i > lim) + nic_i -= lim + 1; + // round to the closest with dd set + nic_i = (nic_i < kring->nkr_num_slots / 4 || + nic_i >= kring->nkr_num_slots*3/4) ? + 0 : report_frequency; + reclaim_tx = txd[nic_i].upper.fields.status & IXGBE_TXD_STAT_DD; // XXX cpu_to_le32 ? + } + if (reclaim_tx) { + /* + * Record completed transmissions. + * We (re)use the driver's txr->next_to_clean to keep + * track of the most recently completed transmission. + * + * The datasheet discourages the use of TDH to find + * out the number of sent packets, but we only set + * REPORT_STATUS in a few slots so TDH is the only + * good way. + */ + nic_i = IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(kring->ring_id)); + if (nic_i >= kring->nkr_num_slots) { /* XXX can it happen ? */ + D("TDH wrap %d", nic_i); + nic_i -= kring->nkr_num_slots; + } + if (nic_i != txr->next_to_clean) { + /* some tx completed, increment avail */ + txr->next_to_clean = nic_i; + kring->nr_hwtail = nm_prev(netmap_idx_n2k(kring, nic_i), lim); + } + } + + return 0; +} + + +/* + * Reconcile kernel and user view of the receive ring. + * Same as for the txsync, this routine must be efficient. + * The caller guarantees a single invocations, but races against + * the rest of the driver should be handled here. + * + * On call, kring->rhead is the first packet that userspace wants + * to keep, and kring->rcur is the wakeup point. + * The kernel has previously reported packets up to kring->rtail. + * + * If (flags & NAF_FORCE_READ) also check for incoming packets irrespective + * of whether or not we received an interrupt. + */ +static int +ixgbe_netmap_rxsync(struct netmap_kring *kring, int flags) +{ + struct netmap_adapter *na = kring->na; + struct ifnet *ifp = na->ifp; + struct netmap_ring *ring = kring->ring; + u_int nm_i; /* index into the netmap ring */ + u_int nic_i; /* index into the NIC ring */ + u_int n; + u_int const lim = kring->nkr_num_slots - 1; + u_int const head = kring->rhead; + int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; + + /* device-specific */ + struct adapter *adapter = ifp->if_softc; + struct rx_ring *rxr = &adapter->rx_rings[kring->ring_id]; + + if (head > lim) + return netmap_ring_reinit(kring); + + /* XXX check sync modes */ + bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + /* + * First part: import newly received packets. + * + * nm_i is the index of the next free slot in the netmap ring, + * nic_i is the index of the next received packet in the NIC ring, + * and they may differ in case if_init() has been called while + * in netmap mode. For the receive ring we have + * + * nic_i = rxr->next_to_check; + * nm_i = kring->nr_hwtail (previous) + * and + * nm_i == (nic_i + kring->nkr_hwofs) % ring_size + * + * rxr->next_to_check is set to 0 on a ring reinit + */ + if (netmap_no_pendintr || force_update) { + int crclen = (ix_crcstrip) ? 0 : 4; + uint16_t slot_flags = kring->nkr_slot_flags; + + nic_i = rxr->next_to_check; // or also k2n(kring->nr_hwtail) + nm_i = netmap_idx_n2k(kring, nic_i); + + for (n = 0; ; n++) { + union ixgbe_adv_rx_desc *curr = &rxr->rx_base[nic_i]; + uint32_t staterr = le32toh(curr->wb.upper.status_error); + + if ((staterr & IXGBE_RXD_STAT_DD) == 0) + break; + ring->slot[nm_i].len = le16toh(curr->wb.upper.length) - crclen; + ring->slot[nm_i].flags = slot_flags; + bus_dmamap_sync(rxr->ptag, + rxr->rx_buffers[nic_i].pmap, BUS_DMASYNC_POSTREAD); + nm_i = nm_next(nm_i, lim); + nic_i = nm_next(nic_i, lim); + } + if (n) { /* update the state variables */ + if (netmap_no_pendintr && !force_update) { + /* diagnostics */ + ix_rx_miss ++; + ix_rx_miss_bufs += n; + } + rxr->next_to_check = nic_i; + kring->nr_hwtail = nm_i; + } + kring->nr_kflags &= ~NKR_PENDINTR; + } + + /* + * Second part: skip past packets that userspace has released. + * (kring->nr_hwcur to kring->rhead excluded), + * and make the buffers available for reception. + * As usual nm_i is the index in the netmap ring, + * nic_i is the index in the NIC ring, and + * nm_i == (nic_i + kring->nkr_hwofs) % ring_size + */ + nm_i = kring->nr_hwcur; + if (nm_i != head) { + nic_i = netmap_idx_k2n(kring, nm_i); + for (n = 0; nm_i != head; n++) { + struct netmap_slot *slot = &ring->slot[nm_i]; + uint64_t paddr; + void *addr = PNMB(na, slot, &paddr); + + union ixgbe_adv_rx_desc *curr = &rxr->rx_base[nic_i]; + struct ixgbe_rx_buf *rxbuf = &rxr->rx_buffers[nic_i]; + + if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ + goto ring_reset; + + if (slot->flags & NS_BUF_CHANGED) { + /* buffer has changed, reload map */ + netmap_reload_map(na, rxr->ptag, rxbuf->pmap, addr); + slot->flags &= ~NS_BUF_CHANGED; + } + curr->wb.upper.status_error = 0; + curr->read.pkt_addr = htole64(paddr); + bus_dmamap_sync(rxr->ptag, rxbuf->pmap, + BUS_DMASYNC_PREREAD); + nm_i = nm_next(nm_i, lim); + nic_i = nm_next(nic_i, lim); + } + kring->nr_hwcur = head; + + bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + /* + * IMPORTANT: we must leave one free slot in the ring, + * so move nic_i back by one unit + */ + nic_i = nm_prev(nic_i, lim); + IXGBE_WRITE_REG(&adapter->hw, rxr->tail, nic_i); + } + + return 0; + +ring_reset: + return netmap_ring_reinit(kring); +} + + +/* + * The attach routine, called near the end of ixgbe_attach(), + * fills the parameters for netmap_attach() and calls it. + * It cannot fail, in the worst case (such as no memory) + * netmap mode will be disabled and the driver will only + * operate in standard mode. + */ +void +ixgbe_netmap_attach(struct adapter *adapter) +{ + struct netmap_adapter na; + + bzero(&na, sizeof(na)); + + na.ifp = adapter->ifp; + na.na_flags = NAF_BDG_MAYSLEEP; + na.num_tx_desc = adapter->num_tx_desc; + na.num_rx_desc = adapter->num_rx_desc; + na.nm_txsync = ixgbe_netmap_txsync; + na.nm_rxsync = ixgbe_netmap_rxsync; + na.nm_register = ixgbe_netmap_reg; + na.num_tx_rings = na.num_rx_rings = adapter->num_queues; + netmap_attach(&na); +} + +#endif /* DEV_NETMAP */ + +/* end of file */ diff --git a/sys/dev/ixgbe/ixgbe_netmap.h b/sys/dev/ixgbe/ixgbe_netmap.h new file mode 100644 index 000000000000..014bb5f7e748 --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_netmap.h @@ -0,0 +1,59 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + + +#ifndef _IXGBE_NETMAP_H_ +#define _IXGBE_NETMAP_H_ + +#ifdef DEV_NETMAP + +#include +#include +#include + +extern int ix_crcstrip; + +/* + * ixgbe_netmap.c contains functions for netmap + * support that extend the standard driver. See additional + * comments in ixgbe_netmap.c. + */ +void ixgbe_netmap_attach(struct adapter *adapter); + +#else +#define ixgbe_netmap_attach(a) +#define netmap_detach(a) +#endif /* DEV_NETMAP */ + +#endif /* _IXGBE_NETMAP_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_osdep.c b/sys/dev/ixgbe/ixgbe_osdep.c index 6a4e2fc34bf5..4584718b2613 100644 --- a/sys/dev/ixgbe/ixgbe_osdep.c +++ b/sys/dev/ixgbe/ixgbe_osdep.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,35 +32,25 @@ ******************************************************************************/ /*$FreeBSD$*/ -#include "ixgbe_osdep.h" #include "ixgbe.h" -inline device_t -ixgbe_dev_from_hw(struct ixgbe_hw *hw) -{ - return ((struct adapter *)hw->back)->dev; -} - inline u16 ixgbe_read_pci_cfg(struct ixgbe_hw *hw, u32 reg) { - return pci_read_config(((struct adapter *)hw->back)->dev, - reg, 2); + return pci_read_config(((struct adapter *)hw->back)->dev, reg, 2); } inline void ixgbe_write_pci_cfg(struct ixgbe_hw *hw, u32 reg, u16 value) { - pci_write_config(((struct adapter *)hw->back)->dev, - reg, value, 2); + pci_write_config(((struct adapter *)hw->back)->dev, reg, value, 2); } inline u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg) { return bus_space_read_4(((struct adapter *)hw->back)->osdep.mem_bus_space_tag, - ((struct adapter *)hw->back)->osdep.mem_bus_space_handle, - reg); + ((struct adapter *)hw->back)->osdep.mem_bus_space_handle, reg); } inline void diff --git a/sys/dev/ixgbe/ixgbe_osdep.h b/sys/dev/ixgbe/ixgbe_osdep.h index 79d11665ee10..ea813c3576c2 100644 --- a/sys/dev/ixgbe/ixgbe_osdep.h +++ b/sys/dev/ixgbe/ixgbe_osdep.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,8 +32,8 @@ ******************************************************************************/ /*$FreeBSD$*/ -#ifndef _IXGBE_OS_H_ -#define _IXGBE_OS_H_ +#ifndef _IXGBE_OSDEP_H_ +#define _IXGBE_OSDEP_H_ #include #include @@ -55,7 +55,7 @@ #include #define ASSERT(x) if(!(x)) panic("IXGBE: x") -#define EWARN(H, W, S) printf(W) +#define EWARN(H, W) printf(W) enum { IXGBE_ERROR_SOFTWARE, @@ -135,10 +135,13 @@ enum { #define IXGBE_NTOHS(_i) ntohs(_i) /* XXX these need to be revisited */ +#define IXGBE_CPU_TO_LE16 htole16 #define IXGBE_CPU_TO_LE32 htole32 +#define IXGBE_LE32_TO_CPU le32toh #define IXGBE_LE32_TO_CPUS(x) #define IXGBE_CPU_TO_BE16 htobe16 #define IXGBE_CPU_TO_BE32 htobe32 +#define IXGBE_BE32_TO_CPU be32toh typedef uint8_t u8; typedef int8_t s8; @@ -159,7 +162,7 @@ typedef boolean_t bool; #define __be32 u32 #define __be64 u64 -#define le16_to_cpu +#define le16_to_cpu #if __FreeBSD_version < 800000 #if defined(__i386__) || defined(__amd64__) @@ -209,8 +212,7 @@ struct ixgbe_osdep }; /* These routines need struct ixgbe_hw declared */ -struct ixgbe_hw; -device_t ixgbe_dev_from_hw(struct ixgbe_hw *hw); +struct ixgbe_hw; /* These routines are needed by the shared code */ extern u16 ixgbe_read_pci_cfg(struct ixgbe_hw *, u32); @@ -235,4 +237,4 @@ extern void ixgbe_write_reg_array(struct ixgbe_hw *, u32, u32, u32); #define IXGBE_WRITE_REG_ARRAY(a, reg, offset, val) \ ixgbe_write_reg_array(a, reg, offset, val) -#endif /* _IXGBE_OS_H_ */ +#endif /* _IXGBE_OSDEP_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c index 11653ec3fc86..ee4e96cd9f35 100644 --- a/sys/dev/ixgbe/ixgbe_phy.c +++ b/sys/dev/ixgbe/ixgbe_phy.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -110,11 +110,11 @@ static u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2) * * Returns an error code on error. */ -static s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, - u16 reg, u16 *val, bool lock) +s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg, + u16 *val, bool lock) { u32 swfw_mask = hw->phy.phy_semaphore_mask; - int max_retry = 10; + int max_retry = 3; int retry = 0; u8 csum_byte; u8 high_bits; @@ -122,8 +122,6 @@ static s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u8 reg_high; u8 csum; - if (hw->mac.type >= ixgbe_mac_X550) - max_retry = 3; reg_high = ((reg >> 7) & 0xFE) | 1; /* Indicate read combined */ csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF); csum = ~csum; @@ -180,37 +178,6 @@ static s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, return IXGBE_ERR_I2C; } -/** - * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation - * @hw: pointer to the hardware structure - * @addr: I2C bus address to read from - * @reg: I2C device register to read from - * @val: pointer to location to receive read value - * - * Returns an error code on error. - **/ -static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, - u16 reg, u16 *val) -{ - return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE); -} - -/** - * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation - * @hw: pointer to the hardware structure - * @addr: I2C bus address to read from - * @reg: I2C device register to read from - * @val: pointer to location to receive read value - * - * Returns an error code on error. - **/ -static s32 -ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, - u16 reg, u16 *val) -{ - return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE); -} - /** * ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation * @hw: pointer to the hardware structure @@ -221,8 +188,8 @@ ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, * * Returns an error code on error. */ -static s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, - u16 reg, u16 val, bool lock) +s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg, + u16 val, bool lock) { u32 swfw_mask = hw->phy.phy_semaphore_mask; int max_retry = 1; @@ -276,37 +243,6 @@ static s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, return IXGBE_ERR_I2C; } -/** - * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation - * @hw: pointer to the hardware structure - * @addr: I2C bus address to write to - * @reg: I2C device register to write to - * @val: value to write - * - * Returns an error code on error. - **/ -static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, - u8 addr, u16 reg, u16 val) -{ - return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE); -} - -/** - * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation - * @hw: pointer to the hardware structure - * @addr: I2C bus address to write to - * @reg: I2C device register to write to - * @val: value to write - * - * Returns an error code on error. - **/ -static s32 -ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, - u8 addr, u16 reg, u16 val) -{ - return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE); -} - /** * ixgbe_init_phy_ops_generic - Inits PHY function ptrs * @hw: pointer to the hardware structure @@ -338,12 +274,6 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) phy->ops.i2c_bus_clear = ixgbe_i2c_bus_clear; phy->ops.identify_sfp = ixgbe_identify_module_generic; phy->sfp_type = ixgbe_sfp_type_unknown; - phy->ops.read_i2c_combined = ixgbe_read_i2c_combined_generic; - phy->ops.write_i2c_combined = ixgbe_write_i2c_combined_generic; - phy->ops.read_i2c_combined_unlocked = - ixgbe_read_i2c_combined_generic_unlocked; - phy->ops.write_i2c_combined_unlocked = - ixgbe_write_i2c_combined_generic_unlocked; phy->ops.read_i2c_byte_unlocked = ixgbe_read_i2c_byte_generic_unlocked; phy->ops.write_i2c_byte_unlocked = ixgbe_write_i2c_byte_generic_unlocked; @@ -351,6 +281,42 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) return IXGBE_SUCCESS; } +/** + * ixgbe_probe_phy - Probe a single address for a PHY + * @hw: pointer to hardware structure + * @phy_addr: PHY address to probe + * + * Returns TRUE if PHY found + */ +static bool ixgbe_probe_phy(struct ixgbe_hw *hw, u16 phy_addr) +{ + u16 ext_ability = 0; + + if (!ixgbe_validate_phy_addr(hw, phy_addr)) { + DEBUGOUT1("Unable to validate PHY address 0x%04X\n", + phy_addr); + return FALSE; + } + + if (ixgbe_get_phy_id(hw)) + return FALSE; + + hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); + + if (hw->phy.type == ixgbe_phy_unknown) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & + (IXGBE_MDIO_PHY_10GBASET_ABILITY | + IXGBE_MDIO_PHY_1000BASET_ABILITY)) + hw->phy.type = ixgbe_phy_cu_unknown; + else + hw->phy.type = ixgbe_phy_generic; + } + + return TRUE; +} + /** * ixgbe_identify_phy_generic - Get physical layer module * @hw: pointer to hardware structure @@ -360,8 +326,7 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; - u32 phy_addr; - u16 ext_ability = 0; + u16 phy_addr; DEBUGFUNC("ixgbe_identify_phy_generic"); @@ -372,45 +337,33 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; } - if (hw->phy.type == ixgbe_phy_unknown) { - for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { - if (ixgbe_validate_phy_addr(hw, phy_addr)) { - hw->phy.addr = phy_addr; - ixgbe_get_phy_id(hw); - hw->phy.type = - ixgbe_get_phy_type_from_id(hw->phy.id); + if (hw->phy.type != ixgbe_phy_unknown) + return IXGBE_SUCCESS; - if (hw->phy.type == ixgbe_phy_unknown) { - hw->phy.ops.read_reg(hw, - IXGBE_MDIO_PHY_EXT_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, - &ext_ability); - if (ext_ability & - (IXGBE_MDIO_PHY_10GBASET_ABILITY | - IXGBE_MDIO_PHY_1000BASET_ABILITY)) - hw->phy.type = - ixgbe_phy_cu_unknown; - else - hw->phy.type = - ixgbe_phy_generic; - } - - status = IXGBE_SUCCESS; - break; - } - } - - /* Certain media types do not have a phy so an address will not - * be found and the code will take this path. Caller has to - * decide if it is an error or not. - */ - if (status != IXGBE_SUCCESS) { - hw->phy.addr = 0; - } - } else { - status = IXGBE_SUCCESS; + if (hw->phy.nw_mng_if_sel) { + phy_addr = (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >> + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT; + if (ixgbe_probe_phy(hw, phy_addr)) + return IXGBE_SUCCESS; + else + return IXGBE_ERR_PHY_ADDR_INVALID; } + for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { + if (ixgbe_probe_phy(hw, phy_addr)) { + status = IXGBE_SUCCESS; + break; + } + } + + /* Certain media types do not have a phy so an address will not + * be found and the code will take this path. Caller has to + * decide if it is an error or not. + */ + if (status != IXGBE_SUCCESS) + hw->phy.addr = 0; + return status; } @@ -462,6 +415,8 @@ bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) if (phy_id != 0xFFFF && phy_id != 0x0) valid = TRUE; + DEBUGOUT1("PHY ID HIGH is 0x%04X\n", phy_id); + return valid; } @@ -490,12 +445,15 @@ s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); } + DEBUGOUT2("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X\n", + phy_id_high, phy_id_low); + return status; } /** * ixgbe_get_phy_type_from_id - Get the phy type - * @hw: pointer to hardware structure + * @phy_id: PHY ID information * **/ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) @@ -508,7 +466,6 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) case TN1010_PHY_ID: phy_type = ixgbe_phy_tn; break; - case X550_PHY_ID1: case X550_PHY_ID2: case X550_PHY_ID3: case X540_PHY_ID: @@ -521,14 +478,17 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) phy_type = ixgbe_phy_nl; break; case X557_PHY_ID: + case X557_PHY_ID2: phy_type = ixgbe_phy_x550em_ext_t; break; + case IXGBE_M88E1500_E_PHY_ID: + case IXGBE_M88E1543_E_PHY_ID: + phy_type = ixgbe_phy_ext_1g_t; + break; default: phy_type = ixgbe_phy_unknown; break; } - - DEBUGOUT1("phy type found is %d\n", phy_type); return phy_type; } @@ -574,11 +534,30 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) */ for (i = 0; i < 30; i++) { msec_delay(100); - hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, - IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl); - if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) { - usec_delay(2); - break; + if (hw->phy.type == ixgbe_phy_x550em_ext_t) { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_TX_VENDOR_ALARMS_3, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &ctrl); + if (status != IXGBE_SUCCESS) + return status; + + if (ctrl & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) { + usec_delay(2); + break; + } + } else { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, + &ctrl); + if (status != IXGBE_SUCCESS) + return status; + + if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) { + usec_delay(2); + break; + } } } @@ -600,7 +579,7 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) * @phy_data: Pointer to read data from PHY register **/ s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, - u16 *phy_data) + u16 *phy_data) { u32 i, data, command; @@ -622,12 +601,13 @@ s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, command = IXGBE_READ_REG(hw, IXGBE_MSCA); if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) - break; + break; } if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address command did not complete.\n"); + DEBUGOUT("PHY address command did not complete, returning IXGBE_ERR_PHY\n"); return IXGBE_ERR_PHY; } @@ -657,6 +637,7 @@ s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY read command didn't complete\n"); + DEBUGOUT("PHY read command didn't complete, returning IXGBE_ERR_PHY\n"); return IXGBE_ERR_PHY; } @@ -686,13 +667,12 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, DEBUGFUNC("ixgbe_read_phy_reg_generic"); - if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { - status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type, - phy_data); - hw->mac.ops.release_swfw_sync(hw, gssr); - } else { - status = IXGBE_ERR_SWFW_SYNC; - } + if (hw->mac.ops.acquire_swfw_sync(hw, gssr)) + return IXGBE_ERR_SWFW_SYNC; + + status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); + + hw->mac.ops.release_swfw_sync(hw, gssr); return status; } @@ -788,7 +768,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, DEBUGFUNC("ixgbe_write_phy_reg_generic"); if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { - status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, + status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type, phy_data); hw->mac.ops.release_swfw_sync(hw, gssr); } else { @@ -815,91 +795,63 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); - if (speed & IXGBE_LINK_SPEED_10GB_FULL) { - /* Set or unset auto-negotiation 10G advertisement */ - hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); + /* Set or unset auto-negotiation 10G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); - autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; - if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) - autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; + autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) && + (speed & IXGBE_LINK_SPEED_10GB_FULL)) + autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; - hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - autoneg_reg); - } + hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); if (hw->mac.type == ixgbe_mac_X550) { - if (speed & IXGBE_LINK_SPEED_5GB_FULL) { - /* Set or unset auto-negotiation 5G advertisement */ - hw->phy.ops.read_reg(hw, - IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); + /* Set or unset auto-negotiation 5G advertisement */ + autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) && + (speed & IXGBE_LINK_SPEED_5GB_FULL)) + autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE; - autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE; - if (hw->phy.autoneg_advertised & - IXGBE_LINK_SPEED_5GB_FULL) - autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE; - - hw->phy.ops.write_reg(hw, - IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - autoneg_reg); - } - - if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) { - /* Set or unset auto-negotiation 2.5G advertisement */ - hw->phy.ops.read_reg(hw, - IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); - - autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE; - if (hw->phy.autoneg_advertised & - IXGBE_LINK_SPEED_2_5GB_FULL) - autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE; - - hw->phy.ops.write_reg(hw, - IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - autoneg_reg); - } + /* Set or unset auto-negotiation 2.5G advertisement */ + autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & + IXGBE_LINK_SPEED_2_5GB_FULL) && + (speed & IXGBE_LINK_SPEED_2_5GB_FULL)) + autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE; } - if (speed & IXGBE_LINK_SPEED_1GB_FULL) { - /* Set or unset auto-negotiation 1G advertisement */ - hw->phy.ops.read_reg(hw, - IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); + /* Set or unset auto-negotiation 1G advertisement */ + autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) && + (speed & IXGBE_LINK_SPEED_1GB_FULL)) + autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; - autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; - if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) - autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); - hw->phy.ops.write_reg(hw, - IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - autoneg_reg); - } + /* Set or unset auto-negotiation 100M advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); - if (speed & IXGBE_LINK_SPEED_100_FULL) { - /* Set or unset auto-negotiation 100M advertisement */ - hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); + autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE | + IXGBE_MII_100BASE_T_ADVERTISE_HALF); + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) && + (speed & IXGBE_LINK_SPEED_100_FULL)) + autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; - autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE | - IXGBE_MII_100BASE_T_ADVERTISE_HALF); - if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) - autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; - - hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - autoneg_reg); - } + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); /* Blocked by MNG FW so don't reset PHY */ if (ixgbe_check_reset_blocked(hw)) @@ -951,6 +903,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, if (speed & IXGBE_LINK_SPEED_100_FULL) hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; + if (speed & IXGBE_LINK_SPEED_10_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10_FULL; + /* Setup link based on the new speed settings */ ixgbe_setup_phy_link(hw); @@ -988,6 +943,7 @@ static s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw) hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; break; case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL; break; default: @@ -1534,18 +1490,21 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->phy.type = ixgbe_phy_sfp_intel; break; default: - hw->phy.type = ixgbe_phy_sfp_unknown; + if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) + hw->phy.type = + ixgbe_phy_sfp_passive_unknown; + else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) + hw->phy.type = + ixgbe_phy_sfp_active_unknown; + else + hw->phy.type = ixgbe_phy_sfp_unknown; break; } } /* Allow any DA cable vendor */ if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE | - IXGBE_SFF_DA_ACTIVE_CABLE)) { - if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) - hw->phy.type = ixgbe_phy_sfp_passive_unknown; - else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) - hw->phy.type = ixgbe_phy_sfp_active_unknown; + IXGBE_SFF_DA_ACTIVE_CABLE)) { status = IXGBE_SUCCESS; goto out; } @@ -1582,16 +1541,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) status = IXGBE_SUCCESS; } else { if (hw->allow_unsupported_sfp == TRUE) { - EWARN(hw, "WARNING: Intel (R) Network " - "Connections are quality tested " - "using Intel (R) Ethernet Optics." - " Using untested modules is not " - "supported and may cause unstable" - " operation or damage to the " - "module or the adapter. Intel " - "Corporation is not responsible " - "for any harm caused by using " - "untested modules.\n", status); + EWARN(hw, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n"); status = IXGBE_SUCCESS; } else { DEBUGOUT("SFP+ module not supported\n"); @@ -1623,9 +1573,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) * * Determines physical layer capabilities of the current SFP. */ -s32 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw) +u64 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw) { - u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; u8 comp_codes_10g = 0; u8 comp_codes_1g = 0; @@ -1844,16 +1794,7 @@ s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) status = IXGBE_SUCCESS; } else { if (hw->allow_unsupported_sfp == TRUE) { - EWARN(hw, "WARNING: Intel (R) Network " - "Connections are quality tested " - "using Intel (R) Ethernet Optics." - " Using untested modules is not " - "supported and may cause unstable" - " operation or damage to the " - "module or the adapter. Intel " - "Corporation is not responsible " - "for any harm caused by using " - "untested modules.\n", status); + EWARN(hw, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n"); status = IXGBE_SUCCESS; } else { DEBUGOUT("QSFP module not supported\n"); @@ -1878,7 +1819,6 @@ s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) return IXGBE_ERR_SFP_NOT_PRESENT; } - /** * ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence * @hw: pointer to hardware structure diff --git a/sys/dev/ixgbe/ixgbe_phy.h b/sys/dev/ixgbe/ixgbe_phy.h index 3713e284bc8e..36624359b46d 100644 --- a/sys/dev/ixgbe/ixgbe_phy.h +++ b/sys/dev/ixgbe/ixgbe_phy.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -90,8 +90,12 @@ #define IXGBE_CS4227 0xBE /* CS4227 address */ #define IXGBE_CS4227_GLOBAL_ID_LSB 0 +#define IXGBE_CS4227_GLOBAL_ID_MSB 1 #define IXGBE_CS4227_SCRATCH 2 #define IXGBE_CS4227_GLOBAL_ID_VALUE 0x03E5 +#define IXGBE_CS4227_EFUSE_PDF_SKU 0x19F +#define IXGBE_CS4223_SKU_ID 0x0010 /* Quad port */ +#define IXGBE_CS4227_SKU_ID 0x0014 /* Dual port */ #define IXGBE_CS4227_RESET_PENDING 0x1357 #define IXGBE_CS4227_RESET_COMPLETE 0x5AA5 #define IXGBE_CS4227_RETRIES 15 @@ -189,7 +193,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on); s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); -s32 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw); s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, @@ -208,4 +212,8 @@ s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data); void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); +s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg, + u16 *val, bool lock); +s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg, + u16 val, bool lock); #endif /* _IXGBE_PHY_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_rss.h b/sys/dev/ixgbe/ixgbe_rss.h new file mode 100644 index 000000000000..e22560b99457 --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_rss.h @@ -0,0 +1,64 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#ifndef _IXGBE_RSS_H_ +#define _IXGBE_RSS_H_ + +#ifdef RSS + +#include +#include + +#else + +#define RSS_HASHTYPE_RSS_IPV4 (1 << 1) +#define RSS_HASHTYPE_RSS_TCP_IPV4 (1 << 2) +#define RSS_HASHTYPE_RSS_IPV6 (1 << 3) +#define RSS_HASHTYPE_RSS_TCP_IPV6 (1 << 4) +#define RSS_HASHTYPE_RSS_IPV6_EX (1 << 5) +#define RSS_HASHTYPE_RSS_TCP_IPV6_EX (1 << 6) +#define RSS_HASHTYPE_RSS_UDP_IPV4 (1 << 7) +#define RSS_HASHTYPE_RSS_UDP_IPV4_EX (1 << 8) +#define RSS_HASHTYPE_RSS_UDP_IPV6 (1 << 9) +#define RSS_HASHTYPE_RSS_UDP_IPV6_EX (1 << 10) + +#define rss_getcpu(_a) 0 +#define rss_getnumbuckets() 1 +#define rss_getkey(_a) +#define rss_get_indirection_to_bucket(_a) 0 +#define rss_gethashconfig() 0x7E +#define rss_hash2bucket(_a,_b,_c) -1 + +#endif +#endif /* _IXGBE_RSS_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_sriov.h b/sys/dev/ixgbe/ixgbe_sriov.h new file mode 100644 index 000000000000..bfe58d4dd24c --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_sriov.h @@ -0,0 +1,102 @@ +/****************************************************************************** + + Copyright (c) 2001-2017, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + + +#ifndef _IXGBE_SRIOV_H_ +#define _IXGBE_SRIOV_H_ + +#ifdef PCI_IOV + +#include +#include +#include +#include "ixgbe_mbx.h" + +#define IXGBE_VF_CTS (1 << 0) /* VF is clear to send. */ +#define IXGBE_VF_CAP_MAC (1 << 1) /* VF is permitted to change MAC. */ +#define IXGBE_VF_CAP_VLAN (1 << 2) /* VF is permitted to join vlans. */ +#define IXGBE_VF_ACTIVE (1 << 3) /* VF is active. */ +#define IXGBE_VF_INDEX(vmdq) ((vmdq) / 32) +#define IXGBE_VF_BIT(vmdq) (1 << ((vmdq) % 32)) + +#define IXGBE_VT_MSG_MASK 0xFFFF + +#define IXGBE_VT_MSGINFO(msg) \ + (((msg) & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT) + +#define IXGBE_VF_GET_QUEUES_RESP_LEN 5 + +#define IXGBE_API_VER_1_0 0 +#define IXGBE_API_VER_2_0 1 /* Solaris API. Not supported. */ +#define IXGBE_API_VER_1_1 2 +#define IXGBE_API_VER_UNKNOWN UINT16_MAX + +#define IXGBE_NO_VM 0 +#define IXGBE_32_VM 32 +#define IXGBE_64_VM 64 + +int ixgbe_add_vf(device_t, u16, const nvlist_t *); +int ixgbe_init_iov(device_t, u16, const nvlist_t *); +void ixgbe_uninit_iov(device_t); +void ixgbe_initialize_iov(struct adapter *); +void ixgbe_recalculate_max_frame(struct adapter *); +void ixgbe_ping_all_vfs(struct adapter *); +int ixgbe_pci_iov_detach(device_t); +void ixgbe_define_iov_schemas(device_t, int *); +void ixgbe_align_all_queue_indices(struct adapter *); +u32 ixgbe_get_mtqc(int); +u32 ixgbe_get_mrqc(int); + +/******************************************************************************/ +#else /* PCI_IOV */ +/******************************************************************************/ + +#define ixgbe_add_vf(_a,_b,_c) +#define ixgbe_init_iov(_a,_b,_c) +#define ixgbe_uninit_iov(_a) +#define ixgbe_initialize_iov(_a) +#define ixgbe_recalculate_max_frame(_a) +#define ixgbe_ping_all_vfs(_a) +#define ixgbe_pci_iov_detach(_a) 0 +#define ixgbe_define_iov_schemas(_a,_b) +#define ixgbe_align_all_queue_indices(_a) +#define ixgbe_get_mtqc(_a) IXGBE_MTQC_64Q_1PB +#define ixgbe_get_mrqc(_a) 0 + +#endif /* PCI_IOV */ + +void ixgbe_handle_mbx(void *, int); +int ixgbe_vf_que_index(int, int, int); + +#endif diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index 123c9d5210df..a448f2b4ed6c 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -107,11 +107,11 @@ #define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 #define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470 #define IXGBE_SUBDEV_ID_82599_SP_560FLR 0x211B -#define IXGBE_SUBDEV_ID_82599_LOM_SFP 0x8976 #define IXGBE_SUBDEV_ID_82599_LOM_SNAP6 0x2159 #define IXGBE_SUBDEV_ID_82599_SFP_1OCP 0x000D #define IXGBE_SUBDEV_ID_82599_SFP_2OCP 0x0008 -#define IXGBE_SUBDEV_ID_82599_SFP_LOM 0x06EE +#define IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM1 0x8976 +#define IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM2 0x06EE #define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152A #define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529 #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 @@ -132,13 +132,27 @@ #define IXGBE_DEV_ID_X540T1 0x1560 #define IXGBE_DEV_ID_X550T 0x1563 #define IXGBE_DEV_ID_X550T1 0x15D1 +#define IXGBE_DEV_ID_X550EM_A_KR 0x15C2 +#define IXGBE_DEV_ID_X550EM_A_KR_L 0x15C3 +#define IXGBE_DEV_ID_X550EM_A_SFP_N 0x15C4 +#define IXGBE_DEV_ID_X550EM_A_SGMII 0x15C6 +#define IXGBE_DEV_ID_X550EM_A_SGMII_L 0x15C7 +#define IXGBE_DEV_ID_X550EM_A_10G_T 0x15C8 +#define IXGBE_DEV_ID_X550EM_A_QSFP 0x15CA +#define IXGBE_DEV_ID_X550EM_A_QSFP_N 0x15CC +#define IXGBE_DEV_ID_X550EM_A_SFP 0x15CE +#define IXGBE_DEV_ID_X550EM_A_1G_T 0x15E4 +#define IXGBE_DEV_ID_X550EM_A_1G_T_L 0x15E5 #define IXGBE_DEV_ID_X550EM_X_KX4 0x15AA #define IXGBE_DEV_ID_X550EM_X_KR 0x15AB #define IXGBE_DEV_ID_X550EM_X_SFP 0x15AC #define IXGBE_DEV_ID_X550EM_X_10G_T 0x15AD #define IXGBE_DEV_ID_X550EM_X_1G_T 0x15AE +#define IXGBE_DEV_ID_X550EM_X_XFI 0x15B0 #define IXGBE_DEV_ID_X550_VF_HV 0x1564 #define IXGBE_DEV_ID_X550_VF 0x1565 +#define IXGBE_DEV_ID_X550EM_A_VF 0x15C5 +#define IXGBE_DEV_ID_X550EM_A_VF_HV 0x15B4 #define IXGBE_DEV_ID_X550EM_X_VF 0x15A8 #define IXGBE_DEV_ID_X550EM_X_VF_HV 0x15A9 @@ -157,6 +171,7 @@ #define IXGBE_I2CCTL_X540 IXGBE_I2CCTL_82599 #define IXGBE_I2CCTL_X550 0x15F5C #define IXGBE_I2CCTL_X550EM_x IXGBE_I2CCTL_X550 +#define IXGBE_I2CCTL_X550EM_a IXGBE_I2CCTL_X550 #define IXGBE_I2CCTL_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2CCTL) #define IXGBE_PHY_GPIO 0x00028 #define IXGBE_MAC_GPIO 0x00030 @@ -174,7 +189,8 @@ #define IXGBE_EEC_X540 IXGBE_EEC #define IXGBE_EEC_X550 IXGBE_EEC #define IXGBE_EEC_X550EM_x IXGBE_EEC -#define IXGBE_EEC_BY_MAC(_hw) IXGBE_EEC +#define IXGBE_EEC_X550EM_a 0x15FF8 +#define IXGBE_EEC_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EEC) #define IXGBE_EERD 0x10014 #define IXGBE_EEWR 0x10018 @@ -183,7 +199,8 @@ #define IXGBE_FLA_X540 IXGBE_FLA #define IXGBE_FLA_X550 IXGBE_FLA #define IXGBE_FLA_X550EM_x IXGBE_FLA -#define IXGBE_FLA_BY_MAC(_hw) IXGBE_FLA +#define IXGBE_FLA_X550EM_a 0x15F68 +#define IXGBE_FLA_BY_MAC(_hw) IXGBE_BY_MAC((_hw), FLA) #define IXGBE_EEMNGCTL 0x10110 #define IXGBE_EEMNGDATA 0x10114 @@ -196,13 +213,15 @@ #define IXGBE_GRC_X540 IXGBE_GRC #define IXGBE_GRC_X550 IXGBE_GRC #define IXGBE_GRC_X550EM_x IXGBE_GRC -#define IXGBE_GRC_BY_MAC(_hw) IXGBE_GRC +#define IXGBE_GRC_X550EM_a 0x15F64 +#define IXGBE_GRC_BY_MAC(_hw) IXGBE_BY_MAC((_hw), GRC) #define IXGBE_SRAMREL 0x10210 #define IXGBE_SRAMREL_X540 IXGBE_SRAMREL #define IXGBE_SRAMREL_X550 IXGBE_SRAMREL #define IXGBE_SRAMREL_X550EM_x IXGBE_SRAMREL -#define IXGBE_SRAMREL_BY_MAC(_hw) IXGBE_SRAMREL +#define IXGBE_SRAMREL_X550EM_a 0x15F6C +#define IXGBE_SRAMREL_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SRAMREL) #define IXGBE_PHYDBG 0x10218 @@ -218,36 +237,42 @@ #define IXGBE_I2C_CLK_IN_X540 IXGBE_I2C_CLK_IN #define IXGBE_I2C_CLK_IN_X550 0x00004000 #define IXGBE_I2C_CLK_IN_X550EM_x IXGBE_I2C_CLK_IN_X550 +#define IXGBE_I2C_CLK_IN_X550EM_a IXGBE_I2C_CLK_IN_X550 #define IXGBE_I2C_CLK_IN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_IN) #define IXGBE_I2C_CLK_OUT 0x00000002 #define IXGBE_I2C_CLK_OUT_X540 IXGBE_I2C_CLK_OUT #define IXGBE_I2C_CLK_OUT_X550 0x00000200 #define IXGBE_I2C_CLK_OUT_X550EM_x IXGBE_I2C_CLK_OUT_X550 +#define IXGBE_I2C_CLK_OUT_X550EM_a IXGBE_I2C_CLK_OUT_X550 #define IXGBE_I2C_CLK_OUT_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_OUT) #define IXGBE_I2C_DATA_IN 0x00000004 #define IXGBE_I2C_DATA_IN_X540 IXGBE_I2C_DATA_IN #define IXGBE_I2C_DATA_IN_X550 0x00001000 #define IXGBE_I2C_DATA_IN_X550EM_x IXGBE_I2C_DATA_IN_X550 +#define IXGBE_I2C_DATA_IN_X550EM_a IXGBE_I2C_DATA_IN_X550 #define IXGBE_I2C_DATA_IN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_IN) #define IXGBE_I2C_DATA_OUT 0x00000008 #define IXGBE_I2C_DATA_OUT_X540 IXGBE_I2C_DATA_OUT #define IXGBE_I2C_DATA_OUT_X550 0x00000400 #define IXGBE_I2C_DATA_OUT_X550EM_x IXGBE_I2C_DATA_OUT_X550 +#define IXGBE_I2C_DATA_OUT_X550EM_a IXGBE_I2C_DATA_OUT_X550 #define IXGBE_I2C_DATA_OUT_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_OUT) #define IXGBE_I2C_DATA_OE_N_EN 0 #define IXGBE_I2C_DATA_OE_N_EN_X540 IXGBE_I2C_DATA_OE_N_EN #define IXGBE_I2C_DATA_OE_N_EN_X550 0x00000800 #define IXGBE_I2C_DATA_OE_N_EN_X550EM_x IXGBE_I2C_DATA_OE_N_EN_X550 +#define IXGBE_I2C_DATA_OE_N_EN_X550EM_a IXGBE_I2C_DATA_OE_N_EN_X550 #define IXGBE_I2C_DATA_OE_N_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_OE_N_EN) #define IXGBE_I2C_BB_EN 0 #define IXGBE_I2C_BB_EN_X540 IXGBE_I2C_BB_EN #define IXGBE_I2C_BB_EN_X550 0x00000100 #define IXGBE_I2C_BB_EN_X550EM_x IXGBE_I2C_BB_EN_X550 +#define IXGBE_I2C_BB_EN_X550EM_a IXGBE_I2C_BB_EN_X550 #define IXGBE_I2C_BB_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_BB_EN) @@ -255,6 +280,7 @@ #define IXGBE_I2C_CLK_OE_N_EN_X540 IXGBE_I2C_CLK_OE_N_EN #define IXGBE_I2C_CLK_OE_N_EN_X550 0x00002000 #define IXGBE_I2C_CLK_OE_N_EN_X550EM_x IXGBE_I2C_CLK_OE_N_EN_X550 +#define IXGBE_I2C_CLK_OE_N_EN_X550EM_a IXGBE_I2C_CLK_OE_N_EN_X550 #define IXGBE_I2C_CLK_OE_N_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_OE_N_EN) #define IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT 500 @@ -522,6 +548,13 @@ #define IXGBE_PROXYFC 0x05F64 /* Proxying Filter Control Register */ #define IXGBE_VXLANCTRL 0x0000507C /* Rx filter VXLAN UDPPORT Register */ +/* masks for accessing VXLAN and GENEVE UDP ports */ +#define IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK 0x0000ffff /* VXLAN port */ +#define IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK 0xffff0000 /* GENEVE port */ +#define IXGBE_VXLANCTRL_ALL_UDPPORT_MASK 0xffffffff /* GENEVE/VXLAN */ + +#define IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT 16 + #define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter table */ /* Ext Flexible Host Filter Table */ #define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) @@ -995,7 +1028,7 @@ struct ixgbe_dmac_config { #define IXGBE_FTFT 0x09400 /* 0x9400-0x97FC */ #define IXGBE_METF(_i) (0x05190 + ((_i) * 4)) /* 4 of these (0-3) */ #define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */ -#define IXGBE_LSWFW 0x15014 +#define IXGBE_LSWFW 0x15F14 #define IXGBE_BMCIP(_i) (0x05050 + ((_i) * 4)) /* 0x5050-0x505C */ #define IXGBE_BMCIPVAL 0x05060 #define IXGBE_BMCIP_IPADDR_TYPE 0x00000001 @@ -1037,36 +1070,64 @@ struct ixgbe_dmac_config { #define IXGBE_PCIEPIPEDAT 0x11008 #define IXGBE_GSCL_1 0x11010 #define IXGBE_GSCL_2 0x11014 +#define IXGBE_GSCL_1_X540 IXGBE_GSCL_1 +#define IXGBE_GSCL_2_X540 IXGBE_GSCL_2 #define IXGBE_GSCL_3 0x11018 #define IXGBE_GSCL_4 0x1101C #define IXGBE_GSCN_0 0x11020 #define IXGBE_GSCN_1 0x11024 #define IXGBE_GSCN_2 0x11028 #define IXGBE_GSCN_3 0x1102C +#define IXGBE_GSCN_0_X540 IXGBE_GSCN_0 +#define IXGBE_GSCN_1_X540 IXGBE_GSCN_1 +#define IXGBE_GSCN_2_X540 IXGBE_GSCN_2 +#define IXGBE_GSCN_3_X540 IXGBE_GSCN_3 #define IXGBE_FACTPS 0x10150 #define IXGBE_FACTPS_X540 IXGBE_FACTPS +#define IXGBE_GSCL_1_X550 0x11800 +#define IXGBE_GSCL_2_X550 0x11804 +#define IXGBE_GSCL_1_X550EM_x IXGBE_GSCL_1_X550 +#define IXGBE_GSCL_2_X550EM_x IXGBE_GSCL_2_X550 +#define IXGBE_GSCN_0_X550 0x11820 +#define IXGBE_GSCN_1_X550 0x11824 +#define IXGBE_GSCN_2_X550 0x11828 +#define IXGBE_GSCN_3_X550 0x1182C +#define IXGBE_GSCN_0_X550EM_x IXGBE_GSCN_0_X550 +#define IXGBE_GSCN_1_X550EM_x IXGBE_GSCN_1_X550 +#define IXGBE_GSCN_2_X550EM_x IXGBE_GSCN_2_X550 +#define IXGBE_GSCN_3_X550EM_x IXGBE_GSCN_3_X550 #define IXGBE_FACTPS_X550 IXGBE_FACTPS #define IXGBE_FACTPS_X550EM_x IXGBE_FACTPS -#define IXGBE_FACTPS_BY_MAC(_hw) IXGBE_FACTPS +#define IXGBE_GSCL_1_X550EM_a IXGBE_GSCL_1_X550 +#define IXGBE_GSCL_2_X550EM_a IXGBE_GSCL_2_X550 +#define IXGBE_GSCN_0_X550EM_a IXGBE_GSCN_0_X550 +#define IXGBE_GSCN_1_X550EM_a IXGBE_GSCN_1_X550 +#define IXGBE_GSCN_2_X550EM_a IXGBE_GSCN_2_X550 +#define IXGBE_GSCN_3_X550EM_a IXGBE_GSCN_3_X550 +#define IXGBE_FACTPS_X550EM_a 0x15FEC +#define IXGBE_FACTPS_BY_MAC(_hw) IXGBE_BY_MAC((_hw), FACTPS) #define IXGBE_PCIEANACTL 0x11040 #define IXGBE_SWSM 0x10140 #define IXGBE_SWSM_X540 IXGBE_SWSM #define IXGBE_SWSM_X550 IXGBE_SWSM #define IXGBE_SWSM_X550EM_x IXGBE_SWSM -#define IXGBE_SWSM_BY_MAC(_hw) IXGBE_SWSM +#define IXGBE_SWSM_X550EM_a 0x15F70 +#define IXGBE_SWSM_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SWSM) #define IXGBE_FWSM 0x10148 #define IXGBE_FWSM_X540 IXGBE_FWSM #define IXGBE_FWSM_X550 IXGBE_FWSM #define IXGBE_FWSM_X550EM_x IXGBE_FWSM -#define IXGBE_FWSM_BY_MAC(_hw) IXGBE_FWSM +#define IXGBE_FWSM_X550EM_a 0x15F74 +#define IXGBE_FWSM_BY_MAC(_hw) IXGBE_BY_MAC((_hw), FWSM) #define IXGBE_SWFW_SYNC IXGBE_GSSR #define IXGBE_SWFW_SYNC_X540 IXGBE_SWFW_SYNC #define IXGBE_SWFW_SYNC_X550 IXGBE_SWFW_SYNC #define IXGBE_SWFW_SYNC_X550EM_x IXGBE_SWFW_SYNC -#define IXGBE_SWFW_SYNC_BY_MAC(_hw) IXGBE_SWFW_SYNC +#define IXGBE_SWFW_SYNC_X550EM_a 0x15F78 +#define IXGBE_SWFW_SYNC_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SWFW_SYNC) #define IXGBE_GSSR 0x10160 #define IXGBE_MREVID 0x11064 @@ -1079,6 +1140,10 @@ struct ixgbe_dmac_config { #define IXGBE_GSCL_6_82599 0x11034 #define IXGBE_GSCL_7_82599 0x11038 #define IXGBE_GSCL_8_82599 0x1103C +#define IXGBE_GSCL_5_X540 IXGBE_GSCL_5_82599 +#define IXGBE_GSCL_6_X540 IXGBE_GSCL_6_82599 +#define IXGBE_GSCL_7_X540 IXGBE_GSCL_7_82599 +#define IXGBE_GSCL_8_X540 IXGBE_GSCL_8_82599 #define IXGBE_PHYADR_82599 0x11040 #define IXGBE_PHYDAT_82599 0x11044 #define IXGBE_PHYCTL_82599 0x11048 @@ -1089,10 +1154,24 @@ struct ixgbe_dmac_config { #define IXGBE_CIAD_82599 IXGBE_CIAD #define IXGBE_CIAA_X540 IXGBE_CIAA #define IXGBE_CIAD_X540 IXGBE_CIAD +#define IXGBE_GSCL_5_X550 0x11810 +#define IXGBE_GSCL_6_X550 0x11814 +#define IXGBE_GSCL_7_X550 0x11818 +#define IXGBE_GSCL_8_X550 0x1181C +#define IXGBE_GSCL_5_X550EM_x IXGBE_GSCL_5_X550 +#define IXGBE_GSCL_6_X550EM_x IXGBE_GSCL_6_X550 +#define IXGBE_GSCL_7_X550EM_x IXGBE_GSCL_7_X550 +#define IXGBE_GSCL_8_X550EM_x IXGBE_GSCL_8_X550 #define IXGBE_CIAA_X550 0x11508 #define IXGBE_CIAD_X550 0x11510 #define IXGBE_CIAA_X550EM_x IXGBE_CIAA_X550 #define IXGBE_CIAD_X550EM_x IXGBE_CIAD_X550 +#define IXGBE_GSCL_5_X550EM_a IXGBE_GSCL_5_X550 +#define IXGBE_GSCL_6_X550EM_a IXGBE_GSCL_6_X550 +#define IXGBE_GSCL_7_X550EM_a IXGBE_GSCL_7_X550 +#define IXGBE_GSCL_8_X550EM_a IXGBE_GSCL_8_X550 +#define IXGBE_CIAA_X550EM_a IXGBE_CIAA_X550 +#define IXGBE_CIAD_X550EM_a IXGBE_CIAD_X550 #define IXGBE_CIAA_BY_MAC(_hw) IXGBE_BY_MAC((_hw), CIAA) #define IXGBE_CIAD_BY_MAC(_hw) IXGBE_BY_MAC((_hw), CIAD) #define IXGBE_PICAUSE 0x110B0 @@ -1238,6 +1317,7 @@ struct ixgbe_dmac_config { #define IXGBE_XPCSS 0x04290 #define IXGBE_MFLCN 0x04294 #define IXGBE_SERDESC 0x04298 +#define IXGBE_MAC_SGMII_BUSY 0x04298 #define IXGBE_MACS 0x0429C #define IXGBE_AUTOC 0x042A0 #define IXGBE_LINKS 0x042A4 @@ -1424,6 +1504,7 @@ struct ixgbe_dmac_config { #define IXGBE_CORECTL_WRITE_CMD 0x00010000 /* Device Type definitions for new protocol MDIO commands */ +#define IXGBE_MDIO_ZERO_DEV_TYPE 0x0 #define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1 #define IXGBE_MDIO_PCS_DEV_TYPE 0x3 #define IXGBE_MDIO_PHY_XS_DEV_TYPE 0x4 @@ -1481,7 +1562,7 @@ struct ixgbe_dmac_config { #define IXGBE_MDIO_GLOBAL_ALARM_1 0xCC00 /* Global alarm 1 */ #define IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT 0x0010 /* device fault */ #define IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL 0x4000 /* high temp failure */ -#define IXGBE_MDIO_GLOBAL_FAULT_MSG 0xC850 /* Global Fault Message */ +#define IXGBE_MDIO_GLOBAL_FAULT_MSG 0xC850 /* Global Fault Message */ #define IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP 0x8007 /* high temp failure */ #define IXGBE_MDIO_GLOBAL_INT_MASK 0xD400 /* Global int mask */ #define IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN 0x1000 /* autoneg vendor alarm int enable */ @@ -1489,6 +1570,7 @@ struct ixgbe_dmac_config { #define IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN 0x1 /* vendor alarm int enable */ #define IXGBE_MDIO_GLOBAL_STD_ALM2_INT 0x200 /* vendor alarm2 int mask */ #define IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN 0x4000 /* int high temp enable */ +#define IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN 0x0010 /* int dev fault enable */ #define IXGBE_MDIO_PMA_PMD_CONTROL_ADDR 0x0000 /* PMA/PMD Control Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ @@ -1548,16 +1630,17 @@ struct ixgbe_dmac_config { #define TN1010_PHY_ID 0x00A19410 #define TNX_FW_REV 0xB #define X540_PHY_ID 0x01540200 -#define X550_PHY_ID1 0x01540220 #define X550_PHY_ID2 0x01540223 #define X550_PHY_ID3 0x01540221 #define X557_PHY_ID 0x01540240 +#define X557_PHY_ID2 0x01540250 #define AQ_FW_REV 0x20 #define QT2022_PHY_ID 0x0043A400 #define ATH_PHY_ID 0x03429050 /* PHY Types */ -#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0 +#define IXGBE_M88E1500_E_PHY_ID 0x01410DD0 +#define IXGBE_M88E1543_E_PHY_ID 0x01410EA0 /* Special PHY Init Routine */ #define IXGBE_PHY_INIT_OFFSET_NL 0x002B @@ -1584,6 +1667,9 @@ struct ixgbe_dmac_config { #define IXGBE_SDP0_GPIEN_X550EM_x IXGBE_SDP0_GPIEN_X540 #define IXGBE_SDP1_GPIEN_X550EM_x IXGBE_SDP1_GPIEN_X540 #define IXGBE_SDP2_GPIEN_X550EM_x IXGBE_SDP2_GPIEN_X540 +#define IXGBE_SDP0_GPIEN_X550EM_a IXGBE_SDP0_GPIEN_X540 +#define IXGBE_SDP1_GPIEN_X550EM_a IXGBE_SDP1_GPIEN_X540 +#define IXGBE_SDP2_GPIEN_X550EM_a IXGBE_SDP2_GPIEN_X540 #define IXGBE_SDP0_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP0_GPIEN) #define IXGBE_SDP1_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP1_GPIEN) #define IXGBE_SDP2_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP2_GPIEN) @@ -1669,6 +1755,8 @@ enum { #define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT) /* VMOLR bitmasks */ +#define IXGBE_VMOLR_UPE 0x00400000 /* unicast promiscuous */ +#define IXGBE_VMOLR_VPE 0x00800000 /* VLAN promiscuous */ #define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */ #define IXGBE_VMOLR_ROMPE 0x02000000 /* accept packets in MTA tbl */ #define IXGBE_VMOLR_ROPE 0x04000000 /* accept packets in UC tbl */ @@ -1774,6 +1862,9 @@ enum { #define IXGBE_EICR_GPI_SDP0_X550EM_x IXGBE_EICR_GPI_SDP0_X540 #define IXGBE_EICR_GPI_SDP1_X550EM_x IXGBE_EICR_GPI_SDP1_X540 #define IXGBE_EICR_GPI_SDP2_X550EM_x IXGBE_EICR_GPI_SDP2_X540 +#define IXGBE_EICR_GPI_SDP0_X550EM_a IXGBE_EICR_GPI_SDP0_X540 +#define IXGBE_EICR_GPI_SDP1_X550EM_a IXGBE_EICR_GPI_SDP1_X540 +#define IXGBE_EICR_GPI_SDP2_X550EM_a IXGBE_EICR_GPI_SDP2_X540 #define IXGBE_EICR_GPI_SDP0_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP0) #define IXGBE_EICR_GPI_SDP1_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP1) #define IXGBE_EICR_GPI_SDP2_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP2) @@ -2104,6 +2195,7 @@ enum { #define IXGBE_LINKS_SPEED_10G_82599 0x30000000 #define IXGBE_LINKS_SPEED_1G_82599 0x20000000 #define IXGBE_LINKS_SPEED_100_82599 0x10000000 +#define IXGBE_LINKS_SPEED_10_X550EM_A 0x00000000 #define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ @@ -2149,6 +2241,7 @@ enum { #define IXGBE_GSSR_FLASH_SM 0x0010 #define IXGBE_GSSR_NVM_UPDATE_SM 0x0200 #define IXGBE_GSSR_SW_MNG_SM 0x0400 +#define IXGBE_GSSR_TOKEN_SM 0x40000000 /* SW bit for shared access */ #define IXGBE_GSSR_SHARED_I2C_SM 0x1806 /* Wait for both phys and both I2Cs */ #define IXGBE_GSSR_I2C_MASK 0x1800 #define IXGBE_GSSR_NVM_PHY_MASK 0xF @@ -2191,6 +2284,9 @@ enum { #define IXGBE_PBANUM_PTR_GUARD 0xFAFA #define IXGBE_EEPROM_CHECKSUM 0x3F #define IXGBE_EEPROM_SUM 0xBABA +#define IXGBE_EEPROM_CTRL_4 0x45 +#define IXGBE_EE_CTRL_4_INST_ID 0x10 +#define IXGBE_EE_CTRL_4_INST_ID_SHIFT 4 #define IXGBE_PCIE_ANALOG_PTR 0x03 #define IXGBE_ATLAS0_CONFIG_PTR 0x04 #define IXGBE_PHY_PTR 0x04 @@ -2218,7 +2314,9 @@ enum { #define IXGBE_SAN_MAC_ADDR_PTR 0x28 #define IXGBE_DEVICE_CAPS 0x2C -#define IXGBE_SERIAL_NUMBER_MAC_ADDR 0x11 +#define IXGBE_82599_SERIAL_NUMBER_MAC_ADDR 0x11 +#define IXGBE_X550_SERIAL_NUMBER_MAC_ADDR 0x04 + #define IXGBE_PCIE_MSIX_82599_CAPS 0x72 #define IXGBE_MAX_MSIX_VECTORS_82599 0x40 #define IXGBE_PCIE_MSIX_82598_CAPS 0x62 @@ -2288,6 +2386,7 @@ enum { #define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3 #define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 #define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 +#define IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR (1 << 7) #define IXGBE_FW_LESM_PARAMETERS_PTR 0x2 #define IXGBE_FW_LESM_STATE_1 0x1 #define IXGBE_FW_LESM_STATE_ENABLED 0x8000 /* LESM Enable bit */ @@ -2491,6 +2590,7 @@ enum { #define IXGBE_MRQC_VMDQRSS64EN 0x0000000B /* VMDq2 64 pools w/ RSS */ #define IXGBE_MRQC_VMDQRT8TCEN 0x0000000C /* VMDq2/RT 16 pool 8 TC */ #define IXGBE_MRQC_VMDQRT4TCEN 0x0000000D /* VMDq2/RT 32 pool 4 TC */ +#define IXGBE_MRQC_L3L4TXSWEN 0x00008000 /* Enable L3/L4 Tx switch */ #define IXGBE_MRQC_RSS_FIELD_MASK 0xFFFF0000 #define IXGBE_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 #define IXGBE_MRQC_RSS_FIELD_IPV4 0x00020000 @@ -2662,6 +2762,7 @@ enum { #define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ #define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ #define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ +#define IXGBE_RXDADV_PKTTYPE_GENEVE 0x00000800 /* GENEVE hdr present */ #define IXGBE_RXDADV_PKTTYPE_VXLAN 0x00000800 /* VXLAN hdr present */ #define IXGBE_RXDADV_PKTTYPE_TUNNEL 0x00010000 /* Tunnel type */ #define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */ @@ -2750,7 +2851,7 @@ enum { #define IXGBE_PVFPSRTYPE(P) (0x0EA00 + (4 * (P))) #define IXGBE_PVFTDBAL(P) (0x06000 + (0x40 * (P))) #define IXGBE_PVFTDBAH(P) (0x06004 + (0x40 * (P))) -#define IXGBE_PVFTTDLEN(P) (0x06008 + (0x40 * (P))) +#define IXGBE_PVFTDLEN(P) (0x06008 + (0x40 * (P))) #define IXGBE_PVFTDH(P) (0x06010 + (0x40 * (P))) #define IXGBE_PVFTDT(P) (0x06018 + (0x40 * (P))) #define IXGBE_PVFTXDCTL(P) (0x06028 + (0x40 * (P))) @@ -2905,6 +3006,7 @@ enum ixgbe_fdir_pballoc_type { #define FW_CEM_UNUSED_VER 0x0 #define FW_CEM_MAX_RETRIES 3 #define FW_CEM_RESP_STATUS_SUCCESS 0x1 +#define FW_CEM_DRIVER_VERSION_SIZE 39 /* +9 would send 48 bytes to fw */ #define FW_READ_SHADOW_RAM_CMD 0x31 #define FW_READ_SHADOW_RAM_LEN 0x6 #define FW_WRITE_SHADOW_RAM_CMD 0x33 @@ -2917,13 +3019,77 @@ enum ixgbe_fdir_pballoc_type { #define FW_DISABLE_RXEN_CMD 0xDE #define FW_DISABLE_RXEN_LEN 0x1 #define FW_PHY_MGMT_REQ_CMD 0x20 +#define FW_PHY_TOKEN_REQ_CMD 0xA +#define FW_PHY_TOKEN_REQ_LEN 2 +#define FW_PHY_TOKEN_REQ 0 +#define FW_PHY_TOKEN_REL 1 +#define FW_PHY_TOKEN_OK 1 +#define FW_PHY_TOKEN_RETRY 0x80 +#define FW_PHY_TOKEN_DELAY 5 /* milliseconds */ +#define FW_PHY_TOKEN_WAIT 5 /* seconds */ +#define FW_PHY_TOKEN_RETRIES ((FW_PHY_TOKEN_WAIT * 1000) / FW_PHY_TOKEN_DELAY) #define FW_INT_PHY_REQ_CMD 0xB #define FW_INT_PHY_REQ_LEN 10 #define FW_INT_PHY_REQ_READ 0 #define FW_INT_PHY_REQ_WRITE 1 +#define FW_PHY_ACT_REQ_CMD 5 +#define FW_PHY_ACT_DATA_COUNT 4 +#define FW_PHY_ACT_REQ_LEN (4 + 4 * FW_PHY_ACT_DATA_COUNT) +#define FW_PHY_ACT_INIT_PHY 1 +#define FW_PHY_ACT_SETUP_LINK 2 +#define FW_PHY_ACT_LINK_SPEED_10 (1u << 0) +#define FW_PHY_ACT_LINK_SPEED_100 (1u << 1) +#define FW_PHY_ACT_LINK_SPEED_1G (1u << 2) +#define FW_PHY_ACT_LINK_SPEED_2_5G (1u << 3) +#define FW_PHY_ACT_LINK_SPEED_5G (1u << 4) +#define FW_PHY_ACT_LINK_SPEED_10G (1u << 5) +#define FW_PHY_ACT_LINK_SPEED_20G (1u << 6) +#define FW_PHY_ACT_LINK_SPEED_25G (1u << 7) +#define FW_PHY_ACT_LINK_SPEED_40G (1u << 8) +#define FW_PHY_ACT_LINK_SPEED_50G (1u << 9) +#define FW_PHY_ACT_LINK_SPEED_100G (1u << 10) +#define FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT 16 +#define FW_PHY_ACT_SETUP_LINK_PAUSE_MASK (3u << \ + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT) +#define FW_PHY_ACT_SETUP_LINK_PAUSE_NONE 0u +#define FW_PHY_ACT_SETUP_LINK_PAUSE_TX 1u +#define FW_PHY_ACT_SETUP_LINK_PAUSE_RX 2u +#define FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX 3u +#define FW_PHY_ACT_SETUP_LINK_LP (1u << 18) +#define FW_PHY_ACT_SETUP_LINK_HP (1u << 19) +#define FW_PHY_ACT_SETUP_LINK_EEE (1u << 20) +#define FW_PHY_ACT_SETUP_LINK_AN (1u << 22) +#define FW_PHY_ACT_SETUP_LINK_RSP_DOWN (1u << 0) +#define FW_PHY_ACT_GET_LINK_INFO 3 +#define FW_PHY_ACT_GET_LINK_INFO_EEE (1u << 19) +#define FW_PHY_ACT_GET_LINK_INFO_FC_TX (1u << 20) +#define FW_PHY_ACT_GET_LINK_INFO_FC_RX (1u << 21) +#define FW_PHY_ACT_GET_LINK_INFO_POWER (1u << 22) +#define FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE (1u << 24) +#define FW_PHY_ACT_GET_LINK_INFO_TEMP (1u << 25) +#define FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX (1u << 28) +#define FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX (1u << 29) +#define FW_PHY_ACT_FORCE_LINK_DOWN 4 +#define FW_PHY_ACT_FORCE_LINK_DOWN_OFF (1u << 0) +#define FW_PHY_ACT_PHY_SW_RESET 5 +#define FW_PHY_ACT_PHY_HW_RESET 6 +#define FW_PHY_ACT_GET_PHY_INFO 7 +#define FW_PHY_ACT_UD_2 0x1002 +#define FW_PHY_ACT_UD_2_10G_KR_EEE (1u << 6) +#define FW_PHY_ACT_UD_2_10G_KX4_EEE (1u << 5) +#define FW_PHY_ACT_UD_2_1G_KX_EEE (1u << 4) +#define FW_PHY_ACT_UD_2_10G_T_EEE (1u << 3) +#define FW_PHY_ACT_UD_2_1G_T_EEE (1u << 2) +#define FW_PHY_ACT_UD_2_100M_TX_EEE (1u << 1) +#define FW_PHY_ACT_RETRIES 50 +#define FW_PHY_INFO_SPEED_MASK 0xFFFu +#define FW_PHY_INFO_ID_HI_MASK 0xFFFF0000u +#define FW_PHY_INFO_ID_LO_MASK 0x0000FFFFu /* Host Interface Command Structures */ +#pragma pack(push, 1) + struct ixgbe_hic_hdr { u8 cmd; u8 buf_len; @@ -2964,6 +3130,16 @@ struct ixgbe_hic_drv_info { u16 pad2; /* end spacing to ensure length is mult. of dword2 */ }; +struct ixgbe_hic_drv_info2 { + struct ixgbe_hic_hdr hdr; + u8 port_num; + u8 ver_sub; + u8 ver_build; + u8 ver_min; + u8 ver_maj; + char driver_string[FW_CEM_DRIVER_VERSION_SIZE]; +}; + /* These need to be dword aligned */ struct ixgbe_hic_read_shadow_ram { union ixgbe_hic_hdr2 hdr; @@ -2990,21 +3166,42 @@ struct ixgbe_hic_disable_rxen { u16 pad3; }; +struct ixgbe_hic_phy_token_req { + struct ixgbe_hic_hdr hdr; + u8 port_number; + u8 command_type; + u16 pad; +}; + struct ixgbe_hic_internal_phy_req { struct ixgbe_hic_hdr hdr; u8 port_number; u8 command_type; - u16 address; + __be16 address; u16 rsv1; - u32 write_data; + __be32 write_data; u16 pad; }; struct ixgbe_hic_internal_phy_resp { struct ixgbe_hic_hdr hdr; - u32 read_data; + __be32 read_data; }; +struct ixgbe_hic_phy_activity_req { + struct ixgbe_hic_hdr hdr; + u8 port_number; + u8 pad; + __le16 activity_id; + __be32 data[FW_PHY_ACT_DATA_COUNT]; +}; + +struct ixgbe_hic_phy_activity_resp { + struct ixgbe_hic_hdr hdr; + __be32 data[FW_PHY_ACT_DATA_COUNT]; +}; + +#pragma pack(pop) /* Transmit Descriptor - Legacy */ struct ixgbe_legacy_tx_desc { @@ -3130,6 +3327,7 @@ struct ixgbe_adv_tx_context_desc { #define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ #define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ #define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */ +#define IXGBE_ADVTXD_TUCMD_L4T_RSV 0x00001800 /* RSV L4 Packet TYPE */ #define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /* req Markers and CRC */ #define IXGBE_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */ #define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */ @@ -3152,12 +3350,14 @@ struct ixgbe_adv_tx_context_desc { #define IXGBE_ADVTXD_TUNNEL_TYPE_SHIFT 16 /* Adv Tx Desc Tunnel Type shift */ #define IXGBE_ADVTXD_OUTERIPCS_SHIFT 17 /* Adv Tx Desc OUTERIPCS Shift */ #define IXGBE_ADVTXD_TUNNEL_TYPE_NVGRE 1 /* Adv Tx Desc Tunnel Type NVGRE */ - +/* Adv Tx Desc OUTERIPCS Shift for X550EM_a */ +#define IXGBE_ADVTXD_OUTERIPCS_SHIFT_X550EM_a 26 /* Autonegotiation advertised speeds */ typedef u32 ixgbe_autoneg_advertised; /* Link speed */ typedef u32 ixgbe_link_speed; #define IXGBE_LINK_SPEED_UNKNOWN 0 +#define IXGBE_LINK_SPEED_10_FULL 0x0002 #define IXGBE_LINK_SPEED_100_FULL 0x0008 #define IXGBE_LINK_SPEED_1GB_FULL 0x0020 #define IXGBE_LINK_SPEED_2_5GB_FULL 0x0400 @@ -3170,23 +3370,25 @@ typedef u32 ixgbe_link_speed; IXGBE_LINK_SPEED_10GB_FULL) /* Physical layer type */ -typedef u32 ixgbe_physical_layer; +typedef u64 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_UNKNOWN 0 -#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001 -#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002 -#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x0004 -#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008 -#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010 -#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020 -#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x0040 -#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x0080 -#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100 -#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200 -#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400 -#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800 -#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000 -#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000 -#define IXGBE_PHYSICAL_LAYER_1000BASE_SX 0x4000 +#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x00001 +#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x00002 +#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x00004 +#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x00008 +#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x00010 +#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x00020 +#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x00040 +#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x00080 +#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x00100 +#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x00200 +#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x00400 +#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x00800 +#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x01000 +#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x02000 +#define IXGBE_PHYSICAL_LAYER_1000BASE_SX 0x04000 +#define IXGBE_PHYSICAL_LAYER_10BASE_T 0x08000 +#define IXGBE_PHYSICAL_LAYER_2500BASE_KX 0x10000 /* Flow Control Data Sheet defined values * Calculation and defines taken from 802.1bb Annex O @@ -3391,8 +3593,10 @@ enum ixgbe_mac_type { ixgbe_mac_X540_vf, ixgbe_mac_X550, ixgbe_mac_X550EM_x, + ixgbe_mac_X550EM_a, ixgbe_mac_X550_vf, ixgbe_mac_X550EM_x_vf, + ixgbe_mac_X550EM_a_vf, ixgbe_num_macs }; @@ -3403,7 +3607,9 @@ enum ixgbe_phy_type { ixgbe_phy_aq, ixgbe_phy_x550em_kr, ixgbe_phy_x550em_kx4, + ixgbe_phy_x550em_xfi, ixgbe_phy_x550em_ext_t, + ixgbe_phy_ext_1g_t, ixgbe_phy_cu_unknown, ixgbe_phy_qt, ixgbe_phy_xaui, @@ -3421,6 +3627,8 @@ enum ixgbe_phy_type { ixgbe_phy_qsfp_intel, ixgbe_phy_qsfp_unknown, ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/ + ixgbe_phy_sgmii, + ixgbe_phy_fw, ixgbe_phy_generic }; @@ -3536,7 +3744,8 @@ struct ixgbe_bus_info { enum ixgbe_bus_type type; u16 func; - u16 lan_id; + u8 lan_id; + u16 instance_id; }; /* Flow control parameters */ @@ -3658,7 +3867,7 @@ struct ixgbe_mac_operations { s32 (*clear_hw_cntrs)(struct ixgbe_hw *); void (*enable_relaxed_ordering)(struct ixgbe_hw *); enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); - u32 (*get_supported_physical_layer)(struct ixgbe_hw *); + u64 (*get_supported_physical_layer)(struct ixgbe_hw *); s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *); s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *); s32 (*set_san_mac_addr)(struct ixgbe_hw *, u8 *); @@ -3667,6 +3876,7 @@ struct ixgbe_mac_operations { s32 (*get_fcoe_boot_status)(struct ixgbe_hw *, u16 *); s32 (*stop_adapter)(struct ixgbe_hw *); s32 (*get_bus_info)(struct ixgbe_hw *); + s32 (*negotiate_api_version)(struct ixgbe_hw *, int); void (*set_lan_id)(struct ixgbe_hw *); s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*); s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8); @@ -3676,6 +3886,7 @@ struct ixgbe_mac_operations { s32 (*enable_sec_rx_path)(struct ixgbe_hw *); s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u32); void (*release_swfw_sync)(struct ixgbe_hw *, u32); + void (*init_swfw_sync)(struct ixgbe_hw *); s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *); s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool); @@ -3698,6 +3909,7 @@ struct ixgbe_mac_operations { s32 (*led_off)(struct ixgbe_hw *, u32); s32 (*blink_led_start)(struct ixgbe_hw *, u32); s32 (*blink_led_stop)(struct ixgbe_hw *, u32); + s32 (*init_led_link_act)(struct ixgbe_hw *); /* RAR, Multicast, VLAN */ s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32); @@ -3712,11 +3924,14 @@ struct ixgbe_mac_operations { ixgbe_mc_addr_itr); s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32, ixgbe_mc_addr_itr, bool clear); + s32 (*update_xcast_mode)(struct ixgbe_hw *, int); s32 (*enable_mc)(struct ixgbe_hw *); s32 (*disable_mc)(struct ixgbe_hw *); s32 (*clear_vfta)(struct ixgbe_hw *); - s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool); - s32 (*set_vlvf)(struct ixgbe_hw *, u32, u32, bool, bool *); + s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool, bool); + s32 (*set_vlvf)(struct ixgbe_hw *, u32, u32, bool, u32 *, u32, + bool); + s32 (*set_rlpml)(struct ixgbe_hw *, u16); s32 (*init_uta_tables)(struct ixgbe_hw *); void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int); void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int); @@ -3724,9 +3939,15 @@ struct ixgbe_mac_operations { /* Flow Control */ s32 (*fc_enable)(struct ixgbe_hw *); s32 (*setup_fc)(struct ixgbe_hw *); + void (*fc_autoneg)(struct ixgbe_hw *); /* Manageability interface */ - s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8); + s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8, u16, + const char *); + s32 (*bypass_rw) (struct ixgbe_hw *hw, u32 cmd, u32 *status); + bool (*bypass_valid_rd) (u32 in_reg, u32 out_reg); + s32 (*bypass_set) (struct ixgbe_hw *hw, u32 cmd, u32 event, u32 action); + s32 (*bypass_rd_eep) (struct ixgbe_hw *hw, u32 addr, u8 *value); void (*get_rtrup2tc)(struct ixgbe_hw *hw, u8 *map); void (*disable_rx)(struct ixgbe_hw *hw); void (*enable_rx)(struct ixgbe_hw *hw); @@ -3765,22 +3986,30 @@ struct ixgbe_phy_operations { s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); void (*i2c_bus_clear)(struct ixgbe_hw *); - s32 (*read_i2c_combined)(struct ixgbe_hw *, u8 addr, u16 reg, u16 *val); - s32 (*write_i2c_combined)(struct ixgbe_hw *, u8 addr, u16 reg, u16 val); s32 (*check_overtemp)(struct ixgbe_hw *); s32 (*set_phy_power)(struct ixgbe_hw *, bool on); s32 (*enter_lplu)(struct ixgbe_hw *); s32 (*handle_lasi)(struct ixgbe_hw *hw); - s32 (*read_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, - u16 *value); - s32 (*write_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, - u16 value); s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, u8 *value); s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, u8 value); }; +struct ixgbe_link_operations { + s32 (*read_link)(struct ixgbe_hw *, u8 addr, u16 reg, u16 *val); + s32 (*read_link_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, + u16 *val); + s32 (*write_link)(struct ixgbe_hw *, u8 addr, u16 reg, u16 val); + s32 (*write_link_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, + u16 val); +}; + +struct ixgbe_link_info { + struct ixgbe_link_operations ops; + u8 addr; +}; + struct ixgbe_eeprom_info { struct ixgbe_eeprom_operations ops; enum ixgbe_eeprom_type type; @@ -3824,6 +4053,7 @@ struct ixgbe_mac_info { struct ixgbe_dmac_config dmac_config; bool set_lben; u32 max_link_up_time; + u8 led_link_act; }; struct ixgbe_phy_info { @@ -3839,6 +4069,8 @@ struct ixgbe_phy_info { bool reset_disable; ixgbe_autoneg_advertised autoneg_advertised; ixgbe_link_speed speeds_supported; + ixgbe_link_speed eee_speeds_supported; + ixgbe_link_speed eee_speeds_advertised; enum ixgbe_smart_speed smart_speed; bool smart_speed_active; bool multispeed_fiber; @@ -3885,6 +4117,7 @@ struct ixgbe_hw { struct ixgbe_addr_filter_info addr_ctrl; struct ixgbe_fc_info fc; struct ixgbe_phy_info phy; + struct ixgbe_link_info link; struct ixgbe_eeprom_info eeprom; struct ixgbe_bus_info bus; struct ixgbe_mbx_info mbx; @@ -3899,6 +4132,7 @@ struct ixgbe_hw { bool force_full_reset; bool allow_unsupported_sfp; bool wol_enabled; + bool need_crosstalk_fix; }; #define ixgbe_call_func(hw, func, params, error) \ @@ -3940,44 +4174,177 @@ struct ixgbe_hw { #define IXGBE_ERR_INVALID_ARGUMENT -32 #define IXGBE_ERR_HOST_INTERFACE_COMMAND -33 #define IXGBE_ERR_OUT_OF_MEM -34 +#define IXGBE_BYPASS_FW_WRITE_FAILURE -35 #define IXGBE_ERR_FEATURE_NOT_SUPPORTED -36 #define IXGBE_ERR_EEPROM_PROTECTED_REGION -37 #define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38 +#define IXGBE_ERR_FW_RESP_INVALID -39 +#define IXGBE_ERR_TOKEN_RETRY -40 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF +#define BYPASS_PAGE_CTL0 0x00000000 +#define BYPASS_PAGE_CTL1 0x40000000 +#define BYPASS_PAGE_CTL2 0x80000000 +#define BYPASS_PAGE_M 0xc0000000 +#define BYPASS_WE 0x20000000 + +#define BYPASS_AUTO 0x0 +#define BYPASS_NOP 0x0 +#define BYPASS_NORM 0x1 +#define BYPASS_BYPASS 0x2 +#define BYPASS_ISOLATE 0x3 + +#define BYPASS_EVENT_MAIN_ON 0x1 +#define BYPASS_EVENT_AUX_ON 0x2 +#define BYPASS_EVENT_MAIN_OFF 0x3 +#define BYPASS_EVENT_AUX_OFF 0x4 +#define BYPASS_EVENT_WDT_TO 0x5 +#define BYPASS_EVENT_USR 0x6 + +#define BYPASS_MODE_OFF_M 0x00000003 +#define BYPASS_STATUS_OFF_M 0x0000000c +#define BYPASS_AUX_ON_M 0x00000030 +#define BYPASS_MAIN_ON_M 0x000000c0 +#define BYPASS_MAIN_OFF_M 0x00000300 +#define BYPASS_AUX_OFF_M 0x00000c00 +#define BYPASS_WDTIMEOUT_M 0x00003000 +#define BYPASS_WDT_ENABLE_M 0x00004000 +#define BYPASS_WDT_VALUE_M 0x00070000 + +#define BYPASS_MODE_OFF_SHIFT 0 +#define BYPASS_STATUS_OFF_SHIFT 2 +#define BYPASS_AUX_ON_SHIFT 4 +#define BYPASS_MAIN_ON_SHIFT 6 +#define BYPASS_MAIN_OFF_SHIFT 8 +#define BYPASS_AUX_OFF_SHIFT 10 +#define BYPASS_WDTIMEOUT_SHIFT 12 +#define BYPASS_WDT_ENABLE_SHIFT 14 +#define BYPASS_WDT_TIME_SHIFT 16 + +#define BYPASS_WDT_1 0x0 +#define BYPASS_WDT_1_5 0x1 +#define BYPASS_WDT_2 0x2 +#define BYPASS_WDT_3 0x3 +#define BYPASS_WDT_4 0x4 +#define BYPASS_WDT_8 0x5 +#define BYPASS_WDT_16 0x6 +#define BYPASS_WDT_32 0x7 +#define BYPASS_WDT_OFF 0xffff + +#define BYPASS_CTL1_TIME_M 0x01ffffff +#define BYPASS_CTL1_VALID_M 0x02000000 +#define BYPASS_CTL1_OFFTRST_M 0x04000000 +#define BYPASS_CTL1_WDT_PET_M 0x08000000 + +#define BYPASS_CTL1_VALID 0x02000000 +#define BYPASS_CTL1_OFFTRST 0x04000000 +#define BYPASS_CTL1_WDT_PET 0x08000000 + +#define BYPASS_CTL2_DATA_M 0x000000ff +#define BYPASS_CTL2_OFFSET_M 0x0000ff00 +#define BYPASS_CTL2_RW_M 0x00010000 +#define BYPASS_CTL2_HEAD_M 0x0ff00000 + +#define BYPASS_CTL2_OFFSET_SHIFT 8 +#define BYPASS_CTL2_HEAD_SHIFT 20 + +#define BYPASS_CTL2_RW 0x00010000 + +struct ixgbe_bypass_eeprom { + u32 logs; + u32 clear_off; + u8 actions; +}; + +#define BYPASS_MAX_LOGS 43 +#define BYPASS_LOG_SIZE 5 +#define BYPASS_LOG_LINE_SIZE 37 + +#define BYPASS_EEPROM_VER_ADD 0x02 + +#define BYPASS_LOG_TIME_M 0x01ffffff +#define BYPASS_LOG_TIME_VALID_M 0x02000000 +#define BYPASS_LOG_HEAD_M 0x04000000 +#define BYPASS_LOG_CLEAR_M 0x08000000 +#define BYPASS_LOG_EVENT_M 0xf0000000 +#define BYPASS_LOG_ACTION_M 0x03 + +#define BYPASS_LOG_EVENT_SHIFT 28 +#define BYPASS_LOG_CLEAR_SHIFT 24 /* bit offset */ + + #define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4)) #define IXGBE_FUSES0_300MHZ (1 << 5) -#define IXGBE_FUSES0_REV1 (1 << 6) +#define IXGBE_FUSES0_REV_MASK (3 << 6) #define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P) ? 0x8010 : 0x4010) +#define IXGBE_KRM_LINK_S1(P) ((P) ? 0x8200 : 0x4200) #define IXGBE_KRM_LINK_CTRL_1(P) ((P) ? 0x820C : 0x420C) #define IXGBE_KRM_AN_CNTL_1(P) ((P) ? 0x822C : 0x422C) +#define IXGBE_KRM_AN_CNTL_4(P) ((P) ? 0x8238 : 0x4238) +#define IXGBE_KRM_AN_CNTL_8(P) ((P) ? 0x8248 : 0x4248) +#define IXGBE_KRM_PCS_KX_AN(P) ((P) ? 0x9918 : 0x5918) +#define IXGBE_KRM_PCS_KX_AN_LP(P) ((P) ? 0x991C : 0x591C) +#define IXGBE_KRM_SGMII_CTRL(P) ((P) ? 0x82A0 : 0x42A0) +#define IXGBE_KRM_LP_BASE_PAGE_HIGH(P) ((P) ? 0x836C : 0x436C) #define IXGBE_KRM_DSP_TXFFE_STATE_4(P) ((P) ? 0x8634 : 0x4634) #define IXGBE_KRM_DSP_TXFFE_STATE_5(P) ((P) ? 0x8638 : 0x4638) #define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P) ((P) ? 0x8B00 : 0x4B00) #define IXGBE_KRM_PMD_DFX_BURNIN(P) ((P) ? 0x8E00 : 0x4E00) +#define IXGBE_KRM_PMD_FLX_MASK_ST20(P) ((P) ? 0x9054 : 0x5054) #define IXGBE_KRM_TX_COEFF_CTRL_1(P) ((P) ? 0x9520 : 0x5520) #define IXGBE_KRM_RX_ANA_CTL(P) ((P) ? 0x9A00 : 0x5A00) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA ~(0x3 << 20) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR (1u << 20) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_LR (0x2 << 20) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN (1u << 25) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN (1u << 26) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN (1u << 27) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10M ~(0x7 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_100M (1u << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G (0x2 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G (0x3 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN (0x4 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_2_5G (0x7 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK (0x7 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART (1u << 31) + #define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B (1 << 9) #define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS (1 << 11) #define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK (0x7 << 8) #define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G (2 << 8) #define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G (4 << 8) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN (1 << 12) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN (1 << 13) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ (1 << 14) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC (1 << 15) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX (1 << 16) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR (1 << 18) #define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX (1 << 24) #define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR (1 << 26) +#define IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE (1 << 28) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE (1 << 29) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART (1 << 31) #define IXGBE_KRM_AN_CNTL_1_SYM_PAUSE (1 << 28) #define IXGBE_KRM_AN_CNTL_1_ASM_PAUSE (1 << 29) +#define IXGBE_KRM_PCS_KX_AN_SYM_PAUSE (1 << 1) +#define IXGBE_KRM_PCS_KX_AN_ASM_PAUSE (1 << 2) +#define IXGBE_KRM_PCS_KX_AN_LP_SYM_PAUSE (1 << 2) +#define IXGBE_KRM_PCS_KX_AN_LP_ASM_PAUSE (1 << 3) +#define IXGBE_KRM_AN_CNTL_4_ECSR_AN37_OVER_73 (1 << 29) +#define IXGBE_KRM_AN_CNTL_8_LINEAR (1 << 0) +#define IXGBE_KRM_AN_CNTL_8_LIMITING (1 << 1) + +#define IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE (1 << 10) +#define IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE (1 << 11) + +#define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D (1 << 12) +#define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D (1 << 19) #define IXGBE_KRM_DSP_TXFFE_STATE_C0_EN (1 << 6) #define IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN (1 << 15) @@ -4011,6 +4378,18 @@ struct ixgbe_hw { #define IXGBE_SB_IOSF_TARGET_KR_PHY 0 #define IXGBE_NW_MNG_IF_SEL 0x00011178 -#define IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE (1 << 24) +#define IXGBE_NW_MNG_IF_SEL_MDIO_ACT (1u << 1) +#define IXGBE_NW_MNG_IF_SEL_MDIO_IF_MODE (1u << 2) +#define IXGBE_NW_MNG_IF_SEL_EN_SHARED_MDIO (1u << 13) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_10M (1u << 17) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_100M (1u << 18) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_1G (1u << 19) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G (1u << 20) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_10G (1u << 21) +#define IXGBE_NW_MNG_IF_SEL_SGMII_ENABLE (1u << 25) +#define IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE (1 << 24) /* X552 reg field only */ +#define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT 3 +#define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD \ + (0x1F << IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT) #endif /* _IXGBE_TYPE_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_vf.c b/sys/dev/ixgbe/ixgbe_vf.c index 2ce4d32a303b..8e103dcbb965 100644 --- a/sys/dev/ixgbe/ixgbe_vf.c +++ b/sys/dev/ixgbe/ixgbe_vf.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -33,9 +33,7 @@ /*$FreeBSD$*/ -#include "ixgbe_api.h" -#include "ixgbe_type.h" -#include "ixgbe_vf.h" +#include "ixgbe.h" #ifndef IXGBE_VFWRITE_REG #define IXGBE_VFWRITE_REG IXGBE_WRITE_REG @@ -65,6 +63,7 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw) hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf; hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf; hw->mac.ops.get_bus_info = NULL; + hw->mac.ops.negotiate_api_version = ixgbevf_negotiate_api_version; /* Link */ hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf; @@ -76,10 +75,12 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw) hw->mac.ops.set_uc_addr = ixgbevf_set_uc_addr_vf; hw->mac.ops.init_rx_addrs = NULL; hw->mac.ops.update_mc_addr_list = ixgbe_update_mc_addr_list_vf; + hw->mac.ops.update_xcast_mode = ixgbevf_update_xcast_mode; hw->mac.ops.enable_mc = NULL; hw->mac.ops.disable_mc = NULL; hw->mac.ops.clear_vfta = NULL; hw->mac.ops.set_vfta = ixgbe_set_vfta_vf; + hw->mac.ops.set_rlpml = ixgbevf_rlpml_set_vf; hw->mac.max_tx_queues = 1; hw->mac.max_rx_queues = 1; @@ -229,7 +230,9 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_NACK)) return IXGBE_ERR_INVALID_MAC_ADDR; - memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS); + if (msgbuf[0] == (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK)) + memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS); + hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; return ret_val; @@ -321,15 +324,16 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) return vector; } -static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, - u32 *msg, u16 size) +static s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg, + u32 *retmsg, u16 size) { struct ixgbe_mbx_info *mbx = &hw->mbx; - u32 retmsg[IXGBE_VFMAILBOX_SIZE]; s32 retval = mbx->ops.write_posted(hw, msg, size, 0); - if (!retval) - mbx->ops.read_posted(hw, retmsg, size, 0); + if (retval) + return retval; + + return mbx->ops.read_posted(hw, retmsg, size, 0); } /** @@ -343,7 +347,6 @@ static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr) { - struct ixgbe_mbx_info *mbx = &hw->mbx; u32 msgbuf[3]; u8 *msg_addr = (u8 *)(&msgbuf[1]); s32 ret_val; @@ -352,17 +355,16 @@ s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, memset(msgbuf, 0, 12); msgbuf[0] = IXGBE_VF_SET_MAC_ADDR; memcpy(msg_addr, addr, 6); - ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); - - if (!ret_val) - ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); + ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3); msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; /* if nacked the address was rejected, use "perm_addr" */ if (!ret_val && - (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK))) + (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK))) { ixgbe_get_mac_addr_vf(hw, hw->mac.addr); + return IXGBE_ERR_MBX; + } return ret_val; } @@ -415,29 +417,66 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, return mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0); } +/** + * ixgbevf_update_xcast_mode - Update Multicast mode + * @hw: pointer to the HW structure + * @xcast_mode: new multicast mode + * + * Updates the Multicast Mode of VF. + **/ +s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode) +{ + u32 msgbuf[2]; + s32 err; + + switch (hw->api_version) { + case ixgbe_mbox_api_12: + /* New modes were introduced in 1.3 version */ + if (xcast_mode > IXGBEVF_XCAST_MODE_ALLMULTI) + return IXGBE_ERR_FEATURE_NOT_SUPPORTED; + /* Fall through */ + case ixgbe_mbox_api_13: + break; + default: + return IXGBE_ERR_FEATURE_NOT_SUPPORTED; + } + + msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE; + msgbuf[1] = xcast_mode; + + err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2); + if (err) + return err; + + msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; + if (msgbuf[0] == (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_NACK)) + return IXGBE_ERR_FEATURE_NOT_SUPPORTED; + return IXGBE_SUCCESS; +} + /** * ixgbe_set_vfta_vf - Set/Unset vlan filter table address * @hw: pointer to the HW structure * @vlan: 12 bit VLAN ID * @vind: unused by VF drivers * @vlan_on: if TRUE then set bit, else clear bit + * @vlvf_bypass: boolean flag indicating updating default pool is okay + * + * Turn on/off specified VLAN in the VLAN filter table. **/ -s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on) +s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on, bool vlvf_bypass) { - struct ixgbe_mbx_info *mbx = &hw->mbx; u32 msgbuf[2]; s32 ret_val; - UNREFERENCED_1PARAMETER(vind); + UNREFERENCED_2PARAMETER(vind, vlvf_bypass); msgbuf[0] = IXGBE_VF_SET_VLAN; msgbuf[1] = vlan; /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT; - ret_val = mbx->ops.write_posted(hw, msgbuf, 2, 0); - if (!ret_val) - ret_val = mbx->ops.read_posted(hw, msgbuf, 1, 0); - + ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2); if (!ret_val && (msgbuf[0] & IXGBE_VT_MSGTYPE_ACK)) return IXGBE_SUCCESS; @@ -484,8 +523,7 @@ s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) { - struct ixgbe_mbx_info *mbx = &hw->mbx; - u32 msgbuf[3]; + u32 msgbuf[3], msgbuf_chk; u8 *msg_addr = (u8 *)(&msgbuf[1]); s32 ret_val; @@ -498,18 +536,17 @@ s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) */ msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; msgbuf[0] |= IXGBE_VF_SET_MACVLAN; + msgbuf_chk = msgbuf[0]; if (addr) memcpy(msg_addr, addr, 6); - ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); - if (!ret_val) - ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); + ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3); + if (!ret_val) { + msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; - msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; - - if (!ret_val) - if (msgbuf[0] == (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK)) - ret_val = IXGBE_ERR_OUT_OF_MEM; + if (msgbuf[0] == (msgbuf_chk | IXGBE_VT_MSGTYPE_NACK)) + return IXGBE_ERR_OUT_OF_MEM; + } return ret_val; } @@ -579,13 +616,29 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, switch (links_reg & IXGBE_LINKS_SPEED_82599) { case IXGBE_LINKS_SPEED_10G_82599: *speed = IXGBE_LINK_SPEED_10GB_FULL; + if (hw->mac.type >= ixgbe_mac_X550) { + if (links_reg & IXGBE_LINKS_SPEED_NON_STD) + *speed = IXGBE_LINK_SPEED_2_5GB_FULL; + } break; case IXGBE_LINKS_SPEED_1G_82599: *speed = IXGBE_LINK_SPEED_1GB_FULL; break; case IXGBE_LINKS_SPEED_100_82599: *speed = IXGBE_LINK_SPEED_100_FULL; + if (hw->mac.type == ixgbe_mac_X550) { + if (links_reg & IXGBE_LINKS_SPEED_NON_STD) + *speed = IXGBE_LINK_SPEED_5GB_FULL; + } break; + case IXGBE_LINKS_SPEED_10_X550EM_A: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + /* Since Reserved in older MAC's */ + if (hw->mac.type >= ixgbe_mac_X550) + *speed = IXGBE_LINK_SPEED_10_FULL; + break; + default: + *speed = IXGBE_LINK_SPEED_UNKNOWN; } /* if the read failed it could just be a mailbox collision, best wait @@ -622,13 +675,22 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, * @hw: pointer to the HW structure * @max_size: value to assign to max frame size **/ -void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) +s32 ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) { u32 msgbuf[2]; + s32 retval; msgbuf[0] = IXGBE_VF_SET_LPE; msgbuf[1] = max_size; - ixgbevf_write_msg_read_ack(hw, msgbuf, 2); + + retval = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2); + if (retval) + return retval; + if ((msgbuf[0] & IXGBE_VF_SET_LPE) && + (msgbuf[0] & IXGBE_VT_MSGTYPE_NACK)) + return IXGBE_ERR_MBX; + + return 0; } /** @@ -645,11 +707,8 @@ int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) msg[0] = IXGBE_VF_API_NEGOTIATE; msg[1] = api; msg[2] = 0; - err = hw->mbx.ops.write_posted(hw, msg, 3, 0); - - if (!err) - err = hw->mbx.ops.read_posted(hw, msg, 3, 0); + err = ixgbevf_write_msg_read_ack(hw, msg, msg, 3); if (!err) { msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; @@ -674,6 +733,8 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, /* do nothing if API doesn't support ixgbevf_get_queues */ switch (hw->api_version) { case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: break; default: return 0; @@ -682,11 +743,8 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, /* Fetch queue configuration from the PF */ msg[0] = IXGBE_VF_GET_QUEUES; msg[1] = msg[2] = msg[3] = msg[4] = 0; - err = hw->mbx.ops.write_posted(hw, msg, 5, 0); - - if (!err) - err = hw->mbx.ops.read_posted(hw, msg, 5, 0); + err = ixgbevf_write_msg_read_ack(hw, msg, msg, 5); if (!err) { msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; diff --git a/sys/dev/ixgbe/ixgbe_vf.h b/sys/dev/ixgbe/ixgbe_vf.h index edc801367d2f..bae94f9b6a1d 100644 --- a/sys/dev/ixgbe/ixgbe_vf.h +++ b/sys/dev/ixgbe/ixgbe_vf.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,8 +32,8 @@ ******************************************************************************/ /*$FreeBSD$*/ -#ifndef __IXGBE_VF_H__ -#define __IXGBE_VF_H__ +#ifndef _IXGBE_VF_H_ +#define _IXGBE_VF_H_ #define IXGBE_VF_IRQ_CLEAR_MASK 7 #define IXGBE_VF_MAX_TX_QUEUES 8 @@ -115,6 +115,7 @@ struct ixgbevf_hw_stats { u64 saved_reset_vfmprc; }; +s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw); s32 ixgbe_init_hw_vf(struct ixgbe_hw *hw); s32 ixgbe_start_hw_vf(struct ixgbe_hw *hw); s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw); @@ -132,8 +133,10 @@ s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr); s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, ixgbe_mc_addr_itr, bool clear); -s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on); -void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); +s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode); +s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on, bool vlvf_bypass); +s32 ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api); int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, unsigned int *default_tc); diff --git a/sys/dev/ixgbe/ixgbe_x540.c b/sys/dev/ixgbe/ixgbe_x540.c index fd52ebeb8c52..2513f37b22f3 100644 --- a/sys/dev/ixgbe/ixgbe_x540.c +++ b/sys/dev/ixgbe/ixgbe_x540.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -100,6 +100,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic; mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540; mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540; + mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540; mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic; mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic; @@ -122,6 +123,10 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) mac->ops.setup_link = ixgbe_setup_mac_link_X540; mac->ops.setup_rxpba = ixgbe_set_rxpba_generic; mac->ops.check_link = ixgbe_check_mac_link_generic; + mac->ops.bypass_rw = ixgbe_bypass_rw_generic; + mac->ops.bypass_valid_rd = ixgbe_bypass_valid_rd_generic; + mac->ops.bypass_set = ixgbe_bypass_set_generic; + mac->ops.bypass_rd_eep = ixgbe_bypass_rd_eep_generic; mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; @@ -208,6 +213,7 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) { s32 status; u32 ctrl, i; + u32 swfw_mask = hw->phy.phy_semaphore_mask; DEBUGFUNC("ixgbe_reset_hw_X540"); @@ -220,10 +226,17 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) ixgbe_clear_tx_pending(hw); mac_reset_top: + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + return IXGBE_ERR_SWFW_SYNC; + } ctrl = IXGBE_CTRL_RST; ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); IXGBE_WRITE_FLUSH(hw); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); /* Poll for reset bit to self-clear indicating reset is complete */ for (i = 0; i < 10; i++) { @@ -269,12 +282,16 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) /* Add the SAN MAC address to the RAR only if it's a valid address */ if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { - hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, - hw->mac.san_addr, 0, IXGBE_RAH_AV); - /* Save the SAN MAC RAR index */ hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; + hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index, + hw->mac.san_addr, 0, IXGBE_RAH_AV); + + /* clear VMDq pool/queue selection for this RAR */ + hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index, + IXGBE_CLEAR_VMDQ_ALL); + /* Reserve the last RAR for the SAN MAC address */ hw->mac.num_rar_entries--; } @@ -317,9 +334,9 @@ s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) * * Determines physical layer capabilities of the current configuration. **/ -u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) +u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) { - u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; u16 ext_ability = 0; DEBUGFUNC("ixgbe_get_supported_physical_layer_X540"); @@ -487,7 +504,6 @@ s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) u16 length = 0; u16 pointer = 0; u16 word = 0; - u16 checksum_last_word = IXGBE_EEPROM_CHECKSUM; u16 ptr_start = IXGBE_PCIE_ANALOG_PTR; /* Do not use hw->eeprom.ops.read because we do not want to take @@ -497,14 +513,15 @@ s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540"); - /* Include 0x0-0x3F in the checksum */ - for (i = 0; i <= checksum_last_word; i++) { + /* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the + * checksum itself + */ + for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { if (ixgbe_read_eerd_generic(hw, i, &word)) { DEBUGOUT("EEPROM read failed\n"); return IXGBE_ERR_EEPROM; } - if (i != IXGBE_EEPROM_CHECKSUM) - checksum += word; + checksum += word; } /* Include all data from pointers 0x3, 0x6-0xE. This excludes the @@ -771,8 +788,10 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) /* SW NVM semaphore bit is used for access to all * SW_FW_SYNC bits (not just NVM) */ - if (ixgbe_get_swfw_sync_semaphore(hw)) + if (ixgbe_get_swfw_sync_semaphore(hw)) { + DEBUGOUT("Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n"); return IXGBE_ERR_SWFW_SYNC; + } swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); if (!(swfw_sync & (fwmask | swmask | hwmask))) { @@ -780,7 +799,6 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); ixgbe_release_swfw_sync_semaphore(hw); - msec_delay(5); return IXGBE_SUCCESS; } /* Firmware currently using resource (fwmask), hardware @@ -791,20 +809,15 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) msec_delay(5); } - /* Failed to get SW only semaphore */ - if (swmask == IXGBE_GSSR_SW_MNG_SM) { - ERROR_REPORT1(IXGBE_ERROR_POLLING, - "Failed to get SW only semaphore"); - return IXGBE_ERR_SWFW_SYNC; - } - /* If the resource is not released by the FW/HW the SW can assume that * the FW/HW malfunctions. In that case the SW should set the SW bit(s) * of the requested resource(s) while ignoring the corresponding FW/HW * bits in the SW_FW_SYNC register. */ - if (ixgbe_get_swfw_sync_semaphore(hw)) + if (ixgbe_get_swfw_sync_semaphore(hw)) { + DEBUGOUT("Failed to get NVM sempahore and register semaphore while forcefully ignoring FW sempahore bit(s) and setting SW semaphore bit(s), returning IXGBE_ERR_SWFW_SYNC\n"); return IXGBE_ERR_SWFW_SYNC; + } swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); if (swfw_sync & (fwmask | hwmask)) { swfw_sync |= swmask; @@ -820,15 +833,18 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) */ if (swfw_sync & swmask) { u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM | - IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM; + IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM | + IXGBE_GSSR_SW_MNG_SM; if (swi2c_mask) rmask |= IXGBE_GSSR_I2C_MASK; ixgbe_release_swfw_sync_X540(hw, rmask); ixgbe_release_swfw_sync_semaphore(hw); + DEBUGOUT("Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n"); return IXGBE_ERR_SWFW_SYNC; } ixgbe_release_swfw_sync_semaphore(hw); + DEBUGOUT("Returning error IXGBE_ERR_SWFW_SYNC\n"); return IXGBE_ERR_SWFW_SYNC; } @@ -857,7 +873,7 @@ void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); ixgbe_release_swfw_sync_semaphore(hw); - msec_delay(5); + msec_delay(2); } /** @@ -943,6 +959,36 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) IXGBE_WRITE_FLUSH(hw); } +/** + * ixgbe_init_swfw_sync_X540 - Release hardware semaphore + * @hw: pointer to hardware structure + * + * This function reset hardware semaphore bits for a semaphore that may + * have be left locked due to a catastrophic failure. + **/ +void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw) +{ + u32 rmask; + + /* First try to grab the semaphore but we don't need to bother + * looking to see whether we got the lock or not since we do + * the same thing regardless of whether we got the lock or not. + * We got the lock - we release it. + * We timeout trying to get the lock - we force its release. + */ + ixgbe_get_swfw_sync_semaphore(hw); + ixgbe_release_swfw_sync_semaphore(hw); + + /* Acquire and release all software resources. */ + rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM | + IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM | + IXGBE_GSSR_SW_MNG_SM; + + rmask |= IXGBE_GSSR_I2C_MASK; + ixgbe_acquire_swfw_sync_X540(hw, rmask); + ixgbe_release_swfw_sync_X540(hw, rmask); +} + /** * ixgbe_blink_led_start_X540 - Blink LED based on index. * @hw: pointer to hardware structure @@ -960,6 +1006,9 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) DEBUGFUNC("ixgbe_blink_led_start_X540"); + if (index > 3) + return IXGBE_ERR_PARAM; + /* * Link should be up in order for the blink bit in the LED control * register to work. Force link and speed in the MAC if link is down. @@ -994,6 +1043,9 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) u32 macc_reg; u32 ledctl_reg; + if (index > 3) + return IXGBE_ERR_PARAM; + DEBUGFUNC("ixgbe_blink_led_stop_X540"); /* Restore the LED to its default value. */ diff --git a/sys/dev/ixgbe/ixgbe_x540.h b/sys/dev/ixgbe/ixgbe_x540.h index efd0d41f417f..7c3514032ab1 100644 --- a/sys/dev/ixgbe/ixgbe_x540.h +++ b/sys/dev/ixgbe/ixgbe_x540.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -44,7 +44,7 @@ s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool link_up_wait_to_complete); s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw); s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw); -u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw); s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw); s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data); @@ -60,6 +60,7 @@ s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); +void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw); s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index); s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index); diff --git a/sys/dev/ixgbe/ixgbe_x550.c b/sys/dev/ixgbe/ixgbe_x550.c index 1199d38f9158..8066964c7f35 100644 --- a/sys/dev/ixgbe/ixgbe_x550.c +++ b/sys/dev/ixgbe/ixgbe_x550.c @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -40,6 +40,9 @@ #include "ixgbe_phy.h" static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed); +static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask); +static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask); +static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw); /** * ixgbe_init_ops_X550 - Inits func ptrs and MAC type @@ -60,7 +63,7 @@ s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw) mac->ops.dmac_config = ixgbe_dmac_config_X550; mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550; mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550; - mac->ops.setup_eee = ixgbe_setup_eee_X550; + mac->ops.setup_eee = NULL; mac->ops.set_source_address_pruning = ixgbe_set_source_address_pruning_X550; mac->ops.set_ethertype_anti_spoofing = @@ -81,9 +84,20 @@ s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw) mac->ops.mdd_event = ixgbe_mdd_event_X550; mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550; mac->ops.disable_rx = ixgbe_disable_rx_x550; - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) { + /* Manageability interface */ + mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_x550; + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_1G_T: + hw->mac.ops.led_on = NULL; + hw->mac.ops.led_off = NULL; + break; + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: hw->mac.ops.led_on = ixgbe_led_on_t_X550em; hw->mac.ops.led_off = ixgbe_led_off_t_X550em; + break; + default: + break; } return ret_val; } @@ -98,7 +112,7 @@ s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw) **/ static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value) { - return ixgbe_read_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, value); + return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value); } /** @@ -111,7 +125,7 @@ static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value) **/ static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value) { - return ixgbe_write_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, value); + return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value); } /** @@ -322,6 +336,98 @@ static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw) IXGBE_WRITE_FLUSH(hw); } +/** + * ixgbe_read_phy_reg_mdi_22 - Read from a clause 22 PHY register without lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @dev_type: always unused + * @phy_data: Pointer to read data from PHY register + */ +static s32 ixgbe_read_phy_reg_mdi_22(struct ixgbe_hw *hw, u32 reg_addr, + u32 dev_type, u16 *phy_data) +{ + u32 i, data, command; + UNREFERENCED_1PARAMETER(dev_type); + + /* Setup and write the read command */ + command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_READ_AUTOINC | + IXGBE_MSCA_MDI_COMMAND; + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* Check every 10 usec to see if the access completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if (!(command & IXGBE_MSCA_MDI_COMMAND)) + break; + } + + if (command & IXGBE_MSCA_MDI_COMMAND) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "PHY read command did not complete.\n"); + return IXGBE_ERR_PHY; + } + + /* Read operation is complete. Get the data from MSRWD */ + data = IXGBE_READ_REG(hw, IXGBE_MSRWD); + data >>= IXGBE_MSRWD_READ_DATA_SHIFT; + *phy_data = (u16)data; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_phy_reg_mdi_22 - Write to a clause 22 PHY register without lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @dev_type: always unused + * @phy_data: Data to write to the PHY register + */ +static s32 ixgbe_write_phy_reg_mdi_22(struct ixgbe_hw *hw, u32 reg_addr, + u32 dev_type, u16 phy_data) +{ + u32 i, command; + UNREFERENCED_1PARAMETER(dev_type); + + /* Put the data in the MDI single read and write data register*/ + IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data); + + /* Setup and write the write command */ + command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_WRITE | + IXGBE_MSCA_MDI_COMMAND; + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* Check every 10 usec to see if the access completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if (!(command & IXGBE_MSCA_MDI_COMMAND)) + break; + } + + if (command & IXGBE_MSCA_MDI_COMMAND) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "PHY write cmd didn't complete\n"); + return IXGBE_ERR_PHY; + } + + return IXGBE_SUCCESS; +} + /** * ixgbe_identify_phy_x550em - Get PHY type based on device id * @hw: pointer to hardware structure @@ -330,30 +436,184 @@ static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw) */ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) { + hw->mac.ops.set_lan_id(hw); + + ixgbe_read_mng_if_sel_x550em(hw); + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_SFP: + return ixgbe_identify_module_generic(hw); case IXGBE_DEV_ID_X550EM_X_SFP: /* set up for CS4227 usage */ - hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; ixgbe_setup_mux_ctl(hw); ixgbe_check_cs4227(hw); + /* Fallthrough */ + case IXGBE_DEV_ID_X550EM_A_SFP_N: return ixgbe_identify_module_generic(hw); break; case IXGBE_DEV_ID_X550EM_X_KX4: hw->phy.type = ixgbe_phy_x550em_kx4; break; + case IXGBE_DEV_ID_X550EM_X_XFI: + hw->phy.type = ixgbe_phy_x550em_xfi; + break; case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: hw->phy.type = ixgbe_phy_x550em_kr; break; - case IXGBE_DEV_ID_X550EM_X_1G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: case IXGBE_DEV_ID_X550EM_X_10G_T: return ixgbe_identify_phy_generic(hw); + case IXGBE_DEV_ID_X550EM_X_1G_T: + hw->phy.type = ixgbe_phy_ext_1g_t; + hw->phy.ops.read_reg = NULL; + hw->phy.ops.write_reg = NULL; + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + hw->phy.type = ixgbe_phy_fw; + hw->phy.ops.read_reg = NULL; + hw->phy.ops.write_reg = NULL; + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; + break; default: break; } return IXGBE_SUCCESS; } +/** + * ixgbe_fw_phy_activity - Perform an activity on a PHY + * @hw: pointer to hardware structure + * @activity: activity to perform + * @data: Pointer to 4 32-bit words of data + */ +s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity, + u32 (*data)[FW_PHY_ACT_DATA_COUNT]) +{ + union { + struct ixgbe_hic_phy_activity_req cmd; + struct ixgbe_hic_phy_activity_resp rsp; + } hic; + u16 retries = FW_PHY_ACT_RETRIES; + s32 rc; + u16 i; + + do { + memset(&hic, 0, sizeof(hic)); + hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD; + hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN; + hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + hic.cmd.port_number = hw->bus.lan_id; + hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity); + for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i) + hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]); + + rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd, + sizeof(hic.cmd), + IXGBE_HI_COMMAND_TIMEOUT, + TRUE); + if (rc != IXGBE_SUCCESS) + return rc; + if (hic.rsp.hdr.cmd_or_resp.ret_status == + FW_CEM_RESP_STATUS_SUCCESS) { + for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i) + (*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]); + return IXGBE_SUCCESS; + } + usec_delay(20); + --retries; + } while (retries > 0); + + return IXGBE_ERR_HOST_INTERFACE_COMMAND; +} + +static const struct { + u16 fw_speed; + ixgbe_link_speed phy_speed; +} ixgbe_fw_map[] = { + { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL }, + { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL }, + { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL }, + { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL }, + { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL }, + { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL }, +}; + +/** + * ixgbe_get_phy_id_fw - Get the phy ID via firmware command + * @hw: pointer to hardware structure + * + * Returns error code + */ +static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw) +{ + u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; + u16 phy_speeds; + u16 phy_id_lo; + s32 rc; + u16 i; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info); + if (rc) + return rc; + + hw->phy.speeds_supported = 0; + phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK; + for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) { + if (phy_speeds & ixgbe_fw_map[i].fw_speed) + hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed; + } + if (!hw->phy.autoneg_advertised) + hw->phy.autoneg_advertised = hw->phy.speeds_supported; + + hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK; + phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK; + hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK; + hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK; + if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK) + return IXGBE_ERR_PHY_ADDR_INVALID; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_identify_phy_fw - Get PHY type based on firmware command + * @hw: pointer to hardware structure + * + * Returns error code + */ +static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw) +{ + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; + + hw->phy.type = ixgbe_phy_fw; + hw->phy.ops.read_reg = NULL; + hw->phy.ops.write_reg = NULL; + return ixgbe_get_phy_id_fw(hw); +} + +/** + * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY + * @hw: pointer to hardware structure + * + * Returns error code + */ +s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw) +{ + u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; + + setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF; + return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup); +} + static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data) { @@ -368,6 +628,68 @@ static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, return IXGBE_NOT_IMPLEMENTED; } +/** + * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to read from + * @reg: I2C device register to read from + * @val: pointer to location to receive read value + * + * Returns an error code on error. + **/ +static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, + u16 reg, u16 *val) +{ + return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE); +} + +/** + * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to read from + * @reg: I2C device register to read from + * @val: pointer to location to receive read value + * + * Returns an error code on error. + **/ +static s32 +ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, + u16 reg, u16 *val) +{ + return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE); +} + +/** + * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to write to + * @reg: I2C device register to write to + * @val: value to write + * + * Returns an error code on error. + **/ +static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, + u8 addr, u16 reg, u16 val) +{ + return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE); +} + +/** + * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to write to + * @reg: I2C device register to write to + * @val: value to write + * + * Returns an error code on error. + **/ +static s32 +ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, + u8 addr, u16 reg, u16 val) +{ + return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE); +} + /** * ixgbe_init_ops_X550EM - Inits func ptrs and MAC type * @hw: pointer to hardware structure @@ -393,6 +715,12 @@ s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw) * the values being set in the x540 function. */ + /* Bypass not supported in x550EM */ + mac->ops.bypass_rw = NULL; + mac->ops.bypass_valid_rd = NULL; + mac->ops.bypass_set = NULL; + mac->ops.bypass_rd_eep = NULL; + /* FCOE not supported in x550EM */ mac->ops.get_san_mac_addr = NULL; mac->ops.set_san_mac_addr = NULL; @@ -411,10 +739,6 @@ s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw) hw->bus.type = ixgbe_bus_type_internal; mac->ops.get_bus_info = ixgbe_get_bus_info_X550em; - if (hw->mac.type == ixgbe_mac_X550EM_x) { - mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550; - mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550; - } mac->ops.get_media_type = ixgbe_get_media_type_X550em; mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em; @@ -428,15 +752,25 @@ s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw) else mac->ops.setup_fc = ixgbe_setup_fc_X550em; - mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em; - mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em; - - if (hw->device_id != IXGBE_DEV_ID_X550EM_X_KR) - mac->ops.setup_eee = NULL; - /* PHY */ phy->ops.init = ixgbe_init_phy_ops_X550em; - phy->ops.identify = ixgbe_identify_phy_x550em; + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + mac->ops.setup_fc = NULL; + phy->ops.identify = ixgbe_identify_phy_fw; + phy->ops.set_phy_power = NULL; + phy->ops.get_firmware_version = NULL; + break; + case IXGBE_DEV_ID_X550EM_X_1G_T: + mac->ops.setup_fc = NULL; + phy->ops.identify = ixgbe_identify_phy_x550em; + phy->ops.set_phy_power = NULL; + break; + default: + phy->ops.identify = ixgbe_identify_phy_x550em; + } + if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper) phy->ops.set_phy_power = NULL; @@ -454,6 +788,188 @@ s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw) return ret_val; } +/** + * ixgbe_setup_fw_link - Setup firmware-controlled PHYs + * @hw: pointer to hardware structure + */ +static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw) +{ + u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; + s32 rc; + u16 i; + + if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) + return 0; + + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + return IXGBE_ERR_INVALID_LINK_SETTINGS; + } + + switch (hw->fc.requested_mode) { + case ixgbe_fc_full: + setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX << + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; + break; + case ixgbe_fc_rx_pause: + setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX << + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; + break; + case ixgbe_fc_tx_pause: + setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX << + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; + break; + default: + break; + } + + for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) { + if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed) + setup[0] |= ixgbe_fw_map[i].fw_speed; + } + setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN; + + if (hw->phy.eee_speeds_advertised) + setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup); + if (rc) + return rc; + if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN) + return IXGBE_ERR_OVERTEMP; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + */ +static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw) +{ + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + return ixgbe_setup_fw_link(hw); +} + +/** + * ixgbe_setup_eee_fw - Enable/disable EEE support + * @hw: pointer to the HW structure + * @enable_eee: boolean flag to enable EEE + * + * Enable/disable EEE based on enable_eee flag. + * This function controls EEE for firmware-based PHY implementations. + */ +static s32 ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee) +{ + if (!!hw->phy.eee_speeds_advertised == enable_eee) + return IXGBE_SUCCESS; + if (enable_eee) + hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported; + else + hw->phy.eee_speeds_advertised = 0; + return hw->phy.ops.setup_link(hw); +} + +/** +* ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type +* @hw: pointer to hardware structure +* +* Initialize the function pointers and for MAC type X550EM_a. +* Does not touch the hardware. +**/ +s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550EM_a"); + + /* Start with generic X550EM init */ + ret_val = ixgbe_init_ops_X550EM(hw); + + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII || + hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) { + mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550; + mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550; + } else { + mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a; + mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a; + } + mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a; + mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a; + + switch (mac->ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + mac->ops.setup_fc = NULL; + mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a; + break; + case ixgbe_media_type_backplane: + mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a; + mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a; + break; + default: + break; + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a; + mac->ops.setup_fc = ixgbe_fc_autoneg_fw; + mac->ops.setup_eee = ixgbe_setup_eee_fw; + hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported; + break; + default: + break; + } + + return ret_val; +} + +/** +* ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type +* @hw: pointer to hardware structure +* +* Initialize the function pointers and for MAC type X550EM_x. +* Does not touch the hardware. +**/ +s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_link_info *link = &hw->link; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550EM_x"); + + /* Start with generic X550EM init */ + ret_val = ixgbe_init_ops_X550EM(hw); + + mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550; + mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550; + mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em; + mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em; + link->ops.read_link = ixgbe_read_i2c_combined_generic; + link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked; + link->ops.write_link = ixgbe_write_i2c_combined_generic; + link->ops.write_link_unlocked = + ixgbe_write_i2c_combined_generic_unlocked; + link->addr = IXGBE_CS4227; + + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) { + mac->ops.setup_fc = NULL; + mac->ops.setup_eee = NULL; + mac->ops.init_led_link_act = NULL; + } + + return ret_val; +} + /** * ixgbe_dmac_config_X550 * @hw: pointer to hardware structure @@ -517,6 +1033,7 @@ s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw) /* Configure DMA coalescing enabled */ switch (hw->mac.dmac_config.link_speed) { + case IXGBE_LINK_SPEED_10_FULL: case IXGBE_LINK_SPEED_100_FULL: pb_headroom = IXGBE_DMACRXT_100M; break; @@ -616,105 +1133,6 @@ s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw) return IXGBE_SUCCESS; } -/** - * ixgbe_setup_eee_X550 - Enable/disable EEE support - * @hw: pointer to the HW structure - * @enable_eee: boolean flag to enable EEE - * - * Enable/disable EEE based on enable_eee flag. - * Auto-negotiation must be started after BASE-T EEE bits in PHY register 7.3C - * are modified. - * - **/ -s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee) -{ - u32 eeer; - u16 autoneg_eee_reg; - u32 link_reg; - s32 status; - u32 fuse; - - DEBUGFUNC("ixgbe_setup_eee_X550"); - - eeer = IXGBE_READ_REG(hw, IXGBE_EEER); - /* Enable or disable EEE per flag */ - if (enable_eee) { - eeer |= (IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN); - - if (hw->mac.type == ixgbe_mac_X550) { - /* Advertise EEE capability */ - hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg); - - autoneg_eee_reg |= (IXGBE_AUTO_NEG_10GBASE_EEE_ADVT | - IXGBE_AUTO_NEG_1000BASE_EEE_ADVT | - IXGBE_AUTO_NEG_100BASE_EEE_ADVT); - - hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg); - } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) { - /* Not supported on first revision. */ - fuse = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)); - if (!(fuse & IXGBE_FUSES0_REV1)) - return IXGBE_SUCCESS; - - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg); - if (status != IXGBE_SUCCESS) - return status; - - link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR | - IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX; - - /* Don't advertise FEC capability when EEE enabled. */ - link_reg &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC; - - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg); - if (status != IXGBE_SUCCESS) - return status; - } - } else { - eeer &= ~(IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN); - - if (hw->mac.type == ixgbe_mac_X550) { - /* Disable advertised EEE capability */ - hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg); - - autoneg_eee_reg &= ~(IXGBE_AUTO_NEG_10GBASE_EEE_ADVT | - IXGBE_AUTO_NEG_1000BASE_EEE_ADVT | - IXGBE_AUTO_NEG_100BASE_EEE_ADVT); - - hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg); - } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) { - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg); - if (status != IXGBE_SUCCESS) - return status; - - link_reg &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR | - IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX); - - /* Advertise FEC capability when EEE is disabled. */ - link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC; - - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg); - if (status != IXGBE_SUCCESS) - return status; - } - } - IXGBE_WRITE_REG(hw, IXGBE_EEER, eeer); - - return IXGBE_SUCCESS; -} - /** * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning * @hw: pointer to hardware structure @@ -801,8 +1219,8 @@ static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl) } /** - * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF - * device + * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register + * of the IOSF device * @hw: pointer to hardware structure * @reg_addr: 32 bit PHY register to write * @device_type: 3 bit device type @@ -848,12 +1266,11 @@ s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, } /** - * ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF - * device + * ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device * @hw: pointer to hardware structure * @reg_addr: 32 bit PHY register to write * @device_type: 3 bit device type - * @phy_data: Pointer to read data from the register + * @data: Pointer to read data from the register **/ s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u32 *data) @@ -894,6 +1311,140 @@ s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, return ret; } +/** + * ixgbe_get_phy_token - Get the token for shared phy access + * @hw: Pointer to hardware structure + */ + +s32 ixgbe_get_phy_token(struct ixgbe_hw *hw) +{ + struct ixgbe_hic_phy_token_req token_cmd; + s32 status; + + token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD; + token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN; + token_cmd.hdr.cmd_or_resp.cmd_resv = 0; + token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + token_cmd.port_number = hw->bus.lan_id; + token_cmd.command_type = FW_PHY_TOKEN_REQ; + token_cmd.pad = 0; + status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd, + sizeof(token_cmd), + IXGBE_HI_COMMAND_TIMEOUT, + TRUE); + if (status) { + DEBUGOUT1("Issuing host interface command failed with Status = %d\n", + status); + return status; + } + if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) + return IXGBE_SUCCESS; + if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) { + DEBUGOUT1("Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n", + token_cmd.hdr.cmd_or_resp.ret_status); + return IXGBE_ERR_FW_RESP_INVALID; + } + + DEBUGOUT("Returning IXGBE_ERR_TOKEN_RETRY\n"); + return IXGBE_ERR_TOKEN_RETRY; +} + +/** + * ixgbe_put_phy_token - Put the token for shared phy access + * @hw: Pointer to hardware structure + */ + +s32 ixgbe_put_phy_token(struct ixgbe_hw *hw) +{ + struct ixgbe_hic_phy_token_req token_cmd; + s32 status; + + token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD; + token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN; + token_cmd.hdr.cmd_or_resp.cmd_resv = 0; + token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + token_cmd.port_number = hw->bus.lan_id; + token_cmd.command_type = FW_PHY_TOKEN_REL; + token_cmd.pad = 0; + status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd, + sizeof(token_cmd), + IXGBE_HI_COMMAND_TIMEOUT, + TRUE); + if (status) + return status; + if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) + return IXGBE_SUCCESS; + + DEBUGOUT("Put PHY Token host interface command failed"); + return IXGBE_ERR_FW_RESP_INVALID; +} + +/** + * ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register + * of the IOSF device + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 3 bit device type + * @data: Data to write to the register + **/ +s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 data) +{ + struct ixgbe_hic_internal_phy_req write_cmd; + s32 status; + UNREFERENCED_1PARAMETER(device_type); + + memset(&write_cmd, 0, sizeof(write_cmd)); + write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD; + write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN; + write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + write_cmd.port_number = hw->bus.lan_id; + write_cmd.command_type = FW_INT_PHY_REQ_WRITE; + write_cmd.address = IXGBE_CPU_TO_BE16(reg_addr); + write_cmd.write_data = IXGBE_CPU_TO_BE32(data); + + status = ixgbe_host_interface_command(hw, (u32 *)&write_cmd, + sizeof(write_cmd), + IXGBE_HI_COMMAND_TIMEOUT, FALSE); + + return status; +} + +/** + * ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 3 bit device type + * @data: Pointer to read data from the register + **/ +s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *data) +{ + union { + struct ixgbe_hic_internal_phy_req cmd; + struct ixgbe_hic_internal_phy_resp rsp; + } hic; + s32 status; + UNREFERENCED_1PARAMETER(device_type); + + memset(&hic, 0, sizeof(hic)); + hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD; + hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN; + hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + hic.cmd.port_number = hw->bus.lan_id; + hic.cmd.command_type = FW_INT_PHY_REQ_READ; + hic.cmd.address = IXGBE_CPU_TO_BE16(reg_addr); + + status = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd, + sizeof(hic.cmd), + IXGBE_HI_COMMAND_TIMEOUT, TRUE); + + /* Extract the register value from the response. */ + *data = IXGBE_BE32_TO_CPU(hic.rsp.read_data); + + return status; +} + /** * ixgbe_disable_mdd_X550 * @hw: pointer to hardware structure @@ -965,7 +1516,7 @@ void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf) num_qs = 4; /* 32 VFs / pools */ bitmask = 0x0000000F; break; - default: /* 64 VFs / pools */ + default: /* 64 VFs / pools */ num_qs = 2; bitmask = 0x00000003; break; @@ -1053,13 +1604,30 @@ enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) switch (hw->device_id) { case IXGBE_DEV_ID_X550EM_X_KR: case IXGBE_DEV_ID_X550EM_X_KX4: + case IXGBE_DEV_ID_X550EM_X_XFI: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: media_type = ixgbe_media_type_backplane; break; case IXGBE_DEV_ID_X550EM_X_SFP: + case IXGBE_DEV_ID_X550EM_A_SFP: + case IXGBE_DEV_ID_X550EM_A_SFP_N: + case IXGBE_DEV_ID_X550EM_A_QSFP: + case IXGBE_DEV_ID_X550EM_A_QSFP_N: media_type = ixgbe_media_type_fiber; break; case IXGBE_DEV_ID_X550EM_X_1G_T: case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: + media_type = ixgbe_media_type_copper; + break; + case IXGBE_DEV_ID_X550EM_A_SGMII: + case IXGBE_DEV_ID_X550EM_A_SGMII_L: + media_type = ixgbe_media_type_backplane; + hw->phy.type = ixgbe_phy_sgmii; + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: media_type = ixgbe_media_type_copper; break; default: @@ -1152,6 +1720,191 @@ s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw) return IXGBE_SUCCESS; } +/** +* ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the +* internal PHY +* @hw: pointer to hardware structure +**/ +static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u32 link_ctrl; + + /* Restart auto-negotiation. */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl); + + if (status) { + DEBUGOUT("Auto-negotiation did not complete\n"); + return status; + } + + link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl); + + if (hw->mac.type == ixgbe_mac_X550EM_a) { + u32 flx_mask_st20; + + /* Indicate to FW that AN restart has been asserted */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20); + + if (status) { + DEBUGOUT("Auto-negotiation did not complete\n"); + return status; + } + + flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20); + } + + return status; +} + +/** + * ixgbe_setup_sgmii - Set up link for sgmii + * @hw: pointer to hardware structure + */ +static s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait) +{ + struct ixgbe_mac_info *mac = &hw->mac; + u32 lval, sval, flx_val; + s32 rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &lval); + if (rc) + return rc; + + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, lval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &sval); + if (rc) + return rc; + + sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D; + sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, sval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); + if (rc) + return rc; + + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); + if (rc) + return rc; + + rc = ixgbe_restart_an_internal_phy_x550em(hw); + if (rc) + return rc; + + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); +} + +/** + * ixgbe_setup_sgmii_fw - Set up link for sgmii with firmware-controlled PHYs + * @hw: pointer to hardware structure + */ +static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait) +{ + struct ixgbe_mac_info *mac = &hw->mac; + u32 lval, sval, flx_val; + s32 rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &lval); + if (rc) + return rc; + + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN; + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, lval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &sval); + if (rc) + return rc; + + sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D; + sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, sval); + if (rc) + return rc; + + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, lval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); + if (rc) + return rc; + + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); + if (rc) + return rc; + + rc = ixgbe_restart_an_internal_phy_x550em(hw); + + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); +} + /** * ixgbe_init_mac_link_ops_X550em - init mac link function pointers * @hw: pointer to hardware structure @@ -1162,8 +1915,8 @@ void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) DEBUGFUNC("ixgbe_init_mac_link_ops_X550em"); - switch (hw->mac.ops.get_media_type(hw)) { - case ixgbe_media_type_fiber: + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: /* CS4227 does not support autoneg, so disable the laser control * functions for SFP+ fiber */ @@ -1171,17 +1924,43 @@ void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) mac->ops.enable_tx_laser = NULL; mac->ops.flap_tx_laser = NULL; mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber; - mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em; mac->ops.set_rate_select_speed = ixgbe_set_soft_rate_select_speed; + + if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) || + (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP)) + mac->ops.setup_mac_link = + ixgbe_setup_mac_link_sfp_x550a; + else + mac->ops.setup_mac_link = + ixgbe_setup_mac_link_sfp_x550em; break; case ixgbe_media_type_copper: - mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; - mac->ops.check_link = ixgbe_check_link_t_X550em; + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) + break; + if (hw->mac.type == ixgbe_mac_X550EM_a) { + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || + hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) { + mac->ops.setup_link = ixgbe_setup_sgmii_fw; + mac->ops.check_link = + ixgbe_check_mac_link_generic; + } else { + mac->ops.setup_link = + ixgbe_setup_mac_link_t_X550em; + } + } else { + mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; + mac->ops.check_link = ixgbe_check_link_t_X550em; + } + break; + case ixgbe_media_type_backplane: + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII || + hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) + mac->ops.setup_link = ixgbe_setup_sgmii; break; default: break; - } + } } /** @@ -1196,6 +1975,13 @@ s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, { DEBUGFUNC("ixgbe_get_link_capabilities_X550em"); + + if (hw->phy.type == ixgbe_phy_fw) { + *autoneg = TRUE; + *speed = hw->phy.speeds_supported; + return 0; + } + /* SFP */ if (hw->phy.media_type == ixgbe_media_type_fiber) { @@ -1218,8 +2004,30 @@ s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, else *speed = IXGBE_LINK_SPEED_10GB_FULL; } else { - *speed = IXGBE_LINK_SPEED_10GB_FULL | - IXGBE_LINK_SPEED_1GB_FULL; + switch (hw->phy.type) { + case ixgbe_phy_ext_1g_t: + case ixgbe_phy_sgmii: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + case ixgbe_phy_x550em_kr: + if (hw->mac.type == ixgbe_mac_X550EM_a) { + /* check different backplane modes */ + if (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) { + *speed = IXGBE_LINK_SPEED_2_5GB_FULL; + break; + } else if (hw->device_id == + IXGBE_DEV_ID_X550EM_A_KR_L) { + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + } + } + /* fall through */ + default: + *speed = IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + break; + } *autoneg = TRUE; } @@ -1335,21 +2143,34 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); /* Enable link status change alarm */ - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); - if (status != IXGBE_SUCCESS) - return status; + /* Enable the LASI interrupts on X552 devices to receive notifications + * of the link configurations of the external PHY and correspondingly + * support the configuration of the internal iXFI link, since iXFI does + * not support auto-negotiation. This is not required for X553 devices + * having KR support, which performs auto-negotiations and which is used + * as the internal link to the external PHY. Hence adding a check here + * to avoid enabling LASI interrupts for X553 devices. + */ + if (hw->mac.type != ixgbe_mac_X550EM_a) { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); - reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN; + if (status != IXGBE_SUCCESS) + return status; - status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg); + reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN; - if (status != IXGBE_SUCCESS) - return status; + status = hw->phy.ops.write_reg(hw, + IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg); - /* Enables high temperature failure alarm */ + if (status != IXGBE_SUCCESS) + return status; + } + + /* Enable high temperature failure and global fault alarms */ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ®); @@ -1357,7 +2178,8 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) if (status != IXGBE_SUCCESS) return status; - reg |= IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN; + reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN | + IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN); status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, @@ -1414,9 +2236,9 @@ static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw, s32 status; u32 reg_val; - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); if (status) return status; @@ -1432,13 +2254,102 @@ static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw, if (speed & IXGBE_LINK_SPEED_1GB_FULL) reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX; - /* Restart auto-negotiation. */ - reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); - return status; + if (hw->mac.type == ixgbe_mac_X550EM_a) { + /* Set lane mode to KR auto negotiation */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + + if (status) + return status; + + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + } + + return ixgbe_restart_an_internal_phy_x550em(hw); +} + +/** + * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs + * @hw: pointer to hardware structure + */ +static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw) +{ + u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; + s32 rc; + + if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) + return IXGBE_SUCCESS; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store); + if (rc) + return rc; + memset(store, 0, sizeof(store)); + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store); + if (rc) + return rc; + + return ixgbe_setup_fw_link(hw); +} + +/** + * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp + * @hw: pointer to hardware structure + */ +static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) +{ + u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; + s32 rc; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store); + if (rc) + return rc; + + if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) { + ixgbe_shutdown_fw_phy(hw); + return IXGBE_ERR_OVERTEMP; + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register + * @hw: pointer to hardware structure + * + * Read NW_MNG_IF_SEL register and save field values, and check for valid field + * values. + **/ +static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw) +{ + /* Save NW management interface connected on board. This is used + * to determine internal PHY mode. + */ + hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL); + + /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set + * PHY address. This register field was has only been used for X552. + */ + if (hw->mac.type == ixgbe_mac_X550EM_a && + hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) { + hw->phy.addr = (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >> + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT; + } + + return IXGBE_SUCCESS; } /** @@ -1452,31 +2363,54 @@ static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw, s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) { struct ixgbe_phy_info *phy = &hw->phy; - ixgbe_link_speed speed; s32 ret_val; DEBUGFUNC("ixgbe_init_phy_ops_X550em"); hw->mac.ops.set_lan_id(hw); + ixgbe_read_mng_if_sel_x550em(hw); if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) { phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; ixgbe_setup_mux_ctl(hw); - - /* Save NW management interface connected on board. This is used - * to determine internal PHY mode. - */ - phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL); - if (phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) { - speed = IXGBE_LINK_SPEED_10GB_FULL | - IXGBE_LINK_SPEED_1GB_FULL; - } phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em; } + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + phy->ops.read_reg_mdi = ixgbe_read_phy_reg_mdi_22; + phy->ops.write_reg_mdi = ixgbe_write_phy_reg_mdi_22; + hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a; + hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a; + phy->ops.check_overtemp = ixgbe_check_overtemp_fw; + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; + + break; + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_SFP: + hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a; + hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a; + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; + break; + case IXGBE_DEV_ID_X550EM_X_SFP: + /* set up for CS4227 usage */ + hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; + break; + default: + break; + } + /* Identify the PHY or SFP module */ ret_val = phy->ops.identify(hw); - if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED || + ret_val == IXGBE_ERR_PHY_ADDR_INVALID) return ret_val; /* Setup function pointers based on detected hardware */ @@ -1496,38 +2430,78 @@ s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) phy->ops.read_reg = ixgbe_read_phy_reg_x550em; phy->ops.write_reg = ixgbe_write_phy_reg_x550em; break; + case ixgbe_phy_ext_1g_t: + /* link is managed by FW */ + phy->ops.setup_link = NULL; + phy->ops.reset = NULL; + break; + case ixgbe_phy_x550em_xfi: + /* link is managed by HW */ + phy->ops.setup_link = NULL; + phy->ops.read_reg = ixgbe_read_phy_reg_x550em; + phy->ops.write_reg = ixgbe_write_phy_reg_x550em; + break; case ixgbe_phy_x550em_ext_t: - /* Save NW management interface connected on board. This is used - * to determine internal PHY mode - */ - phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL); - /* If internal link mode is XFI, then setup iXFI internal link, * else setup KR now. */ - if (!(phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { - phy->ops.setup_internal_link = + phy->ops.setup_internal_link = ixgbe_setup_internal_phy_t_x550em; - } else { - speed = IXGBE_LINK_SPEED_10GB_FULL | - IXGBE_LINK_SPEED_1GB_FULL; - ret_val = ixgbe_setup_kr_speed_x550em(hw, speed); - } - /* setup SW LPLU only for first revision */ - if (!(IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw, - IXGBE_FUSES0_GROUP(0)))) + /* setup SW LPLU only for first revision of X550EM_x */ + if ((hw->mac.type == ixgbe_mac_X550EM_x) && + !(IXGBE_FUSES0_REV_MASK & + IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))) phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em; phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em; phy->ops.reset = ixgbe_reset_phy_t_X550em; break; + case ixgbe_phy_sgmii: + phy->ops.setup_link = NULL; + break; + case ixgbe_phy_fw: + phy->ops.setup_link = ixgbe_setup_fw_link; + phy->ops.reset = ixgbe_reset_phy_fw; + break; default: break; } return ret_val; } +/** + * ixgbe_set_mdio_speed - Set MDIO clock speed + * @hw: pointer to hardware structure + */ +static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw) +{ + u32 hlreg0; + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_SGMII: + case IXGBE_DEV_ID_X550EM_A_SGMII_L: + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_SFP: + case IXGBE_DEV_ID_X550EM_A_QSFP: + /* Config MDIO clock speed before the first MDIO PHY access */ + hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); + hlreg0 &= ~IXGBE_HLREG0_MDCSPD; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + /* Select fast MDIO clock speed for these devices */ + hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); + hlreg0 |= IXGBE_HLREG0_MDCSPD; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); + break; + default: + break; + } +} + /** * ixgbe_reset_hw_X550em - Perform hardware reset * @hw: pointer to hardware structure @@ -1542,37 +2516,42 @@ s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) s32 status; u32 ctrl = 0; u32 i; - u32 hlreg0; bool link_up = FALSE; + u32 swfw_mask = hw->phy.phy_semaphore_mask; DEBUGFUNC("ixgbe_reset_hw_X550em"); /* Call adapter stop to disable Tx/Rx and clear interrupts */ status = hw->mac.ops.stop_adapter(hw); - if (status != IXGBE_SUCCESS) + if (status != IXGBE_SUCCESS) { + DEBUGOUT1("Failed to stop adapter, STATUS = %d\n", status); return status; - + } /* flush pending Tx transactions */ ixgbe_clear_tx_pending(hw); - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) { - /* Config MDIO clock speed before the first MDIO PHY access */ - hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); - hlreg0 &= ~IXGBE_HLREG0_MDCSPD; - IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); - } + ixgbe_set_mdio_speed(hw); /* PHY ops must be identified and initialized prior to reset */ status = hw->phy.ops.init(hw); - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (status) + DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n", + status); + + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) { + DEBUGOUT("Returning from reset HW due to PHY init failure\n"); return status; + } /* start the external PHY */ if (hw->phy.type == ixgbe_phy_x550em_ext_t) { status = ixgbe_init_ext_t_x550em(hw); - if (status) + if (status) { + DEBUGOUT1("Failed to start the external PHY, STATUS = %d\n", + status); return status; + } } /* Setup SFP module if there is one present. */ @@ -1585,8 +2564,10 @@ s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) return status; /* Reset PHY */ - if (!hw->phy.reset_disable && hw->phy.ops.reset) - hw->phy.ops.reset(hw); + if (!hw->phy.reset_disable && hw->phy.ops.reset) { + if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP) + return IXGBE_ERR_OVERTEMP; + } mac_reset_top: /* Issue global reset to the MAC. Needs to be SW reset if link is up. @@ -1601,9 +2582,16 @@ s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) ctrl = IXGBE_CTRL_RST; } + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + return IXGBE_ERR_SWFW_SYNC; + } ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); IXGBE_WRITE_FLUSH(hw); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); /* Poll for reset bit to self-clear meaning reset is complete */ for (i = 0; i < 10; i++) { @@ -1639,9 +2627,14 @@ s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) hw->mac.num_rar_entries = 128; hw->mac.ops.init_rx_addrs(hw); + ixgbe_set_mdio_speed(hw); + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) ixgbe_setup_mux_ctl(hw); + if (status != IXGBE_SUCCESS) + DEBUGOUT1("Reset HW failed, STATUS = %d\n", status); + return status; } @@ -1691,11 +2684,16 @@ s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw) /** * ixgbe_setup_kr_x550em - Configure the KR PHY. * @hw: pointer to hardware structure - * - * Configures the integrated KR PHY. **/ s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw) { + /* leave link alone for 2.5G */ + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) + return IXGBE_SUCCESS; + + if (ixgbe_check_reset_blocked(hw)) + return 0; + return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised); } @@ -1727,56 +2725,242 @@ s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, if (ret_val != IXGBE_SUCCESS) return ret_val; - if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { - /* Configure CS4227 LINE side to 10G SR. */ - reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB + - (hw->bus.lan_id << 12); - reg_val = IXGBE_CS4227_SPEED_10G; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); + /* Configure internal PHY for KR/KX. */ + ixgbe_setup_kr_speed_x550em(hw, speed); - reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + - (hw->bus.lan_id << 12); + /* Configure CS4227 LINE side to proper mode. */ + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + + (hw->bus.lan_id << 12); + if (setup_linear) + reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; + else reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); + ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice, + reg_val); + return ret_val; +} - /* Configure CS4227 for HOST connection rate then type. */ - reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB + - (hw->bus.lan_id << 12); - reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ? - IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); +/** + * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode + * @hw: pointer to hardware structure + * @speed: the link speed to force + * + * Configures the integrated PHY for native SFI mode. Used to connect the + * internal PHY directly to an SFP cage, without autonegotiation. + **/ +static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed) +{ + struct ixgbe_mac_info *mac = &hw->mac; + s32 status; + u32 reg_val; - reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + - (hw->bus.lan_id << 12); - if (setup_linear) - reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; - else - reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); + /* Disable all AN and force speed to 10G Serial. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; - /* Setup XFI internal link. */ - ret_val = ixgbe_setup_ixfi_x550em(hw, &speed); + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + + /* Select forced link speed for internal PHY. */ + switch (*speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; + break; + default: + /* Other link speeds are not supported by internal PHY. */ + return IXGBE_ERR_LINK_SETUP; + } + + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + /* Toggle port SW reset by AN reset. */ + status = ixgbe_restart_an_internal_phy_x550em(hw); + + return status; +} + +/** + * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP + * @hw: pointer to hardware structure + * + * Configure the the integrated PHY for SFP support. + **/ +s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 ret_val; + u16 reg_phy_ext; + bool setup_linear = FALSE; + u32 reg_slice, reg_phy_int, slice_offset; + + UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); + + /* Check if SFP module is supported and linear */ + ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); + + /* If no SFP module present, then return success. Return success since + * SFP not present error is not excepted in the setup MAC link flow. + */ + if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + return IXGBE_SUCCESS; + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) { + /* Configure internal PHY for native SFI based on module type */ + ret_val = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA; + if (!setup_linear) + reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR; + + ret_val = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* Setup SFI internal link. */ + ret_val = ixgbe_setup_sfi_x550a(hw, &speed); } else { /* Configure internal PHY for KR/KX. */ ixgbe_setup_kr_speed_x550em(hw, speed); - /* Configure CS4227 LINE side to proper mode. */ - reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + - (hw->bus.lan_id << 12); - if (setup_linear) - reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; + if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) { + /* Find Address */ + DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n"); + return IXGBE_ERR_PHY_ADDR_INVALID; + } + + /* Get external PHY SKU id */ + ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU, + IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* When configuring quad port CS4223, the MAC instance is part + * of the slice offset. + */ + if (reg_phy_ext == IXGBE_CS4223_SKU_ID) + slice_offset = (hw->bus.lan_id + + (hw->bus.instance_id << 1)) << 12; else - reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); + slice_offset = hw->bus.lan_id << 12; + + /* Configure CS4227/CS4223 LINE side to proper mode. */ + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset; + + ret_val = hw->phy.ops.read_reg(hw, reg_slice, + IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) | + (IXGBE_CS4227_EDC_MODE_SR << 1)); + + if (setup_linear) + reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; + else + reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; + ret_val = hw->phy.ops.write_reg(hw, reg_slice, + IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext); + + /* Flush previous write with a read */ + ret_val = hw->phy.ops.read_reg(hw, reg_slice, + IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); } return ret_val; } +/** + * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration + * @hw: pointer to hardware structure + * + * iXfI configuration needed for ixgbe_mac_X550EM_x devices. + **/ +static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + s32 status; + u32 reg_val; + + /* Disable training protocol FSM. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Disable Flex from training TXFFE. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Enable override for coefficients. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + return status; +} + /** * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode. * @hw: pointer to hardware structure @@ -1787,11 +2971,16 @@ s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, **/ static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) { + struct ixgbe_mac_info *mac = &hw->mac; s32 status; u32 reg_val; + /* iXFI is only supported with X552 */ + if (mac->type != ixgbe_mac_X550EM_x) + return IXGBE_ERR_LINK_SETUP; + /* Disable AN and force speed to 10G Serial. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, + status = mac->ops.read_iosf_sb_reg(hw, IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); if (status != IXGBE_SUCCESS) @@ -1813,79 +3002,21 @@ static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) return IXGBE_ERR_LINK_SETUP; } - status = ixgbe_write_iosf_sb_reg_x550(hw, + status = mac->ops.write_iosf_sb_reg(hw, IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); if (status != IXGBE_SUCCESS) return status; - /* Disable training protocol FSM. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); - if (status != IXGBE_SUCCESS) - return status; - reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); - if (status != IXGBE_SUCCESS) - return status; - - /* Disable Flex from training TXFFE. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); - if (status != IXGBE_SUCCESS) - return status; - reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; - reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; - reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); - if (status != IXGBE_SUCCESS) - return status; - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); - if (status != IXGBE_SUCCESS) - return status; - reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; - reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; - reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); - if (status != IXGBE_SUCCESS) - return status; - - /* Enable override for coefficients. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); - if (status != IXGBE_SUCCESS) - return status; - reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN; - reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN; - reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN; - reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); - if (status != IXGBE_SUCCESS) - return status; + /* Additional configuration needed for x550em_x */ + if (hw->mac.type == ixgbe_mac_X550EM_x) { + status = ixgbe_setup_ixfi_x550em_x(hw); + if (status != IXGBE_SUCCESS) + return status; + } /* Toggle port SW reset by AN reset. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); - if (status != IXGBE_SUCCESS) - return status; - reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + status = ixgbe_restart_an_internal_phy_x550em(hw); return status; } @@ -1944,43 +3075,51 @@ s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) return IXGBE_ERR_CONFIG; - /* If link is not up, then there is no setup necessary so return */ - status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); - if (status != IXGBE_SUCCESS) - return status; + if (hw->mac.type == ixgbe_mac_X550EM_x && + !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { + /* If link is down, there is no setup necessary so return */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return status; - if (!link_up) - return IXGBE_SUCCESS; + if (!link_up) + return IXGBE_SUCCESS; - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &speed); - if (status != IXGBE_SUCCESS) - return status; + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &speed); + if (status != IXGBE_SUCCESS) + return status; - /* If link is not still up, then no setup is necessary so return */ - status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); - if (status != IXGBE_SUCCESS) - return status; - if (!link_up) - return IXGBE_SUCCESS; + /* If link is still down - no setup is required so return */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return status; + if (!link_up) + return IXGBE_SUCCESS; - /* clear everything but the speed and duplex bits */ - speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK; + /* clear everything but the speed and duplex bits */ + speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK; - switch (speed) { - case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL: - force_speed = IXGBE_LINK_SPEED_10GB_FULL; - break; - case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL: - force_speed = IXGBE_LINK_SPEED_1GB_FULL; - break; - default: - /* Internal PHY does not support anything else */ - return IXGBE_ERR_INVALID_LINK_SETTINGS; + switch (speed) { + case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL: + force_speed = IXGBE_LINK_SPEED_10GB_FULL; + break; + case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL: + force_speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + default: + /* Internal PHY does not support anything else */ + return IXGBE_ERR_INVALID_LINK_SETTINGS; + } + + return ixgbe_setup_ixfi_x550em(hw, &force_speed); + } else { + speed = IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + return ixgbe_setup_kr_speed_x550em(hw, speed); } - - return ixgbe_setup_ixfi_x550em(hw, &force_speed); } /** @@ -1995,57 +3134,57 @@ s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw) u32 reg_val; /* Disable AN and force speed to 10G Serial. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); if (status != IXGBE_SUCCESS) return status; reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); if (status != IXGBE_SUCCESS) return status; /* Set near-end loopback clocks. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); if (status != IXGBE_SUCCESS) return status; reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B; reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); if (status != IXGBE_SUCCESS) return status; /* Set loopback enable. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); if (status != IXGBE_SUCCESS) return status; reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); if (status != IXGBE_SUCCESS) return status; /* Training bypass. */ - status = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); if (status != IXGBE_SUCCESS) return status; reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS; - status = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); return status; } @@ -2059,13 +3198,13 @@ s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw) * * Reads a 16 bit word from the EEPROM using the hostif. **/ -s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, - u16 *data) +s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data) { - s32 status; + const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; struct ixgbe_hic_read_shadow_ram buffer; + s32 status; - DEBUGFUNC("ixgbe_read_ee_hostif_data_X550"); + DEBUGFUNC("ixgbe_read_ee_hostif_X550"); buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; buffer.hdr.req.buf_lenh = 0; buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; @@ -2076,42 +3215,18 @@ s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, /* one word */ buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16)); - status = ixgbe_host_interface_command(hw, (u32 *)&buffer, - sizeof(buffer), - IXGBE_HI_COMMAND_TIMEOUT, FALSE); - + status = hw->mac.ops.acquire_swfw_sync(hw, mask); if (status) return status; - *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, - FW_NVM_DATA_OFFSET); - - return 0; -} - -/** - * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command - * @hw: pointer to hardware structure - * @offset: offset of word in the EEPROM to read - * @data: word read from the EEPROM - * - * Reads a 16 bit word from the EEPROM using the hostif. - **/ -s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, - u16 *data) -{ - s32 status = IXGBE_SUCCESS; - - DEBUGFUNC("ixgbe_read_ee_hostif_X550"); - - if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == - IXGBE_SUCCESS) { - status = ixgbe_read_ee_hostif_data_X550(hw, offset, data); - hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); - } else { - status = IXGBE_ERR_SWFW_SYNC; + status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer), + IXGBE_HI_COMMAND_TIMEOUT); + if (!status) { + *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, + FW_NVM_DATA_OFFSET); } + hw->mac.ops.release_swfw_sync(hw, mask); return status; } @@ -2127,6 +3242,7 @@ s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, u16 offset, u16 words, u16 *data) { + const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; struct ixgbe_hic_read_shadow_ram buffer; u32 current_word = 0; u16 words_to_read; @@ -2136,11 +3252,12 @@ s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550"); /* Take semaphore for the entire operation. */ - status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + status = hw->mac.ops.acquire_swfw_sync(hw, mask); if (status) { DEBUGOUT("EEPROM read buffer - semaphore failed\n"); return status; } + while (words) { if (words > FW_MAX_READ_BUFFER_SIZE / 2) words_to_read = FW_MAX_READ_BUFFER_SIZE / 2; @@ -2156,10 +3273,8 @@ s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2); buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2); - status = ixgbe_host_interface_command(hw, (u32 *)&buffer, - sizeof(buffer), - IXGBE_HI_COMMAND_TIMEOUT, - FALSE); + status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer), + IXGBE_HI_COMMAND_TIMEOUT); if (status) { DEBUGOUT("Host interface command failed\n"); @@ -2184,7 +3299,7 @@ s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, } out: - hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + hw->mac.ops.release_swfw_sync(hw, mask); return status; } @@ -2577,9 +3692,9 @@ s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw) * * Determines physical layer capabilities of the current configuration. **/ -u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw) +u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw) { - u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; u16 ext_ability = 0; DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em"); @@ -2588,6 +3703,21 @@ u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw) switch (hw->phy.type) { case ixgbe_phy_x550em_kr: + if (hw->mac.type == ixgbe_mac_X550EM_a) { + if (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) { + physical_layer = + IXGBE_PHYSICAL_LAYER_2500BASE_KX; + break; + } else if (hw->device_id == + IXGBE_DEV_ID_X550EM_A_KR_L) { + physical_layer = + IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + } + } + /* fall through */ + case ixgbe_phy_x550em_xfi: physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR | IXGBE_PHYSICAL_LAYER_1000BASE_KX; break; @@ -2604,6 +3734,20 @@ u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw) if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; break; + case ixgbe_phy_fw: + if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL) + physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T; + break; + case ixgbe_phy_sgmii: + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + case ixgbe_phy_ext_1g_t: + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T; + break; default: break; } @@ -2695,7 +3839,9 @@ s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) bool link_up; /* SW LPLU not required on later HW revisions. */ - if (IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))) + if ((hw->mac.type == ixgbe_mac_X550EM_x) && + (IXGBE_FUSES0_REV_MASK & + IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))) return IXGBE_SUCCESS; /* If blocked by MNG FW, then don't restart AN */ @@ -2879,10 +4025,13 @@ s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw) goto out; } - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) { - ret_val = ixgbe_read_iosf_sb_reg_x550(hw, - IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + ret_val = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); if (ret_val != IXGBE_SUCCESS) goto out; reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | @@ -2891,18 +4040,256 @@ s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw) reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; if (asm_dir) reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; - ret_val = ixgbe_write_iosf_sb_reg_x550(hw, - IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), - IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + ret_val = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); /* This device does not fully support AN. */ hw->fc.disable_fc_autoneg = TRUE; + break; + case IXGBE_DEV_ID_X550EM_X_XFI: + hw->fc.disable_fc_autoneg = TRUE; + break; + default: + break; } out: return ret_val; } +/** + * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) +{ + u32 link_s1, lp_an_page_low, an_cntl_1; + s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; + ixgbe_link_speed speed; + bool link_up; + + /* AN should have completed when the cable was plugged in. + * Look for reasons to bail out. Bail out if: + * - FC autoneg is disabled, or if + * - link is not up. + */ + if (hw->fc.disable_fc_autoneg) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "Flow control autoneg is disabled"); + goto out; + } + + hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); + if (!link_up) { + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); + goto out; + } + + /* Check at auto-negotiation has completed */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_S1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1); + + if (status != IXGBE_SUCCESS || + (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) { + DEBUGOUT("Auto-Negotiation did not complete\n"); + status = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + + /* Read the 10g AN autoc and LP ability registers and resolve + * local flow control settings accordingly + */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1); + + if (status != IXGBE_SUCCESS) { + DEBUGOUT("Auto-Negotiation did not complete\n"); + goto out; + } + + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low); + + if (status != IXGBE_SUCCESS) { + DEBUGOUT("Auto-Negotiation did not complete\n"); + goto out; + } + + status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low, + IXGBE_KRM_AN_CNTL_1_SYM_PAUSE, + IXGBE_KRM_AN_CNTL_1_ASM_PAUSE, + IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE, + IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE); + +out: + if (status == IXGBE_SUCCESS) { + hw->fc.fc_was_autonegged = TRUE; + } else { + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; + } +} + +/** + * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings + * @hw: pointer to hardware structure + * + **/ +void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw) +{ + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; +} + +/** + * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; + u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; + ixgbe_link_speed speed; + bool link_up; + + /* AN should have completed when the cable was plugged in. + * Look for reasons to bail out. Bail out if: + * - FC autoneg is disabled, or if + * - link is not up. + */ + if (hw->fc.disable_fc_autoneg) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "Flow control autoneg is disabled"); + goto out; + } + + hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); + if (!link_up) { + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); + goto out; + } + + /* Check if auto-negotiation has completed */ + status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info); + if (status != IXGBE_SUCCESS || + !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) { + DEBUGOUT("Auto-Negotiation did not complete\n"); + status = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + + /* Negotiate the flow control */ + status = ixgbe_negotiate_fc(hw, info[0], info[0], + FW_PHY_ACT_GET_LINK_INFO_FC_RX, + FW_PHY_ACT_GET_LINK_INFO_FC_TX, + FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX, + FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX); + +out: + if (status == IXGBE_SUCCESS) { + hw->fc.fc_was_autonegged = TRUE; + } else { + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; + } +} + +/** + * ixgbe_setup_fc_backplane_x550em_a - Set up flow control + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + **/ +s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u32 an_cntl = 0; + + DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a"); + + /* Validate the requested mode */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + return IXGBE_ERR_INVALID_LINK_SETTINGS; + } + + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + /* Set up the 1G and 10G flow control advertisement registers so the + * HW will be able to do FC autoneg once the cable is plugged in. If + * we link at 10G, the 1G advertisement is harmless and vice versa. + */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl); + + if (status != IXGBE_SUCCESS) { + DEBUGOUT("Auto-Negotiation did not complete\n"); + return status; + } + + /* The possible values of fc.requested_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.requested_mode) { + case ixgbe_fc_none: + /* Flow control completely disabled by software override. */ + an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | + IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); + break; + case ixgbe_fc_tx_pause: + /* Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; + an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; + break; + case ixgbe_fc_rx_pause: + /* Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE, as such we fall + * through to the fc_full statement. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | + IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; + break; + default: + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, + "Flow control param set incorrectly\n"); + return IXGBE_ERR_CONFIG; + } + + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl); + + /* Restart auto-negotiation. */ + status = ixgbe_restart_an_internal_phy_x550em(hw); + + return status; +} + /** * ixgbe_set_mux - Set mux for port 1 access with CS4227 * @hw: pointer to hardware structure @@ -2963,6 +4350,133 @@ void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask) ixgbe_release_swfw_sync_X540(hw, mask); } +/** + * ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore and get the shared phy token as needed + */ +static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask) +{ + u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM; + int retries = FW_PHY_TOKEN_RETRIES; + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a"); + + while (--retries) { + status = IXGBE_SUCCESS; + if (hmask) + status = ixgbe_acquire_swfw_sync_X540(hw, hmask); + if (status) { + DEBUGOUT1("Could not acquire SWFW semaphore, Status = %d\n", + status); + return status; + } + if (!(mask & IXGBE_GSSR_TOKEN_SM)) + return IXGBE_SUCCESS; + + status = ixgbe_get_phy_token(hw); + if (status == IXGBE_ERR_TOKEN_RETRY) + DEBUGOUT1("Could not acquire PHY token, Status = %d\n", + status); + + if (status == IXGBE_SUCCESS) + return IXGBE_SUCCESS; + + if (hmask) + ixgbe_release_swfw_sync_X540(hw, hmask); + + if (status != IXGBE_ERR_TOKEN_RETRY) { + DEBUGOUT1("Unable to retry acquiring the PHY token, Status = %d\n", + status); + return status; + } + } + + DEBUGOUT1("Semaphore acquisition retries failed!: PHY ID = 0x%08X\n", + hw->phy.id); + return status; +} + +/** + * ixgbe_release_swfw_sync_X550a - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore and puts the shared phy token as needed + */ +static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask) +{ + u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM; + + DEBUGFUNC("ixgbe_release_swfw_sync_X550a"); + + if (mask & IXGBE_GSSR_TOKEN_SM) + ixgbe_put_phy_token(hw); + + if (hmask) + ixgbe_release_swfw_sync_X540(hw, hmask); +} + +/** + * ixgbe_read_phy_reg_x550a - Reads specified PHY register + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @phy_data: Pointer to read data from PHY register + * + * Reads a value from a specified PHY register using the SWFW lock and PHY + * Token. The PHY Token is needed since the MDIO is shared between to MAC + * instances. + **/ +s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) +{ + s32 status; + u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM; + + DEBUGFUNC("ixgbe_read_phy_reg_x550a"); + + if (hw->mac.ops.acquire_swfw_sync(hw, mask)) + return IXGBE_ERR_SWFW_SYNC; + + status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); + + hw->mac.ops.release_swfw_sync(hw, mask); + + return status; +} + +/** + * ixgbe_write_phy_reg_x550a - Writes specified PHY register + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 5 bit device type + * @phy_data: Data to write to the PHY register + * + * Writes a value to specified PHY register using the SWFW lock and PHY Token. + * The PHY Token is needed since the MDIO is shared between to MAC instances. + **/ +s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + s32 status; + u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM; + + DEBUGFUNC("ixgbe_write_phy_reg_x550a"); + + if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) { + status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type, + phy_data); + hw->mac.ops.release_swfw_sync(hw, mask); + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + /** * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt * @hw: pointer to hardware structure @@ -3018,8 +4532,10 @@ s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, else force_speed = IXGBE_LINK_SPEED_1GB_FULL; - /* If internal link mode is XFI, then setup XFI internal link. */ - if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { + /* If X552 and internal link mode is XFI, then setup XFI internal link. + */ + if (hw->mac.type == ixgbe_mac_X550EM_x && + !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { status = ixgbe_setup_ixfi_x550em(hw, &force_speed); if (status != IXGBE_SUCCESS) @@ -3042,7 +4558,7 @@ s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete) { u32 status; - u16 autoneg_status; + u16 i, autoneg_status = 0; if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) return IXGBE_ERR_CONFIG; @@ -3055,21 +4571,18 @@ s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, return status; /* MAC link is up, so check external PHY link. - * Read this twice back to back to indicate current status. + * X557 PHY. Link status is latching low, and can only be used to detect + * link drop, and not the current status of the link without performing + * back-to-back reads. */ - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_status); + for (i = 0; i < 2; i++) { + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_status); - if (status != IXGBE_SUCCESS) - return status; - - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_status); - - if (status != IXGBE_SUCCESS) - return status; + if (status != IXGBE_SUCCESS) + return status; + } /* If external PHY link is not up, then indicate link not up */ if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS)) @@ -3116,7 +4629,8 @@ s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx) ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); - return IXGBE_SUCCESS; + /* Some designs have the LEDs wired to the MAC */ + return ixgbe_led_on_generic(hw, led_idx); } /** @@ -3140,6 +4654,67 @@ s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx) ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); - return IXGBE_SUCCESS; + /* Some designs have the LEDs wired to the MAC */ + return ixgbe_led_off_generic(hw, led_idx); } +/** + * ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware + * @hw: pointer to the HW structure + * @maj: driver version major number + * @min: driver version minor number + * @build: driver version build number + * @sub: driver version sub build number + * @len: length of driver_ver string + * @driver_ver: driver string + * + * Sends driver version number to firmware through the manageability + * block. On success return IXGBE_SUCCESS + * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ +s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 sub, u16 len, const char *driver_ver) +{ + struct ixgbe_hic_drv_info2 fw_cmd; + s32 ret_val = IXGBE_SUCCESS; + int i; + + DEBUGFUNC("ixgbe_set_fw_drv_ver_x550"); + + if ((len == 0) || (driver_ver == NULL) || + (len > sizeof(fw_cmd.driver_string))) + return IXGBE_ERR_INVALID_ARGUMENT; + + fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; + fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len; + fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; + fw_cmd.port_num = (u8)hw->bus.func; + fw_cmd.ver_maj = maj; + fw_cmd.ver_min = min; + fw_cmd.ver_build = build; + fw_cmd.ver_sub = sub; + fw_cmd.hdr.checksum = 0; + memcpy(fw_cmd.driver_string, driver_ver, len); + fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd, + (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); + + for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { + ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, + sizeof(fw_cmd), + IXGBE_HI_COMMAND_TIMEOUT, + TRUE); + if (ret_val != IXGBE_SUCCESS) + continue; + + if (fw_cmd.hdr.cmd_or_resp.ret_status == + FW_CEM_RESP_STATUS_SUCCESS) + ret_val = IXGBE_SUCCESS; + else + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + + break; + } + + return ret_val; +} diff --git a/sys/dev/ixgbe/ixgbe_x550.h b/sys/dev/ixgbe/ixgbe_x550.h index b590bb766361..44c9d06a42d9 100644 --- a/sys/dev/ixgbe/ixgbe_x550.h +++ b/sys/dev/ixgbe/ixgbe_x550.h @@ -1,31 +1,31 @@ /****************************************************************************** - Copyright (c) 2001-2015, Intel Corporation + Copyright (c) 2001-2017, Intel Corporation All rights reserved. - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -56,12 +56,8 @@ s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, u16 offset, u16 words, u16 *data); s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data); -s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, - u16 *data); s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, u16 data); -s32 ixgbe_set_eee_X550(struct ixgbe_hw *hw, bool enable_eee); -s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee); void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable, unsigned int pool); void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, @@ -70,6 +66,14 @@ s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u32 data); s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u32 *data); +s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 ver, u16 len, const char *str); +s32 ixgbe_get_phy_token(struct ixgbe_hw *); +s32 ixgbe_put_phy_token(struct ixgbe_hw *); +s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 data); +s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *data); void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw); void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw); void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap); @@ -85,7 +89,7 @@ s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw); s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw); s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw); s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw); -u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw); void ixgbe_disable_rx_x550(struct ixgbe_hw *hw); s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed); s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw); @@ -95,6 +99,19 @@ s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete); +s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); +s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); +s32 ixgbe_setup_fc_fiber_x550em_a(struct ixgbe_hw *hw); +s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw); +s32 ixgbe_setup_fc_sgmii_x550em_a(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw); s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed speed, diff --git a/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c b/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c index 38c0320db41b..05bf7b41467c 100644 --- a/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c +++ b/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c @@ -394,8 +394,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) ring->rx_mb_size = priv->rx_mb_size; ring->stride = stride; - if (ring->stride <= TXBB_SIZE) + if (ring->stride <= TXBB_SIZE) { + /* Stamp first unused send wqe */ + __be32 *ptr = (__be32 *)ring->buf; + __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT); + *ptr = stamp; + /* Move pointer to start of rx section */ ring->buf += TXBB_SIZE; + } ring->log_stride = ffs(ring->stride) - 1; ring->buf_size = ring->size * ring->stride; diff --git a/sys/dev/mmc/bridge.h b/sys/dev/mmc/bridge.h index a780ffaeea41..502f433c0d5d 100644 --- a/sys/dev/mmc/bridge.h +++ b/sys/dev/mmc/bridge.h @@ -174,6 +174,7 @@ struct mmc_host { struct mmc_ios ios; /* Current state of the host */ }; +#ifdef _KERNEL extern driver_t mmc_driver; extern devclass_t mmc_devclass; @@ -184,5 +185,6 @@ extern devclass_t mmc_devclass; MODULE_DEPEND(name, mmc, MMC_VERSION, MMC_VERSION, MMC_VERSION); #define MMC_DEPEND(name) \ MODULE_DEPEND(name, mmc, MMC_VERSION, MMC_VERSION, MMC_VERSION); +#endif /* _KERNEL */ #endif /* DEV_MMC_BRIDGE_H */ diff --git a/sys/dev/mmc/mmcbrvar.h b/sys/dev/mmc/mmcbrvar.h index d8f79156b81d..47024da7696b 100644 --- a/sys/dev/mmc/mmcbrvar.h +++ b/sys/dev/mmc/mmcbrvar.h @@ -56,7 +56,6 @@ #define DEV_MMC_MMCBRVAR_H #include - #include "mmcbr_if.h" enum mmcbr_device_ivars { diff --git a/sys/dev/mmc/mmcreg.h b/sys/dev/mmc/mmcreg.h index 359f31d50c78..671b8c23529e 100644 --- a/sys/dev/mmc/mmcreg.h +++ b/sys/dev/mmc/mmcreg.h @@ -1,6 +1,7 @@ /*- * Copyright (c) 2006 M. Warner Losh. All rights reserved. * Copyright (c) 2017 Marius Strobl + * Copyright (c) 2015-2016 Ilya Bakulin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -156,6 +157,34 @@ struct mmc_command { #define R1_STATE_PRG 7 #define R1_STATE_DIS 8 +/* R4 response (SDIO) */ +#define R4_IO_NUM_FUNCTIONS(ocr) (((ocr) >> 28) & 0x3) +#define R4_IO_MEM_PRESENT (0x1<<27) +#define R4_IO_OCR_MASK 0x00fffff0 + +/* + * R5 responses + * + * Types (per SD 2.0 standard) + *e : error bit + *s : status bit + *r : detected and set for the actual command response + *x : Detected and set during command execution. The host can get + * the status by issuing a command with R1 response. + * + * Clear Condition (per SD 2.0 standard) + *a : according to the card current state. + *b : always related to the previous command. reception of a valid + * command will clear it (with a delay of one command). + *c : clear by read + */ +#define R5_COM_CRC_ERROR (1u << 15)/* er, b */ +#define R5_ILLEGAL_COMMAND (1u << 14)/* er, b */ +#define R5_IO_CURRENT_STATE_MASK (3u << 12)/* s, b */ +#define R5_IO_CURRENT_STATE(x) (((x) & R5_IO_CURRENT_STATE_MASK) >> 12) +#define R5_ERROR (1u << 11)/* erx, c */ +#define R5_FUNCTION_NUMBER (1u << 9)/* er, c */ +#define R5_OUT_OF_RANGE (1u << 8)/* er, c */ struct mmc_data { size_t len; /* size of the data */ size_t xfer_len; @@ -187,6 +216,7 @@ struct mmc_request { #define SD_SEND_RELATIVE_ADDR 3 #define MMC_SET_DSR 4 #define MMC_SLEEP_AWAKE 5 +#define IO_SEND_OP_COND 5 #define MMC_SWITCH_FUNC 6 #define MMC_SWITCH_FUNC_CMDS 0 #define MMC_SWITCH_FUNC_SET 1 @@ -269,7 +299,31 @@ struct mmc_request { /* Class 9: I/O cards (sd) */ #define SD_IO_RW_DIRECT 52 +/* CMD52 arguments */ +#define SD_ARG_CMD52_READ (0<<31) +#define SD_ARG_CMD52_WRITE (1<<31) +#define SD_ARG_CMD52_FUNC_SHIFT 28 +#define SD_ARG_CMD52_FUNC_MASK 0x7 +#define SD_ARG_CMD52_EXCHANGE (1<<27) +#define SD_ARG_CMD52_REG_SHIFT 9 +#define SD_ARG_CMD52_REG_MASK 0x1ffff +#define SD_ARG_CMD52_DATA_SHIFT 0 +#define SD_ARG_CMD52_DATA_MASK 0xff +#define SD_R5_DATA(resp) ((resp)[0] & 0xff) + #define SD_IO_RW_EXTENDED 53 +/* CMD53 arguments */ +#define SD_ARG_CMD53_READ (0<<31) +#define SD_ARG_CMD53_WRITE (1<<31) +#define SD_ARG_CMD53_FUNC_SHIFT 28 +#define SD_ARG_CMD53_FUNC_MASK 0x7 +#define SD_ARG_CMD53_BLOCK_MODE (1<<27) +#define SD_ARG_CMD53_INCREMENT (1<<26) +#define SD_ARG_CMD53_REG_SHIFT 9 +#define SD_ARG_CMD53_REG_MASK 0x1ffff +#define SD_ARG_CMD53_LENGTH_SHIFT 0 +#define SD_ARG_CMD53_LENGTH_MASK 0x1ff +#define SD_ARG_CMD53_LENGTH_MAX 64 /* XXX should be 511? */ /* Class 10: Switch function commands */ #define SD_SWITCH_FUNC 6 @@ -440,6 +494,54 @@ struct mmc_request { /* Specifications require 400 kHz max. during ID phase. */ #define SD_MMC_CARD_ID_FREQUENCY 400000 +/* + * SDIO Direct & Extended I/O + */ +#define SD_IO_RW_WR (1u << 31) +#define SD_IO_RW_FUNC(x) (((x) & 0x7) << 28) +#define SD_IO_RW_RAW (1u << 27) +#define SD_IO_RW_INCR (1u << 26) +#define SD_IO_RW_ADR(x) (((x) & 0x1FFFF) << 9) +#define SD_IO_RW_DAT(x) (((x) & 0xFF) << 0) +#define SD_IO_RW_LEN(x) (((x) & 0xFF) << 0) + +#define SD_IOE_RW_LEN(x) (((x) & 0x1FF) << 0) +#define SD_IOE_RW_BLK (1u << 27) + +/* Card Common Control Registers (CCCR) */ +#define SD_IO_CCCR_START 0x00000 +#define SD_IO_CCCR_SIZE 0x100 +#define SD_IO_CCCR_FN_ENABLE 0x02 +#define SD_IO_CCCR_FN_READY 0x03 +#define SD_IO_CCCR_INT_ENABLE 0x04 +#define SD_IO_CCCR_INT_PENDING 0x05 +#define SD_IO_CCCR_CTL 0x06 +#define CCCR_CTL_RES (1<<3) +#define SD_IO_CCCR_BUS_WIDTH 0x07 +#define CCCR_BUS_WIDTH_4 (1<<1) +#define CCCR_BUS_WIDTH_1 (1<<0) +#define SD_IO_CCCR_CARDCAP 0x08 +#define SD_IO_CCCR_CISPTR 0x09 /* XXX 9-10, 10-11, or 9-12 */ + +/* Function Basic Registers (FBR) */ +#define SD_IO_FBR_START 0x00100 +#define SD_IO_FBR_SIZE 0x00700 + +/* Card Information Structure (CIS) */ +#define SD_IO_CIS_START 0x01000 +#define SD_IO_CIS_SIZE 0x17000 + +/* CIS tuple codes (based on PC Card 16) */ +#define SD_IO_CISTPL_VERS_1 0x15 +#define SD_IO_CISTPL_MANFID 0x20 +#define SD_IO_CISTPL_FUNCID 0x21 +#define SD_IO_CISTPL_FUNCE 0x22 +#define SD_IO_CISTPL_END 0xff + +/* CISTPL_FUNCID codes */ +/* OpenBSD incorrectly defines 0x0c as FUNCTION_WLAN */ +/* #define SDMMC_FUNCTION_WLAN 0x0c */ + /* OCR bits */ /* diff --git a/sys/dev/mmcnull/mmcnull.c b/sys/dev/mmcnull/mmcnull.c new file mode 100644 index 000000000000..6abaf17c6d72 --- /dev/null +++ b/sys/dev/mmcnull/mmcnull.c @@ -0,0 +1,463 @@ +/*- + * Copyright (c) 2013 Ilya Bakulin. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static int is_sdio_mode = 1; + +struct mmcnull_softc { + device_t dev; + struct mtx sc_mtx; + + struct cam_devq *devq; + struct cam_sim *sim; + struct cam_path *path; + + struct callout tick; + union ccb *cur_ccb; +}; + +static void mmcnull_identify(driver_t *, device_t); +static int mmcnull_probe(device_t); +static int mmcnull_attach(device_t); +static int mmcnull_detach(device_t); +static void mmcnull_action_sd(struct cam_sim *, union ccb *); +static void mmcnull_action_sdio(struct cam_sim *, union ccb *); +static void mmcnull_intr_sd(void *xsc); +static void mmcnull_intr_sdio(void *xsc); +static void mmcnull_poll(struct cam_sim *); + +static void +mmcnull_identify(driver_t *driver, device_t parent) +{ + device_t child; + + if (resource_disabled("mmcnull", 0)) + return; + + if (device_get_unit(parent) != 0) + return; + + /* Avoid duplicates. */ + if (device_find_child(parent, "mmcnull", -1)) + return; + + child = BUS_ADD_CHILD(parent, 20, "mmcnull", 0); + if (child == NULL) { + device_printf(parent, "add MMCNULL child failed\n"); + return; + } +} + + +static int +mmcnull_probe(device_t dev) +{ + device_set_desc(dev, "Emulated MMC controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +mmcnull_attach(device_t dev) +{ + struct mmcnull_softc *sc; + sim_action_func action_func; + + sc = device_get_softc(dev); + sc->dev = dev; + + mtx_init(&sc->sc_mtx, "mmcnullmtx", NULL, MTX_DEF); + + if ((sc->devq = cam_simq_alloc(1)) == NULL) + return (ENOMEM); + + if (is_sdio_mode) + action_func = mmcnull_action_sdio; + else + action_func = mmcnull_action_sd; + sc->sim = cam_sim_alloc(action_func, mmcnull_poll, "mmcnull", sc, + device_get_unit(dev), &sc->sc_mtx, 1, 1, + sc->devq); + + if (sc->sim == NULL) { + cam_simq_free(sc->devq); + device_printf(dev, "cannot allocate CAM SIM\n"); + return (EINVAL); + } + + mtx_lock(&sc->sc_mtx); + if (xpt_bus_register(sc->sim, dev, 0) != 0) { + device_printf(dev, + "cannot register SCSI pass-through bus\n"); + cam_sim_free(sc->sim, FALSE); + cam_simq_free(sc->devq); + mtx_unlock(&sc->sc_mtx); + return (EINVAL); + } + mtx_unlock(&sc->sc_mtx); + + callout_init_mtx(&sc->tick, &sc->sc_mtx, 0); /* Callout to emulate interrupts */ + + device_printf(dev, "attached OK\n"); + + return (0); +} + +static int +mmcnull_detach(device_t dev) +{ + struct mmcnull_softc *sc; + + sc = device_get_softc(dev); + + if (sc == NULL) + return (EINVAL); + + if (sc->sim != NULL) { + mtx_lock(&sc->sc_mtx); + xpt_bus_deregister(cam_sim_path(sc->sim)); + cam_sim_free(sc->sim, FALSE); + mtx_unlock(&sc->sc_mtx); + } + + if (sc->devq != NULL) + cam_simq_free(sc->devq); + + callout_drain(&sc->tick); + mtx_destroy(&sc->sc_mtx); + + device_printf(dev, "detached OK\n"); + return (0); +} + +/* + * The interrupt handler + * This implementation calls it via callout(9) + * with the mutex already taken + */ +static void +mmcnull_intr_sd(void *xsc) { + struct mmcnull_softc *sc; + union ccb *ccb; + struct ccb_mmcio *mmcio; + + sc = (struct mmcnull_softc *) xsc; + mtx_assert(&sc->sc_mtx, MA_OWNED); + + ccb = sc->cur_ccb; + mmcio = &ccb->mmcio; + device_printf(sc->dev, "mmcnull_intr: MMC command = %d\n", + mmcio->cmd.opcode); + + switch (mmcio->cmd.opcode) { + case MMC_GO_IDLE_STATE: + device_printf(sc->dev, "Reset device\n"); + break; + case SD_SEND_IF_COND: + mmcio->cmd.resp[0] = 0x1AA; // To match mmc_xpt expectations :-) + break; + case MMC_APP_CMD: + mmcio->cmd.resp[0] = R1_APP_CMD; + break; + case SD_SEND_RELATIVE_ADDR: + case MMC_SELECT_CARD: + mmcio->cmd.resp[0] = 0x1 << 16; + break; + case ACMD_SD_SEND_OP_COND: + mmcio->cmd.resp[0] = 0xc0ff8000; + mmcio->cmd.resp[0] |= MMC_OCR_CARD_BUSY; + break; + case MMC_ALL_SEND_CID: + /* Note: this is a real CID from Wandboard int mmc */ + mmcio->cmd.resp[0] = 0x1b534d30; + mmcio->cmd.resp[1] = 0x30303030; + mmcio->cmd.resp[2] = 0x10842806; + mmcio->cmd.resp[3] = 0x5700e900; + break; + case MMC_SEND_CSD: + /* Note: this is a real CSD from Wandboard int mmc */ + mmcio->cmd.resp[0] = 0x400e0032; + mmcio->cmd.resp[1] = 0x5b590000; + mmcio->cmd.resp[2] = 0x751f7f80; + mmcio->cmd.resp[3] = 0x0a404000; + break; + case MMC_READ_SINGLE_BLOCK: + case MMC_READ_MULTIPLE_BLOCK: + strcpy(mmcio->cmd.data->data, "WTF?!"); + break; + default: + device_printf(sc->dev, "mmcnull_intr_sd: unknown command\n"); + mmcio->cmd.error = 1; + } + ccb->ccb_h.status = CAM_REQ_CMP; + + sc->cur_ccb = NULL; + xpt_done(ccb); +} + +static void +mmcnull_intr_sdio_newintr(void *xsc) { + struct mmcnull_softc *sc; + struct cam_path *dpath; + + sc = (struct mmcnull_softc *) xsc; + mtx_assert(&sc->sc_mtx, MA_OWNED); + device_printf(sc->dev, "mmcnull_intr_sdio_newintr()\n"); + + /* Our path */ + if (xpt_create_path(&dpath, NULL, cam_sim_path(sc->sim), 0, 0) != CAM_REQ_CMP) { + device_printf(sc->dev, "mmcnull_intr_sdio_newintr(): cannot create path\n"); + return; + } + xpt_async(AC_UNIT_ATTENTION, dpath, NULL); + xpt_free_path(dpath); +} + +static void +mmcnull_intr_sdio(void *xsc) { + struct mmcnull_softc *sc; + union ccb *ccb; + struct ccb_mmcio *mmcio; + + sc = (struct mmcnull_softc *) xsc; + mtx_assert(&sc->sc_mtx, MA_OWNED); + + ccb = sc->cur_ccb; + mmcio = &ccb->mmcio; + device_printf(sc->dev, "mmcnull_intr: MMC command = %d\n", + mmcio->cmd.opcode); + + switch (mmcio->cmd.opcode) { + case MMC_GO_IDLE_STATE: + device_printf(sc->dev, "Reset device\n"); + break; + case SD_SEND_IF_COND: + mmcio->cmd.resp[0] = 0x1AA; // To match mmc_xpt expectations :-) + break; + case MMC_APP_CMD: + mmcio->cmd.resp[0] = R1_APP_CMD; + break; + case IO_SEND_OP_COND: + mmcio->cmd.resp[0] = 0x12345678; + mmcio->cmd.resp[0] |= ~ R4_IO_MEM_PRESENT; + break; + case SD_SEND_RELATIVE_ADDR: + case MMC_SELECT_CARD: + mmcio->cmd.resp[0] = 0x1 << 16; + break; + case ACMD_SD_SEND_OP_COND: + /* TODO: steal valid OCR from somewhere :-) */ + mmcio->cmd.resp[0] = 0x123; + mmcio->cmd.resp[0] |= MMC_OCR_CARD_BUSY; + break; + case MMC_ALL_SEND_CID: + mmcio->cmd.resp[0] = 0x1234; + mmcio->cmd.resp[1] = 0x5678; + mmcio->cmd.resp[2] = 0x9ABC; + mmcio->cmd.resp[3] = 0xDEF0; + break; + case MMC_READ_SINGLE_BLOCK: + case MMC_READ_MULTIPLE_BLOCK: + strcpy(mmcio->cmd.data->data, "WTF?!"); + break; + case SD_IO_RW_DIRECT: + device_printf(sc->dev, "Scheduling interrupt generation...\n"); + callout_reset(&sc->tick, hz / 10, mmcnull_intr_sdio_newintr, sc); + break; + default: + device_printf(sc->dev, "mmcnull_intr_sdio: unknown command\n"); + } + ccb->ccb_h.status = CAM_REQ_CMP; + + sc->cur_ccb = NULL; + xpt_done(ccb); +} + +/* + * This is a MMC IO handler + * It extracts MMC command from CCB and sends it + * to the h/w + */ +static void +mmcnull_handle_mmcio(struct cam_sim *sim, union ccb *ccb) +{ + struct mmcnull_softc *sc; + struct ccb_mmcio *mmcio; + + sc = cam_sim_softc(sim); + mmcio = &ccb->mmcio; + ccb->ccb_h.status = CAM_REQ_INPROG; + sc->cur_ccb = ccb; + + /* Real h/w will wait for the interrupt */ + if (is_sdio_mode) + callout_reset(&sc->tick, hz / 10, mmcnull_intr_sdio, sc); + else + callout_reset(&sc->tick, hz / 10, mmcnull_intr_sd, sc); +} + +static void +mmcnull_action_sd(struct cam_sim *sim, union ccb *ccb) +{ + struct mmcnull_softc *sc; + + sc = cam_sim_softc(sim); + if (sc == NULL) { + ccb->ccb_h.status = CAM_SEL_TIMEOUT; + xpt_done(ccb); + return; + } + + mtx_assert(&sc->sc_mtx, MA_OWNED); + + device_printf(sc->dev, "action: func_code %0x\n", ccb->ccb_h.func_code); + + switch (ccb->ccb_h.func_code) { + case XPT_PATH_INQ: + { + struct ccb_pathinq *cpi; + + cpi = &ccb->cpi; + cpi->version_num = 1; + cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16; + cpi->target_sprt = 0; + cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN; + cpi->hba_eng_cnt = 0; + cpi->max_target = 0; + cpi->max_lun = 0; + cpi->initiator_id = 1; + strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); + strncpy(cpi->hba_vid, "FreeBSD Foundation", HBA_IDLEN); + strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->unit_number = cam_sim_unit(sim); + cpi->bus_id = cam_sim_bus(sim); + cpi->base_transfer_speed = 100; /* XXX WTF? */ + cpi->protocol = PROTO_MMCSD; + cpi->protocol_version = SCSI_REV_0; + cpi->transport = XPORT_MMCSD; + cpi->transport_version = 0; + + cpi->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_GET_TRAN_SETTINGS: + { + struct ccb_trans_settings *cts = &ccb->cts; + struct ccb_trans_settings_mmc *mcts; + mcts = &ccb->cts.proto_specific.mmc; + + device_printf(sc->dev, "Got XPT_GET_TRAN_SETTINGS\n"); + + cts->protocol = PROTO_MMCSD; + cts->protocol_version = 0; + cts->transport = XPORT_MMCSD; + cts->transport_version = 0; + cts->xport_specific.valid = 0; + mcts->host_f_max = 12000000; + mcts->host_f_min = 200000; + mcts->host_ocr = 1; /* Fix this */ + ccb->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_SET_TRAN_SETTINGS: + device_printf(sc->dev, "Got XPT_SET_TRAN_SETTINGS, should update IOS...\n"); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + case XPT_RESET_BUS: + device_printf(sc->dev, "Got XPT_RESET_BUS, ACK it...\n"); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + case XPT_MMC_IO: + /* + * Here is the HW-dependent part of + * sending the command to the underlying h/w + * At some point in the future an interrupt comes. + * Then the request will be marked as completed. + */ + device_printf(sc->dev, "Got XPT_MMC_IO\n"); + mmcnull_handle_mmcio(sim, ccb); + return; + break; + case XPT_RESET_DEV: + /* This is sent by `camcontrol reset`*/ + device_printf(sc->dev, "Got XPT_RESET_DEV\n"); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + default: + device_printf(sc->dev, "Func code %d is unknown\n", ccb->ccb_h.func_code); + ccb->ccb_h.status = CAM_REQ_INVALID; + break; + } + xpt_done(ccb); + return; +} + +static void +mmcnull_action_sdio(struct cam_sim *sim, union ccb *ccb) { + mmcnull_action_sd(sim, ccb); +} + +static void +mmcnull_poll(struct cam_sim *sim) +{ + return; +} + + +static device_method_t mmcnull_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, mmcnull_identify), + DEVMETHOD(device_probe, mmcnull_probe), + DEVMETHOD(device_attach, mmcnull_attach), + DEVMETHOD(device_detach, mmcnull_detach), + DEVMETHOD_END +}; + +static driver_t mmcnull_driver = { + "mmcnull", mmcnull_methods, sizeof(struct mmcnull_softc) +}; + +static devclass_t mmcnull_devclass; + +DRIVER_MODULE(mmcnull, isa, mmcnull_driver, mmcnull_devclass, 0, 0); diff --git a/sys/dev/qlxgbe/ql_hw.c b/sys/dev/qlxgbe/ql_hw.c index e2e45bce7b26..8a8494ce5e72 100644 --- a/sys/dev/qlxgbe/ql_hw.c +++ b/sys/dev/qlxgbe/ql_hw.c @@ -2498,6 +2498,9 @@ ql_init_hw_if(qla_host_t *ha) if (qla_hw_add_all_mcast(ha)) return (-1); + if (ql_set_max_mtu(ha, ha->max_frame_size, ha->hw.rcv_cntxt_id)) + return (-1); + if (qla_config_rss(ha, ha->hw.rcv_cntxt_id)) return (-1); diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c index 5bcc41f3c3e4..d4a18270dd0c 100644 --- a/sys/dev/qlxgbe/ql_os.c +++ b/sys/dev/qlxgbe/ql_os.c @@ -980,8 +980,7 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { - ret = ql_set_max_mtu(ha, ha->max_frame_size, - ha->hw.rcv_cntxt_id); + qla_init_locked(ha); } if (ifp->if_mtu > ETHERMTU) @@ -1014,11 +1013,9 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ret = ql_set_allmulti(ha); } } else { - qla_init_locked(ha); ha->max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - ret = ql_set_max_mtu(ha, ha->max_frame_size, - ha->hw.rcv_cntxt_id); + qla_init_locked(ha); } } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -1522,8 +1519,11 @@ qla_stop(qla_host_t *ha) ha->flags.qla_watchdog_pause = 1; - while (!ha->qla_watchdog_paused) + while (!ha->qla_watchdog_paused) { + QLA_UNLOCK(ha); qla_mdelay(__func__, 1); + QLA_LOCK(ha); + } ha->flags.qla_interface_up = 0; @@ -1918,7 +1918,10 @@ qla_error_recovery(void *context, int pending) if (ha->flags.qla_interface_up) { ha->hw.imd_compl = 1; + + QLA_UNLOCK(ha); qla_mdelay(__func__, 300); + QLA_LOCK(ha); ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); diff --git a/sys/dev/rtwn/if_rtwn_rx.c b/sys/dev/rtwn/if_rtwn_rx.c index d6ccb159fc2f..7d841d99bd3d 100644 --- a/sys/dev/rtwn/if_rtwn_rx.c +++ b/sys/dev/rtwn/if_rtwn_rx.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include void @@ -190,7 +189,8 @@ rtwn_get_tsf(struct rtwn_softc *sc, uint64_t *buf, int id) } static uint64_t -rtwn_extend_rx_tsf(struct rtwn_softc *sc, const struct r92c_rx_stat *stat) +rtwn_extend_rx_tsf(struct rtwn_softc *sc, + const struct rtwn_rx_stat_common *stat) { uint64_t tsft; uint32_t rxdw3, tsfl, tsfl_curr; @@ -198,7 +198,7 @@ rtwn_extend_rx_tsf(struct rtwn_softc *sc, const struct r92c_rx_stat *stat) rxdw3 = le32toh(stat->rxdw3); tsfl = le32toh(stat->tsf_low); - id = MS(rxdw3, R92C_RXDW3_BSSID_FIT); + id = MS(rxdw3, RTWN_RXDW3_BSSID01_FIT); switch (id) { case 1: @@ -241,7 +241,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc) struct ieee80211_frame_min *wh; struct ieee80211_rx_stats rxs; struct rtwn_node *un; - struct r92c_rx_stat *stat; + struct rtwn_rx_stat_common *stat; void *physt; uint32_t rxdw0; int8_t rssi; @@ -250,10 +250,10 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc) stat = desc; rxdw0 = le32toh(stat->rxdw0); - cipher = MS(rxdw0, R92C_RXDW0_CIPHER); - infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8; - pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN); - shift = MS(rxdw0, R92C_RXDW0_SHIFT); + cipher = MS(rxdw0, RTWN_RXDW0_CIPHER); + infosz = MS(rxdw0, RTWN_RXDW0_INFOSZ) * 8; + pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN); + shift = MS(rxdw0, RTWN_RXDW0_SHIFT); wh = (struct ieee80211_frame_min *)(mtodo(m, shift + infosz)); if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && @@ -268,7 +268,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc) ni = NULL; un = RTWN_NODE(ni); - if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) + if (infosz != 0 && (rxdw0 & RTWN_RXDW0_PHYST)) physt = (void *)mtodo(m, shift); else physt = (un != NULL) ? &un->last_physt : &sc->last_physt; @@ -284,7 +284,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc) /* Add some common bits. */ /* NB: should not happen. */ - if (rxdw0 & R92C_RXDW0_CRCERR) + if (rxdw0 & RTWN_RXDW0_CRCERR) rxs.c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC; rxs.r_flags |= IEEE80211_R_TSF_START; /* XXX undocumented */ @@ -298,7 +298,7 @@ rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc) /* XXX TODO: we really need a rate-to-string method */ RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, rate %d\n", __func__, rssi, rxs.c_rate); - if (un != NULL && infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) { + if (un != NULL && infosz != 0 && (rxdw0 & RTWN_RXDW0_PHYST)) { /* Update our average RSSI. */ rtwn_update_avgrssi(sc, un, rssi, is_cck); } diff --git a/sys/dev/rtwn/if_rtwnreg.h b/sys/dev/rtwn/if_rtwnreg.h index 9dc830a2be0a..5588da4e75c8 100644 --- a/sys/dev/rtwn/if_rtwnreg.h +++ b/sys/dev/rtwn/if_rtwnreg.h @@ -48,6 +48,55 @@ struct rtwn_tx_desc_common { } txdw7; } __packed __attribute__((aligned(4))); +/* Common part of Rx descriptor. */ +struct rtwn_rx_stat_common { + uint32_t rxdw0; +#define RTWN_RXDW0_PKTLEN_M 0x00003fff +#define RTWN_RXDW0_PKTLEN_S 0 +#define RTWN_RXDW0_CRCERR 0x00004000 +#define RTWN_RXDW0_ICVERR 0x00008000 +#define RTWN_RXDW0_INFOSZ_M 0x000f0000 +#define RTWN_RXDW0_INFOSZ_S 16 +#define RTWN_RXDW0_CIPHER_M 0x00700000 +#define RTWN_RXDW0_CIPHER_S 20 +#define RTWN_RXDW0_QOS 0x00800000 +#define RTWN_RXDW0_SHIFT_M 0x03000000 +#define RTWN_RXDW0_SHIFT_S 24 +#define RTWN_RXDW0_PHYST 0x04000000 +#define RTWN_RXDW0_SWDEC 0x08000000 +#define RTWN_RXDW0_LS 0x10000000 +#define RTWN_RXDW0_FS 0x20000000 +#define RTWN_RXDW0_EOR 0x40000000 +#define RTWN_RXDW0_OWN 0x80000000 + + uint32_t rxdw1; +#define RTWN_RXDW1_AMSDU 0x00002000 +#define RTWN_RXDW1_MC 0x40000000 +#define RTWN_RXDW1_BC 0x80000000 + + uint32_t rxdw2; + uint32_t rxdw3; +#define RTWN_RXDW3_HTC 0x00000400 +#define RTWN_RXDW3_BSSID01_FIT_M 0x00003000 +#define RTWN_RXDW3_BSSID01_FIT_S 12 + + uint32_t rxdw4; + uint32_t tsf_low; +} __packed __attribute__((aligned(4))); + +/* Rx descriptor for PCIe devices. */ +struct rtwn_rx_stat_pci { + uint32_t rxdw0; + uint32_t rxdw1; + uint32_t rxdw2; + uint32_t rxdw3; + uint32_t rxdw4; + uint32_t tsf_low; + + uint32_t rxbufaddr; + uint32_t rxbufaddr64; +} __packed __attribute__((aligned(4))); + /* * Macros to access subfields in registers. */ diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h index 18ae6b4c455e..40050c3b90a5 100644 --- a/sys/dev/rtwn/if_rtwnvar.h +++ b/sys/dev/rtwn/if_rtwnvar.h @@ -25,8 +25,6 @@ #define RTWN_TX_DESC_SIZE 64 -#define RTWN_TXBUFSZ (16 * 1024) - #define RTWN_BCN_MAX_SIZE 512 #define RTWN_CAM_ENTRY_LIMIT 64 diff --git a/sys/dev/rtwn/pci/rtwn_pci_attach.c b/sys/dev/rtwn/pci/rtwn_pci_attach.c index 3af8d176f790..392279cb7149 100644 --- a/sys/dev/rtwn/pci/rtwn_pci_attach.c +++ b/sys/dev/rtwn/pci/rtwn_pci_attach.c @@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include static device_probe_t rtwn_pci_probe; @@ -133,7 +132,7 @@ rtwn_pci_alloc_rx_list(struct rtwn_softc *sc) int i, error; /* Allocate Rx descriptors. */ - size = sizeof(struct r92ce_rx_stat) * RTWN_PCI_RX_LIST_COUNT; + size = sizeof(struct rtwn_rx_stat_pci) * RTWN_PCI_RX_LIST_COUNT; error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 1, size, 0, NULL, NULL, &rx_ring->desc_dmat); diff --git a/sys/dev/rtwn/pci/rtwn_pci_rx.c b/sys/dev/rtwn/pci/rtwn_pci_rx.c index b747ef24cbbd..497ff04eb9aa 100644 --- a/sys/dev/rtwn/pci/rtwn_pci_rx.c +++ b/sys/dev/rtwn/pci/rtwn_pci_rx.c @@ -56,8 +56,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - void rtwn_pci_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, @@ -71,21 +69,21 @@ rtwn_pci_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, } void -rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *pc, struct r92ce_rx_stat *desc, - bus_addr_t addr, size_t len, int idx) +rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *pc, + struct rtwn_rx_stat_pci *desc, bus_addr_t addr, size_t len, int idx) { memset(desc, 0, sizeof(*desc)); - desc->rxdw0 = htole32(SM(R92C_RXDW0_PKTLEN, len) | - ((idx == RTWN_PCI_RX_LIST_COUNT - 1) ? R92C_RXDW0_EOR : 0)); + desc->rxdw0 = htole32(SM(RTWN_RXDW0_PKTLEN, len) | + ((idx == RTWN_PCI_RX_LIST_COUNT - 1) ? RTWN_RXDW0_EOR : 0)); desc->rxbufaddr = htole32(addr); bus_space_barrier(pc->pc_st, pc->pc_sh, 0, pc->pc_mapsize, BUS_SPACE_BARRIER_WRITE); - desc->rxdw0 |= htole32(R92C_RXDW0_OWN); + desc->rxdw0 |= htole32(RTWN_RXDW0_OWN); } static void -rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc, +rtwn_pci_rx_frame(struct rtwn_softc *sc, struct rtwn_rx_stat_pci *rx_desc, int desc_idx) { struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc); @@ -107,18 +105,18 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc, le32toh(rx_desc->rxbufaddr), le32toh(rx_desc->rxbufaddr64)); rxdw0 = le32toh(rx_desc->rxdw0); - if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) { + if (__predict_false(rxdw0 & (RTWN_RXDW0_CRCERR | RTWN_RXDW0_ICVERR))) { /* * This should not happen since we setup our Rx filter * to not receive these frames. */ RTWN_DPRINTF(sc, RTWN_DEBUG_RECV, "%s: RX flags error (%s)\n", __func__, - rxdw0 & R92C_RXDW0_CRCERR ? "CRC" : "ICV"); + rxdw0 & RTWN_RXDW0_CRCERR ? "CRC" : "ICV"); goto fail; } - pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN); + pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN); if (__predict_false(pktlen < sizeof(struct ieee80211_frame_ack) || pktlen > MJUMPAGESIZE)) { RTWN_DPRINTF(sc, RTWN_DEBUG_RECV, @@ -126,8 +124,8 @@ rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc, goto fail; } - infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8; - shift = MS(rxdw0, R92C_RXDW0_SHIFT); + infosz = MS(rxdw0, RTWN_RXDW0_INFOSZ) * 8; + shift = MS(rxdw0, RTWN_RXDW0_SHIFT); m1 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE); if (__predict_false(m1 == NULL)) { @@ -268,9 +266,9 @@ rtwn_pci_rx_done(struct rtwn_softc *sc) bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_POSTREAD); for (;;) { - struct r92ce_rx_stat *rx_desc = &ring->desc[ring->cur]; + struct rtwn_rx_stat_pci *rx_desc = &ring->desc[ring->cur]; - if (le32toh(rx_desc->rxdw0) & R92C_RXDW0_OWN) + if (le32toh(rx_desc->rxdw0) & RTWN_RXDW0_OWN) break; rtwn_pci_rx_frame(sc, rx_desc, ring->cur); diff --git a/sys/dev/rtwn/pci/rtwn_pci_rx.h b/sys/dev/rtwn/pci/rtwn_pci_rx.h index 265d32d8a117..30dd785a1e7a 100644 --- a/sys/dev/rtwn/pci/rtwn_pci_rx.h +++ b/sys/dev/rtwn/pci/rtwn_pci_rx.h @@ -21,7 +21,7 @@ void rtwn_pci_dma_map_addr(void *, bus_dma_segment_t *, int, int); void rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *, - struct r92ce_rx_stat *, bus_addr_t, size_t, int); + struct rtwn_rx_stat_pci *, bus_addr_t, size_t, int); void rtwn_pci_intr(void *); #endif /* RTWN_PCI_RX_H */ diff --git a/sys/dev/rtwn/pci/rtwn_pci_var.h b/sys/dev/rtwn/pci/rtwn_pci_var.h index 5a9e64e73bb5..194fab4a4736 100644 --- a/sys/dev/rtwn/pci/rtwn_pci_var.h +++ b/sys/dev/rtwn/pci/rtwn_pci_var.h @@ -23,9 +23,6 @@ #ifndef RTWN_PCI_VAR_H #define RTWN_PCI_VAR_H -#include - - #define RTWN_PCI_RX_LIST_COUNT 256 #define RTWN_PCI_TX_LIST_COUNT 256 @@ -36,7 +33,7 @@ struct rtwn_rx_data { }; struct rtwn_rx_ring { - struct r92ce_rx_stat *desc; + struct rtwn_rx_stat_pci *desc; bus_addr_t paddr; bus_dma_tag_t desc_dmat; bus_dmamap_t desc_map; diff --git a/sys/dev/rtwn/usb/rtwn_usb_attach.c b/sys/dev/rtwn/usb/rtwn_usb_attach.c index 6beed50ab357..959184e7f43a 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_attach.c +++ b/sys/dev/rtwn/usb/rtwn_usb_attach.c @@ -155,7 +155,7 @@ rtwn_usb_alloc_tx_list(struct rtwn_softc *sc) int error, i; error = rtwn_usb_alloc_list(sc, uc->uc_tx, RTWN_USB_TX_LIST_COUNT, - RTWN_TXBUFSZ); + RTWN_USB_TXBUFSZ); if (error != 0) return (error); diff --git a/sys/dev/rtwn/usb/rtwn_usb_ep.c b/sys/dev/rtwn/usb/rtwn_usb_ep.c index 52c628d5a9a7..596265d4d4cc 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_ep.c +++ b/sys/dev/rtwn/usb/rtwn_usb_ep.c @@ -73,7 +73,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, - .bufsize = RTWN_TXBUFSZ, + .bufsize = RTWN_USB_TXBUFSZ, .flags = { .ext_buffer = 1, .pipe_bof = 1, @@ -86,7 +86,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, - .bufsize = RTWN_TXBUFSZ, + .bufsize = RTWN_USB_TXBUFSZ, .flags = { .ext_buffer = 1, .pipe_bof = 1, @@ -99,7 +99,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, - .bufsize = RTWN_TXBUFSZ, + .bufsize = RTWN_USB_TXBUFSZ, .flags = { .ext_buffer = 1, .pipe_bof = 1, @@ -112,7 +112,7 @@ static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, - .bufsize = RTWN_TXBUFSZ, + .bufsize = RTWN_USB_TXBUFSZ, .flags = { .ext_buffer = 1, .pipe_bof = 1, diff --git a/sys/dev/rtwn/usb/rtwn_usb_rx.c b/sys/dev/rtwn/usb/rtwn_usb_rx.c index 0fe7482930f5..4f66669158a8 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_rx.c +++ b/sys/dev/rtwn/usb/rtwn_usb_rx.c @@ -63,12 +63,9 @@ __FBSDID("$FreeBSD$"); #include #include -#include /* for CAM_ALGO_NONE */ -#include - static struct mbuf * -rtwn_rx_copy_to_mbuf(struct rtwn_softc *sc, struct r92c_rx_stat *stat, +rtwn_rx_copy_to_mbuf(struct rtwn_softc *sc, struct rtwn_rx_stat_common *stat, int totlen) { struct ieee80211com *ic = &sc->sc_ic; @@ -93,18 +90,18 @@ rtwn_rx_copy_to_mbuf(struct rtwn_softc *sc, struct r92c_rx_stat *stat, return (NULL); rxdw0 = le32toh(stat->rxdw0); - if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) { + if (__predict_false(rxdw0 & (RTWN_RXDW0_CRCERR | RTWN_RXDW0_ICVERR))) { /* * This should not happen since we setup our Rx filter * to not receive these frames. */ RTWN_DPRINTF(sc, RTWN_DEBUG_RECV, "%s: RX flags error (%s)\n", __func__, - rxdw0 & R92C_RXDW0_CRCERR ? "CRC" : "ICV"); + rxdw0 & RTWN_RXDW0_CRCERR ? "CRC" : "ICV"); goto fail; } - pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN); + pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN); if (__predict_false(pktlen < sizeof(struct ieee80211_frame_ack))) { /* * Should not happen (because of Rx filter setup). @@ -140,21 +137,21 @@ static struct mbuf * rtwn_rxeof(struct rtwn_softc *sc, uint8_t *buf, int len) { struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc); - struct r92c_rx_stat *stat; + struct rtwn_rx_stat_common *stat; struct mbuf *m, *m0 = NULL; uint32_t rxdw0; int totlen, pktlen, infosz; /* Process packets. */ while (len >= sizeof(*stat)) { - stat = (struct r92c_rx_stat *)buf; + stat = (struct rtwn_rx_stat_common *)buf; rxdw0 = le32toh(stat->rxdw0); - pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN); + pktlen = MS(rxdw0, RTWN_RXDW0_PKTLEN); if (__predict_false(pktlen == 0)) break; - infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8; + infosz = MS(rxdw0, RTWN_RXDW0_INFOSZ) * 8; /* Make sure everything fits in xfer. */ totlen = sizeof(*stat) + infosz + pktlen; @@ -193,7 +190,7 @@ rtwn_report_intr(struct rtwn_usb_softc *uc, struct usb_xfer *xfer, usbd_xfer_status(xfer, &len, NULL, NULL, NULL); - if (__predict_false(len < sizeof(struct r92c_rx_stat))) { + if (__predict_false(len < sizeof(struct rtwn_rx_stat_common))) { counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -238,11 +235,11 @@ rtwn_report_intr(struct rtwn_usb_softc *uc, struct usb_xfer *xfer, static struct ieee80211_node * rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m) { - struct r92c_rx_stat stat; + struct rtwn_rx_stat_common stat; /* Imitate PCIe layout. */ - m_copydata(m, 0, sizeof(struct r92c_rx_stat), (caddr_t)&stat); - m_adj(m, sizeof(struct r92c_rx_stat)); + m_copydata(m, 0, sizeof(stat), (caddr_t)&stat); + m_adj(m, sizeof(stat)); return (rtwn_rx_common(sc, m, &stat)); } diff --git a/sys/dev/rtwn/usb/rtwn_usb_tx.c b/sys/dev/rtwn/usb/rtwn_usb_tx.c index c30e9e746985..2c5d55d3a56b 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_tx.c +++ b/sys/dev/rtwn/usb/rtwn_usb_tx.c @@ -233,6 +233,9 @@ rtwn_usb_tx_start(struct rtwn_softc *sc, struct ieee80211_node *ni, RTWN_ASSERT_LOCKED(sc); + if (m->m_pkthdr.len + sc->txdesc_len > RTWN_USB_TXBUFSZ) + return (EINVAL); + data = rtwn_usb_getbuf(uc); if (data == NULL) return (ENOBUFS); diff --git a/sys/dev/rtwn/usb/rtwn_usb_var.h b/sys/dev/rtwn/usb/rtwn_usb_var.h index be7f8f198834..aa0f987b7730 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_var.h +++ b/sys/dev/rtwn/usb/rtwn_usb_var.h @@ -21,6 +21,8 @@ #ifndef RTWN_USBVAR_H #define RTWN_USBVAR_H +#define RTWN_USB_TXBUFSZ (16 * 1024) + #define RTWN_IFACE_INDEX 0 #define RTWN_USB_RX_LIST_COUNT 1 diff --git a/sys/dev/sdhci/fsl_sdhci.c b/sys/dev/sdhci/fsl_sdhci.c index 1b5f9371fb51..08f5b94df83d 100644 --- a/sys/dev/sdhci/fsl_sdhci.c +++ b/sys/dev/sdhci/fsl_sdhci.c @@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$"); * This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs). */ +#include "opt_mmccam.h" + #include #include #include @@ -911,7 +913,11 @@ fsl_sdhci_attach(device_t dev) bus_generic_probe(dev); bus_generic_attach(dev); +#ifdef MMCCAM + sdhci_cam_start_slot(&sc->slot); +#else sdhci_start_slot(&sc->slot); +#endif return (0); @@ -988,4 +994,7 @@ static driver_t fsl_sdhci_driver = { DRIVER_MODULE(sdhci_fsl, simplebus, fsl_sdhci_driver, fsl_sdhci_devclass, NULL, NULL); MODULE_DEPEND(sdhci_fsl, sdhci, 1, 1, 1); + +#ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_fsl); +#endif diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 0f842b3492b6..e6bb25969c3e 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -48,13 +48,21 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include +#include +#include +#include + #include "mmcbr_if.h" #include "sdhci.h" #include "sdhci_if.h" +#include "opt_mmccam.h" + SYSCTL_NODE(_hw, OID_AUTO, sdhci, CTLFLAG_RD, 0, "sdhci driver"); -static int sdhci_debug; +static int sdhci_debug = 0; SYSCTL_INT(_hw_sdhci, OID_AUTO, debug, CTLFLAG_RWTUN, &sdhci_debug, 0, "Debug level"); u_int sdhci_quirk_clear = 0; @@ -83,6 +91,16 @@ static void sdhci_start_data(struct sdhci_slot *slot, struct mmc_data *data); static void sdhci_card_poll(void *); static void sdhci_card_task(void *, int); +#ifdef MMCCAM +/* CAM-related */ +int sdhci_cam_get_possible_host_clock(struct sdhci_slot *slot, int proposed_clock); +static int sdhci_cam_update_ios(struct sdhci_slot *slot); +static int sdhci_cam_request(struct sdhci_slot *slot, union ccb *ccb); +static void sdhci_cam_action(struct cam_sim *sim, union ccb *ccb); +static void sdhci_cam_poll(struct cam_sim *sim); +static int sdhci_cam_settran_settings(struct sdhci_slot *slot, union ccb *ccb); +#endif + /* helper routines */ static void sdhci_dumpregs(struct sdhci_slot *slot); static int slot_printf(struct sdhci_slot *slot, const char * fmt, ...) @@ -366,6 +384,7 @@ sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock) static void sdhci_set_power(struct sdhci_slot *slot, u_char power) { + int i; uint8_t pwr; if (slot->power == power) @@ -394,9 +413,20 @@ sdhci_set_power(struct sdhci_slot *slot, u_char power) break; } WR1(slot, SDHCI_POWER_CONTROL, pwr); - /* Turn on the power. */ + /* + * Turn on VDD1 power. Note that at least some Intel controllers can + * fail to enable bus power on the first try after transiting from D3 + * to D0, so we give them up to 2 ms. + */ pwr |= SDHCI_POWER_ON; - WR1(slot, SDHCI_POWER_CONTROL, pwr); + for (i = 0; i < 20; i++) { + WR1(slot, SDHCI_POWER_CONTROL, pwr); + if (RD1(slot, SDHCI_POWER_CONTROL) & SDHCI_POWER_ON) + break; + DELAY(100); + } + if (!(RD1(slot, SDHCI_POWER_CONTROL) & SDHCI_POWER_ON)) + slot_printf(slot, "Bus power failed to enable"); if (slot->quirks & SDHCI_QUIRK_INTEL_POWER_UP_RESET) { WR1(slot, SDHCI_POWER_CONTROL, pwr | 0x10); @@ -519,25 +549,87 @@ sdhci_card_task(void *arg, int pending __unused) SDHCI_LOCK(slot); if (SDHCI_GET_CARD_PRESENT(slot->bus, slot)) { +#ifdef MMCCAM + if (slot->card_present == 0) { +#else if (slot->dev == NULL) { +#endif /* If card is present - attach mmc bus. */ if (bootverbose || sdhci_debug) slot_printf(slot, "Card inserted\n"); +#ifdef MMCCAM + slot->card_present = 1; + union ccb *ccb; + uint32_t pathid; + pathid = cam_sim_path(slot->sim); + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + slot_printf(slot, "Unable to alloc CCB for rescan\n"); + SDHCI_UNLOCK(slot); + return; + } + + /* + * We create a rescan request for BUS:0:0, since the card + * will be at lun 0. + */ + if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, + /* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { + slot_printf(slot, "Unable to create path for rescan\n"); + SDHCI_UNLOCK(slot); + xpt_free_ccb(ccb); + return; + } + SDHCI_UNLOCK(slot); + xpt_rescan(ccb); +#else slot->dev = device_add_child(slot->bus, "mmc", -1); device_set_ivars(slot->dev, slot); SDHCI_UNLOCK(slot); device_probe_and_attach(slot->dev); +#endif } else SDHCI_UNLOCK(slot); } else { +#ifdef MMCCAM + if (slot->card_present == 1) { +#else if (slot->dev != NULL) { +#endif /* If no card present - detach mmc bus. */ if (bootverbose || sdhci_debug) slot_printf(slot, "Card removed\n"); d = slot->dev; slot->dev = NULL; +#ifdef MMCCAM + slot->card_present = 0; + union ccb *ccb; + uint32_t pathid; + pathid = cam_sim_path(slot->sim); + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + slot_printf(slot, "Unable to alloc CCB for rescan\n"); + SDHCI_UNLOCK(slot); + return; + } + + /* + * We create a rescan request for BUS:0:0, since the card + * will be at lun 0. + */ + if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, + /* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { + slot_printf(slot, "Unable to create path for rescan\n"); + SDHCI_UNLOCK(slot); + xpt_free_ccb(ccb); + return; + } + SDHCI_UNLOCK(slot); + xpt_rescan(ccb); +#else SDHCI_UNLOCK(slot); device_delete_child(slot->bus, d); +#endif } else SDHCI_UNLOCK(slot); } @@ -559,7 +651,11 @@ sdhci_handle_card_present_locked(struct sdhci_slot *slot, bool is_present) * because once power is removed, a full card re-init is needed, and * that happens by deleting and recreating the child device. */ +#ifdef MMCCAM + was_present = slot->card_present; +#else was_present = slot->dev != NULL; +#endif if (!was_present && is_present) { taskqueue_enqueue_timeout(taskqueue_swi_giant, &slot->card_delayed_task, -SDHCI_INSERT_DELAY_TICKS); @@ -595,6 +691,7 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) int err; SDHCI_LOCK_INIT(slot); + slot->num = num; slot->bus = dev; @@ -1017,6 +1114,30 @@ sdhci_generic_switch_vccq(device_t brdev __unused, device_t reqdev) return (err); } +#ifdef MMCCAM +static void +sdhci_req_done(struct sdhci_slot *slot) +{ + union ccb *ccb; + + if (sdhci_debug > 1) + slot_printf(slot, "%s\n", __func__); + if (slot->ccb != NULL && slot->curcmd != NULL) { + callout_stop(&slot->timeout_callout); + ccb = slot->ccb; + slot->ccb = NULL; + slot->curcmd = NULL; + + /* Tell CAM the request is finished */ + struct ccb_mmcio *mmcio; + mmcio = &ccb->mmcio; + + ccb->ccb_h.status = + (mmcio->cmd.error == 0 ? CAM_REQ_CMP : CAM_REQ_CMP_ERR); + xpt_done(ccb); + } +} +#else static void sdhci_req_done(struct sdhci_slot *slot) { @@ -1030,6 +1151,7 @@ sdhci_req_done(struct sdhci_slot *slot) req->done(req); } } +#endif static void sdhci_timeout(void *arg) @@ -1060,8 +1182,16 @@ sdhci_set_transfer_mode(struct sdhci_slot *slot, struct mmc_data *data) mode |= SDHCI_TRNS_MULTI; if (data->flags & MMC_DATA_READ) mode |= SDHCI_TRNS_READ; +#ifdef MMCCAM + struct ccb_mmcio *mmcio; + mmcio = &slot->ccb->mmcio; + if (mmcio->stop.opcode == MMC_STOP_TRANSMISSION + && !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) + mode |= SDHCI_TRNS_ACMD12; +#else if (slot->req->stop && !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) mode |= SDHCI_TRNS_ACMD12; +#endif if (slot->flags & SDHCI_USE_DMA) mode |= SDHCI_TRNS_DMA; @@ -1094,6 +1224,9 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) if (!SDHCI_GET_CARD_PRESENT(slot->bus, slot) || slot->power == 0 || slot->clock == 0) { + slot_printf(slot, + "Cannot issue a command (power=%d clock=%d)", + slot->power, slot->clock); cmd->error = MMC_ERR_FAILED; sdhci_req_done(slot); return; @@ -1101,11 +1234,17 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) /* Always wait for free CMD bus. */ mask = SDHCI_CMD_INHIBIT; /* Wait for free DAT if we have data or busy signal. */ - if (cmd->data || (cmd->flags & MMC_RSP_BUSY)) + if (cmd->data != NULL || (cmd->flags & MMC_RSP_BUSY)) mask |= SDHCI_DAT_INHIBIT; /* We shouldn't wait for DAT for stop commands. */ +#ifdef MMCCAM + struct ccb_mmcio *mmcio = &slot->ccb->mmcio; + if (cmd == &mmcio->stop) + mask &= ~SDHCI_DAT_INHIBIT; +#else if (cmd == slot->req->stop) mask &= ~SDHCI_DAT_INHIBIT; +#endif /* * Wait for bus no more then 250 ms. Typically there will be no wait * here at all, but when writing a crash dump we may be bypassing the @@ -1143,7 +1282,7 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) flags |= SDHCI_CMD_CRC; if (cmd->flags & MMC_RSP_OPCODE) flags |= SDHCI_CMD_INDEX; - if (cmd->data) + if (cmd->data != NULL) flags |= SDHCI_CMD_DATA; if (cmd->opcode == MMC_STOP_TRANSMISSION) flags |= SDHCI_CMD_TYPE_ABORT; @@ -1162,6 +1301,8 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) WR4(slot, SDHCI_ARGUMENT, cmd->arg); /* Set data transfer mode. */ sdhci_set_transfer_mode(slot, cmd->data); + if (sdhci_debug > 1) + slot_printf(slot, "Starting command!\n"); /* Start command. */ WR2(slot, SDHCI_COMMAND_FLAGS, (cmd->opcode << 8) | (flags & 0xff)); /* Start timeout callout. */ @@ -1176,6 +1317,9 @@ sdhci_finish_command(struct sdhci_slot *slot) uint32_t val; uint8_t extra; + if (sdhci_debug > 1) + slot_printf(slot, "%s: called, err %d flags %d\n", + __func__, slot->curcmd->error, slot->curcmd->flags); slot->cmd_done = 1; /* * Interrupt aggregation: Restore command interrupt. @@ -1209,6 +1353,11 @@ sdhci_finish_command(struct sdhci_slot *slot) } else slot->curcmd->resp[0] = RD4(slot, SDHCI_RESPONSE); } + if (sdhci_debug > 1) + printf("Resp: %02x %02x %02x %02x\n", + slot->curcmd->resp[0], slot->curcmd->resp[1], + slot->curcmd->resp[2], slot->curcmd->resp[3]); + /* If data ready - finish. */ if (slot->data_done) sdhci_start(slot); @@ -1289,6 +1438,11 @@ sdhci_start_data(struct sdhci_slot *slot, struct mmc_data *data) (data->len < 512) ? data->len : 512)); /* Set block count. */ WR2(slot, SDHCI_BLOCK_COUNT, (data->len + 511) / 512); + + if (sdhci_debug > 1) + slot_printf(slot, "Block size: %02x, count %lu\n", + (unsigned int)SDHCI_MAKE_BLKSZ(DMA_BOUNDARY, (data->len < 512) ? data->len : 512), + (unsigned long)(data->len + 511) / 512); } void @@ -1330,6 +1484,47 @@ sdhci_finish_data(struct sdhci_slot *slot) sdhci_start(slot); } +#ifdef MMCCAM +static void +sdhci_start(struct sdhci_slot *slot) +{ + union ccb *ccb; + + ccb = slot->ccb; + if (ccb == NULL) + return; + + struct ccb_mmcio *mmcio; + mmcio = &ccb->mmcio; + + if (!(slot->flags & CMD_STARTED)) { + slot->flags |= CMD_STARTED; + sdhci_start_command(slot, &mmcio->cmd); + return; + } + + /* + * Old stack doesn't use this! + * Enabling this code causes significant performance degradation + * and IRQ storms on BBB, Wandboard behaves fine. + * Not using this code does no harm... + if (!(slot->flags & STOP_STARTED) && mmcio->stop.opcode != 0) { + slot->flags |= STOP_STARTED; + sdhci_start_command(slot, &mmcio->stop); + return; + } + */ + if (sdhci_debug > 1) + slot_printf(slot, "result: %d\n", mmcio->cmd.error); + if (mmcio->cmd.error == 0 && + (slot->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { + sdhci_reset(slot, SDHCI_RESET_CMD); + sdhci_reset(slot, SDHCI_RESET_DATA); + } + + sdhci_req_done(slot); +} +#else static void sdhci_start(struct sdhci_slot *slot) { @@ -1362,6 +1557,7 @@ sdhci_start(struct sdhci_slot *slot) sdhci_req_done(slot); } +#endif int sdhci_generic_request(device_t brdev __unused, device_t reqdev, @@ -1629,6 +1825,7 @@ sdhci_generic_intr(struct sdhci_slot *slot) "Card is consuming too much power!\n"); intmask &= ~SDHCI_INT_BUS_POWER; } + /* The rest is unknown. */ if (intmask) { WR4(slot, SDHCI_INT_STATUS, intmask); @@ -1712,6 +1909,8 @@ sdhci_generic_write_ivar(device_t bus, device_t child, int which, uint32_t clock, max_clock; int i; + if (sdhci_debug > 1) + slot_printf(slot, "%s: var=%d\n", __func__, which); switch (which) { default: return (EINVAL); @@ -1777,4 +1976,325 @@ sdhci_generic_write_ivar(device_t bus, device_t child, int which, return (0); } +#ifdef MMCCAM +/* CAM-related functions */ +#include +#include +#include +#include +#include + +void +sdhci_cam_start_slot(struct sdhci_slot *slot) +{ + if ((slot->devq = cam_simq_alloc(1)) == NULL) { + goto fail; + } + + mtx_init(&slot->sim_mtx, "sdhcisim", NULL, MTX_DEF); + slot->sim = cam_sim_alloc(sdhci_cam_action, sdhci_cam_poll, + "sdhci_slot", slot, device_get_unit(slot->bus), + &slot->sim_mtx, 1, 1, slot->devq); + + if (slot->sim == NULL) { + cam_simq_free(slot->devq); + slot_printf(slot, "cannot allocate CAM SIM\n"); + goto fail; + } + + mtx_lock(&slot->sim_mtx); + if (xpt_bus_register(slot->sim, slot->bus, 0) != 0) { + slot_printf(slot, + "cannot register SCSI pass-through bus\n"); + cam_sim_free(slot->sim, FALSE); + cam_simq_free(slot->devq); + mtx_unlock(&slot->sim_mtx); + goto fail; + } + + mtx_unlock(&slot->sim_mtx); + /* End CAM-specific init */ + slot->card_present = 0; + sdhci_card_task(slot, 0); + return; + +fail: + if (slot->sim != NULL) { + mtx_lock(&slot->sim_mtx); + xpt_bus_deregister(cam_sim_path(slot->sim)); + cam_sim_free(slot->sim, FALSE); + mtx_unlock(&slot->sim_mtx); + } + + if (slot->devq != NULL) + cam_simq_free(slot->devq); +} + +static void +sdhci_cam_handle_mmcio(struct cam_sim *sim, union ccb *ccb) +{ + struct sdhci_slot *slot; + + slot = cam_sim_softc(sim); + + sdhci_cam_request(slot, ccb); +} + +void +sdhci_cam_action(struct cam_sim *sim, union ccb *ccb) +{ + struct sdhci_slot *slot; + + slot = cam_sim_softc(sim); + if (slot == NULL) { + ccb->ccb_h.status = CAM_SEL_TIMEOUT; + xpt_done(ccb); + return; + } + + mtx_assert(&slot->sim_mtx, MA_OWNED); + + switch (ccb->ccb_h.func_code) { + case XPT_PATH_INQ: + { + struct ccb_pathinq *cpi; + + cpi = &ccb->cpi; + cpi->version_num = 1; + cpi->hba_inquiry = 0; + cpi->target_sprt = 0; + cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN; + cpi->hba_eng_cnt = 0; + cpi->max_target = 0; + cpi->max_lun = 0; + cpi->initiator_id = 1; + cpi->maxio = MAXPHYS; + strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); + strncpy(cpi->hba_vid, "Deglitch Networks", HBA_IDLEN); + strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->unit_number = cam_sim_unit(sim); + cpi->bus_id = cam_sim_bus(sim); + cpi->base_transfer_speed = 100; /* XXX WTF? */ + cpi->protocol = PROTO_MMCSD; + cpi->protocol_version = SCSI_REV_0; + cpi->transport = XPORT_MMCSD; + cpi->transport_version = 0; + + cpi->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_GET_TRAN_SETTINGS: + { + struct ccb_trans_settings *cts = &ccb->cts; + + if (sdhci_debug > 1) + slot_printf(slot, "Got XPT_GET_TRAN_SETTINGS\n"); + + cts->protocol = PROTO_MMCSD; + cts->protocol_version = 1; + cts->transport = XPORT_MMCSD; + cts->transport_version = 1; + cts->xport_specific.valid = 0; + cts->proto_specific.mmc.host_ocr = slot->host.host_ocr; + cts->proto_specific.mmc.host_f_min = slot->host.f_min; + cts->proto_specific.mmc.host_f_max = slot->host.f_max; + cts->proto_specific.mmc.host_caps = slot->host.caps; + memcpy(&cts->proto_specific.mmc.ios, &slot->host.ios, sizeof(struct mmc_ios)); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_SET_TRAN_SETTINGS: + { + if (sdhci_debug > 1) + slot_printf(slot, "Got XPT_SET_TRAN_SETTINGS\n"); + sdhci_cam_settran_settings(slot, ccb); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_RESET_BUS: + if (sdhci_debug > 1) + slot_printf(slot, "Got XPT_RESET_BUS, ACK it...\n"); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + case XPT_MMC_IO: + /* + * Here is the HW-dependent part of + * sending the command to the underlying h/w + * At some point in the future an interrupt comes. + * Then the request will be marked as completed. + */ + if (sdhci_debug > 1) + slot_printf(slot, "Got XPT_MMC_IO\n"); + ccb->ccb_h.status = CAM_REQ_INPROG; + + sdhci_cam_handle_mmcio(sim, ccb); + return; + /* NOTREACHED */ + break; + default: + ccb->ccb_h.status = CAM_REQ_INVALID; + break; + } + xpt_done(ccb); + return; +} + +void +sdhci_cam_poll(struct cam_sim *sim) +{ + return; +} + +int sdhci_cam_get_possible_host_clock(struct sdhci_slot *slot, int proposed_clock) { + int max_clock, clock, i; + + if (proposed_clock == 0) + return 0; + max_clock = slot->max_clk; + clock = max_clock; + + if (slot->version < SDHCI_SPEC_300) { + for (i = 0; i < SDHCI_200_MAX_DIVIDER; + i <<= 1) { + if (clock <= proposed_clock) + break; + clock >>= 1; + } + } else { + for (i = 0; i < SDHCI_300_MAX_DIVIDER; + i += 2) { + if (clock <= proposed_clock) + break; + clock = max_clock / (i + 2); + } + } + return clock; +} + +int +sdhci_cam_settran_settings(struct sdhci_slot *slot, union ccb *ccb) +{ + struct mmc_ios *ios; + struct mmc_ios *new_ios; + struct ccb_trans_settings_mmc *cts; + + ios = &slot->host.ios; + + cts = &ccb->cts.proto_specific.mmc; + new_ios = &cts->ios; + + /* Update only requested fields */ + if (cts->ios_valid & MMC_CLK) { + ios->clock = sdhci_cam_get_possible_host_clock(slot, new_ios->clock); + slot_printf(slot, "Clock => %d\n", ios->clock); + } + if (cts->ios_valid & MMC_VDD) { + ios->vdd = new_ios->vdd; + slot_printf(slot, "VDD => %d\n", ios->vdd); + } + if (cts->ios_valid & MMC_CS) { + ios->chip_select = new_ios->chip_select; + slot_printf(slot, "CS => %d\n", ios->chip_select); + } + if (cts->ios_valid & MMC_BW) { + ios->bus_width = new_ios->bus_width; + slot_printf(slot, "Bus width => %d\n", ios->bus_width); + } + if (cts->ios_valid & MMC_PM) { + ios->power_mode = new_ios->power_mode; + slot_printf(slot, "Power mode => %d\n", ios->power_mode); + } + if (cts->ios_valid & MMC_BT) { + ios->timing = new_ios->timing; + slot_printf(slot, "Timing => %d\n", ios->timing); + } + if (cts->ios_valid & MMC_BM) { + ios->bus_mode = new_ios->bus_mode; + slot_printf(slot, "Bus mode => %d\n", ios->bus_mode); + } + + /* XXX Provide a way to call a chip-specific IOS update, required for TI */ + return (sdhci_cam_update_ios(slot)); +} + +int +sdhci_cam_update_ios(struct sdhci_slot *slot) +{ + struct mmc_ios *ios = &slot->host.ios; + + slot_printf(slot, "%s: power_mode=%d, clk=%d, bus_width=%d, timing=%d\n", + __func__, ios->power_mode, ios->clock, ios->bus_width, ios->timing); + SDHCI_LOCK(slot); + /* Do full reset on bus power down to clear from any state. */ + if (ios->power_mode == power_off) { + WR4(slot, SDHCI_SIGNAL_ENABLE, 0); + sdhci_init(slot); + } + /* Configure the bus. */ + sdhci_set_clock(slot, ios->clock); + sdhci_set_power(slot, (ios->power_mode == power_off) ? 0 : ios->vdd); + if (ios->bus_width == bus_width_8) { + slot->hostctrl |= SDHCI_CTRL_8BITBUS; + slot->hostctrl &= ~SDHCI_CTRL_4BITBUS; + } else if (ios->bus_width == bus_width_4) { + slot->hostctrl &= ~SDHCI_CTRL_8BITBUS; + slot->hostctrl |= SDHCI_CTRL_4BITBUS; + } else if (ios->bus_width == bus_width_1) { + slot->hostctrl &= ~SDHCI_CTRL_8BITBUS; + slot->hostctrl &= ~SDHCI_CTRL_4BITBUS; + } else { + panic("Invalid bus width: %d", ios->bus_width); + } + if (ios->timing == bus_timing_hs && + !(slot->quirks & SDHCI_QUIRK_DONT_SET_HISPD_BIT)) + slot->hostctrl |= SDHCI_CTRL_HISPD; + else + slot->hostctrl &= ~SDHCI_CTRL_HISPD; + WR1(slot, SDHCI_HOST_CONTROL, slot->hostctrl); + /* Some controllers like reset after bus changes. */ + if(slot->quirks & SDHCI_QUIRK_RESET_ON_IOS) + sdhci_reset(slot, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + + SDHCI_UNLOCK(slot); + return (0); +} + +int +sdhci_cam_request(struct sdhci_slot *slot, union ccb *ccb) +{ + struct ccb_mmcio *mmcio; + + mmcio = &ccb->mmcio; + + SDHCI_LOCK(slot); +/* if (slot->req != NULL) { + SDHCI_UNLOCK(slot); + return (EBUSY); + } +*/ + if (sdhci_debug > 1) { + slot_printf(slot, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n", + mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags, + mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0, + mmcio->cmd.data != NULL ? mmcio->cmd.data->flags: 0); + } + if (mmcio->cmd.data != NULL) { + if (mmcio->cmd.data->len == 0 || mmcio->cmd.data->flags == 0) + panic("data->len = %d, data->flags = %d -- something is b0rked", + (int)mmcio->cmd.data->len, mmcio->cmd.data->flags); + } + slot->ccb = ccb; + slot->flags = 0; + sdhci_start(slot); + SDHCI_UNLOCK(slot); + if (dumping) { + while (slot->ccb != NULL) { + sdhci_generic_intr(slot); + DELAY(10); + } + } + return (0); +} +#endif /* MMCCAM */ + MODULE_VERSION(sdhci, 1); diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index 814f81ed5407..52d176009179 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -28,6 +28,8 @@ #ifndef __SDHCI_H__ #define __SDHCI_H__ +#include "opt_mmccam.h" + #define DMA_BLOCK_SIZE 4096 #define DMA_BOUNDARY 0 /* DMA reload every 4K */ @@ -367,6 +369,15 @@ struct sdhci_slot { #define SDHCI_USE_DMA 4 /* Use DMA for this req. */ #define PLATFORM_DATA_STARTED 8 /* Data xfer is handled by platform */ struct mtx mtx; /* Slot mutex */ + +#ifdef MMCCAM + /* CAM stuff */ + union ccb *ccb; + struct cam_devq *devq; + struct cam_sim *sim; + struct mtx sim_mtx; + u_char card_present; /* XXX Maybe derive this from elsewhere? */ +#endif }; int sdhci_generic_read_ivar(device_t bus, device_t child, int which, @@ -393,4 +404,9 @@ bool sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot); void sdhci_generic_set_uhs_timing(device_t brdev, struct sdhci_slot *slot); void sdhci_handle_card_present(struct sdhci_slot *slot, bool is_present); +#ifdef MMCCAM +/* CAM-related */ +void sdhci_cam_start_slot(struct sdhci_slot *slot); +#endif + #endif /* __SDHCI_H__ */ diff --git a/sys/dev/sdhci/sdhci_acpi.c b/sys/dev/sdhci/sdhci_acpi.c index ea5ed70b0877..e6c63824baf9 100644 --- a/sys/dev/sdhci/sdhci_acpi.c +++ b/sys/dev/sdhci/sdhci_acpi.c @@ -400,4 +400,7 @@ static devclass_t sdhci_acpi_devclass; DRIVER_MODULE(sdhci_acpi, acpi, sdhci_acpi_driver, sdhci_acpi_devclass, NULL, NULL); MODULE_DEPEND(sdhci_acpi, sdhci, 1, 1, 1); + +#ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_acpi); +#endif diff --git a/sys/dev/sdhci/sdhci_pci.c b/sys/dev/sdhci/sdhci_pci.c index 9c59d322d6e6..de798cc29e18 100644 --- a/sys/dev/sdhci/sdhci_pci.c +++ b/sys/dev/sdhci/sdhci_pci.c @@ -26,6 +26,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_mmccam.h" + #include #include #include @@ -396,8 +398,13 @@ sdhci_pci_attach(device_t dev) device_printf(dev, "Can't setup IRQ\n"); pci_enable_busmaster(dev); /* Process cards detection. */ - for (i = 0; i < sc->num_slots; i++) + for (i = 0; i < sc->num_slots; i++) { +#ifdef MMCCAM + sdhci_cam_start_slot(&sc->slots[i]); +#else sdhci_start_slot(&sc->slots[i]); +#endif + } return (0); } @@ -518,4 +525,7 @@ static devclass_t sdhci_pci_devclass; DRIVER_MODULE(sdhci_pci, pci, sdhci_pci_driver, sdhci_pci_devclass, NULL, NULL); MODULE_DEPEND(sdhci_pci, sdhci, 1, 1, 1); + +#ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_pci); +#endif diff --git a/sys/dev/syscons/fonts/cursor.awk b/sys/dev/syscons/fonts/cursor.awk new file mode 100644 index 000000000000..425a0a5f67a5 --- /dev/null +++ b/sys/dev/syscons/fonts/cursor.awk @@ -0,0 +1,48 @@ +# $FreeBSD$ +# +# awk script to convert a bdf file to C declarations in a form specialized +# for the mouse cursors in syscons/scvgarndr.c. Usage: +# awk -f thisfile < file.bdf < file.c +# The accompanying syscons mouse cursor bdf file has specialized comments +# which this script converts to details in the C declarations. +# This is not a general conversion utility, but produces reasonable output +# if the input is for a monospaced font of size between 9x16 and 16x16. + +/^COMMENT cn.*mouse/ { + gsub("[(),]", "") + i = index($3, "-") + n = substr($3, 1, i - 1) + name[n] = $4 + i = index($4, "e") + j = index($4, "x") + k = index($4, "_") + width[n] = substr($4, i + 1, j - i - 1) + height[n] = substr($4, j + 1, k - j - 1) + baspect[n] = $6 + iaspect[n] = $8 +} +state == 0 && /^STARTCHAR/ { + n = substr($2, 5) + printf("static const struct mousedata %s = { {\n\t", name[n]) + state = 1 +} +state >= 1 && state < 7 || state >= 7 + 16 && state < 7 + 16 + 7 { + state++ + next +} +state >= 7 && state < 7 + 16 || state >= 7 + 16 + 7 && state < 7 + 16 + 7 +16 { + printf("0x%s,", $1) + if (state == 7 + 7 || state == 7 + 16 + 7 + 7) + printf("\n\t") + else if (state == 7 + 15) + printf(" }, {\n\t") + else if (state == 7 + 16 + 7 + 15) { + printf(" },\n\t%s, %s, %s, %s, \"%s\",", + width[n], height[n], baspect[n], iaspect[n], name[n]) + printf("\n};\n\n") + state = -1 + } else + printf(" ") + state++ + next +} diff --git a/sys/dev/syscons/fonts/cursor.bdf b/sys/dev/syscons/fonts/cursor.bdf new file mode 100644 index 000000000000..08b90009faea --- /dev/null +++ b/sys/dev/syscons/fonts/cursor.bdf @@ -0,0 +1,887 @@ +STARTFONT 2.1 +COMMENT +COMMENT $FreeBSD$ +COMMENT +COMMENT Mouse cursors for syscons. All except some unused ones are the +COMMENT main 10x16 one scaled down to 9x13 and/or scaled to minimize +COMMENT distortion with non-square pixels. Details of the scaling are +COMMENT given in the comments. E.g., for the main pair of glyphs cn 66-67, +COMMENT "mouse10x16_100 9++:13 (96), 8:11 (106)" says that: +COMMENT - the name of the glyph pair is mouse10x16_100 (it is more +COMMENT convenient to put the name in a comment than in STARTCHAR) +COMMENT - the size of the glyph pair is 10x16 (this is only used as part +COMMENT of the name, and is also in standard bdf info) +COMMENT - this glyph pair is designed for a pixel aspect ratio +COMMENT (ysize:xsize) of 100:100 (also just part of the name) +COMMENT - the arrowhead of the border glyph is in a rectangle of 9x13 +COMMENT pixels, but values 2 fudges larger than 9 should be tried in +COMMENT calculations of (diagonal) side lengths +COMMENT - the arrowhead of the border glyph has equal side lengths iff +COMMENT the aspect ratio is 96:100. Syscons makes choices based on +COMMENT this precise ratio for each half of the pair. +COMMENT - 8:11 (106) gives the arrowhead rectangle and preferred aspect +COMMENT ratio for the interior glyph. +COMMENT +COMMENT cn 0-1 mouse10x16_50 7++:16 (49), 6:13 (52) +COMMENT cn 16-17 mouse8x14_67 7++:13 (64), 6:11 (65) (360x400 0.675; also 320x350 24:35 = 0.686 and 320x400 3:5 = 0.600) +COMMENT cn 32-33 mouse8x13_75 6++:10 (75), 5:8 (80) +COMMENT cn 34-35 mouse10x16_75 7++:12 (72), 6:10 (75) +COMMENT cn 40-41 mouse9x16_84 8++:13 (78), 7:11 (82) (not used) +COMMENT cn 48-49 mouse9x13_90 8+:12 (89), 6:9 (89) +COMMENT cn 50-51 mouse10x16_90 10++:15 (89), 8:12 (89) +COMMENT cn 64-65 mouse9x13_100 8:11 (106), 6:8 (113) +COMMENT cn 66-67 mouse10x16_100 9++:13 (96), 8:11 (106) (640x480 and 1920x1080, also 1280x1024 15:16 = 0.9375, 640x400 6:5 = 1.2, 720x480 9:8 = 1.125) +COMMENT cn 72-73 mouse10x16_100large 10:14 (102), 7:10 (98) (use later) +COMMENT cn 74-75 mouse11x16_100 11++:16 (95), 10:14 (102) (use later) +COMMENT cn 80-81 mouse10x14_120 10+:13 (120), 7:9 (124) +COMMENT cn 82-83 mouse10x16_120 10+:13 (120), 7:9 (124) (720x400 1.35; also 640x350 48:35 = 1.371) +COMMENT cn 96-97 mouse9x13_133 9++:11 (142), 7:9 (124) +COMMENT cn 98-99 mouse10x16_133 10+:13 (120), 8:10 (133) (720x400 1.35; also 640x350 48:35 = 1.371) +COMMENT cn 112-113 mouse14x10_240 12+:9 (189), 8:6- (189) (640x200) +COMMENT cn 120-121 mouse9x9 (not used) +COMMENT cn 122-123 mouse11x11thick (not used) +FONT cursor-16x16 +SIZE 1 60 44 +FONTBOUNDINGBOX 16 16 0 0 +STARTPROPERTIES 10 +PIXEL_SIZE 16 +POINT_SIZE 11 +RESOLUTION_X 60 +RESOLUTION_Y 44 +FONT_ASCENT 12 +FONT_DESCENT 4 +AVERAGE_WIDTH 90 +SPACING "C" +DEFAULT_CHAR 32 +_XMBDFED_INFO "Edited with xmbdfed 4.7." +ENDPROPERTIES +CHARS 38 +STARTCHAR char0 +ENCODING 0 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8200 +8400 +8400 +8400 +9200 +B200 +A900 +C900 +8600 +ENDCHAR +STARTCHAR char1 +ENCODING 1 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7C00 +7800 +7800 +7800 +6C00 +4C00 +4600 +0600 +0000 +ENDCHAR +STARTCHAR char16 +ENCODING 16 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8700 +8400 +9200 +B200 +A900 +C900 +0600 +0000 +0000 +ENDCHAR +STARTCHAR char17 +ENCODING 17 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7800 +7800 +6C00 +4C00 +4600 +0600 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char32 +ENCODING 32 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8600 +8400 +B200 +D200 +0900 +0900 +0600 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char33 +ENCODING 33 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7800 +7800 +4C00 +0C00 +0600 +0600 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char34 +ENCODING 34 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8700 +8400 +9200 +B200 +C900 +0900 +0480 +0480 +0300 +ENDCHAR +STARTCHAR char35 +ENCODING 35 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7800 +7800 +6C00 +4C00 +0600 +0600 +0300 +0300 +0000 +ENDCHAR +STARTCHAR char40 +ENCODING 40 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +8780 +8200 +9200 +B900 +C900 +0480 +0480 +0300 +ENDCHAR +STARTCHAR char41 +ENCODING 41 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +7800 +7C00 +6C00 +4600 +0600 +0300 +0300 +0000 +ENDCHAR +STARTCHAR char48 +ENCODING 48 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8780 +9200 +B200 +D900 +8900 +0600 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char49 +ENCODING 49 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7800 +6C00 +4C00 +0600 +0600 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char50 +ENCODING 50 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +8040 +83E0 +8200 +9900 +A900 +C480 +8480 +0300 +ENDCHAR +STARTCHAR char51 +ENCODING 51 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +7F80 +7C00 +7C00 +6600 +4600 +0300 +0300 +0000 +ENDCHAR +STARTCHAR char64 +ENCODING 64 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8780 +B200 +D200 +8900 +0900 +0600 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char65 +ENCODING 65 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7800 +4C00 +0C00 +0600 +0600 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char66 +ENCODING 66 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +8040 +83C0 +9200 +A900 +C900 +0480 +0480 +0300 +ENDCHAR +STARTCHAR char67 +ENCODING 67 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +7F80 +7C00 +6C00 +4600 +0600 +0300 +0300 +0000 +ENDCHAR +STARTCHAR char72 +ENCODING 72 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +8000 +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +87C0 +9200 +A900 +C900 +8480 +0480 +0300 +ENDCHAR +STARTCHAR char73 +ENCODING 73 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +7800 +6C00 +4600 +0600 +0300 +0300 +0000 +0000 +ENDCHAR +STARTCHAR char74 +ENCODING 74 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +8040 +8020 +8010 +81F0 +8900 +9480 +A480 +C240 +ENDCHAR +STARTCHAR char75 +ENCODING 75 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +7F80 +7FC0 +7FE0 +7E00 +7600 +6300 +4300 +0180 +ENDCHAR +STARTCHAR char80 +ENCODING 80 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +97C0 +B200 +F200 +C900 +8900 +0600 +0000 +0000 +ENDCHAR +STARTCHAR char81 +ENCODING 81 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +6800 +4C00 +0C00 +0600 +0600 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char82 +ENCODING 82 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +97C0 +B200 +F200 +C900 +8900 +0480 +0480 +0300 +ENDCHAR +STARTCHAR char83 +ENCODING 83 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +6800 +4C00 +0C00 +0600 +0600 +0300 +0300 +0000 +ENDCHAR +STARTCHAR char96 +ENCODING 96 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +9780 +B200 +C900 +0900 +0600 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char97 +ENCODING 97 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +6800 +4C00 +0600 +0600 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char98 +ENCODING 98 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +C000 +A000 +9000 +8800 +8400 +8200 +8100 +8080 +8040 +93E0 +B200 +C900 +8900 +0480 +0480 +0300 +ENDCHAR +STARTCHAR char99 +ENCODING 99 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +4000 +6000 +7000 +7800 +7C00 +7E00 +7F00 +7F80 +6C00 +4C00 +0600 +0600 +0300 +0300 +0000 +ENDCHAR +STARTCHAR char112 +ENCODING 112 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +F800 +CE00 +C380 +C0E0 +C038 +C1FC +DCC0 +F660 +C330 +01E0 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char113 +ENCODING 113 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +3000 +3C00 +3F00 +3FC0 +3E00 +2300 +0180 +00C0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char120 +ENCODING 120 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +FF80 +8080 +8300 +8400 +8200 +9100 +A880 +A500 +C200 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char121 +ENCODING 121 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +7F00 +7C00 +7800 +7C00 +6E00 +4700 +4200 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char122 +ENCODING 122 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +FFE0 +80C0 +8180 +8300 +8300 +8180 +98C0 +BC60 +E630 +C360 +81C0 +0080 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR char123 +ENCODING 123 +SWIDTH 19200 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +0000 +7F00 +7E00 +7C00 +7C00 +7E00 +6700 +4380 +01C0 +0080 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +ENDFONT diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c index 7cecae9db1cb..aef157f169da 100644 --- a/sys/dev/syscons/scvgarndr.c +++ b/sys/dev/syscons/scvgarndr.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -149,24 +150,136 @@ RENDERER_MODULE(vga, vga_set); struct mousedata { u_short md_border[16]; u_short md_interior[16]; - u_short md_width; - u_short md_height; + u_char md_width; + u_char md_height; + u_char md_baspect; + u_char md_iaspect; + const char *md_name; }; -static const struct mousedata mouse9x13 = { { - 0xc000, 0xa000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x9780, - 0xf200, 0x1200, 0x1900, 0x0900, 0x0f00, 0x0000, 0x0000, 0x0000, }, { - 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800, - 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, - 9, 13, +static const struct mousedata mouse10x16_50 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8200, + 0x8400, 0x8400, 0x8400, 0x9200, 0xB200, 0xA900, 0xC900, 0x8600, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7C00, + 0x7800, 0x7800, 0x7800, 0x6C00, 0x4C00, 0x4600, 0x0600, 0x0000, }, + 10, 16, 49, 52, "mouse10x16_50", }; -static const struct mousedata mouse10x16 = { { - 0xc000, 0xa000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, - 0x8040, 0x83c0, 0x9200, 0xa900, 0xc900, 0x0480, 0x0480, 0x0300, }, { - 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x7f00, - 0x7f80, 0x7c00, 0x6c00, 0x4600, 0x0600, 0x0300, 0x0300, 0x0000, }, - 10, 16, +static const struct mousedata mouse8x14_67 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8700, + 0x8400, 0x9200, 0xB200, 0xA900, 0xC900, 0x0600, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x7800, 0x6C00, 0x4C00, 0x4600, 0x0600, 0x0000, 0x0000, 0x0000, }, + 8, 14, 64, 65, "mouse8x14_67", +}; + +static const struct mousedata mouse8x13_75 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8600, 0x8400, + 0xB200, 0xD200, 0x0900, 0x0900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7800, 0x7800, + 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 8, 13, 75, 80, "mouse8x13_75", +}; + +static const struct mousedata mouse10x16_75 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8700, + 0x8400, 0x9200, 0xB200, 0xC900, 0x0900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x7800, 0x6C00, 0x4C00, 0x0600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 72, 75, "mouse10x16_75", +}; + +static const struct mousedata mouse9x13_90 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8780, + 0x9200, 0xB200, 0xD900, 0x8900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x6C00, 0x4C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 9, 13, 89, 89, "mouse9x13_90", +}; + +static const struct mousedata mouse10x16_90 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x8040, 0x83E0, 0x8200, 0x9900, 0xA900, 0xC480, 0x8480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x7F80, 0x7C00, 0x7C00, 0x6600, 0x4600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 89, 89, "mouse10x16_90", +}; + +static const struct mousedata mouse9x13_100 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8780, + 0xB200, 0xD200, 0x8900, 0x0900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 9, 13, 106, 113, "mouse9x13_100", +}; + +static const struct mousedata mouse10x16_100 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x8040, 0x83C0, 0x9200, 0xA900, 0xC900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x7F80, 0x7C00, 0x6C00, 0x4600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 96, 106, "mouse10x16_100", +}; + +static const struct mousedata mouse10x14_120 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x97C0, 0xB200, 0xF200, 0xC900, 0x8900, 0x0600, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x6800, 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, }, + 10, 14, 120, 124, "mouse10x14_120", +}; + +static const struct mousedata mouse10x16_120 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x97C0, 0xB200, 0xF200, 0xC900, 0x8900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x6800, 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 120, 124, "mouse10x16_120", +}; + +static const struct mousedata mouse9x13_133 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x9780, 0xB200, 0xC900, 0x0900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x6800, 0x4C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 9, 13, 142, 124, "mouse9x13_133", +}; + +static const struct mousedata mouse10x16_133 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x8040, 0x93E0, 0xB200, 0xC900, 0x8900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x7F80, 0x6C00, 0x4C00, 0x0600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 120, 133, "mouse10x16_133", +}; + +static const struct mousedata mouse14x10_240 = { { + 0xF800, 0xCE00, 0xC380, 0xC0E0, 0xC038, 0xC1FC, 0xDCC0, 0xF660, + 0xC330, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x3000, 0x3C00, 0x3F00, 0x3FC0, 0x3E00, 0x2300, 0x0180, + 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, + 14, 10, 189, 189, "mouse14x10_240", +}; + +static const struct mousedata * const mouselarge[] = { + &mouse10x16_50, + &mouse8x14_67, + &mouse10x16_75, + &mouse10x16_90, + &mouse10x16_100, + &mouse10x16_120, + &mouse10x16_133, + &mouse14x10_240, +}; + +static const struct mousedata * const mousesmall[] = { + &mouse8x14_67, + &mouse8x13_75, + &mouse9x13_90, + &mouse9x13_100, + &mouse10x14_120, + &mouse9x13_133, + &mouse14x10_240, }; #endif #endif @@ -227,6 +340,109 @@ static uint16_t vga_palette15[16] = { }; #endif +static int vga_aspect_scale= 100; +SYSCTL_INT(_machdep, OID_AUTO, vga_aspect_scale, CTLFLAG_RW, + &vga_aspect_scale, 0, "Aspect scale ratio (3:4):actual times 100"); + +static u_short +vga_flipattr(u_short a, int blink) +{ + if (blink) + a = (a & 0x8800) | ((a & 0x7000) >> 4) | + ((a & 0x0700) << 4); + else + a = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4); + return (a); +} + +static u_short +vga_cursorattr_adj(u_short a, int blink) +{ + /* + * !blink means pixel mode, and the cursor attribute in that case + * is simplistic reverse video. + */ + if (!blink) + return (vga_flipattr(a, blink)); + + /* + * The cursor attribute is usually that of the underlying char + * with the bg changed to white. If the bg is already white, + * then the bg is changed to black. The fg is usually not + * changed, but if it is the same as the new bg then it is + * changed to the inverse of the new bg. + */ + if ((a & 0x7000) == 0x7000) { + a &= 0x8f00; + if ((a & 0x0700) == 0) + a |= 0x0700; + } else { + a |= 0x7000; + if ((a & 0x0700) == 0x0700) + a &= 0xf000; + } + return (a); +} + +static void +vga_setmdp(scr_stat *scp) +{ +#if !defined(SC_NO_CUTPASTE) && \ + (!defined(SC_ALT_MOUSE_IMAGE) || defined(SC_PIXEL_MODE)) + const struct mousedata *mdp; + const struct mousedata * const *mdpp; + int aspect, best_i, best_v, i, n, v, wb, wi, xpixel, ypixel; + + xpixel = scp->xpixel; + ypixel = scp->ypixel; + if (scp->sc->adp->va_flags & V_ADP_CWIDTH9) + xpixel = xpixel * 9 / 8; + + /* If 16:9 +-1%, assume square pixels, else scale to 4:3 or full. */ + aspect = xpixel * 900 / ypixel / 16; + if (aspect < 99 || aspect > 100) + aspect = xpixel * 300 / ypixel / 4 * vga_aspect_scale / 100; + + /* + * Use 10x16 cursors except even with 8x8 fonts except in ~200- + * line modes where pixels are very large and in text mode where + * even 13 pixels high is really 4 too many. Clipping a 16-high + * cursor at 9-high gives a variable tail which looks better than + * a smaller cursor with a constant tail. + * + * XXX: the IS*SC() macros don't work when this is called at the + * end of a mode switch since UNKNOWN_SC is still set. + */ + if (scp->font_size <= 8 && + (ypixel < 300 || !(scp->status & PIXEL_MODE))) { + mdpp = &mousesmall[0]; + n = nitems(mousesmall); + } else { + mdpp = &mouselarge[0]; + n = nitems(mouselarge); + } + if (scp->status & PIXEL_MODE) { + wb = 1024; + wi = 256; + } else { + wb = 256; + wi = 1024; + } + best_i = 0; + best_v = 0x7fffffff; + for (i = 0; i < n; i++) { + v = (wb * abs(mdpp[i]->md_baspect - aspect) + + wi * abs(mdpp[i]->md_iaspect - aspect)) / aspect; + if (best_v > v) { + best_v = v; + best_i = i; + } + } + mdp = mdpp[best_i]; + scp->mouse_data = mdp; +#endif /* !SC_NO_CUTPASTE && (!SC_ALT_MOUSE_IMAGE || SC_PIXEL_MODE) */ +} + static void vga_nop(scr_stat *scp) { @@ -260,8 +476,7 @@ vga_txtdraw(scr_stat *scp, int from, int count, int flip) for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) { c = sc_vtb_getc(&scp->vtb, from); a = sc_vtb_geta(&scp->vtb, from); - a = (a & 0x8800) | ((a & 0x7000) >> 4) - | ((a & 0x0700) << 4); + a = vga_flipattr(a, TRUE); p = sc_vtb_putchar(&scp->scr, p, c, a); } } else { @@ -272,13 +487,10 @@ vga_txtdraw(scr_stat *scp, int from, int count, int flip) static void vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink) { + vga_setmdp(scp); if (base < 0 || base >= scp->font_size) return; /* the caller may set height <= 0 in order to disable the cursor */ -#if 0 - scp->curs_attr.base = base; - scp->curs_attr.height = height; -#endif vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size, blink); } @@ -309,8 +521,7 @@ draw_txtcharcursor(scr_stat *scp, int at, u_short c, u_short a, int flip) if (scp->curs_attr.base >= h) return; if (flip) - a = (a & 0x8800) - | ((a & 0x7000) >> 4) | ((a & 0x0700) << 4); + a = vga_flipattr(a, TRUE); bcopy(font + c*h, font + sc->cursor_char*h, h); font = font + sc->cursor_char*h; for (i = imax(h - scp->curs_attr.base - scp->curs_attr.height, 0); @@ -323,18 +534,9 @@ draw_txtcharcursor(scr_stat *scp, int at, u_short c, u_short a, int flip) } else #endif /* SC_NO_FONT_LOADING */ { - if ((a & 0x7000) == 0x7000) { - a &= 0x8f00; - if ((a & 0x0700) == 0) - a |= 0x0700; - } else { - a |= 0x7000; - if ((a & 0x0700) == 0x0700) - a &= 0xf000; - } if (flip) - a = (a & 0x8800) - | ((a & 0x7000) >> 4) | ((a & 0x0700) << 4); + a = vga_flipattr(a, TRUE); + a = vga_cursorattr_adj(a, TRUE); sc_vtb_putc(&scp->scr, at, c, a); } } @@ -371,9 +573,7 @@ vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip) } else { cursor_attr = sc_vtb_geta(&scp->vtb, at); if (flip) - cursor_attr = (cursor_attr & 0x8800) - | ((cursor_attr & 0x7000) >> 4) - | ((cursor_attr & 0x0700) << 4); + cursor_attr = vga_flipattr(cursor_attr, TRUE); if (scp->status & VR_CURSOR_ON) sc_vtb_putc(&scp->scr, at, sc_vtb_getc(&scp->vtb, at), @@ -407,7 +607,7 @@ draw_txtmouse(scr_stat *scp, int x, int y) int crtc_addr; int i; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; /* prepare mousepointer char's bitmaps */ pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; @@ -702,13 +902,10 @@ vga_vgadraw_direct(scr_stat *scp, int from, int count, int flip) for (i = from; count-- > 0; ++i) { a = sc_vtb_geta(&scp->vtb, i); - if (flip) { - col1 = (((a & 0x7000) >> 4) | (a & 0x0800)) >> 8; - col2 = (((a & 0x8000) >> 4) | (a & 0x0700)) >> 8; - } else { - col1 = (a & 0x0f00) >> 8; - col2 = (a & 0xf000) >> 12; - } + if (flip) + a = vga_flipattr(a, FALSE); + col1 = (a & 0x0f00) >> 8; + col2 = (a & 0xf000) >> 12; e = d; f = &(scp->font[sc_vtb_getc(&scp->vtb, i) * scp->font_size]); @@ -759,13 +956,10 @@ vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip) count = scp->xsize*scp->ysize - from; for (i = from; count-- > 0; ++i) { a = sc_vtb_geta(&scp->vtb, i); - if (flip) { - col1 = ((a & 0x7000) >> 4) | (a & 0x0800); - col2 = ((a & 0x8000) >> 4) | (a & 0x0700); - } else { - col1 = (a & 0x0f00); - col2 = (a & 0xf000) >> 4; - } + if (flip) + a = vga_flipattr(a, FALSE); + col1 = a & 0x0f00; + col2 = (a & 0xf000) >> 4; /* set background color in EGA/VGA latch */ if (bg != col2) { bg = col2; @@ -807,13 +1001,7 @@ vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip) static void vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) { - if (base < 0 || base >= scp->font_size) - return; - /* the caller may set height <= 0 in order to disable the cursor */ -#if 0 - scp->curs_attr.base = base; - scp->curs_attr.height = height; -#endif + vga_setmdp(scp); } static void @@ -835,13 +1023,12 @@ draw_pxlcursor_direct(scr_stat *scp, int at, int on, int flip) a = sc_vtb_geta(&scp->vtb, at); - if (flip) { - col1 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; - col2 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; - } else { - col1 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; - col2 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; - } + if (flip) + a = vga_flipattr(a, FALSE); + if (on) + a = vga_cursorattr_adj(a, FALSE); + col1 = (a & 0x0f00) >> 8; + col2 = a >> 12; f = &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size + scp->font_size - scp->curs_attr.base - 1]); @@ -881,18 +1068,16 @@ draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip) /* set background color in EGA/VGA latch */ a = sc_vtb_geta(&scp->vtb, at); if (flip) - col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); - else - col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); + a = vga_flipattr(a, FALSE); + if (on) + a = vga_cursorattr_adj(a, FALSE); + col = (a & 0xf000) >> 4; outw(GDCIDX, col | 0x00); /* set/reset */ outw(GDCIDX, 0xff08); /* bit mask */ writeb(d, 0); c = readb(d); /* set bg color in the latch */ /* foreground color */ - if (flip) - col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); - else - col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); + col = a & 0x0f00; outw(GDCIDX, col | 0x00); /* set/reset */ f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size + scp->font_size - scp->curs_attr.base - 1]); @@ -1003,7 +1188,7 @@ draw_pxlmouse_planar(scr_stat *scp, int x, int y) int i, j, k; uint8_t m1; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; line_width = scp->sc->adp->va_line_width; xoff = (x - scp->xoff*8)%8; yoff = y - rounddown(y, line_width); @@ -1070,7 +1255,7 @@ remove_pxlmouse_planar(scr_stat *scp, int x, int y) vm_offset_t p; int bx, by, i, line_width, xend, xoff, yend, yoff; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; /* * It is only necessary to remove the mouse image where it overlaps @@ -1109,7 +1294,7 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on) int xend, yend; int i, j; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; /* * Determine overlap with the border and then if removing, do nothing diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index 5ec5c7eea68e..8e4b6ddbbbf3 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -329,6 +329,7 @@ typedef struct scr_stat { struct proc *mouse_proc; /* proc* of controlling proc */ pid_t mouse_pid; /* pid of controlling proc */ int mouse_signal; /* signal # to report with */ + const void *mouse_data; /* renderer (pixmap) data */ u_short bell_duration; u_short bell_pitch; diff --git a/sys/dev/usb/controller/ehci_imx.c b/sys/dev/usb/controller/ehci_imx.c index 4ebccdfdc30a..6dcebdef76df 100644 --- a/sys/dev/usb/controller/ehci_imx.c +++ b/sys/dev/usb/controller/ehci_imx.c @@ -83,12 +83,11 @@ __FBSDID("$FreeBSD$"); * data, this means that the resources (memory-mapped register range) for the * non-core registers belongs to a device other than the echi devices. * - * At the moment we have no need to access the non-core registers, so all of - * this amounts to documenting what's known. The following compat strings have - * been seen in existing FDT data: - * - "fsl,imx25-usbmisc" - * - "fsl,imx51-usbmisc"; - * - "fsl,imx6q-usbmisc"; + * Because the main ehci device cannot access registers in a range that's + * defined in the fdt data as belonging to another device, we implement a teeny + * little "usbmisc" driver which exists only to provide access to the usbmisc + * control register for each of the 4 usb controller instances. That little + * driver is implemented here in this file, before the main driver. * * In addition to the single usbmisc device, the existing FDT data defines a * separate device for each of the OTG or EHCI cores within the USBOH3. Each of @@ -133,17 +132,128 @@ __FBSDID("$FreeBSD$"); * */ -static struct ofw_compat_data compat_data[] = { - {"fsl,imx6q-usb", 1}, - {"fsl,imx53-usb", 1}, - {"fsl,imx51-usb", 1}, - {"fsl,imx28-usb", 1}, - {"fsl,imx27-usb", 1}, - {"fsl,imx25-usb", 1}, - {"fsl,imx23-usb", 1}, - {NULL, 0}, +/*----------------------------------------------------------------------------- + * imx_usbmisc driver + *---------------------------------------------------------------------------*/ + +#define USBNC_OVER_CUR_POL (1u << 8) +#define USBNC_OVER_CUR_DIS (1u << 7) + +struct imx_usbmisc_softc { + device_t dev; + struct resource *mmio; }; +static struct ofw_compat_data usbmisc_compat_data[] = { + {"fsl,imx6q-usbmisc", true}, + {"fsl,imx51-usbmisc", true}, + {"fsl,imx25-usbmisc", true}, + {NULL, false}, +}; + +static void +imx_usbmisc_set_ctrl(device_t dev, u_int index, uint32_t bits) +{ + struct imx_usbmisc_softc *sc; + uint32_t reg; + + sc = device_get_softc(dev); + reg = bus_read_4(sc->mmio, index * sizeof(uint32_t)); + bus_write_4(sc->mmio, index * sizeof(uint32_t), reg | bits); +} + +#ifdef notyet +static void +imx_usbmisc_clr_ctrl(device_t dev, u_int index, uint32_t bits) +{ + struct imx_usbmisc_softc *sc; + uint32_t reg; + + sc = device_get_softc(dev); + reg = bus_read_4(sc->mmio, index * sizeof(uint32_t)); + bus_write_4(sc->mmio, index * sizeof(uint32_t), reg & ~bits); +} +#endif + +static int +imx_usbmisc_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, usbmisc_compat_data)->ocd_data) { + device_set_desc(dev, "i.MX USB Misc Control"); + return (BUS_PROBE_DEFAULT); + } + return (ENXIO); +} + +static int +imx_usbmisc_detach(device_t dev) +{ + struct imx_usbmisc_softc *sc; + + sc = device_get_softc(dev); + + if (sc->mmio != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mmio); + + return (0); +} + +static int +imx_usbmisc_attach(device_t dev) +{ + struct imx_usbmisc_softc *sc; + int err, rid; + + sc = device_get_softc(dev); + err = 0; + + /* Allocate bus_space resources. */ + rid = 0; + sc->mmio = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->mmio == NULL) { + device_printf(dev, "Cannot allocate memory resources\n"); + return (ENXIO); + } + + OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev); + + return (0); +} + +static device_method_t imx_usbmisc_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, imx_usbmisc_probe), + DEVMETHOD(device_attach, imx_usbmisc_attach), + DEVMETHOD(device_detach, imx_usbmisc_detach), + + DEVMETHOD_END +}; + +static driver_t imx_usbmisc_driver = { + "imx_usbmisc", + imx_usbmisc_methods, + sizeof(struct imx_usbmisc_softc) +}; + +static devclass_t imx_usbmisc_devclass; + +/* + * This driver needs to start before the ehci driver, but later than the usual + * "special" drivers like clocks and cpu. Ehci starts at DEFAULT so + * DEFAULT-1000 seems good. + */ +EARLY_DRIVER_MODULE(imx_usbmisc, simplebus, imx_usbmisc_driver, + imx_usbmisc_devclass, 0, 0, BUS_PASS_DEFAULT - 1000); + +/*----------------------------------------------------------------------------- + * imx_ehci driver... + *---------------------------------------------------------------------------*/ + /* * Each EHCI device in the SoC has some SoC-specific per-device registers at an * offset of 0, then the standard EHCI registers begin at an offset of 0x100. @@ -153,10 +263,22 @@ static struct ofw_compat_data compat_data[] = { struct imx_ehci_softc { ehci_softc_t ehci_softc; + device_t dev; struct resource *ehci_mem_res; /* EHCI core regs. */ struct resource *ehci_irq_res; /* EHCI core IRQ. */ }; +static struct ofw_compat_data compat_data[] = { + {"fsl,imx6q-usb", 1}, + {"fsl,imx53-usb", 1}, + {"fsl,imx51-usb", 1}, + {"fsl,imx28-usb", 1}, + {"fsl,imx27-usb", 1}, + {"fsl,imx25-usb", 1}, + {"fsl,imx23-usb", 1}, + {NULL, 0}, +}; + static void imx_ehci_post_reset(struct ehci_softc *ehci_softc) { @@ -215,6 +337,36 @@ imx_ehci_detach(device_t dev) return (0); } +static void +imx_ehci_disable_oc(struct imx_ehci_softc *sc) +{ + device_t usbmdev; + pcell_t usbmprops[2]; + phandle_t node; + ssize_t size; + int index; + + /* Get the reference to the usbmisc driver from the fdt data */ + node = ofw_bus_get_node(sc->dev); + size = OF_getencprop(node, "fsl,usbmisc", usbmprops, + sizeof(usbmprops)); + if (size < sizeof(usbmprops)) { + device_printf(sc->dev, "failed to retrieve fsl,usbmisc " + "property, cannot disable overcurrent protection"); + return; + } + /* Retrieve the device_t via the xref handle. */ + usbmdev = OF_device_from_xref(usbmprops[0]); + if (usbmdev == NULL) { + device_printf(sc->dev, "usbmisc device not found, " + "cannot disable overcurrent protection"); + return; + } + /* Call the device routine to set the overcurrent disable bit. */ + index = usbmprops[1]; + imx_usbmisc_set_ctrl(usbmdev, index, USBNC_OVER_CUR_DIS); +} + static int imx_ehci_attach(device_t dev) { @@ -223,6 +375,7 @@ imx_ehci_attach(device_t dev) int err, rid; sc = device_get_softc(dev); + sc->dev = dev; esc = &sc->ehci_softc; err = 0; @@ -283,6 +436,10 @@ imx_ehci_attach(device_t dev) /* Turn on clocks. */ imx_ccm_usb_enable(dev); + /* Disable overcurrent detection, if configured to do so. */ + if (OF_hasprop(ofw_bus_get_node(sc->dev), "disable-over-current")) + imx_ehci_disable_oc(sc); + /* Add USB bus device. */ esc->sc_bus.bdev = device_add_child(dev, "usbus", -1); if (esc->sc_bus.bdev == NULL) { diff --git a/sys/dev/usb/controller/saf1761_otg.c b/sys/dev/usb/controller/saf1761_otg.c index d28f41e03c3f..b559ac83b229 100644 --- a/sys/dev/usb/controller/saf1761_otg.c +++ b/sys/dev/usb/controller/saf1761_otg.c @@ -516,7 +516,25 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t DPRINTFN(5, "STATUS=0x%08x\n", status); if (status & SOTG_PTD_DW3_ACTIVE) { - goto busy; + temp = saf1761_peek_host_status_le_4(sc, + pdt_addr + SOTG_PTD_DW0); + if (temp & SOTG_PTD_DW0_VALID) { + goto busy; + } else { + status = saf1761_peek_host_status_le_4(sc, + pdt_addr + SOTG_PTD_DW3); + + /* check if still active */ + if (status & SOTG_PTD_DW3_ACTIVE) { + saf1761_host_channel_free(sc, td); + goto retry; + } else if (status & SOTG_PTD_DW3_HALTED) { + if (!(status & SOTG_PTD_DW3_ERRORS)) + td->error_stall = 1; + td->error_any = 1; + goto complete; + } + } } else if (status & SOTG_PTD_DW3_HALTED) { if (!(status & SOTG_PTD_DW3_ERRORS)) td->error_stall = 1; @@ -560,6 +578,7 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t } saf1761_host_channel_free(sc, td); } +retry: if (saf1761_host_channel_alloc(sc, td)) goto busy; @@ -1589,6 +1608,8 @@ saf1761_otg_filter_interrupt(void *arg) (void) SAF1761_READ_LE_4(sc, SOTG_INT_PTD_DONE_PTD); (void) SAF1761_READ_LE_4(sc, SOTG_ISO_PTD_DONE_PTD); + DPRINTFN(9, "HCINTERRUPT=0x%08x DCINTERRUPT=0x%08x\n", hcstat, status); + if (status & SOTG_DCINTERRUPT_IEPSOF) { if ((sc->sc_host_async_busy_map[1] | sc->sc_host_async_busy_map[0] | sc->sc_host_intr_busy_map[1] | sc->sc_host_intr_busy_map[0] | @@ -2446,11 +2467,15 @@ saf1761_otg_init(struct saf1761_otg_softc *sc) */ SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR, SOTG_CTRL_CLR(0xFFFF)); +#ifdef __rtems__ + SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR, + SOTG_CTRL_SET(SOTG_CTRL_SEL_CP_EXT | SOTG_CTRL_VBUS_DRV)); +#else SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR, SOTG_CTRL_SET(SOTG_CTRL_SW_SEL_HC_DC | SOTG_CTRL_BDIS_ACON_EN | SOTG_CTRL_SEL_CP_EXT | SOTG_CTRL_VBUS_DRV)); - +#endif /* disable device address */ SAF1761_WRITE_LE_4(sc, SOTG_ADDRESS, 0); diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index 03f1e4b9dda9..651b5a3218a9 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -792,20 +792,11 @@ cd9660_pathconf(ap) else *ap->a_retval = 37; return (0); - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - return (0); - case _PC_PIPE_BUF: - *ap->a_retval = PIPE_BUF; - return (0); - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - return (0); case _PC_NO_TRUNC: *ap->a_retval = 1; return (0); default: - return (EINVAL); + return (vop_stdpathconf(ap)); } /* NOTREACHED */ } diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 64abe0d8fe93..6d709a7bd326 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -126,7 +126,7 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) ip->i_gid = ei->e2di_gid; ip->i_uid |= (uint32_t)ei->e2di_uid_high << 16; ip->i_gid |= (uint32_t)ei->e2di_gid_high << 16; - /* XXX use memcpy */ + for (i = 0; i < EXT2_NDADDR; i++) ip->i_db[i] = ei->e2di_blocks[i]; for (i = 0; i < EXT2_NIADDR; i++) @@ -176,7 +176,7 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) ei->e2di_uid_high = ip->i_uid >> 16 & 0xffff; ei->e2di_gid = ip->i_gid & 0xffff; ei->e2di_gid_high = ip->i_gid >> 16 & 0xffff; - /* XXX use memcpy */ + for (i = 0; i < EXT2_NDADDR; i++) ei->e2di_blocks[i] = ip->i_db[i]; for (i = 0; i < EXT2_NIADDR; i++) diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c index 5a1abef0234d..98d4f0a73b2c 100644 --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -279,6 +279,7 @@ ext2_mount(struct mount *mp) static int ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly) { + uint32_t i, mask; if (es->e2fs_magic != E2FS_MAGIC) { printf("ext2fs: %s: wrong magic number %#x (expected %#x)\n", @@ -286,17 +287,29 @@ ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly) return (1); } if (es->e2fs_rev > E2FS_REV0) { - if (es->e2fs_features_incompat & ~(EXT2F_INCOMPAT_SUPP | - EXT4F_RO_INCOMPAT_SUPP)) { - printf( -"WARNING: mount of %s denied due to unsupported optional features\n", - devtoname(dev)); + mask = es->e2fs_features_incompat & ~(EXT2F_INCOMPAT_SUPP | + EXT4F_RO_INCOMPAT_SUPP); + if (mask) { + printf("WARNING: mount of %s denied due to " + "unsupported optional features:\n", devtoname(dev)); + for (i = 0; + i < sizeof(incompat)/sizeof(struct ext2_feature); + i++) + if (mask & incompat[i].mask) + printf("%s ", incompat[i].name); + printf("\n"); return (1); } - if (!ronly && - (es->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP)) { + mask = es->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP; + if (!ronly && mask) { printf("WARNING: R/W mount of %s denied due to " - "unsupported optional features\n", devtoname(dev)); + "unsupported optional features:\n", devtoname(dev)); + for (i = 0; + i < sizeof(ro_compat)/sizeof(struct ext2_feature); + i++) + if (mask & ro_compat[i].mask) + printf("%s ", ro_compat[i].name); + printf("\n"); return (1); } } diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index 7aced4b5f1b2..d5fd6260b890 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -1627,18 +1627,6 @@ ext2_pathconf(struct vop_pathconf_args *ap) else *ap->a_retval = ext2_max_nlink(VTOI(ap->a_vp)); break; - case _PC_NAME_MAX: - *ap->a_retval = NAME_MAX; - break; - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - break; - case _PC_PIPE_BUF: - *ap->a_retval = PIPE_BUF; - break; - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - break; case _PC_NO_TRUNC: *ap->a_retval = 1; break; @@ -1661,11 +1649,6 @@ ext2_pathconf(struct vop_pathconf_args *ap) case _PC_MIN_HOLE_SIZE: *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize; break; - case _PC_ASYNC_IO: - /* _PC_ASYNC_IO should have been handled by upper layers. */ - KASSERT(0, ("_PC_ASYNC_IO should not get here")); - error = EINVAL; - break; case _PC_PRIO_IO: *ap->a_retval = 0; break; @@ -1695,7 +1678,7 @@ ext2_pathconf(struct vop_pathconf_args *ap) break; default: - error = EINVAL; + error = vop_stdpathconf(ap); break; } return (error); diff --git a/sys/fs/ext2fs/ext2fs.h b/sys/fs/ext2fs/ext2fs.h index c6d78ae3fc96..ff0457357bd1 100644 --- a/sys/fs/ext2fs/ext2fs.h +++ b/sys/fs/ext2fs/ext2fs.h @@ -203,10 +203,13 @@ struct csum { * compatible/incompatible features */ #define EXT2F_COMPAT_PREALLOC 0x0001 +#define EXT2F_COMPAT_IMAGIC_INODES 0x0002 #define EXT2F_COMPAT_HASJOURNAL 0x0004 #define EXT2F_COMPAT_EXT_ATTR 0x0008 #define EXT2F_COMPAT_RESIZE 0x0010 #define EXT2F_COMPAT_DIRHASHINDEX 0x0020 +#define EXT2F_COMPAT_LAZY_BG 0x0040 +#define EXT2F_COMPAT_EXCLUDE_BITMAP 0x0100 #define EXT2F_COMPAT_SPARSESUPER2 0x0200 #define EXT2F_ROCOMPAT_SPARSESUPER 0x0001 @@ -216,15 +219,18 @@ struct csum { #define EXT2F_ROCOMPAT_GDT_CSUM 0x0010 #define EXT2F_ROCOMPAT_DIR_NLINK 0x0020 #define EXT2F_ROCOMPAT_EXTRA_ISIZE 0x0040 +#define EXT2F_ROCOMPAT_HAS_SNAPSHOT 0x0080 #define EXT2F_ROCOMPAT_QUOTA 0x0100 #define EXT2F_ROCOMPAT_BIGALLOC 0x0200 #define EXT2F_ROCOMPAT_METADATA_CKSUM 0x0400 +#define EXT2F_ROCOMPAT_REPLICA 0x0800 #define EXT2F_ROCOMPAT_READONLY 0x1000 #define EXT2F_ROCOMPAT_PROJECT 0x2000 #define EXT2F_INCOMPAT_COMP 0x0001 #define EXT2F_INCOMPAT_FTYPE 0x0002 #define EXT2F_INCOMPAT_RECOVER 0x0004 +#define EXT2F_INCOMPAT_JOURNAL_DEV 0x0008 #define EXT2F_INCOMPAT_META_BG 0x0010 #define EXT2F_INCOMPAT_EXTENTS 0x0040 #define EXT2F_INCOMPAT_64BIT 0x0080 @@ -237,6 +243,58 @@ struct csum { #define EXT2F_INCOMPAT_INLINE_DATA 0x8000 #define EXT2F_INCOMPAT_ENCRYPT 0x10000 +struct ext2_feature +{ + int mask; + const char *name; +}; + +static const struct ext2_feature compat[] = { + { EXT2F_COMPAT_PREALLOC, "dir_prealloc" }, + { EXT2F_COMPAT_IMAGIC_INODES, "imagic_inodes" }, + { EXT2F_COMPAT_HASJOURNAL, "has_journal" }, + { EXT2F_COMPAT_EXT_ATTR, "ext_attr" }, + { EXT2F_COMPAT_RESIZE, "resize_inode" }, + { EXT2F_COMPAT_DIRHASHINDEX, "dir_index" }, + { EXT2F_COMPAT_EXCLUDE_BITMAP, "snapshot_bitmap" }, + { EXT2F_COMPAT_SPARSESUPER2, "sparse_super2" } +}; + +static const struct ext2_feature ro_compat[] = { + { EXT2F_ROCOMPAT_SPARSESUPER, "sparse_super" }, + { EXT2F_ROCOMPAT_LARGEFILE, "large_file" }, + { EXT2F_ROCOMPAT_BTREE_DIR, "btree_dir" }, + { EXT2F_ROCOMPAT_HUGE_FILE, "huge_file" }, + { EXT2F_ROCOMPAT_GDT_CSUM, "uninit_groups" }, + { EXT2F_ROCOMPAT_DIR_NLINK, "dir_nlink" }, + { EXT2F_ROCOMPAT_EXTRA_ISIZE, "extra_isize" }, + { EXT2F_ROCOMPAT_HAS_SNAPSHOT, "snapshot" }, + { EXT2F_ROCOMPAT_QUOTA, "quota" }, + { EXT2F_ROCOMPAT_BIGALLOC, "bigalloc" }, + { EXT2F_ROCOMPAT_METADATA_CKSUM, "metadata_csum" }, + { EXT2F_ROCOMPAT_REPLICA, "replica" }, + { EXT2F_ROCOMPAT_READONLY, "ro" }, + { EXT2F_ROCOMPAT_PROJECT, "project" } +}; + +static const struct ext2_feature incompat[] = { + { EXT2F_INCOMPAT_COMP, "compression" }, + { EXT2F_INCOMPAT_FTYPE, "filetype" }, + { EXT2F_INCOMPAT_RECOVER, "needs_recovery" }, + { EXT2F_INCOMPAT_JOURNAL_DEV, "journal_dev" }, + { EXT2F_INCOMPAT_META_BG, "meta_bg" }, + { EXT2F_INCOMPAT_EXTENTS, "extents" }, + { EXT2F_INCOMPAT_64BIT, "64bit" }, + { EXT2F_INCOMPAT_MMP, "mmp" }, + { EXT2F_INCOMPAT_FLEX_BG, "flex_bg" }, + { EXT2F_INCOMPAT_EA_INODE, "ea_inode" }, + { EXT2F_INCOMPAT_DIRDATA, "dirdata" }, + { EXT2F_INCOMPAT_CSUM_SEED, "metadata_csum_seed" }, + { EXT2F_INCOMPAT_LARGEDIR, "large_dir" }, + { EXT2F_INCOMPAT_INLINE_DATA, "inline_data" }, + { EXT2F_INCOMPAT_ENCRYPT, "encrypt" } +}; + /* * Features supported in this implementation * diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c index d41a21af1f02..ef5fd5e4afab 100644 --- a/sys/fs/fdescfs/fdesc_vfsops.c +++ b/sys/fs/fdescfs/fdesc_vfsops.c @@ -68,6 +68,7 @@ static vfs_root_t fdesc_root; int fdesc_cmount(struct mntarg *ma, void *data, uint64_t flags) { + return kernel_mount(ma, flags); } @@ -77,10 +78,10 @@ fdesc_cmount(struct mntarg *ma, void *data, uint64_t flags) static int fdesc_mount(struct mount *mp) { - int error = 0; struct fdescmount *fmp; struct thread *td = curthread; struct vnode *rvp; + int error; if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_FDESCFS)) return (EPERM); @@ -98,7 +99,7 @@ fdesc_mount(struct mount *mp) * We need to initialize a few bits of our local mount point struct to * avoid confusion in allocvp. */ - mp->mnt_data = (qaddr_t) fmp; + mp->mnt_data = fmp; fmp->flags = 0; error = fdesc_allocvp(Froot, -1, FD_ROOT, mp, &rvp); if (error) { @@ -122,11 +123,10 @@ static int fdesc_unmount(struct mount *mp, int mntflags) { struct fdescmount *fmp; - caddr_t data; - int error; - int flags = 0; + int error, flags; - fmp = (struct fdescmount *)mp->mnt_data; + flags = 0; + fmp = mp->mnt_data; if (mntflags & MNT_FORCE) { /* The hash mutex protects the private mount flags. */ mtx_lock(&fdesc_hashmtx); @@ -147,15 +147,10 @@ fdesc_unmount(struct mount *mp, int mntflags) return (error); /* - * Finally, throw away the fdescmount structure. Hold the hashmtx to - * protect the fdescmount structure. + * Finally, throw away the fdescmount structure. */ - mtx_lock(&fdesc_hashmtx); - data = mp->mnt_data; mp->mnt_data = NULL; - mtx_unlock(&fdesc_hashmtx); - free(data, M_FDESCMNT); /* XXX */ - + free(fmp, M_FDESCMNT); return (0); } diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index 885cc35b038e..e49687b5fd19 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -152,7 +152,7 @@ fdesc_allocvp(fdntype ftype, unsigned fd_fd, int ix, struct mount *mp, struct fdescnode *fd, *fd2; struct vnode *vp, *vp2; struct thread *td; - int error = 0; + int error; td = curthread; fc = FD_NHASH(ix); @@ -162,7 +162,7 @@ fdesc_allocvp(fdntype ftype, unsigned fd_fd, int ix, struct mount *mp, * If a forced unmount is progressing, we need to drop it. The flags are * protected by the hashmtx. */ - fmp = (struct fdescmount *)mp->mnt_data; + fmp = mp->mnt_data; if (fmp == NULL || fmp->flags & FMNT_UNMOUNTF) { mtx_unlock(&fdesc_hashmtx); return (-1); @@ -207,7 +207,7 @@ fdesc_allocvp(fdntype ftype, unsigned fd_fd, int ix, struct mount *mp, * If a forced unmount is progressing, we need to drop it. The flags are * protected by the hashmtx. */ - fmp = (struct fdescmount *)mp->mnt_data; + fmp = mp->mnt_data; if (fmp == NULL || fmp->flags & FMNT_UNMOUNTF) { mtx_unlock(&fdesc_hashmtx); vgone(vp); @@ -358,7 +358,7 @@ fdesc_lookup(struct vop_lookup_args *ap) error = vn_vget_ino_gen(dvp, fdesc_get_ino_alloc, &arg, LK_EXCLUSIVE, &fvp); } - + if (error) goto bad; *vpp = fvp; diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index 024adee34cbb..31aa43535cae 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/fifofs/fifo_vnops.c @@ -71,7 +71,6 @@ struct fifoinfo { static vop_print_t fifo_print; static vop_open_t fifo_open; static vop_close_t fifo_close; -static vop_pathconf_t fifo_pathconf; static vop_advlock_t fifo_advlock; struct vop_vector fifo_specops = { @@ -87,7 +86,7 @@ struct vop_vector fifo_specops = { .vop_mkdir = VOP_PANIC, .vop_mknod = VOP_PANIC, .vop_open = fifo_open, - .vop_pathconf = fifo_pathconf, + .vop_pathconf = vop_stdpathconf, .vop_print = fifo_print, .vop_read = VOP_PANIC, .vop_readdir = VOP_PANIC, @@ -339,34 +338,6 @@ fifo_print(ap) return (0); } -/* - * Return POSIX pathconf information applicable to fifo's. - */ -static int -fifo_pathconf(ap) - struct vop_pathconf_args /* { - struct vnode *a_vp; - int a_name; - int *a_retval; - } */ *ap; -{ - - switch (ap->a_name) { - case _PC_LINK_MAX: - *ap->a_retval = LINK_MAX; - return (0); - case _PC_PIPE_BUF: - *ap->a_retval = PIPE_BUF; - return (0); - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - return (0); - default: - return (EINVAL); - } - /* NOTREACHED */ -} - /* * Fifo advisory byte-level locks. */ diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index a37fabe5cbd2..2af5ae0c892e 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -1875,17 +1875,11 @@ msdosfs_pathconf(struct vop_pathconf_args *ap) case _PC_NAME_MAX: *ap->a_retval = pmp->pm_flags & MSDOSFSMNT_LONGNAME ? WIN_MAXLEN : 12; return (0); - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - return (0); - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - return (0); case _PC_NO_TRUNC: *ap->a_retval = 0; return (0); default: - return (EINVAL); + return (vop_stdpathconf(ap)); } /* NOTREACHED */ } diff --git a/sys/fs/nandfs/nandfs_vnops.c b/sys/fs/nandfs/nandfs_vnops.c index 147336db9ff6..f6ba10e887fa 100644 --- a/sys/fs/nandfs/nandfs_vnops.c +++ b/sys/fs/nandfs/nandfs_vnops.c @@ -2236,21 +2236,6 @@ nandfs_pathconf(struct vop_pathconf_args *ap) error = 0; switch (ap->a_name) { - case _PC_LINK_MAX: - *ap->a_retval = LINK_MAX; - break; - case _PC_NAME_MAX: - *ap->a_retval = NAME_MAX; - break; - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - break; - case _PC_PIPE_BUF: - *ap->a_retval = PIPE_BUF; - break; - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - break; case _PC_NO_TRUNC: *ap->a_retval = 1; break; @@ -2273,7 +2258,7 @@ nandfs_pathconf(struct vop_pathconf_args *ap) *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize; break; default: - error = EINVAL; + error = vop_stdpathconf(ap); break; } return (error); diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index b2c396254de2..5f4d68bc697a 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -199,6 +199,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp, nconf = getnetconfigent("udp"); else nconf = getnetconfigent("tcp"); + else if (saddr->sa_family == AF_LOCAL) + nconf = getnetconfigent("local"); else if (nrp->nr_sotype == SOCK_DGRAM) nconf = getnetconfigent("udp6"); diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index 28c2d2d1d235..cebacaf6c531 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); */ #include #include +#include #include #include #include @@ -618,11 +619,30 @@ nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred) goto out; } else if (uap->flag & NFSSVC_NFSUSERDPORT) { u_short sockport; + struct sockaddr *sad; + struct sockaddr_un *sun; - error = copyin(uap->argp, (caddr_t)&sockport, - sizeof (u_short)); - if (!error) - error = nfsrv_nfsuserdport(sockport, p); + if ((uap->flag & NFSSVC_NEWSTRUCT) != 0) { + /* New nfsuserd using an AF_LOCAL socket. */ + sun = malloc(sizeof(struct sockaddr_un), M_SONAME, + M_WAITOK | M_ZERO); + error = copyinstr(uap->argp, sun->sun_path, + sizeof(sun->sun_path), NULL); + if (error != 0) { + free(sun, M_SONAME); + return (error); + } + sun->sun_family = AF_LOCAL; + sun->sun_len = SUN_LEN(sun); + sockport = 0; + sad = (struct sockaddr *)sun; + } else { + error = copyin(uap->argp, (caddr_t)&sockport, + sizeof (u_short)); + sad = NULL; + } + if (error == 0) + error = nfsrv_nfsuserdport(sad, sockport, p); } else if (uap->flag & NFSSVC_NFSUSERDDELPORT) { nfsrv_nfsuserddelport(); error = 0; diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 309553d0ef53..86819ac7f23b 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -3052,7 +3052,7 @@ nfsrv_cmpmixedcase(u_char *cp, u_char *cp2, int len) * Set the port for the nfsuserd. */ APPLESTATIC int -nfsrv_nfsuserdport(u_short port, NFSPROC_T *p) +nfsrv_nfsuserdport(struct sockaddr *sad, u_short port, NFSPROC_T *p) { struct nfssockreq *rp; struct sockaddr_in *ad; @@ -3062,6 +3062,7 @@ nfsrv_nfsuserdport(u_short port, NFSPROC_T *p) if (nfsrv_nfsuserd) { NFSUNLOCKNAMEID(); error = EPERM; + NFSSOCKADDRFREE(sad); goto out; } nfsrv_nfsuserd = 1; @@ -3071,16 +3072,24 @@ nfsrv_nfsuserdport(u_short port, NFSPROC_T *p) */ rp = &nfsrv_nfsuserdsock; rp->nr_client = NULL; - rp->nr_sotype = SOCK_DGRAM; - rp->nr_soproto = IPPROTO_UDP; - rp->nr_lock = (NFSR_RESERVEDPORT | NFSR_LOCALHOST); rp->nr_cred = NULL; - NFSSOCKADDRALLOC(rp->nr_nam); - NFSSOCKADDRSIZE(rp->nr_nam, sizeof (struct sockaddr_in)); - ad = NFSSOCKADDR(rp->nr_nam, struct sockaddr_in *); - ad->sin_family = AF_INET; - ad->sin_addr.s_addr = htonl((u_int32_t)0x7f000001); /* 127.0.0.1 */ - ad->sin_port = port; + rp->nr_lock = (NFSR_RESERVEDPORT | NFSR_LOCALHOST); + if (sad != NULL) { + /* Use the AF_LOCAL socket address passed in. */ + rp->nr_sotype = SOCK_STREAM; + rp->nr_soproto = 0; + rp->nr_nam = sad; + } else { + /* Use the port# for a UDP socket (old nfsuserd). */ + rp->nr_sotype = SOCK_DGRAM; + rp->nr_soproto = IPPROTO_UDP; + NFSSOCKADDRALLOC(rp->nr_nam); + NFSSOCKADDRSIZE(rp->nr_nam, sizeof (struct sockaddr_in)); + ad = NFSSOCKADDR(rp->nr_nam, struct sockaddr_in *); + ad->sin_family = AF_INET; + ad->sin_addr.s_addr = htonl((u_int32_t)0x7f000001); + ad->sin_port = port; + } rp->nr_prog = RPCPROG_NFSUSERD; rp->nr_vers = RPCNFSUSERD_VERS; error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0); diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index ac023dcf451a..7c0008242bd8 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -128,7 +128,7 @@ int nfsrv_checksetattr(vnode_t, struct nfsrv_descript *, NFSPROC_T *); int nfsrv_checkgetattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, struct ucred *, NFSPROC_T *); -int nfsrv_nfsuserdport(u_short, NFSPROC_T *); +int nfsrv_nfsuserdport(struct sockaddr *, u_short, NFSPROC_T *); void nfsrv_nfsuserddelport(void); void nfsrv_throwawayallstate(NFSPROC_T *); int nfsrv_checksequence(struct nfsrv_descript *, uint32_t, uint32_t *, diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index d718f5338380..8b48473eb331 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -3481,12 +3481,6 @@ nfs_pathconf(struct vop_pathconf_args *ap) case _PC_NAME_MAX: *ap->a_retval = pc.pc_namemax; break; - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - break; - case _PC_PIPE_BUF: - *ap->a_retval = PIPE_BUF; - break; case _PC_CHOWN_RESTRICTED: *ap->a_retval = pc.pc_chownrestricted; break; @@ -3512,11 +3506,6 @@ nfs_pathconf(struct vop_pathconf_args *ap) case _PC_MAC_PRESENT: *ap->a_retval = 0; break; - case _PC_ASYNC_IO: - /* _PC_ASYNC_IO should have been handled by upper layers. */ - KASSERT(0, ("_PC_ASYNC_IO should not get here")); - error = EINVAL; - break; case _PC_PRIO_IO: *ap->a_retval = 0; break; @@ -3549,7 +3538,7 @@ nfs_pathconf(struct vop_pathconf_args *ap) break; default: - error = EINVAL; + error = vop_stdpathconf(ap); break; } return (error); diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c index 54c9d998fe49..be2b767b8227 100644 --- a/sys/fs/smbfs/smbfs_vnops.c +++ b/sys/fs/smbfs/smbfs_vnops.c @@ -907,7 +907,7 @@ smbfs_pathconf (ap) *retval = 800; /* XXX: a correct one ? */ break; default: - error = EINVAL; + error = vop_stdpathconf(ap); } return error; } diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index a2b01213d7ae..3eed85a43266 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -1344,26 +1344,6 @@ tmpfs_pathconf(struct vop_pathconf_args *v) error = 0; switch (name) { - case _PC_LINK_MAX: - *retval = LINK_MAX; - break; - - case _PC_NAME_MAX: - *retval = NAME_MAX; - break; - - case _PC_PATH_MAX: - *retval = PATH_MAX; - break; - - case _PC_PIPE_BUF: - *retval = PIPE_BUF; - break; - - case _PC_CHOWN_RESTRICTED: - *retval = 1; - break; - case _PC_NO_TRUNC: *retval = 1; break; @@ -1377,7 +1357,7 @@ tmpfs_pathconf(struct vop_pathconf_args *v) break; default: - error = EINVAL; + error = vop_stdpathconf(v); } return error; diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index 9bd74d4d253b..8dfe99b53c29 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -501,6 +501,8 @@ g_disk_start(struct bio *bp) break; else if (g_handleattr_str(bp, "GEOM::ident", dp->d_ident)) break; + else if (g_handleattr_str(bp, "GEOM::descr", dp->d_descr)) + break; else if (g_handleattr_uint16_t(bp, "GEOM::hba_vendor", dp->d_hba_vendor)) break; diff --git a/sys/gnu/dts/arm/alpine.dtsi b/sys/gnu/dts/arm/alpine.dtsi index d0eefc3b886c..731df7a8c4e6 100644 --- a/sys/gnu/dts/arm/alpine.dtsi +++ b/sys/gnu/dts/arm/alpine.dtsi @@ -41,28 +41,28 @@ compatible = "arm,cortex-a15"; device_type = "cpu"; reg = <0>; - clock-frequency = <0>; /* Filled by loader */ + clock-frequency = <1700000000>; }; cpu@1 { compatible = "arm,cortex-a15"; device_type = "cpu"; reg = <1>; - clock-frequency = <0>; /* Filled by loader */ + clock-frequency = <1700000000>; }; cpu@2 { compatible = "arm,cortex-a15"; device_type = "cpu"; reg = <2>; - clock-frequency = <0>; /* Filled by loader */ + clock-frequency = <1700000000>; }; cpu@3 { compatible = "arm,cortex-a15"; device_type = "cpu"; reg = <3>; - clock-frequency = <0>; /* Filled by loader */ + clock-frequency = <1700000000>; }; }; @@ -81,7 +81,7 @@ , , ; - clock-frequency = <0>; /* Filled by loader */ + clock-frequency = <50000000>; }; /* Interrupt Controller */ @@ -120,26 +120,26 @@ ; }; - uart0:uart@fd883000 { + uart0: uart@fd883000 { compatible = "ns16550a"; reg = <0x0 0xfd883000 0x0 0x1000>; - clock-frequency = <0>; /* Filled by loader */ + clock-frequency = <375000000>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; }; - uart1:uart@0xfd884000 { + uart1: uart@fd884000 { compatible = "ns16550a"; reg = <0x0 0xfd884000 0x0 0x1000>; - clock-frequency = <0>; /* Filled by loader */ + clock-frequency = <375000000>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; }; /* Internal PCIe Controller */ - pcie-internal@0xfbc00000 { + pcie@fbc00000 { compatible = "pci-host-ecam-generic"; device_type = "pci"; #size-cells = <2>; diff --git a/sys/gnu/dts/arm/am335x-baltos-ir2110.dts b/sys/gnu/dts/arm/am335x-baltos-ir2110.dts index 501c7527121b..75de1e723303 100644 --- a/sys/gnu/dts/arm/am335x-baltos-ir2110.dts +++ b/sys/gnu/dts/arm/am335x-baltos-ir2110.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "am335x-baltos.dtsi" +#include "am335x-baltos-leds.dtsi" / { model = "OnRISC Baltos iR 2110"; diff --git a/sys/gnu/dts/arm/am335x-baltos-ir3220.dts b/sys/gnu/dts/arm/am335x-baltos-ir3220.dts index 19f53b8569e1..46df1b22022c 100644 --- a/sys/gnu/dts/arm/am335x-baltos-ir3220.dts +++ b/sys/gnu/dts/arm/am335x-baltos-ir3220.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "am335x-baltos.dtsi" +#include "am335x-baltos-leds.dtsi" / { model = "OnRISC Baltos iR 3220"; diff --git a/sys/gnu/dts/arm/am335x-baltos-ir5221.dts b/sys/gnu/dts/arm/am335x-baltos-ir5221.dts index 2b9d7f4db23f..5d56355ba040 100644 --- a/sys/gnu/dts/arm/am335x-baltos-ir5221.dts +++ b/sys/gnu/dts/arm/am335x-baltos-ir5221.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "am335x-baltos.dtsi" +#include "am335x-baltos-leds.dtsi" / { model = "OnRISC Baltos iR 5221"; diff --git a/sys/gnu/dts/arm/am335x-baltos-leds.dtsi b/sys/gnu/dts/arm/am335x-baltos-leds.dtsi new file mode 100644 index 000000000000..3ab1767d5c13 --- /dev/null +++ b/sys/gnu/dts/arm/am335x-baltos-leds.dtsi @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * VScom OnRISC + * http://www.vscom.de + */ + +/*#include "am33xx.dtsi"*/ + +/ { + leds { + pinctrl-names = "default"; + pinctrl-0 = <&user_leds>; + + compatible = "gpio-leds"; + + power { + label = "onrisc:red:power"; + linux,default-trigger = "default-on"; + gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + wlan { + label = "onrisc:blue:wlan"; + gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + app { + label = "onrisc:green:app"; + gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; +}; + +&am33xx_pinmux { + user_leds: pinmux_user_leds { + pinctrl-single,pins = < + AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mii1_col.gpio3_0 PWR LED */ + AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mii1_txd3.gpio0_16 WLAN LED */ + AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mii1_txd2.gpio0_17 APP LED */ + >; + }; +}; diff --git a/sys/gnu/dts/arm/am335x-boneblack.dts b/sys/gnu/dts/arm/am335x-boneblack.dts index 77273df1a028..935ed17d22e4 100644 --- a/sys/gnu/dts/arm/am335x-boneblack.dts +++ b/sys/gnu/dts/arm/am335x-boneblack.dts @@ -15,3 +15,14 @@ model = "TI AM335x BeagleBone Black"; compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; }; + +&cpu0_opp_table { + /* + * All PG 2.0 silicon may not support 1GHz but some of the early + * BeagleBone Blacks have PG 2.0 silicon which is guaranteed + * to support 1GHz OPP so enable it for PG 2.0 on this board. + */ + oppnitro@1000000000 { + opp-supported-hw = <0x06 0x0100>; + }; +}; diff --git a/sys/gnu/dts/arm/am335x-icev2.dts b/sys/gnu/dts/arm/am335x-icev2.dts index a2ad076822db..f2005ecca74f 100644 --- a/sys/gnu/dts/arm/am335x-icev2.dts +++ b/sys/gnu/dts/arm/am335x-icev2.dts @@ -201,6 +201,69 @@ AM33XX_IOPAD(0x938, PIN_OUTPUT_PULLUP | MUX_MODE1) /* (L16) gmii1_rxd2.uart3_txd */ >; }; + + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1, RMII mode */ + AM33XX_IOPAD(0x90c, (PIN_INPUT_PULLUP | MUX_MODE1)) /* mii1_crs.rmii1_crs_dv */ + AM33XX_IOPAD(0x944, (PIN_INPUT_PULLUP | MUX_MODE0)) /* rmii1_refclk.rmii1_refclk */ + AM33XX_IOPAD(0x940, (PIN_INPUT_PULLUP | MUX_MODE1)) /* mii1_rxd0.rmii1_rxd0 */ + AM33XX_IOPAD(0x93c, (PIN_INPUT_PULLUP | MUX_MODE1)) /* mii1_rxd1.rmii1_rxd1 */ + AM33XX_IOPAD(0x910, (PIN_INPUT_PULLUP | MUX_MODE1)) /* mii1_rxerr.rmii1_rxerr */ + AM33XX_IOPAD(0x928, (PIN_OUTPUT_PULLDOWN | MUX_MODE1)) /* mii1_txd0.rmii1_txd0 */ + AM33XX_IOPAD(0x924, (PIN_OUTPUT_PULLDOWN | MUX_MODE1)) /* mii1_txd1.rmii1_txd1 */ + AM33XX_IOPAD(0x914, (PIN_OUTPUT_PULLDOWN | MUX_MODE1)) /* mii1_txen.rmii1_txen */ + /* Slave 2, RMII mode */ + AM33XX_IOPAD(0x870, (PIN_INPUT_PULLUP | MUX_MODE3)) /* gpmc_wait0.rmii2_crs_dv */ + AM33XX_IOPAD(0x908, (PIN_INPUT_PULLUP | MUX_MODE1)) /* mii1_col.rmii2_refclk */ + AM33XX_IOPAD(0x86c, (PIN_INPUT_PULLUP | MUX_MODE3)) /* gpmc_a11.rmii2_rxd0 */ + AM33XX_IOPAD(0x868, (PIN_INPUT_PULLUP | MUX_MODE3)) /* gpmc_a10.rmii2_rxd1 */ + AM33XX_IOPAD(0x874, (PIN_INPUT_PULLUP | MUX_MODE3)) /* gpmc_wpn.rmii2_rxerr */ + AM33XX_IOPAD(0x854, (PIN_OUTPUT_PULLDOWN | MUX_MODE3)) /* gpmc_a5.rmii2_txd0 */ + AM33XX_IOPAD(0x850, (PIN_OUTPUT_PULLDOWN | MUX_MODE3)) /* gpmc_a4.rmii2_txd1 */ + AM33XX_IOPAD(0x840, (PIN_OUTPUT_PULLDOWN | MUX_MODE3)) /* gpmc_a0.rmii2_txen */ + >; + }; + + cpsw_sleep: cpsw_sleep { + pinctrl-single,pins = < + /* Slave 1 reset value */ + AM33XX_IOPAD(0x90c, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x944, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x940, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x93c, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x910, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x928, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x924, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x914, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + + /* Slave 2 reset value */ + AM33XX_IOPAD(0x870, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x908, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x86c, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x868, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x874, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x854, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x850, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x840, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + AM33XX_IOPAD(0x948, (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)) /* mdio_data.mdio_data */ + AM33XX_IOPAD(0x94c, (PIN_OUTPUT_PULLUP | MUX_MODE0)) /* mdio_clk.mdio_clk */ + >; + }; + + davinci_mdio_sleep: davinci_mdio_sleep { + pinctrl-single,pins = < + /* MDIO reset value */ + AM33XX_IOPAD(0x948, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + AM33XX_IOPAD(0x94c, (PIN_INPUT_PULLDOWN | MUX_MODE7)) + >; + }; }; &i2c0 { @@ -245,6 +308,39 @@ spi-max-frequency = <1000000>; spi-cpol; }; + + spi_nor: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "winbond,w25q64", "jedec,spi-nor"; + spi-max-frequency = <80000000>; + m25p,fast-read; + reg = <0>; + + partition@0 { + label = "u-boot-spl"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@1 { + label = "u-boot"; + reg = <0x80000 0x100000>; + read-only; + }; + + partition@2 { + label = "u-boot-env"; + reg = <0x180000 0x20000>; + read-only; + }; + + partition@3 { + label = "misc"; + reg = <0x1A0000 0x660000>; + }; + }; + }; &tscadc { @@ -350,3 +446,61 @@ pinctrl-0 = <&uart3_pins_default>; status = "okay"; }; + +&gpio3 { + p4 { + gpio-hog; + gpios = <4 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "PR1_MII_CTRL"; + }; + + p10 { + gpio-hog; + gpios = <10 GPIO_ACTIVE_HIGH>; + /* ETH1 mux: Low for MII-PRU, high for RMII-CPSW */ + output-high; + line-name = "MUX_MII_CTL1"; + }; +}; + +&cpsw_emac0 { + phy-handle = <ðphy0>; + phy-mode = "rmii"; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + phy-handle = <ðphy1>; + phy-mode = "rmii"; + dual_emac_res_vlan = <2>; +}; + +&mac { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&cpsw_default>; + pinctrl-1 = <&cpsw_sleep>; + status = "okay"; + dual_emac; +}; + +&phy_sel { + rmii-clock-ext; +}; + +&davinci_mdio { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&davinci_mdio_default>; + pinctrl-1 = <&davinci_mdio_sleep>; + status = "okay"; + reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; + reset-delay-us = <2>; /* PHY datasheet states 1uS min */ + + ethphy0: ethernet-phy@1 { + reg = <1>; + }; + + ethphy1: ethernet-phy@3 { + reg = <3>; + }; +}; diff --git a/sys/gnu/dts/arm/am335x-sl50.dts b/sys/gnu/dts/arm/am335x-sl50.dts index c5d2589c55fc..fc864a855991 100644 --- a/sys/gnu/dts/arm/am335x-sl50.dts +++ b/sys/gnu/dts/arm/am335x-sl50.dts @@ -220,7 +220,7 @@ mmc1_pins: pinmux_mmc1_pins { pinctrl-single,pins = < - AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ + AM33XX_IOPAD(0x96c, PIN_INPUT | MUX_MODE7) /* uart0_rtsn.gpio1_9 */ >; }; @@ -280,10 +280,6 @@ AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE7) /* nKbdReset - gpmc_ad13.gpio1_13 */ AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE7) /* nDispReset - gpmc_ad14.gpio1_14 */ AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE7) /* USB1_enPower - gpmc_a1.gpio1_17 */ - /* AVR Programming - SPI Bus (bit bang) - Screen and Keyboard */ - AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE7) /* Kbd/Disp/BattMOSI spi0_d0.gpio0_3 */ - AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE7) /* Kbd/Disp/BattMISO spi0_d1.gpio0_4 */ - AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE7) /* Kbd/Disp/BattSCLK spi0_clk.gpio0_2 */ /* PDI Bus - Battery system */ AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE7) /* nBattReset gpmc_a0.gpio1_16 */ AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE7) /* BattPDIData gpmc_ad15.gpio1_15 */ @@ -384,7 +380,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; bus-width = <4>; - cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + cd-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; vmmc-supply = <&vmmcsd_fixed>; }; diff --git a/sys/gnu/dts/arm/am33xx.dtsi b/sys/gnu/dts/arm/am33xx.dtsi index 9e96d60976b7..9e242943dcec 100644 --- a/sys/gnu/dts/arm/am33xx.dtsi +++ b/sys/gnu/dts/arm/am33xx.dtsi @@ -46,19 +46,7 @@ device_type = "cpu"; reg = <0>; - /* - * To consider voltage drop between PMIC and SoC, - * tolerance value is reduced to 2% from 4% and - * voltage value is increased as a precaution. - */ - operating-points = < - /* kHz uV */ - 720000 1285000 - 600000 1225000 - 500000 1125000 - 275000 1125000 - >; - voltage-tolerance = <2>; /* 2 percentage */ + operating-points-v2 = <&cpu0_opp_table>; clocks = <&dpll_mpu_ck>; clock-names = "cpu"; @@ -67,6 +55,79 @@ }; }; + cpu0_opp_table: opp-table { + compatible = "operating-points-v2-ti-cpu"; + syscon = <&scm_conf>; + + /* + * The three following nodes are marked with opp-suspend + * because the can not be enabled simultaneously on a + * single SoC. + */ + opp50@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <950000 931000 969000>; + opp-supported-hw = <0x06 0x0010>; + opp-suspend; + }; + + opp100@275000000 { + opp-hz = /bits/ 64 <275000000>; + opp-microvolt = <1100000 1078000 1122000>; + opp-supported-hw = <0x01 0x00FF>; + opp-suspend; + }; + + opp100@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <1100000 1078000 1122000>; + opp-supported-hw = <0x06 0x0020>; + opp-suspend; + }; + + opp100@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1100000 1078000 1122000>; + opp-supported-hw = <0x01 0xFFFF>; + }; + + opp100@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <1100000 1078000 1122000>; + opp-supported-hw = <0x06 0x0040>; + }; + + opp120@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <1200000 1176000 1224000>; + opp-supported-hw = <0x01 0xFFFF>; + }; + + opp120@720000000 { + opp-hz = /bits/ 64 <720000000>; + opp-microvolt = <1200000 1176000 1224000>; + opp-supported-hw = <0x06 0x0080>; + }; + + oppturbo@720000000 { + opp-hz = /bits/ 64 <720000000>; + opp-microvolt = <1260000 1234800 1285200>; + opp-supported-hw = <0x01 0xFFFF>; + }; + + oppturbo@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1260000 1234800 1285200>; + opp-supported-hw = <0x06 0x0100>; + }; + + oppnitro@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <1325000 1298500 1351500>; + opp-supported-hw = <0x04 0x0200>; + }; + }; + pmu { compatible = "arm,cortex-a8-pmu"; interrupts = <3>; diff --git a/sys/gnu/dts/arm/am3517.dtsi b/sys/gnu/dts/arm/am3517.dtsi index 9fe545dbfa89..00da3f2c4072 100644 --- a/sys/gnu/dts/arm/am3517.dtsi +++ b/sys/gnu/dts/arm/am3517.dtsi @@ -13,6 +13,7 @@ / { aliases { serial3 = &uart4; + can = &hecc; }; ocp@68000000 { @@ -72,6 +73,17 @@ pinctrl-single,register-width = <16>; pinctrl-single,function-mask = <0xff1f>; }; + + hecc: can@5c050000 { + compatible = "ti,am3517-hecc"; + status = "disabled"; + reg = <0x5c050000 0x80>, + <0x5c053000 0x180>, + <0x5c052000 0x200>; + reg-names = "hecc", "hecc-ram", "mbx"; + interrupts = <24>; + clocks = <&hecc_ck>; + }; }; }; diff --git a/sys/gnu/dts/arm/am4372.dtsi b/sys/gnu/dts/arm/am4372.dtsi index 97fcaf415de1..176e09e9a45e 100644 --- a/sys/gnu/dts/arm/am4372.dtsi +++ b/sys/gnu/dts/arm/am4372.dtsi @@ -50,15 +50,14 @@ clock-names = "cpu"; operating-points-v2 = <&cpu0_opp_table>; - ti,syscon-efuse = <&scm_conf 0x610 0x3f 0>; - ti,syscon-rev = <&scm_conf 0x600>; clock-latency = <300000>; /* From omap-cpufreq driver */ }; }; - cpu0_opp_table: opp_table0 { - compatible = "operating-points-v2"; + cpu0_opp_table: opp-table { + compatible = "operating-points-v2-ti-cpu"; + syscon = <&scm_conf>; opp50@300000000 { opp-hz = /bits/ 64 <300000000>; diff --git a/sys/gnu/dts/arm/am437x-gp-evm.dts b/sys/gnu/dts/arm/am437x-gp-evm.dts index a4f31739057f..397e98b7e246 100644 --- a/sys/gnu/dts/arm/am437x-gp-evm.dts +++ b/sys/gnu/dts/arm/am437x-gp-evm.dts @@ -501,6 +501,21 @@ AM4372_IOPAD(0x884, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn2.gpio1_31 */ >; }; + + uart0_pins_default: uart0_pins_default { + pinctrl-single,pins = < + AM4372_IOPAD(0x968, PIN_INPUT | MUX_MODE0) /* uart0_ctsn.uart0_ctsn */ + AM4372_IOPAD(0x96C, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_rtsn.uart0_rtsn */ + AM4372_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + AM4372_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; +}; + +&uart0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_default>; }; &i2c0 { diff --git a/sys/gnu/dts/arm/am57xx-idk-common.dtsi b/sys/gnu/dts/arm/am57xx-idk-common.dtsi index e5ac1d81d15c..c536b2f5389f 100644 --- a/sys/gnu/dts/arm/am57xx-idk-common.dtsi +++ b/sys/gnu/dts/arm/am57xx-idk-common.dtsi @@ -101,6 +101,22 @@ }; }; +&dra7_pmx_core { + dcan1_pins_default: dcan1_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37d0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */ + DRA7XX_CORE_IOPAD(0x37d4, PIN_INPUT_PULLUP | MUX_MODE0) /* dcan1_rx */ + >; + }; + + dcan1_pins_sleep: dcan1_pins_sleep { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37d0, MUX_MODE15 | PULL_UP) /* dcan1_tx.off */ + DRA7XX_CORE_IOPAD(0x37d4, MUX_MODE15 | PULL_UP) /* dcan1_rx.off */ + >; + }; +}; + &i2c1 { status = "okay"; clock-frequency = <400000>; @@ -391,6 +407,14 @@ max-frequency = <96000000>; }; +&dcan1 { + status = "okay"; + pinctrl-names = "default", "sleep", "active"; + pinctrl-0 = <&dcan1_pins_sleep>; + pinctrl-1 = <&dcan1_pins_sleep>; + pinctrl-2 = <&dcan1_pins_default>; +}; + &qspi { status = "okay"; diff --git a/sys/gnu/dts/arm/armada-385-linksys-shelby.dts b/sys/gnu/dts/arm/armada-385-linksys-shelby.dts new file mode 100644 index 000000000000..c7a8ddd7f9a5 --- /dev/null +++ b/sys/gnu/dts/arm/armada-385-linksys-shelby.dts @@ -0,0 +1,114 @@ +/* + * Device Tree file for the Linksys WRT1900ACS (Shelby) + * + * Copyright (C) 2015 Imre Kaloz + * + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without + * any warranty of any kind, whether express or implied. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "armada-385-linksys.dtsi" + +/ { + model = "Linksys WRT1900ACS"; + compatible = "linksys,shelby", "linksys,armada385", "marvell,armada385", + "marvell,armada380"; + + soc { + internal-regs{ + i2c@11000 { + + pca9635@68 { + #address-cells = <1>; + #size-cells = <0>; + + wan_amber@0 { + label = "shelby:amber:wan"; + reg = <0x0>; + }; + + wan_white@1 { + label = "shelby:white:wan"; + reg = <0x1>; + }; + + wlan_2g@2 { + label = "shelby:white:wlan_2g"; + reg = <0x2>; + }; + + wlan_5g@3 { + label = "shelby:white:wlan_5g"; + reg = <0x3>; + }; + + usb2@5 { + label = "shelby:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "shelby:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "shelby:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "shelby:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "shelby:amber:wps"; + reg = <0x9>; + }; + }; + }; + }; + }; + + gpio-leds { + power { + label = "shelby:white:power"; + }; + + sata { + label = "shelby:white:sata"; + }; + }; +}; diff --git a/sys/gnu/dts/arm/armada-385-linksys.dtsi b/sys/gnu/dts/arm/armada-385-linksys.dtsi index df47bf1ea5eb..2306c45685b1 100644 --- a/sys/gnu/dts/arm/armada-385-linksys.dtsi +++ b/sys/gnu/dts/arm/armada-385-linksys.dtsi @@ -59,7 +59,8 @@ ranges = ; + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; internal-regs { i2c@11000 { @@ -88,6 +89,9 @@ ethernet@70000 { status = "okay"; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; fixed-link { speed = <1000>; full-duplex; @@ -97,6 +101,9 @@ ethernet@34000 { status = "okay"; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; fixed-link { speed = <1000>; full-duplex; @@ -159,6 +166,10 @@ status = "okay"; }; + bm@c8000 { + status = "okay"; + }; + /* USB part of the eSATA/USB 2.0 port */ usb@58000 { status = "okay"; @@ -241,6 +252,10 @@ }; }; + bm-bppi { + status = "okay"; + }; + pcie-controller { status = "okay"; @@ -305,6 +320,7 @@ sata { gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; default-state = "off"; + linux,default-trigger = "disk-activity"; }; }; diff --git a/sys/gnu/dts/arm/armada-385-synology-ds116.dts b/sys/gnu/dts/arm/armada-385-synology-ds116.dts new file mode 100644 index 000000000000..31510eb56f10 --- /dev/null +++ b/sys/gnu/dts/arm/armada-385-synology-ds116.dts @@ -0,0 +1,321 @@ +/* + * Device Tree file for Synology DS116 NAS + * + * Copyright (C) 2017 Willy Tarreau + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without + * any warranty of any kind, whether express or implied. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "armada-385.dtsi" +#include + +/ { + model = "Synology DS116"; + compatible = "marvell,a385-gp", "marvell,armada385", "marvell,armada380"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; /* 1 GB */ + }; + + soc { + ranges = ; + + internal-regs { + i2c@11000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; + + eeprom@57 { + compatible = "atmel,24c64"; + reg = <0x57>; + }; + }; + + serial@12000 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; + }; + + serial@12100 { + /* A PIC16F1829 is connected to uart1 at 9600 bps, + * and takes single-character orders : + * "1" : power off // already handled by the poweroff node + * "2" : short beep + * "3" : long beep + * "4" : turn the power LED ON + * "5" : flash the power LED + * "6" : turn the power LED OFF + * "7" : turn the status LED OFF + * "8" : turn the status LED ON + * "9" : flash the status LED + * "A" : flash the motherboard LED (D8) + * "B" : turn the motherboard LED OFF + * "C" : hard reset + */ + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; + }; + + poweroff@12100 { + compatible = "synology,power-off"; + reg = <0x12100 0x100>; + clocks = <&coreclk 0>; + }; + + ethernet@70000 { + pinctrl-names = "default"; + phy = <&phy0>; + phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + status = "okay"; + }; + + + mdio@72004 { + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins>; + + phy0: ethernet-phy@1 { + reg = <1>; + }; + }; + + sata@a8000 { + pinctrl-names = "default"; + pinctrl-0 = <&sata0_pins>; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + sata0: sata-port@0 { + reg = <0>; + target-supply = <®_5v_sata0>; + }; + }; + + bm@c8000 { + status = "okay"; + }; + + usb3@f0000 { + usb-phy = <&usb3_0_phy>; + status = "okay"; + }; + + usb3@f8000 { + usb-phy = <&usb3_1_phy>; + status = "okay"; + }; + }; + + bm-bppi { + status = "okay"; + }; + + gpio-fan { + compatible = "gpio-fan"; + gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>, + <&gpio1 17 GPIO_ACTIVE_HIGH>, + <&gpio1 16 GPIO_ACTIVE_HIGH>; + gpio-fan,speed-map = < 0 0 + 1500 1 + 2500 2 + 3000 3 + 3400 4 + 3700 5 + 3900 6 + 4000 7>; + cooling-cells = <2>; + }; + + gpio-leds { + compatible = "gpio-leds"; + + /* The green part is on gpio0.20 which is also used by + * sata0, and accesses to SATA disk 0 make it blink so it + * doesn't need to be declared here. + */ + orange { + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; + label = "ds116:orange:disk"; + default-state = "off"; + }; + }; + }; + + usb3_0_phy: usb3_0_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb3_0_vbus>; + }; + + usb3_1_phy: usb3_1_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb3_1_vbus>; + }; + + reg_usb3_0_vbus: usb3-vbus0 { + compatible = "regulator-fixed"; + regulator-name = "usb3-vbus0"; + pinctrl-names = "default"; + pinctrl-0 = <&xhci0_vbus_pins>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>; + }; + + reg_usb3_1_vbus: usb3-vbus1 { + compatible = "regulator-fixed"; + regulator-name = "usb3-vbus1"; + pinctrl-names = "default"; + pinctrl-0 = <&xhci1_vbus_pins>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>; + }; + + reg_sata0: pwr-sata0 { + compatible = "regulator-fixed"; + regulator-name = "pwr_en_sata0"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + regulator-boot-on; + gpio = <&gpio0 15 GPIO_ACTIVE_HIGH>; + }; + + reg_5v_sata0: v5-sata0 { + compatible = "regulator-fixed"; + regulator-name = "v5.0-sata0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_sata0>; + }; + + reg_12v_sata0: v12-sata0 { + compatible = "regulator-fixed"; + regulator-name = "v12.0-sata0"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + vin-supply = <®_sata0>; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "macronix,mx25l6405d", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <50000000>; + m25p,fast-read; + + /* Note: there is a redboot partition table despite u-boot + * being used. The names presented here are the same as those + * found in the FIS directory. There is also a small device + * tree in the last 64kB of the RedBoot partition which is not + * enumerated. The MAC address and the serial number are listed + * in the "vendor" partition. + */ + partition@00000000 { + label = "RedBoot"; + reg = <0x00000000 0x000f0000>; + read-only; + }; + + partition@000c0000 { + label = "zImage"; + reg = <0x000f0000 0x002d0000>; + }; + + partition@00390000 { + label = "rd.gz"; + reg = <0x003c0000 0x00410000>; + }; + + partition@007d0000 { + label = "vendor"; + reg = <0x007d0000 0x00010000>; + read-only; + }; + + partition@007e0000 { + label = "RedBoot config"; + reg = <0x007e0000 0x00010000>; + read-only; + }; + + partition@007f0000 { + label = "FIS directory"; + reg = <0x007f0000 0x00010000>; + read-only; + }; + }; +}; + +&pinctrl { + /* use only one pin for UART1, as mpp20 is used by sata0 */ + uart1_pins: uart-pins-1 { + marvell,pins = "mpp19"; + marvell,function = "ua1"; + }; + + xhci0_vbus_pins: xhci0_vbus_pins { + marvell,pins = "mpp58"; + marvell,function = "gpio"; + }; + xhci1_vbus_pins: xhci1_vbus_pins { + marvell,pins = "mpp59"; + marvell,function = "gpio"; + }; +}; diff --git a/sys/gnu/dts/arm/armada-385.dtsi b/sys/gnu/dts/arm/armada-385.dtsi index 8e63be33472e..7fcc4c4885cf 100644 --- a/sys/gnu/dts/arm/armada-385.dtsi +++ b/sys/gnu/dts/arm/armada-385.dtsi @@ -70,13 +70,7 @@ }; soc { - internal-regs { - pinctrl@18000 { - compatible = "marvell,mv88f6820-pinctrl"; - }; - }; - - pcie-controller { + pciec: pcie-controller { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -106,7 +100,7 @@ * configured in x4 by the bootloader, then * pcie@4,0 is not available. */ - pcie@1,0 { + pcie1: pcie@1,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; reg = <0x0800 0 0 0 0>; @@ -124,7 +118,7 @@ }; /* x1 port */ - pcie@2,0 { + pcie2: pcie@2,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; reg = <0x1000 0 0 0 0>; @@ -142,7 +136,7 @@ }; /* x1 port */ - pcie@3,0 { + pcie3: pcie@3,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; reg = <0x1800 0 0 0 0>; @@ -163,7 +157,7 @@ * x1 port only available when pcie@1,0 is * configured as a x1 port */ - pcie@4,0 { + pcie4: pcie@4,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; reg = <0x2000 0 0 0 0>; @@ -182,3 +176,7 @@ }; }; }; + +&pinctrl { + compatible = "marvell,mv88f6820-pinctrl"; +}; diff --git a/sys/gnu/dts/arm/armada-388-clearfog.dts b/sys/gnu/dts/arm/armada-388-clearfog.dts index 2745b7416313..0d5f1f062275 100644 --- a/sys/gnu/dts/arm/armada-388-clearfog.dts +++ b/sys/gnu/dts/arm/armada-388-clearfog.dts @@ -186,25 +186,6 @@ }; }; -&pinctrl { - clearfog_dsa0_clk_pins: clearfog-dsa0-clk-pins { - marvell,pins = "mpp46"; - marvell,function = "ref"; - }; - clearfog_dsa0_pins: clearfog-dsa0-pins { - marvell,pins = "mpp23", "mpp41"; - marvell,function = "gpio"; - }; - clearfog_spi1_cs_pins: spi1-cs-pins { - marvell,pins = "mpp55"; - marvell,function = "spi1"; - }; - rear_button_pins: rear-button-pins { - marvell,pins = "mpp34"; - marvell,function = "gpio"; - }; -}; - &mdio { status = "okay"; @@ -268,6 +249,25 @@ }; }; +&pinctrl { + clearfog_dsa0_clk_pins: clearfog-dsa0-clk-pins { + marvell,pins = "mpp46"; + marvell,function = "ref"; + }; + clearfog_dsa0_pins: clearfog-dsa0-pins { + marvell,pins = "mpp23", "mpp41"; + marvell,function = "gpio"; + }; + clearfog_spi1_cs_pins: spi1-cs-pins { + marvell,pins = "mpp55"; + marvell,function = "spi1"; + }; + rear_button_pins: rear-button-pins { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; +}; + &spi1 { /* * Add SPI CS pins for clearfog: diff --git a/sys/gnu/dts/arm/armada-388.dtsi b/sys/gnu/dts/arm/armada-388.dtsi index 564fa5937e25..1c0d151b2aaa 100644 --- a/sys/gnu/dts/arm/armada-388.dtsi +++ b/sys/gnu/dts/arm/armada-388.dtsi @@ -50,13 +50,8 @@ model = "Marvell Armada 388 family SoC"; compatible = "marvell,armada388", "marvell,armada385", "marvell,armada380"; - soc { internal-regs { - pinctrl@18000 { - compatible = "marvell,mv88f6828-pinctrl"; - }; - sata@e0000 { compatible = "marvell,armada-380-ahci"; reg = <0xe0000 0x2000>; @@ -68,3 +63,7 @@ }; }; }; + +&pinctrl { + compatible = "marvell,mv88f6828-pinctrl"; +}; diff --git a/sys/gnu/dts/arm/armada-38x.dtsi b/sys/gnu/dts/arm/armada-38x.dtsi index 79b767507eab..8b165c31de1e 100644 --- a/sys/gnu/dts/arm/armada-38x.dtsi +++ b/sys/gnu/dts/arm/armada-38x.dtsi @@ -82,7 +82,7 @@ reg = ; }; - devbus-bootcs { + devbus_bootcs: devbus-bootcs { compatible = "marvell,mvebu-devbus"; reg = ; ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>; @@ -92,7 +92,7 @@ status = "disabled"; }; - devbus-cs0 { + devbus_cs0: devbus-cs0 { compatible = "marvell,mvebu-devbus"; reg = ; ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>; @@ -102,7 +102,7 @@ status = "disabled"; }; - devbus-cs1 { + devbus_cs1: devbus-cs1 { compatible = "marvell,mvebu-devbus"; reg = ; ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>; @@ -112,7 +112,7 @@ status = "disabled"; }; - devbus-cs2 { + devbus_cs2: devbus-cs2 { compatible = "marvell,mvebu-devbus"; reg = ; ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>; @@ -122,7 +122,7 @@ status = "disabled"; }; - devbus-cs3 { + devbus_cs3: devbus-cs3 { compatible = "marvell,mvebu-devbus"; reg = ; ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>; @@ -339,7 +339,7 @@ ; }; - system-controller@18200 { + systemc: system-controller@18200 { compatible = "marvell,armada-380-system-controller", "marvell,armada-370-xp-system-controller"; reg = <0x18200 0x100>; @@ -360,7 +360,8 @@ mbusc: mbus-controller@20000 { compatible = "marvell,mbus-controller"; - reg = <0x20000 0x100>, <0x20180 0x20>; + reg = <0x20000 0x100>, <0x20180 0x20>, + <0x20250 0x8>; }; mpic: interrupt-controller@20a00 { @@ -373,7 +374,7 @@ interrupts = ; }; - timer@20300 { + timer: timer@20300 { compatible = "marvell,armada-380-timer", "marvell,armada-xp-timer"; reg = <0x20300 0x30>, <0x21040 0x30>; @@ -387,14 +388,14 @@ clock-names = "nbclk", "fixed"; }; - watchdog@20300 { + watchdog: watchdog@20300 { compatible = "marvell,armada-380-wdt"; reg = <0x20300 0x34>, <0x20704 0x4>, <0x18260 0x4>; clocks = <&coreclk 2>, <&refclk>; clock-names = "nbclk", "fixed"; }; - cpurst@20800 { + cpurst: cpurst@20800 { compatible = "marvell,armada-370-cpu-reset"; reg = <0x20800 0x10>; }; @@ -404,12 +405,12 @@ reg = <0x20d20 0x6c>; }; - coherency-fabric@21010 { + coherencyfab: coherency-fabric@21010 { compatible = "marvell,armada-380-coherency-fabric"; reg = <0x21010 0x1c>; }; - pmsu@22000 { + pmsu: pmsu@22000 { compatible = "marvell,armada-380-pmsu"; reg = <0x22000 0x1000>; }; @@ -451,7 +452,7 @@ status = "disabled"; }; - usb@58000 { + usb0: usb@58000 { compatible = "marvell,orion-ehci"; reg = <0x58000 0x500>; interrupts = ; @@ -459,7 +460,7 @@ status = "disabled"; }; - xor@60800 { + xor0: xor@60800 { compatible = "marvell,armada-380-xor", "marvell,orion-xor"; reg = <0x60800 0x100 0x60a00 0x100>; @@ -479,7 +480,7 @@ }; }; - xor@60900 { + xor1: xor@60900 { compatible = "marvell,armada-380-xor", "marvell,orion-xor"; reg = <0x60900 0x100 0x60b00 0x100>; @@ -507,7 +508,7 @@ clocks = <&gateclk 4>; }; - crypto@90000 { + cesa: crypto@90000 { compatible = "marvell,armada-38x-crypto"; reg = <0x90000 0x10000>; reg-names = "regs"; @@ -522,14 +523,14 @@ marvell,crypto-sram-size = <0x800>; }; - rtc@a3800 { + rtc: rtc@a3800 { compatible = "marvell,armada-380-rtc"; reg = <0xa3800 0x20>, <0x184a0 0x0c>; reg-names = "rtc", "rtc-soc"; interrupts = ; }; - sata@a8000 { + ahci0: sata@a8000 { compatible = "marvell,armada-380-ahci"; reg = <0xa8000 0x2000>; interrupts = ; @@ -545,7 +546,7 @@ status = "disabled"; }; - sata@e0000 { + ahci1: sata@e0000 { compatible = "marvell,armada-380-ahci"; reg = <0xe0000 0x2000>; interrupts = ; @@ -561,13 +562,13 @@ clock-output-names = "nand"; }; - thermal@e8078 { + thermal: thermal@e8078 { compatible = "marvell,armada380-thermal"; reg = <0xe4078 0x4>, <0xe4074 0x4>; status = "okay"; }; - flash@d0000 { + nand: flash@d0000 { compatible = "marvell,armada370-nand"; reg = <0xd0000 0x54>; #address-cells = <1>; @@ -577,7 +578,7 @@ status = "disabled"; }; - sdhci@d8000 { + sdhci: sdhci@d8000 { compatible = "marvell,armada-380-sdhci"; reg-names = "sdhci", "mbus", "conf-sdio3"; reg = <0xd8000 0x1000>, @@ -589,7 +590,7 @@ status = "disabled"; }; - usb3@f0000 { + usb3_0: usb3@f0000 { compatible = "marvell,armada-380-xhci"; reg = <0xf0000 0x4000>,<0xf4000 0x4000>; interrupts = ; @@ -597,7 +598,7 @@ status = "disabled"; }; - usb3@f8000 { + usb3_1: usb3@f8000 { compatible = "marvell,armada-380-xhci"; reg = <0xf8000 0x4000>,<0xfc000 0x4000>; interrupts = ; diff --git a/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi b/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi index f6a03dcee5ef..84cc232a29e9 100644 --- a/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi +++ b/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi @@ -45,11 +45,14 @@ * common to all Armada XP SoCs. */ -#include "armada-xp.dtsi" +#include "armada-370-xp.dtsi" / { + #address-cells = <2>; + #size-cells = <2>; + model = "Marvell 98DX3236 SoC"; - compatible = "marvell,armadaxp-98dx3236", "marvell,armadaxp", "marvell,armada-370-xp"; + compatible = "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; aliases { gpio0 = &gpio0; @@ -72,12 +75,19 @@ }; soc { + compatible = "marvell,armadaxp-mbus", "simple-bus"; + ranges = ; + bootrom { + compatible = "marvell,bootrom"; + reg = ; + }; + /* * 98DX3236 has 1 x1 PCIe unit Gen2.0 */ @@ -95,8 +105,7 @@ ranges = <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */ - 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */ - 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */>; + 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>; pcie1: pcie@1,0 { device_type = "pci"; @@ -117,48 +126,18 @@ }; internal-regs { - coreclk: mvebu-sar@18230 { - compatible = "marvell,mv98dx3236-core-clock"; + sdramc@1400 { + compatible = "marvell,armada-xp-sdram-controller"; + reg = <0x1400 0x500>; }; - cpuclk: clock-complex@18700 { - compatible = "marvell,mv98dx3236-cpu-clock"; - }; - - corediv-clock@18740 { - status = "disabled"; - }; - - xor@60900 { - status = "disabled"; - }; - - crypto@90000 { - status = "disabled"; - }; - - xor@f0900 { - status = "disabled"; - }; - - xor@f0800 { - compatible = "marvell,orion-xor"; - reg = <0xf0800 0x100 - 0xf0a00 0x100>; - clocks = <&gateclk 22>; - status = "okay"; - - xor10 { - interrupts = <51>; - dmacap,memcpy; - dmacap,xor; - }; - xor11 { - interrupts = <52>; - dmacap,memcpy; - dmacap,xor; - dmacap,memset; - }; + L2: l2-cache@8000 { + compatible = "marvell,aurora-system-cache"; + reg = <0x08000 0x1000>; + cache-id-part = <0x100>; + cache-level = <2>; + cache-unified; + wt-override; }; gpio0: gpio@18100 { @@ -190,16 +169,99 @@ interrupts = <87>; }; + systemc: system-controller@18200 { + compatible = "marvell,armada-370-xp-system-controller"; + reg = <0x18200 0x500>; + }; + + gateclk: clock-gating-control@18220 { + compatible = "marvell,mv98dx3236-gating-clock"; + reg = <0x18220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; + }; + + cpuclk: clock-complex@18700 { + #clock-cells = <1>; + compatible = "marvell,mv98dx3236-cpu-clock"; + reg = <0x18700 0x24>, <0x1c054 0x10>; + clocks = <&coreclk 1>; + }; + + corediv-clock@18740 { + status = "disabled"; + }; + + cpu-config@21000 { + compatible = "marvell,armada-xp-cpu-config"; + reg = <0x21000 0x8>; + }; + + ethernet@70000 { + compatible = "marvell,armada-xp-neta"; + }; + + ethernet@74000 { + compatible = "marvell,armada-xp-neta"; + }; + + xor1: xor@f0800 { + compatible = "marvell,orion-xor"; + reg = <0xf0800 0x100 + 0xf0a00 0x100>; + clocks = <&gateclk 22>; + status = "okay"; + + xor10 { + interrupts = <51>; + dmacap,memcpy; + dmacap,xor; + }; + xor11 { + interrupts = <52>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + nand: nand@d0000 { clocks = <&dfx_coredivclk 0>; }; + + xor0: xor@f0900 { + compatible = "marvell,orion-xor"; + reg = <0xF0900 0x100 + 0xF0B00 0x100>; + clocks = <&gateclk 28>; + status = "okay"; + + xor00 { + interrupts = <94>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <95>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; }; - dfxr: dfx-registers@ac000000 { - compatible = "simple-bus"; + dfx: dfx-server@ac000000 { + compatible = "marvell,dfx-server", "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 MBUS_ID(0x08, 0x00) 0 0x100000>; + reg = ; + + coreclk: mvebu-sar@f8204 { + compatible = "marvell,mv98dx3236-core-clock"; + reg = <0xf8204 0x4>; + #clock-cells = <1>; + }; dfx_coredivclk: corediv-clock@f8268 { compatible = "marvell,mv98dx3236-corediv-clock"; @@ -208,11 +270,6 @@ clocks = <&mainpll>; clock-output-names = "nand"; }; - - dfx: dfx@0 { - compatible = "marvell,dfx-server"; - reg = <0 0x100000>; - }; }; switch: switch@a8000000 { @@ -229,6 +286,53 @@ }; }; }; + + clocks { + /* 25 MHz reference crystal */ + refclk: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + }; +}; + +&i2c0 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11000 0x100>; +}; + +&i2c1 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11100 0x100>; +}; + +&mpic { + reg = <0x20a00 0x2d0>, <0x21070 0x58>; +}; + +&timer { + compatible = "marvell,armada-xp-timer"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; +}; + +&watchdog { + compatible = "marvell,armada-xp-wdt"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; +}; + +&cpurst { + reg = <0x20800 0x20>; +}; + +&usb0 { + clocks = <&gateclk 18>; +}; + +&usb1 { + clocks = <&gateclk 19>; }; &pinctrl { @@ -241,14 +345,13 @@ }; }; +&spi0 { + compatible = "marvell,armada-xp-spi", "marvell,orion-spi"; + pinctrl-0 = <&spi0_pins>; + pinctrl-names = "default"; +}; + &sdio { status = "disabled"; }; -&crypto_sram0 { - status = "disabled"; -}; - -&crypto_sram1 { - status = "disabled"; -}; diff --git a/sys/gnu/dts/arm/armada-xp-98dx3336.dtsi b/sys/gnu/dts/arm/armada-xp-98dx3336.dtsi index e1580afdc260..a0d81bd7312b 100644 --- a/sys/gnu/dts/arm/armada-xp-98dx3336.dtsi +++ b/sys/gnu/dts/arm/armada-xp-98dx3336.dtsi @@ -49,7 +49,7 @@ / { model = "Marvell 98DX3336 SoC"; - compatible = "marvell,armadaxp-98dx3336", "marvell,armadaxp-98dx3236", "marvell,armadaxp", "marvell,armada-370-xp"; + compatible = "marvell,armadaxp-98dx3336", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; cpus { cpu@1 { diff --git a/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi b/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi index b9d9b269efb4..51de91b31a9d 100644 --- a/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi +++ b/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi @@ -49,7 +49,7 @@ / { model = "Marvell 98DX4251 SoC"; - compatible = "marvell,armadaxp-98dx4251", "marvell,armadaxp-98dx3236", "marvell,armadaxp", "marvell,armada-370-xp"; + compatible = "marvell,armadaxp-98dx4251", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; cpus { cpu@1 { diff --git a/sys/gnu/dts/arm/armada-xp-db-dxbc2.dts b/sys/gnu/dts/arm/armada-xp-db-dxbc2.dts index a8130805074e..1b1ff17fdd9c 100644 --- a/sys/gnu/dts/arm/armada-xp-db-dxbc2.dts +++ b/sys/gnu/dts/arm/armada-xp-db-dxbc2.dts @@ -58,7 +58,7 @@ / { model = "Marvell Bobcat2 Evaluation Board"; - compatible = "marvell,db-dxbc2", "marvell,armadaxp-98dx4251", "marvell,armadaxp", "marvell,armada-370-xp"; + compatible = "marvell,db-dxbc2", "marvell,armadaxp-98dx4251", "marvell,armada-370-xp"; chosen { bootargs = "console=ttyS0,115200 earlyprintk"; diff --git a/sys/gnu/dts/arm/armada-xp-db-xc3-24g4xg.dts b/sys/gnu/dts/arm/armada-xp-db-xc3-24g4xg.dts index 4e07cb6ed800..06fce35d7491 100644 --- a/sys/gnu/dts/arm/armada-xp-db-xc3-24g4xg.dts +++ b/sys/gnu/dts/arm/armada-xp-db-xc3-24g4xg.dts @@ -58,7 +58,7 @@ / { model = "DB-XC3-24G4XG"; - compatible = "marvell,db-xc3-24g4xg", "marvell,armadaxp-98dx3336", "marvell,armadaxp", "marvell,armada-370-xp"; + compatible = "marvell,db-xc3-24g4xg", "marvell,armadaxp-98dx3336", "marvell,armada-370-xp"; chosen { bootargs = "console=ttyS0,115200 earlyprintk"; diff --git a/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts b/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts index 42ea8764814c..9efcf59c9b44 100644 --- a/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts +++ b/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts @@ -71,7 +71,8 @@ ranges = ; + MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>; internal-regs { @@ -95,6 +96,9 @@ pinctrl-names = "default"; status = "okay"; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; fixed-link { speed = <1000>; full-duplex; @@ -106,6 +110,9 @@ pinctrl-names = "default"; status = "okay"; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; fixed-link { speed = <1000>; full-duplex; @@ -156,6 +163,7 @@ esata@4 { label = "mamba:white:esata"; reg = <0x4>; + linux,default-trigger = "disk-activity"; }; usb2@5 { @@ -185,6 +193,10 @@ }; }; + bm@c8000 { + status = "okay"; + }; + nand@d0000 { status = "okay"; num-cs = <1>; @@ -258,6 +270,10 @@ }; }; }; + + bm-bppi { + status = "okay"; + }; }; gpio_keys { diff --git a/sys/gnu/dts/arm/aspeed-ast2500-evb.dts b/sys/gnu/dts/arm/aspeed-ast2500-evb.dts index d967603dade8..7c90dac99822 100644 --- a/sys/gnu/dts/arm/aspeed-ast2500-evb.dts +++ b/sys/gnu/dts/arm/aspeed-ast2500-evb.dts @@ -20,6 +20,28 @@ }; }; +&fmc { + status = "okay"; + flash@0 { + status = "okay"; + m25p,fast-read; + label = "bmc"; + }; +}; + +&spi1 { + status = "okay"; + flash@0 { + status = "okay"; + m25p,fast-read; + label = "pnor"; + }; +}; + +&spi2 { + status = "okay"; +}; + &uart5 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/aspeed-bmc-opp-palmetto.dts b/sys/gnu/dts/arm/aspeed-bmc-opp-palmetto.dts index 1d2fc1e1dc29..112551766275 100644 --- a/sys/gnu/dts/arm/aspeed-bmc-opp-palmetto.dts +++ b/sys/gnu/dts/arm/aspeed-bmc-opp-palmetto.dts @@ -31,6 +31,24 @@ }; }; +&fmc { + status = "okay"; + flash@0 { + status = "okay"; + m25p,fast-read; + label = "bmc"; + }; +}; + +&spi { + status = "okay"; + flash@0 { + status = "okay"; + m25p,fast-read; + label = "pnor"; + }; +}; + &uart5 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/aspeed-bmc-opp-romulus.dts b/sys/gnu/dts/arm/aspeed-bmc-opp-romulus.dts index 7a3b2b50c884..1190fec1b5d0 100644 --- a/sys/gnu/dts/arm/aspeed-bmc-opp-romulus.dts +++ b/sys/gnu/dts/arm/aspeed-bmc-opp-romulus.dts @@ -31,6 +31,42 @@ }; }; +&fmc { + status = "okay"; + flash@0 { + status = "okay"; + m25p,fast-read; + label = "bmc"; + }; +}; + +&spi1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1_default>; + + flash@0 { + status = "okay"; + m25p,fast-read; + label = "pnor"; + }; +}; + +&uart1 { + /* Rear RS-232 connector */ + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd1_default + &pinctrl_rxd1_default + &pinctrl_nrts1_default + &pinctrl_ndtr1_default + &pinctrl_ndsr1_default + &pinctrl_ncts1_default + &pinctrl_ndcd1_default + &pinctrl_nri1_default>; +}; + &uart5 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/aspeed-g4.dtsi b/sys/gnu/dts/arm/aspeed-g4.dtsi index 0b4932cc02a8..8c6bc29eb7f6 100644 --- a/sys/gnu/dts/arm/aspeed-g4.dtsi +++ b/sys/gnu/dts/arm/aspeed-g4.dtsi @@ -18,21 +18,41 @@ }; }; - clocks { - clk_clkin: clk_clkin { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <48000000>; - }; - - }; - ahb { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + fmc: flash-controller@1e620000 { + reg = < 0x1e620000 0x94 + 0x20000000 0x02000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2400-fmc"; + status = "disabled"; + interrupts = <19>; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + + spi: flash-controller@1e630000 { + reg = < 0x1e630000 0x18 + 0x30000000 0x02000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2400-spi"; + status = "disabled"; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + vic: interrupt-controller@1e6c0080 { compatible = "aspeed,ast2400-vic"; interrupt-controller; @@ -42,18 +62,16 @@ }; mac0: ethernet@1e660000 { - compatible = "faraday,ftgmac100"; + compatible = "aspeed,ast2400-mac", "faraday,ftgmac100"; reg = <0x1e660000 0x180>; interrupts = <2>; - no-hw-checksum; status = "disabled"; }; mac1: ethernet@1e680000 { - compatible = "faraday,ftgmac100"; + compatible = "aspeed,ast2400-mac", "faraday,ftgmac100"; reg = <0x1e680000 0x180>; interrupts = <3>; - no-hw-checksum; status = "disabled"; }; @@ -63,16 +81,48 @@ #size-cells = <1>; ranges; - clk_hpll: clk_hpll@1e6e2070 { - #clock-cells = <0>; - compatible = "aspeed,g4-hpll-clock"; - reg = <0x1e6e2070 0x4>; - clocks = <&clk_clkin>; - }; - syscon: syscon@1e6e2000 { compatible = "aspeed,g4-scu", "syscon", "simple-mfd"; reg = <0x1e6e2000 0x1a8>; + #address-cells = <1>; + #size-cells = <0>; + + clk_clkin: clk_clkin { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <48000000>; + }; + + clk_hpll: clk_hpll@70 { + #clock-cells = <0>; + compatible = "aspeed,g4-hpll-clock", "fixed-clock"; + reg = <0x70>; + clocks = <&clk_clkin>; + clock-frequency = <384000000>; + }; + + clk_ahb: clk_ahb@70 { + #clock-cells = <0>; + compatible = "aspeed,g4-ahb-clock", "fixed-clock"; + reg = <0x70>; + clocks = <&clk_hpll>; + clock-frequency = <192000000>; + }; + + clk_apb: clk_apb@08 { + #clock-cells = <0>; + compatible = "aspeed,g4-apb-clock", "fixed-clock"; + reg = <0x08>; + clocks = <&clk_hpll>; + clock-frequency = <48000000>; + }; + + clk_uart: clk_uart@2c{ + #clock-cells = <0>; + compatible = "aspeed,g4-uart-clock", "fixed-clock"; + reg = <0x2c>; + clock-frequency = <24000000>; + }; pinctrl: pinctrl { compatible = "aspeed,g4-pinctrl"; @@ -820,19 +870,6 @@ }; }; - clk_apb: clk_apb@1e6e2008 { - #clock-cells = <0>; - compatible = "aspeed,g4-apb-clock"; - reg = <0x1e6e2008 0x4>; - clocks = <&clk_hpll>; - }; - - clk_uart: clk_uart@1e6e2008 { - #clock-cells = <0>; - compatible = "aspeed,uart-clock"; - reg = <0x1e6e202c 0x4>; - }; - sram@1e720000 { compatible = "mmio-sram"; reg = <0x1e720000 0x8000>; // 32K @@ -859,13 +896,13 @@ }; wdt1: wdt@1e785000 { - compatible = "aspeed,wdt"; + compatible = "aspeed,ast2400-wdt"; reg = <0x1e785000 0x1c>; interrupts = <27>; }; wdt2: wdt@1e785020 { - compatible = "aspeed,wdt"; + compatible = "aspeed,ast2400-wdt"; reg = <0x1e785020 0x1c>; interrupts = <27>; clocks = <&clk_apb>; @@ -932,6 +969,14 @@ no-loopback-test; status = "disabled"; }; + + adc: adc@1e6e9000 { + compatible = "aspeed,ast2400-adc"; + reg = <0x1e6e9000 0xb0>; + clocks = <&clk_apb>; + #io-channel-cells = <1>; + status = "disabled"; + }; }; }; }; diff --git a/sys/gnu/dts/arm/aspeed-g5.dtsi b/sys/gnu/dts/arm/aspeed-g5.dtsi index b664fe380936..a0bea4a6ec77 100644 --- a/sys/gnu/dts/arm/aspeed-g5.dtsi +++ b/sys/gnu/dts/arm/aspeed-g5.dtsi @@ -24,6 +24,69 @@ #size-cells = <1>; ranges; + fmc: flash-controller@1e620000 { + reg = < 0x1e620000 0xc4 + 0x20000000 0x10000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2500-fmc"; + status = "disabled"; + interrupts = <19>; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@1 { + reg = < 1 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@2 { + reg = < 2 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + + spi1: flash-controller@1e630000 { + reg = < 0x1e630000 0xc4 + 0x30000000 0x08000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2500-spi"; + status = "disabled"; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@1 { + reg = < 1 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + + spi2: flash-controller@1e631000 { + reg = < 0x1e631000 0xc4 + 0x38000000 0x08000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2500-spi"; + status = "disabled"; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@1 { + reg = < 1 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + vic: interrupt-controller@1e6c0080 { compatible = "aspeed,ast2400-vic"; interrupt-controller; @@ -33,18 +96,16 @@ }; mac0: ethernet@1e660000 { - compatible = "faraday,ftgmac100"; + compatible = "aspeed,ast2500-mac", "faraday,ftgmac100"; reg = <0x1e660000 0x180>; interrupts = <2>; - no-hw-checksum; status = "disabled"; }; mac1: ethernet@1e680000 { - compatible = "faraday,ftgmac100"; + compatible = "aspeed,ast2500-mac", "faraday,ftgmac100"; reg = <0x1e680000 0x180>; interrupts = <3>; - no-hw-checksum; status = "disabled"; }; @@ -54,15 +115,49 @@ #size-cells = <1>; ranges; - clk_clkin: clk_clkin@1e6e2070 { - #clock-cells = <0>; - compatible = "aspeed,g5-clkin-clock"; - reg = <0x1e6e2070 0x04>; - }; - syscon: syscon@1e6e2000 { compatible = "aspeed,g5-scu", "syscon", "simple-mfd"; reg = <0x1e6e2000 0x1a8>; + #address-cells = <1>; + #size-cells = <0>; + + clk_clkin: clk_clkin@70 { + #clock-cells = <0>; + compatible = "aspeed,g5-clkin-clock", "fixed-clock"; + reg = <0x70>; + clock-frequency = <24000000>; + }; + + clk_hpll: clk_hpll@24 { + #clock-cells = <0>; + compatible = "aspeed,g5-hpll-clock", "fixed-clock"; + reg = <0x24>; + clocks = <&clk_clkin>; + clock-frequency = <792000000>; + }; + + clk_ahb: clk_ahb@70 { + #clock-cells = <0>; + compatible = "aspeed,g5-ahb-clock", "fixed-clock"; + reg = <0x70>; + clocks = <&clk_hpll>; + clock-frequency = <198000000>; + }; + + clk_apb: clk_apb@08 { + #clock-cells = <0>; + compatible = "aspeed,g5-apb-clock", "fixed-clock"; + reg = <0x08>; + clocks = <&clk_hpll>; + clock-frequency = <24750000>; + }; + + clk_uart: clk_uart@2c { + #clock-cells = <0>; + compatible = "aspeed,uart-clock", "fixed-clock"; + reg = <0x2c>; + clock-frequency = <24000000>; + }; pinctrl: pinctrl { compatible = "aspeed,g5-pinctrl"; @@ -287,7 +382,6 @@ function = "LAD0"; groups = "LAD0"; }; - pinctrl_lad1_default: lad1_default { function = "LAD1"; groups = "LAD1"; @@ -874,33 +968,7 @@ }; }; - }; - clk_hpll: clk_hpll@1e6e2024 { - #clock-cells = <0>; - compatible = "aspeed,g5-hpll-clock"; - reg = <0x1e6e2024 0x4>; - clocks = <&clk_clkin>; - }; - - clk_ahb: clk_ahb@1e6e2070 { - #clock-cells = <0>; - compatible = "aspeed,g5-ahb-clock"; - reg = <0x1e6e2070 0x4>; - clocks = <&clk_hpll>; - }; - - clk_apb: clk_apb@1e6e2008 { - #clock-cells = <0>; - compatible = "aspeed,g5-apb-clock"; - reg = <0x1e6e2008 0x4>; - clocks = <&clk_hpll>; - }; - - clk_uart: clk_uart@1e6e2008 { - #clock-cells = <0>; - compatible = "aspeed,uart-clock"; - reg = <0x1e6e202c 0x4>; }; gfx: display@1e6e6000 { @@ -936,21 +1004,21 @@ wdt1: wdt@1e785000 { - compatible = "aspeed,wdt"; - reg = <0x1e785000 0x1c>; + compatible = "aspeed,ast2500-wdt"; + reg = <0x1e785000 0x20>; interrupts = <27>; }; wdt2: wdt@1e785020 { - compatible = "aspeed,wdt"; - reg = <0x1e785020 0x1c>; + compatible = "aspeed,ast2500-wdt"; + reg = <0x1e785020 0x20>; interrupts = <27>; status = "disabled"; }; wdt3: wdt@1e785040 { - compatible = "aspeed,wdt"; - reg = <0x1e785074 0x1c>; + compatible = "aspeed,ast2500-wdt"; + reg = <0x1e785040 0x20>; status = "disabled"; }; @@ -1044,6 +1112,14 @@ no-loopback-test; status = "disabled"; }; + + adc: adc@1e6e9000 { + compatible = "aspeed,ast2500-adc"; + reg = <0x1e6e9000 0xb0>; + clocks = <&clk_apb>; + #io-channel-cells = <1>; + status = "disabled"; + }; }; }; }; diff --git a/sys/gnu/dts/arm/at91-sama5d2_xplained.dts b/sys/gnu/dts/arm/at91-sama5d2_xplained.dts index 9f7f8a7d8ff9..0bef9e0b89c6 100644 --- a/sys/gnu/dts/arm/at91-sama5d2_xplained.dts +++ b/sys/gnu/dts/arm/at91-sama5d2_xplained.dts @@ -246,6 +246,7 @@ shdwc@f8048010 { atmel,shdwc-debouncer = <976>; + atmel,wakeup-rtc-timer; input@0 { reg = <0>; diff --git a/sys/gnu/dts/arm/at91-sama5d3_xplained.dts b/sys/gnu/dts/arm/at91-sama5d3_xplained.dts index c51fc652f6c7..5a53fcf542ab 100644 --- a/sys/gnu/dts/arm/at91-sama5d3_xplained.dts +++ b/sys/gnu/dts/arm/at91-sama5d3_xplained.dts @@ -162,9 +162,10 @@ }; adc0: adc@f8018000 { + atmel,adc-vref = <3300>; + atmel,adc-channels-used = <0xfe>; pinctrl-0 = < &pinctrl_adc0_adtrg - &pinctrl_adc0_ad0 &pinctrl_adc0_ad1 &pinctrl_adc0_ad2 &pinctrl_adc0_ad3 @@ -172,8 +173,6 @@ &pinctrl_adc0_ad5 &pinctrl_adc0_ad6 &pinctrl_adc0_ad7 - &pinctrl_adc0_ad8 - &pinctrl_adc0_ad9 >; status = "okay"; }; diff --git a/sys/gnu/dts/arm/at91-tse850-3.dts b/sys/gnu/dts/arm/at91-tse850-3.dts index 669a2c6bdefc..498fba3e52b5 100644 --- a/sys/gnu/dts/arm/at91-tse850-3.dts +++ b/sys/gnu/dts/arm/at91-tse850-3.dts @@ -86,16 +86,43 @@ #io-channel-cells = <1>; }; - envelope-detector { + env_det: envelope-detector { compatible = "axentia,tse850-envelope-detector"; io-channels = <&dac 0>; io-channel-names = "dac"; + #io-channel-cells = <1>; interrupt-parent = <&pioA>; interrupts = <3 IRQ_TYPE_EDGE_RISING>; interrupt-names = "comp"; }; + mux: mux-controller { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + + mux-gpios = <&pioA 0 GPIO_ACTIVE_HIGH>, + <&pioA 1 GPIO_ACTIVE_HIGH>, + <&pioA 2 GPIO_ACTIVE_HIGH>; + idle-state = <0>; + }; + + envelope-detector-mux { + compatible = "io-channel-mux"; + io-channels = <&env_det 0>; + io-channel-names = "parent"; + + mux-controls = <&mux>; + + channels = "", "", + "sync-1", + "in", + "out", + "sync-2", + "sys-reg", + "ana-reg"; + }; + leds { compatible = "gpio-leds"; diff --git a/sys/gnu/dts/arm/at91sam9261.dtsi b/sys/gnu/dts/arm/at91sam9261.dtsi index 3fe77c38bd0d..7e80acda8f69 100644 --- a/sys/gnu/dts/arm/at91sam9261.dtsi +++ b/sys/gnu/dts/arm/at91sam9261.dtsi @@ -263,7 +263,7 @@ }; matrix: matrix@ffffee00 { - compatible = "atmel,at91sam9260-bus-matrix", "syscon"; + compatible = "atmel,at91sam9261-matrix", "syscon"; reg = <0xffffee00 0x200>; }; diff --git a/sys/gnu/dts/arm/at91sam9x5ek.dtsi b/sys/gnu/dts/arm/at91sam9x5ek.dtsi index 696b8ba064a6..9d2bbc41a7b0 100644 --- a/sys/gnu/dts/arm/at91sam9x5ek.dtsi +++ b/sys/gnu/dts/arm/at91sam9x5ek.dtsi @@ -116,7 +116,7 @@ }; spi0: spi@f0000000 { - status = "okay"; + status = "disabled"; /* conflicts with mmc1 */ cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; m25p80@0 { compatible = "atmel,at25df321a"; diff --git a/sys/gnu/dts/arm/axp209.dtsi b/sys/gnu/dts/arm/axp209.dtsi index 675bb0f30825..9677dd5cf6b6 100644 --- a/sys/gnu/dts/arm/axp209.dtsi +++ b/sys/gnu/dts/arm/axp209.dtsi @@ -53,6 +53,11 @@ interrupt-controller; #interrupt-cells = <1>; + ac_power_supply: ac-power-supply { + compatible = "x-powers,axp202-ac-power-supply"; + status = "disabled"; + }; + axp_gpio: gpio { compatible = "x-powers,axp209-gpio"; gpio-controller; diff --git a/sys/gnu/dts/arm/axp22x.dtsi b/sys/gnu/dts/arm/axp22x.dtsi index 458b6681e3ec..67331c5f1714 100644 --- a/sys/gnu/dts/arm/axp22x.dtsi +++ b/sys/gnu/dts/arm/axp22x.dtsi @@ -52,6 +52,11 @@ interrupt-controller; #interrupt-cells = <1>; + ac_power_supply: ac-power-supply { + compatible = "x-powers,axp221-ac-power-supply"; + status = "disabled"; + }; + regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <3000>; diff --git a/sys/gnu/dts/arm/bcm-cygnus.dtsi b/sys/gnu/dts/arm/bcm-cygnus.dtsi index 8833a4c3cd96..9644fddb5e3c 100644 --- a/sys/gnu/dts/arm/bcm-cygnus.dtsi +++ b/sys/gnu/dts/arm/bcm-cygnus.dtsi @@ -205,7 +205,7 @@ status = "disabled"; msi-parent = <&msi0>; - msi0: msi@18012000 { + msi0: msi-controller { compatible = "brcm,iproc-msi"; msi-controller; interrupt-parent = <&gic>; @@ -240,7 +240,7 @@ status = "disabled"; msi-parent = <&msi1>; - msi1: msi@18013000 { + msi1: msi-controller { compatible = "brcm,iproc-msi"; msi-controller; interrupt-parent = <&gic>; diff --git a/sys/gnu/dts/arm/bcm-nsp.dtsi b/sys/gnu/dts/arm/bcm-nsp.dtsi index 832795b0fd0f..fe6cba994a97 100644 --- a/sys/gnu/dts/arm/bcm-nsp.dtsi +++ b/sys/gnu/dts/arm/bcm-nsp.dtsi @@ -245,6 +245,15 @@ status = "disabled"; }; + mailbox: mailbox@25000 { + compatible = "brcm,iproc-fa2-mbox"; + reg = <0x25000 0x445>; + interrupts = ; + #mbox-cells = <1>; + brcm,rx-status-len = <32>; + brcm,use-bcm-hdr; + }; + nand: nand@26000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x026000 0x600>, @@ -288,6 +297,12 @@ #size-cells = <0>; }; + crypto@2f000 { + compatible = "brcm,spum-nsp-crypto"; + reg = <0x2f000 0x900>; + mboxes = <&mailbox 0>; + }; + gpiob: gpio@30000 { compatible = "brcm,iproc-nsp-gpio", "brcm,iproc-gpio"; reg = <0x30000 0x50>; @@ -306,6 +321,20 @@ status = "disabled"; }; + ehci0: usb@2a000 { + compatible = "generic-ehci"; + reg = <0x2a000 0x100>; + interrupts = ; + status = "disabled"; + }; + + ohci0: usb@2b000 { + compatible = "generic-ohci"; + reg = <0x2b000 0x100>; + interrupts = ; + status = "disabled"; + }; + rng: rng@33000 { compatible = "brcm,bcm-nsp-rng"; reg = <0x33000 0x14>; @@ -347,6 +376,7 @@ #size-cells = <0>; interrupts = ; clock-frequency = <100000>; + status = "disabled"; }; watchdog@39000 { @@ -450,7 +480,7 @@ status = "disabled"; msi-parent = <&msi0>; - msi0: msi@18012000 { + msi0: msi-controller { compatible = "brcm,iproc-msi"; msi-controller; interrupt-parent = <&gic>; @@ -486,7 +516,7 @@ status = "disabled"; msi-parent = <&msi1>; - msi1: msi@18013000 { + msi1: msi-controller { compatible = "brcm,iproc-msi"; msi-controller; interrupt-parent = <&gic>; @@ -522,7 +552,7 @@ status = "disabled"; msi-parent = <&msi2>; - msi2: msi@18014000 { + msi2: msi-controller { compatible = "brcm,iproc-msi"; msi-controller; interrupt-parent = <&gic>; diff --git a/sys/gnu/dts/arm/bcm2835-rpi.dtsi b/sys/gnu/dts/arm/bcm2835-rpi.dtsi index 38e6050035bc..a7b5ce133784 100644 --- a/sys/gnu/dts/arm/bcm2835-rpi.dtsi +++ b/sys/gnu/dts/arm/bcm2835-rpi.dtsi @@ -69,6 +69,12 @@ bus-width = <4>; }; +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; +}; + &pwm { pinctrl-names = "default"; pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio45>; @@ -92,3 +98,11 @@ power-domains = <&power RPI_POWER_DOMAIN_VEC>; status = "okay"; }; + +&dsi0 { + power-domains = <&power RPI_POWER_DOMAIN_DSI0>; +}; + +&dsi1 { + power-domains = <&power RPI_POWER_DOMAIN_DSI1>; +}; diff --git a/sys/gnu/dts/arm/bcm283x-rpi-smsc9512.dtsi b/sys/gnu/dts/arm/bcm283x-rpi-smsc9512.dtsi index 12c981e51134..9a0599f711ff 100644 --- a/sys/gnu/dts/arm/bcm283x-rpi-smsc9512.dtsi +++ b/sys/gnu/dts/arm/bcm283x-rpi-smsc9512.dtsi @@ -1,6 +1,6 @@ / { aliases { - ethernet = ðernet; + ethernet0 = ðernet; }; }; diff --git a/sys/gnu/dts/arm/bcm283x-rpi-smsc9514.dtsi b/sys/gnu/dts/arm/bcm283x-rpi-smsc9514.dtsi index 3f0a56ebcf1f..dc7ae776db5f 100644 --- a/sys/gnu/dts/arm/bcm283x-rpi-smsc9514.dtsi +++ b/sys/gnu/dts/arm/bcm283x-rpi-smsc9514.dtsi @@ -1,6 +1,6 @@ / { aliases { - ethernet = ðernet; + ethernet0 = ðernet; }; }; diff --git a/sys/gnu/dts/arm/bcm283x.dtsi b/sys/gnu/dts/arm/bcm283x.dtsi index a3106aa446c6..9444a9a9ba10 100644 --- a/sys/gnu/dts/arm/bcm283x.dtsi +++ b/sys/gnu/dts/arm/bcm283x.dtsi @@ -3,6 +3,11 @@ #include #include +/* firmware-provided startup stubs live here, where the secondary CPUs are + * spinning. + */ +/memreserve/ 0x00000000 0x00001000; + /* This include file covers the common peripherals and configuration between * bcm2835 and bcm2836 implementations, leaving the CPU configuration to * bcm2835.dtsi and bcm2836.dtsi. @@ -93,10 +98,13 @@ #clock-cells = <1>; reg = <0x7e101000 0x2000>; - /* CPRMAN derives everything from the platform's - * oscillator. + /* CPRMAN derives almost everything from the + * platform's oscillator. However, the DSI + * pixel clocks come from the DSI analog PHY. */ - clocks = <&clk_osc>; + clocks = <&clk_osc>, + <&dsi0 0>, <&dsi0 1>, <&dsi0 2>, + <&dsi1 0>, <&dsi1 1>, <&dsi1 2>; }; rng@7e104000 { @@ -195,8 +203,8 @@ brcm,pins = <0 1>; brcm,function = ; }; - i2c0_gpio32: i2c0_gpio32 { - brcm,pins = <32 34>; + i2c0_gpio28: i2c0_gpio28 { + brcm,pins = <28 29>; brcm,function = ; }; i2c0_gpio44: i2c0_gpio44 { @@ -292,20 +300,28 @@ /* Separate from the uart0_gpio14 group * because it conflicts with spi1_gpio16, and * people often run uart0 on the two pins - * without flow contrl. + * without flow control. */ uart0_ctsrts_gpio16: uart0_ctsrts_gpio16 { brcm,pins = <16 17>; brcm,function = ; }; - uart0_gpio30: uart0_gpio30 { + uart0_ctsrts_gpio30: uart0_ctsrts_gpio30 { brcm,pins = <30 31>; brcm,function = ; }; - uart0_ctsrts_gpio32: uart0_ctsrts_gpio32 { + uart0_gpio32: uart0_gpio32 { brcm,pins = <32 33>; brcm,function = ; }; + uart0_gpio36: uart0_gpio36 { + brcm,pins = <36 37>; + brcm,function = ; + }; + uart0_ctsrts_gpio38: uart0_ctsrts_gpio38 { + brcm,pins = <38 39>; + brcm,function = ; + }; uart1_gpio14: uart1_gpio14 { brcm,pins = <14 15>; @@ -323,10 +339,6 @@ brcm,pins = <30 31>; brcm,function = ; }; - uart1_gpio36: uart1_gpio36 { - brcm,pins = <36 37 38 39>; - brcm,function = ; - }; uart1_gpio40: uart1_gpio40 { brcm,pins = <40 41>; brcm,function = ; @@ -347,6 +359,16 @@ arm,primecell-periphid = <0x00241011>; }; + sdhost: mmc@7e202000 { + compatible = "brcm,bcm2835-sdhost"; + reg = <0x7e202000 0x100>; + interrupts = <2 24>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + dmas = <&dma 13>; + dma-names = "rx-tx"; + status = "disabled"; + }; + i2s: i2s@7e203000 { compatible = "brcm,bcm2835-i2s"; reg = <0x7e203000 0x20>, @@ -390,6 +412,25 @@ interrupts = <2 14>; /* pwa1 */ }; + dsi0: dsi@7e209000 { + compatible = "brcm,bcm2835-dsi0"; + reg = <0x7e209000 0x78>; + interrupts = <2 4>; + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <1>; + + clocks = <&clocks BCM2835_PLLA_DSI0>, + <&clocks BCM2835_CLOCK_DSI0E>, + <&clocks BCM2835_CLOCK_DSI0P>; + clock-names = "phy", "escape", "pixel"; + + clock-output-names = "dsi0_byte", + "dsi0_ddr2", + "dsi0_ddr"; + + }; + thermal: thermal@7e212000 { compatible = "brcm,bcm2835-thermal"; reg = <0x7e212000 0x8>; @@ -456,6 +497,26 @@ interrupts = <2 1>; }; + dsi1: dsi@7e700000 { + compatible = "brcm,bcm2835-dsi1"; + reg = <0x7e700000 0x8c>; + interrupts = <2 12>; + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <1>; + + clocks = <&clocks BCM2835_PLLD_DSI1>, + <&clocks BCM2835_CLOCK_DSI1E>, + <&clocks BCM2835_CLOCK_DSI1P>; + clock-names = "phy", "escape", "pixel"; + + clock-output-names = "dsi1_byte", + "dsi1_ddr2", + "dsi1_ddr"; + + status = "disabled"; + }; + i2c1: i2c@7e804000 { compatible = "brcm,bcm2835-i2c"; reg = <0x7e804000 0x1000>; @@ -499,6 +560,8 @@ clocks = <&clocks BCM2835_PLLH_PIX>, <&clocks BCM2835_CLOCK_HSM>; clock-names = "pixel", "hdmi"; + dmas = <&dma 17>; + dma-names = "audio-rx"; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/bcm4708-asus-rt-ac56u.dts b/sys/gnu/dts/arm/bcm4708-asus-rt-ac56u.dts index d241cee4bfcc..4175174e589a 100644 --- a/sys/gnu/dts/arm/bcm4708-asus-rt-ac56u.dts +++ b/sys/gnu/dts/arm/bcm4708-asus-rt-ac56u.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2015 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -31,19 +41,16 @@ usb3 { label = "bcm53xx:blue:usb3"; gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wan { label = "bcm53xx:blue:wan"; gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; lan { label = "bcm53xx:blue:lan"; gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; power { @@ -61,14 +68,12 @@ 2ghz { label = "bcm53xx:blue:2ghz"; gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb2 { label = "bcm53xx:blue:usb2"; gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4708-asus-rt-ac68u.dts b/sys/gnu/dts/arm/bcm4708-asus-rt-ac68u.dts index b0e62042f62f..8fa033fea959 100644 --- a/sys/gnu/dts/arm/bcm4708-asus-rt-ac68u.dts +++ b/sys/gnu/dts/arm/bcm4708-asus-rt-ac68u.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2015 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -31,7 +41,6 @@ usb2 { label = "bcm53xx:blue:usb2"; gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; power { @@ -49,7 +58,6 @@ usb3 { label = "bcm53xx:blue:usb3"; gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4708-buffalo-wzr-1750dhp.dts b/sys/gnu/dts/arm/bcm4708-buffalo-wzr-1750dhp.dts index c9ba6b964b38..62e1427b3f10 100644 --- a/sys/gnu/dts/arm/bcm4708-buffalo-wzr-1750dhp.dts +++ b/sys/gnu/dts/arm/bcm4708-buffalo-wzr-1750dhp.dts @@ -52,13 +52,11 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&hc595 0 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; power0 { label = "bcm53xx:red:power"; gpios = <&hc595 1 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; power1 { @@ -76,7 +74,6 @@ router1 { label = "bcm53xx:amber:router"; gpios = <&hc595 4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan { @@ -88,13 +85,11 @@ wireless0 { label = "bcm53xx:blue:wireless"; gpios = <&hc595 6 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wireless1 { label = "bcm53xx:amber:wireless"; gpios = <&hc595 7 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4708-linksys-ea6300-v1.dts b/sys/gnu/dts/arm/bcm4708-linksys-ea6300-v1.dts new file mode 100644 index 000000000000..126ab5867772 --- /dev/null +++ b/sys/gnu/dts/arm/bcm4708-linksys-ea6300-v1.dts @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 RafaÅ‚ MiÅ‚ecki + * + * Licensed under the ISC license. + */ + +/dts-v1/; + +#include "bcm4708.dtsi" +#include "bcm5301x-nand-cs0-bch8.dtsi" + +/ { + compatible = "linksys,ea6300-v1", "brcm,bcm4708"; + model = "Linksys EA6300 V1"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>; + }; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/bcm4708-netgear-r6250.dts b/sys/gnu/dts/arm/bcm4708-netgear-r6250.dts index b9f66c0fae27..a5647efe4118 100644 --- a/sys/gnu/dts/arm/bcm4708-netgear-r6250.dts +++ b/sys/gnu/dts/arm/bcm4708-netgear-r6250.dts @@ -43,19 +43,16 @@ power1 { label = "bcm53xx:amber:power"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wireless { label = "bcm53xx:blue:wireless"; gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4708-netgear-r6300-v2.dts b/sys/gnu/dts/arm/bcm4708-netgear-r6300-v2.dts index ae0199f6c7a2..bb66cebe0bd8 100644 --- a/sys/gnu/dts/arm/bcm4708-netgear-r6300-v2.dts +++ b/sys/gnu/dts/arm/bcm4708-netgear-r6300-v2.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2014 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -37,7 +47,6 @@ power0 { label = "bcm53xx:green:power"; gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; power1 { @@ -49,13 +58,11 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wireless { label = "bcm53xx:blue:wireless"; gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4708-smartrg-sr400ac.dts b/sys/gnu/dts/arm/bcm4708-smartrg-sr400ac.dts index 36b628b190d7..19ee924d7d53 100644 --- a/sys/gnu/dts/arm/bcm4708-smartrg-sr400ac.dts +++ b/sys/gnu/dts/arm/bcm4708-smartrg-sr400ac.dts @@ -37,61 +37,51 @@ power-amber { label = "bcm53xx:amber:power"; gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; usb2 { label = "bcm53xx:white:usb2"; gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; usb3-white { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; usb3-green { label = "bcm53xx:green:usb3"; gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wps { label = "bcm53xx:white:wps"; gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; status-red { label = "bcm53xx:red:status"; gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; status-green { label = "bcm53xx:green:status"; gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; status-blue { label = "bcm53xx:blue:status"; gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan-white { label = "bcm53xx:white:wan"; gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan-red { label = "bcm53xx:red:wan"; gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4708.dtsi b/sys/gnu/dts/arm/bcm4708.dtsi index d0eec099f1f8..1a19e97a987d 100644 --- a/sys/gnu/dts/arm/bcm4708.dtsi +++ b/sys/gnu/dts/arm/bcm4708.dtsi @@ -12,6 +12,14 @@ / { compatible = "brcm,bcm4708"; + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/bcm47081-asus-rt-n18u.dts b/sys/gnu/dts/arm/bcm47081-asus-rt-n18u.dts index db8608be0ee7..0800a964f2fe 100644 --- a/sys/gnu/dts/arm/bcm47081-asus-rt-n18u.dts +++ b/sys/gnu/dts/arm/bcm47081-asus-rt-n18u.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2014 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -37,7 +47,6 @@ usb2 { label = "bcm53xx:blue:usb2"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wan { @@ -55,7 +64,6 @@ usb3 { label = "bcm53xx:blue:usb3"; gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm47081-buffalo-wzr-600dhp2.dts b/sys/gnu/dts/arm/bcm47081-buffalo-wzr-600dhp2.dts index d51586d95b9a..c2af33eb47de 100644 --- a/sys/gnu/dts/arm/bcm47081-buffalo-wzr-600dhp2.dts +++ b/sys/gnu/dts/arm/bcm47081-buffalo-wzr-600dhp2.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2014 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -58,7 +68,6 @@ power1 { label = "bcm53xx:red:power"; gpios = <&hc595 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; router0 { @@ -70,7 +79,6 @@ router1 { label = "bcm53xx:amber:router"; gpios = <&hc595 4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan { @@ -82,13 +90,11 @@ wireless0 { label = "bcm53xx:green:wireless"; gpios = <&hc595 6 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wireless1 { label = "bcm53xx:amber:wireless"; gpios = <&hc595 7 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm47081-buffalo-wzr-900dhp.dts b/sys/gnu/dts/arm/bcm47081-buffalo-wzr-900dhp.dts index de041b8c3342..8bef6429feee 100644 --- a/sys/gnu/dts/arm/bcm47081-buffalo-wzr-900dhp.dts +++ b/sys/gnu/dts/arm/bcm47081-buffalo-wzr-900dhp.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2015 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; diff --git a/sys/gnu/dts/arm/bcm47081-tplink-archer-c5-v2.dts b/sys/gnu/dts/arm/bcm47081-tplink-archer-c5-v2.dts new file mode 100644 index 000000000000..a854a5174b7f --- /dev/null +++ b/sys/gnu/dts/arm/bcm47081-tplink-archer-c5-v2.dts @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 RafaÅ‚ MiÅ‚ecki + * + * Licensed under the ISC license. + */ + +/dts-v1/; + +#include "bcm47081.dtsi" + +/ { + compatible = "tplink,archer-c5-v2", "brcm,bcm47081", "brcm,bcm4708"; + model = "TP-LINK Archer C5 V2"; + + chosen { + bootargs = "earlycon"; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + leds { + compatible = "gpio-leds"; + + 2ghz { + label = "bcm53xx:green:2ghz"; + gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>; + }; + + lan { + label = "bcm53xx:green:lan"; + gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>; + }; + + usb2-port1 { + label = "bcm53xx:green:usb2-port1"; + gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>; + }; + + power { + label = "bcm53xx:green:power"; + gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + + wan-green { + label = "bcm53xx:green:wan"; + gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "bcm53xx:green:wps"; + gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>; + }; + + wan-amber { + label = "bcm53xx:amber:wan"; + gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>; + }; + + 5ghz { + label = "bcm53xx:green:5ghz"; + gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>; + }; + + usb2-port2 { + label = "bcm53xx:green:usb2-port2"; + gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + rfkill { + label = "WiFi"; + linux,code = ; + gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; + }; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&spi_nor { + status = "okay"; +}; + +&usb2 { + vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>; +}; diff --git a/sys/gnu/dts/arm/bcm47081.dtsi b/sys/gnu/dts/arm/bcm47081.dtsi index c5f7619af4a6..9829d044aaf4 100644 --- a/sys/gnu/dts/arm/bcm47081.dtsi +++ b/sys/gnu/dts/arm/bcm47081.dtsi @@ -4,7 +4,17 @@ * * Copyright © 2014 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include "bcm5301x.dtsi" @@ -12,6 +22,14 @@ / { compatible = "brcm,bcm47081"; + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/bcm4709-asus-rt-ac87u.dts b/sys/gnu/dts/arm/bcm4709-asus-rt-ac87u.dts index eaca6876db0f..df473cc41572 100644 --- a/sys/gnu/dts/arm/bcm4709-asus-rt-ac87u.dts +++ b/sys/gnu/dts/arm/bcm4709-asus-rt-ac87u.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2015 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -31,7 +41,6 @@ wps { label = "bcm53xx:blue:wps"; gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; power { @@ -43,7 +52,6 @@ wan { label = "bcm53xx:red:wan"; gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4709-buffalo-wxr-1900dhp.dts b/sys/gnu/dts/arm/bcm4709-buffalo-wxr-1900dhp.dts index b32957ca9443..92058c73ee59 100644 --- a/sys/gnu/dts/arm/bcm4709-buffalo-wxr-1900dhp.dts +++ b/sys/gnu/dts/arm/bcm4709-buffalo-wxr-1900dhp.dts @@ -31,13 +31,11 @@ usb { label = "bcm53xx:green:usb"; gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; power-amber { label = "bcm53xx:amber:power"; gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; power-white { @@ -49,37 +47,31 @@ router-amber { label = "bcm53xx:amber:router"; gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; router-white { label = "bcm53xx:white:router"; gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan-amber { label = "bcm53xx:amber:wan"; gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan-white { label = "bcm53xx:white:wan"; gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wireless-amber { label = "bcm53xx:amber:wireless"; gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wireless-white { label = "bcm53xx:white:wireless"; gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4709-linksys-ea9200.dts b/sys/gnu/dts/arm/bcm4709-linksys-ea9200.dts new file mode 100644 index 000000000000..3d1d9c2c4efc --- /dev/null +++ b/sys/gnu/dts/arm/bcm4709-linksys-ea9200.dts @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 RafaÅ‚ MiÅ‚ecki + * + * Licensed under the ISC license. + */ + +/dts-v1/; + +#include "bcm4709.dtsi" +#include "bcm5301x-nand-cs0-bch8.dtsi" + +/ { + compatible = "linksys,ea9200", "brcm,bcm4709", "brcm,bcm4708"; + model = "Linksys EA9200"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x00000000 0x08000000 + 0x88000000 0x08000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; + }; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/bcm4709-netgear-r7000.dts b/sys/gnu/dts/arm/bcm4709-netgear-r7000.dts index f459a98a72c6..f43ab4721456 100644 --- a/sys/gnu/dts/arm/bcm4709-netgear-r7000.dts +++ b/sys/gnu/dts/arm/bcm4709-netgear-r7000.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2015 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -37,43 +47,36 @@ power-amber { label = "bcm53xx:amber:power"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 5ghz { label = "bcm53xx:white:5ghz"; gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 2ghz { label = "bcm53xx:white:2ghz"; gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wps { label = "bcm53xx:white:wps"; gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wireless { label = "bcm53xx:white:wireless"; gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; usb3 { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb2 { label = "bcm53xx:white:usb2"; gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm4709-netgear-r8000.dts b/sys/gnu/dts/arm/bcm4709-netgear-r8000.dts index 8e39a84e5bf9..d266131652ad 100644 --- a/sys/gnu/dts/arm/bcm4709-netgear-r8000.dts +++ b/sys/gnu/dts/arm/bcm4709-netgear-r8000.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2015 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -28,58 +38,61 @@ leds { compatible = "gpio-leds"; - power0 { + power-white { label = "bcm53xx:white:power"; gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; linux,default-trigger = "default-on"; }; - power1 { + power-amber { label = "bcm53xx:amber:power"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; + }; + + wan-white { + label = "bcm53xx:white:wan"; + gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + + wan-amber { + label = "bcm53xx:amber:wan"; + gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>; }; 5ghz-1 { label = "bcm53xx:white:5ghz-1"; gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 2ghz { label = "bcm53xx:white:2ghz"; gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wireless { label = "bcm53xx:white:wireless"; gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wps { label = "bcm53xx:white:wps"; gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; 5ghz-2 { label = "bcm53xx:white:5ghz-2"; gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb3 { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb2 { label = "bcm53xx:white:usb2"; gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; @@ -105,6 +118,12 @@ linux,code = ; gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>; }; + + brightness { + label = "Backlight"; + linux,code = ; + gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>; + }; }; }; diff --git a/sys/gnu/dts/arm/bcm4709-tplink-archer-c9-v1.dts b/sys/gnu/dts/arm/bcm4709-tplink-archer-c9-v1.dts index c67bfaa0c8e8..97aa5d59a1d8 100644 --- a/sys/gnu/dts/arm/bcm4709-tplink-archer-c9-v1.dts +++ b/sys/gnu/dts/arm/bcm4709-tplink-archer-c9-v1.dts @@ -26,49 +26,41 @@ lan { label = "bcm53xx:blue:lan"; gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wps { label = "bcm53xx:blue:wps"; gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; 2ghz { label = "bcm53xx:blue:2ghz"; gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; 5ghz { label = "bcm53xx:blue:5ghz"; gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; usb3 { label = "bcm53xx:blue:usb3"; gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; usb2 { label = "bcm53xx:blue:usb2"; gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan-blue { label = "bcm53xx:blue:wan"; gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wan-amber { label = "bcm53xx:amber:wan"; gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; power { diff --git a/sys/gnu/dts/arm/bcm47094-dlink-dir-885l.dts b/sys/gnu/dts/arm/bcm47094-dlink-dir-885l.dts index 64ded7643e9f..51b0641b5f79 100644 --- a/sys/gnu/dts/arm/bcm47094-dlink-dir-885l.dts +++ b/sys/gnu/dts/arm/bcm47094-dlink-dir-885l.dts @@ -4,7 +4,17 @@ * * Copyright (C) 2016 RafaÅ‚ MiÅ‚ecki * - * Licensed under the GNU/GPL. See COPYING for details. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /dts-v1/; @@ -46,37 +56,31 @@ wan-white { label = "bcm53xx:white:wan"; gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; power-amber { label = "bcm53xx:amber:power"; gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wan-amber { label = "bcm53xx:amber:wan"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb3-white { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 2ghz { label = "bcm53xx:white:2ghz"; gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 5ghz { label = "bcm53xx:white:5ghz"; gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm47094-linksys-panamera.dts b/sys/gnu/dts/arm/bcm47094-linksys-panamera.dts new file mode 100644 index 000000000000..b6750f70dffb --- /dev/null +++ b/sys/gnu/dts/arm/bcm47094-linksys-panamera.dts @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 RafaÅ‚ MiÅ‚ecki + * + * Licensed under the ISC license. + */ + +/dts-v1/; + +#include "bcm47094.dtsi" +#include "bcm5301x-nand-cs0-bch8.dtsi" + +/ { + compatible = "linksys,panamera", "brcm,bcm47094", "brcm,bcm4708"; + model = "Linksys EA9500"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x00000000 0x08000000 + 0x88000000 0x08000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/bcm47094-luxul-xwr-3100.dts b/sys/gnu/dts/arm/bcm47094-luxul-xwr-3100.dts index 5cf4ab1ebe85..5f8621d00c50 100644 --- a/sys/gnu/dts/arm/bcm47094-luxul-xwr-3100.dts +++ b/sys/gnu/dts/arm/bcm47094-luxul-xwr-3100.dts @@ -34,37 +34,31 @@ lan3 { label = "bcm53xx:green:lan3"; gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; lan4 { label = "bcm53xx:green:lan4"; gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; wan { label = "bcm53xx:green:wan"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; lan1 { label = "bcm53xx:green:lan1"; gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; lan2 { label = "bcm53xx:green:lan2"; gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb3 { label = "bcm53xx:green:usb3"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; status { @@ -76,13 +70,11 @@ 2ghz { label = "bcm53xx:green:2ghz"; gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 5ghz { label = "bcm53xx:green:5ghz"; gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm47094-netgear-r8500.dts b/sys/gnu/dts/arm/bcm47094-netgear-r8500.dts index 600795ee1aed..859929973158 100644 --- a/sys/gnu/dts/arm/bcm47094-netgear-r8500.dts +++ b/sys/gnu/dts/arm/bcm47094-netgear-r8500.dts @@ -34,37 +34,31 @@ power1 { label = "bcm53xx:amber:power"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 5ghz-1 { label = "bcm53xx:white:5ghz-1"; gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 5ghz-2 { label = "bcm53xx:white:5ghz-2"; gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; 2ghz { label = "bcm53xx:white:2ghz"; gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb2 { label = "bcm53xx:white:usb2"; gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; usb3 { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; }; diff --git a/sys/gnu/dts/arm/bcm47189-tenda-ac9.dts b/sys/gnu/dts/arm/bcm47189-tenda-ac9.dts index 4403ae8790c2..34417dac1cd0 100644 --- a/sys/gnu/dts/arm/bcm47189-tenda-ac9.dts +++ b/sys/gnu/dts/arm/bcm47189-tenda-ac9.dts @@ -26,19 +26,16 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; wps { label = "bcm53xx:blue:wps"; gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; 5ghz { label = "bcm53xx:blue:5ghz"; gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; system { @@ -48,6 +45,15 @@ }; }; + pcie0_leds { + compatible = "gpio-leds"; + + 2ghz { + label = "bcm53xx:blue:2ghz"; + gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>; + }; + }; + gpio-keys { compatible = "gpio-keys"; #address-cells = <1>; @@ -72,3 +78,30 @@ }; }; }; + +&pcie0 { + ranges = <0x00000000 0 0 0 0 0x00100000>; + #address-cells = <3>; + #size-cells = <2>; + + bridge@0,0,0 { + reg = <0x0000 0 0 0 0>; + ranges = <0x00000000 0 0 0 0 0 0 0x00100000>; + #address-cells = <3>; + #size-cells = <2>; + + wifi@0,1,0 { + reg = <0x0000 0 0 0 0>; + ranges = <0x00000000 0 0 0 0x00100000>; + #address-cells = <1>; + #size-cells = <1>; + + pcie0_chipcommon: chipcommon@0 { + reg = <0 0x1000>; + + gpio-controller; + #gpio-cells = <2>; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/bcm5301x.dtsi b/sys/gnu/dts/arm/bcm5301x.dtsi index 00de62dc0042..acee36a61004 100644 --- a/sys/gnu/dts/arm/bcm5301x.dtsi +++ b/sys/gnu/dts/arm/bcm5301x.dtsi @@ -18,10 +18,6 @@ / { interrupt-parent = <&gic>; - chosen { - stdout-path = &uart0; - }; - chipcommonA { compatible = "simple-bus"; ranges = <0x00000000 0x18000000 0x00001000>; @@ -70,10 +66,19 @@ clocks = <&periph_clk>; }; - local-timer@20600 { + timer@20600 { compatible = "arm,cortex-a9-twd-timer"; - reg = <0x20600 0x100>; - interrupts = ; + reg = <0x20600 0x20>; + interrupts = ; + clocks = <&periph_clk>; + }; + + watchdog@20620 { + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0x20620 0x20>; + interrupts = ; clocks = <&periph_clk>; }; @@ -298,20 +303,6 @@ }; }; - spi@29000 { - reg = <0x00029000 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - spi_nor: spi-nor@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <20000000>; - linux,part-probe = "ofpart", "bcm47xxpart"; - status = "disabled"; - }; - }; - gmac0: ethernet@24000 { reg = <0x24000 0x800>; }; @@ -329,6 +320,16 @@ }; }; + i2c0: i2c@18009000 { + compatible = "brcm,iproc-i2c"; + reg = <0x18009000 0x50>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + status = "disabled"; + }; + lcpll0: lcpll0@1800c100 { #clock-cells = <1>; compatible = "brcm,nsp-lcpll0"; @@ -375,4 +376,40 @@ brcm,nand-has-wp; }; + + spi@18029200 { + compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; + reg = <0x18029200 0x184>, + <0x18029000 0x124>, + <0x1811b408 0x004>, + <0x180293a0 0x01c>; + reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "spi_lr_fullness_reached", + "spi_lr_session_aborted", + "spi_lr_impatient", + "spi_lr_session_done", + "spi_lr_overhead", + "mspi_done", + "mspi_halted"; + clocks = <&iprocmed>; + clock-names = "iprocmed"; + num-cs = <2>; + #address-cells = <1>; + #size-cells = <0>; + + spi_nor: spi-nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <20000000>; + linux,part-probe = "ofpart", "bcm47xxpart"; + status = "disabled"; + }; + }; }; diff --git a/sys/gnu/dts/arm/bcm53573.dtsi b/sys/gnu/dts/arm/bcm53573.dtsi index 2da04d0a7348..eae623f76401 100644 --- a/sys/gnu/dts/arm/bcm53573.dtsi +++ b/sys/gnu/dts/arm/bcm53573.dtsi @@ -13,8 +13,12 @@ / { interrupt-parent = <&gic>; + aliases { + serial0 = &uart0; + }; + chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; cpus { @@ -113,6 +117,10 @@ }; }; + pcie0: pcie@2000 { + reg = <0x00002000 0x1000>; + }; + usb2: usb2@4000 { reg = <0x4000 0x1000>; ranges; diff --git a/sys/gnu/dts/arm/bcm94708.dts b/sys/gnu/dts/arm/bcm94708.dts index 42855a7c1bfa..2e08c895f281 100644 --- a/sys/gnu/dts/arm/bcm94708.dts +++ b/sys/gnu/dts/arm/bcm94708.dts @@ -38,14 +38,6 @@ model = "NorthStar SVK (BCM94708)"; compatible = "brcm,bcm94708", "brcm,bcm4708"; - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - memory { reg = <0x00000000 0x08000000>; }; diff --git a/sys/gnu/dts/arm/bcm94709.dts b/sys/gnu/dts/arm/bcm94709.dts index 95e8be65f2f1..c37616c67edc 100644 --- a/sys/gnu/dts/arm/bcm94709.dts +++ b/sys/gnu/dts/arm/bcm94709.dts @@ -38,14 +38,6 @@ model = "NorthStar SVK (BCM94709)"; compatible = "brcm,bcm94709", "brcm,bcm4709", "brcm,bcm4708"; - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - memory { reg = <0x00000000 0x08000000>; }; diff --git a/sys/gnu/dts/arm/bcm953012er.dts b/sys/gnu/dts/arm/bcm953012er.dts index decd86bae901..40e694bfe5ca 100644 --- a/sys/gnu/dts/arm/bcm953012er.dts +++ b/sys/gnu/dts/arm/bcm953012er.dts @@ -39,14 +39,6 @@ model = "NorthStar Enterprise Router (BCM953012ER)"; compatible = "brcm,bcm953012er", "brcm,brcm53012", "brcm,bcm4708"; - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - memory { reg = <0x00000000 0x8000000>; }; diff --git a/sys/gnu/dts/arm/bcm953012hr.dts b/sys/gnu/dts/arm/bcm953012hr.dts new file mode 100644 index 000000000000..3076e81699cf --- /dev/null +++ b/sys/gnu/dts/arm/bcm953012hr.dts @@ -0,0 +1,97 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Broadcom + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/dts-v1/; + +#include "bcm4708.dtsi" +#include "bcm5301x-nand-cs0-bch4.dtsi" + +/ { + model = "NorthStar HR (BCM953012HR)"; + compatible = "brcm,bcm953012hr", "brcm,brcm53012", "brcm,bcm4708"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + ethernet2 = &gmac2; + }; + + memory@80000000 { + reg = <0x80000000 0x10000000>; + }; +}; + +&nandcs { + partition@0 { + label = "nboot"; + reg = <0x00000000 0x00200000>; + read-only; + }; + partition@200000 { + label = "nenv"; + reg = <0x00200000 0x00400000>; + }; + partition@600000 { + label = "nsystem"; + reg = <0x00600000 0x00a00000>; + }; + partition@1000000 { + label = "nrootfs"; + reg = <0x01000000 0x07000000>; + }; +}; + +&spi_nor { + status = "okay"; + spi-max-frequency = <62500000>; + m25p,default-addr-width = <3>; + + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot"; + reg = <0x00000000 0x000d0000>; + }; + partition@d000 { + label = "env"; + reg = <0x000d0000 0x00030000>; + }; + partition@100000 { + label = "system"; + reg = <0x00100000 0x00600000>; + }; + partition@700000 { + label = "rootfs"; + reg = <0x00700000 0x00900000>; + }; +}; diff --git a/sys/gnu/dts/arm/bcm953012k.dts b/sys/gnu/dts/arm/bcm953012k.dts index ae31a5826e91..79c168e2714b 100644 --- a/sys/gnu/dts/arm/bcm953012k.dts +++ b/sys/gnu/dts/arm/bcm953012k.dts @@ -43,15 +43,69 @@ serial1 = &uart1; }; - chosen { - stdout-path = "serial0:115200n8"; - }; - memory { reg = <0x80000000 0x10000000>; }; }; +&nand { + nandcs@0 { + compatible = "brcm,nandcs"; + reg = <0>; + nand-on-flash-bbt; + + #address-cells = <1>; + #size-cells = <1>; + + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + + partition@0 { + label = "nboot"; + reg = <0x00000000 0x00200000>; + read-only; + }; + partition@200000 { + label = "nenv"; + reg = <0x00200000 0x00400000>; + }; + partition@600000 { + label = "nsystem"; + reg = <0x00600000 0x00a00000>; + }; + partition@1000000 { + label = "nrootfs"; + reg = <0x01000000 0x07000000>; + }; + }; +}; + +&spi_nor { + status = "okay"; + spi-max-frequency = <62500000>; + m25p,default-addr-width = <3>; + + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot"; + reg = <0x00000000 0x000d0000>; + }; + partition@d000 { + label = "env"; + reg = <0x000d0000 0x00030000>; + }; + partition@100000 { + label = "system"; + reg = <0x00100000 0x00600000>; + }; + partition@700000 { + label = "rootfs"; + reg = <0x00700000 0x00900000>; + }; +}; + &uart0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm958522er.dts b/sys/gnu/dts/arm/bcm958522er.dts index df05e7f568af..f5c42962c201 100644 --- a/sys/gnu/dts/arm/bcm958522er.dts +++ b/sys/gnu/dts/arm/bcm958522er.dts @@ -60,7 +60,7 @@ }; }; -/* USB 2/3 support needed to be complete */ +/* USB 3 support needed to be complete */ &amac0 { status = "okay"; @@ -70,6 +70,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; @@ -108,6 +112,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm958525er.dts b/sys/gnu/dts/arm/bcm958525er.dts index 4a3ab19c6281..efcb1f67bdad 100644 --- a/sys/gnu/dts/arm/bcm958525er.dts +++ b/sys/gnu/dts/arm/bcm958525er.dts @@ -60,7 +60,7 @@ }; }; -/* USB 2/3 support needed to be complete */ +/* USB 3 support needed to be complete */ &amac0 { status = "okay"; @@ -70,6 +70,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; @@ -108,6 +112,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm958525xmc.dts b/sys/gnu/dts/arm/bcm958525xmc.dts index 81f78435d8c7..b335ce02e32f 100644 --- a/sys/gnu/dts/arm/bcm958525xmc.dts +++ b/sys/gnu/dts/arm/bcm958525xmc.dts @@ -66,7 +66,13 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &i2c0 { + status = "okay"; + temperature-sensor@4c { compatible = "adi,adt7461a"; reg = <0x4c>; @@ -122,6 +128,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm958622hr.dts b/sys/gnu/dts/arm/bcm958622hr.dts index c88b8fefcb2f..16ab2d82a14b 100644 --- a/sys/gnu/dts/arm/bcm958622hr.dts +++ b/sys/gnu/dts/arm/bcm958622hr.dts @@ -60,7 +60,7 @@ }; }; -/* USB 2/3 and SLIC support needed to be complete */ +/* USB 3 and SLIC support needed to be complete */ &amac0 { status = "okay"; @@ -74,6 +74,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; @@ -112,6 +116,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm958623hr.dts b/sys/gnu/dts/arm/bcm958623hr.dts index d503fa0dde31..9b921c6aa8f8 100644 --- a/sys/gnu/dts/arm/bcm958623hr.dts +++ b/sys/gnu/dts/arm/bcm958623hr.dts @@ -60,7 +60,7 @@ }; }; -/* USB 2/3 and SLIC support needed to be complete */ +/* USB 3 and SLIC support needed to be complete */ &amac0 { status = "okay"; @@ -74,6 +74,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; @@ -112,6 +116,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm958625hr.dts b/sys/gnu/dts/arm/bcm958625hr.dts index cc0363b843c1..006b08e41a3b 100644 --- a/sys/gnu/dts/arm/bcm958625hr.dts +++ b/sys/gnu/dts/arm/bcm958625hr.dts @@ -72,6 +72,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; @@ -110,6 +114,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm958625k.dts b/sys/gnu/dts/arm/bcm958625k.dts index f8d47e517e18..64740f85cf4c 100644 --- a/sys/gnu/dts/arm/bcm958625k.dts +++ b/sys/gnu/dts/arm/bcm958625k.dts @@ -65,6 +65,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; @@ -103,6 +107,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/bcm988312hr.dts b/sys/gnu/dts/arm/bcm988312hr.dts index 74e15a3cd9f8..bce251a68591 100644 --- a/sys/gnu/dts/arm/bcm988312hr.dts +++ b/sys/gnu/dts/arm/bcm988312hr.dts @@ -60,7 +60,7 @@ }; }; -/* USB 2/3 support needed to be complete */ +/* USB 3 support needed to be complete */ &amac0 { status = "okay"; @@ -74,6 +74,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; @@ -112,6 +116,10 @@ }; }; +&ohci0 { + status = "okay"; +}; + &pcie0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/da850-evm.dts b/sys/gnu/dts/arm/da850-evm.dts index d15107cba765..8d244cd76c36 100644 --- a/sys/gnu/dts/arm/da850-evm.dts +++ b/sys/gnu/dts/arm/da850-evm.dts @@ -9,6 +9,7 @@ */ /dts-v1/; #include "da850.dtsi" +#include / { compatible = "ti,da850-evm", "ti,da850"; @@ -78,7 +79,10 @@ DRVDD-supply = <&vbat>; DVDD-supply = <&vbat>; }; - + tca6416: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + }; }; wdt: wdt@21000 { status = "okay"; @@ -293,20 +297,27 @@ &vpif { pinctrl-names = "default"; - pinctrl-0 = <&vpif_capture_pins>; + pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>; status = "okay"; /* VPIF capture port */ - port { - vpif_ch0: endpoint@0 { - reg = <0>; - bus-width = <8>; + port@0 { + vpif_input_ch0: endpoint@0 { + reg = <0>; + bus-width = <8>; }; - vpif_ch1: endpoint@1 { - reg = <1>; - bus-width = <8>; - data-shift = <8>; + vpif_input_ch1: endpoint@1 { + reg = <1>; + bus-width = <8>; + data-shift = <8>; + }; + }; + + /* VPIF display port */ + port@1 { + vpif_output_ch0: endpoint { + bus-width = <8>; }; }; }; diff --git a/sys/gnu/dts/arm/da850-lego-ev3.dts b/sys/gnu/dts/arm/da850-lego-ev3.dts index 112ec92064ce..512604ad8b71 100644 --- a/sys/gnu/dts/arm/da850-lego-ev3.dts +++ b/sys/gnu/dts/arm/da850-lego-ev3.dts @@ -123,6 +123,14 @@ pinctrl-0 = <&system_power_pin>; }; + sound { + compatible = "pwm-beeper"; + pinctrl-names = "default"; + pinctrl-0 = <&ehrpwm0b_pins>; + pwms = <&ehrpwm0 1 1000000 0>; + amp-supply = <&>; + }; + /* * This is a 5V current limiting regulator that is shared by USB, * the sensor (input) ports, the motor (output) ports and the A/DC. @@ -139,18 +147,36 @@ enable-active-high; regulator-boot-on; }; + + /* + * This is a simple voltage divider on VCC5V to provide a 2.5V + * reference signal to the ADC. + */ + adc_ref: regulator2 { + compatible = "regulator-fixed"; + regulator-name = "adc ref"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-boot-on; + vin-supply = <&vcc5v>; + }; + + /* + * This is the amplifier for the speaker. + */ + amp: regulator3 { + pinctrl-names = "default"; + pinctrl-0 = <&_pins>; + compatible = "regulator-fixed"; + regulator-name = "amp"; + gpio = <&gpio 111 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; &pmx_core { status = "okay"; - spi0_cs3_pin: pinmux_spi0_cs3_pin { - pinctrl-single,bits = < - /* CS3 */ - 0xc 0x01000000 0x0f000000 - >; - }; - mmc0_cd_pin: pinmux_mmc0_cd { pinctrl-single,bits = < /* GP5[14] */ @@ -195,6 +221,13 @@ 0x4c 0x00008000 0x0000f000 >; }; + + amp_pins: pinmux_amp_pins { + pinctrl-single,bits = < + /* GP6[15] */ + 0x34 0x00000008 0x0000000f + >; + }; }; &pinconf { @@ -293,6 +326,18 @@ }; }; }; + + adc: adc@3 { + compatible = "ti,ads7957"; + reg = <3>; + #io-channel-cells = <1>; + spi-max-frequency = <10000000>; + vref-supply = <&adc_ref>; + }; +}; + +&ehrpwm0 { + status = "okay"; }; &gpio { diff --git a/sys/gnu/dts/arm/da850.dtsi b/sys/gnu/dts/arm/da850.dtsi index 92d633d1da68..941d455000a7 100644 --- a/sys/gnu/dts/arm/da850.dtsi +++ b/sys/gnu/dts/arm/da850.dtsi @@ -153,6 +153,12 @@ 0x10 0x00000010 0x000000f0 >; }; + spi0_cs3_pin: pinmux_spi0_cs3_pin { + pinctrl-single,bits = < + /* CS3 */ + 0xc 0x01000000 0x0f000000 + >; + }; spi1_pins: pinmux_spi1_pins { pinctrl-single,bits = < /* SIMO, SOMI, CLK */ @@ -216,8 +222,21 @@ 0x3c 0x11111111 0xffffffff /* VP_DIN[8..9] */ 0x40 0x00000011 0x000000ff - /* VP_CLKIN3, VP_CLKIN2 */ - 0x4c 0x00010100 0x000f0f00 + >; + }; + vpif_display_pins: vpif_display_pins { + pinctrl-single,bits = < + /* VP_DOUT[2..7] */ + 0x40 0x11111100 0xffffff00 + /* VP_DOUT[10..15,0..1] */ + 0x44 0x11111111 0xffffffff + /* VP_DOUT[8..9] */ + 0x48 0x00000011 0x000000ff + /* + * VP_CLKOUT3, VP_CLKIN3, + * VP_CLKOUT2, VP_CLKIN2 + */ + 0x4c 0x00111100 0x00ffff00 >; }; }; @@ -345,7 +364,13 @@ status = "disabled"; /* VPIF capture port */ - port { + port@0 { + #address-cells = <1>; + #size-cells = <0>; + }; + + /* VPIF display port */ + port@1 { #address-cells = <1>; #size-cells = <0>; }; diff --git a/sys/gnu/dts/arm/dm8168-evm.dts b/sys/gnu/dts/arm/dm8168-evm.dts index 0bf55fa72dea..1865976db5f9 100644 --- a/sys/gnu/dts/arm/dm8168-evm.dts +++ b/sys/gnu/dts/arm/dm8168-evm.dts @@ -25,6 +25,12 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; + + sata_refclk: fixedclock0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; }; &dm816x_pinmux { @@ -173,3 +179,7 @@ pinctrl-0 = <&usb1_pins>; mentor,multipoint = <0>; }; + +&sata { + clocks = <&sysclk5_ck>, <&sata_refclk>; +}; diff --git a/sys/gnu/dts/arm/dm816x.dtsi b/sys/gnu/dts/arm/dm816x.dtsi index 276211e1ee53..59cbf958fcc3 100644 --- a/sys/gnu/dts/arm/dm816x.dtsi +++ b/sys/gnu/dts/arm/dm816x.dtsi @@ -293,6 +293,13 @@ phy-handle = <&phy1>; }; + sata: sata@4a140000 { + compatible = "ti,dm816-ahci"; + reg = <0x4a140000 0x10000>; + interrupts = <16>; + ti,hwmods = "sata"; + }; + mcspi1: spi@48030000 { compatible = "ti,omap4-mcspi"; reg = <0x48030000 0x1000>; diff --git a/sys/gnu/dts/arm/dra7-evm.dts b/sys/gnu/dts/arm/dra7-evm.dts index 4bc4b575c99b..31a9e061ddd0 100644 --- a/sys/gnu/dts/arm/dra7-evm.dts +++ b/sys/gnu/dts/arm/dra7-evm.dts @@ -204,6 +204,8 @@ tps659038: tps659038@58 { compatible = "ti,tps659038"; reg = <0x58>; + ti,palmas-override-powerhold; + ti,system-power-controller; tps659038_pmic { compatible = "ti,tps659038-pmic"; diff --git a/sys/gnu/dts/arm/dra7.dtsi b/sys/gnu/dts/arm/dra7.dtsi index bbfb9d5a70a9..e7144662af45 100644 --- a/sys/gnu/dts/arm/dra7.dtsi +++ b/sys/gnu/dts/arm/dra7.dtsi @@ -81,11 +81,7 @@ compatible = "arm,cortex-a15"; reg = <0>; - operating-points = < - /* kHz uV */ - 1000000 1060000 - 1176000 1160000 - >; + operating-points-v2 = <&cpu0_opp_table>; clocks = <&dpll_mpu_ck>; clock-names = "cpu"; @@ -99,6 +95,24 @@ }; }; + cpu0_opp_table: opp-table { + compatible = "operating-points-v2-ti-cpu"; + syscon = <&scm_wkup>; + + opp_nom@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <1060000 850000 1150000>; + opp-supported-hw = <0xFF 0x01>; + opp-suspend; + }; + + opp_od@1176000000 { + opp-hz = /bits/ 64 <1176000000>; + opp-microvolt = <1160000 885000 1160000>; + opp-supported-hw = <0xFF 0x02>; + }; + }; + /* * The soc node represents the soc top level view. It is used for IPs * that are not memory mapped in the MPU view or for the MPU itself. @@ -1984,6 +1998,27 @@ &cpu_thermal { polling-delay = <500>; /* milliseconds */ + coefficients = <0 2000>; +}; + +&gpu_thermal { + coefficients = <0 2000>; +}; + +&core_thermal { + coefficients = <0 2000>; +}; + +&dspeve_thermal { + coefficients = <0 2000>; +}; + +&iva_thermal { + coefficients = <0 2000>; +}; + +&cpu_crit { + temperature = <120000>; /* milli Celsius */ }; /include/ "dra7xx-clocks.dtsi" diff --git a/sys/gnu/dts/arm/dra74x.dtsi b/sys/gnu/dts/arm/dra74x.dtsi index 0a78347e6615..24e6746c5b26 100644 --- a/sys/gnu/dts/arm/dra74x.dtsi +++ b/sys/gnu/dts/arm/dra74x.dtsi @@ -17,6 +17,7 @@ device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <1>; + operating-points-v2 = <&cpu0_opp_table>; }; }; @@ -79,6 +80,10 @@ }; }; +&cpu0_opp_table { + opp-shared; +}; + &dss { reg = <0x58000000 0x80>, <0x58004054 0x4>, diff --git a/sys/gnu/dts/arm/exynos3250-rinato.dts b/sys/gnu/dts/arm/exynos3250-rinato.dts index 548413e23c47..c9f191ca7b9c 100644 --- a/sys/gnu/dts/arm/exynos3250-rinato.dts +++ b/sys/gnu/dts/arm/exynos3250-rinato.dts @@ -215,6 +215,8 @@ &dsi_0 { vddcore-supply = <&ldo6_reg>; vddio-supply = <&ldo6_reg>; + samsung,burst-clock-frequency = <250000000>; + samsung,esc-clock-frequency = <20000000>; samsung,pll-clock-frequency = <24000000>; status = "okay"; diff --git a/sys/gnu/dts/arm/exynos3250.dtsi b/sys/gnu/dts/arm/exynos3250.dtsi index 9c28ef4508e0..590ee442d0ae 100644 --- a/sys/gnu/dts/arm/exynos3250.dtsi +++ b/sys/gnu/dts/arm/exynos3250.dtsi @@ -745,23 +745,23 @@ compatible = "operating-points-v2"; opp-shared; - opp@50000000 { + opp-50000000 { opp-hz = /bits/ 64 <50000000>; opp-microvolt = <800000>; }; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; opp-microvolt = <800000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; opp-microvolt = <800000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <825000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <875000>; }; @@ -835,23 +835,23 @@ compatible = "operating-points-v2"; opp-shared; - opp@50000000 { + opp-50000000 { opp-hz = /bits/ 64 <50000000>; opp-microvolt = <900000>; }; - opp@80000000 { + opp-80000000 { opp-hz = /bits/ 64 <80000000>; opp-microvolt = <900000>; }; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; opp-microvolt = <1000000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; opp-microvolt = <1000000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <1000000>; }; @@ -861,19 +861,19 @@ compatible = "operating-points-v2"; opp-shared; - opp@50000000 { + opp-50000000 { opp-hz = /bits/ 64 <50000000>; }; - opp@80000000 { + opp-80000000 { opp-hz = /bits/ 64 <80000000>; }; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; }; }; @@ -882,19 +882,19 @@ compatible = "operating-points-v2"; opp-shared; - opp@50000000 { + opp-50000000 { opp-hz = /bits/ 64 <50000000>; }; - opp@80000000 { + opp-80000000 { opp-hz = /bits/ 64 <80000000>; }; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; }; - opp@300000000 { + opp-300000000 { opp-hz = /bits/ 64 <300000000>; }; }; @@ -903,13 +903,13 @@ compatible = "operating-points-v2"; opp-shared; - opp@50000000 { + opp-50000000 { opp-hz = /bits/ 64 <50000000>; }; - opp@80000000 { + opp-80000000 { opp-hz = /bits/ 64 <80000000>; }; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; }; diff --git a/sys/gnu/dts/arm/exynos4.dtsi b/sys/gnu/dts/arm/exynos4.dtsi index 18def1c774d5..497a9470c888 100644 --- a/sys/gnu/dts/arm/exynos4.dtsi +++ b/sys/gnu/dts/arm/exynos4.dtsi @@ -283,15 +283,6 @@ }; }; - watchdog: watchdog@10060000 { - compatible = "samsung,s3c2410-wdt"; - reg = <0x10060000 0x100>; - interrupts = ; - clocks = <&clock CLK_WDT>; - clock-names = "watchdog"; - status = "disabled"; - }; - rtc: rtc@10070000 { compatible = "samsung,s3c6410-rtc"; reg = <0x10070000 0x100>; @@ -771,6 +762,7 @@ clocks = <&clock CLK_HDMI_CEC>; clock-names = "hdmicec"; samsung,syscon-phandle = <&pmu_system_controller>; + hdmi-phandle = <&hdmi>; pinctrl-names = "default"; pinctrl-0 = <&hdmi_cec>; status = "disabled"; diff --git a/sys/gnu/dts/arm/exynos4210-origen.dts b/sys/gnu/dts/arm/exynos4210-origen.dts index a2c6a13fe67b..312650e2450f 100644 --- a/sys/gnu/dts/arm/exynos4210-origen.dts +++ b/sys/gnu/dts/arm/exynos4210-origen.dts @@ -328,7 +328,3 @@ &tmu { status = "okay"; }; - -&watchdog { - status = "okay"; -}; diff --git a/sys/gnu/dts/arm/exynos4210-trats.dts b/sys/gnu/dts/arm/exynos4210-trats.dts index 0ca1b4d355f2..1743ca850070 100644 --- a/sys/gnu/dts/arm/exynos4210-trats.dts +++ b/sys/gnu/dts/arm/exynos4210-trats.dts @@ -197,6 +197,8 @@ &dsi_0 { vddcore-supply = <&vusb_reg>; vddio-supply = <&vmipi_reg>; + samsung,burst-clock-frequency = <500000000>; + samsung,esc-clock-frequency = <20000000>; samsung,pll-clock-frequency = <24000000>; status = "okay"; diff --git a/sys/gnu/dts/arm/exynos4210.dtsi b/sys/gnu/dts/arm/exynos4210.dtsi index f9408188f97f..768fb075b1fd 100644 --- a/sys/gnu/dts/arm/exynos4210.dtsi +++ b/sys/gnu/dts/arm/exynos4210.dtsi @@ -119,6 +119,14 @@ }; }; + watchdog: watchdog@10060000 { + compatible = "samsung,s3c6410-wdt"; + reg = <0x10060000 0x100>; + interrupts = ; + clocks = <&clock CLK_WDT>; + clock-names = "watchdog"; + }; + clock: clock-controller@10030000 { compatible = "samsung,exynos4210-clock"; reg = <0x10030000 0x20000>; @@ -335,15 +343,15 @@ compatible = "operating-points-v2"; opp-shared; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; opp-microvolt = <1025000>; }; - opp@267000000 { + opp-267000000 { opp-hz = /bits/ 64 <267000000>; opp-microvolt = <1050000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1150000>; }; @@ -353,13 +361,13 @@ compatible = "operating-points-v2"; opp-shared; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; }; - opp@160000000 { + opp-160000000 { opp-hz = /bits/ 64 <160000000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; }; }; @@ -368,10 +376,10 @@ compatible = "operating-points-v2"; opp-shared; - opp@5000000 { + opp-5000000 { opp-hz = /bits/ 64 <5000000>; }; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; }; @@ -380,10 +388,10 @@ compatible = "operating-points-v2"; opp-shared; - opp@10000000 { + opp-10000000 { opp-hz = /bits/ 64 <10000000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; }; }; @@ -392,13 +400,13 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; }; - opp@160000000 { + opp-160000000 { opp-hz = /bits/ 64 <160000000>; }; }; @@ -407,13 +415,13 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; - opp@160000000 { + opp-160000000 { opp-hz = /bits/ 64 <160000000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; }; }; diff --git a/sys/gnu/dts/arm/exynos4412-itop-scp-core.dtsi b/sys/gnu/dts/arm/exynos4412-itop-scp-core.dtsi index a36cd36a26b8..4cd62487bb16 100644 --- a/sys/gnu/dts/arm/exynos4412-itop-scp-core.dtsi +++ b/sys/gnu/dts/arm/exynos4412-itop-scp-core.dtsi @@ -495,7 +495,3 @@ vtmu-supply = <&ldo16_reg>; status = "okay"; }; - -&watchdog { - status = "okay"; -}; diff --git a/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi b/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi index 78f118cb73d4..0f1ff792fe44 100644 --- a/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi +++ b/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi @@ -555,7 +555,3 @@ vtmu-supply = <&ldo10_reg>; status = "okay"; }; - -&watchdog { - status = "okay"; -}; diff --git a/sys/gnu/dts/arm/exynos4412-origen.dts b/sys/gnu/dts/arm/exynos4412-origen.dts index a1ab6f94bb64..7a83e2df18a6 100644 --- a/sys/gnu/dts/arm/exynos4412-origen.dts +++ b/sys/gnu/dts/arm/exynos4412-origen.dts @@ -541,7 +541,3 @@ &serial_3 { status = "okay"; }; - -&watchdog { - status = "okay"; -}; diff --git a/sys/gnu/dts/arm/exynos4412-prime.dtsi b/sys/gnu/dts/arm/exynos4412-prime.dtsi index e75bc170c89c..a67bd953d754 100644 --- a/sys/gnu/dts/arm/exynos4412-prime.dtsi +++ b/sys/gnu/dts/arm/exynos4412-prime.dtsi @@ -20,12 +20,12 @@ }; &cpu0_opp_table { - opp@1600000000 { + opp-1600000000 { opp-hz = /bits/ 64 <1600000000>; opp-microvolt = <1350000>; clock-latency-ns = <200000>; }; - opp@1704000000 { + opp-1704000000 { opp-hz = /bits/ 64 <1704000000>; opp-microvolt = <1350000>; clock-latency-ns = <200000>; diff --git a/sys/gnu/dts/arm/exynos4412-trats2.dts b/sys/gnu/dts/arm/exynos4412-trats2.dts index 41ecd6d465a7..82221a00444d 100644 --- a/sys/gnu/dts/arm/exynos4412-trats2.dts +++ b/sys/gnu/dts/arm/exynos4412-trats2.dts @@ -385,6 +385,8 @@ &dsi_0 { vddcore-supply = <&ldo8_reg>; vddio-supply = <&ldo10_reg>; + samsung,burst-clock-frequency = <500000000>; + samsung,esc-clock-frequency = <20000000>; samsung,pll-clock-frequency = <24000000>; status = "okay"; diff --git a/sys/gnu/dts/arm/exynos4412.dtsi b/sys/gnu/dts/arm/exynos4412.dtsi index 235bbb69ad7c..7ff03a7e8fb9 100644 --- a/sys/gnu/dts/arm/exynos4412.dtsi +++ b/sys/gnu/dts/arm/exynos4412.dtsi @@ -76,73 +76,73 @@ compatible = "operating-points-v2"; opp-shared; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <900000>; clock-latency-ns = <200000>; }; - opp@300000000 { + opp-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <900000>; clock-latency-ns = <200000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <925000>; clock-latency-ns = <200000>; }; - opp@500000000 { + opp-500000000 { opp-hz = /bits/ 64 <500000000>; opp-microvolt = <950000>; clock-latency-ns = <200000>; }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <975000>; clock-latency-ns = <200000>; }; - opp@700000000 { + opp-700000000 { opp-hz = /bits/ 64 <700000000>; opp-microvolt = <987500>; clock-latency-ns = <200000>; }; - opp@800000000 { + opp-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1000000>; clock-latency-ns = <200000>; opp-suspend; }; - opp@900000000 { + opp-900000000 { opp-hz = /bits/ 64 <900000000>; opp-microvolt = <1037500>; clock-latency-ns = <200000>; }; - opp@1000000000 { + opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1087500>; clock-latency-ns = <200000>; }; - opp@1100000000 { + opp-1100000000 { opp-hz = /bits/ 64 <1100000000>; opp-microvolt = <1137500>; clock-latency-ns = <200000>; }; - opp@1200000000 { + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; opp-microvolt = <1187500>; clock-latency-ns = <200000>; }; - opp@1300000000 { + opp-1300000000 { opp-hz = /bits/ 64 <1300000000>; opp-microvolt = <1250000>; clock-latency-ns = <200000>; }; - opp@1400000000 { + opp-1400000000 { opp-hz = /bits/ 64 <1400000000>; opp-microvolt = <1287500>; clock-latency-ns = <200000>; }; - cpu0_opp_1500: opp@1500000000 { + cpu0_opp_1500: opp-1500000000 { opp-hz = /bits/ 64 <1500000000>; opp-microvolt = <1350000>; clock-latency-ns = <200000>; @@ -215,6 +215,15 @@ }; }; + watchdog: watchdog@10060000 { + compatible = "samsung,exynos5250-wdt"; + reg = <0x10060000 0x100>; + interrupts = ; + clocks = <&clock CLK_WDT>; + clock-names = "watchdog"; + samsung,syscon-phandle = <&pmu_system_controller>; + }; + adc: adc@126C0000 { compatible = "samsung,exynos-adc-v1"; reg = <0x126C0000 0x100>; @@ -433,23 +442,23 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; opp-microvolt = <900000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; opp-microvolt = <900000>; }; - opp@160000000 { + opp-160000000 { opp-hz = /bits/ 64 <160000000>; opp-microvolt = <900000>; }; - opp@267000000 { + opp-267000000 { opp-hz = /bits/ 64 <267000000>; opp-microvolt = <950000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1050000>; }; @@ -459,16 +468,16 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; }; - opp@160000000 { + opp-160000000 { opp-hz = /bits/ 64 <160000000>; }; - opp@267000000 { + opp-267000000 { opp-hz = /bits/ 64 <267000000>; }; }; @@ -525,19 +534,19 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; opp-microvolt = <900000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; opp-microvolt = <925000>; }; - opp@160000000 { + opp-160000000 { opp-hz = /bits/ 64 <160000000>; opp-microvolt = <950000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <1000000>; }; @@ -547,10 +556,10 @@ compatible = "operating-points-v2"; opp-shared; - opp@160000000 { + opp-160000000 { opp-hz = /bits/ 64 <160000000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; }; }; @@ -559,10 +568,10 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; - opp@134000000 { + opp-134000000 { opp-hz = /bits/ 64 <134000000>; }; }; @@ -571,10 +580,10 @@ compatible = "operating-points-v2"; opp-shared; - opp@50000000 { + opp-50000000 { opp-hz = /bits/ 64 <50000000>; }; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; }; }; diff --git a/sys/gnu/dts/arm/exynos5420-tmu-sensor-conf.dtsi b/sys/gnu/dts/arm/exynos5420-tmu-sensor-conf.dtsi new file mode 100644 index 000000000000..c8771c660550 --- /dev/null +++ b/sys/gnu/dts/arm/exynos5420-tmu-sensor-conf.dtsi @@ -0,0 +1,25 @@ +/* + * Device tree sources for Exynos5420 TMU sensor configuration + * + * Copyright (c) 2014 Lukasz Majewski + * Copyright (c) 2017 Krzysztof Kozlowski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include + +#thermal-sensor-cells = <0>; +samsung,tmu_gain = <8>; +samsung,tmu_reference_voltage = <16>; +samsung,tmu_noise_cancel_mode = <4>; +samsung,tmu_efuse_value = <55>; +samsung,tmu_min_efuse_value = <0>; +samsung,tmu_max_efuse_value = <100>; +samsung,tmu_first_point_trim = <25>; +samsung,tmu_second_point_trim = <85>; +samsung,tmu_default_temp_offset = <50>; +samsung,tmu_cal_type = ; diff --git a/sys/gnu/dts/arm/exynos5420.dtsi b/sys/gnu/dts/arm/exynos5420.dtsi index 7dc9dc82afd8..0db0bcf8da36 100644 --- a/sys/gnu/dts/arm/exynos5420.dtsi +++ b/sys/gnu/dts/arm/exynos5420.dtsi @@ -49,62 +49,62 @@ cluster_a15_opp_table: opp_table0 { compatible = "operating-points-v2"; opp-shared; - opp@1800000000 { + opp-1800000000 { opp-hz = /bits/ 64 <1800000000>; opp-microvolt = <1250000>; clock-latency-ns = <140000>; }; - opp@1700000000 { + opp-1700000000 { opp-hz = /bits/ 64 <1700000000>; opp-microvolt = <1212500>; clock-latency-ns = <140000>; }; - opp@1600000000 { + opp-1600000000 { opp-hz = /bits/ 64 <1600000000>; opp-microvolt = <1175000>; clock-latency-ns = <140000>; }; - opp@1500000000 { + opp-1500000000 { opp-hz = /bits/ 64 <1500000000>; opp-microvolt = <1137500>; clock-latency-ns = <140000>; }; - opp@1400000000 { + opp-1400000000 { opp-hz = /bits/ 64 <1400000000>; opp-microvolt = <1112500>; clock-latency-ns = <140000>; }; - opp@1300000000 { + opp-1300000000 { opp-hz = /bits/ 64 <1300000000>; opp-microvolt = <1062500>; clock-latency-ns = <140000>; }; - opp@1200000000 { + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; opp-microvolt = <1037500>; clock-latency-ns = <140000>; }; - opp@1100000000 { + opp-1100000000 { opp-hz = /bits/ 64 <1100000000>; opp-microvolt = <1012500>; clock-latency-ns = <140000>; }; - opp@1000000000 { + opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = < 987500>; clock-latency-ns = <140000>; }; - opp@900000000 { + opp-900000000 { opp-hz = /bits/ 64 <900000000>; opp-microvolt = < 962500>; clock-latency-ns = <140000>; }; - opp@800000000 { + opp-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = < 937500>; clock-latency-ns = <140000>; }; - opp@700000000 { + opp-700000000 { opp-hz = /bits/ 64 <700000000>; opp-microvolt = < 912500>; clock-latency-ns = <140000>; @@ -114,42 +114,42 @@ cluster_a7_opp_table: opp_table1 { compatible = "operating-points-v2"; opp-shared; - opp@1300000000 { + opp-1300000000 { opp-hz = /bits/ 64 <1300000000>; opp-microvolt = <1275000>; clock-latency-ns = <140000>; }; - opp@1200000000 { + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; opp-microvolt = <1212500>; clock-latency-ns = <140000>; }; - opp@1100000000 { + opp-1100000000 { opp-hz = /bits/ 64 <1100000000>; opp-microvolt = <1162500>; clock-latency-ns = <140000>; }; - opp@1000000000 { + opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1112500>; clock-latency-ns = <140000>; }; - opp@900000000 { + opp-900000000 { opp-hz = /bits/ 64 <900000000>; opp-microvolt = <1062500>; clock-latency-ns = <140000>; }; - opp@800000000 { + opp-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1025000>; clock-latency-ns = <140000>; }; - opp@700000000 { + opp-700000000 { opp-hz = /bits/ 64 <700000000>; opp-microvolt = <975000>; clock-latency-ns = <140000>; }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <937500>; clock-latency-ns = <140000>; @@ -699,7 +699,7 @@ interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clock CLK_TMU>; clock-names = "tmu_apbif"; - #include "exynos4412-tmu-sensor-conf.dtsi" + #include "exynos5420-tmu-sensor-conf.dtsi" }; tmu_cpu1: tmu@10064000 { @@ -708,7 +708,7 @@ interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clock CLK_TMU>; clock-names = "tmu_apbif"; - #include "exynos4412-tmu-sensor-conf.dtsi" + #include "exynos5420-tmu-sensor-conf.dtsi" }; tmu_cpu2: tmu@10068000 { @@ -717,7 +717,7 @@ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clock CLK_TMU>, <&clock CLK_TMU>; clock-names = "tmu_apbif", "tmu_triminfo_apbif"; - #include "exynos4412-tmu-sensor-conf.dtsi" + #include "exynos5420-tmu-sensor-conf.dtsi" }; tmu_cpu3: tmu@1006c000 { @@ -726,7 +726,7 @@ interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>; clock-names = "tmu_apbif", "tmu_triminfo_apbif"; - #include "exynos4412-tmu-sensor-conf.dtsi" + #include "exynos5420-tmu-sensor-conf.dtsi" }; tmu_gpu: tmu@100a0000 { @@ -735,7 +735,7 @@ interrupts = <0 215 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>; clock-names = "tmu_apbif", "tmu_triminfo_apbif"; - #include "exynos4412-tmu-sensor-conf.dtsi" + #include "exynos5420-tmu-sensor-conf.dtsi" }; sysmmu_g2dr: sysmmu@0x10A60000 { diff --git a/sys/gnu/dts/arm/exynos5440.dtsi b/sys/gnu/dts/arm/exynos5440.dtsi index 77d35bb92950..a4ea018464fc 100644 --- a/sys/gnu/dts/arm/exynos5440.dtsi +++ b/sys/gnu/dts/arm/exynos5440.dtsi @@ -189,7 +189,7 @@ }; watchdog@110000 { - compatible = "samsung,s3c2410-wdt"; + compatible = "samsung,s3c6410-wdt"; reg = <0x110000 0x1000>; interrupts = ; clocks = <&clock CLK_B_125>; @@ -290,11 +290,22 @@ clock-names = "usbhost"; }; + pcie_phy0: pcie-phy@270000 { + #phy-cells = <0>; + compatible = "samsung,exynos5440-pcie-phy"; + reg = <0x270000 0x1000>, <0x271000 0x40>; + }; + + pcie_phy1: pcie-phy@272000 { + #phy-cells = <0>; + compatible = "samsung,exynos5440-pcie-phy"; + reg = <0x272000 0x1000>, <0x271040 0x40>; + }; + pcie_0: pcie@290000 { compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; - reg = <0x290000 0x1000 - 0x270000 0x1000 - 0x271000 0x40>; + reg = <0x290000 0x1000>, <0x40000000 0x1000>; + reg-names = "elbi", "config"; interrupts = , , ; @@ -303,8 +314,8 @@ #address-cells = <3>; #size-cells = <2>; device_type = "pci"; - ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000 /* configuration space */ - 0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */ + phys = <&pcie_phy0>; + ranges = <0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */ #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; @@ -315,9 +326,8 @@ pcie_1: pcie@2a0000 { compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; - reg = <0x2a0000 0x1000 - 0x272000 0x1000 - 0x271040 0x40>; + reg = <0x2a0000 0x1000>, <0x60000000 0x1000>; + reg-names = "elbi", "config"; interrupts = , , ; @@ -326,8 +336,8 @@ #address-cells = <3>; #size-cells = <2>; device_type = "pci"; - ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000 /* configuration space */ - 0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */ + phys = <&pcie_phy1>; + ranges = <0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */ #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; diff --git a/sys/gnu/dts/arm/exynos5800.dtsi b/sys/gnu/dts/arm/exynos5800.dtsi index 8213016803e5..9ddb6bacac5a 100644 --- a/sys/gnu/dts/arm/exynos5800.dtsi +++ b/sys/gnu/dts/arm/exynos5800.dtsi @@ -24,60 +24,60 @@ }; &cluster_a15_opp_table { - opp@1700000000 { + opp-1700000000 { opp-microvolt = <1250000>; }; - opp@1600000000 { + opp-1600000000 { opp-microvolt = <1250000>; }; - opp@1500000000 { + opp-1500000000 { opp-microvolt = <1100000>; }; - opp@1400000000 { + opp-1400000000 { opp-microvolt = <1100000>; }; - opp@1300000000 { + opp-1300000000 { opp-microvolt = <1100000>; }; - opp@1200000000 { + opp-1200000000 { opp-microvolt = <1000000>; }; - opp@1100000000 { + opp-1100000000 { opp-microvolt = <1000000>; }; - opp@1000000000 { + opp-1000000000 { opp-microvolt = <1000000>; }; - opp@900000000 { + opp-900000000 { opp-microvolt = <1000000>; }; - opp@800000000 { + opp-800000000 { opp-microvolt = <900000>; }; - opp@700000000 { + opp-700000000 { opp-microvolt = <900000>; }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <900000>; clock-latency-ns = <140000>; }; - opp@500000000 { + opp-500000000 { opp-hz = /bits/ 64 <500000000>; opp-microvolt = <900000>; clock-latency-ns = <140000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <900000>; clock-latency-ns = <140000>; }; - opp@300000000 { + opp-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <900000>; clock-latency-ns = <140000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <900000>; clock-latency-ns = <140000>; @@ -85,46 +85,46 @@ }; &cluster_a7_opp_table { - opp@1300000000 { + opp-1300000000 { opp-microvolt = <1250000>; }; - opp@1200000000 { + opp-1200000000 { opp-microvolt = <1250000>; }; - opp@1100000000 { + opp-1100000000 { opp-microvolt = <1250000>; }; - opp@1000000000 { + opp-1000000000 { opp-microvolt = <1100000>; }; - opp@900000000 { + opp-900000000 { opp-microvolt = <1100000>; }; - opp@800000000 { + opp-800000000 { opp-microvolt = <1100000>; }; - opp@700000000 { + opp-700000000 { opp-microvolt = <1000000>; }; - opp@600000000 { + opp-600000000 { opp-microvolt = <1000000>; }; - opp@500000000 { + opp-500000000 { opp-hz = /bits/ 64 <500000000>; opp-microvolt = <1000000>; clock-latency-ns = <140000>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1000000>; clock-latency-ns = <140000>; }; - opp@300000000 { + opp-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <900000>; clock-latency-ns = <140000>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <900000>; clock-latency-ns = <140000>; diff --git a/sys/gnu/dts/arm/gemini-nas4220b.dts b/sys/gnu/dts/arm/gemini-nas4220b.dts new file mode 100644 index 000000000000..7668ba52158e --- /dev/null +++ b/sys/gnu/dts/arm/gemini-nas4220b.dts @@ -0,0 +1,102 @@ +/* + * Device Tree file for the Gemini-based Raidsonic NAS IB-4220-B + */ + +/dts-v1/; + +#include "gemini.dtsi" +#include + +/ { + model = "Raidsonic NAS IB-4220-B"; + compatible = "raidsonic,ib-4220-b", "cortina,gemini"; + #address-cells = <1>; + #size-cells = <1>; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS0,19200n8"; + stdout-path = &uart0; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@29 { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "Backup button"; + gpios = <&gpio1 29 GPIO_ACTIVE_LOW>; + }; + button@31 { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "Softreset button"; + gpios = <&gpio1 31 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + led@28 { + label = "nas4220b:orange:hdd"; + gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + led@30 { + label = "nas4220b:green:os"; + gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + }; + + soc { + flash@30000000 { + status = "okay"; + /* 16MB of flash */ + reg = <0x30000000 0x01000000>; + + partition@0 { + label = "RedBoot"; + reg = <0x00000000 0x00020000>; + read-only; + }; + partition@20000 { + label = "Kernel"; + reg = <0x00020000 0x00300000>; + }; + partition@320000 { + label = "Ramdisk"; + reg = <0x00320000 0x00600000>; + }; + partition@920000 { + label = "Application"; + reg = <0x00920000 0x00600000>; + }; + partition@f20000 { + label = "VCTL"; + reg = <0x00f20000 0x00020000>; + read-only; + }; + partition@f40000 { + label = "CurConf"; + reg = <0x00f40000 0x000a0000>; + read-only; + }; + partition@fe0000 { + label = "FIS directory"; + reg = <0x00fe0000 0x00020000>; + read-only; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/gemini-rut1xx.dts b/sys/gnu/dts/arm/gemini-rut1xx.dts new file mode 100644 index 000000000000..7b920bfbda32 --- /dev/null +++ b/sys/gnu/dts/arm/gemini-rut1xx.dts @@ -0,0 +1,65 @@ +/* + * Device Tree file for Teltonika RUT1xx + */ + +/dts-v1/; + +#include "gemini.dtsi" +#include + +/ { + model = "Teltonika RUT1xx"; + compatible = "teltonika,rut1xx", "cortina,gemini"; + #address-cells = <1>; + #size-cells = <1>; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + stdout-path = &uart0; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@28 { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "Reset to defaults"; + gpios = <&gpio1 28 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + led@7 { + /* FIXME: add the LED color */ + label = "rut1xx::gsm"; + gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + led@31 { + /* FIXME: add the LED color */ + label = "rut1xx::power"; + gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "heartbeat"; + }; + }; + + soc { + flash@30000000 { + status = "okay"; + /* 8MB of flash */ + reg = <0x30000000 0x00800000>; + /* TODO: add flash partitions here */ + }; + }; +}; diff --git a/sys/gnu/dts/arm/gemini-sq201.dts b/sys/gnu/dts/arm/gemini-sq201.dts new file mode 100644 index 000000000000..46309e79cc7b --- /dev/null +++ b/sys/gnu/dts/arm/gemini-sq201.dts @@ -0,0 +1,118 @@ +/* + * Device Tree file for ITian Square One SQ201 NAS + */ + +/dts-v1/; + +#include "gemini.dtsi" +#include + +/ { + model = "ITian Square One SQ201"; + compatible = "itian,sq201", "cortina,gemini"; + #address-cells = <1>; + #size-cells = <1>; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + stdout-path = &uart0; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@18 { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "factory reset"; + gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + led@20 { + label = "sq201:green:info"; + gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + led@31 { + label = "sq201:green:usb"; + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "usb-host"; + }; + }; + + soc { + flash@30000000 { + status = "okay"; + /* 16MB of flash */ + reg = <0x30000000 0x01000000>; + + partition@0 { + label = "RedBoot"; + reg = <0x00000000 0x00120000>; + read-only; + }; + partition@120000 { + label = "Kernel"; + reg = <0x00120000 0x00200000>; + }; + partition@320000 { + label = "Ramdisk"; + reg = <0x00320000 0x00600000>; + }; + partition@920000 { + label = "Application"; + reg = <0x00920000 0x00600000>; + }; + partition@f20000 { + label = "VCTL"; + reg = <0x00f20000 0x00020000>; + read-only; + }; + partition@f40000 { + label = "CurConf"; + reg = <0x00f40000 0x000a0000>; + read-only; + }; + partition@fe0000 { + label = "FIS directory"; + reg = <0x00fe0000 0x00020000>; + read-only; + }; + }; + + pci@50000000 { + status = "okay"; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = + <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */ + <0x4800 0 0 2 &pci_intc 1>, + <0x4800 0 0 3 &pci_intc 2>, + <0x4800 0 0 4 &pci_intc 3>, + <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */ + <0x5000 0 0 2 &pci_intc 2>, + <0x5000 0 0 3 &pci_intc 3>, + <0x5000 0 0 4 &pci_intc 0>, + <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */ + <0x5800 0 0 2 &pci_intc 3>, + <0x5800 0 0 3 &pci_intc 0>, + <0x5800 0 0 4 &pci_intc 1>, + <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */ + <0x6000 0 0 2 &pci_intc 0>, + <0x6000 0 0 3 &pci_intc 1>, + <0x6000 0 0 4 &pci_intc 2>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/gemini-wbd111.dts b/sys/gnu/dts/arm/gemini-wbd111.dts new file mode 100644 index 000000000000..63b756e3bf5a --- /dev/null +++ b/sys/gnu/dts/arm/gemini-wbd111.dts @@ -0,0 +1,102 @@ +/* + * Device Tree file for Wiliboard WBD-111 + */ + +/dts-v1/; + +#include "gemini.dtsi" +#include + +/ { + model = "Wiliboard WBD-111"; + compatible = "wiliboard,wbd111", "cortina,gemini"; + #address-cells = <1>; + #size-cells = <1>; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + stdout-path = &uart0; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@5 { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "reset"; + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led@1 { + label = "wbd111:red:L3"; + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@2 { + label = "wbd111:green:L4"; + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@3 { + label = "wbd111:red:L4"; + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@5 { + label = "wbd111:green:L3"; + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + }; + + soc { + flash@30000000 { + status = "okay"; + /* 8MB of flash */ + reg = <0x30000000 0x00800000>; + + partition@0 { + label = "RedBoot"; + reg = <0x00000000 0x00020000>; + read-only; + }; + partition@20000 { + label = "kernel"; + reg = <0x00020000 0x00100000>; + }; + partition@120000 { + label = "rootfs"; + reg = <0x00120000 0x006a0000>; + }; + partition@7c0000 { + label = "VCTL"; + reg = <0x007c0000 0x00010000>; + read-only; + }; + partition@7d0000 { + label = "cfg"; + reg = <0x007d0000 0x00010000>; + read-only; + }; + partition@7e0000 { + label = "FIS"; + reg = <0x007e0000 0x00010000>; + read-only; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/gemini-wbd222.dts b/sys/gnu/dts/arm/gemini-wbd222.dts new file mode 100644 index 000000000000..9747f5a47807 --- /dev/null +++ b/sys/gnu/dts/arm/gemini-wbd222.dts @@ -0,0 +1,102 @@ +/* + * Device Tree file for Wiliboard WBD-222 + */ + +/dts-v1/; + +#include "gemini.dtsi" +#include + +/ { + model = "Wiliboard WBD-222"; + compatible = "wiliboard,wbd222", "cortina,gemini"; + #address-cells = <1>; + #size-cells = <1>; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + stdout-path = &uart0; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@5 { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "reset"; + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led@1 { + label = "wbd111:red:L3"; + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@2 { + label = "wbd111:green:L4"; + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@3 { + label = "wbd111:red:L4"; + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@5 { + label = "wbd111:green:L3"; + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + }; + + soc { + flash@30000000 { + status = "okay"; + /* 8MB of flash */ + reg = <0x30000000 0x00800000>; + + partition@0 { + label = "RedBoot"; + reg = <0x00000000 0x00020000>; + read-only; + }; + partition@20000 { + label = "kernel"; + reg = <0x00020000 0x00100000>; + }; + partition@120000 { + label = "rootfs"; + reg = <0x00120000 0x006a0000>; + }; + partition@7c0000 { + label = "VCTL"; + reg = <0x007c0000 0x00010000>; + read-only; + }; + partition@7d0000 { + label = "cfg"; + reg = <0x007d0000 0x00010000>; + read-only; + }; + partition@7e0000 { + label = "FIS"; + reg = <0x007e0000 0x00010000>; + read-only; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/gemini.dtsi b/sys/gnu/dts/arm/gemini.dtsi new file mode 100644 index 000000000000..b8d011bdcc76 --- /dev/null +++ b/sys/gnu/dts/arm/gemini.dtsi @@ -0,0 +1,156 @@ +/* + * Device Tree file for Cortina systems Gemini SoC + */ + +/include/ "skeleton.dtsi" + +#include +#include + +/ { + soc { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "simple-bus"; + interrupt-parent = <&intcon>; + + flash@30000000 { + compatible = "cortina,gemini-flash", "cfi-flash"; + syscon = <&syscon>; + bank-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; + + syscon: syscon@40000000 { + compatible = "cortina,gemini-syscon", "syscon", "simple-mfd"; + reg = <0x40000000 0x1000>; + + syscon-reboot { + compatible = "syscon-reboot"; + regmap = <&syscon>; + /* GLOBAL_RESET register */ + offset = <0x0c>; + /* RESET_GLOBAL | RESET_CPU1 */ + mask = <0xC0000000>; + }; + }; + + watchdog@41000000 { + compatible = "cortina,gemini-watchdog"; + reg = <0x41000000 0x1000>; + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; + }; + + uart0: serial@42000000 { + compatible = "ns16550a"; + reg = <0x42000000 0x100>; + clock-frequency = <48000000>; + interrupts = <18 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + }; + + timer@43000000 { + compatible = "cortina,gemini-timer"; + reg = <0x43000000 0x1000>; + interrupt-parent = <&intcon>; + interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */ + <15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */ + <16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */ + syscon = <&syscon>; + }; + + rtc@45000000 { + compatible = "cortina,gemini-rtc"; + reg = <0x45000000 0x100>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; + }; + + intcon: interrupt-controller@48000000 { + compatible = "faraday,ftintc010"; + reg = <0x48000000 0x1000>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + power-controller@4b000000 { + compatible = "cortina,gemini-power-controller"; + reg = <0x4b000000 0x100>; + interrupts = <26 IRQ_TYPE_EDGE_RISING>; + }; + + gpio0: gpio@4d000000 { + compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; + reg = <0x4d000000 0x100>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@4e000000 { + compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; + reg = <0x4e000000 0x100>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio@4f000000 { + compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; + reg = <0x4f000000 0x100>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pci@50000000 { + compatible = "cortina,gemini-pci", "faraday,ftpci100"; + /* + * The first 256 bytes in the IO range is actually used + * to configure the host bridge. + */ + reg = <0x50000000 0x100>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + status = "disabled"; + + bus-range = <0x00 0xff>; + /* PCI ranges mappings */ + ranges = + /* 1MiB I/O space 0x50000000-0x500fffff */ + <0x01000000 0 0 0x50000000 0 0x00100000>, + /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */ + <0x02000000 0 0x58000000 0x58000000 0 0x08000000>; + + /* DMA ranges */ + dma-ranges = + /* 128MiB at 0x00000000-0x07ffffff */ + <0x02000000 0 0x00000000 0x00000000 0 0x08000000>, + /* 64MiB at 0x00000000-0x03ffffff */ + <0x02000000 0 0x00000000 0x00000000 0 0x04000000>, + /* 64MiB at 0x00000000-0x03ffffff */ + <0x02000000 0 0x00000000 0x00000000 0 0x04000000>; + + /* + * This PCI host bridge variant has a cascaded interrupt + * controller embedded in the host bridge. + */ + pci_intc: interrupt-controller { + interrupt-parent = <&intcon>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx25-eukrea-mbimxsd25-baseboard.dts b/sys/gnu/dts/arm/imx25-eukrea-mbimxsd25-baseboard.dts index 9300711f1ea3..db39bd6b8e00 100644 --- a/sys/gnu/dts/arm/imx25-eukrea-mbimxsd25-baseboard.dts +++ b/sys/gnu/dts/arm/imx25-eukrea-mbimxsd25-baseboard.dts @@ -179,8 +179,6 @@ }; &usbotg { - phy_type = "utmi"; - dr_mode = "otg"; external-vbus-divider; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx25-pdk.dts b/sys/gnu/dts/arm/imx25-pdk.dts index 70292101ba03..d921dd2ed676 100644 --- a/sys/gnu/dts/arm/imx25-pdk.dts +++ b/sys/gnu/dts/arm/imx25-pdk.dts @@ -309,8 +309,6 @@ }; &usbotg { - phy_type = "utmi"; - dr_mode = "otg"; external-vbus-divider; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx25-pinfunc.h b/sys/gnu/dts/arm/imx25-pinfunc.h index f840f03ad171..6c63dca1b9b8 100644 --- a/sys/gnu/dts/arm/imx25-pinfunc.h +++ b/sys/gnu/dts/arm/imx25-pinfunc.h @@ -17,8 +17,6 @@ * */ -#define MX25_PAD_TDO__TDO 0x000 0x3e8 0x000 0x00 0x000 - #define MX25_PAD_A10__A10 0x008 0x000 0x000 0x00 0x000 #define MX25_PAD_A10__GPIO_4_0 0x008 0x000 0x000 0x05 0x000 @@ -68,7 +66,6 @@ #define MX25_PAD_A22__A22 0x030 0x000 0x000 0x00 0x000 #define MX25_PAD_A22__GPIO_2_8 0x030 0x000 0x000 0x05 0x000 -#define MX25_PAD_A22__FEC_TDATA2 0x030 0x000 0x000 0x07 0x000 #define MX25_PAD_A22__SIM2_VEN1 0x030 0x000 0x000 0x06 0x000 #define MX25_PAD_A22__FEC_TDATA2 0x030 0x000 0x000 0x07 0x000 @@ -542,6 +539,8 @@ #define MX25_PAD_RTCK__OWIRE 0x1ec 0x3e4 0x000 0x01 0x000 #define MX25_PAD_RTCK__GPIO_3_14 0x1ec 0x3e4 0x000 0x05 0x000 +#define MX25_PAD_TDO__TDO 0x000 0x3e8 0x000 0x00 0x000 + #define MX25_PAD_DE_B__DE_B 0x1f0 0x3ec 0x000 0x00 0x000 #define MX25_PAD_DE_B__GPIO_2_20 0x1f0 0x3ec 0x000 0x05 0x000 diff --git a/sys/gnu/dts/arm/imx25.dtsi b/sys/gnu/dts/arm/imx25.dtsi index e0ba55016a04..0cdf333336cd 100644 --- a/sys/gnu/dts/arm/imx25.dtsi +++ b/sys/gnu/dts/arm/imx25.dtsi @@ -93,6 +93,11 @@ reg = <0x43f00000 0x100000>; ranges; + aips1: bridge@43f00000 { + compatible = "fsl,imx25-aips"; + reg = <0x43f00000 0x4000>; + }; + i2c1: i2c@43f80000 { #address-cells = <1>; #size-cells = <0>; @@ -342,6 +347,11 @@ reg = <0x53f00000 0x100000>; ranges; + aips2: bridge@53f00000 { + compatible = "fsl,imx25-aips"; + reg = <0x53f00000 0x4000>; + }; + clks: ccm@53f80000 { compatible = "fsl,imx25-ccm"; reg = <0x53f80000 0x4000>; @@ -544,6 +554,8 @@ clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 0>; fsl,usbphy = <&usbphy0>; + phy_type = "utmi"; + dr_mode = "otg"; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/imx28-duckbill-2-485.dts b/sys/gnu/dts/arm/imx28-duckbill-2-485.dts new file mode 100644 index 000000000000..bd3fd470f9c3 --- /dev/null +++ b/sys/gnu/dts/arm/imx28-duckbill-2-485.dts @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2015-2017 I2SE GmbH + * Copyright (C) 2016 Michael Heimpold + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include +#include +#include "imx28.dtsi" + +/ { + model = "I2SE Duckbill 2 485"; + compatible = "i2se,duckbill-2-485", "i2se,duckbill-2", "fsl,imx28"; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_8bit_pins_a + &mmc0_cd_cfg &mmc0_sck_cfg>; + bus-width = <8>; + vmmc-supply = <®_3p3v>; + status = "okay"; + non-removable; + }; + + ssp2: ssp@80014000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_4bit_pins_b + &mmc2_cd_cfg &mmc2_sck_cfg_b>; + bus-width = <4>; + vmmc-supply = <®_3p3v>; + status = "okay"; + }; + + pinctrl@80018000 { + pinctrl-names = "default"; + pinctrl-0 = <&hog_pins_a>; + + hog_pins_a: hog@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_LCD_D17__GPIO_1_17 /* Revision detection */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_reset_pin: mac0-phy-reset@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_ALE__GPIO_0_26 /* PHY Reset */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_int_pin: mac0-phy-int@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_D07__GPIO_0_7 /* PHY Interrupt */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + led_pins: leds@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SAIF0_MCLK__GPIO_3_20 + MX28_PAD_SAIF0_LRCLK__GPIO_3_21 + MX28_PAD_I2C0_SCL__GPIO_3_24 + MX28_PAD_I2C0_SDA__GPIO_3_25 + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + }; + }; + + apbx@80040000 { + lradc@80050000 { + status = "okay"; + }; + + auart0: serial@8006a000 { + pinctrl-names = "default"; + pinctrl-0 = <&auart0_2pins_a>; + status = "okay"; + }; + + duart: serial@80074000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; + status = "okay"; + }; + + usbphy0: usbphy@8007c000 { + status = "okay"; + }; + }; + }; + + ahb@80080000 { + usb0: usb@80080000 { + status = "okay"; + dr_mode = "peripheral"; + }; + + mac0: ethernet@800f0000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_pins_a>, <&mac0_phy_reset_pin>; + phy-supply = <®_3p3v>; + phy-reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + phy-reset-duration = <25>; + phy-handle = <ðphy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_phy_int_pin>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + max-speed = <100>; + }; + }; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + status-red { + label = "duckbill:red:status"; + gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + + status-green { + label = "duckbill:green:status"; + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + rs485-red { + label = "duckbill:red:rs485"; + gpios = <&gpio3 24 GPIO_ACTIVE_LOW>; + }; + + rs485-green { + label = "duckbill:green:rs485"; + gpios = <&gpio3 25 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx28-duckbill-2-enocean.dts b/sys/gnu/dts/arm/imx28-duckbill-2-enocean.dts new file mode 100644 index 000000000000..4450047885eb --- /dev/null +++ b/sys/gnu/dts/arm/imx28-duckbill-2-enocean.dts @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2015-2017 I2SE GmbH + * Copyright (C) 2016 Michael Heimpold + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include +#include +#include +#include "imx28.dtsi" + +/ { + model = "I2SE Duckbill 2 EnOcean"; + compatible = "i2se,duckbill-2-enocean", "i2se,duckbill-2", "fsl,imx28"; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_8bit_pins_a + &mmc0_cd_cfg &mmc0_sck_cfg>; + bus-width = <8>; + vmmc-supply = <®_3p3v>; + status = "okay"; + non-removable; + }; + + ssp2: ssp@80014000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_4bit_pins_b + &mmc2_cd_cfg &mmc2_sck_cfg_b>; + bus-width = <4>; + vmmc-supply = <®_3p3v>; + status = "okay"; + }; + + pinctrl@80018000 { + pinctrl-names = "default"; + pinctrl-0 = <&hog_pins_a>; + + hog_pins_a: hog@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_LCD_D17__GPIO_1_17 /* Revision detection */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_reset_pin: mac0-phy-reset@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_ALE__GPIO_0_26 /* PHY Reset */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_int_pin: mac0-phy-int@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_D07__GPIO_0_7 /* PHY Interrupt */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + led_pins: leds@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SAIF0_MCLK__GPIO_3_20 + MX28_PAD_SAIF0_LRCLK__GPIO_3_21 + MX28_PAD_AUART0_CTS__GPIO_3_2 + MX28_PAD_I2C0_SCL__GPIO_3_24 + MX28_PAD_I2C0_SDA__GPIO_3_25 + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + enocean_button: enocean-button@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_AUART0_RTS__GPIO_3_3 + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + }; + }; + + apbx@80040000 { + lradc@80050000 { + status = "okay"; + }; + + auart0: serial@8006a000 { + pinctrl-names = "default"; + pinctrl-0 = <&auart0_2pins_a>; + status = "okay"; + }; + + duart: serial@80074000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; + status = "okay"; + }; + + usbphy0: usbphy@8007c000 { + status = "okay"; + }; + }; + }; + + ahb@80080000 { + usb0: usb@80080000 { + status = "okay"; + dr_mode = "peripheral"; + }; + + mac0: ethernet@800f0000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_pins_a>, <&mac0_phy_reset_pin>; + phy-supply = <®_3p3v>; + phy-reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + phy-reset-duration = <25>; + phy-handle = <ðphy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_phy_int_pin>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + max-speed = <100>; + }; + }; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + status-red { + label = "duckbill:red:status"; + gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + + status-green { + label = "duckbill:green:status"; + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + enocean-blue { + label = "duckbill:blue:enocean"; + gpios = <&gpio3 24 GPIO_ACTIVE_LOW>; + }; + + enocean-red { + label = "duckbill:red:enocean"; + gpios = <&gpio3 25 GPIO_ACTIVE_LOW>; + }; + + enocean-green { + label = "duckbill:green:enocean"; + gpios = <&gpio3 2 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&enocean_button>; + + enocean { + label = "EnOcean"; + linux,code = ; + gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx28-duckbill-2-spi.dts b/sys/gnu/dts/arm/imx28-duckbill-2-spi.dts new file mode 100644 index 000000000000..927732efca98 --- /dev/null +++ b/sys/gnu/dts/arm/imx28-duckbill-2-spi.dts @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2015-2017 I2SE GmbH + * Copyright (C) 2016 Michael Heimpold + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include +#include +#include "imx28.dtsi" + +/ { + model = "I2SE Duckbill 2 SPI"; + compatible = "i2se,duckbill-2-spi", "i2se,duckbill-2", "fsl,imx28"; + + aliases { + ethernet1 = &qca7000; + }; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_8bit_pins_a + &mmc0_cd_cfg &mmc0_sck_cfg>; + bus-width = <8>; + vmmc-supply = <®_3p3v>; + status = "okay"; + non-removable; + }; + + ssp2: ssp@80014000 { + compatible = "fsl,imx28-spi"; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins_a>; + status = "okay"; + + qca7000: ethernet@0 { + reg = <0>; + compatible = "qca,qca7000"; + pinctrl-names = "default"; + pinctrl-0 = <&qca7000_pins>; + interrupt-parent = <&gpio3>; + interrupts = <3 IRQ_TYPE_EDGE_RISING>; + spi-cpha; + spi-cpol; + spi-max-frequency = <8000000>; + }; + }; + + pinctrl@80018000 { + pinctrl-names = "default"; + pinctrl-0 = <&hog_pins_a>; + + hog_pins_a: hog@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_LCD_D17__GPIO_1_17 /* Revision detection */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_reset_pin: mac0-phy-reset@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_ALE__GPIO_0_26 /* PHY Reset */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_int_pin: mac0-phy-int@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_D07__GPIO_0_7 /* PHY Interrupt */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + led_pins: led@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SAIF0_MCLK__GPIO_3_20 + MX28_PAD_SAIF0_LRCLK__GPIO_3_21 + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + qca7000_pins: qca7000@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_AUART0_RTS__GPIO_3_3 /* Interrupt */ + MX28_PAD_LCD_D13__GPIO_1_13 /* QCA7K reset */ + MX28_PAD_LCD_D14__GPIO_1_14 /* GPIO 0 */ + MX28_PAD_LCD_D15__GPIO_1_15 /* GPIO 1 */ + MX28_PAD_LCD_D18__GPIO_1_18 /* GPIO 2 */ + MX28_PAD_LCD_D21__GPIO_1_21 /* GPIO 3 */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + }; + }; + + apbx@80040000 { + lradc@80050000 { + status = "okay"; + }; + + duart: serial@80074000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; + status = "okay"; + }; + + usbphy0: usbphy@8007c000 { + status = "okay"; + }; + }; + }; + + ahb@80080000 { + usb0: usb@80080000 { + status = "okay"; + dr_mode = "peripheral"; + }; + + mac0: ethernet@800f0000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_pins_a>, <&mac0_phy_reset_pin>; + phy-supply = <®_3p3v>; + phy-reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + phy-reset-duration = <25>; + phy-handle = <ðphy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_phy_int_pin>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + max-speed = <100>; + }; + }; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + status-red { + label = "duckbill:red:status"; + gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + + status-green { + label = "duckbill:green:status"; + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx28-duckbill-2.dts b/sys/gnu/dts/arm/imx28-duckbill-2.dts new file mode 100644 index 000000000000..7fa3d759505c --- /dev/null +++ b/sys/gnu/dts/arm/imx28-duckbill-2.dts @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2015-2017 I2SE GmbH + * Copyright (C) 2016 Michael Heimpold + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include +#include +#include "imx28.dtsi" + +/ { + model = "I2SE Duckbill 2"; + compatible = "i2se,duckbill-2", "fsl,imx28"; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_8bit_pins_a + &mmc0_cd_cfg &mmc0_sck_cfg>; + bus-width = <8>; + vmmc-supply = <®_3p3v>; + status = "okay"; + non-removable; + }; + + ssp2: ssp@80014000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_4bit_pins_b + &mmc2_cd_cfg &mmc2_sck_cfg_b>; + bus-width = <4>; + vmmc-supply = <®_3p3v>; + status = "okay"; + }; + + pinctrl@80018000 { + pinctrl-names = "default"; + pinctrl-0 = <&hog_pins_a>; + + hog_pins_a: hog@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_LCD_D17__GPIO_1_17 /* Revision detection */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_reset_pin: mac0-phy-reset@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_ALE__GPIO_0_26 /* PHY Reset */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + mac0_phy_int_pin: mac0-phy-int@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_GPMI_D07__GPIO_0_7 /* PHY Interrupt */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + led_pins: leds@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SAIF0_MCLK__GPIO_3_20 + MX28_PAD_SAIF0_LRCLK__GPIO_3_21 + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + }; + }; + + apbx@80040000 { + lradc@80050000 { + status = "okay"; + }; + + i2c0: i2c@80058000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + auart0: serial@8006a000 { + pinctrl-names = "default"; + pinctrl-0 = <&auart0_2pins_a>; + status = "okay"; + }; + + duart: serial@80074000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; + status = "okay"; + }; + + usbphy0: usbphy@8007c000 { + status = "okay"; + }; + }; + }; + + ahb@80080000 { + usb0: usb@80080000 { + status = "okay"; + dr_mode = "peripheral"; + }; + + mac0: ethernet@800f0000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_pins_a>, <&mac0_phy_reset_pin>; + phy-supply = <®_3p3v>; + phy-reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + phy-reset-duration = <25>; + phy-handle = <ðphy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_phy_int_pin>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + max-speed = <100>; + }; + }; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + status-red { + label = "duckbill:red:status"; + gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + + status-green { + label = "duckbill:green:status"; + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx28-duckbill.dts b/sys/gnu/dts/arm/imx28-duckbill.dts index ce1a7effba37..3e4385d4ed78 100644 --- a/sys/gnu/dts/arm/imx28-duckbill.dts +++ b/sys/gnu/dts/arm/imx28-duckbill.dts @@ -1,5 +1,6 @@ /* - * Copyright (C) 2013 Michael Heimpold + * Copyright (C) 2013-2014,2016 Michael Heimpold + * Copyright (C) 2015-2017 I2SE GmbH * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -10,6 +11,7 @@ */ /dts-v1/; +#include #include "imx28.dtsi" / { @@ -32,6 +34,13 @@ status = "okay"; }; + ssp2: ssp@80014000 { + compatible = "fsl,imx28-spi"; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins_a>; + status = "okay"; + }; + pinctrl@80018000 { pinctrl-names = "default"; pinctrl-0 = <&hog_pins_a>; @@ -39,14 +48,24 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - MX28_PAD_SSP0_DATA7__GPIO_2_7 /* PHY Reset */ + MX28_PAD_LCD_D17__GPIO_1_17 /* Revision detection */ >; fsl,drive-strength = ; fsl,voltage = ; fsl,pull-up = ; }; - led_pins_a: led_gpio@0 { + mac0_phy_reset_pin: mac0-phy-reset@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SSP0_DATA7__GPIO_2_7 /* PHY Reset */ + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + + led_pins: leds@0 { reg = <0>; fsl,pinmux-ids = < MX28_PAD_AUART1_RX__GPIO_3_4 @@ -60,6 +79,22 @@ }; apbx@80040000 { + lradc@80050000 { + status = "okay"; + }; + + i2c0: i2c@80058000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + auart0: serial@8006a000 { + pinctrl-names = "default"; + pinctrl-0 = <&auart0_2pins_a>; + status = "okay"; + }; + duart: serial@80074000 { pinctrl-names = "default"; pinctrl-0 = <&duart_pins_a>; @@ -75,47 +110,43 @@ ahb@80080000 { usb0: usb@80080000 { status = "okay"; + dr_mode = "peripheral"; }; mac0: ethernet@800f0000 { phy-mode = "rmii"; pinctrl-names = "default"; - pinctrl-0 = <&mac0_pins_a>; + pinctrl-0 = <&mac0_pins_a>, <&mac0_phy_reset_pin>; phy-supply = <®_3p3v>; phy-reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; - phy-reset-duration = <100>; + phy-reset-duration = <25>; status = "okay"; }; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - reg_3p3v: regulator@0 { - compatible = "regulator-fixed"; - reg = <0>; - regulator-name = "3P3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; }; leds { compatible = "gpio-leds"; pinctrl-names = "default"; - pinctrl-0 = <&led_pins_a>; + pinctrl-0 = <&led_pins>; - status { - label = "duckbill:green:status"; - gpios = <&gpio3 5 GPIO_ACTIVE_HIGH>; - }; - - failure { + status-red { label = "duckbill:red:status"; gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + + status-green { + label = "duckbill:green:status"; + gpios = <&gpio3 5 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; }; }; }; diff --git a/sys/gnu/dts/arm/imx28-m28cu3.dts b/sys/gnu/dts/arm/imx28-m28cu3.dts index 2df63bee6f4e..bb5329479c62 100644 --- a/sys/gnu/dts/arm/imx28-m28cu3.dts +++ b/sys/gnu/dts/arm/imx28-m28cu3.dts @@ -57,7 +57,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_4bit_pins_a &mmc2_cd_cfg - &mmc2_sck_cfg>; + &mmc2_sck_cfg_a>; bus-width = <4>; vmmc-supply = <®_vddio_sd1>; status = "okay"; diff --git a/sys/gnu/dts/arm/imx28.dtsi b/sys/gnu/dts/arm/imx28.dtsi index 148fcf4d3b98..2f4ebe0318d3 100644 --- a/sys/gnu/dts/arm/imx28.dtsi +++ b/sys/gnu/dts/arm/imx28.dtsi @@ -590,6 +590,22 @@ fsl,pull-up = ; }; + mmc2_4bit_pins_b: mmc2-4bit@1 { + reg = <1>; + fsl,pinmux-ids = < + MX28_PAD_SSP2_SCK__SSP2_SCK + MX28_PAD_SSP2_MOSI__SSP2_CMD + MX28_PAD_SSP2_MISO__SSP2_D0 + MX28_PAD_SSP2_SS0__SSP2_D3 + MX28_PAD_SSP2_SS1__SSP2_D1 + MX28_PAD_SSP2_SS2__SSP2_D2 + MX28_PAD_AUART1_RX__SSP2_CARD_DETECT + >; + fsl,drive-strength = ; + fsl,voltage = ; + fsl,pull-up = ; + }; + mmc2_cd_cfg: mmc2-cd-cfg { fsl,pinmux-ids = < MX28_PAD_AUART1_RX__SSP2_CARD_DETECT @@ -597,7 +613,8 @@ fsl,pull-up = ; }; - mmc2_sck_cfg: mmc2-sck-cfg { + mmc2_sck_cfg_a: mmc2-sck-cfg@0 { + reg = <0>; fsl,pinmux-ids = < MX28_PAD_SSP0_DATA7__SSP2_SCK >; @@ -605,6 +622,15 @@ fsl,pull-up = ; }; + mmc2_sck_cfg_b: mmc2-sck-cfg@1 { + reg = <1>; + fsl,pinmux-ids = < + MX28_PAD_SSP2_SCK__SSP2_SCK + >; + fsl,drive-strength = ; + fsl,pull-up = ; + }; + i2c0_pins_a: i2c0@0 { reg = <0>; fsl,pinmux-ids = < diff --git a/sys/gnu/dts/arm/imx50.dtsi b/sys/gnu/dts/arm/imx50.dtsi index ceae909e2201..2a98afcd8a4e 100644 --- a/sys/gnu/dts/arm/imx50.dtsi +++ b/sys/gnu/dts/arm/imx50.dtsi @@ -109,7 +109,7 @@ ranges; esdhc1: esdhc@50004000 { - compatible = "fsl,imx50-esdhc"; + compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc"; reg = <0x50004000 0x4000>; interrupts = <1>; clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>, @@ -121,7 +121,7 @@ }; esdhc2: esdhc@50008000 { - compatible = "fsl,imx50-esdhc"; + compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc"; reg = <0x50008000 0x4000>; interrupts = <2>; clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>, @@ -170,7 +170,7 @@ }; esdhc3: esdhc@50020000 { - compatible = "fsl,imx50-esdhc"; + compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc"; reg = <0x50020000 0x4000>; interrupts = <3>; clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>, @@ -182,7 +182,7 @@ }; esdhc4: esdhc@50024000 { - compatible = "fsl,imx50-esdhc"; + compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc"; reg = <0x50024000 0x4000>; interrupts = <4>; clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>, diff --git a/sys/gnu/dts/arm/imx53-qsb.dts b/sys/gnu/dts/arm/imx53-qsb.dts index f4c158cce908..d3d662e37677 100644 --- a/sys/gnu/dts/arm/imx53-qsb.dts +++ b/sys/gnu/dts/arm/imx53-qsb.dts @@ -88,8 +88,8 @@ }; ldo7_reg: ldo7 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3600000>; + regulator-min-microvolt = <2750000>; + regulator-max-microvolt = <2750000>; }; ldo8_reg: ldo8 { diff --git a/sys/gnu/dts/arm/imx53-qsrb.dts b/sys/gnu/dts/arm/imx53-qsrb.dts index 479ca4c9e384..4e103a905dc9 100644 --- a/sys/gnu/dts/arm/imx53-qsrb.dts +++ b/sys/gnu/dts/arm/imx53-qsrb.dts @@ -23,7 +23,7 @@ imx53-qsrb { pinctrl_pmic: pmicgrp { fsl,pins = < - MX53_PAD_CSI0_DAT5__GPIO5_23 0x1e4 /* IRQ */ + MX53_PAD_CSI0_DAT5__GPIO5_23 0x1c4 /* IRQ */ >; }; }; @@ -128,8 +128,8 @@ vdac_reg: vdac { regulator-name = "VDAC"; - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2775000>; + regulator-min-microvolt = <2750000>; + regulator-max-microvolt = <2750000>; }; vgen1_reg: vgen1 { diff --git a/sys/gnu/dts/arm/imx6dl-gw5903.dts b/sys/gnu/dts/arm/imx6dl-gw5903.dts new file mode 100644 index 000000000000..103261ea9334 --- /dev/null +++ b/sys/gnu/dts/arm/imx6dl-gw5903.dts @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6dl.dtsi" +#include "imx6qdl-gw5903.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 Duallite/Solo GW5903"; + compatible = "gw,imx6dl-gw5903", "gw,ventana", "fsl,imx6dl"; +}; diff --git a/sys/gnu/dts/arm/imx6dl-gw5904.dts b/sys/gnu/dts/arm/imx6dl-gw5904.dts new file mode 100644 index 000000000000..9c6d3cd3d6a7 --- /dev/null +++ b/sys/gnu/dts/arm/imx6dl-gw5904.dts @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6dl.dtsi" +#include "imx6qdl-gw5904.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 DualLite/Solo GW5904"; + compatible = "gw,imx6dl-gw5904", "gw,ventana", "fsl,imx6dl"; +}; diff --git a/sys/gnu/dts/arm/imx6q-b450v3.dts b/sys/gnu/dts/arm/imx6q-b450v3.dts index 116bebb5e435..404a93d9596b 100644 --- a/sys/gnu/dts/arm/imx6q-b450v3.dts +++ b/sys/gnu/dts/arm/imx6q-b450v3.dts @@ -104,4 +104,11 @@ output-low; line-name = "PCA9539-P05"; }; + + P07 { + gpio-hog; + gpios = <7 0>; + output-low; + line-name = "PCA9539-P07"; + }; }; diff --git a/sys/gnu/dts/arm/imx6q-b650v3.dts b/sys/gnu/dts/arm/imx6q-b650v3.dts index 33f5c436c09f..7f9f176901d4 100644 --- a/sys/gnu/dts/arm/imx6q-b650v3.dts +++ b/sys/gnu/dts/arm/imx6q-b650v3.dts @@ -97,6 +97,13 @@ output-low; line-name = "PCA9539-P05"; }; + + P07 { + gpio-hog; + gpios = <7 0>; + output-low; + line-name = "PCA9539-P07"; + }; }; &usbphy1 { diff --git a/sys/gnu/dts/arm/imx6q-b850v3.dts b/sys/gnu/dts/arm/imx6q-b850v3.dts index d78514c92349..2c1e98e0cf7b 100644 --- a/sys/gnu/dts/arm/imx6q-b850v3.dts +++ b/sys/gnu/dts/arm/imx6q-b850v3.dts @@ -72,6 +72,14 @@ fsl,data-mapping = "spwg"; fsl,data-width = <24>; status = "okay"; + + port@4 { + reg = <4>; + + lvds0_out: endpoint { + remote-endpoint = <&stdp4028_in>; + }; + }; }; }; @@ -142,3 +150,65 @@ reg = <0x4a>; }; }; + +&mux2_i2c2 { + clock-frequency = <100000>; + + stdp2690@72 { + compatible = "megachips,stdp2690-ge-b850v3-fw"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + stdp2690_in: endpoint { + remote-endpoint = <&stdp4028_out>; + }; + }; + + port@1 { + reg = <1>; + + stdp2690_out: endpoint { + /* Connector for external display */ + }; + }; + }; + }; + + stdp4028@73 { + compatible = "megachips,stdp4028-ge-b850v3-fw"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + interrupt-parent = <&gpio2>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + stdp4028_in: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + + port@1 { + reg = <1>; + + stdp4028_out: endpoint { + remote-endpoint = <&stdp2690_in>; + }; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx6q-bx50v3.dtsi b/sys/gnu/dts/arm/imx6q-bx50v3.dtsi index 36d6bb39593a..c90b26f00e24 100644 --- a/sys/gnu/dts/arm/imx6q-bx50v3.dtsi +++ b/sys/gnu/dts/arm/imx6q-bx50v3.dtsi @@ -102,7 +102,7 @@ m25_eeprom: m25p80@0 { compatible = "atmel,at25"; - spi-max-frequency = <20000000>; + spi-max-frequency = <10000000>; size = <0x8000>; pagesize = <64>; reg = <0>; @@ -183,20 +183,6 @@ interrupt-parent = <&gpio2>; interrupts = <3 IRQ_TYPE_LEVEL_LOW>; - P06 { - gpio-hog; - gpios = <6 0>; - output-low; - line-name = "PCA9539-P06"; - }; - - P07 { - gpio-hog; - gpios = <7 0>; - output-low; - line-name = "PCA9539-P07"; - }; - P10 { gpio-hog; gpios = <8 0>; diff --git a/sys/gnu/dts/arm/imx6q-cm-fx6.dts b/sys/gnu/dts/arm/imx6q-cm-fx6.dts index d8a5789a4bc8..66cac5328b86 100644 --- a/sys/gnu/dts/arm/imx6q-cm-fx6.dts +++ b/sys/gnu/dts/arm/imx6q-cm-fx6.dts @@ -43,6 +43,7 @@ /dts-v1/; #include +#include #include "imx6q.dtsi" / { @@ -90,6 +91,34 @@ enable-active-high; }; + sound-analog { + compatible = "simple-audio-card"; + simple-audio-card,name = "On-board analog audio"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line Out", + "Microphone", "Mic Jack", + "Line", "Line In"; + simple-audio-card,routing = + "Headphone Jack", "RHPOUT", + "Headphone Jack", "LHPOUT", + "MICIN", "Mic Bias", + "Mic Bias", "Mic Jack"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,frame-master = <&sound_master>; + simple-audio-card,bitclock-inversion; + + sound_master: simple-audio-card,cpu { + sound-dai = <&ssi2>; + system-clock-frequency = <2822400>; + }; + + simple-audio-card,codec { + sound-dai = <&wm8731>; + }; + }; + sound-spdif { compatible = "fsl,imx-audio-spdif"; model = "imx-spdif"; @@ -99,6 +128,36 @@ }; }; +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; + + ssi2 { + fsl,audmux-port = <1>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_RCLKDIR | + IMX_AUDMUX_V2_PTCR_RCSEL(3 | 0x8) | + IMX_AUDMUX_V2_PTCR_TCLKDIR | + IMX_AUDMUX_V2_PTCR_TCSEL(3)) + IMX_AUDMUX_V2_PDCR_RXDSEL(3) + >; + }; + + audmux4 { + fsl,audmux-port = <3>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TFSEL(1) | + IMX_AUDMUX_V2_PTCR_RCLKDIR | + IMX_AUDMUX_V2_PTCR_RCSEL(1 | 0x8) | + IMX_AUDMUX_V2_PTCR_TCLKDIR | + IMX_AUDMUX_V2_PTCR_TCSEL(1)) + IMX_AUDMUX_V2_PDCR_RXDSEL(1) + >; + }; +}; + &cpu0 { /* * Although the imx6q fuse indicates that 1.2GHz operation is possible, @@ -160,9 +219,25 @@ reg = <0x50>; pagesize = <16>; }; + + wm8731: codec@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8731"; + reg = <0x1a>; + }; }; &iomuxc { + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__AUD4_RXC 0x17059 + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x17059 + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x17059 + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x17059 + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x17059 + >; + }; + pinctrl_ecspi1: ecspi1grp { fsl,pins = < MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1 @@ -279,6 +354,14 @@ status = "okay"; }; +&ssi2 { + assigned-clocks = <&clks IMX6QDL_CLK_SSI2_SEL>, + <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>; + assigned-clock-rates = <0>, <786432000>; + status = "okay"; +}; + &uart4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart4>; diff --git a/sys/gnu/dts/arm/imx6q-gw5903.dts b/sys/gnu/dts/arm/imx6q-gw5903.dts new file mode 100644 index 000000000000..a182e4cb0e6e --- /dev/null +++ b/sys/gnu/dts/arm/imx6q-gw5903.dts @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6q.dtsi" +#include "imx6qdl-gw5903.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 Dual/Quad GW5903"; + compatible = "gw,imx6q-gw5903", "gw,ventana", "fsl,imx6q"; +}; diff --git a/sys/gnu/dts/arm/imx6q-gw5904.dts b/sys/gnu/dts/arm/imx6q-gw5904.dts new file mode 100644 index 000000000000..ca1e2ae3341e --- /dev/null +++ b/sys/gnu/dts/arm/imx6q-gw5904.dts @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6q.dtsi" +#include "imx6qdl-gw5904.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 Dual/Quad GW5904"; + compatible = "gw,imx6q-gw5904", "gw,ventana", "fsl,imx6q"; +}; + +&sata { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/imx6q-icore-ofcap10.dts b/sys/gnu/dts/arm/imx6q-icore-ofcap10.dts new file mode 100644 index 000000000000..49b60ca20e6d --- /dev/null +++ b/sys/gnu/dts/arm/imx6q-icore-ofcap10.dts @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 Amarula Solutions B.V. + * Copyright (C) 2016 Engicam S.r.l. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-icore.dtsi" + +/ { + model = "Engicam i.CoreM6 Quad/Dual OpenFrame Capacitive touch 10.1 Kit"; + compatible = "engicam,imx6-icore", "fsl,imx6q"; +}; + +&ldb { + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <24>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <60000000>; + hactive = <1280>; + vactive = <800>; + hback-porch = <40>; + hfront-porch = <40>; + vback-porch = <10>; + vfront-porch = <3>; + hsync-len = <80>; + vsync-len = <10>; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx6q-icore-ofcap12.dts b/sys/gnu/dts/arm/imx6q-icore-ofcap12.dts new file mode 100644 index 000000000000..9e230f56c5fb --- /dev/null +++ b/sys/gnu/dts/arm/imx6q-icore-ofcap12.dts @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 Amarula Solutions B.V. + * Copyright (C) 2016 Engicam S.r.l. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-icore.dtsi" + +/ { + model = "Engicam i.CoreM6 Quad/Dual OpenFrame Capacitive touch 12 Kit"; + compatible = "engicam,imx6-icore", "fsl,imx6q"; +}; + +&ldb { + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <46800000>; + hactive = <1280>; + vactive = <480>; + hback-porch = <353>; + hfront-porch = <47>; + vback-porch = <39>; + vfront-porch = <4>; + hsync-len = <8>; + vsync-len = <2>; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx6q-icore.dts b/sys/gnu/dts/arm/imx6q-icore.dts index 59eb7adc2472..5613dd9dc469 100644 --- a/sys/gnu/dts/arm/imx6q-icore.dts +++ b/sys/gnu/dts/arm/imx6q-icore.dts @@ -57,3 +57,37 @@ &can2 { status = "okay"; }; + +&i2c1 { + max11801: touchscreen@48 { + compatible = "maxim,max11801"; + reg = <0x48>; + interrupt-parent = <&gpio3>; + interrupts = <31 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&ldb { + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <60000000>; + hactive = <800>; + vactive = <480>; + hback-porch = <30>; + hfront-porch = <30>; + vback-porch = <5>; + vfront-porch = <5>; + hsync-len = <64>; + vsync-len = <20>; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx6q-utilite-pro.dts b/sys/gnu/dts/arm/imx6q-utilite-pro.dts index 69bdd82ce21f..d900ad6ec5f8 100644 --- a/sys/gnu/dts/arm/imx6q-utilite-pro.dts +++ b/sys/gnu/dts/arm/imx6q-utilite-pro.dts @@ -101,9 +101,11 @@ hdmi-connector { compatible = "hdmi-connector"; - + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hpd>; type = "a"; ddc-i2c-bus = <&i2c_dvi_ddc>; + hpd-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; port { hdmi_connector_in: endpoint { @@ -209,6 +211,12 @@ >; }; + pinctrl_hpd: hpdgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 diff --git a/sys/gnu/dts/arm/imx6q-zii-rdu2.dts b/sys/gnu/dts/arm/imx6q-zii-rdu2.dts new file mode 100644 index 000000000000..b2d346640fd7 --- /dev/null +++ b/sys/gnu/dts/arm/imx6q-zii-rdu2.dts @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016-2017 Zodiac Inflight Innovations + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include + +/ { + model = "ZII RDU2 Board"; + compatible = "zii,imx6q-zii-rdu2", "fsl,imx6q"; +}; diff --git a/sys/gnu/dts/arm/imx6qdl-gw5903.dtsi b/sys/gnu/dts/arm/imx6qdl-gw5903.dtsi new file mode 100644 index 000000000000..444425153fc7 --- /dev/null +++ b/sys/gnu/dts/arm/imx6qdl-gw5903.dtsi @@ -0,0 +1,654 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +/ { + chosen { + stdout-path = &uart2; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 5000000>; + brightness-levels = < + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 + >; + default-brightness-level = <100>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led0: user1 { + label = "user1"; + gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ + default-state = "off"; + }; + }; + + memory { + reg = <0x10000000 0x40000000>; + }; + + reg_5p0v: regulator-5p0v { + compatible = "regulator-fixed"; + regulator-name = "5P0V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_usb_h1_vbus: regulator-usb-h1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 30 0>; + enable-active-high; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_12p0: regulator-12p0v { + compatible = "regulator-fixed"; + regulator-name = "12P0V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + sound { + compatible = "fsl,imx-audio-tlv320"; + model = "imx-tlv320"; + ssi-controller = <&ssi1>; + audio-codec = <&tlv320aic3105>; + /* routing of sink, source */ + audio-routing = + /* TLV320 LINE1L pin <-> Mic Jack connector */ + "LINE1L", "Mic Jack", + /* board Headphone Jack <-> HPOUT */ + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "Mic Jack", "Mic Bias"; + mux-int-port = <1>; + mux-ext-port = <6>; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pca9555: gpio@23 { + compatible = "nxp,pca9555"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + }; + + eeprom1: eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; + + eeprom2: eeprom@51 { + compatible = "atmel,24c02"; + reg = <0x51>; + pagesize = <16>; + }; + + eeprom3: eeprom@52 { + compatible = "atmel,24c02"; + reg = <0x52>; + pagesize = <16>; + }; + + eeprom4: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; + + dts1672: rtc@68 { + compatible = "dallas,ds1672"; + reg = <0x68>; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + ltc3676: pmic@3c { + compatible = "lltc,ltc3676"; + reg = <0x3c>; + interrupt-parent = <&gpio1>; + interrupts = <8 IRQ_TYPE_EDGE_FALLING>; + + regulators { + /* VDD_1P8 (1+R1/R2 = 2.505): Aud/eMMC/microSD/Touch */ + reg_1p8v: sw1 { + regulator-name = "vdd1p8"; + regulator-min-microvolt = <1033310>; + regulator-max-microvolt = <2004000>; + lltc,fb-voltage-divider = <301000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_DDR (1+R1/R2 = 2.105) */ + reg_vdd_ddr: sw2 { + regulator-name = "vddddr"; + regulator-min-microvolt = <868310>; + regulator-max-microvolt = <1684000>; + lltc,fb-voltage-divider = <221000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_ARM (1+R1/R2 = 1.635) */ + reg_vdd_arm: sw3 { + regulator-name = "vddarm"; + regulator-min-microvolt = <674400>; + regulator-max-microvolt = <1308000>; + lltc,fb-voltage-divider = <127000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <®_vdd_arm>; + }; + + /* VDD_SOC (1+R1/R2 = 1.635) */ + reg_vdd_soc: sw4 { + regulator-name = "vddsoc"; + regulator-min-microvolt = <674400>; + regulator-max-microvolt = <1308000>; + lltc,fb-voltage-divider = <127000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <®_vdd_soc>; + }; + + /* VDD_1P0 (1+R1/R2 = 1.38): */ + reg_1p0v: ldo2 { + regulator-name = "vdd1p0"; + regulator-min-microvolt = <1002777>; + regulator-max-microvolt = <1002777>; + lltc,fb-voltage-divider = <100000 261000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_HIGH (1+R1/R2 = 4.17) */ + reg_3p0v: ldo4 { + regulator-name = "vdd3p0"; + regulator-min-microvolt = <3023250>; + regulator-max-microvolt = <3023250>; + lltc,fb-voltage-divider = <634000 200000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + tlv320aic3105: codec@18 { + compatible = "ti,tlv320aic3x"; + reg = <0x18>; + gpio-reset = <&gpio5 17 GPIO_ACTIVE_LOW>; + clocks = <&clks IMX6QDL_CLK_CKO>; + ai3x-micbias-vg = <2>; /* MICBIAS_2_5V */ + /* Regulators */ + DRVDD-supply = <®_3p3v>; + AVDD-supply = <®_3p3v>; + IOVDD-supply = <®_3p3v>; + DVDD-supply = <®_1p8v>; + }; + + accelerometer@1d { + compatible = "fsl,mma8451"; + reg = <0x1d>; + interrupt-parent = <&gpio7>; + interrupts = <11 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "INT2"; + }; + + /* headphone detect */ + ts3a227e@3b { + compatible = "ti,ts3a227e"; + reg = <0x3b>; + interrupt-parent = <&gpio5>; + interrupts = <15 IRQ_TYPE_LEVEL_LOW>; + ti,micbias = <4>; /* 2.5V micbias */ + }; +}; + +&ldb { + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: g101evn010 { + clock-frequency = <68930000>; + hactive = <1280>; + vactive = <800>; + hback-porch = <220>; + hfront-porch = <40>; + vback-porch = <21>; + vfront-porch = <7>; + hsync-len = <60>; + vsync-len = <10>; + }; + }; + }; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "okay"; +}; + +&ssi1 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1_200mhz>; + vmmc-supply = <®_3p3v>; + non-removable; + bus-width = <4>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + cd-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_3p3v>; + max-frequency = <100000000>; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + non-removable; + vmmc-supply = <®_3p3v>; + keep-power-in-suspend; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; +}; + +&iomuxc { + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x130b0 + MX6QDL_PAD_DI0_PIN3__AUD6_TXFS 0x130b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x130b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x130b0 + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* MCK */ + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b030 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b030 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b030 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x4001b0b0 /* PHY_RST# */ + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x4001b0b0 /* PHY_EN */ + >; + }; + + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x0001b0b0 /* GSC_IRQ# */ + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0001b0b0 /* PMIC_IRQ# */ + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + /* I2C3 */ + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + + /* Headphone Detect */ + MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x0001b0b0 /* HPDET_IRQ# */ + MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x0001b0b0 /* HPDET_MIC# */ + + /* Codec */ + MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x0001b0b0 /* CODEC_RST# */ + + /* Touch Controller */ + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x0001b0b0 /* TOUCH_IRQ# */ + MX6QDL_PAD_KEY_COL1__GPIO4_IO08 0x0001b0b0 /* TOUCH_RST */ + + /* Stow Sensor */ + MX6QDL_PAD_GPIO_16__GPIO7_IO11 0x0001b0b0 /* ACCEL_IRQ2 */ + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x0001b0b0 /* ACCEL_IRQ1 */ + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT12__GPIO5_IO30 0x1b0b1 /* TXEN */ + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059 + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x4001b0b0 /* PWR_EN */ + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0 /* OC */ + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + fsl,pins = < + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x4001b0b0 /* EMMY_EN */ + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x4001b0b0 /* EMMY_CFG1# */ + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x4001b0b0 /* EMMY_CFG2# */ + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x0001b0b0 /* EMMY_BTWAKE# */ + MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x0001b0b0 /* EMMY_WFWAKE# */ + + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9 + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x100f9 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x17059 /* CD */ + MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x17059 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x170b9 + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x170b9 /* CD */ + MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x170b9 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x170f9 + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x170f9 /* CD */ + MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x170f9 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x100b9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x100f9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT8__WDOG1_B 0x1b0b0 + >; + }; +}; diff --git a/sys/gnu/dts/arm/imx6qdl-gw5904.dtsi b/sys/gnu/dts/arm/imx6qdl-gw5904.dtsi new file mode 100644 index 000000000000..fd4b68be9fe9 --- /dev/null +++ b/sys/gnu/dts/arm/imx6qdl-gw5904.dtsi @@ -0,0 +1,641 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +/ { + /* these are used by bootloader for disabling nodes */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + usb0 = &usbh1; + usb1 = &usbotg; + }; + + chosen { + stdout-path = &uart2; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm4 0 5000000>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <7>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led0: user1 { + label = "user1"; + gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + led1: user2 { + label = "user2"; + gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ + default-state = "off"; + }; + + led2: user3 { + label = "user3"; + gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ + default-state = "off"; + }; + }; + + memory { + reg = <0x10000000 0x40000000>; + }; + + pps { + compatible = "pps-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pps>; + gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; + }; + + reg_1p0v: regulator-1p0v { + compatible = "regulator-fixed"; + regulator-name = "1P0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_usb_h1_vbus: regulator-usb-h1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii-id"; + status = "okay"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "marvell,mv88e6085"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan4"; + }; + + port@1 { + reg = <1>; + label = "lan3"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan1"; + }; + + port@5 { + reg = <5>; + label = "cpu"; + ethernet = <&fec>; + }; + }; + }; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pca9555: gpio@23 { + compatible = "nxp,pca9555"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + }; + + eeprom1: eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; + + eeprom2: eeprom@51 { + compatible = "atmel,24c02"; + reg = <0x51>; + pagesize = <16>; + }; + + eeprom3: eeprom@52 { + compatible = "atmel,24c02"; + reg = <0x52>; + pagesize = <16>; + }; + + eeprom4: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; + + dts1672: rtc@68 { + compatible = "dallas,ds1672"; + reg = <0x68>; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + ltc3676: pmic@3c { + compatible = "lltc,ltc3676"; + reg = <0x3c>; + interrupt-parent = <&gpio1>; + interrupts = <8 IRQ_TYPE_EDGE_FALLING>; + + regulators { + /* VDD_SOC (1+R1/R2 = 1.635) */ + reg_vdd_soc: sw1 { + regulator-name = "vddsoc"; + regulator-min-microvolt = <674400>; + regulator-max-microvolt = <1308000>; + lltc,fb-voltage-divider = <127000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_1P8 (1+R1/R2 = 2.505): GbE switch */ + reg_1p8v: sw2 { + regulator-name = "vdd1p8"; + regulator-min-microvolt = <1033310>; + regulator-max-microvolt = <2004000>; + lltc,fb-voltage-divider = <301000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_ARM (1+R1/R2 = 1.635) */ + reg_vdd_arm: sw3 { + regulator-name = "vddarm"; + regulator-min-microvolt = <674400>; + regulator-max-microvolt = <1308000>; + lltc,fb-voltage-divider = <127000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_DDR (1+R1/R2 = 2.105) */ + reg_vdd_ddr: sw4 { + regulator-name = "vddddr"; + regulator-min-microvolt = <868310>; + regulator-max-microvolt = <1684000>; + lltc,fb-voltage-divider = <221000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_2P5 (1+R1/R2 = 3.435): PCIe/ENET-PHY */ + reg_2p5v: ldo2 { + regulator-name = "vdd2p5"; + regulator-min-microvolt = <2490375>; + regulator-max-microvolt = <2490375>; + lltc,fb-voltage-divider = <487000 200000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_HIGH (1+R1/R2 = 4.17) */ + reg_3p0v: ldo4 { + regulator-name = "vdd3p0"; + regulator-min-microvolt = <3023250>; + regulator-max-microvolt = <3023250>; + lltc,fb-voltage-divider = <634000 200000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + egalax_ts: touchscreen@4 { + compatible = "eeti,egalax_ts"; + reg = <0x04>; + interrupt-parent = <&gpio1>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + wakeup-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; +}; + +&ldb { + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: hsd100pxn1 { + clock-frequency = <65000000>; + hactive = <1024>; + vactive = <768>; + hback-porch = <220>; + hfront-porch = <40>; + vback-porch = <21>; + vfront-porch = <7>; + hsync-len = <60>; + vsync-len = <10>; + }; + }; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio1 0 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */ + status = "disabled"; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */ + status = "disabled"; +}; + +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm4>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + uart-has-rtscts; + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + non-removable; + vmmc-supply = <®_3p3v>; + keep-power-in-suspend; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; +}; + +&iomuxc { + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b030 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b030 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b030 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x4001b0b0 /* PHY_RST# */ + >; + }; + + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0 + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0 + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 /* PCIE RST */ + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0 /* PMIC_IRQ# */ + >; + }; + + pinctrl_pps: ppsgrp { + fsl,pins = < + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b1 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm3: pwm3grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm4: pwm4grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1 + MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1 + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* PWR_EN */ + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0 /* OC */ + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x100b9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x100f9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT8__WDOG1_B 0x1b0b0 + >; + }; +}; diff --git a/sys/gnu/dts/arm/imx6qdl-icore.dtsi b/sys/gnu/dts/arm/imx6qdl-icore.dtsi index 55bebfc9ad94..56d0c5d21cd0 100644 --- a/sys/gnu/dts/arm/imx6qdl-icore.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-icore.dtsi @@ -48,6 +48,13 @@ reg = <0x10000000 0x80000000>; }; + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm3 0 100000>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <7>; + }; + reg_3p3v: regulator-3p3v { compatible = "regulator-fixed"; regulator-name = "3P3V"; @@ -136,6 +143,12 @@ status = "okay"; }; +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; + status = "okay"; +}; + &uart4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart4>; @@ -246,6 +259,12 @@ >; }; + pinctrl_pwm3: pwm3grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + >; + }; + pinctrl_usbotg: usbotggrp { fsl,pins = < MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 diff --git a/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi b/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi index 63bf95ed8c88..58055ceec6dc 100644 --- a/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi @@ -548,6 +548,18 @@ status = "okay"; }; +®_arm { + vin-supply = <&sw1a_reg>; +}; + +®_pu { + vin-supply = <&sw1c_reg>; +}; + +®_soc { + vin-supply = <&sw1c_reg>; +}; + &snvs_poweroff { status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-zii-rdu2.dtsi b/sys/gnu/dts/arm/imx6qdl-zii-rdu2.dtsi new file mode 100644 index 000000000000..5d94b5ee6aa0 --- /dev/null +++ b/sys/gnu/dts/arm/imx6qdl-zii-rdu2.dtsi @@ -0,0 +1,932 @@ +/* + * Copyright (C) 2016-2017 Zodiac Inflight Innovations + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +/ { + chosen { + stdout-path = &uart1; + }; + + aliases { + mdio-gpio0 = &mdio1; + }; + + mdio1: mdio { + compatible = "virtual,mdio-gpio"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mdio1>; + gpios = <&gpio6 5 GPIO_ACTIVE_HIGH + &gpio6 4 GPIO_ACTIVE_HIGH>; + }; + + reg_28p0v: regulator-28p0v { + compatible = "regulator-fixed"; + regulator-name = "28V_IN"; + regulator-min-microvolt = <28000000>; + regulator-max-microvolt = <28000000>; + regulator-always-on; + }; + + reg_12p0v: regulator-12p0v { + compatible = "regulator-fixed"; + vin-supply = <®_28p0v>; + regulator-name = "12V_MAIN"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + reg_5p0v_main: regulator-5p0v-main { + compatible = "regulator-fixed"; + vin-supply = <®_12p0v>; + regulator-name = "5V_MAIN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_5p0v_user_usb: regulator-5p0v-user-usb { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_user_usb>; + vin-supply = <®_5p0v_main>; + regulator-name = "5V_USER_USB"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_LOW>; + startup-delay-us = <1000>; + }; + + reg_3p3v_pmic: regulator-3p3v-pmic { + compatible = "regulator-fixed"; + vin-supply = <®_12p0v>; + regulator-name = "PMIC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + vin-supply = <®_3p3v_pmic>; + regulator-name = "GEN_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_3p3v_sd: regulator-3p3v-sd { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_3p3v_sd>; + vin-supply = <®_3p3v>; + regulator-name = "3V3_SD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>; + startup-delay-us = <1000>; + enable-active-high; + regulator-always-on; + }; + + reg_3p3v_display: regulator-3p3v-display { + compatible = "regulator-fixed"; + vin-supply = <®_12p0v>; + regulator-name = "3V3_DISPLAY"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_3p3v_ssd: regulator-3p3v-ssd { + compatible = "regulator-fixed"; + vin-supply = <®_12p0v>; + regulator-name = "3V3_SSD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + sound1 { + compatible = "simple-audio-card"; + simple-audio-card,name = "Front"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound1_codec>; + simple-audio-card,frame-master = <&sound1_codec>; + simple-audio-card,widgets = + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Headphone Jack", "HPLEFT", + "Headphone Jack", "HPRIGHT", + "LEFTIN", "HPL", + "RIGHTIN", "HPR"; + simple-audio-card,aux-devs = <&hpa1>; + + sound1_cpu: simple-audio-card,cpu { + sound-dai = <&ssi2>; + }; + + sound1_codec: simple-audio-card,codec { + sound-dai = <&codec1>; + clocks = <&cs2000>; + }; + }; + + sound2 { + compatible = "simple-audio-card"; + simple-audio-card,name = "Back"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound2_codec>; + simple-audio-card,frame-master = <&sound2_codec>; + simple-audio-card,widgets = + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Headphone Jack", "HPLEFT", + "Headphone Jack", "HPRIGHT", + "LEFTIN", "HPL", + "RIGHTIN", "HPR"; + simple-audio-card,aux-devs = <&hpa2>; + + sound2_cpu: simple-audio-card,cpu { + sound-dai = <&ssi1>; + }; + + sound2_codec: simple-audio-card,codec { + sound-dai = <&codec2>; + clocks = <&cs2000>; + }; + }; + + panel { + power-supply = <®_3p3v_display>; + status = "disabled"; + + port { + panel_in: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + }; + + disp0: disp0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx-parallel-display"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_disp0>; + status = "disabled"; + + port@0 { + reg = <0>; + + disp0_in_0: endpoint { + remote-endpoint = <&ipu1_di0_disp0>; + }; + }; + + port@1 { + reg = <1>; + + disp0_out: endpoint { + remote-endpoint = <&tc358767_in>; + }; + }; + }; + + cs2000_ref: cs2000-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; + + cs2000_in_dummy: cs2000-in-dummy { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + edp_refclk: edp-refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; +}; + +®_arm { + vin-supply = <&sw1a_reg>; +}; + +®_pu { + vin-supply = <&sw1c_reg>; +}; + +®_soc { + vin-supply = <&sw1c_reg>; +}; + +&ldb { + lvds-channel@0 { + port@4 { + reg = <4>; + + lvds0_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; + linux,rs485-enabled-at-boot-time; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + status = "okay"; + + flash@0 { + compatible = "st,m25p128", "jedec,spi-nor"; + spi-max-frequency = <20000000>; + reg = <0>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + clock-frequency = <100000>; + status = "okay"; + + codec2: codec@18 { + compatible = "ti,tlv320dac3100"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_codec2>; + reg = <0x18>; + #sound-dai-cells = <0>; + HPVDD-supply = <®_3p3v>; + SPRVDD-supply = <®_3p3v>; + SPLVDD-supply = <®_3p3v>; + AVDD-supply = <®_3p3v>; + IOVDD-supply = <®_3p3v>; + DVDD-supply = <&vgen4_reg>; + gpio-reset = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + accel@1c { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_accel>; + compatible = "fsl,mma8451"; + reg = <0x1c>; + interrupt-parent = <&gpio1>; + interrupt-names = "int1", "int2"; + interrupts = <18 IRQ_TYPE_LEVEL_LOW>, <20 IRQ_TYPE_LEVEL_LOW>; + }; + + hpa2: amp@60 { + compatible = "ti,tpa6130a2"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tpa2>; + reg = <0x60>; + power-gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; + Vdd-supply = <®_5p0v_main>; + }; + + edp-bridge@68 { + compatible = "toshiba,tc358767"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tc358767>; + reg = <0x68>; + shutdown-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + clock-names = "ref"; + clocks = <&edp_refclk>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + tc358767_in: endpoint { + remote-endpoint = <&disp0_out>; + }; + }; + }; + }; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; + status = "okay"; + + pmic@08 { + compatible = "fsl,pfuze100"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pfuze100_irq>; + reg = <0x08>; + interrupt-parent = <&gpio7>; + interrupts = <13 IRQ_TYPE_LEVEL_LOW>; + + regulators { + sw1a_reg: sw1ab { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw1c_reg: sw1c { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3a { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3b_reg: sw3b { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + vgen4_reg: vgen4 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vgen5_reg: vgen5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + vgen6_reg: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + }; + }; + + temp-sense@48 { + compatible = "national,lm75"; + reg = <0x48>; + }; + + cs2000: clkgen@4e { + compatible = "cirrus,cs2000-cp"; + reg = <0x4e>; + #clock-cells = <0>; + clock-names = "clk_in", "ref_clk"; + clocks = <&cs2000_in_dummy>, <&cs2000_ref>; + assigned-clocks = <&cs2000>; + assigned-clock-rates = <24000000>; + }; + + eeprom@54 { + compatible = "at,24c128"; + reg = <0x54>; + }; + + rtc@68 { + compatible = "dallas,ds1341"; + reg = <0x68>; + }; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <400000>; + status = "okay"; + + codec1: codec@18 { + compatible = "ti,tlv320dac3100"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_codec1>; + reg = <0x18>; + #sound-dai-cells = <0>; + HPVDD-supply = <®_3p3v>; + SPRVDD-supply = <®_3p3v>; + SPLVDD-supply = <®_3p3v>; + AVDD-supply = <®_3p3v>; + IOVDD-supply = <®_3p3v>; + DVDD-supply = <&vgen4_reg>; + gpio-reset = <&gpio1 0 GPIO_ACTIVE_HIGH>; + }; + + touchscreen@20 { + compatible = "syna,rmi4-i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ts>; + reg = <0x20>; + interrupt-parent = <&gpio1>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; + vdd-supply = <®_5p0v_main>; + vio-supply = <®_3p3v>; + + #address-cells = <1>; + #size-cells = <0>; + + rmi4-f01@1 { + reg = <0x1>; + syna,nosleep-mode = <1>; + }; + + rmi4-f11@11 { + reg = <0x11>; + touchscreen-inverted-y; + touchscreen-swapped-x-y; + syna,sensor-type = <1>; + }; + + rmi4-f12@12 { + reg = <0x12>; + touchscreen-inverted-y; + touchscreen-swapped-x-y; + syna,sensor-type = <1>; + }; + }; + + hpa1: amp@60 { + compatible = "ti,tpa6130a2"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tpa1>; + reg = <0x60>; + power-gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>; + Vdd-supply = <®_5p0v_main>; + }; +}; + +&ipu1_di0_disp0 { + remote-endpoint = <&disp0_in_0>; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + bus-width = <4>; + cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>; + vmmc-supply = <®_3p3v_sd>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <4>; + cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + vmmc-supply = <®_3p3v_sd>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; + +&usdhc4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc4>; + bus-width = <8>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; + +&sata { + target-supply = <®_3p3v_ssd>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rmii"; + phy-reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; + phy-reset-duration = <100>; + phy-supply = <®_3p3v>; + status = "okay"; + + fixed-link { + speed = <100>; + full-duplex; + }; +}; + +&usbh1 { + vbus-supply = <®_5p0v_main>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_5p0v_user_usb>; + disable-over-current; + dr_mode = "host"; + status = "okay"; +}; + +&ssi1 { + status = "okay"; +}; + +&ssi2 { + status = "okay"; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; + + ssi1 { + fsl,audmux-port = <0>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_SYN | + IMX_AUDMUX_V2_PTCR_TFSEL(2) | + IMX_AUDMUX_V2_PTCR_TCSEL(2) | + IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TCLKDIR) + IMX_AUDMUX_V2_PDCR_RXDSEL(2) + >; + }; + + aud3 { + fsl,audmux-port = <2>; + fsl,port-config = < + IMX_AUDMUX_V2_PTCR_SYN + IMX_AUDMUX_V2_PDCR_RXDSEL(0) + >; + }; + + ssi2 { + fsl,audmux-port = <1>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_SYN | + IMX_AUDMUX_V2_PTCR_TFSEL(4) | + IMX_AUDMUX_V2_PTCR_TCSEL(4) | + IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TCLKDIR) + IMX_AUDMUX_V2_PDCR_RXDSEL(4) + >; + }; + + aud5 { + fsl,audmux-port = <4>; + fsl,port-config = < + IMX_AUDMUX_V2_PTCR_SYN + IMX_AUDMUX_V2_PDCR_RXDSEL(1) + >; + }; +}; + +&iomuxc { + pinctrl_accel: accelgrp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__GPIO1_IO18 0x4001b000 + MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x4001b000 + >; + }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0 + MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x130b0 + MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0 + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0 + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x130b0 + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0 + >; + }; + + pinctrl_codec1: dac1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x40000038 + >; + }; + + pinctrl_codec2: dac2grp { + fsl,pins = < + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x40000038 + >; + }; + + pinctrl_disp0: disp0grp { + fsl,pins = < + MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x100f9 + MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x100f9 + MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x100f9 + MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x100f9 + MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x100f9 + MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x100f9 + MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x100f9 + MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x100f9 + MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x100f9 + MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x100f9 + MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x100f9 + MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x100f9 + MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x100f9 + MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x100f9 + MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x100f9 + MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x100f9 + MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x100f9 + MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x100f9 + MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x100f9 + MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x100f9 + MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x100f9 + MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x100f9 + MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x100f9 + MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x100f9 + MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x100f9 + MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x100f9 + MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x100f9 + MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x100f9 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1 + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1 + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b1 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x000b1 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b1 + MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x100f5 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x100f5 + MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x100c0 + MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x100c0 + MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x100f5 + MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x100f5 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x40010040 + MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x100b0 + MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_mdio1: bitbangmdiogrp { + fsl,pins = < + /* Bitbang MDIO for DEB Switch */ + MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05 0x4001b030 + MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x40018830 + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x10038 + >; + }; + + pinctrl_pfuze100_irq: pfuze100grp { + fsl,pins = < + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x40010000 + >; + }; + + pinctrl_reg_3p3v_sd: mmcsupply1grp { + fsl,pins = < + MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x858 + >; + }; + + pinctrl_reg_user_usb: usbotggrp { + fsl,pins = < + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x40000038 + >; + }; + + pinctrl_rmii_phy_irq: phygrp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x40010000 + >; + }; + + pinctrl_tc358767: tc358767grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x10 + >; + }; + + pinctrl_tpa1: tpa6130-1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x40000038 + >; + }; + + pinctrl_tpa2: tpa6130-2grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x40000038 + >; + }; + + pinctrl_ts: tsgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0 + MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x1b0b0 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x10059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10069 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x40010040 + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x40010040 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x10059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10069 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x40010040 + MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x40010040 + + >; + }; + + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059 + MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x1b0b1 + >; + }; +}; diff --git a/sys/gnu/dts/arm/imx6qdl.dtsi b/sys/gnu/dts/arm/imx6qdl.dtsi index 6d7bf6496117..e426faa9c243 100644 --- a/sys/gnu/dts/arm/imx6qdl.dtsi +++ b/sys/gnu/dts/arm/imx6qdl.dtsi @@ -197,7 +197,7 @@ arm,shared-override; }; - pcie: pcie@0x01000000 { + pcie: pcie@1ffc000 { compatible = "fsl,imx6q-pcie", "snps,dw-pcie"; reg = <0x01ffc000 0x04000>, <0x01f00000 0x80000>; @@ -205,6 +205,7 @@ #address-cells = <3>; #size-cells = <2>; device_type = "pci"; + bus-range = <0x00 0xff>; ranges = <0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */ num-lanes = <1>; diff --git a/sys/gnu/dts/arm/imx6qp-nitrogen6_som2.dts b/sys/gnu/dts/arm/imx6qp-nitrogen6_som2.dts new file mode 100644 index 000000000000..011726c836cd --- /dev/null +++ b/sys/gnu/dts/arm/imx6qp-nitrogen6_som2.dts @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Boundary Devices, Inc. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6qp.dtsi" +#include "imx6qdl-nitrogen6_som2.dtsi" + +/ { + model = "Boundary Devices i.MX6 Quad Plus Nitrogen6_SOM2 Board"; + compatible = "boundary,imx6qp-nitrogen6_som2", "fsl,imx6qp"; +}; + +&sata { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/imx6qp-sabresd.dts b/sys/gnu/dts/arm/imx6qp-sabresd.dts index b23458062f5e..a8a5004dd9c8 100644 --- a/sys/gnu/dts/arm/imx6qp-sabresd.dts +++ b/sys/gnu/dts/arm/imx6qp-sabresd.dts @@ -50,8 +50,8 @@ compatible = "fsl,imx6qp-sabresd", "fsl,imx6qp"; }; -&cpu0 { - arm-supply = <&sw2_reg>; +®_arm { + vin-supply = <&sw2_reg>; }; &iomuxc { diff --git a/sys/gnu/dts/arm/imx6qp-zii-rdu2.dts b/sys/gnu/dts/arm/imx6qp-zii-rdu2.dts new file mode 100644 index 000000000000..882b3bd97e07 --- /dev/null +++ b/sys/gnu/dts/arm/imx6qp-zii-rdu2.dts @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016-2017 Zodiac Inflight Innovations + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include + +/ { + model = "ZII RDU2+ Board"; + compatible = "zii,imx6qp-zii-rdu2", "fsl,imx6qp"; +}; diff --git a/sys/gnu/dts/arm/imx6qp.dtsi b/sys/gnu/dts/arm/imx6qp.dtsi index 24d071f5d9cd..59453f2ac4ba 100644 --- a/sys/gnu/dts/arm/imx6qp.dtsi +++ b/sys/gnu/dts/arm/imx6qp.dtsi @@ -56,40 +56,59 @@ clocks = <&clks IMX6QDL_CLK_OCRAM>; }; - ipu1: ipu@02400000 { - compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; - clocks = <&clks IMX6QDL_CLK_IPU1>, - <&clks IMX6QDL_CLK_IPU1_DI0>, <&clks IMX6QDL_CLK_IPU1_DI1>, - <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>, - <&clks IMX6QDL_CLK_LDB_DI0_PODF>, <&clks IMX6QDL_CLK_LDB_DI1_PODF>, - <&clks IMX6QDL_CLK_PRG0_APB>; - clock-names = "bus", - "di0", "di1", - "di0_sel", "di1_sel", - "ldb_di0", "ldb_di1", "prg"; - }; - - ipu2: ipu@02800000 { - compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; - clocks = <&clks IMX6QDL_CLK_IPU2>, - <&clks IMX6QDL_CLK_IPU2_DI0>, <&clks IMX6QDL_CLK_IPU2_DI1>, - <&clks IMX6QDL_CLK_IPU2_DI0_SEL>, <&clks IMX6QDL_CLK_IPU2_DI1_SEL>, - <&clks IMX6QDL_CLK_LDB_DI0_PODF>, <&clks IMX6QDL_CLK_LDB_DI1_PODF>, - <&clks IMX6QDL_CLK_PRG1_APB>; - clock-names = "bus", - "di0", "di1", - "di0_sel", "di1_sel", - "ldb_di0", "ldb_di1", "prg"; - }; - - pcie: pcie@0x01000000 { - compatible = "fsl,imx6qp-pcie", "snps,dw-pcie"; - }; - aips-bus@02100000 { - mmdc0: mmdc@021b0000 { /* MMDC0 */ - compatible = "fsl,imx6qp-mmdc", "fsl,imx6q-mmdc"; - reg = <0x021b0000 0x4000>; + pre1: pre@21c8000 { + compatible = "fsl,imx6qp-pre"; + reg = <0x021c8000 0x1000>; + interrupts = ; + clocks = <&clks IMX6QDL_CLK_PRE0>; + clock-names = "axi"; + fsl,iram = <&ocram2>; + }; + + pre2: pre@21c9000 { + compatible = "fsl,imx6qp-pre"; + reg = <0x021c9000 0x1000>; + interrupts = ; + clocks = <&clks IMX6QDL_CLK_PRE1>; + clock-names = "axi"; + fsl,iram = <&ocram2>; + }; + + pre3: pre@21ca000 { + compatible = "fsl,imx6qp-pre"; + reg = <0x021ca000 0x1000>; + interrupts = ; + clocks = <&clks IMX6QDL_CLK_PRE2>; + clock-names = "axi"; + fsl,iram = <&ocram3>; + }; + + pre4: pre@21cb000 { + compatible = "fsl,imx6qp-pre"; + reg = <0x021cb000 0x1000>; + interrupts = ; + clocks = <&clks IMX6QDL_CLK_PRE3>; + clock-names = "axi"; + fsl,iram = <&ocram3>; + }; + + prg1: prg@21cc000 { + compatible = "fsl,imx6qp-prg"; + reg = <0x021cc000 0x1000>; + clocks = <&clks IMX6QDL_CLK_PRG0_APB>, + <&clks IMX6QDL_CLK_PRG0_AXI>; + clock-names = "ipg", "axi"; + fsl,pres = <&pre1>, <&pre2>, <&pre3>; + }; + + prg2: prg@21cd000 { + compatible = "fsl,imx6qp-prg"; + reg = <0x021cd000 0x1000>; + clocks = <&clks IMX6QDL_CLK_PRG1_APB>, + <&clks IMX6QDL_CLK_PRG1_AXI>; + clock-names = "ipg", "axi"; + fsl,pres = <&pre4>, <&pre2>, <&pre3>; }; }; }; @@ -101,6 +120,16 @@ <0 119 IRQ_TYPE_LEVEL_HIGH>; }; +&ipu1 { + compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; + fsl,prg = <&prg1>; +}; + +&ipu2 { + compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; + fsl,prg = <&prg2>; +}; + &ldb { clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>, @@ -110,3 +139,11 @@ "di0_sel", "di1_sel", "di2_sel", "di3_sel", "di0", "di1"; }; + +&mmdc0 { + compatible = "fsl,imx6qp-mmdc", "fsl,imx6q-mmdc"; +}; + +&pcie { + compatible = "fsl,imx6qp-pcie", "snps,dw-pcie"; +}; diff --git a/sys/gnu/dts/arm/imx6sx-sdb.dts b/sys/gnu/dts/arm/imx6sx-sdb.dts index 5bb8fd57e7f5..d71da30c9cff 100644 --- a/sys/gnu/dts/arm/imx6sx-sdb.dts +++ b/sys/gnu/dts/arm/imx6sx-sdb.dts @@ -12,23 +12,6 @@ model = "Freescale i.MX6 SoloX SDB RevB Board"; }; -&cpu0 { - operating-points = < - /* kHz uV */ - 996000 1250000 - 792000 1175000 - 396000 1175000 - 198000 1175000 - >; - fsl,soc-operating-points = < - /* ARM kHz SOC uV */ - 996000 1250000 - 792000 1175000 - 396000 1175000 - 198000 1175000 - >; -}; - &i2c1 { clock-frequency = <100000>; pinctrl-names = "default"; diff --git a/sys/gnu/dts/arm/imx6sx.dtsi b/sys/gnu/dts/arm/imx6sx.dtsi index dd4ec85ecbaa..3f1416be4c36 100644 --- a/sys/gnu/dts/arm/imx6sx.dtsi +++ b/sys/gnu/dts/arm/imx6sx.dtsi @@ -297,7 +297,8 @@ }; uart1: serial@02020000 { - compatible = "fsl,imx6sx-uart", "fsl,imx21-uart"; + compatible = "fsl,imx6sx-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x02020000 0x4000>; interrupts = ; clocks = <&clks IMX6SX_CLK_UART_IPG>, @@ -1053,7 +1054,8 @@ }; uart2: serial@021e8000 { - compatible = "fsl,imx6sx-uart", "fsl,imx21-uart"; + compatible = "fsl,imx6sx-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021e8000 0x4000>; interrupts = ; clocks = <&clks IMX6SX_CLK_UART_IPG>, @@ -1065,7 +1067,8 @@ }; uart3: serial@021ec000 { - compatible = "fsl,imx6sx-uart", "fsl,imx21-uart"; + compatible = "fsl,imx6sx-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021ec000 0x4000>; interrupts = ; clocks = <&clks IMX6SX_CLK_UART_IPG>, @@ -1077,7 +1080,8 @@ }; uart4: serial@021f0000 { - compatible = "fsl,imx6sx-uart", "fsl,imx21-uart"; + compatible = "fsl,imx6sx-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021f0000 0x4000>; interrupts = ; clocks = <&clks IMX6SX_CLK_UART_IPG>, @@ -1089,7 +1093,8 @@ }; uart5: serial@021f4000 { - compatible = "fsl,imx6sx-uart", "fsl,imx21-uart"; + compatible = "fsl,imx6sx-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021f4000 0x4000>; interrupts = ; clocks = <&clks IMX6SX_CLK_UART_IPG>, @@ -1229,7 +1234,8 @@ }; uart6: serial@022a0000 { - compatible = "fsl,imx6sx-uart", "fsl,imx21-uart"; + compatible = "fsl,imx6sx-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x022a0000 0x4000>; interrupts = ; clocks = <&clks IMX6SX_CLK_UART_IPG>, @@ -1281,7 +1287,7 @@ }; }; - pcie: pcie@0x08000000 { + pcie: pcie@8ffc000 { compatible = "fsl,imx6sx-pcie", "snps,dw-pcie"; reg = <0x08ffc000 0x4000>; /* DBI */ #address-cells = <3>; @@ -1293,6 +1299,7 @@ 0x81000000 0 0 0x08f80000 0 0x00010000 /* non-prefetchable memory */ 0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; + bus-range = <0x00 0xff>; num-lanes = <1>; interrupts = ; clocks = <&clks IMX6SX_CLK_PCIE_REF_125M>, diff --git a/sys/gnu/dts/arm/imx6ul-14x14-evk.dts b/sys/gnu/dts/arm/imx6ul-14x14-evk.dts index 00f98e5bfcaf..d2be8aa3370b 100644 --- a/sys/gnu/dts/arm/imx6ul-14x14-evk.dts +++ b/sys/gnu/dts/arm/imx6ul-14x14-evk.dts @@ -85,11 +85,6 @@ assigned-clock-rates = <786432000>; }; -&cpu0 { - arm-supply = <®_arm>; - soc-supply = <®_soc>; -}; - &i2c2 { clock_frequency = <100000>; pinctrl-names = "default"; @@ -125,10 +120,16 @@ ethphy0: ethernet-phy@2 { reg = <2>; + micrel,led-mode = <1>; + clocks = <&clks IMX6UL_CLK_ENET_REF>; + clock-names = "rmii-ref"; }; ethphy1: ethernet-phy@1 { reg = <1>; + micrel,led-mode = <1>; + clocks = <&clks IMX6UL_CLK_ENET2_REF>; + clock-names = "rmii-ref"; }; }; }; diff --git a/sys/gnu/dts/arm/imx6ul-geam.dtsi b/sys/gnu/dts/arm/imx6ul-geam.dtsi index 940aef67313b..eb94d956808b 100644 --- a/sys/gnu/dts/arm/imx6ul-geam.dtsi +++ b/sys/gnu/dts/arm/imx6ul-geam.dtsi @@ -49,6 +49,23 @@ reg = <0x80000000 0x08000000>; }; + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm8 0 100000>; + brightness-levels = < 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100>; + default-brightness-level = <100>; + }; + chosen { stdout-path = &uart1; }; @@ -143,12 +160,24 @@ display = <&display0>; }; +&pwm8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm8>; + status = "okay"; +}; + &tsc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_tsc>; xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; }; +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -290,6 +319,12 @@ >; }; + pinctrl_pwm8: pwm8grp { + fsl,pins = < + MX6UL_PAD_ENET1_RX_ER__PWM8_OUT 0x110b0 + >; + }; + pinctrl_tsc: tscgrp { fsl,pin = < MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0 @@ -299,6 +334,16 @@ >; }; + pinctrl_sai2: sai2grp { + fsl,pins = < + MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x130b0 + MX6UL_PAD_JTAG_TMS__CCM_CLKO1 0x4001b031 + MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088 + MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088 + MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x120b0 + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1 diff --git a/sys/gnu/dts/arm/imx6ul-isiot-common.dtsi b/sys/gnu/dts/arm/imx6ul-isiot-common.dtsi new file mode 100644 index 000000000000..2beaab6e272e --- /dev/null +++ b/sys/gnu/dts/arm/imx6ul-isiot-common.dtsi @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2016 Amarula Solutions B.V. + * Copyright (C) 2016 Engicam S.r.l. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +&i2c1 { + stmpe811: gpio-expander@44 { + compatible = "st,stmpe811"; + reg = <0x44>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_stmpe>; + interrupt-parent = <&gpio1>; + interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + stmpe: touchscreen { + compatible = "st,stmpe-ts"; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; + st,fraction-z = <7>; + st,i-drive = <1>; + }; + }; +}; + +&lcdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcdif_dat + &pinctrl_lcdif_ctrl>; + display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <16>; + bus-width = <18>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <28000000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <30>; + hback-porch = <30>; + hsync-len = <64>; + vback-porch = <5>; + vfront-porch = <5>; + vsync-len = <20>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; +}; + +&iomuxc { + pinctrl_lcdif_ctrl: lcdifctrlgrp { + fsl,pins = < + MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 + MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 + MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 + MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 + >; + }; + + pinctrl_lcdif_dat: lcdifdatgrp { + fsl,pins = < + MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 + MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 + MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 + MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 + MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 + MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 + MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 + MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 + MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 + MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 + MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 + MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 + MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 + MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 + MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 + MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 + MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 + MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 + >; + }; + + pinctrl_stmpe: stmpegrp { + fsl,pins = < + MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x1b0b0 + >; + }; +}; diff --git a/sys/gnu/dts/arm/imx6ul-isiot-emmc.dts b/sys/gnu/dts/arm/imx6ul-isiot-emmc.dts index f5b422898e61..73a1d0f0b9d5 100644 --- a/sys/gnu/dts/arm/imx6ul-isiot-emmc.dts +++ b/sys/gnu/dts/arm/imx6ul-isiot-emmc.dts @@ -43,6 +43,7 @@ /dts-v1/; #include "imx6ul-isiot.dtsi" +#include "imx6ul-isiot-common.dtsi" / { model = "Engicam Is.IoT MX6UL eMMC Starter kit"; diff --git a/sys/gnu/dts/arm/imx6ul-isiot-nand.dts b/sys/gnu/dts/arm/imx6ul-isiot-nand.dts index de15e1c75dd1..da29a86eb6a8 100644 --- a/sys/gnu/dts/arm/imx6ul-isiot-nand.dts +++ b/sys/gnu/dts/arm/imx6ul-isiot-nand.dts @@ -43,6 +43,7 @@ /dts-v1/; #include "imx6ul-isiot.dtsi" +#include "imx6ul-isiot-common.dtsi" / { model = "Engicam Is.IoT MX6UL NAND Starter kit"; diff --git a/sys/gnu/dts/arm/imx6ul-isiot.dtsi b/sys/gnu/dts/arm/imx6ul-isiot.dtsi index 0b43699af3e3..ea30380ad7a4 100644 --- a/sys/gnu/dts/arm/imx6ul-isiot.dtsi +++ b/sys/gnu/dts/arm/imx6ul-isiot.dtsi @@ -52,6 +52,49 @@ chosen { stdout-path = &uart1; }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm8 0 100000>; + brightness-levels = < 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100>; + default-brightness-level = <100>; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; +}; + +&i2c2 { + clock_frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&pwm8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm8>; + status = "okay"; +}; + +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + status = "okay"; }; &uart1 { @@ -72,6 +115,36 @@ }; &iomuxc { + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 + MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6UL_PAD_GPIO1_IO00__I2C2_SCL 0x4001b8b0 + MX6UL_PAD_GPIO1_IO01__I2C2_SDA 0x4001b8b0 + >; + }; + + pinctrl_pwm8: pwm8grp { + fsl,pins = < + MX6UL_PAD_ENET1_RX_ER__PWM8_OUT 0x110b0 + >; + }; + + pinctrl_sai2: sai2grp { + fsl,pins = < + MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x130b0 + MX6UL_PAD_JTAG_TMS__CCM_CLKO1 0x4001b031 + MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088 + MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088 + MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x120b0 + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1 diff --git a/sys/gnu/dts/arm/imx7-colibri-eval-v3.dtsi b/sys/gnu/dts/arm/imx7-colibri-eval-v3.dtsi index 373ee19196a6..18bebd6d8d47 100644 --- a/sys/gnu/dts/arm/imx7-colibri-eval-v3.dtsi +++ b/sys/gnu/dts/arm/imx7-colibri-eval-v3.dtsi @@ -44,11 +44,39 @@ chosen { stdout-path = "serial0:115200n8"; }; + + panel: panel { + compatible = "edt,et057090dhu"; + backlight = <&bl>; + power-supply = <®_3v3>; + + port { + panel_in: endpoint { + remote-endpoint = <&lcdif_out>; + }; + }; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; }; &bl { brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; + power-supply = <®_3v3>; + status = "okay"; }; @@ -75,32 +103,11 @@ }; &lcdif { - display = <&display0>; status = "okay"; - display0: lcd-display { - bits-per-pixel = <16>; - bus-width = <18>; - - display-timings { - native-mode = <&timing_vga>; - - /* Standard VGA timing */ - timing_vga: 640x480 { - clock-frequency = <25175000>; - hactive = <640>; - vactive = <480>; - hback-porch = <40>; - hfront-porch = <24>; - vback-porch = <32>; - vfront-porch = <11>; - hsync-len = <96>; - vsync-len = <2>; - de-active = <1>; - hsync-active = <0>; - vsync-active = <0>; - pixelclk-active = <0>; - }; + port { + lcdif_out: endpoint { + remote-endpoint = <&panel_in>; }; }; }; diff --git a/sys/gnu/dts/arm/imx7-colibri.dtsi b/sys/gnu/dts/arm/imx7-colibri.dtsi index a171545478be..2d87489f9105 100644 --- a/sys/gnu/dts/arm/imx7-colibri.dtsi +++ b/sys/gnu/dts/arm/imx7-colibri.dtsi @@ -60,13 +60,6 @@ regulator-max-microvolt = <3300000>; }; - reg_vref_1v8: regulator-vref-1v8 { - compatible = "regulator-fixed"; - regulator-name = "vref-1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - sound { compatible = "simple-audio-card"; simple-audio-card,name = "imx7-sgtl5000"; @@ -85,11 +78,11 @@ }; &adc1 { - vref-supply = <®_vref_1v8>; + vref-supply = <®_DCDC3>; }; &adc2 { - vref-supply = <®_vref_1v8>; + vref-supply = <®_DCDC3>; }; &cpu0 { @@ -151,29 +144,29 @@ regulators { reg_DCDC1: DCDC1 { /* V1.0_SOC */ - regulator-min-microvolt = <975000>; - regulator-max-microvolt = <1125000>; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; regulator-boot-on; regulator-always-on; }; reg_DCDC2: DCDC2 { /* V1.1_ARM */ - regulator-min-microvolt = <975000>; - regulator-max-microvolt = <1125000>; + regulator-min-microvolt = <975000>; + regulator-max-microvolt = <1100000>; regulator-boot-on; regulator-always-on; }; reg_DCDC3: DCDC3 { /* V1.8 */ - regulator-min-microvolt = <1775000>; - regulator-max-microvolt = <1825000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; regulator-boot-on; regulator-always-on; }; reg_DCDC4: DCDC4 { /* V1.35_DRAM */ - regulator-min-microvolt = <1325000>; - regulator-max-microvolt = <1375000>; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; regulator-boot-on; regulator-always-on; }; @@ -181,33 +174,33 @@ reg_LDO1: LDO1 { /* PWR_EN_+V3.3_ETH */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; - regulator-always-on; + regulator-boot-on; }; reg_LDO2: LDO2 { /* +V1.8_SD */ - regulator-min-microvolt = <1775000>; - regulator-max-microvolt = <3325000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; }; reg_LDO3: LDO3 { /* PWR_EN_+V3.3_LPSR */ - regulator-min-microvolt = <3275000>; - regulator-max-microvolt = <3325000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; }; reg_LDO4: LDO4 { /* V1.8_LPSR */ - regulator-min-microvolt = <1775000>; - regulator-max-microvolt = <1825000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; regulator-boot-on; regulator-always-on; }; reg_LDO5: LDO5 { /* PWR_EN_+V3.3 */ - regulator-min-microvolt = <1775000>; - regulator-max-microvolt = <1825000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; }; diff --git a/sys/gnu/dts/arm/imx7d-colibri-eval-v3.dts b/sys/gnu/dts/arm/imx7d-colibri-eval-v3.dts index bd01d2cc642d..a608a14d8c85 100644 --- a/sys/gnu/dts/arm/imx7d-colibri-eval-v3.dts +++ b/sys/gnu/dts/arm/imx7d-colibri-eval-v3.dts @@ -57,6 +57,7 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio4 7 GPIO_ACTIVE_LOW>; + vin-supply = <®_5v0>; }; }; diff --git a/sys/gnu/dts/arm/imx7d-sdb-sht11.dts b/sys/gnu/dts/arm/imx7d-sdb-sht11.dts new file mode 100644 index 000000000000..64a20ed1713a --- /dev/null +++ b/sys/gnu/dts/arm/imx7d-sdb-sht11.dts @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "imx7d-sdb.dts" + +/ { + sensor { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sensor>; + compatible = "sensirion,sht15"; + clk-gpios = <&gpio4 12 0>; + data-gpios = <&gpio4 13 0>; + vcc-supply = <®_sht15>; + }; + + reg_sht15: regulator-sht15 { + compatible = "regulator-fixed"; + regulator-name = "reg_sht15"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&i2c3 { + status = "disabled"; +}; + +&iomuxc { + pinctrl_sensor: sensorgrp { + fsl,pins = < + MX7D_PAD_I2C3_SDA__GPIO4_IO13 0x4000007f + MX7D_PAD_I2C3_SCL__GPIO4_IO12 0x4000007f + >; + }; +}; diff --git a/sys/gnu/dts/arm/imx7s.dtsi b/sys/gnu/dts/arm/imx7s.dtsi index 5d3a43b8de20..c4f12fd2e044 100644 --- a/sys/gnu/dts/arm/imx7s.dtsi +++ b/sys/gnu/dts/arm/imx7s.dtsi @@ -493,10 +493,9 @@ }; ocotp: ocotp-ctrl@30350000 { - compatible = "syscon"; + compatible = "fsl,imx7d-ocotp", "syscon"; reg = <0x30350000 0x10000>; - clocks = <&clks IMX7D_CLK_DUMMY>; - status = "disabled"; + clocks = <&clks IMX7D_OCOTP_CLK>; }; anatop: anatop@30360000 { @@ -559,7 +558,7 @@ }; src: src@30390000 { - compatible = "fsl,imx7d-src", "fsl,imx51-src", "syscon"; + compatible = "fsl,imx7d-src", "syscon"; reg = <0x30390000 0x10000>; interrupts = ; #reset-cells = <1>; diff --git a/sys/gnu/dts/arm/keystone-k2l-netcp.dtsi b/sys/gnu/dts/arm/keystone-k2l-netcp.dtsi index b6f26824e83a..66f615a74118 100644 --- a/sys/gnu/dts/arm/keystone-k2l-netcp.dtsi +++ b/sys/gnu/dts/arm/keystone-k2l-netcp.dtsi @@ -137,8 +137,8 @@ netcp: netcp@26000000 { /* NetCP address range */ ranges = <0 0x26000000 0x1000000>; - clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>, <&clkosr>; - clock-names = "pa_clk", "ethss_clk", "cpts", "osr_clk"; + clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>; + clock-names = "pa_clk", "ethss_clk", "cpts"; dma-coherent; ti,navigator-dmas = <&dma_gbe 0>, diff --git a/sys/gnu/dts/arm/keystone-k2l.dtsi b/sys/gnu/dts/arm/keystone-k2l.dtsi index b58e7ebc0919..148650406cf7 100644 --- a/sys/gnu/dts/arm/keystone-k2l.dtsi +++ b/sys/gnu/dts/arm/keystone-k2l.dtsi @@ -232,6 +232,14 @@ }; }; + osr: sram@70000000 { + compatible = "mmio-sram"; + reg = <0x70000000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&clkosr>; + }; + dspgpio0: keystone_dsp_gpio@02620240 { compatible = "ti,keystone-dsp-gpio"; gpio-controller; diff --git a/sys/gnu/dts/arm/logicpd-torpedo-37xx-devkit.dts b/sys/gnu/dts/arm/logicpd-torpedo-37xx-devkit.dts index 08cce17a25a0..43e9364083de 100644 --- a/sys/gnu/dts/arm/logicpd-torpedo-37xx-devkit.dts +++ b/sys/gnu/dts/arm/logicpd-torpedo-37xx-devkit.dts @@ -249,9 +249,9 @@ OMAP3_CORE1_IOPAD(0x2110, PIN_INPUT | MUX_MODE0) /* cam_xclka.cam_xclka */ OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT | MUX_MODE0) /* cam_pclk.cam_pclk */ - OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */ - OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */ - OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */ + OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */ + OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */ + OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */ OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE0) /* cam_d3.cam_d3 */ OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE0) /* cam_d4.cam_d4 */ OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE0) /* cam_d5.cam_d5 */ diff --git a/sys/gnu/dts/arm/meson8.dtsi b/sys/gnu/dts/arm/meson8.dtsi index 3f21e4fba42d..a3f05950000e 100644 --- a/sys/gnu/dts/arm/meson8.dtsi +++ b/sys/gnu/dts/arm/meson8.dtsi @@ -106,6 +106,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_cbus 0 0 120>; }; spi_nor_pins: nor { @@ -148,6 +149,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 120 16>; }; uart_ao_a_pins: uart_ao_a { diff --git a/sys/gnu/dts/arm/meson8b.dtsi b/sys/gnu/dts/arm/meson8b.dtsi index 41fd53671859..828aa49c678c 100644 --- a/sys/gnu/dts/arm/meson8b.dtsi +++ b/sys/gnu/dts/arm/meson8b.dtsi @@ -198,6 +198,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_cbus 0 0 130>; }; }; @@ -215,6 +216,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 130 16>; }; uart_ao_a_pins: uart_ao_a { diff --git a/sys/gnu/dts/arm/motorola-cpcap-mapphone.dtsi b/sys/gnu/dts/arm/motorola-cpcap-mapphone.dtsi new file mode 100644 index 000000000000..f5aeb3959afd --- /dev/null +++ b/sys/gnu/dts/arm/motorola-cpcap-mapphone.dtsi @@ -0,0 +1,243 @@ +/* + * Common CPCAP configuration used on Motorola phones + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +&mcspi1 { + cpcap: pmic@0 { + compatible = "motorola,cpcap", "st,6556002"; + reg = <0>; /* cs0 */ + interrupt-parent = <&gpio1>; + interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <2>; + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <3000000>; + spi-cs-high; + + cpcap_adc: adc { + compatible = "motorola,mapphone-cpcap-adc"; + interrupts-extended = <&cpcap 8 0>; + interrupt-names = "adcdone"; + #io-channel-cells = <1>; + }; + + cpcap_charger: charger { + compatible = "motorola,mapphone-cpcap-charger"; + interrupts-extended = < + &cpcap 13 0 &cpcap 12 0 &cpcap 29 0 &cpcap 28 0 + &cpcap 22 0 &cpcap 20 0 &cpcap 19 0 &cpcap 54 0 + >; + interrupt-names = + "chrg_det", "rvrs_chrg", "chrg_se1b", "se0conn", + "rvrs_mode", "chrgcurr1", "vbusvld", "battdetb"; + mode-gpios = <&gpio3 29 GPIO_ACTIVE_LOW + &gpio3 23 GPIO_ACTIVE_LOW>; + io-channels = <&cpcap_adc 0 &cpcap_adc 1 + &cpcap_adc 2 &cpcap_adc 5 + &cpcap_adc 6>; + io-channel-names = "battdetb", "battp", + "vbus", "chg_isense", + "batti"; + }; + + cpcap_regulator: regulator { + compatible = "motorola,mapphone-cpcap-regulator"; + + cpcap_regulators: regulators { + }; + }; + + cpcap_rtc: rtc { + compatible = "motorola,cpcap-rtc"; + + interrupt-parent = <&cpcap>; + interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>; + }; + + power_button: button { + compatible = "motorola,cpcap-pwrbutton"; + + interrupts = <23 IRQ_TYPE_NONE>; + }; + + cpcap_usb2_phy: phy { + compatible = "motorola,mapphone-cpcap-usb-phy"; + pinctrl-0 = <&usb_gpio_mux_sel1 &usb_gpio_mux_sel2>; + pinctrl-1 = <&usb_ulpi_pins>; + pinctrl-2 = <&usb_utmi_pins>; + pinctrl-3 = <&uart3_pins>; + pinctrl-names = "default", "ulpi", "utmi", "uart"; + #phy-cells = <0>; + interrupts-extended = < + &cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0 + &cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0 + &cpcap 48 1 + >; + interrupt-names = + "id_ground", "id_float", "se0conn", "vbusvld", + "sessvld", "sessend", "se1", "dm", "dp"; + mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH + &gpio1 0 GPIO_ACTIVE_HIGH>; + io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>; + io-channel-names = "vbus", "id"; + vusb-supply = <&vusb>; + }; + + led_red: led-red { + compatible = "motorola,cpcap-led-red"; + vdd-supply = <&sw5>; + label = "status-led:red"; + }; + + led_green: led-green { + compatible = "motorola,cpcap-led-green"; + vdd-supply = <&sw5>; + label = "status-led:green"; + }; + + led_blue: led-blue { + compatible = "motorola,cpcap-led-blue"; + vdd-supply = <&sw5>; + label = "status-led:blue"; + }; + + led_adl: led-adl { + compatible = "motorola,cpcap-led-adl"; + vdd-supply = <&sw5>; + label = "button-backlight"; + }; + + led_cp: led-cp { + compatible = "motorola,cpcap-led-cp"; + vdd-supply = <&sw5>; + label = "shift-key-light"; + }; + }; +}; + +&cpcap_regulators { + sw5: SW5 { + regulator-min-microvolt = <5050000>; + regulator-max-microvolt = <5050000>; + regulator-enable-ramp-delay = <50000>; + regulator-boot-on; + }; + + vcam: VCAM { + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-enable-ramp-delay = <1000>; + }; + + /* Used by DSS */ + vcsi: VCSI { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <1000>; + regulator-boot-on; + }; + + vdac: VDAC { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <1000>; + }; + + vdig: VDIG { + regulator-min-microvolt = <1875000>; + regulator-max-microvolt = <1875000>; + regulator-enable-ramp-delay = <1000>; + }; + + vfuse: VFUSE { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <3150000>; + regulator-enable-ramp-delay = <1000>; + }; + + vhvio: VHVIO { + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + }; + + /* Used by eMMC at mmc2 */ + vsdio: VSDIO { + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-enable-ramp-delay = <1000>; + }; + + vpll: VPLL { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <100>; + }; + + vrf1: VRF1 { + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + }; + + vrf2: VRF2 { + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + }; + + vrfref: VRFREF { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <100>; + }; + + vwlan1: VWLAN1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + regulator-enable-ramp-delay = <1000>; + }; + + /* Used by micro-SDIO at mmc1 */ + vwlan2: VWLAN2 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <1000>; + }; + + vsim: VSIM { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-enable-ramp-delay = <1000>; + }; + + vsimcard: VSIMCARD { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-enable-ramp-delay = <1000>; + }; + + vvib: VVIB { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <500>; + }; + + vusb: VUSB { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <1000>; + }; + + vaudio: VAUDIO { + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + }; +}; diff --git a/sys/gnu/dts/arm/moxart-uc7112lx.dts b/sys/gnu/dts/arm/moxart-uc7112lx.dts index 10d088df0c35..4a962a26482d 100644 --- a/sys/gnu/dts/arm/moxart-uc7112lx.dts +++ b/sys/gnu/dts/arm/moxart-uc7112lx.dts @@ -6,7 +6,7 @@ */ /dts-v1/; -/include/ "moxart.dtsi" +#include "moxart.dtsi" / { model = "MOXA UC-7112-LX"; diff --git a/sys/gnu/dts/arm/moxart.dtsi b/sys/gnu/dts/arm/moxart.dtsi index 1fd27ed65a01..e86f8c905ac5 100644 --- a/sys/gnu/dts/arm/moxart.dtsi +++ b/sys/gnu/dts/arm/moxart.dtsi @@ -6,6 +6,7 @@ */ /include/ "skeleton.dtsi" +#include / { compatible = "moxa,moxart"; @@ -36,8 +37,8 @@ ranges; intc: interrupt-controller@98800000 { - compatible = "moxa,moxart-ic"; - reg = <0x98800000 0x38>; + compatible = "moxa,moxart-ic", "faraday,ftintc010"; + reg = <0x98800000 0x100>; interrupt-controller; #interrupt-cells = <2>; interrupt-mask = <0x00080000>; @@ -59,15 +60,15 @@ timer: timer@98400000 { compatible = "moxa,moxart-timer"; reg = <0x98400000 0x42>; - interrupts = <19 1>; + interrupts = <19 IRQ_TYPE_EDGE_FALLING>; clocks = <&clk_apb>; }; gpio: gpio@98700000 { gpio-controller; #gpio-cells = <2>; - compatible = "moxa,moxart-gpio"; - reg = <0x98700000 0xC>; + compatible = "moxa,moxart-gpio", "faraday,ftgpio010"; + reg = <0x98700000 0x100>; }; rtc: rtc { @@ -80,7 +81,7 @@ dma: dma@90500000 { compatible = "moxa,moxart-dma"; reg = <0x90500080 0x40>; - interrupts = <24 0>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; #dma-cells = <1>; }; @@ -93,7 +94,7 @@ sdhci: sdhci@98e00000 { compatible = "moxa,moxart-sdhci"; reg = <0x98e00000 0x5C>; - interrupts = <5 0>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk_apb>; dmas = <&dma 5>, <&dma 5>; @@ -120,7 +121,7 @@ mac0: mac@90900000 { compatible = "moxa,moxart-mac"; reg = <0x90900000 0x90>; - interrupts = <25 0>; + interrupts = <25 IRQ_TYPE_LEVEL_HIGH>; phy-handle = <ðphy0>; phy-mode = "mii"; status = "disabled"; @@ -129,7 +130,7 @@ mac1: mac@92000000 { compatible = "moxa,moxart-mac"; reg = <0x92000000 0x90>; - interrupts = <27 0>; + interrupts = <27 IRQ_TYPE_LEVEL_HIGH>; phy-handle = <ðphy1>; phy-mode = "mii"; status = "disabled"; @@ -138,7 +139,7 @@ uart0: uart@98200000 { compatible = "ns16550a"; reg = <0x98200000 0x20>; - interrupts = <31 8>; + interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <4>; clock-frequency = <14745600>; diff --git a/sys/gnu/dts/arm/mt7623.dtsi b/sys/gnu/dts/arm/mt7623.dtsi index 402579ab70d2..3a9e9b6aea68 100644 --- a/sys/gnu/dts/arm/mt7623.dtsi +++ b/sys/gnu/dts/arm/mt7623.dtsi @@ -72,6 +72,8 @@ , , ; + clock-frequency = <13000000>; + arm,cpu-registers-not-fw-configured; }; watchdog: watchdog@10007000 { diff --git a/sys/gnu/dts/arm/omap3-cpu-thermal.dtsi b/sys/gnu/dts/arm/omap3-cpu-thermal.dtsi new file mode 100644 index 000000000000..235ecfd61e2d --- /dev/null +++ b/sys/gnu/dts/arm/omap3-cpu-thermal.dtsi @@ -0,0 +1,20 @@ +/* + * Device Tree Source for OMAP3 SoC CPU thermal + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include + +cpu_thermal: cpu_thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + coefficients = <0 20000>; + + /* sensor ID */ + thermal-sensors = <&bandgap 0>; +}; diff --git a/sys/gnu/dts/arm/omap3-gta04.dtsi b/sys/gnu/dts/arm/omap3-gta04.dtsi index b3a8b1f24499..9ec737069369 100644 --- a/sys/gnu/dts/arm/omap3-gta04.dtsi +++ b/sys/gnu/dts/arm/omap3-gta04.dtsi @@ -55,7 +55,8 @@ simple-audio-card,bitclock-master = <&telephony_link_master>; simple-audio-card,frame-master = <&telephony_link_master>; simple-audio-card,format = "i2s"; - + simple-audio-card,bitclock-inversion; + simple-audio-card,frame-inversion; simple-audio-card,cpu { sound-dai = <&mcbsp4>; }; diff --git a/sys/gnu/dts/arm/omap3-igep.dtsi b/sys/gnu/dts/arm/omap3-igep.dtsi index e268efde6c6d..4ad7d5565906 100644 --- a/sys/gnu/dts/arm/omap3-igep.dtsi +++ b/sys/gnu/dts/arm/omap3-igep.dtsi @@ -37,6 +37,13 @@ }; &omap3_pmx_core { + gpmc_pins: pinmux_gpmc_pins { + pinctrl-single,pins = < + /* OneNAND seems to require PIN_INPUT on clock. */ + OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */ + >; + }; + uart1_pins: pinmux_uart1_pins { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ @@ -98,6 +105,9 @@ }; &gpmc { + pinctrl-names = "default"; + pinctrl-0 = <&gpmc_pins>; + nand@0,0 { compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ @@ -126,6 +136,48 @@ #address-cells = <1>; #size-cells = <1>; + + status = "okay"; + }; + + onenand@0,0 { + compatible = "ti,omap2-onenand"; + reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ + + gpmc,sync-read; + gpmc,sync-write; + gpmc,burst-length = <16>; + gpmc,burst-read; + gpmc,burst-wrap; + gpmc,burst-write; + gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */ + gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */ + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <87>; + gpmc,cs-wr-off-ns = <87>; + gpmc,adv-on-ns = <0>; + gpmc,adv-rd-off-ns = <10>; + gpmc,adv-wr-off-ns = <10>; + gpmc,oe-on-ns = <15>; + gpmc,oe-off-ns = <87>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <87>; + gpmc,rd-cycle-ns = <112>; + gpmc,wr-cycle-ns = <112>; + gpmc,access-ns = <81>; + gpmc,page-burst-access-ns = <15>; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,wait-monitoring-ns = <0>; + gpmc,clk-activation-ns = <5>; + gpmc,wr-data-mux-bus-ns = <30>; + gpmc,wr-access-ns = <81>; + gpmc,sync-clk-ps = <15000>; + + #address-cells = <1>; + #size-cells = <1>; + + status = "disabled"; }; }; diff --git a/sys/gnu/dts/arm/omap3-n900.dts b/sys/gnu/dts/arm/omap3-n900.dts index b64cfda8dbb7..49f37084e435 100644 --- a/sys/gnu/dts/arm/omap3-n900.dts +++ b/sys/gnu/dts/arm/omap3-n900.dts @@ -155,6 +155,13 @@ compatible = "nokia,n900-ir"; pwms = <&pwm9 0 26316 0>; /* 38000 Hz */ }; + + /* controlled (enabled/disabled) directly by bcm2048 and wl1251 */ + vctcxo: vctcxo { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <38400000>; + }; }; &omap3_pmx_core { @@ -162,8 +169,10 @@ uart2_pins: pinmux_uart2_pins { pinctrl-single,pins = < - OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx */ + OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts */ + OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts */ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx */ + OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx */ >; }; @@ -920,6 +929,8 @@ interrupt-parent = <&gpio2>; interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */ + + clocks = <&vctcxo>; }; }; @@ -937,9 +948,17 @@ }; &uart2 { - interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; + + bcm2048: bluetooth { + compatible = "brcm,bcm2048-nokia", "nokia,h4p-bluetooth"; + reset-gpios = <&gpio3 27 GPIO_ACTIVE_LOW>; /* 91 */ + host-wakeup-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* 101 */ + bluetooth-wakeup-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* 37 */ + clocks = <&vctcxo>; + clock-names = "sysclk"; + }; }; &uart3 { diff --git a/sys/gnu/dts/arm/omap3-n950-n9.dtsi b/sys/gnu/dts/arm/omap3-n950-n9.dtsi index 5d8c4b4a4205..df3366fa5409 100644 --- a/sys/gnu/dts/arm/omap3-n950-n9.dtsi +++ b/sys/gnu/dts/arm/omap3-n950-n9.dtsi @@ -58,6 +58,13 @@ pinctrl-0 = <&debug_leds>; }; }; + + /* controlled (enabled/disabled) directly by wl1271 */ + vctcxo: vctcxo { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <38400000>; + }; }; &omap3_pmx_core { @@ -125,6 +132,15 @@ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE4) /* gpio_93 (cmt_apeslpx) */ >; }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts */ + OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts */ + OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx */ + OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx */ + >; + }; }; &omap3_pmx_core2 { @@ -435,3 +451,19 @@ &ssi_port2 { status = "disabled"; }; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + + bluetooth { + compatible = "ti,wl1271-bluetooth-nokia", "nokia,h4p-bluetooth"; + + reset-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; /* 26 */ + host-wakeup-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* 101 */ + bluetooth-wakeup-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* 37 */ + + clocks = <&vctcxo>; + clock-names = "sysclk"; + }; +}; diff --git a/sys/gnu/dts/arm/omap34xx.dtsi b/sys/gnu/dts/arm/omap34xx.dtsi index 834fdf13601f..ac4f8795b756 100644 --- a/sys/gnu/dts/arm/omap34xx.dtsi +++ b/sys/gnu/dts/arm/omap34xx.dtsi @@ -14,7 +14,7 @@ / { cpus { - cpu@0 { + cpu: cpu@0 { /* OMAP343x/OMAP35xx variants OPP1-5 */ operating-points = < /* kHz uV */ @@ -56,12 +56,16 @@ }; }; - bandgap@48002524 { + bandgap: bandgap@48002524 { reg = <0x48002524 0x4>; compatible = "ti,omap34xx-bandgap"; #thermal-sensor-cells = <0>; }; }; + + thermal_zones: thermal-zones { + #include "omap3-cpu-thermal.dtsi" + }; }; &ssi { diff --git a/sys/gnu/dts/arm/omap36xx.dtsi b/sys/gnu/dts/arm/omap36xx.dtsi index d1a3e56b50ce..ade31d74c70c 100644 --- a/sys/gnu/dts/arm/omap36xx.dtsi +++ b/sys/gnu/dts/arm/omap36xx.dtsi @@ -19,7 +19,7 @@ cpus { /* OMAP3630/OMAP37xx 'standard device' variants OPP50 to OPP130 */ - cpu@0 { + cpu: cpu@0 { operating-points = < /* kHz uV */ 300000 1012500 @@ -88,12 +88,16 @@ }; }; - bandgap@48002524 { + bandgap: bandgap@48002524 { reg = <0x48002524 0x4>; compatible = "ti,omap36xx-bandgap"; #thermal-sensor-cells = <0>; }; }; + + thermal_zones: thermal-zones { + #include "omap3-cpu-thermal.dtsi" + }; }; /* OMAP3630 needs dss_96m_fck for VENC */ diff --git a/sys/gnu/dts/arm/omap4-droid4-xt894.dts b/sys/gnu/dts/arm/omap4-droid4-xt894.dts index f3ccb4ceed9e..89eb607f4a9e 100644 --- a/sys/gnu/dts/arm/omap4-droid4-xt894.dts +++ b/sys/gnu/dts/arm/omap4-droid4-xt894.dts @@ -5,7 +5,9 @@ */ /dts-v1/; +#include #include "omap443x.dtsi" +#include "motorola-cpcap-mapphone.dtsi" / { model = "Motorola Droid 4 XT894"; @@ -15,35 +17,76 @@ stdout-path = &uart3; }; + aliases { + display0 = &lcd0; + display1 = &hdmi0; + }; + /* * We seem to have only 1021 MB accessible, 1021 - 1022 is locked, - * then 1023 - 1024 seems to contain mbm. For SRAM, see the notes - * below about SRAM and L3_ICLK2 being unused by default, + * then 1023 - 1024 seems to contain mbm. */ memory { device_type = "memory"; reg = <0x80000000 0x3fd00000>; /* 1021 MB */ }; - /* CPCAP really supports 1650000 to 3400000 range */ - vmmc: regulator-mmc { + /* Poweroff GPIO probably connected to CPCAP */ + gpio-poweroff { + compatible = "gpio-poweroff"; + pinctrl-0 = <&poweroff_gpio>; + pinctrl-names = "default"; + gpios = <&gpio2 18 GPIO_ACTIVE_LOW>; /* gpio50 */ + }; + + hdmi0: connector { + compatible = "hdmi-connector"; + pinctrl-0 = <&hdmi_hpd_gpio>; + pinctrl-names = "default"; + label = "hdmi"; + type = "d"; + + hpd-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>; /* gpio63 */ + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_out>; + }; + }; + }; + + /* + * HDMI 5V regulator probably sourced from battery. Let's keep + * keep this as always enabled for HDMI to work until we've + * figured what the encoder chip is. + */ + hdmi_regulator: regulator-hdmi { compatible = "regulator-fixed"; - regulator-name = "vmmc"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; + regulator-name = "hdmi"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio2 27 GPIO_ACTIVE_HIGH>; /* gpio59 */ + enable-active-high; regulator-always-on; }; - /* CPCAP really supports 3000000 to 3100000 range */ - vemmc: regulator-emmc { - compatible = "regulator-fixed"; - regulator-name = "vemmc"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-always-on; + /* HS USB Host PHY on PORT 1 */ + hsusb1_phy: hsusb1_phy { + compatible = "usb-nop-xceiv"; }; - /* CPCAP really supports 1650000 to 1950000 range */ + /* LCD regulator from sw5 source */ + lcd_regulator: regulator-lcd { + compatible = "regulator-fixed"; + regulator-name = "lcd"; + regulator-min-microvolt = <5050000>; + regulator-max-microvolt = <5050000>; + gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>; /* gpio96 */ + enable-active-high; + vin-supply = <&sw5>; + }; + + /* This is probably coming straight from the battery.. */ wl12xx_vmmc: regulator-wl12xx { compatible = "regulator-fixed"; regulator-name = "vwl1271"; @@ -53,21 +96,195 @@ startup-delay-us = <70000>; enable-active-high; }; + + gpio_keys { + compatible = "gpio-keys"; + + volume_down { + label = "Volume Down"; + gpios = <&gpio5 26 GPIO_ACTIVE_LOW>; /* gpio154 */ + linux,code = ; + linux,can-disable; + }; + + slider { + label = "Keypad Slide"; + gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */ + linux,input-type = ; + linux,code = ; + linux,can-disable; + + }; + }; }; -/* L3_2 interconnect is unused, SRAM, GPMC and L3_ICLK2 disabled */ -&gpmc { - status = "disabled"; +&dss { + status = "okay"; +}; + +&gpio6 { + touchscreen_reset { + gpio-hog; + gpios = <13 0>; + output-high; + line-name = "touchscreen-reset"; + }; +}; + +&dsi1 { + status = "okay"; + vdd-supply = <&vcsi>; + + port { + dsi1_out_ep: endpoint { + remote-endpoint = <&lcd0_in>; + lanes = <0 1 2 3 4 5>; + }; + }; + + lcd0: display { + compatible = "panel-dsi-cm"; + label = "lcd0"; + vddi-supply = <&lcd_regulator>; + reset-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* gpio101 */ + + panel-timing { + clock-frequency = <0>; /* Calculated by dsi */ + + hback-porch = <2>; + hactive = <540>; + hfront-porch = <0>; + hsync-len = <2>; + + vback-porch = <1>; + vactive = <960>; + vfront-porch = <0>; + vsync-len = <1>; + + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + + port { + lcd0_in: endpoint { + remote-endpoint = <&dsi1_out_ep>; + }; + }; + }; +}; + +&hdmi { + status = "okay"; + pinctrl-0 = <&dss_hdmi_pins>; + pinctrl-names = "default"; + vdda-supply = <&vdac>; + + port { + hdmi_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + lanes = <1 0 3 2 5 4 7 6>; + }; + }; +}; + +&i2c1 { + tmp105@48 { + compatible = "ti,tmp105"; + reg = <0x48>; + pinctrl-0 = <&tmp105_irq>; + pinctrl-names = "default"; + /* kpd_row0.gpio_178 */ + interrupts-extended = <&gpio6 18 IRQ_TYPE_EDGE_FALLING + &omap4_pmx_core 0x14e>; + interrupt-names = "irq", "wakeup"; + wakeup-source; + }; +}; + +&keypad { + keypad,num-rows = <8>; + keypad,num-columns = <8>; + linux,keymap = < + + /* Row 1 */ + MATRIX_KEY(0, 2, KEY_1) + MATRIX_KEY(0, 6, KEY_2) + MATRIX_KEY(2, 3, KEY_3) + MATRIX_KEY(0, 7, KEY_4) + MATRIX_KEY(0, 4, KEY_5) + MATRIX_KEY(5, 5, KEY_6) + MATRIX_KEY(0, 1, KEY_7) + MATRIX_KEY(0, 5, KEY_8) + MATRIX_KEY(0, 0, KEY_9) + MATRIX_KEY(1, 6, KEY_0) + + /* Row 2 */ + MATRIX_KEY(3, 4, KEY_APOSTROPHE) + MATRIX_KEY(7, 6, KEY_Q) + MATRIX_KEY(7, 7, KEY_W) + MATRIX_KEY(7, 2, KEY_E) + MATRIX_KEY(1, 0, KEY_R) + MATRIX_KEY(4, 4, KEY_T) + MATRIX_KEY(1, 2, KEY_Y) + MATRIX_KEY(6, 7, KEY_U) + MATRIX_KEY(2, 2, KEY_I) + MATRIX_KEY(5, 6, KEY_O) + MATRIX_KEY(3, 7, KEY_P) + MATRIX_KEY(6, 5, KEY_BACKSPACE) + + /* Row 3 */ + MATRIX_KEY(5, 4, KEY_TAB) + MATRIX_KEY(5, 7, KEY_A) + MATRIX_KEY(2, 7, KEY_S) + MATRIX_KEY(7, 0, KEY_D) + MATRIX_KEY(2, 6, KEY_F) + MATRIX_KEY(6, 2, KEY_G) + MATRIX_KEY(6, 6, KEY_H) + MATRIX_KEY(1, 4, KEY_J) + MATRIX_KEY(3, 1, KEY_K) + MATRIX_KEY(2, 1, KEY_L) + MATRIX_KEY(4, 6, KEY_ENTER) + + /* Row 4 */ + MATRIX_KEY(3, 6, KEY_LEFTSHIFT) /* KEY_CAPSLOCK */ + MATRIX_KEY(6, 1, KEY_Z) + MATRIX_KEY(7, 4, KEY_X) + MATRIX_KEY(5, 1, KEY_C) + MATRIX_KEY(1, 7, KEY_V) + MATRIX_KEY(2, 4, KEY_B) + MATRIX_KEY(4, 1, KEY_N) + MATRIX_KEY(1, 1, KEY_M) + MATRIX_KEY(3, 5, KEY_COMMA) + MATRIX_KEY(5, 2, KEY_DOT) + MATRIX_KEY(6, 3, KEY_UP) + MATRIX_KEY(7, 3, KEY_OK) + + /* Row 5 */ + MATRIX_KEY(2, 5, KEY_LEFTCTRL) /* KEY_LEFTSHIFT */ + MATRIX_KEY(4, 5, KEY_LEFTALT) /* SYM */ + MATRIX_KEY(6, 0, KEY_MINUS) + MATRIX_KEY(4, 7, KEY_EQUAL) + MATRIX_KEY(1, 5, KEY_SPACE) + MATRIX_KEY(3, 2, KEY_SLASH) + MATRIX_KEY(4, 3, KEY_LEFT) + MATRIX_KEY(5, 3, KEY_DOWN) + MATRIX_KEY(3, 3, KEY_RIGHT) + + /* Side buttons, KEY_VOLUMEDOWN and KEY_PWER are on CPCAP? */ + MATRIX_KEY(5, 0, KEY_VOLUMEUP) + >; }; &mmc1 { - vmmc-supply = <&vmmc>; + vmmc-supply = <&vwlan2>; bus-width = <4>; - cd-gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* gpio106 */ + cd-gpios = <&gpio6 16 GPIO_ACTIVE_LOW>; /* gpio176 */ }; &mmc2 { - vmmc-supply = <&vemmc>; + vmmc-supply = <&vsdio>; bus-width = <8>; non-removable; }; @@ -93,12 +310,78 @@ }; }; -/* L3_2 interconnect is unused, SRAM, GPMC and L3_ICLK2 disabled */ -&ocmcram { - status = "disabled"; +&i2c1 { + lm3532@38 { + compatible = "ti,lm3532"; + reg = <0x38>; + + enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; + + backlight { + compatible = "ti,lm3532-backlight"; + + lcd { + led-sources = <0 1 2>; + ramp-up-msec = <1>; + ramp-down-msec = <0>; + }; + }; + }; +}; + +/* + * REVISIT: Add gpio173 reset pin handling to the driver, see gpio-hog above. + * If the GPIO reset is used, we probably need to have /lib/firmware/maxtouch.fw + * available. See "mxt-app" and "droid4-touchscreen-firmware" tools for more + * information. + */ +&i2c2 { + tsp@4a { + compatible = "atmel,maxtouch"; + reg = <0x4a>; + pinctrl-names = "default"; + pinctrl-0 = <&touchscreen_pins>; + + /* gpio_183 with sys_nirq2 pad as wakeup */ + interrupts-extended = <&gpio6 23 IRQ_TYPE_EDGE_FALLING + &omap4_pmx_core 0x160>; + interrupt-names = "irq", "wakeup"; + wakeup-source; + }; }; &omap4_pmx_core { + + /* hdmi_hpd.gpio_63 */ + hdmi_hpd_gpio: pinmux_hdmi_hpd_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) + >; + }; + + /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */ + dss_hdmi_pins: pinmux_dss_hdmi_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) + OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) + OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) + >; + }; + + /* gpmc_ncs0.gpio_50 */ + poweroff_gpio: pinmux_poweroff_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x074, PIN_OUTPUT_PULLUP | MUX_MODE3) + >; + }; + + /* kpd_row0.gpio_178 */ + tmp105_irq: pinmux_tmp105_irq { + pinctrl-single,pins = < + OMAP4_IOPAD(0x18e, PIN_INPUT_PULLUP | MUX_MODE3) + >; + }; + usb_gpio_mux_sel1: pinmux_usb_gpio_mux_sel1_pins { /* gpio_60 */ pinctrl-single,pins = < @@ -106,6 +389,12 @@ >; }; + touchscreen_pins: pinmux_touchscreen_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE3) + >; + }; + usb_ulpi_pins: pinmux_usb_ulpi_pins { pinctrl-single,pins = < OMAP4_IOPAD(0x196, MUX_MODE7) @@ -180,9 +469,49 @@ &omap4_pmx_core 0x17c>; }; +&usbhsehci { + phys = <&hsusb1_phy>; +}; + +&usbhshost { + port1-mode = "ohci-phy-4pin-dpdm"; + port2-mode = "ehci-tll"; +}; + /* Internal UTMI+ PHY used for OTG, CPCAP ULPI PHY for detection and charger */ &usb_otg_hs { interface-type = <1>; mode = <3>; power = <50>; }; + +&i2c4 { + ak8975: magnetometer@c { + compatible = "asahi-kasei,ak8975"; + reg = <0x0c>; + + vdd-supply = <&vhvio>; + + interrupt-parent = <&gpio6>; + interrupts = <15 IRQ_TYPE_EDGE_RISING>; /* gpio175 */ + + rotation-matrix = "-1", "0", "0", + "0", "1", "0", + "0", "0", "-1"; + + }; + + lis3dh: accelerometer@18 { + compatible = "st,lis3dh-accel"; + reg = <0x18>; + + vdd-supply = <&vhvio>; + + interrupt-parent = <&gpio2>; + interrupts = <2 IRQ_TYPE_EDGE_BOTH>; /* gpio34 */ + + rotation-matrix = "0", "-1", "0", + "1", "0", "0", + "0", "0", "1"; + }; +}; diff --git a/sys/gnu/dts/arm/omap4-panda-a4.dts b/sys/gnu/dts/arm/omap4-panda-a4.dts index 78d363177762..f1a6476af371 100644 --- a/sys/gnu/dts/arm/omap4-panda-a4.dts +++ b/sys/gnu/dts/arm/omap4-panda-a4.dts @@ -13,7 +13,7 @@ /* Pandaboard Rev A4+ have external pullups on SCL & SDA */ &dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/sys/gnu/dts/arm/omap4-panda-es.dts b/sys/gnu/dts/arm/omap4-panda-es.dts index 119f8e657edc..940fe4f7c5f6 100644 --- a/sys/gnu/dts/arm/omap4-panda-es.dts +++ b/sys/gnu/dts/arm/omap4-panda-es.dts @@ -34,7 +34,7 @@ /* PandaboardES has external pullups on SCL & SDA */ &dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/sys/gnu/dts/arm/omap443x.dtsi b/sys/gnu/dts/arm/omap443x.dtsi index fc6a8610c24c..03c8ad91ddac 100644 --- a/sys/gnu/dts/arm/omap443x.dtsi +++ b/sys/gnu/dts/arm/omap443x.dtsi @@ -71,4 +71,8 @@ }; +&cpu_thermal { + coefficients = <0 20000>; +}; + /include/ "omap443x-clocks.dtsi" diff --git a/sys/gnu/dts/arm/omap4460.dtsi b/sys/gnu/dts/arm/omap4460.dtsi index ef66e12e0a67..c43f2a2d0a1e 100644 --- a/sys/gnu/dts/arm/omap4460.dtsi +++ b/sys/gnu/dts/arm/omap4460.dtsi @@ -90,4 +90,8 @@ }; +&cpu_thermal { + coefficients = <348 (-9301)>; +}; + /include/ "omap446x-clocks.dtsi" diff --git a/sys/gnu/dts/arm/omap5.dtsi b/sys/gnu/dts/arm/omap5.dtsi index 222155ca8ad7..eaff2a5751dd 100644 --- a/sys/gnu/dts/arm/omap5.dtsi +++ b/sys/gnu/dts/arm/omap5.dtsi @@ -1127,6 +1127,15 @@ &cpu_thermal { polling-delay = <500>; /* milliseconds */ + coefficients = <65 (-1791)>; }; /include/ "omap54xx-clocks.dtsi" + +&gpu_thermal { + coefficients = <117 (-2992)>; +}; + +&core_thermal { + coefficients = <0 2000>; +}; diff --git a/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts b/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts index 39d9e6ddefed..2da1413f5720 100644 --- a/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts +++ b/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts @@ -95,17 +95,17 @@ function = "sdc1"; }; clk { - pins = "gpio167"; /* SDC5 CLK */ + pins = "gpio167"; /* SDC1 CLK */ drive-strength = <16>; bias-disable; }; cmd { - pins = "gpio168"; /* SDC5 CMD */ + pins = "gpio168"; /* SDC1 CMD */ drive-strength = <10>; bias-pull-up; }; data { - /* SDC5 D0 to D7 */ + /* SDC1 D0 to D7 */ pins = "gpio159", "gpio160", "gpio161", "gpio162", "gpio163", "gpio164", "gpio165", "gpio166"; drive-strength = <10>; diff --git a/sys/gnu/dts/arm/qcom-msm8660.dtsi b/sys/gnu/dts/arm/qcom-msm8660.dtsi index 91c9a62ae725..747669a62aa8 100644 --- a/sys/gnu/dts/arm/qcom-msm8660.dtsi +++ b/sys/gnu/dts/arm/qcom-msm8660.dtsi @@ -392,6 +392,21 @@ cap-mmc-highspeed; }; + sdcc2: sdcc@12140000 { + status = "disabled"; + compatible = "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00051180>; + reg = <0x12140000 0x8000>; + interrupts = ; + interrupt-names = "cmd_irq"; + clocks = <&gcc SDC2_CLK>, <&gcc SDC2_H_CLK>; + clock-names = "mclk", "apb_pclk"; + bus-width = <8>; + max-frequency = <48000000>; + cap-sd-highspeed; + cap-mmc-highspeed; + }; + sdcc3: sdcc@12180000 { compatible = "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x00051180>; @@ -408,6 +423,21 @@ no-1-8-v; }; + sdcc4: sdcc@121c0000 { + compatible = "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00051180>; + status = "disabled"; + reg = <0x121c0000 0x8000>; + interrupts = ; + interrupt-names = "cmd_irq"; + clocks = <&gcc SDC4_CLK>, <&gcc SDC4_H_CLK>; + clock-names = "mclk", "apb_pclk"; + bus-width = <4>; + max-frequency = <48000000>; + cap-sd-highspeed; + cap-mmc-highspeed; + }; + sdcc5: sdcc@12200000 { compatible = "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x00051180>; diff --git a/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts b/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts index 96c853bab8ba..e7c1577d56f4 100644 --- a/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts +++ b/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts @@ -413,14 +413,6 @@ dma-controller@f9944000 { qcom,controlled-remotely; }; - - usb-phy@f9a55000 { - status = "ok"; - }; - - usb@f9a55000 { - status = "ok"; - }; }; &spmi_bus { diff --git a/sys/gnu/dts/arm/qcom-msm8974.dtsi b/sys/gnu/dts/arm/qcom-msm8974.dtsi index d3e1a61b8671..307bf6a647b3 100644 --- a/sys/gnu/dts/arm/qcom-msm8974.dtsi +++ b/sys/gnu/dts/arm/qcom-msm8974.dtsi @@ -2,8 +2,8 @@ #include #include +#include #include -#include #include "skeleton.dtsi" / { @@ -67,7 +67,7 @@ #size-cells = <0>; interrupts = <1 9 0xf04>; - cpu@0 { + CPU0: cpu@0 { compatible = "qcom,krait"; enable-method = "qcom,kpss-acc-v2"; device_type = "cpu"; @@ -78,7 +78,7 @@ cpu-idle-states = <&CPU_SPC>; }; - cpu@1 { + CPU1: cpu@1 { compatible = "qcom,krait"; enable-method = "qcom,kpss-acc-v2"; device_type = "cpu"; @@ -89,7 +89,7 @@ cpu-idle-states = <&CPU_SPC>; }; - cpu@2 { + CPU2: cpu@2 { compatible = "qcom,krait"; enable-method = "qcom,kpss-acc-v2"; device_type = "cpu"; @@ -100,7 +100,7 @@ cpu-idle-states = <&CPU_SPC>; }; - cpu@3 { + CPU3: cpu@3 { compatible = "qcom,krait"; enable-method = "qcom,kpss-acc-v2"; device_type = "cpu"; @@ -250,6 +250,9 @@ cx-supply = <&pm8841_s2>; + clocks = <&xo_board>; + clock-names = "xo"; + memory-region = <&adsp_region>; qcom,smem-states = <&adsp_smp2p_out 0>; @@ -695,42 +698,276 @@ qcom,ee = <0>; }; - usb1_phy: usb-phy@f9a55000 { - compatible = "qcom,usb-otg-snps"; + etr@fc322000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0xfc322000 0x1000>; - reg = <0xf9a55000 0x400>; - interrupts-extended = <&intc 0 134 0>, <&intc 0 140 0>, - <&spmi_bus 0 0x9 0 0>; - interrupt-names = "core_irq", "async_irq", "pmic_id_irq"; + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; - vddcx-supply = <&pm8841_s2>; - v3p3-supply = <&pm8941_l24>; - v1p8-supply = <&pm8941_l6>; - - dr_mode = "otg"; - qcom,phy-init-sequence = <0x63 0x81 0xfffffff>; - qcom,otg-control = <1>; - qcom,phy-num = <0>; - - resets = <&gcc GCC_USB2A_PHY_BCR>, <&gcc GCC_USB_HS_BCR>; - reset-names = "phy", "link"; - - clocks = <&gcc GCC_XO_CLK>, <&gcc GCC_USB_HS_SYSTEM_CLK>, - <&gcc GCC_USB_HS_AHB_CLK>; - clock-names = "phy", "core", "iface"; - - status = "disabled"; + port { + etr_in: endpoint { + slave-mode; + remote-endpoint = <&replicator_out0>; + }; + }; }; - usb@f9a55000 { - compatible = "qcom,ci-hdrc"; - reg = <0xf9a55000 0x400>; - dr_mode = "otg"; - interrupts = <0 134 0>, <0 140 0>; - interrupt-names = "core_irq", "async_irq"; - usb-phy = <&usb1_phy>; + tpiu@fc318000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + reg = <0xfc318000 0x1000>; - status = "disabled"; + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + port { + tpiu_in: endpoint { + slave-mode; + remote-endpoint = <&replicator_out1>; + }; + }; + }; + + replicator@fc31c000 { + compatible = "qcom,coresight-replicator1x", "arm,primecell"; + reg = <0xfc31c000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + replicator_out0: endpoint { + remote-endpoint = <&etr_in>; + }; + }; + port@1 { + reg = <1>; + replicator_out1: endpoint { + remote-endpoint = <&tpiu_in>; + }; + }; + port@2 { + reg = <0>; + replicator_in: endpoint { + slave-mode; + remote-endpoint = <&etf_out>; + }; + }; + }; + }; + + etf@fc307000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0xfc307000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + etf_out: endpoint { + remote-endpoint = <&replicator_in>; + }; + }; + port@1 { + reg = <0>; + etf_in: endpoint { + slave-mode; + remote-endpoint = <&merger_out>; + }; + }; + }; + }; + + funnel@fc31b000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0xfc31b000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* + * Not described input ports: + * 0 - connected trought funnel to Audio, Modem and + * Resource and Power Manager CPU's + * 2...7 - not-connected + */ + port@1 { + reg = <1>; + merger_in1: endpoint { + slave-mode; + remote-endpoint = <&funnel1_out>; + }; + }; + port@8 { + reg = <0>; + merger_out: endpoint { + remote-endpoint = <&etf_in>; + }; + }; + }; + }; + + funnel@fc31a000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0xfc31a000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* + * Not described input ports: + * 0 - not-connected + * 1 - connected trought funnel to Multimedia CPU + * 2 - connected to Wireless CPU + * 3 - not-connected + * 4 - not-connected + * 6 - not-connected + * 7 - connected to STM + */ + port@5 { + reg = <5>; + funnel1_in5: endpoint { + slave-mode; + remote-endpoint = <&kpss_out>; + }; + }; + port@8 { + reg = <0>; + funnel1_out: endpoint { + remote-endpoint = <&merger_in1>; + }; + }; + }; + }; + + funnel@fc345000 { /* KPSS funnel only 4 inputs are used */ + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0xfc345000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + kpss_in0: endpoint { + slave-mode; + remote-endpoint = <&etm0_out>; + }; + }; + port@1 { + reg = <1>; + kpss_in1: endpoint { + slave-mode; + remote-endpoint = <&etm1_out>; + }; + }; + port@2 { + reg = <2>; + kpss_in2: endpoint { + slave-mode; + remote-endpoint = <&etm2_out>; + }; + }; + port@3 { + reg = <3>; + kpss_in3: endpoint { + slave-mode; + remote-endpoint = <&etm3_out>; + }; + }; + port@8 { + reg = <0>; + kpss_out: endpoint { + remote-endpoint = <&funnel1_in5>; + }; + }; + }; + }; + + etm@fc33c000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0xfc33c000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + cpu = <&CPU0>; + + port { + etm0_out: endpoint { + remote-endpoint = <&kpss_in0>; + }; + }; + }; + + etm@fc33d000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0xfc33d000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + cpu = <&CPU1>; + + port { + etm1_out: endpoint { + remote-endpoint = <&kpss_in1>; + }; + }; + }; + + etm@fc33e000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0xfc33e000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + cpu = <&CPU2>; + + port { + etm2_out: endpoint { + remote-endpoint = <&kpss_in2>; + }; + }; + }; + + etm@fc33f000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0xfc33f000 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + + cpu = <&CPU3>; + + port { + etm3_out: endpoint { + remote-endpoint = <&kpss_in3>; + }; + }; }; }; @@ -760,6 +997,11 @@ compatible = "qcom,rpm-msm8974"; qcom,smd-channels = "rpm_requests"; + rpmcc: clock-controller { + compatible = "qcom,rpmcc-msm8974", "qcom,rpmcc"; + #clock-cells = <1>; + }; + pm8841-regulators { compatible = "qcom,rpm-pm8841-regulators"; diff --git a/sys/gnu/dts/arm/r7s72100-genmai.dts b/sys/gnu/dts/arm/r7s72100-genmai.dts index 118a8e2b86bd..52a7b586bac7 100644 --- a/sys/gnu/dts/arm/r7s72100-genmai.dts +++ b/sys/gnu/dts/arm/r7s72100-genmai.dts @@ -44,6 +44,10 @@ clock-frequency = <48000000>; }; +&rtc_x1_clk { + clock-frequency = <32768>; +}; + &mtu2 { status = "okay"; }; @@ -59,6 +63,10 @@ }; }; +&rtc { + status = "okay"; +}; + &scif2 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/r7s72100-rskrza1.dts b/sys/gnu/dts/arm/r7s72100-rskrza1.dts index 02b59c5b3c53..72df20a04320 100644 --- a/sys/gnu/dts/arm/r7s72100-rskrza1.dts +++ b/sys/gnu/dts/arm/r7s72100-rskrza1.dts @@ -43,6 +43,10 @@ clock-frequency = <48000000>; }; +&rtc_x1_clk { + clock-frequency = <32768>; +}; + &mtu2 { status = "okay"; }; @@ -69,6 +73,10 @@ status = "okay"; }; +&rtc { + status = "okay"; +}; + &scif2 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/r7s72100.dtsi b/sys/gnu/dts/arm/r7s72100.dtsi index b8aa256bd515..0423996e4dcc 100644 --- a/sys/gnu/dts/arm/r7s72100.dtsi +++ b/sys/gnu/dts/arm/r7s72100.dtsi @@ -51,6 +51,20 @@ clock-frequency = <0>; }; + rtc_x1_clk: rtc_x1 { + #clock-cells = <0>; + compatible = "fixed-clock"; + /* If clk present, value must be set by board to 32678 */ + clock-frequency = <0>; + }; + + rtc_x3_clk: rtc_x3 { + #clock-cells = <0>; + compatible = "fixed-clock"; + /* If clk present, value must be set by board to 4000000 */ + clock-frequency = <0>; + }; + /* Fixed factor clocks */ b_clk: b { #clock-cells = <0>; @@ -117,11 +131,20 @@ clock-output-names = "ostm0", "ostm1"; }; + mstp6_clks: mstp6_clks@fcfe042c { + #clock-cells = <1>; + compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0xfcfe042c 4>; + clocks = <&p0_clk>; + clock-indices = ; + clock-output-names = "rtc"; + }; + mstp7_clks: mstp7_clks@fcfe0430 { #clock-cells = <1>; compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0xfcfe0430 4>; - clocks = <&p0_clk>; + clocks = <&b_clk>; clock-indices = ; clock-output-names = "ether"; }; @@ -162,9 +185,12 @@ #clock-cells = <1>; compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0xfcfe0444 4>; - clocks = <&p1_clk>, <&p1_clk>; - clock-indices = ; - clock-output-names = "sdhi1", "sdhi0"; + clocks = <&p1_clk>, <&p1_clk>, <&p1_clk>, <&p1_clk>; + clock-indices = < + R7S72100_CLK_SDHI00 R7S72100_CLK_SDHI01 + R7S72100_CLK_SDHI10 R7S72100_CLK_SDHI11 + >; + clock-output-names = "sdhi00", "sdhi01", "sdhi10", "sdhi11"; }; }; @@ -177,6 +203,7 @@ compatible = "arm,cortex-a9"; reg = <0>; clock-frequency = <400000000>; + next-level-cache = <&L2>; }; }; @@ -368,6 +395,23 @@ <0xe8202000 0x1000>; }; + L2: cache-controller@3ffff000 { + compatible = "arm,pl310-cache"; + reg = <0x3ffff000 0x1000>; + interrupts = ; + arm,early-bresp-disable; + arm,full-line-zero-disable; + cache-unified; + cache-level = <2>; + }; + + wdt: watchdog@fcfe0000 { + compatible = "renesas,r7s72100-wdt", "renesas,rza-wdt"; + reg = <0xfcfe0000 0x6>; + interrupts = ; + clocks = <&p0_clk>; + }; + i2c0: i2c@fcfee000 { #address-cells = <1>; #size-cells = <0>; @@ -488,7 +532,10 @@ GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp12_clks R7S72100_CLK_SDHI0>; + clocks = <&mstp12_clks R7S72100_CLK_SDHI00>, + <&mstp12_clks R7S72100_CLK_SDHI01>; + clock-names = "core", "cd"; + power-domains = <&cpg_clocks>; cap-sd-highspeed; cap-sdio-irq; status = "disabled"; @@ -501,7 +548,10 @@ GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp12_clks R7S72100_CLK_SDHI1>; + clocks = <&mstp12_clks R7S72100_CLK_SDHI10>, + <&mstp12_clks R7S72100_CLK_SDHI11>; + clock-names = "core", "cd"; + power-domains = <&cpg_clocks>; cap-sd-highspeed; cap-sdio-irq; status = "disabled"; @@ -524,4 +574,18 @@ power-domains = <&cpg_clocks>; status = "disabled"; }; + + rtc: rtc@fcff1000 { + compatible = "renesas,r7s72100-rtc", "renesas,sh-rtc"; + reg = <0xfcff1000 0x2e>; + interrupts = ; + interrupt-names = "alarm", "period", "carry"; + clocks = <&mstp6_clks R7S72100_CLK_RTC>, <&rtc_x1_clk>, + <&rtc_x3_clk>, <&extal_clk>; + clock-names = "fck", "rtc_x1", "rtc_x3", "extal"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; }; diff --git a/sys/gnu/dts/arm/r8a73a4.dtsi b/sys/gnu/dts/arm/r8a73a4.dtsi index 00eb9a7114dc..1f5c9f6dddba 100644 --- a/sys/gnu/dts/arm/r8a73a4.dtsi +++ b/sys/gnu/dts/arm/r8a73a4.dtsi @@ -32,18 +32,16 @@ next-level-cache = <&L2_CA15>; }; - L2_CA15: cache-controller@0 { + L2_CA15: cache-controller-0 { compatible = "cache"; - reg = <0>; clocks = <&cpg_clocks R8A73A4_CLK_Z>; power-domains = <&pd_a3sm>; cache-unified; cache-level = <2>; }; - L2_CA7: cache-controller@100 { + L2_CA7: cache-controller-1 { compatible = "cache"; - reg = <0x100>; clocks = <&cpg_clocks R8A73A4_CLK_Z2>; power-domains = <&pd_a3km>; cache-unified; @@ -469,6 +467,9 @@ <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; interrupts = ; + clocks = <&mstp4_clks R8A73A4_CLK_INTC_SYS>; + clock-names = "clk"; + power-domains = <&pd_c4>; }; bsc: bus@fec10000 { @@ -727,16 +728,18 @@ mstp4_clks: mstp4_clks@e6150140 { compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>; - clocks = <&main_div2_clk>, <&main_div2_clk>, + clocks = <&main_div2_clk>, <&cpg_clocks R8A73A4_CLK_ZS>, + <&main_div2_clk>, <&cpg_clocks R8A73A4_CLK_HP>, <&cpg_clocks R8A73A4_CLK_HP>; #clock-cells = <1>; clock-indices = < - R8A73A4_CLK_IRQC R8A73A4_CLK_IIC5 - R8A73A4_CLK_IIC4 R8A73A4_CLK_IIC3 + R8A73A4_CLK_IRQC R8A73A4_CLK_INTC_SYS + R8A73A4_CLK_IIC5 R8A73A4_CLK_IIC4 + R8A73A4_CLK_IIC3 >; clock-output-names = - "irqc", "iic5", "iic4", "iic3"; + "irqc", "intc-sys", "iic5", "iic4", "iic3"; }; mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks"; diff --git a/sys/gnu/dts/arm/r8a7743.dtsi b/sys/gnu/dts/arm/r8a7743.dtsi index d8393b97768b..0ddac81742e4 100644 --- a/sys/gnu/dts/arm/r8a7743.dtsi +++ b/sys/gnu/dts/arm/r8a7743.dtsi @@ -32,9 +32,8 @@ next-level-cache = <&L2_CA15>; }; - L2_CA15: cache-controller@0 { + L2_CA15: cache-controller-0 { compatible = "cache"; - reg = <0>; cache-unified; cache-level = <2>; power-domains = <&sysc R8A7743_PD_CA15_SCU>; @@ -63,6 +62,7 @@ clocks = <&cpg CPG_MOD 408>; clock-names = "clk"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 408>; }; irqc: interrupt-controller@e61c0000 { @@ -82,6 +82,7 @@ ; clocks = <&cpg CPG_MOD 407>; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 407>; }; timer { @@ -103,6 +104,7 @@ clock-names = "extal", "usb_extal"; #clock-cells = <2>; #power-domain-cells = <0>; + #reset-cells = <1>; }; prr: chipid@ff000044 { @@ -149,6 +151,7 @@ clocks = <&cpg CPG_MOD 219>; clock-names = "fck"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 219>; #dma-cells = <1>; dma-channels = <15>; }; @@ -181,6 +184,7 @@ clocks = <&cpg CPG_MOD 218>; clock-names = "fck"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 218>; #dma-cells = <1>; dma-channels = <15>; }; @@ -196,6 +200,7 @@ <&dmac1 0x21>, <&dmac1 0x22>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 204>; status = "disabled"; }; @@ -210,6 +215,7 @@ <&dmac1 0x25>, <&dmac1 0x26>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 203>; status = "disabled"; }; @@ -224,6 +230,7 @@ <&dmac1 0x27>, <&dmac1 0x28>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 202>; status = "disabled"; }; @@ -238,6 +245,7 @@ <&dmac1 0x1b>, <&dmac1 0x1c>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 1106>; status = "disabled"; }; @@ -252,6 +260,7 @@ <&dmac1 0x1f>, <&dmac1 0x20>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 1107>; status = "disabled"; }; @@ -266,6 +275,7 @@ <&dmac1 0x23>, <&dmac1 0x24>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 1108>; status = "disabled"; }; @@ -277,9 +287,10 @@ clocks = <&cpg CPG_MOD 206>; clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>, - <&dmac1 0x3d>, <&dmac1 0x3e>; + <&dmac1 0x3d>, <&dmac1 0x3e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 206>; status = "disabled"; }; @@ -294,6 +305,7 @@ <&dmac1 0x19>, <&dmac1 0x1a>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 207>; status = "disabled"; }; @@ -308,6 +320,7 @@ <&dmac1 0x1d>, <&dmac1 0x1e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 216>; status = "disabled"; }; @@ -323,6 +336,7 @@ <&dmac1 0x29>, <&dmac1 0x2a>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 721>; status = "disabled"; }; @@ -338,6 +352,7 @@ <&dmac1 0x2d>, <&dmac1 0x2e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 720>; status = "disabled"; }; @@ -353,6 +368,7 @@ <&dmac1 0x2b>, <&dmac1 0x2c>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 719>; status = "disabled"; }; @@ -368,6 +384,7 @@ <&dmac1 0x2f>, <&dmac1 0x30>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 718>; status = "disabled"; }; @@ -383,6 +400,7 @@ <&dmac1 0xfb>, <&dmac1 0xfc>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 715>; status = "disabled"; }; @@ -398,6 +416,7 @@ <&dmac1 0xfd>, <&dmac1 0xfe>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 714>; status = "disabled"; }; @@ -413,6 +432,7 @@ <&dmac1 0x39>, <&dmac1 0x3a>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 717>; status = "disabled"; }; @@ -428,6 +448,7 @@ <&dmac1 0x4d>, <&dmac1 0x4e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 716>; status = "disabled"; }; @@ -443,6 +464,7 @@ <&dmac1 0x3b>, <&dmac1 0x3c>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 713>; status = "disabled"; }; @@ -452,6 +474,7 @@ interrupts = ; clocks = <&cpg CPG_MOD 813>; power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 813>; phy-mode = "rmii"; #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/r8a7745.dtsi b/sys/gnu/dts/arm/r8a7745.dtsi index 1f65ff68a469..2feb0084bb3b 100644 --- a/sys/gnu/dts/arm/r8a7745.dtsi +++ b/sys/gnu/dts/arm/r8a7745.dtsi @@ -32,9 +32,8 @@ next-level-cache = <&L2_CA7>; }; - L2_CA7: cache-controller@0 { + L2_CA7: cache-controller-0 { compatible = "cache"; - reg = <0>; cache-unified; cache-level = <2>; power-domains = <&sysc R8A7745_PD_CA7_SCU>; @@ -63,6 +62,7 @@ clocks = <&cpg CPG_MOD 408>; clock-names = "clk"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 408>; }; irqc: interrupt-controller@e61c0000 { @@ -82,6 +82,7 @@ ; clocks = <&cpg CPG_MOD 407>; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 407>; }; timer { @@ -103,6 +104,7 @@ clock-names = "extal", "usb_extal"; #clock-cells = <2>; #power-domain-cells = <0>; + #reset-cells = <1>; }; prr: chipid@ff000044 { @@ -149,6 +151,7 @@ clocks = <&cpg CPG_MOD 219>; clock-names = "fck"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 219>; #dma-cells = <1>; dma-channels = <15>; }; @@ -181,6 +184,7 @@ clocks = <&cpg CPG_MOD 218>; clock-names = "fck"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 218>; #dma-cells = <1>; dma-channels = <15>; }; @@ -196,6 +200,7 @@ <&dmac1 0x21>, <&dmac1 0x22>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 204>; status = "disabled"; }; @@ -210,6 +215,7 @@ <&dmac1 0x25>, <&dmac1 0x26>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 203>; status = "disabled"; }; @@ -224,6 +230,7 @@ <&dmac1 0x27>, <&dmac1 0x28>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 202>; status = "disabled"; }; @@ -238,6 +245,7 @@ <&dmac1 0x1b>, <&dmac1 0x1c>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 1106>; status = "disabled"; }; @@ -252,6 +260,7 @@ <&dmac1 0x1f>, <&dmac1 0x20>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 1107>; status = "disabled"; }; @@ -266,6 +275,7 @@ <&dmac1 0x23>, <&dmac1 0x24>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 1108>; status = "disabled"; }; @@ -277,9 +287,10 @@ clocks = <&cpg CPG_MOD 206>; clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>, - <&dmac1 0x3d>, <&dmac1 0x3e>; + <&dmac1 0x3d>, <&dmac1 0x3e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 206>; status = "disabled"; }; @@ -294,6 +305,7 @@ <&dmac1 0x19>, <&dmac1 0x1a>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 207>; status = "disabled"; }; @@ -308,6 +320,7 @@ <&dmac1 0x1d>, <&dmac1 0x1e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 216>; status = "disabled"; }; @@ -323,6 +336,7 @@ <&dmac1 0x29>, <&dmac1 0x2a>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 721>; status = "disabled"; }; @@ -338,6 +352,7 @@ <&dmac1 0x2d>, <&dmac1 0x2e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 720>; status = "disabled"; }; @@ -353,6 +368,7 @@ <&dmac1 0x2b>, <&dmac1 0x2c>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 719>; status = "disabled"; }; @@ -368,6 +384,7 @@ <&dmac1 0x2f>, <&dmac1 0x30>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 718>; status = "disabled"; }; @@ -383,6 +400,7 @@ <&dmac1 0xfb>, <&dmac1 0xfc>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 715>; status = "disabled"; }; @@ -398,6 +416,7 @@ <&dmac1 0xfd>, <&dmac1 0xfe>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 714>; status = "disabled"; }; @@ -413,6 +432,7 @@ <&dmac1 0x39>, <&dmac1 0x3a>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 717>; status = "disabled"; }; @@ -428,6 +448,7 @@ <&dmac1 0x4d>, <&dmac1 0x4e>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 716>; status = "disabled"; }; @@ -443,6 +464,7 @@ <&dmac1 0x3b>, <&dmac1 0x3c>; dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 713>; status = "disabled"; }; @@ -452,6 +474,7 @@ interrupts = ; clocks = <&cpg CPG_MOD 813>; power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 813>; phy-mode = "rmii"; #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/r8a7778-bockw.dts b/sys/gnu/dts/arm/r8a7778-bockw.dts index 211d239d9041..c79d55eb43c5 100644 --- a/sys/gnu/dts/arm/r8a7778-bockw.dts +++ b/sys/gnu/dts/arm/r8a7778-bockw.dts @@ -229,5 +229,4 @@ &scif_clk { clock-frequency = <14745600>; - status = "okay"; }; diff --git a/sys/gnu/dts/arm/r8a7779-marzen.dts b/sys/gnu/dts/arm/r8a7779-marzen.dts index 89c5b24a3d03..9412a86f9b30 100644 --- a/sys/gnu/dts/arm/r8a7779-marzen.dts +++ b/sys/gnu/dts/arm/r8a7779-marzen.dts @@ -236,7 +236,6 @@ &scif_clk { clock-frequency = <14745600>; - status = "okay"; }; &sdhi0 { diff --git a/sys/gnu/dts/arm/r8a7790-lager.dts b/sys/gnu/dts/arm/r8a7790-lager.dts index bd512c86e852..ba100a6f67ca 100644 --- a/sys/gnu/dts/arm/r8a7790-lager.dts +++ b/sys/gnu/dts/arm/r8a7790-lager.dts @@ -581,7 +581,6 @@ &scif_clk { clock-frequency = <14745600>; - status = "okay"; }; &msiof1 { diff --git a/sys/gnu/dts/arm/r8a7790.dtsi b/sys/gnu/dts/arm/r8a7790.dtsi index 6d10450de6d7..99269aaca6fc 100644 --- a/sys/gnu/dts/arm/r8a7790.dtsi +++ b/sys/gnu/dts/arm/r8a7790.dtsi @@ -129,17 +129,15 @@ next-level-cache = <&L2_CA7>; }; - L2_CA15: cache-controller@0 { + L2_CA15: cache-controller-0 { compatible = "cache"; - reg = <0>; power-domains = <&sysc R8A7790_PD_CA15_SCU>; cache-unified; cache-level = <2>; }; - L2_CA7: cache-controller@100 { + L2_CA7: cache-controller-1 { compatible = "cache"; - reg = <0x100>; power-domains = <&sysc R8A7790_PD_CA7_SCU>; cache-unified; cache-level = <2>; @@ -187,6 +185,9 @@ <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; interrupts = ; + clocks = <&mstp4_clks R8A7790_CLK_INTC_SYS>; + clock-names = "clk"; + power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; }; gpio0: gpio@e6050000 { @@ -1100,7 +1101,7 @@ }; /* External CAN clock */ - can_clk: can_clk { + can_clk: can { compatible = "fixed-clock"; #clock-cells = <0>; /* This value must be overridden by the board. */ @@ -1366,10 +1367,10 @@ mstp4_clks: mstp4_clks@e6150140 { compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>; - clocks = <&cp_clk>; + clocks = <&cp_clk>, <&zs_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "irqc"; + clock-indices = ; + clock-output-names = "irqc", "intc-sys"; }; mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; @@ -1442,8 +1443,11 @@ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>; clocks = <&p_clk>, - <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, - <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>, + <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>, + <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>, + <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>, + <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&p_clk>, <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>, <&mstp10_clks R8A7790_CLK_SCU_ALL>, @@ -1740,11 +1744,11 @@ rcar_sound,dvc { dvc0: dvc-0 { - dmas = <&audma0 0xbc>; + dmas = <&audma1 0xbc>; dma-names = "tx"; }; dvc1: dvc-1 { - dmas = <&audma0 0xbe>; + dmas = <&audma1 0xbe>; dma-names = "tx"; }; }; diff --git a/sys/gnu/dts/arm/r8a7791-koelsch.dts b/sys/gnu/dts/arm/r8a7791-koelsch.dts index 5405d337d744..001e6116c47c 100644 --- a/sys/gnu/dts/arm/r8a7791-koelsch.dts +++ b/sys/gnu/dts/arm/r8a7791-koelsch.dts @@ -292,7 +292,7 @@ x2_clk: x2-clock { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <148500000>; + clock-frequency = <74250000>; }; x13_clk: x13-clock { @@ -516,7 +516,6 @@ &scif_clk { clock-frequency = <14745600>; - status = "okay"; }; &sdhi0 { @@ -767,7 +766,6 @@ &pcie_bus_clk { clock-frequency = <100000000>; - status = "okay"; }; &pciec { diff --git a/sys/gnu/dts/arm/r8a7791-porter.dts b/sys/gnu/dts/arm/r8a7791-porter.dts index 6761d11d3f9e..95da5cb9d37a 100644 --- a/sys/gnu/dts/arm/r8a7791-porter.dts +++ b/sys/gnu/dts/arm/r8a7791-porter.dts @@ -226,7 +226,7 @@ phy-handle = <&phy1>; renesas,ether-link-active-low; - status = "ok"; + status = "okay"; phy1: ethernet-phy@1 { reg = <1>; @@ -359,7 +359,7 @@ /* composite video input */ &vin0 { - status = "ok"; + status = "okay"; pinctrl-0 = <&vin0_pins>; pinctrl-names = "default"; @@ -401,7 +401,6 @@ &pcie_bus_clk { clock-frequency = <100000000>; - status = "okay"; }; &pciec { diff --git a/sys/gnu/dts/arm/r8a7791.dtsi b/sys/gnu/dts/arm/r8a7791.dtsi index 9f9e48511836..4d0c2ce59900 100644 --- a/sys/gnu/dts/arm/r8a7791.dtsi +++ b/sys/gnu/dts/arm/r8a7791.dtsi @@ -74,9 +74,8 @@ next-level-cache = <&L2_CA15>; }; - L2_CA15: cache-controller@0 { + L2_CA15: cache-controller-0 { compatible = "cache"; - reg = <0>; power-domains = <&sysc R8A7791_PD_CA15_SCU>; cache-unified; cache-level = <2>; @@ -118,6 +117,9 @@ <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; interrupts = ; + clocks = <&mstp4_clks R8A7791_CLK_INTC_SYS>; + clock-names = "clk"; + power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; }; gpio0: gpio@e6050000 { @@ -1124,7 +1126,7 @@ }; /* External CAN clock */ - can_clk: can_clk { + can_clk: can { compatible = "fixed-clock"; #clock-cells = <0>; /* This value must be overridden by the board. */ @@ -1366,10 +1368,10 @@ mstp4_clks: mstp4_clks@e6150140 { compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>; - clocks = <&cp_clk>; + clocks = <&cp_clk>, <&zs_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "irqc"; + clock-indices = ; + clock-output-names = "irqc", "intc-sys"; }; mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; @@ -1445,8 +1447,11 @@ compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>; clocks = <&p_clk>, - <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, - <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>, + <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>, + <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>, + <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>, + <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&p_clk>, <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>, <&mstp10_clks R8A7791_CLK_SCU_ALL>, @@ -1777,11 +1782,11 @@ rcar_sound,dvc { dvc0: dvc-0 { - dmas = <&audma0 0xbc>; + dmas = <&audma1 0xbc>; dma-names = "tx"; }; dvc1: dvc-1 { - dmas = <&audma0 0xbe>; + dmas = <&audma1 0xbe>; dma-names = "tx"; }; }; diff --git a/sys/gnu/dts/arm/r8a7792.dtsi b/sys/gnu/dts/arm/r8a7792.dtsi index 8ecfda7a004e..0efecb232ee5 100644 --- a/sys/gnu/dts/arm/r8a7792.dtsi +++ b/sys/gnu/dts/arm/r8a7792.dtsi @@ -46,7 +46,7 @@ compatible = "arm,cortex-a15"; reg = <0>; clock-frequency = <1000000000>; - clocks = <&cpg_clocks R8A7792_CLK_Z>; + clocks = <&z_clk>; power-domains = <&sysc R8A7792_PD_CA15_CPU0>; next-level-cache = <&L2_CA15>; }; @@ -60,9 +60,8 @@ next-level-cache = <&L2_CA15>; }; - L2_CA15: cache-controller@0 { + L2_CA15: cache-controller-0 { compatible = "cache"; - reg = <0>; cache-unified; cache-level = <2>; power-domains = <&sysc R8A7792_PD_CA15_SCU>; @@ -93,6 +92,9 @@ <0 0xf1006000 0 0x2000>; interrupts = ; + clocks = <&mstp4_clks R8A7792_CLK_INTC_SYS>; + clock-names = "clk"; + power-domains = <&sysc R8A7792_PD_ALWAYS_ON>; }; irqc: interrupt-controller@e61c0000 { @@ -764,7 +766,7 @@ clocks = <&extal_clk>; #clock-cells = <1>; clock-output-names = "main", "pll0", "pll1", "pll3", - "lb", "qspi", "z"; + "lb", "qspi"; #power-domain-cells = <0>; }; @@ -776,6 +778,13 @@ clock-div = <2>; clock-mult = <1>; }; + z_clk: z { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7792_CLK_PLL0>; + #clock-cells = <0>; + clock-div = <1>; + clock-mult = <1>; + }; zx_clk: zx { compatible = "fixed-factor-clock"; clocks = <&cpg_clocks R8A7792_CLK_PLL1>; @@ -896,10 +905,12 @@ compatible = "renesas,r8a7792-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>; - clocks = <&cp_clk>; + clocks = <&cp_clk>, <&zs_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "irqc"; + clock-indices = < + R8A7792_CLK_IRQC R8A7792_CLK_INTC_SYS + >; + clock-output-names = "irqc", "intc-sys"; }; mstp7_clks: mstp7_clks@e615014c { compatible = "renesas,r8a7792-mstp-clocks", diff --git a/sys/gnu/dts/arm/r8a7793-gose.dts b/sys/gnu/dts/arm/r8a7793-gose.dts index 92fff07c5e2b..806c93f6ae8b 100644 --- a/sys/gnu/dts/arm/r8a7793-gose.dts +++ b/sys/gnu/dts/arm/r8a7793-gose.dts @@ -412,7 +412,6 @@ &scif_clk { clock-frequency = <14745600>; - status = "okay"; }; &sdhi0 { diff --git a/sys/gnu/dts/arm/r8a7793.dtsi b/sys/gnu/dts/arm/r8a7793.dtsi index 48ce21c5e8db..4de6041d61f9 100644 --- a/sys/gnu/dts/arm/r8a7793.dtsi +++ b/sys/gnu/dts/arm/r8a7793.dtsi @@ -65,9 +65,8 @@ power-domains = <&sysc R8A7793_PD_CA15_CPU1>; }; - L2_CA15: cache-controller@0 { + L2_CA15: cache-controller-0 { compatible = "cache"; - reg = <0>; power-domains = <&sysc R8A7793_PD_CA15_SCU>; cache-unified; cache-level = <2>; @@ -109,6 +108,9 @@ <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; interrupts = ; + clocks = <&mstp4_clks R8A7793_CLK_INTC_SYS>; + clock-names = "clk"; + power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; }; gpio0: gpio@e6050000 { @@ -1179,10 +1181,12 @@ mstp4_clks: mstp4_clks@e6150140 { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>; - clocks = <&cp_clk>; + clocks = <&cp_clk>, <&zs_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "irqc"; + clock-indices = < + R8A7793_CLK_IRQC R8A7793_CLK_INTC_SYS + >; + clock-output-names = "irqc", "intc-sys"; }; mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; @@ -1265,8 +1269,11 @@ compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>; clocks = <&p_clk>, - <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, - <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&mstp10_clks R8A7793_CLK_SSI_ALL>, <&mstp10_clks R8A7793_CLK_SSI_ALL>, + <&mstp10_clks R8A7793_CLK_SSI_ALL>, <&mstp10_clks R8A7793_CLK_SSI_ALL>, + <&mstp10_clks R8A7793_CLK_SSI_ALL>, <&mstp10_clks R8A7793_CLK_SSI_ALL>, + <&mstp10_clks R8A7793_CLK_SSI_ALL>, <&mstp10_clks R8A7793_CLK_SSI_ALL>, + <&mstp10_clks R8A7793_CLK_SSI_ALL>, <&mstp10_clks R8A7793_CLK_SSI_ALL>, <&p_clk>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, @@ -1426,11 +1433,11 @@ rcar_sound,dvc { dvc0: dvc-0 { - dmas = <&audma0 0xbc>; + dmas = <&audma1 0xbc>; dma-names = "tx"; }; dvc1: dvc-1 { - dmas = <&audma0 0xbe>; + dmas = <&audma1 0xbe>; dma-names = "tx"; }; }; diff --git a/sys/gnu/dts/arm/r8a7794-alt.dts b/sys/gnu/dts/arm/r8a7794-alt.dts index 569e3f0e97a5..f1eea13cdf44 100644 --- a/sys/gnu/dts/arm/r8a7794-alt.dts +++ b/sys/gnu/dts/arm/r8a7794-alt.dts @@ -168,7 +168,7 @@ status = "okay"; clocks = <&mstp7_clks R8A7794_CLK_DU0>, - <&mstp7_clks R8A7794_CLK_DU0>, + <&mstp7_clks R8A7794_CLK_DU1>, <&x13_clk>, <&x2_clk>; clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; @@ -375,7 +375,6 @@ &scif_clk { clock-frequency = <14745600>; - status = "okay"; }; &qspi { diff --git a/sys/gnu/dts/arm/r8a7794-silk.dts b/sys/gnu/dts/arm/r8a7794-silk.dts index cf880ac06f4b..4cb5278d104d 100644 --- a/sys/gnu/dts/arm/r8a7794-silk.dts +++ b/sys/gnu/dts/arm/r8a7794-silk.dts @@ -248,7 +248,6 @@ &scif_clk { clock-frequency = <14745600>; - status = "okay"; }; ðer { @@ -425,7 +424,7 @@ status = "okay"; clocks = <&mstp7_clks R8A7794_CLK_DU0>, - <&mstp7_clks R8A7794_CLK_DU0>, + <&mstp7_clks R8A7794_CLK_DU1>, <&x2_clk>, <&x3_clk>; clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; diff --git a/sys/gnu/dts/arm/r8a7794.dtsi b/sys/gnu/dts/arm/r8a7794.dtsi index 319c1069b7ee..a19b884fb258 100644 --- a/sys/gnu/dts/arm/r8a7794.dtsi +++ b/sys/gnu/dts/arm/r8a7794.dtsi @@ -43,6 +43,7 @@ compatible = "arm,cortex-a7"; reg = <0>; clock-frequency = <1000000000>; + clocks = <&z2_clk>; power-domains = <&sysc R8A7794_PD_CA7_CPU0>; next-level-cache = <&L2_CA7>; }; @@ -56,9 +57,8 @@ next-level-cache = <&L2_CA7>; }; - L2_CA7: cache-controller@0 { + L2_CA7: cache-controller-0 { compatible = "cache"; - reg = <0>; power-domains = <&sysc R8A7794_PD_CA7_SCU>; cache-unified; cache-level = <2>; @@ -75,6 +75,9 @@ <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; interrupts = ; + clocks = <&mstp4_clks R8A7794_CLK_INTC_SYS>; + clock-names = "clk"; + power-domains = <&sysc R8A7794_PD_ALWAYS_ON>; }; gpio0: gpio@e6050000 { @@ -923,7 +926,7 @@ interrupts = , ; clocks = <&mstp7_clks R8A7794_CLK_DU0>, - <&mstp7_clks R8A7794_CLK_DU0>; + <&mstp7_clks R8A7794_CLK_DU1>; clock-names = "du.0", "du.1"; status = "disabled"; @@ -1062,6 +1065,13 @@ clock-div = <2>; clock-mult = <1>; }; + z2_clk: z2 { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7794_CLK_PLL0>; + #clock-cells = <0>; + clock-div = <1>; + clock-mult = <1>; + }; zg_clk: zg { compatible = "fixed-factor-clock"; clocks = <&cpg_clocks R8A7794_CLK_PLL1>; @@ -1248,10 +1258,10 @@ mstp4_clks: mstp4_clks@e6150140 { compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>; - clocks = <&cp_clk>; + clocks = <&cp_clk>, <&zs_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "irqc"; + clock-indices = ; + clock-output-names = "irqc", "intc-sys"; }; mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks"; @@ -1268,19 +1278,21 @@ clocks = <&mp_clk>, <&hp_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, - <&zx_clk>; + <&zx_clk>, <&zx_clk>; #clock-cells = <1>; clock-indices = < R8A7794_CLK_EHCI R8A7794_CLK_HSUSB R8A7794_CLK_HSCIF2 R8A7794_CLK_SCIF5 R8A7794_CLK_SCIF4 R8A7794_CLK_HSCIF1 R8A7794_CLK_HSCIF0 R8A7794_CLK_SCIF3 R8A7794_CLK_SCIF2 R8A7794_CLK_SCIF1 - R8A7794_CLK_SCIF0 R8A7794_CLK_DU0 + R8A7794_CLK_SCIF0 + R8A7794_CLK_DU1 R8A7794_CLK_DU0 >; clock-output-names = "ehci", "hsusb", "hscif2", "scif5", "scif4", "hscif1", "hscif0", - "scif3", "scif2", "scif1", "scif0", "du0"; + "scif3", "scif2", "scif1", "scif0", + "du1", "du0"; }; mstp8_clks: mstp8_clks@e6150990 { compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks"; diff --git a/sys/gnu/dts/arm/rk1108.dtsi b/sys/gnu/dts/arm/rk1108.dtsi index d6194bff7afe..1297924db6ad 100644 --- a/sys/gnu/dts/arm/rk1108.dtsi +++ b/sys/gnu/dts/arm/rk1108.dtsi @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include / { #address-cells = <1>; @@ -222,7 +222,7 @@ }; pinctrl: pinctrl { - compatible = "rockchip,rk1108-pinctrl"; + compatible = "rockchip,rv1108-pinctrl"; rockchip,grf = <&grf>; rockchip,pmu = <&pmugrf>; #address-cells = <1>; diff --git a/sys/gnu/dts/arm/rk3036.dtsi b/sys/gnu/dts/arm/rk3036.dtsi index ff9b90bfaefd..ec91325d3b6e 100644 --- a/sys/gnu/dts/arm/rk3036.dtsi +++ b/sys/gnu/dts/arm/rk3036.dtsi @@ -250,6 +250,8 @@ clock-names = "biu", "ciu"; fifo-depth = <0x100>; interrupts = ; + resets = <&cru SRST_MMC0>; + reset-names = "reset"; status = "disabled"; }; @@ -262,6 +264,8 @@ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; fifo-depth = <0x100>; interrupts = ; + resets = <&cru SRST_SDIO>; + reset-names = "reset"; status = "disabled"; }; @@ -286,6 +290,8 @@ num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + resets = <&cru SRST_EMMC>; + reset-names = "reset"; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/rk3188.dtsi b/sys/gnu/dts/arm/rk3188.dtsi index cf91254d0a43..1399bc04ea77 100644 --- a/sys/gnu/dts/arm/rk3188.dtsi +++ b/sys/gnu/dts/arm/rk3188.dtsi @@ -106,6 +106,22 @@ }; }; + timer3: timer@2000e000 { + compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; + reg = <0x2000e000 0x20>; + interrupts = ; + clocks = <&cru SCLK_TIMER3>, <&cru PCLK_TIMER3>; + clock-names = "timer", "pclk"; + }; + + timer6: timer@200380a0 { + compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; + reg = <0x200380a0 0x20>; + interrupts = ; + clocks = <&cru SCLK_TIMER6>, <&cru PCLK_TIMER0>; + clock-names = "timer", "pclk"; + }; + i2s0: i2s@1011a000 { compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s"; reg = <0x1011a000 0x2000>; @@ -529,11 +545,12 @@ }; &global_timer { - interrupts = ; + interrupts = ; + status = "disabled"; }; &local_timer { - interrupts = ; + interrupts = ; }; &i2c0 { diff --git a/sys/gnu/dts/arm/rk322x.dtsi b/sys/gnu/dts/arm/rk322x.dtsi index 9dff8221112c..48a0c1cf4301 100644 --- a/sys/gnu/dts/arm/rk322x.dtsi +++ b/sys/gnu/dts/arm/rk322x.dtsi @@ -325,7 +325,7 @@ }; timer: timer@110c0000 { - compatible = "rockchip,rk3288-timer"; + compatible = "rockchip,rk3228-timer", "rockchip,rk3288-timer"; reg = <0x110c0000 0x20>; interrupts = ; clocks = <&xin24m>, <&cru PCLK_TIMER>; @@ -414,6 +414,8 @@ fifo-depth = <0x100>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + resets = <&cru SRST_EMMC>; + reset-names = "reset"; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/rk3288-miqi.dts b/sys/gnu/dts/arm/rk3288-miqi.dts index 21326f3e8564..30e93f694ae8 100644 --- a/sys/gnu/dts/arm/rk3288-miqi.dts +++ b/sys/gnu/dts/arm/rk3288-miqi.dts @@ -68,11 +68,9 @@ compatible = "gpio-leds"; work { - gpios = <&gpio7 RK_PA4 GPIO_ACTIVE_LOW>; + gpios = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>; label = "miqi:green:user"; - linux,default-trigger = "default-on"; - pinctrl-names = "default"; - pinctrl-0 = <&led_ctl>; + linux,default-trigger = "timer"; }; }; @@ -363,12 +361,6 @@ }; }; - leds { - led_ctl: led-ctl { - rockchip,pins = <7 4 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - sdmmc { /* * Default drive strength isn't enough to achieve even diff --git a/sys/gnu/dts/arm/rk3288-phycore-rdk.dts b/sys/gnu/dts/arm/rk3288-phycore-rdk.dts new file mode 100644 index 000000000000..3dda79579b51 --- /dev/null +++ b/sys/gnu/dts/arm/rk3288-phycore-rdk.dts @@ -0,0 +1,298 @@ +/* + * Device tree file for Phytec PCM-947 carrier board + * Copyright (C) 2017 PHYTEC Messtechnik GmbH + * Author: Wadim Egorov + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include +#include "rk3288-phycore-som.dtsi" + +/ { + model = "Phytec RK3288 PCM-947"; + compatible = "phytec,rk3288-pcm-947", "phytec,rk3288-phycore-som", "rockchip,rk3288"; + + user_buttons: user-buttons { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&user_button_pins>; + + button@0 { + label = "home"; + linux,code = ; + gpios = <&gpio8 0 GPIO_ACTIVE_HIGH>; + wakeup-source; + }; + + button@1 { + label = "menu"; + linux,code = ; + gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>; + wakeup-source; + }; + }; + + vcc_host0_5v: usb-host0-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&host0_vbus_drv>; + regulator-name = "vcc_host0_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&vdd_in_otg_out>; + }; + + vcc_host1_5v: usb-host1-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio2 0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&host1_vbus_drv>; + regulator-name = "vcc_host1_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&vdd_in_otg_out>; + }; + + vcc_otg_5v: usb-otg-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&otg_vbus_drv>; + regulator-name = "vcc_otg_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&vdd_in_otg_out>; + }; +}; + +&gmac { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + touchscreen@44 { + compatible = "st,stmpe811"; + reg = <0x44>; + }; + + adc@64 { + compatible = "maxim,max1037"; + reg = <0x64>; + }; + + i2c_rtc: rtc@68 { + compatible = "rv4162"; + reg = <0x68>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c_rtc_int>; + interrupt-parent = <&gpio5>; + interrupts = <10 0>; + }; +}; + +&i2c3 { + status = "okay"; + + i2c_eeprom_cb: eeprom@51 { + compatible = "atmel,24c32"; + reg = <0x51>; + pagesize = <32>; + }; +}; + +&i2c4 { + status = "okay"; + + /* PCA9533 - 4-bit LED dimmer */ + leddim: leddimmer@62 { + compatible = "nxp,pca9533"; + reg = <0x62>; + + led1 { + label = "red:user1"; + linux,default-trigger = "none"; + type = ; + }; + + led2 { + label = "green:user2"; + linux,default-trigger = "none"; + type = ; + }; + + led3 { + label = "blue:user3"; + linux,default-trigger = "none"; + type = ; + }; + + led4 { + label = "red:user4"; + linux,default-trigger = "none"; + type = ; + }; + }; +}; + +&i2c5 { + status = "okay"; +}; + +&pinctrl { + pcfg_pull_up_drv_12ma: pcfg-pull-up-drv-12ma { + bias-pull-up; + drive-strength = <12>; + }; + + buttons { + user_button_pins: user-button-pins { + /* button 1 */ + rockchip,pins = <8 3 RK_FUNC_GPIO &pcfg_pull_up>, + /* button 2 */ + <8 0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + rv4162 { + i2c_rtc_int: i2c-rtc-int { + rockchip,pins = <5 10 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdmmc { + /* + * Default drive strength isn't enough to achieve even + * high-speed mode on pcm-947 board so bump up to 12 mA. + */ + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 17 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 18 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 19 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_12ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + touchscreen { + ts_irq_pin: ts-irq-pin { + rockchip,pins = <5 15 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb_host { + host0_vbus_drv: host0-vbus-drv { + rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + host1_vbus_drv: host1-vbus-drv { + rockchip,pins = <2 0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb_otg { + otg_vbus_drv: otg-vbus-drv { + rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + vmmc-supply = <&vdd_io_sd>; + vqmmc-supply = <&vdd_io_sd>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host1 { + status = "okay"; +}; + +&usb_otg { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/rk3288-phycore-som.dtsi b/sys/gnu/dts/arm/rk3288-phycore-som.dtsi new file mode 100644 index 000000000000..26cd3ad45160 --- /dev/null +++ b/sys/gnu/dts/arm/rk3288-phycore-som.dtsi @@ -0,0 +1,497 @@ +/* + * Device tree file for Phytec phyCORE-RK3288 SoM + * Copyright (C) 2017 PHYTEC Messtechnik GmbH + * Author: Wadim Egorov + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "rk3288.dtsi" + +/ { + model = "Phytec RK3288 phyCORE"; + compatible = "phytec,rk3288-phycore-som", "rockchip,rk3288"; + + /* + * Set the minimum memory size here and + * let the bootloader set the real size. + */ + memory { + device_type = "memory"; + reg = <0 0x8000000>; + }; + + aliases { + rtc0 = &i2c_rtc; + rtc1 = &rk818; + }; + + ext_gmac: external-gmac-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + clock-output-names = "ext_gmac"; + }; + + leds: user-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&user_led>; + + user { + label = "green_led"; + gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "keep"; + }; + }; + + vdd_emmc_io: vdd-emmc-io { + compatible = "regulator-fixed"; + regulator-name = "vdd_emmc_io"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vdd_3v3_io>; + }; + + vdd_in_otg_out: vdd-in-otg-out { + compatible = "regulator-fixed"; + regulator-name = "vdd_in_otg_out"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vdd_misc_1v8: vdd-misc-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vdd_misc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; +}; + +&cpu0 { + cpu0-supply = <&vdd_cpu>; + operating-points = < + /* KHz uV */ + 1800000 1400000 + 1608000 1350000 + 1512000 1300000 + 1416000 1200000 + 1200000 1100000 + 1008000 1050000 + 816000 1000000 + 696000 950000 + 600000 900000 + 408000 900000 + 312000 900000 + 216000 900000 + 126000 900000 + >; +}; + +&emmc { + status = "okay"; + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; + vmmc-supply = <&vdd_3v3_io>; + vqmmc-supply = <&vdd_emmc_io>; +}; + +&gmac { + assigned-clocks = <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>; + clock_in_out = "input"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins &phy_rst &phy_int>; + phy-handle = <&phy0>; + phy-supply = <&vdd_eth_2v5>; + phy-mode = "rgmii-id"; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-gpio = <&gpio4 8 GPIO_ACTIVE_HIGH>; + tx_delay = <0x0>; + rx_delay = <0x0>; + + mdio0 { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + interrupt-parent = <&gpio4>; + interrupts = <2 IRQ_TYPE_EDGE_FALLING>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + enet-phy-lane-no-swap; + }; + }; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; +}; + +&io_domains { + status = "okay"; + sdcard-supply = <&vdd_io_sd>; + flash0-supply = <&vdd_emmc_io>; + flash1-supply = <&vdd_misc_1v8>; + gpio1830-supply = <&vdd_3v3_io>; + gpio30-supply = <&vdd_3v3_io>; + bb-supply = <&vdd_3v3_io>; + dvp-supply = <&vdd_3v3_io>; + lcdc-supply = <&vdd_3v3_io>; + wifi-supply = <&vdd_3v3_io>; + audio-supply = <&vdd_3v3_io>; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + rk818: pmic@1c { + compatible = "rockchip,rk818"; + reg = <0x1c>; + interrupt-parent = <&gpio0>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + + vcc1-supply = <&vdd_sys>; + vcc2-supply = <&vdd_sys>; + vcc3-supply = <&vdd_sys>; + vcc4-supply = <&vdd_sys>; + boost-supply = <&vdd_in_otg_out>; + vcc6-supply = <&vdd_sys>; + vcc7-supply = <&vdd_misc_1v8>; + vcc8-supply = <&vdd_misc_1v8>; + vcc9-supply = <&vdd_3v3_io>; + vddio-supply = <&vdd_3v3_io>; + + regulators { + vdd_log: DCDC_REG1 { + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1250000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_3v3_io: DCDC_REG4 { + regulator-name = "vdd_3v3_io"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vdd_sys: DCDC_BOOST { + regulator-name = "vdd_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <5000000>; + }; + }; + + /* vcc9 */ + vdd_sd: SWITCH_REG { + regulator-name = "vdd_sd"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* vcc6 */ + vdd_eth_2v5: LDO_REG2 { + regulator-name = "vdd_eth_2v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <2500000>; + }; + }; + + /* vcc7 */ + vdd_1v0: LDO_REG3 { + regulator-name = "vdd_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + /* vcc8 */ + vdd_1v8_lcd_ldo: LDO_REG4 { + regulator-name = "vdd_1v8_lcd_ldo"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + /* vcc8 */ + vdd_1v0_lcd: LDO_REG6 { + regulator-name = "vdd_1v0_lcd"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + /* vcc7 */ + vdd_1v8_ldo: LDO_REG7 { + regulator-name = "vdd_1v8_ldo"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + /* vcc9 */ + vdd_io_sd: LDO_REG9 { + regulator-name = "vdd_io_sd"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + }; + }; + + /* M24C32-D */ + i2c_eeprom: eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; + + vdd_cpu: regulator@60 { + compatible = "fcs,fan53555"; + reg = <0x60>; + fcs,suspend-voltage-selector = <1>; + regulator-always-on; + regulator-boot-on; + regulator-enable-ramp-delay = <300>; + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1430000>; + regulator-ramp-delay = <8000>; + vin-supply = <&vdd_sys>; + }; +}; + +&pinctrl { + pcfg_output_high: pcfg-output-high { + output-high; + }; + + emmc { + /* + * We run eMMC at max speed; bump up drive strength. + * We also have external pulls, so disable the internal ones. + */ + emmc_clk: emmc-clk { + rockchip,pins = <3 18 RK_FUNC_2 &pcfg_pull_none_12ma>; + }; + + emmc_cmd: emmc-cmd { + rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_none_12ma>; + }; + + emmc_bus8: emmc-bus8 { + rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_none_12ma>, + <3 1 RK_FUNC_2 &pcfg_pull_none_12ma>, + <3 2 RK_FUNC_2 &pcfg_pull_none_12ma>, + <3 3 RK_FUNC_2 &pcfg_pull_none_12ma>, + <3 4 RK_FUNC_2 &pcfg_pull_none_12ma>, + <3 5 RK_FUNC_2 &pcfg_pull_none_12ma>, + <3 6 RK_FUNC_2 &pcfg_pull_none_12ma>, + <3 7 RK_FUNC_2 &pcfg_pull_none_12ma>; + }; + }; + + gmac { + phy_int: phy-int { + rockchip,pins = <4 2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + phy_rst: phy-rst { + rockchip,pins = <4 8 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; + + leds { + user_led: user-led { + rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = ; + }; + + /* Pin for switching state between sleep and non-sleep state */ + pmic_sleep: pmic-sleep { + rockchip,pins = ; + }; + }; +}; + +&pwm1 { + status = "okay"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vdd_1v8_ldo>; +}; + +&spi2 { + status = "okay"; + + serial_flash: flash@0 { + compatible = "micron,n25q128a13", "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + }; +}; + +&tsadc { + status = "okay"; + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&wdt { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/rk3288-rock2-som.dtsi b/sys/gnu/dts/arm/rk3288-rock2-som.dtsi index 1c0bbc9b928b..f0778a46bca9 100644 --- a/sys/gnu/dts/arm/rk3288-rock2-som.dtsi +++ b/sys/gnu/dts/arm/rk3288-rock2-som.dtsi @@ -136,7 +136,7 @@ regulator-always-on; }; - vcc_io: REG2 { + vcc_io: vccio_codec: REG2 { regulator-name = "VCC_IO"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; diff --git a/sys/gnu/dts/arm/rk3288-rock2-square.dts b/sys/gnu/dts/arm/rk3288-rock2-square.dts index 96a2e745bb93..a23a94811be8 100644 --- a/sys/gnu/dts/arm/rk3288-rock2-square.dts +++ b/sys/gnu/dts/arm/rk3288-rock2-square.dts @@ -81,11 +81,35 @@ }; }; + sata_pwr: sata-prw-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 13 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sata_pwr_en>; + /* Always turn on the 5V sata power connector */ + regulator-always-on; + regulator-name = "sata_pwr"; + }; + spdif_out: spdif-out { compatible = "linux,spdif-dit"; #sound-dai-cells = <0>; }; + sound-i2s { + compatible = "rockchip,rk3288-hdmi-analog"; + pinctrl-names = "default"; + pinctrl-0 = <&phone_ctl>, <&hp_det>; + rockchip,audio-codec = <&es8388>; + rockchip,hp-det-gpios = <&gpio7 7 GPIO_ACTIVE_HIGH>; + rockchip,hp-en-gpios = <&gpio8 0 GPIO_ACTIVE_HIGH>; + rockchip,i2s-controller = <&i2s>; + rockchip,model = "I2S"; + rockchip,routing = "Analog", "LOUT2", + "Analog", "ROUT2"; + }; + sdio_pwrseq: sdio-pwrseq { compatible = "mmc-pwrseq-simple"; clocks = <&hym8563>; @@ -173,10 +197,28 @@ }; }; +&i2c2 { + status = "okay"; + + es8388: es8388@10 { + compatible = "everest,es8388", "everest,es8328"; + reg = <0x10>; + AVDD-supply = <&vccio_codec>; + DVDD-supply = <&vccio_codec>; + HPVDD-supply = <&vccio_codec>; + PVDD-supply = <&vccio_codec>; + clocks = <&cru SCLK_I2S0_OUT>; + }; +}; + &i2c5 { status = "okay"; }; +&i2s { + status = "okay"; +}; + &pinctrl { ir { ir_int: ir-int { @@ -190,12 +232,28 @@ }; }; + headphone { + hp_det: hp-det { + rockchip,pins = <7 7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + phone_ctl: phone-ctl { + rockchip,pins = <8 0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + usb { host_vbus_drv: host-vbus-drv { rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + sata { + sata_pwr_en: sata-pwr-en { + rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + sdmmc { sdmmc_pwr: sdmmc-pwr { rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; @@ -224,3 +282,7 @@ &usb_host0_ehci { status = "okay"; }; + +&usb_host1 { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/rk3288-tinker.dts b/sys/gnu/dts/arm/rk3288-tinker.dts new file mode 100644 index 000000000000..f601c78386a9 --- /dev/null +++ b/sys/gnu/dts/arm/rk3288-tinker.dts @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "rk3288.dtsi" +#include + +/ { + model = "Rockchip RK3288 Tinker Board"; + compatible = "asus,rk3288-tinker", "rockchip,rk3288"; + + memory { + reg = <0x0 0x80000000>; + device_type = "memory"; + }; + + ext_gmac: external-gmac-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + clock-output-names = "ext_gmac"; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + pinctrl-names = "default"; + pinctrl-0 = <&pwrbtn>; + + button@0 { + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "GPIO Key Power"; + linux,input-type = <1>; + wakeup-source; + debounce-interval = <100>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + act-led { + gpios=<&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; + linux,default-trigger="mmc0"; + }; + + heartbeat-led { + gpios=<&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>; + linux,default-trigger="heartbeat"; + }; + + pwr-led { + gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,tinker-codec"; + simple-audio-card,mclk-fs = <512>; + + simple-audio-card,codec { + sound-dai = <&hdmi>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + }; + + vcc_sys: vsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio7 11 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwr>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + vin-supply = <&vcc_io>; + }; +}; + +&cpu0 { + cpu0-supply = <&vdd_cpu>; +}; + +&gmac { + assigned-clocks = <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>; + clock_in_out = "input"; + phy-mode = "rgmii"; + phy-supply = <&vcc33_lan>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio4 7 0>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + tx_delay = <0x30>; + rx_delay = <0x10>; + status = "ok"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio0>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + dvs-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>, + <&gpio0 12 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int &global_pwroff &dvs_1 &dvs_2>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc_io>; + vcc9-supply = <&vcc_io>; + vcc10-supply = <&vcc_io>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc_io>; + vddio-supply = <&vcc_io>; + + regulators { + vdd_cpu: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-name = "vdd_arm"; + regulator-ramp-delay = <6000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-name = "vdd_gpu"; + regulator-ramp-delay = <6000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_io"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc18_ldo1: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc18_ldo1"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc33_mipi: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc33_mipi"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_10: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vdd_10"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc18_codec: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc18_codec"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vdd10_lcd: LDO_REG6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vdd10_lcd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_18: LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_18"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc18_lcd: LDO_REG8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc18_lcd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc33_sd: SWITCH_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc33_sd"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc33_lan: SWITCH_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc33_lan"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&i2s { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&io_domains { + status = "okay"; + + sdcard-supply = <&vccio_sd>; +}; + +&pinctrl { + pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma { + drive-strength = <8>; + }; + + pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma { + bias-pull-up; + drive-strength = <8>; + }; + + backlight { + bl_en: bl-en { + rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + buttons { + pwrbtn: pwrbtn { + rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + eth_phy { + eth_phy_pwr: eth-phy-pwr { + rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = ; + }; + + dvs_1: dvs-1 { + rockchip,pins = ; + }; + + dvs_2: dvs-2 { + rockchip,pins = ; + }; + }; + + sdmmc { + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 \ + &pcfg_pull_none_drv_8ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>; + }; + + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + host_vbus_drv: host-vbus-drv { + rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pwr_3g: pwr-3g { + rockchip,pins = <7 8 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc18_ldo1>; + status ="okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; /* wp not hooked up */ + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + status = "okay"; + vmmc-supply = <&vcc33_sd>; + vqmmc-supply = <&vccio_sd>; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host1 { + status = "okay"; +}; + +&usb_otg { + status= "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&wdt { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/rk3288.dtsi b/sys/gnu/dts/arm/rk3288.dtsi index df8a0dbe9d91..ad5d6022e95f 100644 --- a/sys/gnu/dts/arm/rk3288.dtsi +++ b/sys/gnu/dts/arm/rk3288.dtsi @@ -236,6 +236,8 @@ fifo-depth = <0x100>; interrupts = ; reg = <0xff0c0000 0x4000>; + resets = <&cru SRST_MMC0>; + reset-names = "reset"; status = "disabled"; }; @@ -248,6 +250,8 @@ fifo-depth = <0x100>; interrupts = ; reg = <0xff0d0000 0x4000>; + resets = <&cru SRST_SDIO0>; + reset-names = "reset"; status = "disabled"; }; @@ -260,6 +264,8 @@ fifo-depth = <0x100>; interrupts = ; reg = <0xff0e0000 0x4000>; + resets = <&cru SRST_SDIO1>; + reset-names = "reset"; status = "disabled"; }; @@ -272,6 +278,8 @@ fifo-depth = <0x100>; interrupts = ; reg = <0xff0f0000 0x4000>; + resets = <&cru SRST_EMMC>; + reset-names = "reset"; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/rk3xxx.dtsi b/sys/gnu/dts/arm/rk3xxx.dtsi index 0b45811cf28b..4aa6f60d6a22 100644 --- a/sys/gnu/dts/arm/rk3xxx.dtsi +++ b/sys/gnu/dts/arm/rk3xxx.dtsi @@ -132,14 +132,14 @@ global_timer: global-timer@1013c200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x1013c200 0x20>; - interrupts = ; + interrupts = ; clocks = <&cru CORE_PERI>; }; local_timer: local-timer@1013c600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x1013c600 0x20>; - interrupts = ; + interrupts = ; clocks = <&cru CORE_PERI>; }; @@ -223,7 +223,11 @@ interrupts = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; clock-names = "biu", "ciu"; + dmas = <&dmac2 1>; + dma-names = "rx-tx"; fifo-depth = <256>; + resets = <&cru SRST_SDMMC>; + reset-names = "reset"; status = "disabled"; }; @@ -233,7 +237,11 @@ interrupts = ; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>; clock-names = "biu", "ciu"; + dmas = <&dmac2 3>; + dma-names = "rx-tx"; fifo-depth = <256>; + resets = <&cru SRST_SDIO>; + reset-names = "reset"; status = "disabled"; }; @@ -243,7 +251,11 @@ interrupts = ; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; clock-names = "biu", "ciu"; + dmas = <&dmac2 4>; + dma-names = "rx-tx"; fifo-depth = <256>; + resets = <&cru SRST_EMMC>; + reset-names = "reset"; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/s3c64xx.dtsi b/sys/gnu/dts/arm/s3c64xx.dtsi index 0ccb414cd268..c55cbb3af2c0 100644 --- a/sys/gnu/dts/arm/s3c64xx.dtsi +++ b/sys/gnu/dts/arm/s3c64xx.dtsi @@ -94,13 +94,12 @@ }; watchdog: watchdog@7e004000 { - compatible = "samsung,s3c2410-wdt"; + compatible = "samsung,s3c6410-wdt"; reg = <0x7e004000 0x1000>; interrupt-parent = <&vic0>; interrupts = <26>; clock-names = "watchdog"; clocks = <&clocks PCLK_WDT>; - status = "disabled"; }; i2c0: i2c@7f004000 { diff --git a/sys/gnu/dts/arm/s5pv210.dtsi b/sys/gnu/dts/arm/s5pv210.dtsi index a853918be43f..726c5d0dbd5b 100644 --- a/sys/gnu/dts/arm/s5pv210.dtsi +++ b/sys/gnu/dts/arm/s5pv210.dtsi @@ -310,7 +310,7 @@ }; watchdog: watchdog@e2700000 { - compatible = "samsung,s3c2410-wdt"; + compatible = "samsung,s3c6410-wdt"; reg = <0xe2700000 0x1000>; interrupt-parent = <&vic0>; interrupts = <26>; diff --git a/sys/gnu/dts/arm/sama5d2.dtsi b/sys/gnu/dts/arm/sama5d2.dtsi index 528b4e9c6d3d..8067c71c3a38 100644 --- a/sys/gnu/dts/arm/sama5d2.dtsi +++ b/sys/gnu/dts/arm/sama5d2.dtsi @@ -1305,6 +1305,11 @@ status = "okay"; }; + sfrbu: sfr@fc05c000 { + compatible = "atmel,sama5d2-sfrbu", "syscon"; + reg = <0xfc05c000 0x20>; + }; + chipid@fc069000 { compatible = "atmel,sama5d2-chipid"; reg = <0xfc069000 0x8>; diff --git a/sys/gnu/dts/arm/socfpga.dtsi b/sys/gnu/dts/arm/socfpga.dtsi index 2c43c4d85dee..b2674bdb8e6a 100644 --- a/sys/gnu/dts/arm/socfpga.dtsi +++ b/sys/gnu/dts/arm/socfpga.dtsi @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -#include "skeleton.dtsi" #include / { @@ -38,13 +37,13 @@ #size-cells = <0>; enable-method = "altr,socfpga-smp"; - cpu@0 { + cpu0: cpu@0 { compatible = "arm,cortex-a9"; device_type = "cpu"; reg = <0>; next-level-cache = <&L2>; }; - cpu@1 { + cpu1: cpu@1 { compatible = "arm,cortex-a9"; device_type = "cpu"; reg = <1>; @@ -52,6 +51,15 @@ }; }; + pmu: pmu@ff111000 { + compatible = "arm,cortex-a9-pmu"; + interrupt-parent = <&intc>; + interrupts = <0 176 4>, <0 177 4>; + interrupt-affinity = <&cpu0>, <&cpu1>; + reg = <0xff111000 0x1000>, + <0xff113000 0x1000>; + }; + intc: intc@fffed000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; @@ -145,7 +153,7 @@ compatible = "fixed-clock"; }; - main_pll: main_pll { + main_pll: main_pll@40 { #address-cells = <1>; #size-cells = <0>; #clock-cells = <0>; @@ -153,7 +161,7 @@ clocks = <&osc1>; reg = <0x40>; - mpuclk: mpuclk { + mpuclk: mpuclk@48 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&main_pll>; @@ -161,7 +169,7 @@ reg = <0x48>; }; - mainclk: mainclk { + mainclk: mainclk@4c { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&main_pll>; @@ -169,7 +177,7 @@ reg = <0x4C>; }; - dbg_base_clk: dbg_base_clk { + dbg_base_clk: dbg_base_clk@50 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&main_pll>, <&osc1>; @@ -177,21 +185,21 @@ reg = <0x50>; }; - main_qspi_clk: main_qspi_clk { + main_qspi_clk: main_qspi_clk@54 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&main_pll>; reg = <0x54>; }; - main_nand_sdmmc_clk: main_nand_sdmmc_clk { + main_nand_sdmmc_clk: main_nand_sdmmc_clk@58 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&main_pll>; reg = <0x58>; }; - cfg_h2f_usr0_clk: cfg_h2f_usr0_clk { + cfg_h2f_usr0_clk: cfg_h2f_usr0_clk@5c { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&main_pll>; @@ -199,7 +207,7 @@ }; }; - periph_pll: periph_pll { + periph_pll: periph_pll@80 { #address-cells = <1>; #size-cells = <0>; #clock-cells = <0>; @@ -207,42 +215,42 @@ clocks = <&osc1>, <&osc2>, <&f2s_periph_ref_clk>; reg = <0x80>; - emac0_clk: emac0_clk { + emac0_clk: emac0_clk@88 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&periph_pll>; reg = <0x88>; }; - emac1_clk: emac1_clk { + emac1_clk: emac1_clk@8c { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&periph_pll>; reg = <0x8C>; }; - per_qspi_clk: per_qsi_clk { + per_qspi_clk: per_qsi_clk@90 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&periph_pll>; reg = <0x90>; }; - per_nand_mmc_clk: per_nand_mmc_clk { + per_nand_mmc_clk: per_nand_mmc_clk@94 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&periph_pll>; reg = <0x94>; }; - per_base_clk: per_base_clk { + per_base_clk: per_base_clk@98 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&periph_pll>; reg = <0x98>; }; - h2f_usr1_clk: h2f_usr1_clk { + h2f_usr1_clk: h2f_usr1_clk@9c { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&periph_pll>; @@ -250,7 +258,7 @@ }; }; - sdram_pll: sdram_pll { + sdram_pll: sdram_pll@c0 { #address-cells = <1>; #size-cells = <0>; #clock-cells = <0>; @@ -258,28 +266,28 @@ clocks = <&osc1>, <&osc2>, <&f2s_sdram_ref_clk>; reg = <0xC0>; - ddr_dqs_clk: ddr_dqs_clk { + ddr_dqs_clk: ddr_dqs_clk@c8 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&sdram_pll>; reg = <0xC8>; }; - ddr_2x_dqs_clk: ddr_2x_dqs_clk { + ddr_2x_dqs_clk: ddr_2x_dqs_clk@cc { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&sdram_pll>; reg = <0xCC>; }; - ddr_dq_clk: ddr_dq_clk { + ddr_dq_clk: ddr_dq_clk@d0 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&sdram_pll>; reg = <0xD0>; }; - h2f_usr2_clk: h2f_usr2_clk { + h2f_usr2_clk: h2f_usr2_clk@d4 { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&sdram_pll>; @@ -678,7 +686,7 @@ status = "disabled"; }; - eccmgr: eccmgr@ffd08140 { + eccmgr: eccmgr { compatible = "altr,socfpga-ecc-manager"; #address-cells = <1>; #size-cells = <1>; @@ -879,7 +887,7 @@ dma-names = "tx", "rx"; }; - usbphy0: usbphy@0 { + usbphy0: usbphy { #phy-cells = <0>; compatible = "usb-nop-xceiv"; status = "okay"; diff --git a/sys/gnu/dts/arm/socfpga_arria10.dtsi b/sys/gnu/dts/arm/socfpga_arria10.dtsi index 6b0b7463f36f..bead79e4b2aa 100644 --- a/sys/gnu/dts/arm/socfpga_arria10.dtsi +++ b/sys/gnu/dts/arm/socfpga_arria10.dtsi @@ -14,7 +14,6 @@ * this program. If not, see . */ -#include "skeleton.dtsi" #include #include @@ -119,7 +118,7 @@ compatible = "fixed-clock"; }; - main_pll: main_pll { + main_pll: main_pll@40 { #address-cells = <1>; #size-cells = <0>; #clock-cells = <0>; @@ -142,35 +141,35 @@ div-reg = <0x144 0 11>; }; - main_emaca_clk: main_emaca_clk { + main_emaca_clk: main_emaca_clk@68 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; reg = <0x68>; }; - main_emacb_clk: main_emacb_clk { + main_emacb_clk: main_emacb_clk@6c { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; reg = <0x6C>; }; - main_emac_ptp_clk: main_emac_ptp_clk { + main_emac_ptp_clk: main_emac_ptp_clk@70 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; reg = <0x70>; }; - main_gpio_db_clk: main_gpio_db_clk { + main_gpio_db_clk: main_gpio_db_clk@74 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; reg = <0x74>; }; - main_sdmmc_clk: main_sdmmc_clk { + main_sdmmc_clk: main_sdmmc_clk@78 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk" ; @@ -178,28 +177,28 @@ reg = <0x78>; }; - main_s2f_usr0_clk: main_s2f_usr0_clk { + main_s2f_usr0_clk: main_s2f_usr0_clk@7c { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; reg = <0x7C>; }; - main_s2f_usr1_clk: main_s2f_usr1_clk { + main_s2f_usr1_clk: main_s2f_usr1_clk@80 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; reg = <0x80>; }; - main_hmc_pll_ref_clk: main_hmc_pll_ref_clk { + main_hmc_pll_ref_clk: main_hmc_pll_ref_clk@84 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; reg = <0x84>; }; - main_periph_ref_clk: main_periph_ref_clk { + main_periph_ref_clk: main_periph_ref_clk@9c { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; @@ -207,7 +206,7 @@ }; }; - periph_pll: periph_pll { + periph_pll: periph_pll@c0 { #address-cells = <1>; #size-cells = <0>; #clock-cells = <0>; @@ -230,56 +229,56 @@ div-reg = <0x144 16 11>; }; - peri_emaca_clk: peri_emaca_clk { + peri_emaca_clk: peri_emaca_clk@e8 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; reg = <0xE8>; }; - peri_emacb_clk: peri_emacb_clk { + peri_emacb_clk: peri_emacb_clk@ec { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; reg = <0xEC>; }; - peri_emac_ptp_clk: peri_emac_ptp_clk { + peri_emac_ptp_clk: peri_emac_ptp_clk@f0 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; reg = <0xF0>; }; - peri_gpio_db_clk: peri_gpio_db_clk { + peri_gpio_db_clk: peri_gpio_db_clk@f4 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; reg = <0xF4>; }; - peri_sdmmc_clk: peri_sdmmc_clk { + peri_sdmmc_clk: peri_sdmmc_clk@f8 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; reg = <0xF8>; }; - peri_s2f_usr0_clk: peri_s2f_usr0_clk { + peri_s2f_usr0_clk: peri_s2f_usr0_clk@fc { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; reg = <0xFC>; }; - peri_s2f_usr1_clk: peri_s2f_usr1_clk { + peri_s2f_usr1_clk: peri_s2f_usr1_clk@100 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; reg = <0x100>; }; - peri_hmc_pll_ref_clk: peri_hmc_pll_ref_clk { + peri_hmc_pll_ref_clk: peri_hmc_pll_ref_clk@104 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; @@ -287,7 +286,7 @@ }; }; - mpu_free_clk: mpu_free_clk { + mpu_free_clk: mpu_free_clk@60 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_mpu_base_clk>, <&peri_mpu_base_clk>, @@ -296,7 +295,7 @@ reg = <0x60>; }; - noc_free_clk: noc_free_clk { + noc_free_clk: noc_free_clk@64 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_noc_base_clk>, <&peri_noc_base_clk>, @@ -305,7 +304,7 @@ reg = <0x64>; }; - s2f_user1_free_clk: s2f_user1_free_clk { + s2f_user1_free_clk: s2f_user1_free_clk@104 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_s2f_usr1_clk>, <&peri_s2f_usr1_clk>, @@ -314,7 +313,7 @@ reg = <0x104>; }; - sdmmc_free_clk: sdmmc_free_clk { + sdmmc_free_clk: sdmmc_free_clk@f8 { #clock-cells = <0>; compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_sdmmc_clk>, <&peri_sdmmc_clk>, @@ -649,7 +648,7 @@ reg = <0xffe00000 0x40000>; }; - eccmgr: eccmgr@ffd06000 { + eccmgr: eccmgr { compatible = "altr,socfpga-a10-ecc-manager"; altr,sysmgr-syscon = <&sysmgr>; #address-cells = <1>; @@ -806,7 +805,7 @@ status = "disabled"; }; - usbphy0: usbphy@0 { + usbphy0: usbphy { #phy-cells = <0>; compatible = "usb-nop-xceiv"; status = "okay"; diff --git a/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi b/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi index c57e6cea0d83..94e088473823 100644 --- a/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi +++ b/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi @@ -30,7 +30,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1GB */ @@ -121,6 +121,11 @@ gpio-controller; #gpio-cells = <2>; }; + + a10sr_rst: reset-controller { + compatible = "altr,a10sr-reset"; + #reset-cells = <1>; + }; }; }; diff --git a/sys/gnu/dts/arm/socfpga_arria5_socdk.dts b/sys/gnu/dts/arm/socfpga_arria5_socdk.dts index 8672edf9ba4e..aac4feea86f3 100644 --- a/sys/gnu/dts/arm/socfpga_arria5_socdk.dts +++ b/sys/gnu/dts/arm/socfpga_arria5_socdk.dts @@ -26,7 +26,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1GB */ diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts b/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts index 5ecd2ef405e3..7b49395452b6 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts @@ -25,7 +25,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1GB */ diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_mcv.dtsi b/sys/gnu/dts/arm/socfpga_cyclone5_mcv.dtsi index 6ad3b1eb9b86..3c03da6b8b1d 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_mcv.dtsi +++ b/sys/gnu/dts/arm/socfpga_cyclone5_mcv.dtsi @@ -21,7 +21,7 @@ model = "Aries/DENX MCV"; compatible = "altr,socfpga-cyclone5", "altr,socfpga"; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1 GiB */ diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts b/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts index e5a98e5696ca..21e397287e29 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts @@ -71,7 +71,6 @@ stmpe_touchscreen { compatible = "st,stmpe-ts"; - reg = <0>; ts,sample-time = <4>; ts,mod-12b = <1>; ts,ref-sel = <0>; diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_socdk.dts b/sys/gnu/dts/arm/socfpga_cyclone5_socdk.dts index 7ea32c81e720..155829f9eba1 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_socdk.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_socdk.dts @@ -26,7 +26,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1GB */ diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_sockit.dts b/sys/gnu/dts/arm/socfpga_cyclone5_sockit.dts index a0c90b3bdfd1..a4a555c19d94 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_sockit.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_sockit.dts @@ -26,7 +26,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1GB */ diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_socrates.dts b/sys/gnu/dts/arm/socfpga_cyclone5_socrates.dts index c3d52f27b21e..53bf99eef66d 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_socrates.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_socrates.dts @@ -25,7 +25,7 @@ bootargs = "console=ttyS0,115200"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1GB */ @@ -60,18 +60,18 @@ &leds { compatible = "gpio-leds"; - led@0 { + led0 { label = "led:green:heartbeat"; gpios = <&porta 28 1>; linux,default-trigger = "heartbeat"; }; - led@1 { + led1 { label = "led:green:D7"; gpios = <&portb 19 1>; }; - led@2 { + led2 { label = "led:green:D8"; gpios = <&portb 25 1>; }; diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_sodia.dts b/sys/gnu/dts/arm/socfpga_cyclone5_sodia.dts index 5b7e3c27e6e9..8860dd2e242c 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_sodia.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_sodia.dts @@ -28,7 +28,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; @@ -121,3 +121,24 @@ &usb1 { status = "okay"; }; + +&qspi { + status = "okay"; + + flash0: n25q512a@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q512a"; + reg = <0>; + spi-max-frequency = <100000000>; + + m25p,fast-read; + cdns,page-size = <256>; + cdns,block-size = <16>; + cdns,read-delay = <4>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + }; +}; diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts b/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts index 363ee62457fe..893198049397 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts @@ -57,7 +57,7 @@ bootargs = "console=ttyS0,115200"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1GB */ diff --git a/sys/gnu/dts/arm/socfpga_vt.dts b/sys/gnu/dts/arm/socfpga_vt.dts index f9345e02ca49..dfe2193cd4d5 100644 --- a/sys/gnu/dts/arm/socfpga_vt.dts +++ b/sys/gnu/dts/arm/socfpga_vt.dts @@ -26,7 +26,7 @@ bootargs = "console=ttyS0,57600"; }; - memory { + memory@0 { name = "memory"; device_type = "memory"; reg = <0x0 0x40000000>; /* 1 GB */ diff --git a/sys/gnu/dts/arm/spear600-evb.dts b/sys/gnu/dts/arm/spear600-evb.dts index d865a891776d..c67e76c8ba5d 100644 --- a/sys/gnu/dts/arm/spear600-evb.dts +++ b/sys/gnu/dts/arm/spear600-evb.dts @@ -22,95 +22,91 @@ device_type = "memory"; reg = <0 0x10000000>; }; +}; - ahb { - clcd@fc200000 { - status = "okay"; - }; +&clcd { + status = "okay"; +}; - dma@fc400000 { - status = "okay"; - }; +&dmac { + status = "okay"; +}; - ehci@e1800000 { - status = "okay"; - }; +&ehci_usb0 { + status = "okay"; +}; - ehci@e2000000 { - status = "okay"; - }; +&ehci_usb1 { + status = "okay"; +}; - gmac: ethernet@e0800000 { - phy-mode = "gmii"; - status = "okay"; - }; +&gmac { + phy-mode = "gmii"; + status = "okay"; +}; - ohci@e1900000 { - status = "okay"; - }; +&ohci_usb0 { + status = "okay"; +}; - ohci@e2100000 { - status = "okay"; - }; +&ohci_usb1 { + status = "okay"; +}; - smi: flash@fc000000 { - status = "okay"; - clock-rate=<50000000>; +&smi { + status = "okay"; + clock-rate = <50000000>; - flash@f8000000 { - #address-cells = <1>; - #size-cells = <1>; - reg = <0xf8000000 0x800000>; - st,smi-fast-mode; + flash@f8000000 { + reg = <0xf8000000 0x800000>; + st,smi-fast-mode; - partition@0 { - label = "xloader"; - reg = <0x0 0x10000>; - }; - partition@10000 { - label = "u-boot"; - reg = <0x10000 0x50000>; - }; - partition@60000 { - label = "environment"; - reg = <0x60000 0x10000>; - }; - partition@70000 { - label = "dtb"; - reg = <0x70000 0x10000>; - }; - partition@80000 { - label = "linux"; - reg = <0x80000 0x310000>; - }; - partition@390000 { - label = "rootfs"; - reg = <0x390000 0x0>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; }; - }; - - apb { - serial@d0000000 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x50000>; }; - - serial@d0080000 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; }; - - rtc@fc900000 { - status = "okay"; + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; }; - - i2c@d0200000 { - clock-frequency = <400000>; - status = "okay"; + partition@80000 { + label = "linux"; + reg = <0x80000 0x310000>; + }; + partition@390000 { + label = "rootfs"; + reg = <0x390000 0x0>; }; }; }; }; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&i2c { + clock-frequency = <400000>; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/spear600.dtsi b/sys/gnu/dts/arm/spear600.dtsi index 9f60a7b6a42b..6b32d20acc9f 100644 --- a/sys/gnu/dts/arm/spear600.dtsi +++ b/sys/gnu/dts/arm/spear600.dtsi @@ -49,7 +49,7 @@ #interrupt-cells = <1>; }; - clcd@fc200000 { + clcd: clcd@fc200000 { compatible = "arm,pl110", "arm,primecell"; reg = <0xfc200000 0x1000>; interrupt-parent = <&vic1>; @@ -57,7 +57,7 @@ status = "disabled"; }; - dma@fc400000 { + dmac: dma@fc400000 { compatible = "arm,pl080", "arm,primecell"; reg = <0xfc400000 0x1000>; interrupt-parent = <&vic1>; @@ -97,7 +97,7 @@ status = "disabled"; }; - ehci@e1800000 { + ehci_usb0: ehci@e1800000 { compatible = "st,spear600-ehci", "usb-ehci"; reg = <0xe1800000 0x1000>; interrupt-parent = <&vic1>; @@ -105,7 +105,7 @@ status = "disabled"; }; - ehci@e2000000 { + ehci_usb1: ehci@e2000000 { compatible = "st,spear600-ehci", "usb-ehci"; reg = <0xe2000000 0x1000>; interrupt-parent = <&vic1>; @@ -113,7 +113,7 @@ status = "disabled"; }; - ohci@e1900000 { + ohci_usb0: ohci@e1900000 { compatible = "st,spear600-ohci", "usb-ohci"; reg = <0xe1900000 0x1000>; interrupt-parent = <&vic1>; @@ -121,7 +121,7 @@ status = "disabled"; }; - ohci@e2100000 { + ohci_usb1: ohci@e2100000 { compatible = "st,spear600-ohci", "usb-ohci"; reg = <0xe2100000 0x1000>; interrupt-parent = <&vic1>; @@ -135,7 +135,7 @@ compatible = "simple-bus"; ranges = <0xd0000000 0xd0000000 0x30000000>; - serial@d0000000 { + uart0: serial@d0000000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xd0000000 0x1000>; interrupt-parent = <&vic0>; @@ -143,7 +143,7 @@ status = "disabled"; }; - serial@d0080000 { + uart1: serial@d0080000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xd0080000 0x1000>; interrupt-parent = <&vic0>; @@ -181,7 +181,7 @@ interrupts = <4>; }; - i2c@d0200000 { + i2c: i2c@d0200000 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,designware-i2c"; @@ -191,7 +191,7 @@ status = "disabled"; }; - rtc@fc900000 { + rtc: rtc@fc900000 { compatible = "st,spear600-rtc"; reg = <0xfc900000 0x1000>; interrupts = <10>; @@ -204,6 +204,14 @@ interrupt-parent = <&vic0>; interrupts = <16>; }; + + adc: adc@d820b000 { + compatible = "st,spear600-adc"; + reg = <0xd820b000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <6>; + status = "disabled"; + }; }; }; }; diff --git a/sys/gnu/dts/arm/ste-dbx5x0.dtsi b/sys/gnu/dts/arm/ste-dbx5x0.dtsi index 162e1eb5373d..6c5affe2d0f5 100644 --- a/sys/gnu/dts/arm/ste-dbx5x0.dtsi +++ b/sys/gnu/dts/arm/ste-dbx5x0.dtsi @@ -1189,11 +1189,6 @@ status = "disabled"; }; - cpufreq-cooling { - compatible = "stericsson,db8500-cpufreq-cooling"; - status = "disabled"; - }; - mcde@a0350000 { compatible = "stericsson,mcde"; reg = <0xa0350000 0x1000>, /* MCDE */ diff --git a/sys/gnu/dts/arm/stih407-family.dtsi b/sys/gnu/dts/arm/stih407-family.dtsi index d753ac36788f..12c0757594d7 100644 --- a/sys/gnu/dts/arm/stih407-family.dtsi +++ b/sys/gnu/dts/arm/stih407-family.dtsi @@ -464,6 +464,8 @@ clock-names = "ssc"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1_default>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -476,6 +478,8 @@ clock-names = "ssc"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi2_default>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -488,6 +492,8 @@ clock-names = "ssc"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi3_default>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -500,6 +506,8 @@ clock-names = "ssc"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi4_default>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -513,6 +521,8 @@ clock-names = "ssc"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi10_default>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -525,6 +535,8 @@ clock-names = "ssc"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi11_default>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -537,6 +549,8 @@ clock-names = "ssc"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi12_default>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -742,18 +756,6 @@ <&clk_s_c0_flexgen CLK_ETH_PHY>; }; - cec: sti-cec@094a087c { - compatible = "st,stih-cec"; - reg = <0x94a087c 0x64>; - clocks = <&clk_sysin>; - clock-names = "cec-clk"; - interrupts = ; - interrupt-names = "cec-irq"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_cec0_default>; - resets = <&softreset STIH407_LPM_SOFTRESET>; - }; - rng10: rng@08a89000 { compatible = "st,rng"; reg = <0x08a89000 0x1000>; @@ -801,7 +803,7 @@ status = "okay"; }; - st231_gp0: remote-processor { + st231_gp0: st231-gp0@0 { compatible = "st,st231-rproc"; memory-region = <&gp0_reserved>; resets = <&softreset STIH407_ST231_GP0_SOFTRESET>; @@ -814,7 +816,7 @@ mboxes = <&mailbox0 0 2>, <&mailbox2 0 1>, <&mailbox0 0 3>, <&mailbox2 0 0>; }; - st231_delta: remote-processor { + st231_delta: st231-delta@0 { compatible = "st,st231-rproc"; memory-region = <&delta_reserved>; resets = <&softreset STIH407_ST231_DMU_SOFTRESET>; diff --git a/sys/gnu/dts/arm/stih410.dtsi b/sys/gnu/dts/arm/stih410.dtsi index 3c9672c5b09f..21fe72b183d8 100644 --- a/sys/gnu/dts/arm/stih410.dtsi +++ b/sys/gnu/dts/arm/stih410.dtsi @@ -281,5 +281,18 @@ <&clk_s_c0_flexgen CLK_ST231_DMU>, <&clk_s_c0_flexgen CLK_FLASH_PROMIP>; }; + + sti-cec@094a087c { + compatible = "st,stih-cec"; + reg = <0x94a087c 0x64>; + clocks = <&clk_sysin>; + clock-names = "cec-clk"; + interrupts = ; + interrupt-names = "cec-irq"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cec0_default>; + resets = <&softreset STIH407_LPM_SOFTRESET>; + hdmi-phandle = <&sti_hdmi>; + }; }; }; diff --git a/sys/gnu/dts/arm/stm32429i-eval.dts b/sys/gnu/dts/arm/stm32429i-eval.dts index 3c99466989b1..b6331146aa02 100644 --- a/sys/gnu/dts/arm/stm32429i-eval.dts +++ b/sys/gnu/dts/arm/stm32429i-eval.dts @@ -167,6 +167,34 @@ status = "okay"; }; +&timers1 { + status = "okay"; + + pwm { + pinctrl-0 = <&pwm1_pins>; + pinctrl-names = "default"; + status = "okay"; + }; + + timer@0 { + status = "okay"; + }; +}; + +&timers3 { + status = "okay"; + + pwm { + pinctrl-0 = <&pwm3_pins>; + pinctrl-names = "default"; + status = "okay"; + }; + + timer@2 { + status = "okay"; + }; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/sys/gnu/dts/arm/stm32746g-eval.dts b/sys/gnu/dts/arm/stm32746g-eval.dts index aa03fac1ec55..69a957963fa8 100644 --- a/sys/gnu/dts/arm/stm32746g-eval.dts +++ b/sys/gnu/dts/arm/stm32746g-eval.dts @@ -89,6 +89,14 @@ clock-frequency = <25000000>; }; +&crc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/sys/gnu/dts/arm/stm32f429-disco.dts b/sys/gnu/dts/arm/stm32f429-disco.dts index 9222b9f37bc0..191fa50e34eb 100644 --- a/sys/gnu/dts/arm/stm32f429-disco.dts +++ b/sys/gnu/dts/arm/stm32f429-disco.dts @@ -88,6 +88,14 @@ gpios = <&gpioa 0 0>; }; }; + + /* This turns on vbus for otg for host mode (dwc2) */ + vcc5v_otg: vcc5v-otg-regulator { + compatible = "regulator-fixed"; + gpio = <&gpioc 4 0>; + regulator-name = "vcc5_host1"; + regulator-always-on; + }; }; &clk_hse { @@ -105,3 +113,11 @@ pinctrl-names = "default"; status = "okay"; }; + +&usbotg_hs { + compatible = "st,stm32f4x9-fsotg"; + dr_mode = "host"; + pinctrl-0 = <&usbotg_fs_pins_b>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/stm32f429.dtsi b/sys/gnu/dts/arm/stm32f429.dtsi index ee0da970e8ad..b2a2b5c38caa 100644 --- a/sys/gnu/dts/arm/stm32f429.dtsi +++ b/sys/gnu/dts/arm/stm32f429.dtsi @@ -450,6 +450,8 @@ clocks = <&rcc 0 STM32F4_APB2_CLOCK(ADC1)>; interrupt-parent = <&adc>; interrupts = <0>; + dmas = <&dma2 0 0 0x400 0x0>; + dma-names = "rx"; status = "disabled"; }; @@ -460,6 +462,8 @@ clocks = <&rcc 0 STM32F4_APB2_CLOCK(ADC2)>; interrupt-parent = <&adc>; interrupts = <1>; + dmas = <&dma2 3 1 0x400 0x0>; + dma-names = "rx"; status = "disabled"; }; @@ -470,6 +474,8 @@ clocks = <&rcc 0 STM32F4_APB2_CLOCK(ADC3)>; interrupt-parent = <&adc>; interrupts = <2>; + dmas = <&dma2 1 2 0x400 0x0>; + dma-names = "rx"; status = "disabled"; }; }; @@ -666,6 +672,28 @@ }; }; + usbotg_fs_pins_a: usbotg_fs@0 { + pins { + pinmux = , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + usbotg_fs_pins_b: usbotg_fs@1 { + pins { + pinmux = , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + usbotg_hs_pins_a: usbotg_hs@0 { pins { pinmux = , @@ -805,6 +833,15 @@ status = "disabled"; }; + usbotg_fs: usb@50000000 { + compatible = "st,stm32f4x9-fsotg"; + reg = <0x50000000 0x40000>; + interrupts = <67>; + clocks = <&rcc 0 39>; + clock-names = "otg"; + status = "disabled"; + }; + rng: rng@50060800 { compatible = "st,stm32-rng"; reg = <0x50060800 0x400>; diff --git a/sys/gnu/dts/arm/stm32f469-disco.dts b/sys/gnu/dts/arm/stm32f469-disco.dts index 0dd56ef574fa..75470c34b92c 100644 --- a/sys/gnu/dts/arm/stm32f469-disco.dts +++ b/sys/gnu/dts/arm/stm32f469-disco.dts @@ -68,6 +68,15 @@ soc { dma-ranges = <0xc0000000 0x0 0x10000000>; }; + + /* This turns on vbus for otg for host mode (dwc2) */ + vcc5v_otg: vcc5v-otg-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpiob 2 0>; + regulator-name = "vcc5_host1"; + regulator-always-on; + }; }; &rcc { @@ -115,3 +124,10 @@ pinctrl-names = "default"; status = "okay"; }; + +&usbotg_fs { + dr_mode = "host"; + pinctrl-0 = <&usbotg_fs_pins_a>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/stm32f746.dtsi b/sys/gnu/dts/arm/stm32f746.dtsi index f321ffe87144..c2765ce12e2e 100644 --- a/sys/gnu/dts/arm/stm32f746.dtsi +++ b/sys/gnu/dts/arm/stm32f746.dtsi @@ -43,6 +43,8 @@ #include "skeleton.dtsi" #include "armv7-m.dtsi" #include +#include +#include / { clocks { @@ -51,6 +53,24 @@ compatible = "fixed-clock"; clock-frequency = <0>; }; + + clk-lse { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + + clk-lsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32000>; + }; + + clk_i2s_ckin: clk-i2s-ckin { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <48000000>; + }; }; soc { @@ -58,7 +78,7 @@ compatible = "st,stm32-timer"; reg = <0x40000000 0x400>; interrupts = <28>; - clocks = <&rcc 0 128>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM2)>; status = "disabled"; }; @@ -66,7 +86,7 @@ compatible = "st,stm32-timer"; reg = <0x40000400 0x400>; interrupts = <29>; - clocks = <&rcc 0 129>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM3)>; status = "disabled"; }; @@ -74,7 +94,7 @@ compatible = "st,stm32-timer"; reg = <0x40000800 0x400>; interrupts = <30>; - clocks = <&rcc 0 130>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM4)>; status = "disabled"; }; @@ -82,14 +102,14 @@ compatible = "st,stm32-timer"; reg = <0x40000c00 0x400>; interrupts = <50>; - clocks = <&rcc 0 131>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM5)>; }; timer6: timer@40001000 { compatible = "st,stm32-timer"; reg = <0x40001000 0x400>; interrupts = <54>; - clocks = <&rcc 0 132>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM6)>; status = "disabled"; }; @@ -97,7 +117,21 @@ compatible = "st,stm32-timer"; reg = <0x40001400 0x400>; interrupts = <55>; - clocks = <&rcc 0 133>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM7)>; + status = "disabled"; + }; + + rtc: rtc@40002800 { + compatible = "st,stm32-rtc"; + reg = <0x40002800 0x400>; + clocks = <&rcc 1 CLK_RTC>; + clock-names = "ck_rtc"; + assigned-clocks = <&rcc 1 CLK_RTC>; + assigned-clock-parents = <&rcc 1 CLK_LSE>; + interrupt-parent = <&exti>; + interrupts = <17 1>; + interrupt-names = "alarm"; + st,syscfg = <&pwrcfg>; status = "disabled"; }; @@ -105,7 +139,7 @@ compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40004400 0x400>; interrupts = <38>; - clocks = <&rcc 0 145>; + clocks = <&rcc 1 CLK_USART2>; status = "disabled"; }; @@ -113,7 +147,7 @@ compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40004800 0x400>; interrupts = <39>; - clocks = <&rcc 0 146>; + clocks = <&rcc 1 CLK_USART3>; status = "disabled"; }; @@ -121,7 +155,7 @@ compatible = "st,stm32f7-uart"; reg = <0x40004c00 0x400>; interrupts = <52>; - clocks = <&rcc 0 147>; + clocks = <&rcc 1 CLK_UART4>; status = "disabled"; }; @@ -129,7 +163,7 @@ compatible = "st,stm32f7-uart"; reg = <0x40005000 0x400>; interrupts = <53>; - clocks = <&rcc 0 148>; + clocks = <&rcc 1 CLK_UART5>; status = "disabled"; }; @@ -137,7 +171,7 @@ compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40007800 0x400>; interrupts = <82>; - clocks = <&rcc 0 158>; + clocks = <&rcc 1 CLK_UART7>; status = "disabled"; }; @@ -145,7 +179,7 @@ compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40007c00 0x400>; interrupts = <83>; - clocks = <&rcc 0 159>; + clocks = <&rcc 1 CLK_UART8>; status = "disabled"; }; @@ -153,7 +187,7 @@ compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40011000 0x400>; interrupts = <37>; - clocks = <&rcc 0 164>; + clocks = <&rcc 1 CLK_USART1>; status = "disabled"; }; @@ -161,7 +195,7 @@ compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40011400 0x400>; interrupts = <71>; - clocks = <&rcc 0 165>; + clocks = <&rcc 1 CLK_USART6>; status = "disabled"; }; @@ -178,6 +212,11 @@ interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>; }; + pwrcfg: power-config@40007000 { + compatible = "syscon"; + reg = <0x40007000 0x400>; + }; + pin-controller { #address-cells = <1>; #size-cells = <1>; @@ -191,7 +230,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x0 0x400>; - clocks = <&rcc 0 256>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>; st,bank-name = "GPIOA"; }; @@ -199,7 +238,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x400 0x400>; - clocks = <&rcc 0 257>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>; st,bank-name = "GPIOB"; }; @@ -207,7 +246,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x800 0x400>; - clocks = <&rcc 0 258>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>; st,bank-name = "GPIOC"; }; @@ -215,7 +254,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0xc00 0x400>; - clocks = <&rcc 0 259>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>; st,bank-name = "GPIOD"; }; @@ -223,7 +262,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x1000 0x400>; - clocks = <&rcc 0 260>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>; st,bank-name = "GPIOE"; }; @@ -231,7 +270,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x1400 0x400>; - clocks = <&rcc 0 261>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>; st,bank-name = "GPIOF"; }; @@ -239,7 +278,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x1800 0x400>; - clocks = <&rcc 0 262>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>; st,bank-name = "GPIOG"; }; @@ -247,7 +286,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x1c00 0x400>; - clocks = <&rcc 0 263>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>; st,bank-name = "GPIOH"; }; @@ -255,7 +294,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x2000 0x400>; - clocks = <&rcc 0 264>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>; st,bank-name = "GPIOI"; }; @@ -263,7 +302,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x2400 0x400>; - clocks = <&rcc 0 265>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>; st,bank-name = "GPIOJ"; }; @@ -271,7 +310,7 @@ gpio-controller; #gpio-cells = <2>; reg = <0x2800 0x400>; - clocks = <&rcc 0 266>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>; st,bank-name = "GPIOK"; }; @@ -289,11 +328,21 @@ }; }; + crc: crc@40023000 { + compatible = "st,stm32f7-crc"; + reg = <0x40023000 0x400>; + clocks = <&rcc 0 12>; + status = "disabled"; + }; + rcc: rcc@40023800 { #clock-cells = <2>; - compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; + compatible = "st,stm32f746-rcc", "st,stm32-rcc"; reg = <0x40023800 0x400>; - clocks = <&clk_hse>; + clocks = <&clk_hse>, <&clk_i2s_ckin>; + st,syscfg = <&pwrcfg>; + assigned-clocks = <&rcc 1 CLK_HSE_RTC>; + assigned-clock-rates = <1000000>; }; }; }; diff --git a/sys/gnu/dts/arm/stm32h743-pinctrl.dtsi b/sys/gnu/dts/arm/stm32h743-pinctrl.dtsi new file mode 100644 index 000000000000..fcc1e0640233 --- /dev/null +++ b/sys/gnu/dts/arm/stm32h743-pinctrl.dtsi @@ -0,0 +1,156 @@ +/* + * Copyright 2017 - Alexandre Torgue + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +/ { + soc { + pin-controller { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,stm32h743-pinctrl"; + ranges = <0 0x58020000 0x3000>; + pins-are-numbered; + + gpioa: gpio@58020000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x0 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOA"; + }; + + gpiob: gpio@58020400 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x400 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOB"; + }; + + gpioc: gpio@58020800 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x800 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOC"; + }; + + gpiod: gpio@58020c00 { + gpio-controller; + #gpio-cells = <2>; + reg = <0xc00 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOD"; + }; + + gpioe: gpio@58021000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1000 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOE"; + }; + + gpiof: gpio@58021400 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1400 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOF"; + }; + + gpiog: gpio@58021800 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1800 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOG"; + }; + + gpioh: gpio@58021c00 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1c00 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOH"; + }; + + gpioi: gpio@58022000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2000 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOI"; + }; + + gpioj: gpio@58022400 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2400 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOJ"; + }; + + gpiok: gpio@58022800 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2800 0x400>; + clocks = <&timer_clk>; + st,bank-name = "GPIOK"; + }; + + usart1_pins: usart1@0 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/stm32h743.dtsi b/sys/gnu/dts/arm/stm32h743.dtsi new file mode 100644 index 000000000000..46856298ee16 --- /dev/null +++ b/sys/gnu/dts/arm/stm32h743.dtsi @@ -0,0 +1,83 @@ +/* + * Copyright 2017 - Alexandre Torgue + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "skeleton.dtsi" +#include "armv7-m.dtsi" + +/ { + clocks { + clk_hse: clk-hse { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + timer_clk: timer-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <125000000>; + }; + }; + + soc { + usart1: serial@40011000 { + compatible = "st,stm32f7-usart", "st,stm32f7-uart"; + reg = <0x40011000 0x400>; + interrupts = <37>; + status = "disabled"; + clocks = <&timer_clk>; + + }; + + timer5: timer@40000c00 { + compatible = "st,stm32-timer"; + reg = <0x40000c00 0x400>; + interrupts = <50>; + clocks = <&timer_clk>; + }; + }; +}; + +&systick { + clock-frequency = <250000000>; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/stm32h743i-eval.dts b/sys/gnu/dts/arm/stm32h743i-eval.dts new file mode 100644 index 000000000000..c6effbb36e4a --- /dev/null +++ b/sys/gnu/dts/arm/stm32h743i-eval.dts @@ -0,0 +1,74 @@ +/* + * Copyright 2017 - Alexandre Torgue + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "stm32h743.dtsi" +#include "stm32h743-pinctrl.dtsi" + +/ { + model = "STMicroelectronics STM32H743i-EVAL board"; + compatible = "st,stm32h743i-eval", "st,stm32h743"; + + chosen { + bootargs = "root=/dev/ram"; + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0xd0000000 0x2000000>; + }; + + aliases { + serial0 = &usart1; + }; +}; + +&clk_hse { + clock-frequency = <125000000>; +}; + +&usart1 { + pinctrl-0 = <&usart1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + diff --git a/sys/gnu/dts/arm/sun4i-a10-a1000.dts b/sys/gnu/dts/arm/sun4i-a10-a1000.dts index f3fc27412a67..f2a01fe2bebc 100644 --- a/sys/gnu/dts/arm/sun4i-a10-a1000.dts +++ b/sys/gnu/dts/arm/sun4i-a10-a1000.dts @@ -47,7 +47,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Mele A1000"; diff --git a/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts b/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts index 04e040e6233d..d844938e2aa7 100644 --- a/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts +++ b/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts @@ -46,7 +46,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Cubietech Cubieboard"; diff --git a/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts b/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts index 8317fbfeec4a..aad3bec1cb39 100644 --- a/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts +++ b/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts @@ -46,7 +46,6 @@ #include #include #include -#include #include / { diff --git a/sys/gnu/dts/arm/sun4i-a10-hackberry.dts b/sys/gnu/dts/arm/sun4i-a10-hackberry.dts index a48b46474417..a1a7282199d5 100644 --- a/sys/gnu/dts/arm/sun4i-a10-hackberry.dts +++ b/sys/gnu/dts/arm/sun4i-a10-hackberry.dts @@ -47,7 +47,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Miniand Hackberry"; diff --git a/sys/gnu/dts/arm/sun4i-a10-inet1.dts b/sys/gnu/dts/arm/sun4i-a10-inet1.dts index f3092703a1a6..b8923b92cb36 100644 --- a/sys/gnu/dts/arm/sun4i-a10-inet1.dts +++ b/sys/gnu/dts/arm/sun4i-a10-inet1.dts @@ -46,7 +46,6 @@ #include #include #include -#include #include / { diff --git a/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts b/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts index 4ef2a60a8cd4..4a27eb9102cd 100644 --- a/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts +++ b/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts @@ -46,7 +46,6 @@ #include #include #include -#include / { model = "iNet-9F Rev 03"; diff --git a/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts b/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts index fc4d4d49e2e2..308dc1513041 100644 --- a/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts +++ b/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts @@ -47,7 +47,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Jesurun Q5"; diff --git a/sys/gnu/dts/arm/sun4i-a10-marsboard.dts b/sys/gnu/dts/arm/sun4i-a10-marsboard.dts index a2885039d5f1..98a5f7258dca 100644 --- a/sys/gnu/dts/arm/sun4i-a10-marsboard.dts +++ b/sys/gnu/dts/arm/sun4i-a10-marsboard.dts @@ -46,7 +46,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "HAOYU Electronics Marsboard A10"; diff --git a/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts b/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts index af42ebb3a97b..484c57493bd2 100644 --- a/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts +++ b/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts @@ -47,7 +47,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "PineRiver Mini X-Plus"; diff --git a/sys/gnu/dts/arm/sun4i-a10-mk802.dts b/sys/gnu/dts/arm/sun4i-a10-mk802.dts index 9c1afd4277d7..2b75745cd246 100644 --- a/sys/gnu/dts/arm/sun4i-a10-mk802.dts +++ b/sys/gnu/dts/arm/sun4i-a10-mk802.dts @@ -44,7 +44,6 @@ #include "sun4i-a10.dtsi" #include "sunxi-common-regulators.dtsi" #include -#include / { model = "MK802"; diff --git a/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts b/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts index 214a5accfe93..3a2522a9419d 100644 --- a/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts +++ b/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts @@ -45,7 +45,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Olimex A10-OLinuXino-LIME"; diff --git a/sys/gnu/dts/arm/sun4i-a10-pcduino.dts b/sys/gnu/dts/arm/sun4i-a10-pcduino.dts index b0365d63ba70..83596fd2ccfc 100644 --- a/sys/gnu/dts/arm/sun4i-a10-pcduino.dts +++ b/sys/gnu/dts/arm/sun4i-a10-pcduino.dts @@ -47,7 +47,6 @@ #include #include -#include / { model = "LinkSprite pcDuino"; diff --git a/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts b/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts index bfa6bbdaab27..a68c7cc53b94 100644 --- a/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts +++ b/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts @@ -46,7 +46,6 @@ #include #include #include -#include #include / { diff --git a/sys/gnu/dts/arm/sun4i-a10.dtsi b/sys/gnu/dts/arm/sun4i-a10.dtsi index ba20b48c0702..b63668ece151 100644 --- a/sys/gnu/dts/arm/sun4i-a10.dtsi +++ b/sys/gnu/dts/arm/sun4i-a10.dtsi @@ -47,7 +47,6 @@ #include #include -#include / { interrupt-parent = <&intc>; @@ -974,6 +973,11 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + can0_pins_a: can0@0 { + pins = "PH20", "PH21"; + function = "can"; + }; + emac_pins_a: emac0@0 { pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", @@ -1283,6 +1287,22 @@ status = "disabled"; }; + ps20: ps2@01c2a000 { + compatible = "allwinner,sun4i-a10-ps2"; + reg = <0x01c2a000 0x400>; + interrupts = <62>; + clocks = <&apb1_gates 6>; + status = "disabled"; + }; + + ps21: ps2@01c2a400 { + compatible = "allwinner,sun4i-a10-ps2"; + reg = <0x01c2a400 0x400>; + interrupts = <63>; + clocks = <&apb1_gates 7>; + status = "disabled"; + }; + i2c0: i2c@01c2ac00 { compatible = "allwinner,sun4i-a10-i2c"; reg = <0x01c2ac00 0x400>; @@ -1313,19 +1333,11 @@ #size-cells = <0>; }; - ps20: ps2@01c2a000 { - compatible = "allwinner,sun4i-a10-ps2"; - reg = <0x01c2a000 0x400>; - interrupts = <62>; - clocks = <&apb1_gates 6>; - status = "disabled"; - }; - - ps21: ps2@01c2a400 { - compatible = "allwinner,sun4i-a10-ps2"; - reg = <0x01c2a400 0x400>; - interrupts = <63>; - clocks = <&apb1_gates 7>; + can0: can@01c2bc00 { + compatible = "allwinner,sun4i-a10-can"; + reg = <0x01c2bc00 0x400>; + interrupts = <26>; + clocks = <&apb1_gates 4>; status = "disabled"; }; }; diff --git a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts index a539b72ce093..c6f742a7e69f 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts @@ -44,7 +44,6 @@ #include "sun5i-a10s.dtsi" #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Auxtek t003 A10s hdmi tv-stick"; diff --git a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts index e1b5e8a446fe..a27c3fa58736 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts @@ -44,7 +44,6 @@ #include "sun5i-a10s.dtsi" #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Auxtek t004 A10s hdmi tv-stick"; diff --git a/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts b/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts index d8245c6314a7..894f874a5beb 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Olimex A10s-Olinuxino Micro"; @@ -83,7 +82,7 @@ &emac { pinctrl-names = "default"; - pinctrl-0 = <&emac_pins_a>; + pinctrl-0 = <&emac_pins_b>; phy = <&phy1>; status = "okay"; }; @@ -257,7 +256,7 @@ &uart2 { pinctrl-names = "default"; - pinctrl-0 = <&uart2_pins_a>; + pinctrl-0 = <&uart2_pins_b>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun5i-a10s-r7-tv-dongle.dts b/sys/gnu/dts/arm/sun5i-a10s-r7-tv-dongle.dts index 51371f9b1cf0..262b3669f04d 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-r7-tv-dongle.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-r7-tv-dongle.dts @@ -45,7 +45,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "R7 A10s hdmi tv-stick"; diff --git a/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts b/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts index 2b8adda0deda..ea3e5655a61b 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "A10s-Wobo i5"; @@ -95,7 +94,7 @@ &emac { pinctrl-names = "default"; - pinctrl-0 = <&emac_pins_b>; + pinctrl-0 = <&emac_pins_a>; phy = <&phy1>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun5i-a10s.dtsi b/sys/gnu/dts/arm/sun5i-a10s.dtsi index 24b0f5f556f8..1e38ff80366c 100644 --- a/sys/gnu/dts/arm/sun5i-a10s.dtsi +++ b/sys/gnu/dts/arm/sun5i-a10s.dtsi @@ -47,7 +47,6 @@ #include "sun5i.dtsi" #include -#include / { interrupt-parent = <&intc>; @@ -61,7 +60,7 @@ #size-cells = <1>; ranges; - framebuffer@0 { + framebuffer@2 { compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; allwinner,pipeline = "de_be0-lcd0-hdmi"; @@ -70,45 +69,9 @@ <&ccu CLK_DE_BE>, <&ccu CLK_HDMI>; status = "disabled"; }; - - framebuffer@1 { - compatible = "allwinner,simple-framebuffer", - "simple-framebuffer"; - allwinner,pipeline = "de_be0-lcd0"; - clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, - <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>; - status = "disabled"; - }; - - framebuffer@2 { - compatible = "allwinner,simple-framebuffer", - "simple-framebuffer"; - allwinner,pipeline = "de_be0-lcd0-tve0"; - clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>, - <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, - <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>; - status = "disabled"; - }; }; soc@01c00000 { - emac: ethernet@01c0b000 { - compatible = "allwinner,sun4i-a10-emac"; - reg = <0x01c0b000 0x1000>; - interrupts = <55>; - clocks = <&ccu CLK_AHB_EMAC>; - allwinner,sram = <&emac_sram 1>; - status = "disabled"; - }; - - mdio: mdio@01c0b080 { - compatible = "allwinner,sun4i-a10-mdio"; - reg = <0x01c0b080 0x14>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - pwm: pwm@01c20e00 { compatible = "allwinner,sun5i-a10s-pwm"; reg = <0x01c20e00 0xc>; @@ -116,26 +79,6 @@ #pwm-cells = <3>; status = "disabled"; }; - - uart0: serial@01c28000 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28000 0x400>; - interrupts = <1>; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_APB1_UART0>; - status = "disabled"; - }; - - uart2: serial@01c28800 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28800 0x400>; - interrupts = <3>; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_APB1_UART2>; - status = "disabled"; - }; }; }; @@ -151,12 +94,12 @@ function = "uart0"; }; - uart2_pins_a: uart2@0 { + uart2_pins_b: uart2@1 { pins = "PC18", "PC19"; function = "uart2"; }; - emac_pins_a: emac0@0 { + emac_pins_b: emac0@1 { pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", @@ -165,15 +108,6 @@ function = "emac"; }; - emac_pins_b: emac0@1 { - pins = "PD6", "PD7", "PD10", - "PD11", "PD12", "PD13", "PD14", - "PD15", "PD18", "PD19", "PD20", - "PD21", "PD22", "PD23", "PD24", - "PD25", "PD26", "PD27"; - function = "emac"; - }; - mmc1_pins_a: mmc1@0 { pins = "PG3", "PG4", "PG5", "PG6", "PG7", "PG8"; @@ -193,9 +127,4 @@ }; &sram_a { - emac_sram: sram-section@8000 { - compatible = "allwinner,sun4i-a10-sram-a3-a4"; - reg = <0x8000 0x4000>; - status = "disabled"; - }; }; diff --git a/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts b/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts index 42435454acef..34411d27aadf 100644 --- a/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts +++ b/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts @@ -46,7 +46,6 @@ #include #include #include -#include #include / { diff --git a/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts b/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts index 5879a75cf97a..2489c16f7efa 100644 --- a/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts +++ b/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "HSG H702"; diff --git a/sys/gnu/dts/arm/sun5i-a13-licheepi-one.dts b/sys/gnu/dts/arm/sun5i-a13-licheepi-one.dts index 566cda91a66b..bc883893f4a4 100644 --- a/sys/gnu/dts/arm/sun5i-a13-licheepi-one.dts +++ b/sys/gnu/dts/arm/sun5i-a13-licheepi-one.dts @@ -50,7 +50,6 @@ #include #include -#include / { model = "Lichee Pi One"; diff --git a/sys/gnu/dts/arm/sun5i-a13-olinuxino-micro.dts b/sys/gnu/dts/arm/sun5i-a13-olinuxino-micro.dts index 60e393e28783..3a831eaf1dfc 100644 --- a/sys/gnu/dts/arm/sun5i-a13-olinuxino-micro.dts +++ b/sys/gnu/dts/arm/sun5i-a13-olinuxino-micro.dts @@ -46,7 +46,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Olimex A13-Olinuxino Micro"; diff --git a/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts b/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts index 940d47e88056..95f591bb8ced 100644 --- a/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts +++ b/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Olimex A13-Olinuxino"; diff --git a/sys/gnu/dts/arm/sun5i-a13.dtsi b/sys/gnu/dts/arm/sun5i-a13.dtsi index fb2ddb9a04c9..6436bad94404 100644 --- a/sys/gnu/dts/arm/sun5i-a13.dtsi +++ b/sys/gnu/dts/arm/sun5i-a13.dtsi @@ -46,27 +46,11 @@ #include "sun5i.dtsi" -#include #include / { interrupt-parent = <&intc>; - chosen { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - framebuffer@0 { - compatible = "allwinner,simple-framebuffer", - "simple-framebuffer"; - allwinner,pipeline = "de_be0-lcd0"; - clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, - <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>; - status = "disabled"; - }; - }; - thermal-zones { cpu_thermal { /* milliseconds */ @@ -105,44 +89,6 @@ }; soc@01c00000 { - tcon0: lcd-controller@01c0c000 { - compatible = "allwinner,sun5i-a13-tcon"; - reg = <0x01c0c000 0x1000>; - interrupts = <44>; - resets = <&ccu RST_LCD>; - reset-names = "lcd"; - clocks = <&ccu CLK_AHB_LCD>, - <&ccu CLK_TCON_CH0>, - <&ccu CLK_TCON_CH1>; - clock-names = "ahb", - "tcon-ch0", - "tcon-ch1"; - clock-output-names = "tcon-pixel-clock"; - status = "disabled"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - tcon0_in: port@0 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - tcon0_in_be0: endpoint@0 { - reg = <0>; - remote-endpoint = <&be0_out_tcon0>; - }; - }; - - tcon0_out: port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - }; - }; - }; - pwm: pwm@01c20e00 { compatible = "allwinner,sun5i-a13-pwm"; reg = <0x01c20e00 0xc>; @@ -151,74 +97,6 @@ status = "disabled"; }; - fe0: display-frontend@01e00000 { - compatible = "allwinner,sun5i-a13-display-frontend"; - reg = <0x01e00000 0x20000>; - interrupts = <47>; - clocks = <&ccu CLK_DE_FE>, <&ccu CLK_DE_FE>, - <&ccu CLK_DRAM_DE_FE>; - clock-names = "ahb", "mod", - "ram"; - resets = <&ccu RST_DE_FE>; - status = "disabled"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - fe0_out: port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - - fe0_out_be0: endpoint@0 { - reg = <0>; - remote-endpoint = <&be0_in_fe0>; - }; - }; - }; - }; - - be0: display-backend@01e60000 { - compatible = "allwinner,sun5i-a13-display-backend"; - reg = <0x01e60000 0x10000>; - clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, - <&ccu CLK_DRAM_DE_BE>; - clock-names = "ahb", "mod", - "ram"; - resets = <&ccu RST_DE_BE>; - status = "disabled"; - - assigned-clocks = <&ccu CLK_DE_BE>; - assigned-clock-rates = <300000000>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - be0_in: port@0 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - be0_in_fe0: endpoint@0 { - reg = <0>; - remote-endpoint = <&fe0_out_be0>; - }; - }; - - be0_out: port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - - be0_out_tcon0: endpoint@0 { - reg = <0>; - remote-endpoint = <&tcon0_in_be0>; - }; - }; - }; - }; }; }; @@ -244,22 +122,4 @@ &pio { compatible = "allwinner,sun5i-a13-pinctrl"; - - lcd_rgb666_pins: lcd_rgb666@0 { - pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", - "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", - "PD18", "PD19", "PD20", "PD21", "PD22", "PD23", - "PD24", "PD25", "PD26", "PD27"; - function = "lcd0"; - }; - - uart1_pins_a: uart1@0 { - pins = "PE10", "PE11"; - function = "uart1"; - }; - - uart1_pins_b: uart1@1 { - pins = "PG3", "PG4"; - function = "uart1"; - }; }; diff --git a/sys/gnu/dts/arm/sun5i-gr8-chip-pro.dts b/sys/gnu/dts/arm/sun5i-gr8-chip-pro.dts index 0cf0813d363a..c55b11a4d3c7 100644 --- a/sys/gnu/dts/arm/sun5i-gr8-chip-pro.dts +++ b/sys/gnu/dts/arm/sun5i-gr8-chip-pro.dts @@ -171,7 +171,7 @@ &pwm { pinctrl-names = "default"; - pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins>; + pinctrl-0 = <&pwm0_pins>, <&pwm1_pins>; status = "disabled"; }; @@ -220,7 +220,7 @@ &uart1 { pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>; + pinctrl-0 = <&uart1_pins_b>, <&uart1_cts_rts_pins_a>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun5i-gr8-evb.dts b/sys/gnu/dts/arm/sun5i-gr8-evb.dts index 1a845af4d4db..558c16a30543 100644 --- a/sys/gnu/dts/arm/sun5i-gr8-evb.dts +++ b/sys/gnu/dts/arm/sun5i-gr8-evb.dts @@ -281,7 +281,7 @@ &pwm { pinctrl-names = "default"; - pinctrl-0 = <&pwm0_pins_a>; + pinctrl-0 = <&pwm0_pins>; status = "okay"; }; @@ -332,7 +332,7 @@ &uart1 { pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>; + pinctrl-0 = <&uart1_pins_b>, <&uart1_cts_rts_pins_a>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun5i-gr8.dtsi b/sys/gnu/dts/arm/sun5i-gr8.dtsi index cb9b2aaf7297..3eb56cad0cea 100644 --- a/sys/gnu/dts/arm/sun5i-gr8.dtsi +++ b/sys/gnu/dts/arm/sun5i-gr8.dtsi @@ -42,429 +42,19 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include "sun5i.dtsi" + #include #include -#include #include / { - interrupt-parent = <&intc>; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a8"; - reg = <0x0>; - clocks = <&ccu CLK_CPU>; - }; - }; - - clocks { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - osc24M: clk@01c20050 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <24000000>; - clock-output-names = "osc24M"; - }; - - osc32k: clk@0 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; - clock-output-names = "osc32k"; - }; - }; - display-engine { compatible = "allwinner,sun5i-a13-display-engine"; allwinner,pipelines = <&fe0>; }; soc@01c00000 { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram-controller@01c00000 { - compatible = "allwinner,sun4i-a10-sram-controller"; - reg = <0x01c00000 0x30>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram_a: sram@00000000 { - compatible = "mmio-sram"; - reg = <0x00000000 0xc000>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x00000000 0xc000>; - }; - - sram_d: sram@00010000 { - compatible = "mmio-sram"; - reg = <0x00010000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x00010000 0x1000>; - - otg_sram: sram-section@0000 { - compatible = "allwinner,sun4i-a10-sram-d"; - reg = <0x0000 0x1000>; - status = "disabled"; - }; - }; - }; - - dma: dma-controller@01c02000 { - compatible = "allwinner,sun4i-a10-dma"; - reg = <0x01c02000 0x1000>; - interrupts = <27>; - clocks = <&ccu CLK_AHB_DMA>; - #dma-cells = <2>; - }; - - nfc: nand@01c03000 { - compatible = "allwinner,sun4i-a10-nand"; - reg = <0x01c03000 0x1000>; - interrupts = <37>; - clocks = <&ccu CLK_AHB_NAND>, <&ccu CLK_NAND>; - clock-names = "ahb", "mod"; - dmas = <&dma SUN4I_DMA_DEDICATED 3>; - dma-names = "rxtx"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi0: spi@01c05000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c05000 0x1000>; - interrupts = <10>; - clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>; - clock-names = "ahb", "mod"; - dmas = <&dma SUN4I_DMA_DEDICATED 27>, - <&dma SUN4I_DMA_DEDICATED 26>; - dma-names = "rx", "tx"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi1: spi@01c06000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c06000 0x1000>; - interrupts = <11>; - clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>; - clock-names = "ahb", "mod"; - dmas = <&dma SUN4I_DMA_DEDICATED 9>, - <&dma SUN4I_DMA_DEDICATED 8>; - dma-names = "rx", "tx"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - tve0: tv-encoder@01c0a000 { - compatible = "allwinner,sun4i-a10-tv-encoder"; - reg = <0x01c0a000 0x1000>; - clocks = <&ccu CLK_AHB_TVE>; - resets = <&ccu RST_TVE>; - status = "disabled"; - - port { - #address-cells = <1>; - #size-cells = <0>; - - tve0_in_tcon0: endpoint@0 { - reg = <0>; - remote-endpoint = <&tcon0_out_tve0>; - }; - }; - }; - - tcon0: lcd-controller@01c0c000 { - compatible = "allwinner,sun5i-a13-tcon"; - reg = <0x01c0c000 0x1000>; - interrupts = <44>; - resets = <&ccu RST_LCD>; - reset-names = "lcd"; - clocks = <&ccu CLK_AHB_LCD>, - <&ccu CLK_TCON_CH0>, - <&ccu CLK_TCON_CH1>; - clock-names = "ahb", - "tcon-ch0", - "tcon-ch1"; - clock-output-names = "tcon-pixel-clock"; - status = "disabled"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - tcon0_in: port@0 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - tcon0_in_be0: endpoint@0 { - reg = <0>; - remote-endpoint = <&be0_out_tcon0>; - }; - }; - - tcon0_out: port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - - tcon0_out_tve0: endpoint@1 { - reg = <1>; - remote-endpoint = <&tve0_in_tcon0>; - }; - }; - }; - }; - - mmc0: mmc@01c0f000 { - compatible = "allwinner,sun5i-a13-mmc"; - reg = <0x01c0f000 0x1000>; - clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>; - clock-names = "ahb", "mmc"; - interrupts = <32>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - mmc1: mmc@01c10000 { - compatible = "allwinner,sun5i-a13-mmc"; - reg = <0x01c10000 0x1000>; - clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>; - clock-names = "ahb", "mmc"; - interrupts = <33>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - mmc2: mmc@01c11000 { - compatible = "allwinner,sun5i-a13-mmc"; - reg = <0x01c11000 0x1000>; - clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>; - clock-names = "ahb", "mmc"; - interrupts = <34>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - usb_otg: usb@01c13000 { - compatible = "allwinner,sun4i-a10-musb"; - reg = <0x01c13000 0x0400>; - clocks = <&ccu CLK_AHB_OTG>; - interrupts = <38>; - interrupt-names = "mc"; - phys = <&usbphy 0>; - phy-names = "usb"; - extcon = <&usbphy 0>; - allwinner,sram = <&otg_sram 1>; - status = "disabled"; - - dr_mode = "otg"; - }; - - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun5i-a13-usb-phy"; - reg = <0x01c13400 0x10 0x01c14800 0x4>; - reg-names = "phy_ctrl", "pmu1"; - clocks = <&ccu CLK_USB_PHY0>; - clock-names = "usb_phy"; - resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>; - reset-names = "usb0_reset", "usb1_reset"; - status = "disabled"; - }; - - ehci0: usb@01c14000 { - compatible = "allwinner,sun5i-a13-ehci", "generic-ehci"; - reg = <0x01c14000 0x100>; - interrupts = <39>; - clocks = <&ccu CLK_AHB_EHCI>; - phys = <&usbphy 1>; - phy-names = "usb"; - status = "disabled"; - }; - - ohci0: usb@01c14400 { - compatible = "allwinner,sun5i-a13-ohci", "generic-ohci"; - reg = <0x01c14400 0x100>; - interrupts = <40>; - clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>; - phys = <&usbphy 1>; - phy-names = "usb"; - status = "disabled"; - }; - - spi2: spi@01c17000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c17000 0x1000>; - interrupts = <12>; - clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>; - clock-names = "ahb", "mod"; - dmas = <&dma SUN4I_DMA_DEDICATED 29>, - <&dma SUN4I_DMA_DEDICATED 28>; - dma-names = "rx", "tx"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - ccu: clock@01c20000 { - compatible = "nextthing,gr8-ccu"; - reg = <0x01c20000 0x400>; - clocks = <&osc24M>, <&osc32k>; - clock-names = "hosc", "losc"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - intc: interrupt-controller@01c20400 { - compatible = "allwinner,sun4i-a10-ic"; - reg = <0x01c20400 0x400>; - interrupt-controller; - #interrupt-cells = <1>; - }; - - pio: pinctrl@01c20800 { - compatible = "nextthing,gr8-pinctrl"; - reg = <0x01c20800 0x400>; - interrupts = <28>; - clocks = <&ccu CLK_APB0_PIO>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <3>; - #gpio-cells = <3>; - - i2c0_pins_a: i2c0@0 { - pins = "PB0", "PB1"; - function = "i2c0"; - }; - - i2c1_pins_a: i2c1@0 { - pins = "PB15", "PB16"; - function = "i2c1"; - }; - - i2c2_pins_a: i2c2@0 { - pins = "PB17", "PB18"; - function = "i2c2"; - }; - - i2s0_data_pins_a: i2s0-data@0 { - pins = "PB6", "PB7", "PB8", "PB9"; - function = "i2s0"; - }; - - i2s0_mclk_pins_a: i2s0-mclk@0 { - pins = "PB5"; - function = "i2s0"; - }; - - ir0_rx_pins_a: ir0@0 { - pins = "PB4"; - function = "ir0"; - }; - - lcd_rgb666_pins: lcd-rgb666@0 { - pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", - "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", - "PD18", "PD19", "PD20", "PD21", "PD22", "PD23", - "PD24", "PD25", "PD26", "PD27"; - function = "lcd0"; - }; - - mmc0_pins_a: mmc0@0 { - pins = "PF0", "PF1", "PF2", "PF3", - "PF4", "PF5"; - function = "mmc0"; - drive-strength = <30>; - }; - - nand_pins_a: nand-base0@0 { - pins = "PC0", "PC1", "PC2", - "PC5", "PC8", "PC9", "PC10", - "PC11", "PC12", "PC13", "PC14", - "PC15"; - function = "nand0"; - }; - - nand_cs0_pins_a: nand-cs@0 { - pins = "PC4"; - function = "nand0"; - }; - - nand_rb0_pins_a: nand-rb@0 { - pins = "PC6"; - function = "nand0"; - }; - - pwm0_pins_a: pwm0@0 { - pins = "PB2"; - function = "pwm0"; - }; - - pwm1_pins: pwm1 { - pins = "PG13"; - function = "pwm1"; - }; - - spdif_tx_pins_a: spdif@0 { - pins = "PB10"; - function = "spdif"; - bias-pull-up; - }; - - uart1_pins_a: uart1@1 { - pins = "PG3", "PG4"; - function = "uart1"; - }; - - uart1_cts_rts_pins_a: uart1-cts-rts@0 { - pins = "PG5", "PG6"; - function = "uart1"; - }; - - uart2_pins_a: uart2@1 { - pins = "PD2", "PD3"; - function = "uart2"; - }; - - uart2_cts_rts_pins_a: uart2-cts-rts@0 { - pins = "PD4", "PD5"; - function = "uart2"; - }; - - uart3_pins_a: uart3@1 { - pins = "PG9", "PG10"; - function = "uart3"; - }; - - uart3_cts_rts_pins_a: uart3-cts-rts@0 { - pins = "PG11", "PG12"; - function = "uart3"; - }; - }; - pwm: pwm@01c20e00 { compatible = "allwinner,sun5i-a10s-pwm"; reg = <0x01c20e00 0xc>; @@ -473,18 +63,6 @@ status = "disabled"; }; - timer@01c20c00 { - compatible = "allwinner,sun4i-a10-timer"; - reg = <0x01c20c00 0x90>; - interrupts = <22>; - clocks = <&ccu CLK_HOSC>; - }; - - wdt: watchdog@01c20c90 { - compatible = "allwinner,sun4i-a10-wdt"; - reg = <0x01c20c90 0x10>; - }; - spdif: spdif@01c21000 { #sound-dai-cells = <0>; compatible = "allwinner,sun4i-a10-spdif"; @@ -498,15 +76,6 @@ status = "disabled"; }; - ir0: ir@01c21800 { - compatible = "allwinner,sun4i-a10-ir"; - clocks = <&ccu CLK_APB0_IR>, <&ccu CLK_IR>; - clock-names = "apb", "ir"; - interrupts = <5>; - reg = <0x01c21800 0x40>; - status = "disabled"; - }; - i2s0: i2s@01c22400 { #sound-dai-cells = <0>; compatible = "allwinner,sun4i-a10-i2s"; @@ -519,168 +88,39 @@ dma-names = "rx", "tx"; status = "disabled"; }; - - lradc: lradc@01c22800 { - compatible = "allwinner,sun4i-a10-lradc-keys"; - reg = <0x01c22800 0x100>; - interrupts = <31>; - status = "disabled"; - }; - - codec: codec@01c22c00 { - #sound-dai-cells = <0>; - compatible = "allwinner,sun4i-a10-codec"; - reg = <0x01c22c00 0x40>; - interrupts = <30>; - clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>; - clock-names = "apb", "codec"; - dmas = <&dma SUN4I_DMA_NORMAL 19>, - <&dma SUN4I_DMA_NORMAL 19>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - rtp: rtp@01c25000 { - compatible = "allwinner,sun5i-a13-ts"; - reg = <0x01c25000 0x100>; - interrupts = <29>; - #thermal-sensor-cells = <0>; - }; - - uart1: serial@01c28400 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28400 0x400>; - interrupts = <2>; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_APB1_UART1>; - status = "disabled"; - }; - - uart2: serial@01c28800 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28800 0x400>; - interrupts = <3>; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_APB1_UART2>; - status = "disabled"; - }; - - uart3: serial@01c28c00 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28c00 0x400>; - interrupts = <4>; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_APB1_UART3>; - status = "disabled"; - }; - - i2c0: i2c@01c2ac00 { - compatible = "allwinner,sun4i-a10-i2c"; - reg = <0x01c2ac00 0x400>; - interrupts = <7>; - clocks = <&ccu CLK_APB1_I2C0>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - i2c1: i2c@01c2b000 { - compatible = "allwinner,sun4i-a10-i2c"; - reg = <0x01c2b000 0x400>; - interrupts = <8>; - clocks = <&ccu CLK_APB1_I2C1>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - i2c2: i2c@01c2b400 { - compatible = "allwinner,sun4i-a10-i2c"; - reg = <0x01c2b400 0x400>; - interrupts = <9>; - clocks = <&ccu CLK_APB1_I2C2>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - timer@01c60000 { - compatible = "allwinner,sun5i-a13-hstimer"; - reg = <0x01c60000 0x1000>; - interrupts = <82>, <83>; - clocks = <&ccu CLK_AHB_HSTIMER>; - }; - - fe0: display-frontend@01e00000 { - compatible = "allwinner,sun5i-a13-display-frontend"; - reg = <0x01e00000 0x20000>; - interrupts = <47>; - clocks = <&ccu CLK_AHB_DE_FE>, <&ccu CLK_DE_FE>, - <&ccu CLK_DRAM_DE_FE>; - clock-names = "ahb", "mod", - "ram"; - resets = <&ccu RST_DE_FE>; - status = "disabled"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - fe0_out: port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - - fe0_out_be0: endpoint@0 { - reg = <0>; - remote-endpoint = <&be0_in_fe0>; - }; - }; - }; - }; - - be0: display-backend@01e60000 { - compatible = "allwinner,sun5i-a13-display-backend"; - reg = <0x01e60000 0x10000>; - clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, - <&ccu CLK_DRAM_DE_BE>; - clock-names = "ahb", "mod", - "ram"; - resets = <&ccu RST_DE_BE>; - status = "disabled"; - - assigned-clocks = <&ccu CLK_DE_BE>; - assigned-clock-rates = <300000000>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - be0_in: port@0 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - be0_in_fe0: endpoint@0 { - reg = <0>; - remote-endpoint = <&fe0_out_be0>; - }; - }; - - be0_out: port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - - be0_out_tcon0: endpoint@0 { - reg = <0>; - remote-endpoint = <&tcon0_in_be0>; - }; - }; - }; - }; + }; +}; + +&ccu { + compatible = "nextthing,gr8-ccu"; +}; + +&pio { + compatible = "nextthing,gr8-pinctrl"; + + i2s0_data_pins_a: i2s0-data@0 { + pins = "PB6", "PB7", "PB8", "PB9"; + function = "i2s0"; + }; + + i2s0_mclk_pins_a: i2s0-mclk@0 { + pins = "PB5"; + function = "i2s0"; + }; + + pwm1_pins: pwm1 { + pins = "PG13"; + function = "pwm1"; + }; + + spdif_tx_pins_a: spdif@0 { + pins = "PB10"; + function = "spdif"; + bias-pull-up; + }; + + uart1_cts_rts_pins_a: uart1-cts-rts@0 { + pins = "PG5", "PG6"; + function = "uart1"; }; }; diff --git a/sys/gnu/dts/arm/sun5i-r8-chip.dts b/sys/gnu/dts/arm/sun5i-r8-chip.dts index e86fa46fdd45..d0785602663b 100644 --- a/sys/gnu/dts/arm/sun5i-r8-chip.dts +++ b/sys/gnu/dts/arm/sun5i-r8-chip.dts @@ -128,6 +128,10 @@ #include "axp209.dtsi" +&ac_power_supply { + status = "okay"; +}; + &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins_a>; @@ -281,7 +285,7 @@ &uart3 { pinctrl-names = "default"; pinctrl-0 = <&uart3_pins_a>, - <&uart3_pins_cts_rts_a>; + <&uart3_cts_rts_pins_a>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun5i-r8.dtsi b/sys/gnu/dts/arm/sun5i-r8.dtsi index 4c1141396c99..de35dbcd1191 100644 --- a/sys/gnu/dts/arm/sun5i-r8.dtsi +++ b/sys/gnu/dts/arm/sun5i-r8.dtsi @@ -45,43 +45,3 @@ #include "sun5i-a13.dtsi" -/ { - chosen { - framebuffer@1 { - compatible = "allwinner,simple-framebuffer", - "simple-framebuffer"; - allwinner,pipeline = "de_be0-lcd0-tve0"; - clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>, - <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, - <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>; - status = "disabled"; - }; - }; - - soc@01c00000 { - tve0: tv-encoder@01c0a000 { - compatible = "allwinner,sun4i-a10-tv-encoder"; - reg = <0x01c0a000 0x1000>; - clocks = <&ccu CLK_AHB_TVE>; - resets = <&ccu RST_TVE>; - status = "disabled"; - - port { - #address-cells = <1>; - #size-cells = <0>; - - tve0_in_tcon0: endpoint@0 { - reg = <0>; - remote-endpoint = <&tcon0_out_tve0>; - }; - }; - }; - }; -}; - -&tcon0_out { - tcon0_out_tve0: endpoint@1 { - reg = <1>; - remote-endpoint = <&tve0_in_tcon0>; - }; -}; diff --git a/sys/gnu/dts/arm/sun5i.dtsi b/sys/gnu/dts/arm/sun5i.dtsi index a9574a6cd95c..5175f9cc9bed 100644 --- a/sys/gnu/dts/arm/sun5i.dtsi +++ b/sys/gnu/dts/arm/sun5i.dtsi @@ -46,7 +46,6 @@ #include #include -#include #include / { @@ -64,6 +63,31 @@ }; }; + chosen { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + framebuffer@0 { + compatible = "allwinner,simple-framebuffer", + "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0"; + clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, + <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>; + status = "disabled"; + }; + + framebuffer@1 { + compatible = "allwinner,simple-framebuffer", + "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0-tve0"; + clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>, + <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, + <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>; + status = "disabled"; + }; + }; + clocks { #address-cells = <1>; #size-cells = <1>; @@ -105,6 +129,12 @@ ranges = <0 0x00000000 0xc000>; }; + emac_sram: sram-section@8000 { + compatible = "allwinner,sun4i-a10-sram-a3-a4"; + reg = <0x8000 0x4000>; + status = "disabled"; + }; + sram_d: sram@00010000 { compatible = "mmio-sram"; reg = <0x00010000 0x1000>; @@ -128,6 +158,19 @@ #dma-cells = <2>; }; + nfc: nand@01c03000 { + compatible = "allwinner,sun4i-a10-nand"; + reg = <0x01c03000 0x1000>; + interrupts = <37>; + clocks = <&ccu CLK_AHB_NAND>, <&ccu CLK_NAND>; + clock-names = "ahb", "mod"; + dmas = <&dma SUN4I_DMA_DEDICATED 3>; + dma-names = "rxtx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + spi0: spi@01c05000 { compatible = "allwinner,sun4i-a10-spi"; reg = <0x01c05000 0x1000>; @@ -156,6 +199,84 @@ #size-cells = <0>; }; + tve0: tv-encoder@01c0a000 { + compatible = "allwinner,sun4i-a10-tv-encoder"; + reg = <0x01c0a000 0x1000>; + clocks = <&ccu CLK_AHB_TVE>; + resets = <&ccu RST_TVE>; + status = "disabled"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + tve0_in_tcon0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon0_out_tve0>; + }; + }; + }; + + emac: ethernet@01c0b000 { + compatible = "allwinner,sun4i-a10-emac"; + reg = <0x01c0b000 0x1000>; + interrupts = <55>; + clocks = <&ccu CLK_AHB_EMAC>; + allwinner,sram = <&emac_sram 1>; + status = "disabled"; + }; + + mdio: mdio@01c0b080 { + compatible = "allwinner,sun4i-a10-mdio"; + reg = <0x01c0b080 0x14>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + tcon0: lcd-controller@01c0c000 { + compatible = "allwinner,sun5i-a13-tcon"; + reg = <0x01c0c000 0x1000>; + interrupts = <44>; + resets = <&ccu RST_LCD>; + reset-names = "lcd"; + clocks = <&ccu CLK_AHB_LCD>, + <&ccu CLK_TCON_CH0>, + <&ccu CLK_TCON_CH1>; + clock-names = "ahb", + "tcon-ch0", + "tcon-ch1"; + clock-output-names = "tcon-pixel-clock"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon0_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + tcon0_in_be0: endpoint@0 { + reg = <0>; + remote-endpoint = <&be0_out_tcon0>; + }; + }; + + tcon0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + tcon0_out_tve0: endpoint@1 { + reg = <1>; + remote-endpoint = <&tve0_in_tcon0>; + }; + }; + }; + }; + mmc0: mmc@01c0f000 { compatible = "allwinner,sun5i-a13-mmc"; reg = <0x01c0f000 0x1000>; @@ -273,6 +394,15 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + emac_pins_a: emac0@0 { + pins = "PD6", "PD7", "PD10", + "PD11", "PD12", "PD13", "PD14", + "PD15", "PD18", "PD19", "PD20", + "PD21", "PD22", "PD23", "PD24", + "PD25", "PD26", "PD27"; + function = "emac"; + }; + i2c0_pins_a: i2c0@0 { pins = "PB0", "PB1"; function = "i2c0"; @@ -288,6 +418,11 @@ function = "i2c2"; }; + ir0_rx_pins_a: ir0@0 { + pins = "PB4"; + function = "ir0"; + }; + lcd_rgb565_pins: lcd_rgb565@0 { pins = "PD3", "PD4", "PD5", "PD6", "PD7", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", @@ -296,6 +431,14 @@ function = "lcd0"; }; + lcd_rgb666_pins: lcd_rgb666@0 { + pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", + "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", + "PD18", "PD19", "PD20", "PD21", "PD22", "PD23", + "PD24", "PD25", "PD26", "PD27"; + function = "lcd0"; + }; + mmc0_pins_a: mmc0@0 { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; @@ -321,6 +464,24 @@ bias-pull-up; }; + nand_pins_a: nand-base0@0 { + pins = "PC0", "PC1", "PC2", + "PC5", "PC8", "PC9", "PC10", + "PC11", "PC12", "PC13", "PC14", + "PC15"; + function = "nand0"; + }; + + nand_cs0_pins_a: nand-cs@0 { + pins = "PC4"; + function = "nand0"; + }; + + nand_rb0_pins_a: nand-rb@0 { + pins = "PC6"; + function = "nand0"; + }; + spi2_pins_a: spi2@0 { pins = "PE1", "PE2", "PE3"; function = "spi2"; @@ -331,12 +492,32 @@ function = "spi2"; }; + uart1_pins_a: uart1@0 { + pins = "PE10", "PE11"; + function = "uart1"; + }; + + uart1_pins_b: uart1@1 { + pins = "PG3", "PG4"; + function = "uart1"; + }; + + uart2_pins_a: uart2@0 { + pins = "PD2", "PD3"; + function = "uart2"; + }; + + uart2_cts_rts_pins_a: uart2-cts-rts@0 { + pins = "PD4", "PD5"; + function = "uart2"; + }; + uart3_pins_a: uart3@0 { pins = "PG9", "PG10"; function = "uart3"; }; - uart3_pins_cts_rts_a: uart3-cts-rts@0 { + uart3_cts_rts_pins_a: uart3-cts-rts@0 { pins = "PG11", "PG12"; function = "uart3"; }; @@ -359,6 +540,15 @@ reg = <0x01c20c90 0x10>; }; + ir0: ir@01c21800 { + compatible = "allwinner,sun4i-a10-ir"; + clocks = <&ccu CLK_APB0_IR>, <&ccu CLK_IR>; + clock-names = "apb", "ir"; + interrupts = <5>; + reg = <0x01c21800 0x40>; + status = "disabled"; + }; + lradc: lradc@01c22800 { compatible = "allwinner,sun4i-a10-lradc-keys"; reg = <0x01c22800 0x100>; @@ -391,6 +581,16 @@ #thermal-sensor-cells = <0>; }; + uart0: serial@01c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>; + interrupts = <1>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_APB1_UART0>; + status = "disabled"; + }; + uart1: serial@01c28400 { compatible = "snps,dw-apb-uart"; reg = <0x01c28400 0x400>; @@ -401,6 +601,16 @@ status = "disabled"; }; + uart2: serial@01c28800 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28800 0x400>; + interrupts = <3>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_APB1_UART2>; + status = "disabled"; + }; + uart3: serial@01c28c00 { compatible = "snps,dw-apb-uart"; reg = <0x01c28c00 0x400>; @@ -447,5 +657,75 @@ interrupts = <82>, <83>; clocks = <&ccu CLK_AHB_HSTIMER>; }; + + fe0: display-frontend@01e00000 { + compatible = "allwinner,sun5i-a13-display-frontend"; + reg = <0x01e00000 0x20000>; + interrupts = <47>; + clocks = <&ccu CLK_DE_FE>, <&ccu CLK_DE_FE>, + <&ccu CLK_DRAM_DE_FE>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_DE_FE>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + fe0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + fe0_out_be0: endpoint@0 { + reg = <0>; + remote-endpoint = <&be0_in_fe0>; + }; + }; + }; + }; + + be0: display-backend@01e60000 { + compatible = "allwinner,sun5i-a13-display-backend"; + reg = <0x01e60000 0x10000>; + interrupts = <47>; + clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>, + <&ccu CLK_DRAM_DE_BE>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_DE_BE>; + status = "disabled"; + + assigned-clocks = <&ccu CLK_DE_BE>; + assigned-clock-rates = <300000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + be0_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + be0_in_fe0: endpoint@0 { + reg = <0>; + remote-endpoint = <&fe0_out_be0>; + }; + }; + + be0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + be0_out_tcon0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon0_in_be0>; + }; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/sun6i-a31-app4-evb1.dts b/sys/gnu/dts/arm/sun6i-a31-app4-evb1.dts index effbdc766938..7f34323a668c 100644 --- a/sys/gnu/dts/arm/sun6i-a31-app4-evb1.dts +++ b/sys/gnu/dts/arm/sun6i-a31-app4-evb1.dts @@ -47,7 +47,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Allwinner A31 APP4 EVB1 Evaluation Board"; diff --git a/sys/gnu/dts/arm/sun6i-a31-colombus.dts b/sys/gnu/dts/arm/sun6i-a31-colombus.dts index f5ececd45bc0..85eff0307ca4 100644 --- a/sys/gnu/dts/arm/sun6i-a31-colombus.dts +++ b/sys/gnu/dts/arm/sun6i-a31-colombus.dts @@ -47,7 +47,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "WITS A31 Colombus Evaluation Board"; diff --git a/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts b/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts index f094eeb6c499..d4f74f476f25 100644 --- a/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts +++ b/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts @@ -47,7 +47,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Merrii A31 Hummingbird"; diff --git a/sys/gnu/dts/arm/sun6i-a31-i7.dts b/sys/gnu/dts/arm/sun6i-a31-i7.dts index 2bc57d2dcd80..010a84c7c012 100644 --- a/sys/gnu/dts/arm/sun6i-a31-i7.dts +++ b/sys/gnu/dts/arm/sun6i-a31-i7.dts @@ -45,7 +45,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Mele I7 Quad top set box"; diff --git a/sys/gnu/dts/arm/sun6i-a31-m9.dts b/sys/gnu/dts/arm/sun6i-a31-m9.dts index 8af5b667a46d..50605fd4449e 100644 --- a/sys/gnu/dts/arm/sun6i-a31-m9.dts +++ b/sys/gnu/dts/arm/sun6i-a31-m9.dts @@ -45,7 +45,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Mele M9 top set box"; diff --git a/sys/gnu/dts/arm/sun6i-a31-mele-a1000g-quad.dts b/sys/gnu/dts/arm/sun6i-a31-mele-a1000g-quad.dts index bf0f5831126f..5219556e9f73 100644 --- a/sys/gnu/dts/arm/sun6i-a31-mele-a1000g-quad.dts +++ b/sys/gnu/dts/arm/sun6i-a31-mele-a1000g-quad.dts @@ -45,7 +45,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Mele A1000G Quad top set box"; diff --git a/sys/gnu/dts/arm/sun6i-a31.dtsi b/sys/gnu/dts/arm/sun6i-a31.dtsi index a4b96184cac1..9c999d3788f6 100644 --- a/sys/gnu/dts/arm/sun6i-a31.dtsi +++ b/sys/gnu/dts/arm/sun6i-a31.dtsi @@ -48,7 +48,6 @@ #include #include -#include #include / { diff --git a/sys/gnu/dts/arm/sun6i-a31s-cs908.dts b/sys/gnu/dts/arm/sun6i-a31s-cs908.dts index 5e8f8c4f2b30..75e578159c3a 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-cs908.dts +++ b/sys/gnu/dts/arm/sun6i-a31s-cs908.dts @@ -43,8 +43,6 @@ /dts-v1/; #include "sun6i-a31s.dtsi" -#include - / { model = "CSQ CS908 top set box"; compatible = "csq,cs908", "allwinner,sun6i-a31s"; diff --git a/sys/gnu/dts/arm/sun6i-a31s-primo81.dts b/sys/gnu/dts/arm/sun6i-a31s-primo81.dts index 2238eda318f6..f3712753fa42 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-primo81.dts +++ b/sys/gnu/dts/arm/sun6i-a31s-primo81.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "MSI Primo81 tablet"; diff --git a/sys/gnu/dts/arm/sun6i-a31s-sina31s-core.dtsi b/sys/gnu/dts/arm/sun6i-a31s-sina31s-core.dtsi index 4ec0c8679b2e..d7325bc4eeb4 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-sina31s-core.dtsi +++ b/sys/gnu/dts/arm/sun6i-a31s-sina31s-core.dtsi @@ -45,7 +45,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Sinlinx SinA31s Core Board"; diff --git a/sys/gnu/dts/arm/sun6i-a31s-sina31s.dts b/sys/gnu/dts/arm/sun6i-a31s-sina31s.dts index 7ff68bdd7109..b3d98222bd81 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-sina31s.dts +++ b/sys/gnu/dts/arm/sun6i-a31s-sina31s.dts @@ -63,6 +63,23 @@ gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>; /* PH13 */ }; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "On-board SPDIF"; + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + + simple-audio-card,codec { + sound-dai = <&spdif_out>; + }; + }; + + spdif_out: spdif-out { + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; + }; }; &codec { @@ -153,6 +170,12 @@ regulator-name = "vcc-gmac-phy"; }; +&spdif { + pinctrl-names = "default"; + pinctrl-0 = <&spdif_pins_a>; + status = "okay"; +}; + &usb_otg { dr_mode = "peripheral"; status = "okay"; diff --git a/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts b/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts index 3bd862bf82a9..bdfdce8ca6ba 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts +++ b/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts @@ -86,6 +86,10 @@ }; }; +&cpu0 { + cpu-supply = <®_dcdc3>; +}; + &ehci0 { status = "okay"; }; @@ -151,6 +155,17 @@ status = "okay"; }; +&p2wi { + status = "okay"; + + axp22x: pmic@68 { + compatible = "x-powers,axp221"; + reg = <0x68>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + &pio { gmac_phy_reset_pin_bpi_m2: gmac_phy_reset_pin@0 { pins = "PA21"; @@ -176,6 +191,48 @@ }; }; +#include "axp22x.dtsi" + +®_dc5ldo { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1320000>; + regulator-name = "vdd-cpus"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vdd-3v0"; +}; + +®_dcdc2 { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1320000>; + regulator-name = "vdd-gpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1320000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc4 { + regulator-always-on; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1320000>; + regulator-name = "vdd-sys-dll"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; diff --git a/sys/gnu/dts/arm/sun6i-a31s-yones-toptech-bs1078-v2.dts b/sys/gnu/dts/arm/sun6i-a31s-yones-toptech-bs1078-v2.dts index 154ebf5082ed..f3edf9ca435c 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-yones-toptech-bs1078-v2.dts +++ b/sys/gnu/dts/arm/sun6i-a31s-yones-toptech-bs1078-v2.dts @@ -45,7 +45,6 @@ #include "sunxi-common-regulators.dtsi" #include -#include / { model = "Yones TopTech BS1078 v2 Tablet"; diff --git a/sys/gnu/dts/arm/sun6i-reference-design-tablet.dtsi b/sys/gnu/dts/arm/sun6i-reference-design-tablet.dtsi index edaba5f904fd..3cc4046b904a 100644 --- a/sys/gnu/dts/arm/sun6i-reference-design-tablet.dtsi +++ b/sys/gnu/dts/arm/sun6i-reference-design-tablet.dtsi @@ -44,7 +44,6 @@ #include #include -#include / { aliases { diff --git a/sys/gnu/dts/arm/sun7i-a20-bananapi.dts b/sys/gnu/dts/arm/sun7i-a20-bananapi.dts index 91f2e5f9efcb..ed2f35adf542 100644 --- a/sys/gnu/dts/arm/sun7i-a20-bananapi.dts +++ b/sys/gnu/dts/arm/sun7i-a20-bananapi.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "LeMaker Banana Pi"; diff --git a/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts b/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts index 4dc1e10f88c4..a2eab7aa80e0 100644 --- a/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts +++ b/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Cubietech Cubieboard2"; diff --git a/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts b/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts index f019aa3fe96d..102903e83bd2 100644 --- a/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts +++ b/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Cubietech Cubietruck"; @@ -268,6 +267,10 @@ #include "axp209.dtsi" +&ac_power_supply { + status = "okay"; +}; + ®_dcdc2 { regulator-always-on; regulator-min-microvolt = <1000000>; @@ -324,6 +327,10 @@ status = "okay"; }; +&usb_power_supply { + status = "okay"; +}; + &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; diff --git a/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts b/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts index e921ba42f170..99c00b9a1546 100644 --- a/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts +++ b/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Merrii A20 Hummingbird"; diff --git a/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts b/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts index 385fd8232ae0..4da49717da21 100644 --- a/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts +++ b/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "I12 / Q5 / QT840A A20 tvbox"; diff --git a/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts b/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts index f5b5325a70e2..28d3abbdc2d4 100644 --- a/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts +++ b/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "ICnova-A20 SWAC"; diff --git a/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts b/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts index bbf1c8cbaac6..96bb0bc198ba 100644 --- a/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts +++ b/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Lamobo R1"; diff --git a/sys/gnu/dts/arm/sun7i-a20-m3.dts b/sys/gnu/dts/arm/sun7i-a20-m3.dts index 0e074bd0e8c9..86f69813683e 100644 --- a/sys/gnu/dts/arm/sun7i-a20-m3.dts +++ b/sys/gnu/dts/arm/sun7i-a20-m3.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Mele M3"; diff --git a/sys/gnu/dts/arm/sun7i-a20-mk808c.dts b/sys/gnu/dts/arm/sun7i-a20-mk808c.dts index 97d7a8b65a03..c4ee30709f3a 100644 --- a/sys/gnu/dts/arm/sun7i-a20-mk808c.dts +++ b/sys/gnu/dts/arm/sun7i-a20-mk808c.dts @@ -53,7 +53,6 @@ #include #include -#include / { model = "mk808c"; diff --git a/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts b/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts index a1450c10b08e..1af5b46862cb 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts @@ -48,7 +48,6 @@ #include #include #include -#include / { model = "Olimex A20-Olimex-SOM-EVB"; diff --git a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts index 1297432c2802..dcd0f7a0dffa 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts @@ -49,7 +49,6 @@ #include #include -#include / { model = "Olimex A20-OLinuXino-LIME"; diff --git a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts index 71cca5360728..e7d45425758c 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Olimex A20-OLinuXino-LIME2"; diff --git a/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts b/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts index 223fbd9f7c62..def0ad8395bb 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts @@ -49,7 +49,6 @@ #include #include #include -#include / { model = "Olimex A20-Olinuxino Micro"; @@ -85,6 +84,14 @@ status = "okay"; }; +&codec { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + &ehci0 { status = "okay"; }; @@ -111,13 +118,9 @@ status = "okay"; axp209: pmic@34 { - compatible = "x-powers,axp209"; reg = <0x34>; interrupt-parent = <&nmi_intc>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; - - interrupt-controller; - #interrupt-cells = <1>; }; }; @@ -251,6 +254,29 @@ }; }; +#include "axp209.dtsi" + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-int-dll"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + ®_ahci_5v { status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun7i-a20-orangepi-mini.dts b/sys/gnu/dts/arm/sun7i-a20-orangepi-mini.dts index a74265749227..7af4c8fc1865 100644 --- a/sys/gnu/dts/arm/sun7i-a20-orangepi-mini.dts +++ b/sys/gnu/dts/arm/sun7i-a20-orangepi-mini.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Orange Pi Mini"; diff --git a/sys/gnu/dts/arm/sun7i-a20-orangepi.dts b/sys/gnu/dts/arm/sun7i-a20-orangepi.dts index 3de980c8f8ff..0a8d4a05e8a0 100644 --- a/sys/gnu/dts/arm/sun7i-a20-orangepi.dts +++ b/sys/gnu/dts/arm/sun7i-a20-orangepi.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Orange Pi"; diff --git a/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts b/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts index 4599f98a3aee..7c96b53b76bf 100644 --- a/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts +++ b/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts @@ -48,7 +48,6 @@ #include #include #include -#include / { model = "LinkSprite pcDuino3"; diff --git a/sys/gnu/dts/arm/sun7i-a20.dtsi b/sys/gnu/dts/arm/sun7i-a20.dtsi index 2db97fc820dd..93aa55970bd7 100644 --- a/sys/gnu/dts/arm/sun7i-a20.dtsi +++ b/sys/gnu/dts/arm/sun7i-a20.dtsi @@ -49,7 +49,6 @@ #include #include -#include / { interrupt-parent = <&gic>; @@ -1096,6 +1095,11 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + can0_pins_a: can0@0 { + pins = "PH20", "PH21"; + function = "can"; + }; + clk_out_a_pins_a: clk_out_a@0 { pins = "PI12"; function = "clk_out_a"; @@ -1538,6 +1542,22 @@ status = "disabled"; }; + ps20: ps2@01c2a000 { + compatible = "allwinner,sun4i-a10-ps2"; + reg = <0x01c2a000 0x400>; + interrupts = ; + clocks = <&apb1_gates 6>; + status = "disabled"; + }; + + ps21: ps2@01c2a400 { + compatible = "allwinner,sun4i-a10-ps2"; + reg = <0x01c2a400 0x400>; + interrupts = ; + clocks = <&apb1_gates 7>; + status = "disabled"; + }; + i2c0: i2c@01c2ac00 { compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c"; @@ -1582,6 +1602,15 @@ #size-cells = <0>; }; + can0: can@01c2bc00 { + compatible = "allwinner,sun7i-a20-can", + "allwinner,sun4i-a10-can"; + reg = <0x01c2bc00 0x400>; + interrupts = ; + clocks = <&apb1_gates 4>; + status = "disabled"; + }; + i2c4: i2c@01c2c000 { compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c"; @@ -1629,20 +1658,5 @@ interrupts = ; }; - ps20: ps2@01c2a000 { - compatible = "allwinner,sun4i-a10-ps2"; - reg = <0x01c2a000 0x400>; - interrupts = ; - clocks = <&apb1_gates 6>; - status = "disabled"; - }; - - ps21: ps2@01c2a400 { - compatible = "allwinner,sun4i-a10-ps2"; - reg = <0x01c2a400 0x400>; - interrupts = ; - clocks = <&apb1_gates 7>; - status = "disabled"; - }; }; }; diff --git a/sys/gnu/dts/arm/sun8i-a23-a33.dtsi b/sys/gnu/dts/arm/sun8i-a23-a33.dtsi index 8a3ed21cb7bc..a8b978d0f35b 100644 --- a/sys/gnu/dts/arm/sun8i-a23-a33.dtsi +++ b/sys/gnu/dts/arm/sun8i-a23-a33.dtsi @@ -47,7 +47,6 @@ #include #include -#include #include / { @@ -493,6 +492,7 @@ clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>; clock-names = "bus", "core"; resets = <&ccu RST_BUS_GPU>; + #cooling-cells = <2>; assigned-clocks = <&ccu CLK_GPU>; assigned-clock-rates = <384000000>; diff --git a/sys/gnu/dts/arm/sun8i-a23-evb.dts b/sys/gnu/dts/arm/sun8i-a23-evb.dts index c21f5b1b255e..87289a60c520 100644 --- a/sys/gnu/dts/arm/sun8i-a23-evb.dts +++ b/sys/gnu/dts/arm/sun8i-a23-evb.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Allwinner A23 Evaluation Board"; diff --git a/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v1.2.dts b/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v1.2.dts index 3ab5c0c09d93..b6958e8f2f01 100644 --- a/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v1.2.dts +++ b/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v1.2.dts @@ -50,7 +50,6 @@ }; &codec { - pinctrl-0 = <&codec_pa_pin>; allwinner,pa-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */ allwinner,audio-routing = "Headphone", "HP", @@ -62,12 +61,3 @@ "Headset Mic", "HBIAS"; status = "okay"; }; - -&pio { - codec_pa_pin: codec_pa_pin@0 { - allwinner,pins = "PH9"; - allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; - }; -}; diff --git a/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v5.dts b/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v5.dts index 3ab5c0c09d93..b6958e8f2f01 100644 --- a/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v5.dts +++ b/sys/gnu/dts/arm/sun8i-a23-ippo-q8h-v5.dts @@ -50,7 +50,6 @@ }; &codec { - pinctrl-0 = <&codec_pa_pin>; allwinner,pa-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */ allwinner,audio-routing = "Headphone", "HP", @@ -62,12 +61,3 @@ "Headset Mic", "HBIAS"; status = "okay"; }; - -&pio { - codec_pa_pin: codec_pa_pin@0 { - allwinner,pins = "PH9"; - allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; - }; -}; diff --git a/sys/gnu/dts/arm/sun8i-a23-q8-tablet.dts b/sys/gnu/dts/arm/sun8i-a23-q8-tablet.dts index 3ab5c0c09d93..b6958e8f2f01 100644 --- a/sys/gnu/dts/arm/sun8i-a23-q8-tablet.dts +++ b/sys/gnu/dts/arm/sun8i-a23-q8-tablet.dts @@ -50,7 +50,6 @@ }; &codec { - pinctrl-0 = <&codec_pa_pin>; allwinner,pa-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */ allwinner,audio-routing = "Headphone", "HP", @@ -62,12 +61,3 @@ "Headset Mic", "HBIAS"; status = "okay"; }; - -&pio { - codec_pa_pin: codec_pa_pin@0 { - allwinner,pins = "PH9"; - allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; - }; -}; diff --git a/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts b/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts index 03b89bdd55ba..9b620cc1d5f1 100644 --- a/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts +++ b/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts @@ -48,7 +48,6 @@ #include #include -#include / { model = "Sinlinx SinA33"; @@ -84,6 +83,24 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <®_dcdc3>; +}; + +&cpu0_opp_table { + opp@1104000000 { + opp-hz = /bits/ 64 <1104000000>; + opp-microvolt = <1320000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1320000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; +}; + &de { status = "okay"; }; @@ -175,6 +192,10 @@ #include "axp223.dtsi" +&ac_power_supply { + status = "okay"; +}; + ®_aldo1 { regulator-always-on; regulator-min-microvolt = <3000000>; diff --git a/sys/gnu/dts/arm/sun8i-a33.dtsi b/sys/gnu/dts/arm/sun8i-a33.dtsi index 306af6cadf26..013978259372 100644 --- a/sys/gnu/dts/arm/sun8i-a33.dtsi +++ b/sys/gnu/dts/arm/sun8i-a33.dtsi @@ -43,24 +43,79 @@ */ #include "sun8i-a23-a33.dtsi" +#include / { cpu0_opp_table: opp_table0 { compatible = "operating-points-v2"; opp-shared; + opp@120000000 { + opp-hz = /bits/ 64 <120000000>; + opp-microvolt = <1040000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@240000000 { + opp-hz = /bits/ 64 <240000000>; + opp-microvolt = <1040000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@312000000 { + opp-hz = /bits/ 64 <312000000>; + opp-microvolt = <1040000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <1040000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@480000000 { + opp-hz = /bits/ 64 <480000000>; + opp-microvolt = <1040000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@504000000 { + opp-hz = /bits/ 64 <504000000>; + opp-microvolt = <1040000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <1040000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + opp@648000000 { opp-hz = /bits/ 64 <648000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; + opp@720000000 { + opp-hz = /bits/ 64 <720000000>; + opp-microvolt = <1100000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + opp@816000000 { opp-hz = /bits/ 64 <816000000>; opp-microvolt = <1100000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; + opp@912000000 { + opp-hz = /bits/ 64 <912000000>; + opp-microvolt = <1200000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + opp@1008000000 { opp-hz = /bits/ 64 <1008000000>; opp-microvolt = <1200000>; @@ -73,6 +128,7 @@ clocks = <&ccu CLK_CPUX>; clock-names = "cpu"; operating-points-v2 = <&cpu0_opp_table>; + #cooling-cells = <2>; }; cpu@1 { @@ -100,6 +156,27 @@ status = "disabled"; }; + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&ths>; + }; + + mali_opp_table: gpu-opp-table { + compatible = "operating-points-v2"; + + opp@144000000 { + opp-hz = /bits/ 64 <144000000>; + }; + + opp@240000000 { + opp-hz = /bits/ 64 <240000000>; + }; + + opp@384000000 { + opp-hz = /bits/ 64 <384000000>; + }; + }; + memory { reg = <0x40000000 0x80000000>; }; @@ -196,6 +273,13 @@ status = "disabled"; }; + ths: ths@01c25000 { + compatible = "allwinner,sun8i-a33-ths"; + reg = <0x01c25000 0x100>; + #thermal-sensor-cells = <0>; + #io-channel-cells = <0>; + }; + fe0: display-frontend@01e00000 { compatible = "allwinner,sun8i-a33-display-frontend"; reg = <0x01e00000 0x20000>; @@ -306,12 +390,83 @@ }; }; }; + + thermal-zones { + cpu_thermal { + /* milliseconds */ + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&ths>; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu_alert1>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map2 { + trip = <&gpu_alert0>; + cooling-device = <&mali 1 THERMAL_NO_LIMIT>; + }; + + map3 { + trip = <&gpu_alert1>; + cooling-device = <&mali 2 THERMAL_NO_LIMIT>; + }; + }; + + trips { + cpu_alert0: cpu_alert0 { + /* milliCelsius */ + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + + gpu_alert0: gpu_alert0 { + /* milliCelsius */ + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_alert1: cpu_alert1 { + /* milliCelsius */ + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpu_alert1: gpu_alert1 { + /* milliCelsius */ + temperature = <95000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu_crit: cpu_crit { + /* milliCelsius */ + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; }; &ccu { compatible = "allwinner,sun8i-a33-ccu"; }; +&mali { + operating-points-v2 = <&mali_opp_table>; +}; + &pio { compatible = "allwinner,sun8i-a33-pinctrl"; interrupts = , diff --git a/sys/gnu/dts/arm/sun8i-a83t.dtsi b/sys/gnu/dts/arm/sun8i-a83t.dtsi index a789a7caf217..0ec143773ee9 100644 --- a/sys/gnu/dts/arm/sun8i-a83t.dtsi +++ b/sys/gnu/dts/arm/sun8i-a83t.dtsi @@ -47,8 +47,6 @@ #include -#include - / { interrupt-parent = <&gic>; diff --git a/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts b/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts index b7ca916d871d..9e8b082c134f 100644 --- a/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts +++ b/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts @@ -49,7 +49,6 @@ #include #include -#include / { model = "Xunlong Orange Pi Zero"; @@ -96,6 +95,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -132,6 +135,10 @@ bias-pull-up; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; @@ -154,7 +161,17 @@ status = "disabled"; }; -&usbphy { - /* USB VBUS is always on */ +&usb_otg { + dr_mode = "peripheral"; status = "okay"; }; + +&usbphy { + /* + * USB Type-A port VBUS is always on. However, MicroUSB VBUS can only + * power up the board; when it's used as OTG port, this VBUS is + * always off even if the board is powered via GPIO pins. + */ + status = "okay"; + usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ +}; diff --git a/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts b/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts index c0c49dd4d3b2..52acbe111cad 100644 --- a/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts +++ b/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Banana Pi BPI-M2-Plus"; diff --git a/sys/gnu/dts/arm/sun8i-h3-beelink-x2.dts b/sys/gnu/dts/arm/sun8i-h3-beelink-x2.dts index 25b225b7dfd6..e7fae65eb5d3 100644 --- a/sys/gnu/dts/arm/sun8i-h3-beelink-x2.dts +++ b/sys/gnu/dts/arm/sun8i-h3-beelink-x2.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Beelink X2"; @@ -138,6 +137,16 @@ }; }; +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + &ohci1 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun8i-h3-nanopi-neo-air.dts b/sys/gnu/dts/arm/sun8i-h3-nanopi-neo-air.dts new file mode 100644 index 000000000000..03ff6f8b93ff --- /dev/null +++ b/sys/gnu/dts/arm/sun8i-h3-nanopi-neo-air.dts @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2017 Jelle van der Waa + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-h3.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include + +/ { + model = "FriendlyARM NanoPi NEO Air"; + compatible = "friendlyarm,nanopi-neo-air", "allwinner,sun8i-h3"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + pwr { + label = "nanopi:green:pwr"; + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */ + default-state = "on"; + }; + + status { + label = "nanopi:blue:status"; + gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>; /* PA10 */ + }; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + /* USB VBUS is always on */ + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/sun8i-h3-nanopi.dtsi b/sys/gnu/dts/arm/sun8i-h3-nanopi.dtsi index 2216e68d1838..c6decee41a27 100644 --- a/sys/gnu/dts/arm/sun8i-h3-nanopi.dtsi +++ b/sys/gnu/dts/arm/sun8i-h3-nanopi.dtsi @@ -47,7 +47,6 @@ #include #include -#include / { aliases { diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts index 047e9e1c6093..5b6d14555b7c 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Xunlong Orange Pi 2"; diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-lite.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-lite.dts index 22b99b407019..9b47a0def740 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-lite.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-lite.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Xunlong Orange Pi Lite"; diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-one.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-one.dts index 34da853ee037..5fea430e0eb1 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-one.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-one.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Xunlong Orange Pi One"; @@ -90,6 +89,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -104,6 +107,10 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; @@ -127,6 +134,11 @@ }; }; +®_usb0_vbus { + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -151,7 +163,14 @@ status = "disabled"; }; -&usbphy { - /* USB VBUS is always on */ +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + /* USB Type-A port's VBUS is always on */ + usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ + usb0_vbus-supply = <®_usb0_vbus>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts index d43978d3294e..f148111c326d 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts @@ -46,7 +46,6 @@ #include #include -#include / { model = "Xunlong Orange Pi PC"; diff --git a/sys/gnu/dts/arm/sun8i-h3.dtsi b/sys/gnu/dts/arm/sun8i-h3.dtsi index 27780b97c863..b36f9f423c39 100644 --- a/sys/gnu/dts/arm/sun8i-h3.dtsi +++ b/sys/gnu/dts/arm/sun8i-h3.dtsi @@ -40,16 +40,9 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "skeleton.dtsi" - -#include -#include -#include -#include +#include "sunxi-h3-h5.dtsi" / { - interrupt-parent = <&gic>; - cpus { #address-cells = <1>; #size-cells = <0>; @@ -86,563 +79,48 @@ , ; }; - - clocks { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - osc24M: osc24M_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <24000000>; - clock-output-names = "osc24M"; - }; - - osc32k: osc32k_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; - clock-output-names = "osc32k"; - }; - - apb0: apb0_clk { - compatible = "fixed-factor-clock"; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clocks = <&osc24M>; - clock-output-names = "apb0"; - }; - - apb0_gates: clk@01f01428 { - compatible = "allwinner,sun8i-h3-apb0-gates-clk", - "allwinner,sun4i-a10-gates-clk"; - reg = <0x01f01428 0x4>; - #clock-cells = <1>; - clocks = <&apb0>; - clock-indices = <0>, <1>; - clock-output-names = "apb0_pio", "apb0_ir"; - }; - - ir_clk: ir_clk@01f01454 { - compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01f01454 0x4>; - #clock-cells = <0>; - clocks = <&osc32k>, <&osc24M>; - clock-output-names = "ir"; - }; - }; - - soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - dma: dma-controller@01c02000 { - compatible = "allwinner,sun8i-h3-dma"; - reg = <0x01c02000 0x1000>; - interrupts = ; - clocks = <&ccu CLK_BUS_DMA>; - resets = <&ccu RST_BUS_DMA>; - #dma-cells = <1>; - }; - - mmc0: mmc@01c0f000 { - compatible = "allwinner,sun7i-a20-mmc"; - reg = <0x01c0f000 0x1000>; - clocks = <&ccu CLK_BUS_MMC0>, - <&ccu CLK_MMC0>, - <&ccu CLK_MMC0_OUTPUT>, - <&ccu CLK_MMC0_SAMPLE>; - clock-names = "ahb", - "mmc", - "output", - "sample"; - resets = <&ccu RST_BUS_MMC0>; - reset-names = "ahb"; - interrupts = ; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - mmc1: mmc@01c10000 { - compatible = "allwinner,sun7i-a20-mmc"; - reg = <0x01c10000 0x1000>; - clocks = <&ccu CLK_BUS_MMC1>, - <&ccu CLK_MMC1>, - <&ccu CLK_MMC1_OUTPUT>, - <&ccu CLK_MMC1_SAMPLE>; - clock-names = "ahb", - "mmc", - "output", - "sample"; - resets = <&ccu RST_BUS_MMC1>; - reset-names = "ahb"; - interrupts = ; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - mmc2: mmc@01c11000 { - compatible = "allwinner,sun7i-a20-mmc"; - reg = <0x01c11000 0x1000>; - clocks = <&ccu CLK_BUS_MMC2>, - <&ccu CLK_MMC2>, - <&ccu CLK_MMC2_OUTPUT>, - <&ccu CLK_MMC2_SAMPLE>; - clock-names = "ahb", - "mmc", - "output", - "sample"; - resets = <&ccu RST_BUS_MMC2>; - reset-names = "ahb"; - interrupts = ; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - usbphy: phy@01c19400 { - compatible = "allwinner,sun8i-h3-usb-phy"; - reg = <0x01c19400 0x2c>, - <0x01c1a800 0x4>, - <0x01c1b800 0x4>, - <0x01c1c800 0x4>, - <0x01c1d800 0x4>; - reg-names = "phy_ctrl", - "pmu0", - "pmu1", - "pmu2", - "pmu3"; - clocks = <&ccu CLK_USB_PHY0>, - <&ccu CLK_USB_PHY1>, - <&ccu CLK_USB_PHY2>, - <&ccu CLK_USB_PHY3>; - clock-names = "usb0_phy", - "usb1_phy", - "usb2_phy", - "usb3_phy"; - resets = <&ccu RST_USB_PHY0>, - <&ccu RST_USB_PHY1>, - <&ccu RST_USB_PHY2>, - <&ccu RST_USB_PHY3>; - reset-names = "usb0_reset", - "usb1_reset", - "usb2_reset", - "usb3_reset"; - status = "disabled"; - #phy-cells = <1>; - }; - - ehci1: usb@01c1b000 { - compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; - reg = <0x01c1b000 0x100>; - interrupts = ; - clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>; - resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>; - phys = <&usbphy 1>; - phy-names = "usb"; - status = "disabled"; - }; - - ohci1: usb@01c1b400 { - compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; - reg = <0x01c1b400 0x100>; - interrupts = ; - clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>, - <&ccu CLK_USB_OHCI1>; - resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>; - phys = <&usbphy 1>; - phy-names = "usb"; - status = "disabled"; - }; - - ehci2: usb@01c1c000 { - compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; - reg = <0x01c1c000 0x100>; - interrupts = ; - clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>; - resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>; - phys = <&usbphy 2>; - phy-names = "usb"; - status = "disabled"; - }; - - ohci2: usb@01c1c400 { - compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; - reg = <0x01c1c400 0x100>; - interrupts = ; - clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>, - <&ccu CLK_USB_OHCI2>; - resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>; - phys = <&usbphy 2>; - phy-names = "usb"; - status = "disabled"; - }; - - ehci3: usb@01c1d000 { - compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; - reg = <0x01c1d000 0x100>; - interrupts = ; - clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>; - resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>; - phys = <&usbphy 3>; - phy-names = "usb"; - status = "disabled"; - }; - - ohci3: usb@01c1d400 { - compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; - reg = <0x01c1d400 0x100>; - interrupts = ; - clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>, - <&ccu CLK_USB_OHCI3>; - resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>; - phys = <&usbphy 3>; - phy-names = "usb"; - status = "disabled"; - }; - - ccu: clock@01c20000 { - compatible = "allwinner,sun8i-h3-ccu"; - reg = <0x01c20000 0x400>; - clocks = <&osc24M>, <&osc32k>; - clock-names = "hosc", "losc"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - pio: pinctrl@01c20800 { - compatible = "allwinner,sun8i-h3-pinctrl"; - reg = <0x01c20800 0x400>; - interrupts = , - ; - clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>; - clock-names = "apb", "hosc", "losc"; - gpio-controller; - #gpio-cells = <3>; - interrupt-controller; - #interrupt-cells = <3>; - - i2c0_pins: i2c0 { - pins = "PA11", "PA12"; - function = "i2c0"; - }; - - i2c1_pins: i2c1 { - pins = "PA18", "PA19"; - function = "i2c1"; - }; - - i2c2_pins: i2c2 { - pins = "PE12", "PE13"; - function = "i2c2"; - }; - - mmc0_pins_a: mmc0@0 { - pins = "PF0", "PF1", "PF2", "PF3", - "PF4", "PF5"; - function = "mmc0"; - drive-strength = <30>; - bias-pull-up; - }; - - mmc0_cd_pin: mmc0_cd_pin@0 { - pins = "PF6"; - function = "gpio_in"; - bias-pull-up; - }; - - mmc1_pins_a: mmc1@0 { - pins = "PG0", "PG1", "PG2", "PG3", - "PG4", "PG5"; - function = "mmc1"; - drive-strength = <30>; - bias-pull-up; - }; - - mmc2_8bit_pins: mmc2_8bit { - pins = "PC5", "PC6", "PC8", - "PC9", "PC10", "PC11", - "PC12", "PC13", "PC14", - "PC15", "PC16"; - function = "mmc2"; - drive-strength = <30>; - bias-pull-up; - }; - - spdif_tx_pins_a: spdif@0 { - pins = "PA17"; - function = "spdif"; - }; - - spi0_pins: spi0 { - pins = "PC0", "PC1", "PC2", "PC3"; - function = "spi0"; - }; - - spi1_pins: spi1 { - pins = "PA15", "PA16", "PA14", "PA13"; - function = "spi1"; - }; - - uart0_pins_a: uart0@0 { - pins = "PA4", "PA5"; - function = "uart0"; - }; - - uart1_pins: uart1 { - pins = "PG6", "PG7"; - function = "uart1"; - }; - - uart1_rts_cts_pins: uart1_rts_cts { - pins = "PG8", "PG9"; - function = "uart1"; - }; - - uart2_pins: uart2 { - pins = "PA0", "PA1"; - function = "uart2"; - }; - - uart3_pins: uart3 { - pins = "PA13", "PA14"; - function = "uart3"; - }; - }; - - timer@01c20c00 { - compatible = "allwinner,sun4i-a10-timer"; - reg = <0x01c20c00 0xa0>; - interrupts = , - ; - clocks = <&osc24M>; - }; - - spi0: spi@01c68000 { - compatible = "allwinner,sun8i-h3-spi"; - reg = <0x01c68000 0x1000>; - interrupts = ; - clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; - clock-names = "ahb", "mod"; - dmas = <&dma 23>, <&dma 23>; - dma-names = "rx", "tx"; - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; - resets = <&ccu RST_BUS_SPI0>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi1: spi@01c69000 { - compatible = "allwinner,sun8i-h3-spi"; - reg = <0x01c69000 0x1000>; - interrupts = ; - clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>; - clock-names = "ahb", "mod"; - dmas = <&dma 24>, <&dma 24>; - dma-names = "rx", "tx"; - pinctrl-names = "default"; - pinctrl-0 = <&spi1_pins>; - resets = <&ccu RST_BUS_SPI1>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - wdt0: watchdog@01c20ca0 { - compatible = "allwinner,sun6i-a31-wdt"; - reg = <0x01c20ca0 0x20>; - interrupts = ; - }; - - spdif: spdif@01c21000 { - #sound-dai-cells = <0>; - compatible = "allwinner,sun8i-h3-spdif"; - reg = <0x01c21000 0x400>; - interrupts = ; - clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>; - resets = <&ccu RST_BUS_SPDIF>; - clock-names = "apb", "spdif"; - dmas = <&dma 2>; - dma-names = "tx"; - status = "disabled"; - }; - - pwm: pwm@01c21400 { - compatible = "allwinner,sun8i-h3-pwm"; - reg = <0x01c21400 0x8>; - clocks = <&osc24M>; - #pwm-cells = <3>; - status = "disabled"; - }; - - codec: codec@01c22c00 { - #sound-dai-cells = <0>; - compatible = "allwinner,sun8i-h3-codec"; - reg = <0x01c22c00 0x400>; - interrupts = ; - clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>; - clock-names = "apb", "codec"; - resets = <&ccu RST_BUS_CODEC>; - dmas = <&dma 15>, <&dma 15>; - dma-names = "rx", "tx"; - allwinner,codec-analog-controls = <&codec_analog>; - status = "disabled"; - }; - - uart0: serial@01c28000 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28000 0x400>; - interrupts = ; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_BUS_UART0>; - resets = <&ccu RST_BUS_UART0>; - dmas = <&dma 6>, <&dma 6>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - uart1: serial@01c28400 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28400 0x400>; - interrupts = ; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_BUS_UART1>; - resets = <&ccu RST_BUS_UART1>; - dmas = <&dma 7>, <&dma 7>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - uart2: serial@01c28800 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28800 0x400>; - interrupts = ; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_BUS_UART2>; - resets = <&ccu RST_BUS_UART2>; - dmas = <&dma 8>, <&dma 8>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - uart3: serial@01c28c00 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28c00 0x400>; - interrupts = ; - reg-shift = <2>; - reg-io-width = <4>; - clocks = <&ccu CLK_BUS_UART3>; - resets = <&ccu RST_BUS_UART3>; - dmas = <&dma 9>, <&dma 9>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - i2c0: i2c@01c2ac00 { - compatible = "allwinner,sun6i-a31-i2c"; - reg = <0x01c2ac00 0x400>; - interrupts = ; - clocks = <&ccu CLK_BUS_I2C0>; - resets = <&ccu RST_BUS_I2C0>; - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - i2c1: i2c@01c2b000 { - compatible = "allwinner,sun6i-a31-i2c"; - reg = <0x01c2b000 0x400>; - interrupts = ; - clocks = <&ccu CLK_BUS_I2C1>; - resets = <&ccu RST_BUS_I2C1>; - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pins>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - i2c2: i2c@01c2b400 { - compatible = "allwinner,sun6i-a31-i2c"; - reg = <0x01c2b000 0x400>; - interrupts = ; - clocks = <&ccu CLK_BUS_I2C2>; - resets = <&ccu RST_BUS_I2C2>; - pinctrl-names = "default"; - pinctrl-0 = <&i2c2_pins>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - gic: interrupt-controller@01c81000 { - compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; - reg = <0x01c81000 0x1000>, - <0x01c82000 0x2000>, - <0x01c84000 0x2000>, - <0x01c86000 0x2000>; - interrupt-controller; - #interrupt-cells = <3>; - interrupts = ; - }; - - rtc: rtc@01f00000 { - compatible = "allwinner,sun6i-a31-rtc"; - reg = <0x01f00000 0x54>; - interrupts = , - ; - }; - - apb0_reset: reset@01f014b0 { - reg = <0x01f014b0 0x4>; - compatible = "allwinner,sun6i-a31-clock-reset"; - #reset-cells = <1>; - }; - - codec_analog: codec-analog@01f015c0 { - compatible = "allwinner,sun8i-h3-codec-analog"; - reg = <0x01f015c0 0x4>; - }; - - ir: ir@01f02000 { - compatible = "allwinner,sun5i-a13-ir"; - clocks = <&apb0_gates 1>, <&ir_clk>; - clock-names = "apb", "ir"; - resets = <&apb0_reset 1>; - interrupts = ; - reg = <0x01f02000 0x40>; - status = "disabled"; - }; - - r_pio: pinctrl@01f02c00 { - compatible = "allwinner,sun8i-h3-r-pinctrl"; - reg = <0x01f02c00 0x400>; - interrupts = ; - clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>; - clock-names = "apb", "hosc", "losc"; - resets = <&apb0_reset 0>; - gpio-controller; - #gpio-cells = <3>; - interrupt-controller; - #interrupt-cells = <3>; - - ir_pins_a: ir@0 { - pins = "PL11"; - function = "s_cir_rx"; - }; - }; - }; +}; + +&ccu { + compatible = "allwinner,sun8i-h3-ccu"; +}; + +&mmc0 { + compatible = "allwinner,sun7i-a20-mmc"; + clocks = <&ccu CLK_BUS_MMC0>, + <&ccu CLK_MMC0>, + <&ccu CLK_MMC0_OUTPUT>, + <&ccu CLK_MMC0_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; +}; + +&mmc1 { + compatible = "allwinner,sun7i-a20-mmc"; + clocks = <&ccu CLK_BUS_MMC1>, + <&ccu CLK_MMC1>, + <&ccu CLK_MMC1_OUTPUT>, + <&ccu CLK_MMC1_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; +}; + +&mmc2 { + compatible = "allwinner,sun7i-a20-mmc"; + clocks = <&ccu CLK_BUS_MMC2>, + <&ccu CLK_MMC2>, + <&ccu CLK_MMC2_OUTPUT>, + <&ccu CLK_MMC2_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; +}; + +&pio { + compatible = "allwinner,sun8i-h3-pinctrl"; }; diff --git a/sys/gnu/dts/arm/sun9i-a80-cubieboard4.dts b/sys/gnu/dts/arm/sun9i-a80-cubieboard4.dts index 9112a200fd5e..3741ac71c3d6 100644 --- a/sys/gnu/dts/arm/sun9i-a80-cubieboard4.dts +++ b/sys/gnu/dts/arm/sun9i-a80-cubieboard4.dts @@ -47,7 +47,6 @@ #include "sun9i-a80.dtsi" #include -#include / { model = "Cubietech Cubieboard4"; diff --git a/sys/gnu/dts/arm/sun9i-a80-optimus.dts b/sys/gnu/dts/arm/sun9i-a80-optimus.dts index 0fc3a87f5576..85f1ad670310 100644 --- a/sys/gnu/dts/arm/sun9i-a80-optimus.dts +++ b/sys/gnu/dts/arm/sun9i-a80-optimus.dts @@ -46,7 +46,6 @@ #include "sun9i-a80.dtsi" #include -#include / { model = "Merrii A80 Optimus Board"; diff --git a/sys/gnu/dts/arm/sun9i-a80.dtsi b/sys/gnu/dts/arm/sun9i-a80.dtsi index 15b6d122f878..759a72317eb8 100644 --- a/sys/gnu/dts/arm/sun9i-a80.dtsi +++ b/sys/gnu/dts/arm/sun9i-a80.dtsi @@ -46,8 +46,6 @@ #include -#include - #include #include #include diff --git a/sys/gnu/dts/arm/sunxi-common-regulators.dtsi b/sys/gnu/dts/arm/sunxi-common-regulators.dtsi index 17c09fed9e84..ce5c53e4452f 100644 --- a/sys/gnu/dts/arm/sunxi-common-regulators.dtsi +++ b/sys/gnu/dts/arm/sunxi-common-regulators.dtsi @@ -43,7 +43,6 @@ */ #include -#include &pio { ahci_pwr_pin_a: ahci_pwr_pin@0 { diff --git a/sys/gnu/dts/arm/sunxi-h3-h5.dtsi b/sys/gnu/dts/arm/sunxi-h3-h5.dtsi new file mode 100644 index 000000000000..d4f600dbb7eb --- /dev/null +++ b/sys/gnu/dts/arm/sunxi-h3-h5.dtsi @@ -0,0 +1,602 @@ +/* + * Copyright (C) 2015 Jens Kuske + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +/ { + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + osc24M: osc24M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "osc24M"; + }; + + osc32k: osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "osc32k"; + }; + + iosc: internal-osc-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <16000000>; + clock-accuracy = <300000000>; + clock-output-names = "iosc"; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + dma: dma-controller@01c02000 { + compatible = "allwinner,sun8i-h3-dma"; + reg = <0x01c02000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_DMA>; + resets = <&ccu RST_BUS_DMA>; + #dma-cells = <1>; + }; + + mmc0: mmc@01c0f000 { + /* compatible and clocks are in per SoC .dtsi file */ + reg = <0x01c0f000 0x1000>; + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc1: mmc@01c10000 { + /* compatible and clocks are in per SoC .dtsi file */ + reg = <0x01c10000 0x1000>; + resets = <&ccu RST_BUS_MMC1>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc2: mmc@01c11000 { + /* compatible and clocks are in per SoC .dtsi file */ + reg = <0x01c11000 0x1000>; + resets = <&ccu RST_BUS_MMC2>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + usb_otg: usb@01c19000 { + compatible = "allwinner,sun8i-h3-musb"; + reg = <0x01c19000 0x400>; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; + interrupts = ; + interrupt-names = "mc"; + phys = <&usbphy 0>; + phy-names = "usb"; + extcon = <&usbphy 0>; + status = "disabled"; + }; + + usbphy: phy@01c19400 { + compatible = "allwinner,sun8i-h3-usb-phy"; + reg = <0x01c19400 0x2c>, + <0x01c1a800 0x4>, + <0x01c1b800 0x4>, + <0x01c1c800 0x4>, + <0x01c1d800 0x4>; + reg-names = "phy_ctrl", + "pmu0", + "pmu1", + "pmu2", + "pmu3"; + clocks = <&ccu CLK_USB_PHY0>, + <&ccu CLK_USB_PHY1>, + <&ccu CLK_USB_PHY2>, + <&ccu CLK_USB_PHY3>; + clock-names = "usb0_phy", + "usb1_phy", + "usb2_phy", + "usb3_phy"; + resets = <&ccu RST_USB_PHY0>, + <&ccu RST_USB_PHY1>, + <&ccu RST_USB_PHY2>, + <&ccu RST_USB_PHY3>; + reset-names = "usb0_reset", + "usb1_reset", + "usb2_reset", + "usb3_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ehci0: usb@01c1a000 { + compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>; + resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>; + status = "disabled"; + }; + + ohci0: usb@01c1a400 { + compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; + reg = <0x01c1a400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>; + status = "disabled"; + }; + + ehci1: usb@01c1b000 { + compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; + reg = <0x01c1b000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>; + resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci1: usb@01c1b400 { + compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; + reg = <0x01c1b400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>, + <&ccu CLK_USB_OHCI1>; + resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci2: usb@01c1c000 { + compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; + reg = <0x01c1c000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>; + resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>; + phys = <&usbphy 2>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci2: usb@01c1c400 { + compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; + reg = <0x01c1c400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>, + <&ccu CLK_USB_OHCI2>; + resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>; + phys = <&usbphy 2>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci3: usb@01c1d000 { + compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; + reg = <0x01c1d000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>; + resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>; + phys = <&usbphy 3>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci3: usb@01c1d400 { + compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; + reg = <0x01c1d400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>, + <&ccu CLK_USB_OHCI3>; + resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>; + phys = <&usbphy 3>; + phy-names = "usb"; + status = "disabled"; + }; + + ccu: clock@01c20000 { + /* compatible is in per SoC .dtsi file */ + reg = <0x01c20000 0x400>; + clocks = <&osc24M>, <&osc32k>; + clock-names = "hosc", "losc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pio: pinctrl@01c20800 { + /* compatible is in per SoC .dtsi file */ + reg = <0x01c20800 0x400>; + interrupts = , + ; + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + i2c0_pins: i2c0 { + pins = "PA11", "PA12"; + function = "i2c0"; + }; + + i2c1_pins: i2c1 { + pins = "PA18", "PA19"; + function = "i2c1"; + }; + + i2c2_pins: i2c2 { + pins = "PE12", "PE13"; + function = "i2c2"; + }; + + mmc0_pins_a: mmc0@0 { + pins = "PF0", "PF1", "PF2", "PF3", + "PF4", "PF5"; + function = "mmc0"; + drive-strength = <30>; + bias-pull-up; + }; + + mmc0_cd_pin: mmc0_cd_pin@0 { + pins = "PF6"; + function = "gpio_in"; + bias-pull-up; + }; + + mmc1_pins_a: mmc1@0 { + pins = "PG0", "PG1", "PG2", "PG3", + "PG4", "PG5"; + function = "mmc1"; + drive-strength = <30>; + bias-pull-up; + }; + + mmc2_8bit_pins: mmc2_8bit { + pins = "PC5", "PC6", "PC8", + "PC9", "PC10", "PC11", + "PC12", "PC13", "PC14", + "PC15", "PC16"; + function = "mmc2"; + drive-strength = <30>; + bias-pull-up; + }; + + spdif_tx_pins_a: spdif@0 { + pins = "PA17"; + function = "spdif"; + }; + + spi0_pins: spi0 { + pins = "PC0", "PC1", "PC2", "PC3"; + function = "spi0"; + }; + + spi1_pins: spi1 { + pins = "PA15", "PA16", "PA14", "PA13"; + function = "spi1"; + }; + + uart0_pins_a: uart0@0 { + pins = "PA4", "PA5"; + function = "uart0"; + }; + + uart1_pins: uart1 { + pins = "PG6", "PG7"; + function = "uart1"; + }; + + uart1_rts_cts_pins: uart1_rts_cts { + pins = "PG8", "PG9"; + function = "uart1"; + }; + + uart2_pins: uart2 { + pins = "PA0", "PA1"; + function = "uart2"; + }; + + uart3_pins: uart3 { + pins = "PA13", "PA14"; + function = "uart3"; + }; + }; + + timer@01c20c00 { + compatible = "allwinner,sun4i-a10-timer"; + reg = <0x01c20c00 0xa0>; + interrupts = , + ; + clocks = <&osc24M>; + }; + + spi0: spi@01c68000 { + compatible = "allwinner,sun8i-h3-spi"; + reg = <0x01c68000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; + clock-names = "ahb", "mod"; + dmas = <&dma 23>, <&dma 23>; + dma-names = "rx", "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + resets = <&ccu RST_BUS_SPI0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@01c69000 { + compatible = "allwinner,sun8i-h3-spi"; + reg = <0x01c69000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>; + clock-names = "ahb", "mod"; + dmas = <&dma 24>, <&dma 24>; + dma-names = "rx", "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins>; + resets = <&ccu RST_BUS_SPI1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + wdt0: watchdog@01c20ca0 { + compatible = "allwinner,sun6i-a31-wdt"; + reg = <0x01c20ca0 0x20>; + interrupts = ; + }; + + spdif: spdif@01c21000 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun8i-h3-spdif"; + reg = <0x01c21000 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>; + resets = <&ccu RST_BUS_SPDIF>; + clock-names = "apb", "spdif"; + dmas = <&dma 2>; + dma-names = "tx"; + status = "disabled"; + }; + + pwm: pwm@01c21400 { + compatible = "allwinner,sun8i-h3-pwm"; + reg = <0x01c21400 0x8>; + clocks = <&osc24M>; + #pwm-cells = <3>; + status = "disabled"; + }; + + codec: codec@01c22c00 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun8i-h3-codec"; + reg = <0x01c22c00 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>; + clock-names = "apb", "codec"; + resets = <&ccu RST_BUS_CODEC>; + dmas = <&dma 15>, <&dma 15>; + dma-names = "rx", "tx"; + allwinner,codec-analog-controls = <&codec_analog>; + status = "disabled"; + }; + + uart0: serial@01c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; + dmas = <&dma 6>, <&dma 6>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uart1: serial@01c28400 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28400 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART1>; + resets = <&ccu RST_BUS_UART1>; + dmas = <&dma 7>, <&dma 7>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uart2: serial@01c28800 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28800 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART2>; + resets = <&ccu RST_BUS_UART2>; + dmas = <&dma 8>, <&dma 8>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + uart3: serial@01c28c00 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28c00 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART3>; + resets = <&ccu RST_BUS_UART3>; + dmas = <&dma 9>, <&dma 9>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c0: i2c@01c2ac00 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2ac00 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C0>; + resets = <&ccu RST_BUS_I2C0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@01c2b000 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2b000 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C1>; + resets = <&ccu RST_BUS_I2C1>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@01c2b400 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2b000 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C2>; + resets = <&ccu RST_BUS_I2C2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + gic: interrupt-controller@01c81000 { + compatible = "arm,gic-400"; + reg = <0x01c81000 0x1000>, + <0x01c82000 0x2000>, + <0x01c84000 0x2000>, + <0x01c86000 0x2000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = ; + }; + + rtc: rtc@01f00000 { + compatible = "allwinner,sun6i-a31-rtc"; + reg = <0x01f00000 0x54>; + interrupts = , + ; + }; + + r_ccu: clock@1f01400 { + compatible = "allwinner,sun8i-h3-r-ccu"; + reg = <0x01f01400 0x100>; + clocks = <&osc24M>, <&osc32k>, <&iosc>, + <&ccu 9>; + clock-names = "hosc", "losc", "iosc", "pll-periph"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + codec_analog: codec-analog@01f015c0 { + compatible = "allwinner,sun8i-h3-codec-analog"; + reg = <0x01f015c0 0x4>; + }; + + ir: ir@01f02000 { + compatible = "allwinner,sun5i-a13-ir"; + clocks = <&r_ccu 4>, <&r_ccu 11>; + clock-names = "apb", "ir"; + resets = <&r_ccu 0>; + interrupts = ; + reg = <0x01f02000 0x40>; + status = "disabled"; + }; + + r_pio: pinctrl@01f02c00 { + compatible = "allwinner,sun8i-h3-r-pinctrl"; + reg = <0x01f02c00 0x400>; + interrupts = ; + clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + ir_pins_a: ir@0 { + pins = "PL11"; + function = "s_cir_rx"; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/sunxi-reference-design-tablet.dtsi b/sys/gnu/dts/arm/sunxi-reference-design-tablet.dtsi index b8241462fcea..245d0bcde441 100644 --- a/sys/gnu/dts/arm/sunxi-reference-design-tablet.dtsi +++ b/sys/gnu/dts/arm/sunxi-reference-design-tablet.dtsi @@ -42,7 +42,6 @@ #include #include -#include #include "sunxi-common-regulators.dtsi" &i2c0 { diff --git a/sys/gnu/dts/arm/uniphier-ld4-ref.dts b/sys/gnu/dts/arm/uniphier-ld4-ref.dts index 110031bc0e7e..e0da4ee21c21 100644 --- a/sys/gnu/dts/arm/uniphier-ld4-ref.dts +++ b/sys/gnu/dts/arm/uniphier-ld4-ref.dts @@ -52,11 +52,6 @@ model = "UniPhier LD4 Reference Board"; compatible = "socionext,uniphier-ld4-ref", "socionext,uniphier-ld4"; - memory { - device_type = "memory"; - reg = <0x80000000 0x20000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -71,6 +66,11 @@ i2c2 = &i2c2; i2c3 = &i2c3; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; + }; }; ðsc { diff --git a/sys/gnu/dts/arm/uniphier-ld4.dtsi b/sys/gnu/dts/arm/uniphier-ld4.dtsi index a7c494d7c43a..4f5fe15eaee2 100644 --- a/sys/gnu/dts/arm/uniphier-ld4.dtsi +++ b/sys/gnu/dts/arm/uniphier-ld4.dtsi @@ -43,10 +43,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/include/ "skeleton.dtsi" - / { compatible = "socionext,uniphier-ld4"; + #address-cells = <1>; + #size-cells = <1>; cpus { #address-cells = <1>; diff --git a/sys/gnu/dts/arm/uniphier-ld6b-ref.dts b/sys/gnu/dts/arm/uniphier-ld6b-ref.dts index c05d631dcf02..a397a8811c78 100644 --- a/sys/gnu/dts/arm/uniphier-ld6b-ref.dts +++ b/sys/gnu/dts/arm/uniphier-ld6b-ref.dts @@ -52,11 +52,6 @@ model = "UniPhier LD6b Reference Board"; compatible = "socionext,uniphier-ld6b-ref", "socionext,uniphier-ld6b"; - memory { - device_type = "memory"; - reg = <0x80000000 0x80000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -73,6 +68,11 @@ i2c5 = &i2c5; i2c6 = &i2c6; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; }; ðsc { diff --git a/sys/gnu/dts/arm/uniphier-pinctrl.dtsi b/sys/gnu/dts/arm/uniphier-pinctrl.dtsi index 8ee79da9af7c..246f35ffb638 100644 --- a/sys/gnu/dts/arm/uniphier-pinctrl.dtsi +++ b/sys/gnu/dts/arm/uniphier-pinctrl.dtsi @@ -45,7 +45,7 @@ &pinctrl { pinctrl_emmc: emmc_grp { - groups = "emmc"; + groups = "emmc", "emmc_dat8"; function = "emmc"; }; diff --git a/sys/gnu/dts/arm/uniphier-pro4-ace.dts b/sys/gnu/dts/arm/uniphier-pro4-ace.dts index 0ab0a40c041e..fefc89149234 100644 --- a/sys/gnu/dts/arm/uniphier-pro4-ace.dts +++ b/sys/gnu/dts/arm/uniphier-pro4-ace.dts @@ -50,11 +50,6 @@ model = "UniPhier Pro4 Ace Board"; compatible = "socionext,uniphier-pro4-ace", "socionext,uniphier-pro4"; - memory { - device_type = "memory"; - reg = <0x80000000 0x40000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -70,6 +65,11 @@ i2c5 = &i2c5; i2c6 = &i2c6; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; }; &serial0 { @@ -90,6 +90,7 @@ eeprom@54 { compatible = "st,24c64"; reg = <0x54>; + pagesize = <32>; }; }; diff --git a/sys/gnu/dts/arm/uniphier-pro4-ref.dts b/sys/gnu/dts/arm/uniphier-pro4-ref.dts index 9e92e60d25ce..6077e634d14a 100644 --- a/sys/gnu/dts/arm/uniphier-pro4-ref.dts +++ b/sys/gnu/dts/arm/uniphier-pro4-ref.dts @@ -52,11 +52,6 @@ model = "UniPhier Pro4 Reference Board"; compatible = "socionext,uniphier-pro4-ref", "socionext,uniphier-pro4"; - memory { - device_type = "memory"; - reg = <0x80000000 0x40000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -73,6 +68,11 @@ i2c5 = &i2c5; i2c6 = &i2c6; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; }; ðsc { diff --git a/sys/gnu/dts/arm/uniphier-pro4-sanji.dts b/sys/gnu/dts/arm/uniphier-pro4-sanji.dts index dc4ea8832ce2..6c63c8bad825 100644 --- a/sys/gnu/dts/arm/uniphier-pro4-sanji.dts +++ b/sys/gnu/dts/arm/uniphier-pro4-sanji.dts @@ -50,11 +50,6 @@ model = "UniPhier Pro4 Sanji Board"; compatible = "socionext,uniphier-pro4-sanji", "socionext,uniphier-pro4"; - memory { - device_type = "memory"; - reg = <0x80000000 0x80000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -69,6 +64,11 @@ i2c5 = &i2c5; i2c6 = &i2c6; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; }; &serial0 { @@ -85,6 +85,7 @@ eeprom@54 { compatible = "st,24c64"; reg = <0x54>; + pagesize = <32>; }; }; diff --git a/sys/gnu/dts/arm/uniphier-pro4.dtsi b/sys/gnu/dts/arm/uniphier-pro4.dtsi index e960b09ff01c..794a85a7068b 100644 --- a/sys/gnu/dts/arm/uniphier-pro4.dtsi +++ b/sys/gnu/dts/arm/uniphier-pro4.dtsi @@ -43,10 +43,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/include/ "skeleton.dtsi" - / { compatible = "socionext,uniphier-pro4"; + #address-cells = <1>; + #size-cells = <1>; cpus { #address-cells = <1>; diff --git a/sys/gnu/dts/arm/uniphier-pro5.dtsi b/sys/gnu/dts/arm/uniphier-pro5.dtsi index dbc5e5333163..df07b555cbed 100644 --- a/sys/gnu/dts/arm/uniphier-pro5.dtsi +++ b/sys/gnu/dts/arm/uniphier-pro5.dtsi @@ -43,10 +43,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/include/ "skeleton.dtsi" - / { compatible = "socionext,uniphier-pro5"; + #address-cells = <1>; + #size-cells = <1>; cpus { #address-cells = <1>; diff --git a/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts b/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts index 373818ace086..cccc86658d20 100644 --- a/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts +++ b/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts @@ -51,11 +51,6 @@ compatible = "socionext,uniphier-pxs2-gentil", "socionext,uniphier-pxs2"; - memory { - device_type = "memory"; - reg = <0x80000000 0x80000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -70,6 +65,11 @@ i2c5 = &i2c5; i2c6 = &i2c6; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; }; &serial2 { @@ -82,6 +82,7 @@ eeprom@54 { compatible = "st,24c64"; reg = <0x54>; + pagesize = <32>; }; }; diff --git a/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts b/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts index 51a3eacddfc6..803a39aa39d0 100644 --- a/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts +++ b/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts @@ -50,11 +50,6 @@ model = "UniPhier PXs2 Vodka Board"; compatible = "socionext,uniphier-pxs2-vodka", "socionext,uniphier-pxs2"; - memory { - device_type = "memory"; - reg = <0x80000000 0x80000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -68,6 +63,11 @@ i2c5 = &i2c5; i2c6 = &i2c6; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; }; &serial2 { diff --git a/sys/gnu/dts/arm/uniphier-pxs2.dtsi b/sys/gnu/dts/arm/uniphier-pxs2.dtsi index e9e031d63c1a..58c3e2f35706 100644 --- a/sys/gnu/dts/arm/uniphier-pxs2.dtsi +++ b/sys/gnu/dts/arm/uniphier-pxs2.dtsi @@ -43,10 +43,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/include/ "skeleton.dtsi" - / { compatible = "socionext,uniphier-pxs2"; + #address-cells = <1>; + #size-cells = <1>; cpus { #address-cells = <1>; diff --git a/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi b/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi index f7df0881c5e0..c62ae1a81f47 100644 --- a/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi +++ b/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi @@ -1,7 +1,8 @@ /* * Device Tree Source for UniPhier Reference Daughter Board * - * Copyright (C) 2015 Masahiro Yamada + * Copyright (C) 2015-2017 Socionext Inc. + * Author: Masahiro Yamada * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -46,5 +47,6 @@ eeprom@50 { compatible = "microchip,24lc128"; reg = <0x50>; + pagesize = <64>; }; }; diff --git a/sys/gnu/dts/arm/uniphier-sld3-ref.dts b/sys/gnu/dts/arm/uniphier-sld3-ref.dts index ac792ae07ae0..eb63dcca92b5 100644 --- a/sys/gnu/dts/arm/uniphier-sld3-ref.dts +++ b/sys/gnu/dts/arm/uniphier-sld3-ref.dts @@ -52,12 +52,6 @@ model = "UniPhier sLD3 Reference Board"; compatible = "socionext,uniphier-sld3-ref", "socionext,uniphier-sld3"; - memory { - device_type = "memory"; - reg = <0x80000000 0x20000000 - 0xc0000000 0x20000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -72,6 +66,12 @@ i2c3 = &i2c3; i2c4 = &i2c4; }; + + memory@8000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000 + 0xc0000000 0x20000000>; + }; }; ðsc { diff --git a/sys/gnu/dts/arm/uniphier-sld3.dtsi b/sys/gnu/dts/arm/uniphier-sld3.dtsi index 9fad6bd2db8a..01d77edac01f 100644 --- a/sys/gnu/dts/arm/uniphier-sld3.dtsi +++ b/sys/gnu/dts/arm/uniphier-sld3.dtsi @@ -43,10 +43,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/include/ "skeleton.dtsi" - / { compatible = "socionext,uniphier-sld3"; + #address-cells = <1>; + #size-cells = <1>; cpus { #address-cells = <1>; diff --git a/sys/gnu/dts/arm/uniphier-sld8-ref.dts b/sys/gnu/dts/arm/uniphier-sld8-ref.dts index a8291f988066..737d276349fd 100644 --- a/sys/gnu/dts/arm/uniphier-sld8-ref.dts +++ b/sys/gnu/dts/arm/uniphier-sld8-ref.dts @@ -52,11 +52,6 @@ model = "UniPhier sLD8 Reference Board"; compatible = "socionext,uniphier-sld8-ref", "socionext,uniphier-sld8"; - memory { - device_type = "memory"; - reg = <0x80000000 0x20000000>; - }; - chosen { stdout-path = "serial0:115200n8"; }; @@ -71,6 +66,11 @@ i2c2 = &i2c2; i2c3 = &i2c3; }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; + }; }; ðsc { diff --git a/sys/gnu/dts/arm/uniphier-sld8.dtsi b/sys/gnu/dts/arm/uniphier-sld8.dtsi index b2c980ead7f0..eb06fdc04b02 100644 --- a/sys/gnu/dts/arm/uniphier-sld8.dtsi +++ b/sys/gnu/dts/arm/uniphier-sld8.dtsi @@ -43,10 +43,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/include/ "skeleton.dtsi" - / { compatible = "socionext,uniphier-sld8"; + #address-cells = <1>; + #size-cells = <1>; cpus { #address-cells = <1>; diff --git a/sys/gnu/dts/arm/uniphier-support-card.dtsi b/sys/gnu/dts/arm/uniphier-support-card.dtsi index 51ecc9b9c0ce..f61dfec2807f 100644 --- a/sys/gnu/dts/arm/uniphier-support-card.dtsi +++ b/sys/gnu/dts/arm/uniphier-support-card.dtsi @@ -1,7 +1,8 @@ /* * Device Tree Source for UniPhier Support Card (Expansion Board) * - * Copyright (C) 2015 Masahiro Yamada + * Copyright (C) 2015-2017 Socionext Inc. + * Author: Masahiro Yamada * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -46,7 +47,7 @@ status = "okay"; ranges = <1 0x00000000 0x42000000 0x02000000>; - support_card: support_card { + support_card: support_card@1,1f00000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/sys/gnu/dts/arm/versatile-pb.dts b/sys/gnu/dts/arm/versatile-pb.dts index 33a8eb28374e..06e2331f666d 100644 --- a/sys/gnu/dts/arm/versatile-pb.dts +++ b/sys/gnu/dts/arm/versatile-pb.dts @@ -1,4 +1,4 @@ -#include +#include "versatile-ab.dts" / { model = "ARM Versatile PB"; diff --git a/sys/gnu/dts/arm/vexpress-v2m-rs1.dtsi b/sys/gnu/dts/arm/vexpress-v2m-rs1.dtsi index 3086efacd00e..35714ff6f467 100644 --- a/sys/gnu/dts/arm/vexpress-v2m-rs1.dtsi +++ b/sys/gnu/dts/arm/vexpress-v2m-rs1.dtsi @@ -71,7 +71,7 @@ #size-cells = <1>; ranges = <0 3 0 0x200000>; - v2m_sysreg: sysreg@010000 { + v2m_sysreg: sysreg@10000 { compatible = "arm,vexpress-sysreg"; reg = <0x010000 0x1000>; @@ -94,7 +94,7 @@ }; }; - v2m_sysctl: sysctl@020000 { + v2m_sysctl: sysctl@20000 { compatible = "arm,sp810", "arm,primecell"; reg = <0x020000 0x1000>; clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>; @@ -106,7 +106,7 @@ }; /* PCI-E I2C bus */ - v2m_i2c_pcie: i2c@030000 { + v2m_i2c_pcie: i2c@30000 { compatible = "arm,versatile-i2c"; reg = <0x030000 0x1000>; @@ -119,7 +119,7 @@ }; }; - aaci@040000 { + aaci@40000 { compatible = "arm,pl041", "arm,primecell"; reg = <0x040000 0x1000>; interrupts = <11>; @@ -127,7 +127,7 @@ clock-names = "apb_pclk"; }; - mmci@050000 { + mmci@50000 { compatible = "arm,pl180", "arm,primecell"; reg = <0x050000 0x1000>; interrupts = <9 10>; @@ -139,7 +139,7 @@ clock-names = "mclk", "apb_pclk"; }; - kmi@060000 { + kmi@60000 { compatible = "arm,pl050", "arm,primecell"; reg = <0x060000 0x1000>; interrupts = <12>; @@ -147,7 +147,7 @@ clock-names = "KMIREFCLK", "apb_pclk"; }; - kmi@070000 { + kmi@70000 { compatible = "arm,pl050", "arm,primecell"; reg = <0x070000 0x1000>; interrupts = <13>; @@ -155,7 +155,7 @@ clock-names = "KMIREFCLK", "apb_pclk"; }; - v2m_serial0: uart@090000 { + v2m_serial0: uart@90000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x090000 0x1000>; interrupts = <5>; @@ -163,7 +163,7 @@ clock-names = "uartclk", "apb_pclk"; }; - v2m_serial1: uart@0a0000 { + v2m_serial1: uart@a0000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0a0000 0x1000>; interrupts = <6>; @@ -171,7 +171,7 @@ clock-names = "uartclk", "apb_pclk"; }; - v2m_serial2: uart@0b0000 { + v2m_serial2: uart@b0000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0b0000 0x1000>; interrupts = <7>; @@ -179,7 +179,7 @@ clock-names = "uartclk", "apb_pclk"; }; - v2m_serial3: uart@0c0000 { + v2m_serial3: uart@c0000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0c0000 0x1000>; interrupts = <8>; @@ -187,7 +187,7 @@ clock-names = "uartclk", "apb_pclk"; }; - wdt@0f0000 { + wdt@f0000 { compatible = "arm,sp805", "arm,primecell"; reg = <0x0f0000 0x1000>; interrupts = <0>; diff --git a/sys/gnu/dts/arm/vexpress-v2m.dtsi b/sys/gnu/dts/arm/vexpress-v2m.dtsi index c6393d3f1719..1b6f6393be93 100644 --- a/sys/gnu/dts/arm/vexpress-v2m.dtsi +++ b/sys/gnu/dts/arm/vexpress-v2m.dtsi @@ -70,7 +70,7 @@ #size-cells = <1>; ranges = <0 7 0 0x20000>; - v2m_sysreg: sysreg@00000 { + v2m_sysreg: sysreg@0 { compatible = "arm,vexpress-sysreg"; reg = <0x00000 0x1000>; @@ -93,7 +93,7 @@ }; }; - v2m_sysctl: sysctl@01000 { + v2m_sysctl: sysctl@1000 { compatible = "arm,sp810", "arm,primecell"; reg = <0x01000 0x1000>; clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>; @@ -105,7 +105,7 @@ }; /* PCI-E I2C bus */ - v2m_i2c_pcie: i2c@02000 { + v2m_i2c_pcie: i2c@2000 { compatible = "arm,versatile-i2c"; reg = <0x02000 0x1000>; @@ -118,7 +118,7 @@ }; }; - aaci@04000 { + aaci@4000 { compatible = "arm,pl041", "arm,primecell"; reg = <0x04000 0x1000>; interrupts = <11>; @@ -126,7 +126,7 @@ clock-names = "apb_pclk"; }; - mmci@05000 { + mmci@5000 { compatible = "arm,pl180", "arm,primecell"; reg = <0x05000 0x1000>; interrupts = <9 10>; @@ -138,7 +138,7 @@ clock-names = "mclk", "apb_pclk"; }; - kmi@06000 { + kmi@6000 { compatible = "arm,pl050", "arm,primecell"; reg = <0x06000 0x1000>; interrupts = <12>; @@ -146,7 +146,7 @@ clock-names = "KMIREFCLK", "apb_pclk"; }; - kmi@07000 { + kmi@7000 { compatible = "arm,pl050", "arm,primecell"; reg = <0x07000 0x1000>; interrupts = <13>; @@ -154,7 +154,7 @@ clock-names = "KMIREFCLK", "apb_pclk"; }; - v2m_serial0: uart@09000 { + v2m_serial0: uart@9000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x09000 0x1000>; interrupts = <5>; @@ -162,7 +162,7 @@ clock-names = "uartclk", "apb_pclk"; }; - v2m_serial1: uart@0a000 { + v2m_serial1: uart@a000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0a000 0x1000>; interrupts = <6>; @@ -170,7 +170,7 @@ clock-names = "uartclk", "apb_pclk"; }; - v2m_serial2: uart@0b000 { + v2m_serial2: uart@b000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0b000 0x1000>; interrupts = <7>; @@ -178,7 +178,7 @@ clock-names = "uartclk", "apb_pclk"; }; - v2m_serial3: uart@0c000 { + v2m_serial3: uart@c000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0c000 0x1000>; interrupts = <8>; @@ -186,7 +186,7 @@ clock-names = "uartclk", "apb_pclk"; }; - wdt@0f000 { + wdt@f000 { compatible = "arm,sp805", "arm,primecell"; reg = <0x0f000 0x1000>; interrupts = <0>; diff --git a/sys/gnu/dts/arm/vexpress-v2p-ca15-tc1.dts b/sys/gnu/dts/arm/vexpress-v2p-ca15-tc1.dts index 15f4fd3f4695..0c8de0ca73ee 100644 --- a/sys/gnu/dts/arm/vexpress-v2p-ca15-tc1.dts +++ b/sys/gnu/dts/arm/vexpress-v2p-ca15-tc1.dts @@ -220,7 +220,7 @@ }; }; - smb@08000000 { + smb@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/sys/gnu/dts/arm/vexpress-v2p-ca15_a7.dts b/sys/gnu/dts/arm/vexpress-v2p-ca15_a7.dts index bd107c5a0226..65ecf206388c 100644 --- a/sys/gnu/dts/arm/vexpress-v2p-ca15_a7.dts +++ b/sys/gnu/dts/arm/vexpress-v2p-ca15_a7.dts @@ -385,7 +385,7 @@ }; }; - etb@0,20010000 { + etb@20010000 { compatible = "arm,coresight-etb10", "arm,primecell"; reg = <0 0x20010000 0 0x1000>; @@ -399,7 +399,7 @@ }; }; - tpiu@0,20030000 { + tpiu@20030000 { compatible = "arm,coresight-tpiu", "arm,primecell"; reg = <0 0x20030000 0 0x1000>; @@ -449,7 +449,7 @@ }; }; - funnel@0,20040000 { + funnel@20040000 { compatible = "arm,coresight-funnel", "arm,primecell"; reg = <0 0x20040000 0 0x1000>; @@ -513,7 +513,7 @@ }; }; - ptm@0,2201c000 { + ptm@2201c000 { compatible = "arm,coresight-etm3x", "arm,primecell"; reg = <0 0x2201c000 0 0x1000>; @@ -527,7 +527,7 @@ }; }; - ptm@0,2201d000 { + ptm@2201d000 { compatible = "arm,coresight-etm3x", "arm,primecell"; reg = <0 0x2201d000 0 0x1000>; @@ -541,7 +541,7 @@ }; }; - etm@0,2203c000 { + etm@2203c000 { compatible = "arm,coresight-etm3x", "arm,primecell"; reg = <0 0x2203c000 0 0x1000>; @@ -555,7 +555,7 @@ }; }; - etm@0,2203d000 { + etm@2203d000 { compatible = "arm,coresight-etm3x", "arm,primecell"; reg = <0 0x2203d000 0 0x1000>; @@ -569,7 +569,7 @@ }; }; - etm@0,2203e000 { + etm@2203e000 { compatible = "arm,coresight-etm3x", "arm,primecell"; reg = <0 0x2203e000 0 0x1000>; @@ -583,7 +583,7 @@ }; }; - smb@08000000 { + smb@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/sys/gnu/dts/arm/vexpress-v2p-ca5s.dts b/sys/gnu/dts/arm/vexpress-v2p-ca5s.dts index 1acecaf4b13d..6e69b8e6c1a7 100644 --- a/sys/gnu/dts/arm/vexpress-v2p-ca5s.dts +++ b/sys/gnu/dts/arm/vexpress-v2p-ca5s.dts @@ -190,7 +190,7 @@ }; }; - smb@08000000 { + smb@8000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/sys/gnu/dts/arm/vexpress-v2p-ca9.dts b/sys/gnu/dts/arm/vexpress-v2p-ca9.dts index b608a03ee02f..c9305b58afc2 100644 --- a/sys/gnu/dts/arm/vexpress-v2p-ca9.dts +++ b/sys/gnu/dts/arm/vexpress-v2p-ca9.dts @@ -300,7 +300,7 @@ }; }; - smb@04000000 { + smb@4000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts b/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts index 7940408838df..37f95427616f 100644 --- a/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts +++ b/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts @@ -239,7 +239,7 @@ #size-cells = <0>; reg = <4>; - switch2: switch2@0 { + switch2: switch@0 { compatible = "marvell,mv88e6085"; #address-cells = <1>; #size-cells = <0>; @@ -459,18 +459,6 @@ >; }; - pinctrl_gpio_switch0: pinctrl-gpio-switch0 { - fsl,pins = < - VF610_PAD_PTB5__GPIO_27 0x219d - >; - }; - - pinctrl_gpio_switch1: pinctrl-gpio-switch1 { - fsl,pins = < - VF610_PAD_PTB4__GPIO_26 0x219d - >; - }; - pinctrl_mdio_mux: pinctrl-mdio-mux { fsl,pins = < VF610_PAD_PTA18__GPIO_8 0x31c2 diff --git a/sys/gnu/dts/arm/vf610-zii-dev-rev-c.dts b/sys/gnu/dts/arm/vf610-zii-dev-rev-c.dts index 6a45bd24ffe6..db3b408ea55a 100644 --- a/sys/gnu/dts/arm/vf610-zii-dev-rev-c.dts +++ b/sys/gnu/dts/arm/vf610-zii-dev-rev-c.dts @@ -67,11 +67,17 @@ switch0: switch@0 { compatible = "marvell,mv88e6190"; + pinctrl-0 = <&pinctrl_gpio_switch0>; + pinctrl-names = "default"; #address-cells = <1>; #size-cells = <0>; reg = <0>; dsa,member = <0 0>; eeprom-length = <512>; + interrupt-parent = <&gpio0>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; ports { #address-cells = <1>; @@ -91,21 +97,25 @@ port@1 { reg = <1>; label = "lan1"; + phy-handle = <&switch0phy1>; }; port@2 { reg = <2>; label = "lan2"; + phy-handle = <&switch0phy2>; }; port@3 { reg = <3>; label = "lan3"; + phy-handle = <&switch0phy3>; }; port@4 { reg = <4>; label = "lan4"; + phy-handle = <&switch0phy4>; }; switch0port10: port@10 { @@ -115,6 +125,35 @@ link = <&switch1port10>; }; }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + switch0phy1: switch0phy@1 { + reg = <1>; + interrupt-parent = <&switch0>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + }; + + switch0phy2: switch0phy@2 { + reg = <2>; + interrupt-parent = <&switch0>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; + }; + + switch0phy3: switch0phy@3 { + reg = <3>; + interrupt-parent = <&switch0>; + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; + }; + + switch0phy4: switch0phy@4 { + reg = <4>; + interrupt-parent = <&switch0>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + }; + }; }; }; @@ -125,11 +164,17 @@ switch1: switch@0 { compatible = "marvell,mv88e6190"; + pinctrl-0 = <&pinctrl_gpio_switch1>; + pinctrl-names = "default"; #address-cells = <1>; #size-cells = <0>; reg = <0>; dsa,member = <0 1>; eeprom-length = <512>; + interrupt-parent = <&gpio0>; + interrupts = <26 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; ports { #address-cells = <1>; @@ -138,21 +183,25 @@ port@1 { reg = <1>; label = "lan5"; + phy-handle = <&switch1phy1>; }; port@2 { reg = <2>; label = "lan6"; + phy-handle = <&switch1phy2>; }; port@3 { reg = <3>; label = "lan7"; + phy-handle = <&switch1phy3>; }; port@4 { reg = <4>; label = "lan8"; + phy-handle = <&switch1phy4>; }; @@ -163,6 +212,34 @@ link = <&switch0port10>; }; }; + mdio { + #address-cells = <1>; + #size-cells = <0>; + + switch1phy1: switch1phy@1 { + reg = <1>; + interrupt-parent = <&switch1>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + }; + + switch1phy2: switch1phy@2 { + reg = <2>; + interrupt-parent = <&switch1>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; + }; + + switch1phy3: switch1phy@3 { + reg = <3>; + interrupt-parent = <&switch1>; + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; + }; + + switch1phy4: switch1phy@4 { + reg = <4>; + interrupt-parent = <&switch1>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/vf610-zii-dev.dtsi b/sys/gnu/dts/arm/vf610-zii-dev.dtsi index ca9e1bc35e45..6b58d3a97992 100644 --- a/sys/gnu/dts/arm/vf610-zii-dev.dtsi +++ b/sys/gnu/dts/arm/vf610-zii-dev.dtsi @@ -296,6 +296,18 @@ >; }; + pinctrl_gpio_switch0: pinctrl-gpio-switch0 { + fsl,pins = < + VF610_PAD_PTB5__GPIO_27 0x219d + >; + }; + + pinctrl_gpio_switch1: pinctrl-gpio-switch1 { + fsl,pins = < + VF610_PAD_PTB4__GPIO_26 0x219d + >; + }; + pinctrl_i2c_mux_reset: pinctrl-i2c-mux-reset { fsl,pins = < VF610_PAD_PTE14__GPIO_119 0x31c2 diff --git a/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h b/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h index 692846c7941b..3190e30b9398 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h +++ b/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h @@ -10,12 +10,18 @@ #define CLKID_FCLK_DIV2 4 #define CLKID_FCLK_DIV3 5 #define CLKID_FCLK_DIV4 6 +#define CLKID_GP0_PLL 9 #define CLKID_CLK81 12 #define CLKID_MPLL2 15 -#define CLKID_SPI 34 #define CLKID_I2C 22 #define CLKID_SAR_ADC 23 +#define CLKID_RNG0 25 +#define CLKID_SPI 34 #define CLKID_ETH 36 +#define CLKID_AIU_GLUE 38 +#define CLKID_I2S_OUT 40 +#define CLKID_MIXER_IFACE 44 +#define CLKID_AIU 47 #define CLKID_USB0 50 #define CLKID_USB1 51 #define CLKID_USB 55 @@ -24,11 +30,17 @@ #define CLKID_USB0_DDR_BRIDGE 65 #define CLKID_SANA 69 #define CLKID_GCLK_VENCI_INT0 77 +#define CLKID_AOCLK_GATE 80 #define CLKID_AO_I2C 93 #define CLKID_SD_EMMC_A 94 #define CLKID_SD_EMMC_B 95 #define CLKID_SD_EMMC_C 96 #define CLKID_SAR_ADC_CLK 97 #define CLKID_SAR_ADC_SEL 98 +#define CLKID_MALI_0_SEL 100 +#define CLKID_MALI_0 102 +#define CLKID_MALI_1_SEL 103 +#define CLKID_MALI_1 105 +#define CLKID_MALI 106 #endif /* __GXBB_CLKC_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h b/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h index 6b03c84f4278..b8ba665aab7b 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h @@ -124,7 +124,10 @@ #define HI6220_CS_DAPB 57 #define HI6220_CS_ATB_DIV 58 -#define HI6220_SYS_NR_CLKS 59 +/* gate clock */ +#define HI6220_DAPB_CLK 59 + +#define HI6220_SYS_NR_CLKS 60 /* clk in Hi6220 media controller */ /* gate clocks */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/mt6797-clk.h b/sys/gnu/dts/include/dt-bindings/clock/mt6797-clk.h new file mode 100644 index 000000000000..2f25a5aca019 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/mt6797-clk.h @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Kevin Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_CLK_MT6797_H +#define _DT_BINDINGS_CLK_MT6797_H + +/* TOPCKGEN */ +#define CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE 1 +#define CLK_TOP_MUX_ULPOSC_AXI_CK_MUX 2 +#define CLK_TOP_MUX_AXI 3 +#define CLK_TOP_MUX_MEM 4 +#define CLK_TOP_MUX_DDRPHYCFG 5 +#define CLK_TOP_MUX_MM 6 +#define CLK_TOP_MUX_PWM 7 +#define CLK_TOP_MUX_VDEC 8 +#define CLK_TOP_MUX_VENC 9 +#define CLK_TOP_MUX_MFG 10 +#define CLK_TOP_MUX_CAMTG 11 +#define CLK_TOP_MUX_UART 12 +#define CLK_TOP_MUX_SPI 13 +#define CLK_TOP_MUX_ULPOSC_SPI_CK_MUX 14 +#define CLK_TOP_MUX_USB20 15 +#define CLK_TOP_MUX_MSDC50_0_HCLK 16 +#define CLK_TOP_MUX_MSDC50_0 17 +#define CLK_TOP_MUX_MSDC30_1 18 +#define CLK_TOP_MUX_MSDC30_2 19 +#define CLK_TOP_MUX_AUDIO 20 +#define CLK_TOP_MUX_AUD_INTBUS 21 +#define CLK_TOP_MUX_PMICSPI 22 +#define CLK_TOP_MUX_SCP 23 +#define CLK_TOP_MUX_ATB 24 +#define CLK_TOP_MUX_MJC 25 +#define CLK_TOP_MUX_DPI0 26 +#define CLK_TOP_MUX_AUD_1 27 +#define CLK_TOP_MUX_AUD_2 28 +#define CLK_TOP_MUX_SSUSB_TOP_SYS 29 +#define CLK_TOP_MUX_SPM 30 +#define CLK_TOP_MUX_BSI_SPI 31 +#define CLK_TOP_MUX_AUDIO_H 32 +#define CLK_TOP_MUX_ANC_MD32 33 +#define CLK_TOP_MUX_MFG_52M 34 +#define CLK_TOP_SYSPLL_CK 35 +#define CLK_TOP_SYSPLL_D2 36 +#define CLK_TOP_SYSPLL1_D2 37 +#define CLK_TOP_SYSPLL1_D4 38 +#define CLK_TOP_SYSPLL1_D8 39 +#define CLK_TOP_SYSPLL1_D16 40 +#define CLK_TOP_SYSPLL_D3 41 +#define CLK_TOP_SYSPLL_D3_D3 42 +#define CLK_TOP_SYSPLL2_D2 43 +#define CLK_TOP_SYSPLL2_D4 44 +#define CLK_TOP_SYSPLL2_D8 45 +#define CLK_TOP_SYSPLL_D5 46 +#define CLK_TOP_SYSPLL3_D2 47 +#define CLK_TOP_SYSPLL3_D4 48 +#define CLK_TOP_SYSPLL_D7 49 +#define CLK_TOP_SYSPLL4_D2 50 +#define CLK_TOP_SYSPLL4_D4 51 +#define CLK_TOP_UNIVPLL_CK 52 +#define CLK_TOP_UNIVPLL_D7 53 +#define CLK_TOP_UNIVPLL_D26 54 +#define CLK_TOP_SSUSB_PHY_48M_CK 55 +#define CLK_TOP_USB_PHY48M_CK 56 +#define CLK_TOP_UNIVPLL_D2 57 +#define CLK_TOP_UNIVPLL1_D2 58 +#define CLK_TOP_UNIVPLL1_D4 59 +#define CLK_TOP_UNIVPLL1_D8 60 +#define CLK_TOP_UNIVPLL_D3 61 +#define CLK_TOP_UNIVPLL2_D2 62 +#define CLK_TOP_UNIVPLL2_D4 63 +#define CLK_TOP_UNIVPLL2_D8 64 +#define CLK_TOP_UNIVPLL_D5 65 +#define CLK_TOP_UNIVPLL3_D2 66 +#define CLK_TOP_UNIVPLL3_D4 67 +#define CLK_TOP_UNIVPLL3_D8 68 +#define CLK_TOP_ULPOSC_CK_ORG 69 +#define CLK_TOP_ULPOSC_CK 70 +#define CLK_TOP_ULPOSC_D2 71 +#define CLK_TOP_ULPOSC_D3 72 +#define CLK_TOP_ULPOSC_D4 73 +#define CLK_TOP_ULPOSC_D8 74 +#define CLK_TOP_ULPOSC_D10 75 +#define CLK_TOP_APLL1_CK 76 +#define CLK_TOP_APLL2_CK 77 +#define CLK_TOP_MFGPLL_CK 78 +#define CLK_TOP_MFGPLL_D2 79 +#define CLK_TOP_IMGPLL_CK 80 +#define CLK_TOP_IMGPLL_D2 81 +#define CLK_TOP_IMGPLL_D4 82 +#define CLK_TOP_CODECPLL_CK 83 +#define CLK_TOP_CODECPLL_D2 84 +#define CLK_TOP_VDECPLL_CK 85 +#define CLK_TOP_TVDPLL_CK 86 +#define CLK_TOP_TVDPLL_D2 87 +#define CLK_TOP_TVDPLL_D4 88 +#define CLK_TOP_TVDPLL_D8 89 +#define CLK_TOP_TVDPLL_D16 90 +#define CLK_TOP_MSDCPLL_CK 91 +#define CLK_TOP_MSDCPLL_D2 92 +#define CLK_TOP_MSDCPLL_D4 93 +#define CLK_TOP_MSDCPLL_D8 94 +#define CLK_TOP_NR 95 + +/* APMIXED_SYS */ +#define CLK_APMIXED_MAINPLL 1 +#define CLK_APMIXED_UNIVPLL 2 +#define CLK_APMIXED_MFGPLL 3 +#define CLK_APMIXED_MSDCPLL 4 +#define CLK_APMIXED_IMGPLL 5 +#define CLK_APMIXED_TVDPLL 6 +#define CLK_APMIXED_CODECPLL 7 +#define CLK_APMIXED_VDECPLL 8 +#define CLK_APMIXED_APLL1 9 +#define CLK_APMIXED_APLL2 10 +#define CLK_APMIXED_NR 11 + +/* INFRA_SYS */ +#define CLK_INFRA_PMIC_TMR 1 +#define CLK_INFRA_PMIC_AP 2 +#define CLK_INFRA_PMIC_MD 3 +#define CLK_INFRA_PMIC_CONN 4 +#define CLK_INFRA_SCP 5 +#define CLK_INFRA_SEJ 6 +#define CLK_INFRA_APXGPT 7 +#define CLK_INFRA_SEJ_13M 8 +#define CLK_INFRA_ICUSB 9 +#define CLK_INFRA_GCE 10 +#define CLK_INFRA_THERM 11 +#define CLK_INFRA_I2C0 12 +#define CLK_INFRA_I2C1 13 +#define CLK_INFRA_I2C2 14 +#define CLK_INFRA_I2C3 15 +#define CLK_INFRA_PWM_HCLK 16 +#define CLK_INFRA_PWM1 17 +#define CLK_INFRA_PWM2 18 +#define CLK_INFRA_PWM3 19 +#define CLK_INFRA_PWM4 20 +#define CLK_INFRA_PWM 21 +#define CLK_INFRA_UART0 22 +#define CLK_INFRA_UART1 23 +#define CLK_INFRA_UART2 24 +#define CLK_INFRA_UART3 25 +#define CLK_INFRA_MD2MD_CCIF_0 26 +#define CLK_INFRA_MD2MD_CCIF_1 27 +#define CLK_INFRA_MD2MD_CCIF_2 28 +#define CLK_INFRA_FHCTL 29 +#define CLK_INFRA_BTIF 30 +#define CLK_INFRA_MD2MD_CCIF_3 31 +#define CLK_INFRA_SPI 32 +#define CLK_INFRA_MSDC0 33 +#define CLK_INFRA_MD2MD_CCIF_4 34 +#define CLK_INFRA_MSDC1 35 +#define CLK_INFRA_MSDC2 36 +#define CLK_INFRA_MD2MD_CCIF_5 37 +#define CLK_INFRA_GCPU 38 +#define CLK_INFRA_TRNG 39 +#define CLK_INFRA_AUXADC 40 +#define CLK_INFRA_CPUM 41 +#define CLK_INFRA_AP_C2K_CCIF_0 42 +#define CLK_INFRA_AP_C2K_CCIF_1 43 +#define CLK_INFRA_CLDMA 44 +#define CLK_INFRA_DISP_PWM 45 +#define CLK_INFRA_AP_DMA 46 +#define CLK_INFRA_DEVICE_APC 47 +#define CLK_INFRA_L2C_SRAM 48 +#define CLK_INFRA_CCIF_AP 49 +#define CLK_INFRA_AUDIO 50 +#define CLK_INFRA_CCIF_MD 51 +#define CLK_INFRA_DRAMC_F26M 52 +#define CLK_INFRA_I2C4 53 +#define CLK_INFRA_I2C_APPM 54 +#define CLK_INFRA_I2C_GPUPM 55 +#define CLK_INFRA_I2C2_IMM 56 +#define CLK_INFRA_I2C2_ARB 57 +#define CLK_INFRA_I2C3_IMM 58 +#define CLK_INFRA_I2C3_ARB 59 +#define CLK_INFRA_I2C5 60 +#define CLK_INFRA_SYS_CIRQ 61 +#define CLK_INFRA_SPI1 62 +#define CLK_INFRA_DRAMC_B_F26M 63 +#define CLK_INFRA_ANC_MD32 64 +#define CLK_INFRA_ANC_MD32_32K 65 +#define CLK_INFRA_DVFS_SPM1 66 +#define CLK_INFRA_AES_TOP0 67 +#define CLK_INFRA_AES_TOP1 68 +#define CLK_INFRA_SSUSB_BUS 69 +#define CLK_INFRA_SPI2 70 +#define CLK_INFRA_SPI3 71 +#define CLK_INFRA_SPI4 72 +#define CLK_INFRA_SPI5 73 +#define CLK_INFRA_IRTX 74 +#define CLK_INFRA_SSUSB_SYS 75 +#define CLK_INFRA_SSUSB_REF 76 +#define CLK_INFRA_AUDIO_26M 77 +#define CLK_INFRA_AUDIO_26M_PAD_TOP 78 +#define CLK_INFRA_MODEM_TEMP_SHARE 79 +#define CLK_INFRA_VAD_WRAP_SOC 80 +#define CLK_INFRA_DRAMC_CONF 81 +#define CLK_INFRA_DRAMC_B_CONF 82 +#define CLK_INFRA_MFG_VCG 83 +#define CLK_INFRA_13M 84 +#define CLK_INFRA_NR 85 + +/* IMG_SYS */ +#define CLK_IMG_FDVT 1 +#define CLK_IMG_DPE 2 +#define CLK_IMG_DIP 3 +#define CLK_IMG_LARB6 4 +#define CLK_IMG_NR 5 + +/* MM_SYS */ +#define CLK_MM_SMI_COMMON 1 +#define CLK_MM_SMI_LARB0 2 +#define CLK_MM_SMI_LARB5 3 +#define CLK_MM_CAM_MDP 4 +#define CLK_MM_MDP_RDMA0 5 +#define CLK_MM_MDP_RDMA1 6 +#define CLK_MM_MDP_RSZ0 7 +#define CLK_MM_MDP_RSZ1 8 +#define CLK_MM_MDP_RSZ2 9 +#define CLK_MM_MDP_TDSHP 10 +#define CLK_MM_MDP_COLOR 11 +#define CLK_MM_MDP_WDMA 12 +#define CLK_MM_MDP_WROT0 13 +#define CLK_MM_MDP_WROT1 14 +#define CLK_MM_FAKE_ENG 15 +#define CLK_MM_DISP_OVL0 16 +#define CLK_MM_DISP_OVL1 17 +#define CLK_MM_DISP_OVL0_2L 18 +#define CLK_MM_DISP_OVL1_2L 19 +#define CLK_MM_DISP_RDMA0 20 +#define CLK_MM_DISP_RDMA1 21 +#define CLK_MM_DISP_WDMA0 22 +#define CLK_MM_DISP_WDMA1 23 +#define CLK_MM_DISP_COLOR 24 +#define CLK_MM_DISP_CCORR 25 +#define CLK_MM_DISP_AAL 26 +#define CLK_MM_DISP_GAMMA 27 +#define CLK_MM_DISP_OD 28 +#define CLK_MM_DISP_DITHER 29 +#define CLK_MM_DISP_UFOE 30 +#define CLK_MM_DISP_DSC 31 +#define CLK_MM_DISP_SPLIT 32 +#define CLK_MM_DSI0_MM_CLOCK 33 +#define CLK_MM_DSI1_MM_CLOCK 34 +#define CLK_MM_DPI_MM_CLOCK 35 +#define CLK_MM_DPI_INTERFACE_CLOCK 36 +#define CLK_MM_LARB4_AXI_ASIF_MM_CLOCK 37 +#define CLK_MM_LARB4_AXI_ASIF_MJC_CLOCK 38 +#define CLK_MM_DISP_OVL0_MOUT_CLOCK 39 +#define CLK_MM_FAKE_ENG2 40 +#define CLK_MM_DSI0_INTERFACE_CLOCK 41 +#define CLK_MM_DSI1_INTERFACE_CLOCK 42 +#define CLK_MM_NR 43 + +/* VDEC_SYS */ +#define CLK_VDEC_CKEN_ENG 1 +#define CLK_VDEC_ACTIVE 2 +#define CLK_VDEC_CKEN 3 +#define CLK_VDEC_LARB1_CKEN 4 +#define CLK_VDEC_NR 5 + +/* VENC_SYS */ +#define CLK_VENC_0 1 +#define CLK_VENC_1 2 +#define CLK_VENC_2 3 +#define CLK_VENC_3 4 +#define CLK_VENC_NR 5 + +#endif /* _DT_BINDINGS_CLK_MT6797_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h index ce09915c298f..bc256d31099a 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h @@ -29,6 +29,9 @@ #define R7S72100_CLK_OSTM0 1 #define R7S72100_CLK_OSTM1 0 +/* MSTP6 */ +#define R7S72100_CLK_RTC 0 + /* MSTP7 */ #define R7S72100_CLK_ETHER 4 @@ -49,7 +52,9 @@ #define R7S72100_CLK_SPI4 3 /* MSTP12 */ -#define R7S72100_CLK_SDHI0 3 -#define R7S72100_CLK_SDHI1 2 +#define R7S72100_CLK_SDHI00 3 +#define R7S72100_CLK_SDHI01 2 +#define R7S72100_CLK_SDHI10 1 +#define R7S72100_CLK_SDHI11 0 #endif /* __DT_BINDINGS_CLOCK_R7S72100_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a73a4-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r8a73a4-clock.h index dd11ecdf837e..4b3668157257 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a73a4-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a73a4-clock.h @@ -54,6 +54,7 @@ #define R8A73A4_CLK_IIC3 11 #define R8A73A4_CLK_IIC4 10 #define R8A73A4_CLK_IIC5 9 +#define R8A73A4_CLK_INTC_SYS 8 #define R8A73A4_CLK_IRQC 7 /* MSTP5 */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7790-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7790-clock.h index fa5e8da809f2..20641fa68e73 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a7790-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7790-clock.h @@ -82,6 +82,7 @@ /* MSTP4 */ #define R8A7790_CLK_IRQC 7 +#define R8A7790_CLK_INTC_SYS 8 /* MSTP5 */ #define R8A7790_CLK_AUDIO_DMAC1 1 diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h index ffa11379b3f0..adc50dc31ab3 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h @@ -72,6 +72,7 @@ /* MSTP4 */ #define R8A7791_CLK_IRQC 7 +#define R8A7791_CLK_INTC_SYS 8 /* MSTP5 */ #define R8A7791_CLK_AUDIO_DMAC1 1 diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7792-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7792-clock.h index 9a8b392ceb00..5be90bc23bd7 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a7792-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7792-clock.h @@ -17,7 +17,6 @@ #define R8A7792_CLK_PLL3 3 #define R8A7792_CLK_LB 4 #define R8A7792_CLK_QSPI 5 -#define R8A7792_CLK_Z 6 /* MSTP0 */ #define R8A7792_CLK_MSIOF0 0 @@ -45,6 +44,7 @@ /* MSTP4 */ #define R8A7792_CLK_IRQC 7 +#define R8A7792_CLK_INTC_SYS 8 /* MSTP5 */ #define R8A7792_CLK_AUDIO_DMAC0 2 diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7793-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7793-clock.h index efcbc594fe82..7318d45d4e7e 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a7793-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7793-clock.h @@ -77,10 +77,11 @@ /* MSTP4 */ #define R8A7793_CLK_IRQC 7 +#define R8A7793_CLK_INTC_SYS 8 /* MSTP5 */ -#define R8A7793_CLK_AUDIO_DMAC1 1 -#define R8A7793_CLK_AUDIO_DMAC0 2 +#define R8A7793_CLK_AUDIO_DMAC1 1 +#define R8A7793_CLK_AUDIO_DMAC0 2 #define R8A7793_CLK_ADSP_MOD 6 #define R8A7793_CLK_THERMAL 22 #define R8A7793_CLK_PWM 23 diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7794-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7794-clock.h index 88e64846cf37..93e99c3ffc8d 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a7794-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7794-clock.h @@ -64,6 +64,7 @@ /* MSTP4 */ #define R8A7794_CLK_IRQC 7 +#define R8A7794_CLK_INTC_SYS 8 /* MSTP5 */ #define R8A7794_CLK_AUDIO_DMAC0 2 @@ -81,6 +82,7 @@ #define R8A7794_CLK_SCIF2 19 #define R8A7794_CLK_SCIF1 20 #define R8A7794_CLK_SCIF0 21 +#define R8A7794_CLK_DU1 23 #define R8A7794_CLK_DU0 24 /* MSTP8 */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7795-cpg-mssr.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7795-cpg-mssr.h index e864aae0a256..f047eaf261f3 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a7795-cpg-mssr.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7795-cpg-mssr.h @@ -60,4 +60,11 @@ #define R8A7795_CLK_R 45 #define R8A7795_CLK_OSC 46 +/* r8a7795 ES2.0 CPG Core Clocks */ +#define R8A7795_CLK_S0D2 47 +#define R8A7795_CLK_S0D3 48 +#define R8A7795_CLK_S0D6 49 +#define R8A7795_CLK_S0D8 50 +#define R8A7795_CLK_S0D12 51 + #endif /* __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/rk3328-cru.h b/sys/gnu/dts/include/dt-bindings/clock/rk3328-cru.h index ee702c8e4c09..d2b26a4b43eb 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/rk3328-cru.h +++ b/sys/gnu/dts/include/dt-bindings/clock/rk3328-cru.h @@ -97,6 +97,7 @@ #define SCLK_MAC2IO_SRC 99 #define SCLK_MAC2IO 100 #define SCLK_MAC2PHY 101 +#define SCLK_MAC2IO_EXT 102 /* dclk gates */ #define DCLK_LCDC 120 diff --git a/sys/gnu/dts/include/dt-bindings/clock/rk3368-cru.h b/sys/gnu/dts/include/dt-bindings/clock/rk3368-cru.h index 9c5dd9ba2f6c..aeb83e581a11 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/rk3368-cru.h +++ b/sys/gnu/dts/include/dt-bindings/clock/rk3368-cru.h @@ -44,13 +44,12 @@ #define SCLK_I2S_8CH 82 #define SCLK_SPDIF_8CH 83 #define SCLK_I2S_2CH 84 -#define SCLK_TIMER0 85 -#define SCLK_TIMER1 86 -#define SCLK_TIMER2 87 -#define SCLK_TIMER3 88 -#define SCLK_TIMER4 89 -#define SCLK_TIMER5 90 -#define SCLK_TIMER6 91 +#define SCLK_TIMER00 85 +#define SCLK_TIMER01 86 +#define SCLK_TIMER02 87 +#define SCLK_TIMER03 88 +#define SCLK_TIMER04 89 +#define SCLK_TIMER05 90 #define SCLK_OTGPHY0 93 #define SCLK_OTG_ADP 96 #define SCLK_HSICPHY480M 97 @@ -82,6 +81,12 @@ #define SCLK_SFC 126 #define SCLK_MAC 127 #define SCLK_MACREF_OUT 128 +#define SCLK_TIMER10 133 +#define SCLK_TIMER11 134 +#define SCLK_TIMER12 135 +#define SCLK_TIMER13 136 +#define SCLK_TIMER14 137 +#define SCLK_TIMER15 138 #define DCLK_VOP 190 #define MCLK_CRYPTO 191 diff --git a/sys/gnu/dts/include/dt-bindings/clock/rk1108-cru.h b/sys/gnu/dts/include/dt-bindings/clock/rv1108-cru.h similarity index 97% rename from sys/gnu/dts/include/dt-bindings/clock/rk1108-cru.h rename to sys/gnu/dts/include/dt-bindings/clock/rv1108-cru.h index 9350a5527a36..ae26f8105914 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/rk1108-cru.h +++ b/sys/gnu/dts/include/dt-bindings/clock/rv1108-cru.h @@ -13,8 +13,8 @@ * GNU General Public License for more details. */ -#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H -#define _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1108_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RV1108_H /* pll id */ #define PLL_APLL 0 @@ -266,4 +266,4 @@ #define ARST_DSP_EDP_PERF 184 #define ARST_DSP_EPP_PERF 185 -#endif /* _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H */ +#endif /* _DT_BINDINGS_CLK_ROCKCHIP_RV1108_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/sun50i-a64-ccu.h b/sys/gnu/dts/include/dt-bindings/clock/sun50i-a64-ccu.h index 370c0a0473fc..d66432c6e675 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/sun50i-a64-ccu.h +++ b/sys/gnu/dts/include/dt-bindings/clock/sun50i-a64-ccu.h @@ -43,6 +43,8 @@ #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_ #define _DT_BINDINGS_CLK_SUN50I_A64_H_ +#define CLK_PLL_PERIPH0 11 + #define CLK_BUS_MIPI_DSI 28 #define CLK_BUS_CE 29 #define CLK_BUS_DMA 30 diff --git a/sys/gnu/dts/include/dt-bindings/clock/sun8i-h3-ccu.h b/sys/gnu/dts/include/dt-bindings/clock/sun8i-h3-ccu.h index efb7ba2bd515..e139fe5c62ec 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/sun8i-h3-ccu.h +++ b/sys/gnu/dts/include/dt-bindings/clock/sun8i-h3-ccu.h @@ -43,6 +43,8 @@ #ifndef _DT_BINDINGS_CLK_SUN8I_H3_H_ #define _DT_BINDINGS_CLK_SUN8I_H3_H_ +#define CLK_PLL_PERIPH0 9 + #define CLK_CPUX 14 #define CLK_BUS_CE 20 @@ -91,7 +93,7 @@ #define CLK_BUS_UART1 63 #define CLK_BUS_UART2 64 #define CLK_BUS_UART3 65 -#define CLK_BUS_SCR 66 +#define CLK_BUS_SCR0 66 #define CLK_BUS_EPHY 67 #define CLK_BUS_DBG 68 @@ -142,4 +144,7 @@ #define CLK_GPU 114 +/* New clocks imported in H5 */ +#define CLK_BUS_SCR1 115 + #endif /* _DT_BINDINGS_CLK_SUN8I_H3_H_ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/sun8i-r-ccu.h b/sys/gnu/dts/include/dt-bindings/clock/sun8i-r-ccu.h new file mode 100644 index 000000000000..779d20aa0d05 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/sun8i-r-ccu.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ +#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ + +#define CLK_AR100 0 + +#define CLK_APB0_PIO 3 +#define CLK_APB0_IR 4 +#define CLK_APB0_TIMER 5 +#define CLK_APB0_RSB 6 +#define CLK_APB0_UART 7 +/* 8 is reserved for CLK_APB0_W1 on A31 */ +#define CLK_APB0_I2C 9 +#define CLK_APB0_TWD 10 + +#define CLK_IR 11 + +#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/tegra114-car.h b/sys/gnu/dts/include/dt-bindings/clock/tegra114-car.h index 534c03f8ad72..ed5ca218c857 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/tegra114-car.h +++ b/sys/gnu/dts/include/dt-bindings/clock/tegra114-car.h @@ -156,7 +156,7 @@ /* 133 */ /* 134 */ /* 135 */ -/* 136 */ +#define TEGRA114_CLK_CEC 136 /* 137 */ /* 138 */ /* 139 */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/tegra124-car-common.h b/sys/gnu/dts/include/dt-bindings/clock/tegra124-car-common.h index a2156090563f..9352c7e2ce0b 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/tegra124-car-common.h +++ b/sys/gnu/dts/include/dt-bindings/clock/tegra124-car-common.h @@ -156,7 +156,7 @@ /* 133 */ /* 134 */ /* 135 */ -/* 136 */ +#define TEGRA124_CLK_CEC 136 /* 137 */ /* 138 */ /* 139 */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/tegra210-car.h b/sys/gnu/dts/include/dt-bindings/clock/tegra210-car.h index 35288b20f2c9..46689cd3750b 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/tegra210-car.h +++ b/sys/gnu/dts/include/dt-bindings/clock/tegra210-car.h @@ -39,7 +39,7 @@ /* 20 (register bit affects vi and vi_sensor) */ /* 21 */ #define TEGRA210_CLK_USBD 22 -#define TEGRA210_CLK_ISP 23 +#define TEGRA210_CLK_ISPA 23 /* 24 */ /* 25 */ #define TEGRA210_CLK_DISP2 26 @@ -156,7 +156,7 @@ /* 133 */ /* 134 */ /* 135 */ -/* 136 */ +#define TEGRA210_CLK_CEC 136 /* 137 */ /* 138 */ /* 139 */ @@ -173,7 +173,7 @@ #define TEGRA210_CLK_ENTROPY 149 /* 150 */ /* 151 */ -/* 152 */ +#define TEGRA210_CLK_DP2 152 /* 153 */ /* 154 */ /* 155 (bit affects dfll_ref and dfll_soc) */ @@ -210,7 +210,7 @@ #define TEGRA210_CLK_DBGAPB 185 /* 186 */ #define TEGRA210_CLK_PLL_P_OUT_ADSP 187 -/* 188 */ +/* 188 ((bit affects pll_a_out_adsp and pll_a_out0_out_adsp)*/ #define TEGRA210_CLK_PLL_G_REF 189 /* 190 */ /* 191 */ @@ -222,7 +222,7 @@ /* 196 */ #define TEGRA210_CLK_DMIC3 197 #define TEGRA210_CLK_APE 198 -/* 199 */ +#define TEGRA210_CLK_ADSP 199 /* 200 */ /* 201 */ #define TEGRA210_CLK_MAUD 202 @@ -241,10 +241,10 @@ /* 215 */ /* 216 */ /* 217 */ -/* 218 */ +#define TEGRA210_CLK_ADSP_NEON 218 #define TEGRA210_CLK_NVENC 219 -/* 220 */ -/* 221 */ +#define TEGRA210_CLK_IQC2 220 +#define TEGRA210_CLK_IQC1 221 #define TEGRA210_CLK_SOR_SAFE 222 #define TEGRA210_CLK_PLL_P_OUT_CPU 223 @@ -349,9 +349,9 @@ #define TEGRA210_CLK_PLL_RE_OUT1 319 /* 320 */ /* 321 */ -/* 322 */ -/* 323 */ -/* 324 */ +#define TEGRA210_CLK_ISP 322 +#define TEGRA210_CLK_PLL_A_OUT_ADSP 323 +#define TEGRA210_CLK_PLL_A_OUT0_OUT_ADSP 324 /* 325 */ /* 326 */ /* 327 */ @@ -396,6 +396,15 @@ #define TEGRA210_CLK_PLL_C_UD 364 #define TEGRA210_CLK_SCLK_MUX 365 -#define TEGRA210_CLK_CLK_MAX 366 +#define TEGRA210_CLK_ACLK 370 + +#define TEGRA210_CLK_DMIC1_SYNC_CLK 388 +#define TEGRA210_CLK_DMIC1_SYNC_CLK_MUX 389 +#define TEGRA210_CLK_DMIC2_SYNC_CLK 390 +#define TEGRA210_CLK_DMIC2_SYNC_CLK_MUX 391 +#define TEGRA210_CLK_DMIC3_SYNC_CLK 392 +#define TEGRA210_CLK_DMIC3_SYNC_CLK_MUX 393 + +#define TEGRA210_CLK_CLK_MAX 394 #endif /* _DT_BINDINGS_CLOCK_TEGRA210_CAR_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/tegra30-car.h b/sys/gnu/dts/include/dt-bindings/clock/tegra30-car.h index 889e49ba0aa3..7213354b9652 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/tegra30-car.h +++ b/sys/gnu/dts/include/dt-bindings/clock/tegra30-car.h @@ -156,7 +156,7 @@ /* 133 */ /* 134 */ /* 135 */ -/* 136 */ +#define TEGRA30_CLK_CEC 136 /* 137 */ /* 138 */ /* 139 */ diff --git a/sys/gnu/dts/include/dt-bindings/genpd/k2g.h b/sys/gnu/dts/include/dt-bindings/genpd/k2g.h new file mode 100644 index 000000000000..1f31f17e19eb --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/genpd/k2g.h @@ -0,0 +1,90 @@ +/* + * TI K2G SoC Device definitions + * + * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_GENPD_K2G_H +#define _DT_BINDINGS_GENPD_K2G_H + +/* Documented in http://processors.wiki.ti.com/index.php/TISCI */ + +#define K2G_DEV_PMMC0 0x0000 +#define K2G_DEV_MLB0 0x0001 +#define K2G_DEV_DSS0 0x0002 +#define K2G_DEV_MCBSP0 0x0003 +#define K2G_DEV_MCASP0 0x0004 +#define K2G_DEV_MCASP1 0x0005 +#define K2G_DEV_MCASP2 0x0006 +#define K2G_DEV_DCAN0 0x0008 +#define K2G_DEV_DCAN1 0x0009 +#define K2G_DEV_EMIF0 0x000a +#define K2G_DEV_MMCHS0 0x000b +#define K2G_DEV_MMCHS1 0x000c +#define K2G_DEV_GPMC0 0x000d +#define K2G_DEV_ELM0 0x000e +#define K2G_DEV_SPI0 0x0010 +#define K2G_DEV_SPI1 0x0011 +#define K2G_DEV_SPI2 0x0012 +#define K2G_DEV_SPI3 0x0013 +#define K2G_DEV_ICSS0 0x0014 +#define K2G_DEV_ICSS1 0x0015 +#define K2G_DEV_USB0 0x0016 +#define K2G_DEV_USB1 0x0017 +#define K2G_DEV_NSS0 0x0018 +#define K2G_DEV_PCIE0 0x0019 +#define K2G_DEV_GPIO0 0x001b +#define K2G_DEV_GPIO1 0x001c +#define K2G_DEV_TIMER64_0 0x001d +#define K2G_DEV_TIMER64_1 0x001e +#define K2G_DEV_TIMER64_2 0x001f +#define K2G_DEV_TIMER64_3 0x0020 +#define K2G_DEV_TIMER64_4 0x0021 +#define K2G_DEV_TIMER64_5 0x0022 +#define K2G_DEV_TIMER64_6 0x0023 +#define K2G_DEV_MSGMGR0 0x0025 +#define K2G_DEV_BOOTCFG0 0x0026 +#define K2G_DEV_ARM_BOOTROM0 0x0027 +#define K2G_DEV_DSP_BOOTROM0 0x0029 +#define K2G_DEV_DEBUGSS0 0x002b +#define K2G_DEV_UART0 0x002c +#define K2G_DEV_UART1 0x002d +#define K2G_DEV_UART2 0x002e +#define K2G_DEV_EHRPWM0 0x002f +#define K2G_DEV_EHRPWM1 0x0030 +#define K2G_DEV_EHRPWM2 0x0031 +#define K2G_DEV_EHRPWM3 0x0032 +#define K2G_DEV_EHRPWM4 0x0033 +#define K2G_DEV_EHRPWM5 0x0034 +#define K2G_DEV_EQEP0 0x0035 +#define K2G_DEV_EQEP1 0x0036 +#define K2G_DEV_EQEP2 0x0037 +#define K2G_DEV_ECAP0 0x0038 +#define K2G_DEV_ECAP1 0x0039 +#define K2G_DEV_I2C0 0x003a +#define K2G_DEV_I2C1 0x003b +#define K2G_DEV_I2C2 0x003c +#define K2G_DEV_EDMA0 0x003f +#define K2G_DEV_SEMAPHORE0 0x0040 +#define K2G_DEV_INTC0 0x0041 +#define K2G_DEV_GIC0 0x0042 +#define K2G_DEV_QSPI0 0x0043 +#define K2G_DEV_ARM_64B_COUNTER0 0x0044 +#define K2G_DEV_TETRIS0 0x0045 +#define K2G_DEV_CGEM0 0x0046 +#define K2G_DEV_MSMC0 0x0047 +#define K2G_DEV_CBASS0 0x0049 +#define K2G_DEV_BOARD0 0x004c +#define K2G_DEV_EDMA1 0x004f + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/gpio/gpio.h b/sys/gnu/dts/include/dt-bindings/gpio/gpio.h index c673d2c87c60..b4f54da694eb 100644 --- a/sys/gnu/dts/include/dt-bindings/gpio/gpio.h +++ b/sys/gnu/dts/include/dt-bindings/gpio/gpio.h @@ -17,11 +17,15 @@ #define GPIO_PUSH_PULL 0 #define GPIO_SINGLE_ENDED 2 +/* Bit 2 express Open drain or open source */ +#define GPIO_LINE_OPEN_SOURCE 0 +#define GPIO_LINE_OPEN_DRAIN 4 + /* - * Open Drain/Collector is the combination of single-ended active low, - * Open Source/Emitter is the combination of single-ended active high. + * Open Drain/Collector is the combination of single-ended open drain interface. + * Open Source/Emitter is the combination of single-ended open source interface. */ -#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_ACTIVE_LOW) -#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_ACTIVE_HIGH) +#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN) +#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE) #endif diff --git a/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h b/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h index 3af60ee69053..f5a8d96e1e09 100644 --- a/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h +++ b/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h @@ -641,6 +641,7 @@ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) */ #define KEY_DATA 0x277 +#define KEY_ONSCREEN_KEYBOARD 0x278 #define BTN_TRIGGER_HAPPY 0x2c0 #define BTN_TRIGGER_HAPPY1 0x2c0 diff --git a/sys/gnu/dts/include/dt-bindings/mfd/stm32f7-rcc.h b/sys/gnu/dts/include/dt-bindings/mfd/stm32f7-rcc.h new file mode 100644 index 000000000000..e36cc69959c7 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/mfd/stm32f7-rcc.h @@ -0,0 +1,112 @@ +/* + * This header provides constants for the STM32F7 RCC IP + */ + +#ifndef _DT_BINDINGS_MFD_STM32F7_RCC_H +#define _DT_BINDINGS_MFD_STM32F7_RCC_H + +/* AHB1 */ +#define STM32F7_RCC_AHB1_GPIOA 0 +#define STM32F7_RCC_AHB1_GPIOB 1 +#define STM32F7_RCC_AHB1_GPIOC 2 +#define STM32F7_RCC_AHB1_GPIOD 3 +#define STM32F7_RCC_AHB1_GPIOE 4 +#define STM32F7_RCC_AHB1_GPIOF 5 +#define STM32F7_RCC_AHB1_GPIOG 6 +#define STM32F7_RCC_AHB1_GPIOH 7 +#define STM32F7_RCC_AHB1_GPIOI 8 +#define STM32F7_RCC_AHB1_GPIOJ 9 +#define STM32F7_RCC_AHB1_GPIOK 10 +#define STM32F7_RCC_AHB1_CRC 12 +#define STM32F7_RCC_AHB1_BKPSRAM 18 +#define STM32F7_RCC_AHB1_DTCMRAM 20 +#define STM32F7_RCC_AHB1_DMA1 21 +#define STM32F7_RCC_AHB1_DMA2 22 +#define STM32F7_RCC_AHB1_DMA2D 23 +#define STM32F7_RCC_AHB1_ETHMAC 25 +#define STM32F7_RCC_AHB1_ETHMACTX 26 +#define STM32F7_RCC_AHB1_ETHMACRX 27 +#define STM32FF_RCC_AHB1_ETHMACPTP 28 +#define STM32F7_RCC_AHB1_OTGHS 29 +#define STM32F7_RCC_AHB1_OTGHSULPI 30 + +#define STM32F7_AHB1_RESET(bit) (STM32F7_RCC_AHB1_##bit + (0x10 * 8)) +#define STM32F7_AHB1_CLOCK(bit) (STM32F7_RCC_AHB1_##bit) + + +/* AHB2 */ +#define STM32F7_RCC_AHB2_DCMI 0 +#define STM32F7_RCC_AHB2_CRYP 4 +#define STM32F7_RCC_AHB2_HASH 5 +#define STM32F7_RCC_AHB2_RNG 6 +#define STM32F7_RCC_AHB2_OTGFS 7 + +#define STM32F7_AHB2_RESET(bit) (STM32F7_RCC_AHB2_##bit + (0x14 * 8)) +#define STM32F7_AHB2_CLOCK(bit) (STM32F7_RCC_AHB2_##bit + 0x20) + +/* AHB3 */ +#define STM32F7_RCC_AHB3_FMC 0 +#define STM32F7_RCC_AHB3_QSPI 1 + +#define STM32F7_AHB3_RESET(bit) (STM32F7_RCC_AHB3_##bit + (0x18 * 8)) +#define STM32F7_AHB3_CLOCK(bit) (STM32F7_RCC_AHB3_##bit + 0x40) + +/* APB1 */ +#define STM32F7_RCC_APB1_TIM2 0 +#define STM32F7_RCC_APB1_TIM3 1 +#define STM32F7_RCC_APB1_TIM4 2 +#define STM32F7_RCC_APB1_TIM5 3 +#define STM32F7_RCC_APB1_TIM6 4 +#define STM32F7_RCC_APB1_TIM7 5 +#define STM32F7_RCC_APB1_TIM12 6 +#define STM32F7_RCC_APB1_TIM13 7 +#define STM32F7_RCC_APB1_TIM14 8 +#define STM32F7_RCC_APB1_LPTIM1 9 +#define STM32F7_RCC_APB1_WWDG 11 +#define STM32F7_RCC_APB1_SPI2 14 +#define STM32F7_RCC_APB1_SPI3 15 +#define STM32F7_RCC_APB1_SPDIFRX 16 +#define STM32F7_RCC_APB1_UART2 17 +#define STM32F7_RCC_APB1_UART3 18 +#define STM32F7_RCC_APB1_UART4 19 +#define STM32F7_RCC_APB1_UART5 20 +#define STM32F7_RCC_APB1_I2C1 21 +#define STM32F7_RCC_APB1_I2C2 22 +#define STM32F7_RCC_APB1_I2C3 23 +#define STM32F7_RCC_APB1_I2C4 24 +#define STM32F7_RCC_APB1_CAN1 25 +#define STM32F7_RCC_APB1_CAN2 26 +#define STM32F7_RCC_APB1_CEC 27 +#define STM32F7_RCC_APB1_PWR 28 +#define STM32F7_RCC_APB1_DAC 29 +#define STM32F7_RCC_APB1_UART7 30 +#define STM32F7_RCC_APB1_UART8 31 + +#define STM32F7_APB1_RESET(bit) (STM32F7_RCC_APB1_##bit + (0x20 * 8)) +#define STM32F7_APB1_CLOCK(bit) (STM32F7_RCC_APB1_##bit + 0x80) + +/* APB2 */ +#define STM32F7_RCC_APB2_TIM1 0 +#define STM32F7_RCC_APB2_TIM8 1 +#define STM32F7_RCC_APB2_USART1 4 +#define STM32F7_RCC_APB2_USART6 5 +#define STM32F7_RCC_APB2_ADC1 8 +#define STM32F7_RCC_APB2_ADC2 9 +#define STM32F7_RCC_APB2_ADC3 10 +#define STM32F7_RCC_APB2_SDMMC1 11 +#define STM32F7_RCC_APB2_SPI1 12 +#define STM32F7_RCC_APB2_SPI4 13 +#define STM32F7_RCC_APB2_SYSCFG 14 +#define STM32F7_RCC_APB2_TIM9 16 +#define STM32F7_RCC_APB2_TIM10 17 +#define STM32F7_RCC_APB2_TIM11 18 +#define STM32F7_RCC_APB2_SPI5 20 +#define STM32F7_RCC_APB2_SPI6 21 +#define STM32F7_RCC_APB2_SAI1 22 +#define STM32F7_RCC_APB2_SAI2 23 +#define STM32F7_RCC_APB2_LTDC 26 + +#define STM32F7_APB2_RESET(bit) (STM32F7_RCC_APB2_##bit + (0x24 * 8)) +#define STM32F7_APB2_CLOCK(bit) (STM32F7_RCC_APB2_##bit + 0xA0) + +#endif /* _DT_BINDINGS_MFD_STM32F7_RCC_H */ diff --git a/sys/gnu/dts/include/dt-bindings/pinctrl/hisi.h b/sys/gnu/dts/include/dt-bindings/pinctrl/hisi.h index 38f1ea879ea1..0359bfdc9119 100644 --- a/sys/gnu/dts/include/dt-bindings/pinctrl/hisi.h +++ b/sys/gnu/dts/include/dt-bindings/pinctrl/hisi.h @@ -56,4 +56,19 @@ #define DRIVE4_08MA (4 << 4) #define DRIVE4_10MA (6 << 4) +/* drive strength definition for hi3660 */ +#define DRIVE6_MASK (15 << 4) +#define DRIVE6_04MA (0 << 4) +#define DRIVE6_12MA (4 << 4) +#define DRIVE6_19MA (8 << 4) +#define DRIVE6_27MA (10 << 4) +#define DRIVE6_32MA (15 << 4) +#define DRIVE7_02MA (0 << 4) +#define DRIVE7_04MA (1 << 4) +#define DRIVE7_06MA (2 << 4) +#define DRIVE7_08MA (3 << 4) +#define DRIVE7_10MA (4 << 4) +#define DRIVE7_12MA (5 << 4) +#define DRIVE7_14MA (6 << 4) +#define DRIVE7_16MA (7 << 4) #endif diff --git a/sys/gnu/dts/include/dt-bindings/pinctrl/mt7623-pinfunc.h b/sys/gnu/dts/include/dt-bindings/pinctrl/mt7623-pinfunc.h index 2f00bdc42442..436a87be864a 100644 --- a/sys/gnu/dts/include/dt-bindings/pinctrl/mt7623-pinfunc.h +++ b/sys/gnu/dts/include/dt-bindings/pinctrl/mt7623-pinfunc.h @@ -185,6 +185,12 @@ #define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO (MTK_PIN_NO(56) | 1) #define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MI (MTK_PIN_NO(56) | 2) +#define MT7623_PIN_57_SDA1_FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define MT7623_PIN_57_SDA1_FUNC_SDA1 (MTK_PIN_NO(57) | 1) + +#define MT7623_PIN_58_SCL1_FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define MT7623_PIN_58_SCL1_FUNC_SCL1 (MTK_PIN_NO(58) | 1) + #define MT7623_PIN_60_WB_RSTB_FUNC_GPIO60 (MTK_PIN_NO(60) | 0) #define MT7623_PIN_60_WB_RSTB_FUNC_WB_RSTB (MTK_PIN_NO(60) | 1) @@ -244,6 +250,22 @@ #define MT7623_PIN_76_SCL0_FUNC_GPIO76 (MTK_PIN_NO(76) | 0) #define MT7623_PIN_76_SCL0_FUNC_SCL0 (MTK_PIN_NO(76) | 1) +#define MT7623_PIN_79_URXD0_FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define MT7623_PIN_79_URXD0_FUNC_URXD0 (MTK_PIN_NO(79) | 1) +#define MT7623_PIN_79_URXD0_FUNC_UTXD0 (MTK_PIN_NO(79) | 2) + +#define MT7623_PIN_80_UTXD0_FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define MT7623_PIN_80_UTXD0_FUNC_UTXD0 (MTK_PIN_NO(80) | 1) +#define MT7623_PIN_80_UTXD0_FUNC_URXD0 (MTK_PIN_NO(80) | 2) + +#define MT7623_PIN_81_URXD1_FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define MT7623_PIN_81_URXD1_FUNC_URXD1 (MTK_PIN_NO(81) | 1) +#define MT7623_PIN_81_URXD1_FUNC_UTXD1 (MTK_PIN_NO(81) | 2) + +#define MT7623_PIN_82_UTXD1_FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define MT7623_PIN_82_UTXD1_FUNC_UTXD1 (MTK_PIN_NO(82) | 1) +#define MT7623_PIN_82_UTXD1_FUNC_URXD1 (MTK_PIN_NO(82) | 2) + #define MT7623_PIN_83_LCM_RST_FUNC_GPIO83 (MTK_PIN_NO(83) | 0) #define MT7623_PIN_83_LCM_RST_FUNC_LCM_RST (MTK_PIN_NO(83) | 1) @@ -351,10 +373,10 @@ #define MT7623_PIN_122_GPIO122_FUNC_SDA2 (MTK_PIN_NO(122) | 4) #define MT7623_PIN_122_GPIO122_FUNC_URXD0 (MTK_PIN_NO(122) | 5) -#define MT7623_PIN_123_GPIO123_FUNC_GPIO123 (MTK_PIN_NO(123) | 0) -#define MT7623_PIN_123_GPIO123_FUNC_TEST (MTK_PIN_NO(123) | 1) -#define MT7623_PIN_123_GPIO123_FUNC_SCL2 (MTK_PIN_NO(123) | 4) -#define MT7623_PIN_123_GPIO123_FUNC_UTXD0 (MTK_PIN_NO(123) | 5) +#define MT7623_PIN_123_HTPLG_FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define MT7623_PIN_123_HTPLG_FUNC_HTPLG (MTK_PIN_NO(123) | 1) +#define MT7623_PIN_123_HTPLG_FUNC_SCL2 (MTK_PIN_NO(123) | 4) +#define MT7623_PIN_123_HTPLG_FUNC_UTXD0 (MTK_PIN_NO(123) | 5) #define MT7623_PIN_124_GPIO124_FUNC_GPIO124 (MTK_PIN_NO(124) | 0) #define MT7623_PIN_124_GPIO124_FUNC_TEST (MTK_PIN_NO(124) | 1) diff --git a/sys/gnu/dts/include/dt-bindings/power/imx7-power.h b/sys/gnu/dts/include/dt-bindings/power/imx7-power.h new file mode 100644 index 000000000000..3a181e410517 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/power/imx7-power.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2017 Impinj + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __DT_BINDINGS_IMX7_POWER_H__ +#define __DT_BINDINGS_IMX7_POWER_H__ + +#define IMX7_POWER_DOMAIN_MIPI_PHY 0 +#define IMX7_POWER_DOMAIN_PCIE_PHY 1 +#define IMX7_POWER_DOMAIN_USB_HSIC_PHY 2 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/power/r8a7795-sysc.h b/sys/gnu/dts/include/dt-bindings/power/r8a7795-sysc.h index ee2e26ba605e..ad679eeda137 100644 --- a/sys/gnu/dts/include/dt-bindings/power/r8a7795-sysc.h +++ b/sys/gnu/dts/include/dt-bindings/power/r8a7795-sysc.h @@ -33,7 +33,7 @@ #define R8A7795_PD_CA53_SCU 21 #define R8A7795_PD_3DG_E 22 #define R8A7795_PD_A3IR 24 -#define R8A7795_PD_A2VC0 25 +#define R8A7795_PD_A2VC0 25 /* ES1.x only */ #define R8A7795_PD_A2VC1 26 /* Always-on power area */ diff --git a/sys/gnu/dts/include/dt-bindings/reset/altr,rst-mgr-a10sr.h b/sys/gnu/dts/include/dt-bindings/reset/altr,rst-mgr-a10sr.h new file mode 100644 index 000000000000..9855925e5256 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/altr,rst-mgr-a10sr.h @@ -0,0 +1,33 @@ +/* + * Copyright Intel Corporation (C) 2017. All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * Reset binding definitions for Altera Arria10 MAX5 System Resource Chip + * + * Adapted from altr,rst-mgr-a10.h + */ + +#ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H +#define _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H + +/* Peripheral PHY resets */ +#define A10SR_RESET_ENET_HPS 0 +#define A10SR_RESET_PCIE 1 +#define A10SR_RESET_FILE 2 +#define A10SR_RESET_BQSPI 3 +#define A10SR_RESET_USB 4 + +#define A10SR_RESET_NUM 5 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/reset/imx7-reset.h b/sys/gnu/dts/include/dt-bindings/reset/imx7-reset.h new file mode 100644 index 000000000000..63948170c7b2 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/imx7-reset.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 Impinj, Inc. + * + * Author: Andrey Smirnov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DT_BINDING_RESET_IMX7_H +#define DT_BINDING_RESET_IMX7_H + +#define IMX7_RESET_A7_CORE_POR_RESET0 0 +#define IMX7_RESET_A7_CORE_POR_RESET1 1 +#define IMX7_RESET_A7_CORE_RESET0 2 +#define IMX7_RESET_A7_CORE_RESET1 3 +#define IMX7_RESET_A7_DBG_RESET0 4 +#define IMX7_RESET_A7_DBG_RESET1 5 +#define IMX7_RESET_A7_ETM_RESET0 6 +#define IMX7_RESET_A7_ETM_RESET1 7 +#define IMX7_RESET_A7_SOC_DBG_RESET 8 +#define IMX7_RESET_A7_L2RESET 9 +#define IMX7_RESET_SW_M4C_RST 10 +#define IMX7_RESET_SW_M4P_RST 11 +#define IMX7_RESET_EIM_RST 12 +#define IMX7_RESET_HSICPHY_PORT_RST 13 +#define IMX7_RESET_USBPHY1_POR 14 +#define IMX7_RESET_USBPHY1_PORT_RST 15 +#define IMX7_RESET_USBPHY2_POR 16 +#define IMX7_RESET_USBPHY2_PORT_RST 17 +#define IMX7_RESET_MIPI_PHY_MRST 18 +#define IMX7_RESET_MIPI_PHY_SRST 19 + +/* + * IMX7_RESET_PCIEPHY is a logical reset line combining PCIEPHY_BTN + * and PCIEPHY_G_RST + */ +#define IMX7_RESET_PCIEPHY 20 +#define IMX7_RESET_PCIEPHY_PERST 21 + +/* + * IMX7_RESET_PCIE_CTRL_APPS_EN is not strictly a reset line, but it + * can be used to inhibit PCIe LTTSM, so, in a way, it can be thoguht + * of as one + */ +#define IMX7_RESET_PCIE_CTRL_APPS_EN 22 +#define IMX7_RESET_DDRC_PRST 23 +#define IMX7_RESET_DDRC_CORE_RST 24 + +#define IMX7_RESET_NUM 25 + +#endif + diff --git a/sys/gnu/dts/include/dt-bindings/reset/mt2701-resets.h b/sys/gnu/dts/include/dt-bindings/reset/mt2701-resets.h index aaf03057f755..21deb547cfa4 100644 --- a/sys/gnu/dts/include/dt-bindings/reset/mt2701-resets.h +++ b/sys/gnu/dts/include/dt-bindings/reset/mt2701-resets.h @@ -80,4 +80,11 @@ #define MT2701_HIFSYS_PCIE1_RST 25 #define MT2701_HIFSYS_PCIE2_RST 26 +/* ETHSYS resets */ +#define MT2701_ETHSYS_SYS_RST 0 +#define MT2701_ETHSYS_MCM_RST 2 +#define MT2701_ETHSYS_FE_RST 6 +#define MT2701_ETHSYS_GMAC_RST 23 +#define MT2701_ETHSYS_PPE_RST 31 + #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */ diff --git a/sys/gnu/dts/include/dt-bindings/reset/sun8i-h3-ccu.h b/sys/gnu/dts/include/dt-bindings/reset/sun8i-h3-ccu.h index 6b7af80c26ec..484c2a22919d 100644 --- a/sys/gnu/dts/include/dt-bindings/reset/sun8i-h3-ccu.h +++ b/sys/gnu/dts/include/dt-bindings/reset/sun8i-h3-ccu.h @@ -98,6 +98,9 @@ #define RST_BUS_UART1 50 #define RST_BUS_UART2 51 #define RST_BUS_UART3 52 -#define RST_BUS_SCR 53 +#define RST_BUS_SCR0 53 + +/* New resets imported in H5 */ +#define RST_BUS_SCR1 54 #endif /* _DT_BINDINGS_RST_SUN8I_H3_H_ */ diff --git a/sys/gnu/dts/include/dt-bindings/reset/sun8i-r-ccu.h b/sys/gnu/dts/include/dt-bindings/reset/sun8i-r-ccu.h new file mode 100644 index 000000000000..4ba64f3d6fc9 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/sun8i-r-ccu.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_ +#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_ + +#define RST_APB0_IR 0 +#define RST_APB0_TIMER 1 +#define RST_APB0_RSB 2 +#define RST_APB0_UART 3 +/* 4 is reserved for RST_APB0_W1 on A31 */ +#define RST_APB0_I2C 5 + +#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */ diff --git a/sys/gnu/dts/include/dt-bindings/reset/tegra210-car.h b/sys/gnu/dts/include/dt-bindings/reset/tegra210-car.h new file mode 100644 index 000000000000..296ec6e3f8c0 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/tegra210-car.h @@ -0,0 +1,13 @@ +/* + * This header provides Tegra210-specific constants for binding + * nvidia,tegra210-car. + */ + +#ifndef _DT_BINDINGS_RESET_TEGRA210_CAR_H +#define _DT_BINDINGS_RESET_TEGRA210_CAR_H + +#define TEGRA210_RESET(x) (7 * 32 + (x)) +#define TEGRA210_RST_DFLL_DVCO TEGRA210_RESET(0) +#define TEGRA210_RST_ADSP TEGRA210_RESET(1) + +#endif /* _DT_BINDINGS_RESET_TEGRA210_CAR_H */ diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 041bd9268a3c..ce64f83b03f3 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -673,7 +673,6 @@ device arcmsr # Areca SATA II RAID # The driver is implemented as a SIM, and so, needs the CAM infrastructure. # options TWA_DEBUG # 0-10; 10 prints the most messages. -options TWA_FLASH_FIRMWARE # firmware image bundled when defined. device twa # 3ware 9000 series PATA/SATA RAID # diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 3ad3ff997c67..a49bb1784a69 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -550,11 +550,7 @@ trap(struct trapframe *frame) vm86_trap((struct vm86frame *)frame); goto out; } - if (type == T_STKFLT) - break; - /* FALL THROUGH */ - case T_SEGNPFLT: /* segment not present fault */ if (curpcb->pcb_flags & PCB_VM86CALL) break; @@ -595,6 +591,9 @@ trap(struct trapframe *frame) frame->tf_eip = (int)doreti_iret_fault; goto out; } + if (type == T_STKFLT) + break; + if (frame->tf_eip == (int)doreti_popl_ds) { frame->tf_eip = (int)doreti_popl_ds_fault; goto out; diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index a4919a02acef..7a189fea72ef 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -1120,9 +1120,22 @@ static Elf32_Brandinfo linux_glibc2brand = { .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE }; +static Elf32_Brandinfo linux_muslbrand = { + .brand = ELFOSABI_LINUX, + .machine = EM_386, + .compat_3_brand = "Linux", + .emul_path = "/compat/linux", + .interp_path = "/lib/ld-musl-i386.so.1", + .sysvec = &elf_linux_sysvec, + .interp_newpath = NULL, + .brand_note = &linux_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + Elf32_Brandinfo *linux_brandlist[] = { &linux_brand, &linux_glibc2brand, + &linux_muslbrand, NULL }; diff --git a/sys/isa/rtc.h b/sys/isa/rtc.h index 011854a37159..64dd4e012715 100644 --- a/sys/isa/rtc.h +++ b/sys/isa/rtc.h @@ -113,6 +113,7 @@ #ifdef _KERNEL extern struct mtx clock_lock; +extern struct mtx atrtc_time_lock; extern int atrtcclock_disable; int rtcin(int reg); void atrtc_restore(void); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index bb9334146249..953da2d908a7 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1054,9 +1054,9 @@ exec_unmap_first_page(struct image_params *imgp) } /* - * Destroy old address space, and allocate a new stack - * The new stack is only SGROWSIZ large because it is grown - * automatically in trap.c. + * Destroy old address space, and allocate a new stack. + * The new stack is only sgrowsiz large because it is grown + * automatically on a page fault. */ int exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv) @@ -1112,9 +1112,9 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv) VM_PROT_READ | VM_PROT_EXECUTE, VM_PROT_READ | VM_PROT_EXECUTE, MAP_INHERIT_SHARE | MAP_ACC_NO_CHARGE); - if (error) { + if (error != KERN_SUCCESS) { vm_object_deallocate(obj); - return (error); + return (vm_mmap_to_errno(error)); } } @@ -1138,10 +1138,9 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv) stack_addr = sv->sv_usrstack - ssiz; error = vm_map_stack(map, stack_addr, (vm_size_t)ssiz, obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : - sv->sv_stackprot, - VM_PROT_ALL, MAP_STACK_GROWS_DOWN); - if (error) - return (error); + sv->sv_stackprot, VM_PROT_ALL, MAP_STACK_GROWS_DOWN); + if (error != KERN_SUCCESS) + return (vm_mmap_to_errno(error)); /* * vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but they diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index af699ab4fda7..97ca92810d9b 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -650,7 +650,7 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis uintmax_t num; int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; int cflag, hflag, jflag, tflag, zflag; - int dwidth, upper; + int bconv, dwidth, upper; char padc; int stop = 0, retval = 0; @@ -676,7 +676,7 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis } percent = fmt - 1; qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; - sign = 0; dot = 0; dwidth = 0; upper = 0; + sign = 0; dot = 0; bconv = 0; dwidth = 0; upper = 0; cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; reswitch: switch (ch = (u_char)*fmt++) { case '.': @@ -724,28 +724,9 @@ reswitch: switch (ch = (u_char)*fmt++) { width = n; goto reswitch; case 'b': - num = (u_int)va_arg(ap, int); - p = va_arg(ap, char *); - for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) - PCHAR(*q--); - - if (num == 0) - break; - - for (tmp = 0; *p;) { - n = *p++; - if (num & (1 << (n - 1))) { - PCHAR(tmp ? ',' : '<'); - for (; (n = *p) > ' '; ++p) - PCHAR(n); - tmp = 1; - } else - for (; *p > ' '; ++p) - continue; - } - if (tmp) - PCHAR('>'); - break; + ladjust = 1; + bconv = 1; + goto handle_nosign; case 'c': width -= 1; @@ -883,6 +864,10 @@ reswitch: switch (ch = (u_char)*fmt++) { num = (u_char)va_arg(ap, int); else num = va_arg(ap, u_int); + if (bconv) { + q = va_arg(ap, char *); + base = *q++; + } goto number; handle_sign: if (jflag) @@ -940,6 +925,26 @@ reswitch: switch (ch = (u_char)*fmt++) { while (*p) PCHAR(*p--); + if (bconv && num != 0) { + /* %b conversion flag format. */ + tmp = retval; + while (*q) { + n = *q++; + if (num & (1 << (n - 1))) { + PCHAR(retval != tmp ? + ',' : '<'); + for (; (n = *q) > ' '; ++q) + PCHAR(n); + } else + for (; *q > ' '; ++q) + continue; + } + if (retval != tmp) { + PCHAR('>'); + width -= retval - tmp; + } + } + if (ladjust) while (width-- > 0) PCHAR(' '); diff --git a/sys/kern/subr_rtc.c b/sys/kern/subr_rtc.c index 538708c5a314..a0884852ab33 100644 --- a/sys/kern/subr_rtc.c +++ b/sys/kern/subr_rtc.c @@ -63,8 +63,10 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include +#include #include +#include #ifdef FFCLOCK #include #endif @@ -72,116 +74,210 @@ __FBSDID("$FreeBSD$"); #include "clock_if.h" -static device_t clock_dev = NULL; -static long clock_res; -static struct timespec clock_adj; -struct mtx resettodr_lock; -MTX_SYSINIT(resettodr_init, &resettodr_lock, "tod2rl", MTX_DEF); - /* XXX: should be kern. now, it's no longer machdep. */ static int disable_rtc_set; SYSCTL_INT(_machdep, OID_AUTO, disable_rtc_set, CTLFLAG_RW, &disable_rtc_set, 0, "Disallow adjusting time-of-day clock"); +/* + * An instance of a realtime clock. A list of these tracks all the registered + * clocks in the system. + * + * The resadj member is used to apply a "resolution adjustment" equal to half + * the clock's resolution, which is useful mainly on clocks with a whole-second + * resolution. Because the clock truncates the fractional part, adding half the + * resolution performs 4/5 rounding. The same adjustment is applied to the + * times returned from clock_gettime(), because the fraction returned will + * always be zero, but on average the actual fraction at the time of the call + * should be about .5. + */ +struct rtc_instance { + device_t clockdev; + int resolution; + int flags; + struct timespec resadj; + LIST_ENTRY(rtc_instance) + rtc_entries; +}; + +/* + * Clocks are updated using a task running on taskqueue_thread. + */ +static void settime_task_func(void *arg, int pending); +static struct task settime_task = TASK_INITIALIZER(0, settime_task_func, NULL); + +/* + * Registered clocks are kept in a list which is sorted by resolution; the more + * accurate clocks get the first shot at providing the time. + */ +LIST_HEAD(rtc_listhead, rtc_instance); +static struct rtc_listhead rtc_list = LIST_HEAD_INITIALIZER(rtc_list); +static struct sx rtc_list_lock; +SX_SYSINIT(rtc_list_lock_init, &rtc_list_lock, "rtc list"); + +/* + * On the task thread, invoke the clock_settime() method of each registered + * clock. Do so holding only an sxlock, so that clock drivers are free to do + * whatever kind of locking or sleeping they need to. + */ +static void +settime_task_func(void *arg, int pending) +{ + struct timespec ts; + struct rtc_instance *rtc; + + sx_xlock(&rtc_list_lock); + LIST_FOREACH(rtc, &rtc_list, rtc_entries) { + if (!(rtc->flags & CLOCKF_SETTIME_NO_TS)) { + getnanotime(&ts); + if (!(rtc->flags & CLOCKF_SETTIME_NO_ADJ)) { + ts.tv_sec -= utc_offset(); + timespecadd(&ts, &rtc->resadj); + } + } else { + ts.tv_sec = 0; + ts.tv_nsec = 0; + } + CLOCK_SETTIME(rtc->clockdev, &ts); + } + sx_xunlock(&rtc_list_lock); +} + void -clock_register(device_t dev, long res) /* res has units of microseconds */ +clock_register_flags(device_t clockdev, long resolution, int flags) +{ + struct rtc_instance *rtc, *newrtc; + + newrtc = malloc(sizeof(*newrtc), M_DEVBUF, M_WAITOK); + newrtc->clockdev = clockdev; + newrtc->resolution = (int)resolution; + newrtc->flags = flags; + newrtc->resadj.tv_sec = newrtc->resolution / 2 / 1000000; + newrtc->resadj.tv_nsec = newrtc->resolution / 2 % 1000000 * 1000; + + sx_xlock(&rtc_list_lock); + if (LIST_EMPTY(&rtc_list)) { + LIST_INSERT_HEAD(&rtc_list, newrtc, rtc_entries); + } else { + LIST_FOREACH(rtc, &rtc_list, rtc_entries) { + if (rtc->resolution > newrtc->resolution) { + LIST_INSERT_BEFORE(rtc, newrtc, rtc_entries); + break; + } else if (LIST_NEXT(rtc, rtc_entries) == NULL) { + LIST_INSERT_AFTER(rtc, newrtc, rtc_entries); + break; + } + } + } + sx_xunlock(&rtc_list_lock); + + device_printf(clockdev, + "registered as a time-of-day clock, resolution %d.%6.6ds\n", + newrtc->resolution / 1000000, newrtc->resolution % 1000000); +} + +void +clock_register(device_t dev, long res) { - if (clock_dev != NULL) { - if (clock_res <= res) { - if (bootverbose) - device_printf(dev, "not installed as " - "time-of-day clock: clock %s has higher " - "resolution\n", device_get_name(clock_dev)); - return; + clock_register_flags(dev, res, 0); +} + +void +clock_unregister(device_t clockdev) +{ + struct rtc_instance *rtc, *tmp; + + sx_xlock(&rtc_list_lock); + LIST_FOREACH_SAFE(rtc, &rtc_list, rtc_entries, tmp) { + if (rtc->clockdev == clockdev) { + LIST_REMOVE(rtc, rtc_entries); + free(rtc, M_DEVBUF); } - if (bootverbose) - device_printf(clock_dev, "removed as " - "time-of-day clock: clock %s has higher " - "resolution\n", device_get_name(dev)); } - clock_dev = dev; - clock_res = res; - clock_adj.tv_sec = res / 2 / 1000000; - clock_adj.tv_nsec = res / 2 % 1000000 * 1000; - if (bootverbose) - device_printf(dev, "registered as a time-of-day clock " - "(resolution %ldus, adjustment %jd.%09jds)\n", res, - (intmax_t)clock_adj.tv_sec, (intmax_t)clock_adj.tv_nsec); + sx_xunlock(&rtc_list_lock); } /* - * inittodr and settodr derived from the i386 versions written - * by Christoph Robitschko , reintroduced and - * updated by Chris Stenton 8/10/94 - */ - -/* - * Initialize the time of day register, based on the time base which is, e.g. - * from a filesystem. + * Initialize the system time. Must be called from a context which does not + * restrict any locking or sleeping that clock drivers may need to do. + * + * First attempt to get the time from a registered realtime clock. The clocks + * are queried in order of resolution until one provides the time. If no clock + * can provide the current time, use the 'base' time provided by the caller, if + * non-zero. The 'base' time is potentially highly inaccurate, such as the last + * known good value of the system clock, or even a filesystem last-updated + * timestamp. It is used to prevent system time from appearing to move + * backwards in logs. */ void inittodr(time_t base) { struct timespec ts; + struct rtc_instance *rtc; int error; - if (clock_dev == NULL) { - printf("warning: no time-of-day clock registered, system time " - "will not be set accurately\n"); - goto wrong_time; - } - /* XXX: We should poll all registered RTCs in case of failure */ - mtx_lock(&resettodr_lock); - error = CLOCK_GETTIME(clock_dev, &ts); - mtx_unlock(&resettodr_lock); - if (error != 0 && error != EINVAL) { - printf("warning: clock_gettime failed (%d), the system time " - "will not be set accurately\n", error); - goto wrong_time; - } - if (error == EINVAL || ts.tv_sec < 0) { - printf("Invalid time in real time clock.\n" - "Check and reset the date immediately!\n"); - goto wrong_time; + error = ENXIO; + sx_xlock(&rtc_list_lock); + LIST_FOREACH(rtc, &rtc_list, rtc_entries) { + if ((error = CLOCK_GETTIME(rtc->clockdev, &ts)) != 0) + continue; + if (ts.tv_sec < 0 || ts.tv_nsec < 0) { + error = EINVAL; + continue; + } + if (!(rtc->flags & CLOCKF_GETTIME_NO_ADJ)) { + timespecadd(&ts, &rtc->resadj); + ts.tv_sec += utc_offset(); + } + if (bootverbose) + device_printf(rtc->clockdev, + "providing initial system time\n"); + break; } + sx_xunlock(&rtc_list_lock); - ts.tv_sec += utc_offset(); - timespecadd(&ts, &clock_adj); - tc_setclock(&ts); -#ifdef FFCLOCK - ffclock_reset_clock(&ts); -#endif - return; - -wrong_time: - if (base > 0) { - ts.tv_sec = base; + /* + * Do not report errors from each clock; it is expected that some clocks + * cannot provide results in some situations. Only report problems when + * no clocks could provide the time. + */ + if (error != 0) { + switch (error) { + case ENXIO: + printf("Warning: no time-of-day clock registered, "); + break; + case EINVAL: + printf("Warning: bad time from time-of-day clock, "); + break; + default: + printf("Error reading time-of-day clock (%d), ", error); + break; + } + printf("system time will not be set accurately\n"); + ts.tv_sec = (base > 0) ? base : -1; ts.tv_nsec = 0; + } + + if (ts.tv_sec >= 0) { tc_setclock(&ts); +#ifdef FFCLOCK + ffclock_reset_clock(&ts); +#endif } } /* - * Write system time back to RTC + * Write system time back to all registered clocks, unless disabled by admin. + * This can be called from a context that restricts locking and/or sleeping; the + * actual updating is done asynchronously on a task thread. */ void resettodr(void) { - struct timespec ts; - int error; - if (disable_rtc_set || clock_dev == NULL) + if (disable_rtc_set) return; - getnanotime(&ts); - timespecadd(&ts, &clock_adj); - ts.tv_sec -= utc_offset(); - /* XXX: We should really set all registered RTCs */ - mtx_lock(&resettodr_lock); - error = CLOCK_SETTIME(clock_dev, &ts); - mtx_unlock(&resettodr_lock); - if (error != 0) - printf("warning: clock_settime failed (%d), time-of-day clock " - "not adjusted to system time\n", error); + taskqueue_enqueue(taskqueue_thread, &settime_task); } diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index 01df8fffdb99..c47ae4fee4cd 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -206,31 +206,32 @@ uiomove_nofault(void *cp, int n, struct uio *uio) static int uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault) { - struct thread *td; struct iovec *iov; size_t cnt; int error, newflags, save; - td = curthread; error = 0; KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE, ("uiomove: mode")); - KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == td, + KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, ("uiomove proc")); - if (!nofault) - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, - "Calling uiomove()"); - /* XXX does it make a sense to set TDP_DEADLKTREAT for UIO_SYSSPACE ? */ - newflags = TDP_DEADLKTREAT; - if (uio->uio_segflg == UIO_USERSPACE && nofault) { - /* - * Fail if a non-spurious page fault occurs. - */ - newflags |= TDP_NOFAULTING | TDP_RESETSPUR; + if (uio->uio_segflg == UIO_USERSPACE) { + newflags = TDP_DEADLKTREAT; + if (nofault) { + /* + * Fail if a non-spurious page fault occurs. + */ + newflags |= TDP_NOFAULTING | TDP_RESETSPUR; + } else { + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "Calling uiomove()"); + } + save = curthread_pflags_set(newflags); + } else { + KASSERT(nofault == 0, ("uiomove: nofault")); } - save = curthread_pflags_set(newflags); while (n > 0 && uio->uio_resid) { iov = uio->uio_iov; @@ -272,7 +273,8 @@ uiomove_faultflag(void *cp, int n, struct uio *uio, int nofault) n -= cnt; } out: - curthread_pflags_restore(save); + if (uio->uio_segflg == UIO_USERSPACE) + curthread_pflags_restore(save); return (error); } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 129a0a2842b2..b11d2f78852f 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -858,6 +858,9 @@ solisten_proto(struct socket *so, int backlog) so->sol_accept_filter_arg = NULL; so->sol_accept_filter_str = NULL; + so->sol_upcall = NULL; + so->sol_upcallarg = NULL; + so->so_options |= SO_ACCEPTCONN; listening: diff --git a/sys/mips/atheros/ar724x_pci.c b/sys/mips/atheros/ar724x_pci.c index ad1ec75d5ee0..1f8efd25a663 100644 --- a/sys/mips/atheros/ar724x_pci.c +++ b/sys/mips/atheros/ar724x_pci.c @@ -104,10 +104,12 @@ ar724x_pci_write(uint32_t reg, uint32_t offset, uint32_t data, int bytes) else mask = 0xffffffff; + rmb(); val = ATH_READ_REG(reg + (offset & ~3)); val &= ~(mask << shift); val |= ((data & mask) << shift); ATH_WRITE_REG(reg + (offset & ~3), val); + wmb(); dprintf("%s: %#x/%#x addr=%#x, data=%#x(%#x), bytes=%d\n", __func__, reg, reg + (offset & ~3), offset, data, val, bytes); @@ -133,6 +135,7 @@ ar724x_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, func, reg, bytes); + rmb(); if ((bus == 0) && (slot == 0) && (func == 0)) data = ATH_READ_REG(AR724X_PCI_CFG_BASE + (reg & ~3)); else @@ -166,6 +169,9 @@ ar724x_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, * map is for this device. Without it, it'll think the memory * map is 32 bits wide, the PCI code will then end up thinking * the register window is '0' and fail to allocate resources. + * + * Note: Test on AR7241/AR7242/AR9344! Those use a WAR value of + * 0x1000ffff. */ if (reg == PCIR_BAR(0) && bytes == 4 && ar71xx_soc == AR71XX_SOC_AR7240 @@ -284,6 +290,7 @@ ar724x_pci_fixup(device_t dev, long flash_addr, int len) bar0 = ar724x_pci_read_config(dev, 0, 0, 0, PCIR_BAR(0), 4); /* Write temporary BAR0 to map the NIC into a fixed location */ + /* XXX AR7240: 0xffff; 7241/7242/9344: 0x1000ffff */ ar724x_pci_write_config(dev, 0, 0, 0, PCIR_BAR(0), AR71XX_PCI_MEM_BASE, 4); @@ -299,7 +306,7 @@ ar724x_pci_fixup(device_t dev, long flash_addr, int len) val |= (*cal_data++) << 16; if (bootverbose) - printf(" 0x%08x=0x%04x\n", reg, val); + printf(" 0x%08x=0x%08x\n", reg, val); /* Write eeprom fixup data to device memory */ ATH_WRITE_REG(AR71XX_PCI_MEM_BASE + reg, val); diff --git a/sys/mips/conf/AR934X_BASE.hints b/sys/mips/conf/AR934X_BASE.hints index 6dae4a6076c5..aa45331695b3 100644 --- a/sys/mips/conf/AR934X_BASE.hints +++ b/sys/mips/conf/AR934X_BASE.hints @@ -9,6 +9,10 @@ hint.apb.0.at="nexus0" hint.apb.0.irq=4 +# ART calibration data mapping device +hint.ar71xx_caldata.0.at="nexus0" +hint.ar71xx_caldata.0.order=0 + # uart0 hint.uart.0.at="apb0" # NB: This isn't an ns8250 UART @@ -47,6 +51,13 @@ hint.ath.0.device_id=0x0031 # should be fetched from in physical memory. # hint.ath.0.eepromaddr=0x1fff1000 +# Where the ART is - last 64k in the first 8MB of flash +#hint.ar71xx_caldata.0.map.0.ath_fixup_addr=0x1fff0000 +#hint.ar71xx_caldata.0.map.0.ath_fixup_size=16384 + +# And now tell the ath(4) driver where to look! +#hint.ath.0.eeprom_firmware="ar71xx_caldata.0.map.0.eeprom_firmware" + # SPI flash hint.spi.0.at="nexus0" hint.spi.0.maddr=0x1f000000 diff --git a/sys/mips/conf/std.AR934X b/sys/mips/conf/std.AR934X index eab4b84c7c54..89700557817b 100644 --- a/sys/mips/conf/std.AR934X +++ b/sys/mips/conf/std.AR934X @@ -51,8 +51,17 @@ options NO_FFS_SNAPSHOT # We don't require snapshot support include "std.AR_MIPS_BASE" makeoptions MODULES_OVERRIDE+="hwpmc_mips24k" +# EEPROM caldata for AHB connected device +options AR71XX_ATH_EEPROM +device ar71xx_caldata +device firmware + +# Support AR9340 support in AR9300 HAL options AH_SUPPORT_AR9340 +# Support EEPROM caldata in AHB devices +options ATH_EEPROM_FIRMWARE + device pci device ar724x_pci device uart_ar71xx diff --git a/sys/mips/mips/db_disasm.c b/sys/mips/mips/db_disasm.c index 108c9dd8a1a8..4adf6f31dfeb 100644 --- a/sys/mips/mips/db_disasm.c +++ b/sys/mips/mips/db_disasm.c @@ -104,7 +104,11 @@ static char *fmt_name[16] = { static char *reg_name[32] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", +#if defined(__mips_n32) || defined(__mips_n64) + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", +#else "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", +#endif "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" }; diff --git a/sys/modules/agp/Makefile b/sys/modules/agp/Makefile index 383788f9d6b4..a96dfc9fa7c4 100644 --- a/sys/modules/agp/Makefile +++ b/sys/modules/agp/Makefile @@ -35,6 +35,7 @@ EXPORT_SYMS= agp_find_device \ .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" EXPORT_SYMS+= intel_gtt_clear_range \ intel_gtt_insert_pages \ + intel_gtt_install_pte \ intel_gtt_get \ intel_gtt_chipset_flush \ intel_gtt_unmap_memory \ diff --git a/sys/modules/ix/Makefile b/sys/modules/ix/Makefile index 0da729470774..4cf4e856b0a0 100644 --- a/sys/modules/ix/Makefile +++ b/sys/modules/ix/Makefile @@ -5,7 +5,8 @@ KMOD = if_ix SRCS = device_if.h bus_if.h pci_if.h pci_iov_if.h SRCS += opt_inet.h opt_inet6.h opt_rss.h -SRCS += if_ix.c ix_txrx.c ixgbe_osdep.c +SRCS += if_ix.c if_bypass.c if_fdir.c if_sriov.c ix_txrx.c ixgbe_osdep.c +SRCS += ixgbe_netmap.c # Shared source SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c SRCS += ixgbe_dcb.c ixgbe_dcb_82598.c ixgbe_dcb_82599.c diff --git a/sys/modules/ixv/Makefile b/sys/modules/ixv/Makefile index 814efa2801ec..26bde06a5d4f 100644 --- a/sys/modules/ixv/Makefile +++ b/sys/modules/ixv/Makefile @@ -5,7 +5,7 @@ KMOD = if_ixv SRCS = device_if.h bus_if.h pci_if.h pci_iov_if.h SRCS += opt_inet.h opt_inet6.h opt_rss.h -SRCS += if_ixv.c ix_txrx.c ixgbe_osdep.c +SRCS += if_ixv.c if_fdir.c if_sriov.c ix_txrx.c ixgbe_osdep.c ixgbe_netmap.c # Shared source SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c SRCS += ixgbe_dcb.c ixgbe_dcb_82598.c ixgbe_dcb_82599.c diff --git a/sys/modules/mmcnull/Makefile b/sys/modules/mmcnull/Makefile new file mode 100644 index 000000000000..526c3446fee6 --- /dev/null +++ b/sys/modules/mmcnull/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/mmcnull + +KMOD= mmcnull +SRCS= mmcnull.c device_if.h bus_if.h + +.include diff --git a/sys/modules/sdhci/Makefile b/sys/modules/sdhci/Makefile index 941b4d51ada4..158ed4cd945a 100644 --- a/sys/modules/sdhci/Makefile +++ b/sys/modules/sdhci/Makefile @@ -3,6 +3,6 @@ .PATH: ${SRCTOP}/sys/dev/sdhci KMOD= sdhci -SRCS= sdhci.c sdhci.h sdhci_if.c sdhci_if.h device_if.h bus_if.h mmcbr_if.h +SRCS= sdhci.c sdhci.h sdhci_if.c sdhci_if.h device_if.h bus_if.h mmcbr_if.h opt_mmccam.h opt_cam.h .include diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 4d1d3479a1cc..633ebc9668ba 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$"); #include #endif +#include /* * enable accounting of every mbuf as it comes in to and goes out of * iflib's software descriptor references @@ -381,6 +382,8 @@ struct iflib_fl { #endif /* implicit pad */ + bitstr_t *ifl_rx_bitmap; + qidx_t ifl_fragidx; /* constant */ qidx_t ifl_size; uint16_t ifl_buf_size; @@ -1797,7 +1800,8 @@ static void _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) { struct mbuf *m; - int idx, pidx = fl->ifl_pidx; + int idx, frag_idx = fl->ifl_fragidx; + int pidx = fl->ifl_pidx; caddr_t cl, *sd_cl; struct mbuf **sd_m; uint8_t *sd_flags; @@ -1840,8 +1844,11 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) * * If the cluster is still set then we know a minimum sized packet was received */ - if ((cl = sd_cl[idx]) == NULL) { - if ((cl = sd_cl[idx] = m_cljget(NULL, M_NOWAIT, fl->ifl_buf_size)) == NULL) + bit_ffc_at(fl->ifl_rx_bitmap, frag_idx, fl->ifl_size, &frag_idx); + if ((frag_idx < 0) || (frag_idx >= fl->ifl_size)) + bit_ffc(fl->ifl_rx_bitmap, fl->ifl_size, &frag_idx); + if ((cl = sd_cl[frag_idx]) == NULL) { + if ((cl = sd_cl[frag_idx] = m_cljget(NULL, M_NOWAIT, fl->ifl_buf_size)) == NULL) break; #if MEMORY_LOGGING fl->ifl_cl_enqueued++; @@ -1867,10 +1874,11 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) cb_arg.error = 0; q = fl->ifl_rxq; MPASS(sd_map != NULL); - MPASS(sd_map[idx] != NULL); - err = bus_dmamap_load(fl->ifl_desc_tag, sd_map[idx], + MPASS(sd_map[frag_idx] != NULL); + err = bus_dmamap_load(fl->ifl_desc_tag, sd_map[frag_idx], cl, fl->ifl_buf_size, _rxq_refill_cb, &cb_arg, 0); - bus_dmamap_sync(fl->ifl_desc_tag, sd_map[idx], BUS_DMASYNC_PREREAD); + bus_dmamap_sync(fl->ifl_desc_tag, sd_map[frag_idx], + BUS_DMASYNC_PREREAD); if (err != 0 || cb_arg.error) { /* @@ -1884,12 +1892,13 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) } bus_addr = cb_arg.seg.ds_addr; } - sd_flags[idx] |= RX_SW_DESC_INUSE; + bit_set(fl->ifl_rx_bitmap, frag_idx); + sd_flags[frag_idx] |= RX_SW_DESC_INUSE; - MPASS(sd_m[idx] == NULL); - sd_cl[idx] = cl; - sd_m[idx] = m; - fl->ifl_rxd_idxs[i] = idx; + MPASS(sd_m[frag_idx] == NULL); + sd_cl[frag_idx] = cl; + sd_m[frag_idx] = m; + fl->ifl_rxd_idxs[i] = frag_idx; fl->ifl_bus_addrs[i] = bus_addr; fl->ifl_vm_addrs[i] = cl; fl->ifl_credits++; @@ -1905,8 +1914,8 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) ctx->isc_rxd_refill(ctx->ifc_softc, &iru); i = 0; pidx = idx; + fl->ifl_pidx = idx; } - fl->ifl_pidx = idx; } done: @@ -1920,6 +1929,7 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); ctx->isc_rxd_flush(ctx->ifc_softc, fl->ifl_rxq->ifr_id, fl->ifl_id, pidx); + fl->ifl_fragidx = frag_idx; } static __inline void @@ -1983,7 +1993,7 @@ iflib_fl_bufs_free(iflib_fl_t fl) /* * Reset free list values */ - fl->ifl_credits = fl->ifl_cidx = fl->ifl_pidx = fl->ifl_gen = 0;; + fl->ifl_credits = fl->ifl_cidx = fl->ifl_pidx = fl->ifl_gen = fl->ifl_fragidx = 0; bzero(idi->idi_vaddr, idi->idi_size); } @@ -1999,6 +2009,7 @@ iflib_fl_setup(iflib_fl_t fl) if_ctx_t ctx = rxq->ifr_ctx; if_softc_ctx_t sctx = &ctx->ifc_softc_ctx; + bit_nclear(fl->ifl_rx_bitmap, 0, fl->ifl_size); /* ** Free current RX buffer structs and their mbufs */ @@ -2348,6 +2359,7 @@ rxd_frag_to_sd(iflib_rxq_t rxq, if_rxd_frag_t irf, int unload, if_rxsd_t sd) if (map != NULL) bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + bit_clear(fl->ifl_rx_bitmap, cidx); } static struct mbuf * @@ -2880,7 +2892,7 @@ iflib_busdma_load_mbuf_sg(iflib_txq_t txq, bus_dma_tag_t tag, bus_dmamap_t map, if_ctx_t ctx; if_shared_ctx_t sctx; if_softc_ctx_t scctx; - int i, next, pidx, err, maxsegsz, ntxd, count; + int i, next, pidx, err, ntxd, count; struct mbuf *m, *tmp, **ifsd_m; m = *m0; @@ -2923,13 +2935,17 @@ iflib_busdma_load_mbuf_sg(iflib_txq_t txq, bus_dma_tag_t tag, bus_dmamap_t map, m = m->m_next; } while (m != NULL); } else { - int buflen, sgsize, max_sgsize; + int buflen, sgsize, maxsegsz, max_sgsize; vm_offset_t vaddr; vm_paddr_t curaddr; count = i = 0; - maxsegsz = sctx->isc_tx_maxsize; m = *m0; + if (m->m_pkthdr.csum_flags & CSUM_TSO) + maxsegsz = scctx->isc_tx_tso_segsize_max; + else + maxsegsz = sctx->isc_tx_maxsegsize; + do { if (__predict_false(m->m_len <= 0)) { tmp = m; @@ -4243,8 +4259,9 @@ iflib_device_deregister(if_ctx_t ctx) iflib_txq_t txq; iflib_rxq_t rxq; device_t dev = ctx->ifc_dev; - int i; + int i, j; struct taskqgroup *tqg; + iflib_fl_t fl; /* Make sure VLANS are not using driver */ if (if_vlantrunkinuse(ifp)) { @@ -4279,6 +4296,10 @@ iflib_device_deregister(if_ctx_t ctx) for (i = 0, rxq = ctx->ifc_rxqs; i < NRXQSETS(ctx); i++, rxq++) { if (rxq->ifr_task.gt_uniq != NULL) taskqgroup_detach(tqg, &rxq->ifr_task); + + for (j = 0, fl = rxq->ifr_fl; j < rxq->ifr_nfl; j++, fl++) + free(fl->ifl_rx_bitmap, M_IFLIB); + } tqg = qgroup_if_config_tqg; if (ctx->ifc_admin_task.gt_uniq != NULL) @@ -4672,6 +4693,9 @@ iflib_queues_alloc(if_ctx_t ctx) err = ENOMEM; goto err_rx_desc; } + + for (j = 0, fl = rxq->ifr_fl; j < rxq->ifr_nfl; j++, fl++) + fl->ifl_rx_bitmap = bit_alloc(fl->ifl_size, M_IFLIB, M_WAITOK|M_ZERO); } /* TXQs */ diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 5361294903fb..07d4e85e49b4 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -2149,23 +2149,23 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, * cookie was in flight. Only recourse is to abort the * association. */ - atomic_add_int(&stcb->asoc.refcnt, 1); op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen, src, dst, sh, op_err, mflowtype, mflowid, vrf_id, port); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + atomic_add_int(&stcb->asoc.refcnt, 1); SCTP_TCB_UNLOCK(stcb); SCTP_SOCKET_LOCK(so, 1); SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); #endif (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_18); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) SCTP_SOCKET_UNLOCK(so, 1); #endif - atomic_subtract_int(&stcb->asoc.refcnt, 1); return (NULL); } /* process the INIT-ACK info (my info) */ @@ -2186,36 +2186,36 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, else retval = 0; if (retval < 0) { - atomic_add_int(&stcb->asoc.refcnt, 1); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + atomic_add_int(&stcb->asoc.refcnt, 1); SCTP_TCB_UNLOCK(stcb); SCTP_SOCKET_LOCK(so, 1); SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); #endif (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_19); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) SCTP_SOCKET_UNLOCK(so, 1); #endif - atomic_subtract_int(&stcb->asoc.refcnt, 1); return (NULL); } /* load all addresses */ if (sctp_load_addresses_from_init(stcb, m, init_offset + sizeof(struct sctp_init_chunk), initack_offset, src, dst, init_src, port)) { - atomic_add_int(&stcb->asoc.refcnt, 1); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + atomic_add_int(&stcb->asoc.refcnt, 1); SCTP_TCB_UNLOCK(stcb); SCTP_SOCKET_LOCK(so, 1); SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); #endif (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_20); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) SCTP_SOCKET_UNLOCK(so, 1); #endif - atomic_subtract_int(&stcb->asoc.refcnt, 1); return (NULL); } /* @@ -2234,35 +2234,24 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, /* auth HMAC failed, dump the assoc and packet */ SCTPDBG(SCTP_DEBUG_AUTH1, "COOKIE-ECHO: AUTH failed\n"); - atomic_add_int(&stcb->asoc.refcnt, 1); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + atomic_add_int(&stcb->asoc.refcnt, 1); SCTP_TCB_UNLOCK(stcb); SCTP_SOCKET_LOCK(so, 1); SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); #endif (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_21); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) SCTP_SOCKET_UNLOCK(so, 1); #endif - atomic_subtract_int(&stcb->asoc.refcnt, 1); return (NULL); } else { /* remaining chunks checked... good to go */ stcb->asoc.authenticated = 1; } } - /* update current state */ - SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n"); - SCTP_SET_STATE(asoc, SCTP_STATE_OPEN); - if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) { - sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, - stcb->sctp_ep, stcb, asoc->primary_destination); - } - sctp_stop_all_cookie_timers(stcb); - SCTP_STAT_INCR_COUNTER32(sctps_passiveestab); - SCTP_STAT_INCR_GAUGE32(sctps_currestab); - /* * if we're doing ASCONFs, check to see if we have any new local * addresses that need to get added to the peer (eg. addresses @@ -2295,21 +2284,32 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, break; #endif default: - atomic_add_int(&stcb->asoc.refcnt, 1); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + atomic_add_int(&stcb->asoc.refcnt, 1); SCTP_TCB_UNLOCK(stcb); SCTP_SOCKET_LOCK(so, 1); SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); #endif (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_22); #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) SCTP_SOCKET_UNLOCK(so, 1); #endif - atomic_subtract_int(&stcb->asoc.refcnt, 1); return (NULL); } + /* update current state */ + SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n"); + SCTP_SET_STATE(asoc, SCTP_STATE_OPEN); + if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) { + sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, + stcb->sctp_ep, stcb, asoc->primary_destination); + } + sctp_stop_all_cookie_timers(stcb); + SCTP_STAT_INCR_COUNTER32(sctps_passiveestab); + SCTP_STAT_INCR_GAUGE32(sctps_currestab); + /* set up to notify upper layer */ *notification = SCTP_NOTIFY_ASSOC_UP; if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index d997b271ea3e..2c9898469d71 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -130,6 +130,12 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autosndbuf_max), 0, "Max size of automatic send buffer"); +VNET_DEFINE(int, tcp_sendbuf_auto_lowat) = 0; +#define V_tcp_sendbuf_auto_lowat VNET(tcp_sendbuf_auto_lowat) +SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto_lowat, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(tcp_sendbuf_auto_lowat), 0, + "Modify threshold for auto send buffer growth to account for SO_SNDLOWAT"); + /* * Make sure that either retransmit or persist timer is set for SYN, FIN and * non-ACK. @@ -380,7 +386,7 @@ tcp_output(struct tcpcb *tp) */ if (sack_rxmit == 0) { if (sack_bytes_rxmt == 0) - len = ((int32_t)ulmin(sbavail(&so->so_snd), sendwin) - + len = ((int32_t)min(sbavail(&so->so_snd), sendwin) - off); else { int32_t cwin; @@ -521,8 +527,12 @@ tcp_output(struct tcpcb *tp) * XXXGL: should there be used sbused() or sbavail()? */ if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) { - if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat && - sbused(&so->so_snd) >= (so->so_snd.sb_hiwat / 8 * 7) && + int autosndbuf_mod = 0; + if (V_tcp_sendbuf_auto_lowat) + autosndbuf_mod = so->so_snd.sb_lowat; + + if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat - autosndbuf_mod && + sbused(&so->so_snd) >= (so->so_snd.sb_hiwat / 8 * 7) - autosndbuf_mod && sbused(&so->so_snd) < V_tcp_autosndbuf_max && sendwin >= (sbused(&so->so_snd) - (tp->snd_nxt - tp->snd_una))) { diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index a66d5e7e379f..a32261dac8a7 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -92,6 +92,8 @@ __FBSDID("$FreeBSD$"); #include #endif +#include /* for struct grehdr */ + #include #include /* XXX for in_cksum */ @@ -1162,6 +1164,11 @@ do { \ PULLUP_TO(hlen, ulp, struct pim); break; + case IPPROTO_GRE: /* RFC 1701 */ + /* XXX GRE header check? */ + PULLUP_TO(hlen, ulp, struct grehdr); + break; + case IPPROTO_CARP: PULLUP_TO(hlen, ulp, struct carp_header); if (((struct carp_header *)ulp)->carp_version != diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 7d6c53d94565..8613a161f0a4 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -132,6 +132,9 @@ VNET_DEFINE(int, pf_tcp_iss_off); VNET_DECLARE(int, pf_vnet_active); #define V_pf_vnet_active VNET(pf_vnet_active) +static VNET_DEFINE(uint32_t, pf_purge_idx); +#define V_pf_purge_idx VNET(pf_purge_idx) + /* * Queue for pf_intr() sends. */ @@ -1427,7 +1430,6 @@ void pf_purge_thread(void *unused __unused) { VNET_ITERATOR_DECL(vnet_iter); - u_int idx = 0; sx_xlock(&pf_end_lock); while (pf_end_threads == 0) { @@ -1448,14 +1450,15 @@ pf_purge_thread(void *unused __unused) * Process 1/interval fraction of the state * table every run. */ - idx = pf_purge_expired_states(idx, pf_hashmask / + V_pf_purge_idx = + pf_purge_expired_states(V_pf_purge_idx, pf_hashmask / (V_pf_default_rule.timeout[PFTM_INTERVAL] * 10)); /* * Purge other expired types every * PFTM_INTERVAL seconds. */ - if (idx == 0) { + if (V_pf_purge_idx == 0) { /* * Order is important: * - states and src nodes reference rules diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 9a61980474e6..5540b312f140 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -3850,7 +3850,6 @@ tlb1_read_entry(tlb_entry_t *entry, unsigned int slot) /* * Write given entry to TLB1 hardware. - * Use 32 bit pa, clear 4 high-order bits of RPN (mas7). */ static void tlb1_write_entry(tlb_entry_t *e, unsigned int idx) diff --git a/sys/sys/bitset.h b/sys/sys/bitset.h index 8bc9e3d87a0b..566d94484207 100644 --- a/sys/sys/bitset.h +++ b/sys/sys/bitset.h @@ -213,6 +213,21 @@ __bit; \ }) +#define BIT_FLS(_s, p) __extension__ ({ \ + __size_t __i; \ + int __bit; \ + \ + __bit = 0; \ + for (__i = __bitset_words((_s)); __i > 0; __i--) { \ + if ((p)->__bits[__i - 1] != 0) { \ + __bit = flsl((p)->__bits[__i - 1]); \ + __bit += (__i - 1) * _BITSET_BITS; \ + break; \ + } \ + } \ + __bit; \ +}) + #define BIT_COUNT(_s, p) __extension__ ({ \ __size_t __i; \ int __count; \ diff --git a/sys/sys/clock.h b/sys/sys/clock.h index f1809dbb9527..696ff55eee14 100644 --- a/sys/sys/clock.h +++ b/sys/sys/clock.h @@ -54,7 +54,6 @@ */ extern int tz_minuteswest; extern int tz_dsttime; -extern struct mtx resettodr_lock; int utc_offset(void); @@ -76,7 +75,34 @@ struct clocktime { int clock_ct_to_ts(struct clocktime *, struct timespec *); void clock_ts_to_ct(struct timespec *, struct clocktime *); -void clock_register(device_t, long); + +/* + * Time-of-day clock register/unregister functions, and associated flags. These + * functions can sleep. Upon return from unregister, the clock's methods are + * not running and will not be called again. + * + * Flags: + * + * CLOCKF_SETTIME_NO_TS + * Do not pass a timespec to clock_settime(), the driver obtains its own time + * and applies its own adjustments (this flag implies CLOCKF_SETTIME_NO_ADJ). + * + * CLOCKF_SETTIME_NO_ADJ + * Do not apply utc offset and resolution/accuracy adjustments to the value + * passed to clock_settime(), the driver applies them itself. + * + * CLOCKF_GETTIME_NO_ADJ + * Do not apply utc offset and resolution/accuracy adjustments to the value + * returned from clock_gettime(), the driver has already applied them. + */ + +#define CLOCKF_SETTIME_NO_TS 0x00000001 +#define CLOCKF_SETTIME_NO_ADJ 0x00000002 +#define CLOCKF_GETTIME_NO_ADJ 0x00000004 + +void clock_register(device_t _clockdev, long _resolution_us); +void clock_register_flags(device_t _clockdev, long _resolution_us, int _flags); +void clock_unregister(device_t _clockdev); /* * BCD to decimal and decimal to BCD. diff --git a/sys/sys/jail.h b/sys/sys/jail.h index 2c329b5d32b7..91c694f2fba7 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -215,23 +215,24 @@ struct prison_racct { /* by this jail or an ancestor */ /* Flags for pr_allow */ -#define PR_ALLOW_SET_HOSTNAME 0x0001 -#define PR_ALLOW_SYSVIPC 0x0002 -#define PR_ALLOW_RAW_SOCKETS 0x0004 -#define PR_ALLOW_CHFLAGS 0x0008 -#define PR_ALLOW_MOUNT 0x0010 -#define PR_ALLOW_QUOTAS 0x0020 -#define PR_ALLOW_SOCKET_AF 0x0040 -#define PR_ALLOW_MOUNT_DEVFS 0x0080 -#define PR_ALLOW_MOUNT_NULLFS 0x0100 -#define PR_ALLOW_MOUNT_ZFS 0x0200 -#define PR_ALLOW_MOUNT_PROCFS 0x0400 -#define PR_ALLOW_MOUNT_TMPFS 0x0800 -#define PR_ALLOW_MOUNT_FDESCFS 0x1000 -#define PR_ALLOW_MOUNT_LINPROCFS 0x2000 -#define PR_ALLOW_MOUNT_LINSYSFS 0x4000 -#define PR_ALLOW_RESERVED_PORTS 0x8000 -#define PR_ALLOW_ALL 0xffff +#define PR_ALLOW_SET_HOSTNAME 0x00000001 +#define PR_ALLOW_SYSVIPC 0x00000002 +#define PR_ALLOW_RAW_SOCKETS 0x00000004 +#define PR_ALLOW_CHFLAGS 0x00000008 +#define PR_ALLOW_MOUNT 0x00000010 +#define PR_ALLOW_QUOTAS 0x00000020 +#define PR_ALLOW_SOCKET_AF 0x00000040 +#define PR_ALLOW_MOUNT_DEVFS 0x00000080 +#define PR_ALLOW_MOUNT_NULLFS 0x00000100 +#define PR_ALLOW_MOUNT_ZFS 0x00000200 +#define PR_ALLOW_MOUNT_PROCFS 0x00000400 +#define PR_ALLOW_MOUNT_TMPFS 0x00000800 +#define PR_ALLOW_MOUNT_FDESCFS 0x00001000 +#define PR_ALLOW_MOUNT_LINPROCFS 0x00002000 +#define PR_ALLOW_MOUNT_LINSYSFS 0x00004000 +#define PR_ALLOW_RESERVED_PORTS 0x00008000 +#define PR_ALLOW_KMEM_ACCESS 0x00010000 /* reserved, not used yet */ +#define PR_ALLOW_ALL 0x0001ffff /* * OSD methods diff --git a/sys/sys/param.h b/sys/sys/param.h index 4f638e7f620c..6377ad7de7ae 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1200037 /* Master, propagated to newvers */ +#define __FreeBSD_version 1200038 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index a859fb8032f2..d42b36a5a446 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -2442,21 +2442,9 @@ ufs_pathconf(ap) error = 0; switch (ap->a_name) { - case _PC_LINK_MAX: - *ap->a_retval = LINK_MAX; - break; case _PC_NAME_MAX: *ap->a_retval = UFS_MAXNAMLEN; break; - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - break; - case _PC_PIPE_BUF: - *ap->a_retval = PIPE_BUF; - break; - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - break; case _PC_NO_TRUNC: *ap->a_retval = 1; break; @@ -2505,11 +2493,6 @@ ufs_pathconf(ap) case _PC_MIN_HOLE_SIZE: *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize; break; - case _PC_ASYNC_IO: - /* _PC_ASYNC_IO should have been handled by upper layers. */ - KASSERT(0, ("_PC_ASYNC_IO should not get here")); - error = EINVAL; - break; case _PC_PRIO_IO: *ap->a_retval = 0; break; @@ -2539,7 +2522,7 @@ ufs_pathconf(ap) break; default: - error = EINVAL; + error = vop_stdpathconf(ap); break; } return (error); diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 0a99ddde486f..a0688fe4f0c5 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1571,7 +1571,7 @@ vm_map_find_min(vm_map_t map, vm_object_t object, vm_ooffset_t offset, find_space, prot, max, cow); if (rv == KERN_SUCCESS || min_addr >= hint) return (rv); - *addr = min_addr; + *addr = hint = min_addr; } } diff --git a/sys/x86/isa/atrtc.c b/sys/x86/isa/atrtc.c index 3213e180409b..ffc9b26ef943 100644 --- a/sys/x86/isa/atrtc.c +++ b/sys/x86/isa/atrtc.c @@ -53,9 +53,17 @@ __FBSDID("$FreeBSD$"); #include #include "clock_if.h" +/* + * clock_lock protects low-level access to individual hardware registers. + * atrtc_time_lock protects the entire sequence of accessing multiple registers + * to read or write the date and time. + */ #define RTC_LOCK do { if (!kdb_active) mtx_lock_spin(&clock_lock); } while (0) #define RTC_UNLOCK do { if (!kdb_active) mtx_unlock_spin(&clock_lock); } while (0) +struct mtx atrtc_time_lock; +MTX_SYSINIT(atrtc_lock_init, &atrtc_time_lock, "atrtc", MTX_DEF); + int atrtcclock_disable = 0; static int rtc_reg = -1; @@ -163,6 +171,8 @@ atrtc_set(struct timespec *ts) clock_ts_to_ct(ts, &ct); + mtx_lock(&atrtc_time_lock); + /* Disable RTC updates and interrupts. */ writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); @@ -181,6 +191,8 @@ atrtc_set(struct timespec *ts) /* Re-enable RTC updates and interrupts. */ writertc(RTC_STATUSB, rtc_statusb); rtcin(RTC_INTR); + + mtx_unlock(&atrtc_time_lock); } /********************************************************************** @@ -352,6 +364,7 @@ atrtc_gettime(device_t dev, struct timespec *ts) * to make sure that no more than 240us pass after we start reading, * and try again if so. */ + mtx_lock(&atrtc_time_lock); while (rtcin(RTC_STATUSA) & RTCSA_TUP) continue; critical_enter(); @@ -369,6 +382,7 @@ atrtc_gettime(device_t dev, struct timespec *ts) ct.year += (ct.year < 80 ? 2000 : 1900); #endif critical_exit(); + mtx_unlock(&atrtc_time_lock); /* Set dow = -1 because some clocks don't set it correctly. */ ct.dow = -1; return (clock_ct_to_ts(&ct, ts)); diff --git a/targets/pseudo/userland/lib/Makefile.depend b/targets/pseudo/userland/lib/Makefile.depend index 81284c71f9d0..2735e3b8ca15 100644 --- a/targets/pseudo/userland/lib/Makefile.depend +++ b/targets/pseudo/userland/lib/Makefile.depend @@ -2,9 +2,7 @@ # This file is not autogenerated - take care! -.if !defined(MK_CLANG) .include -.endif DIRDEPS = \ lib/${CSU_DIR} \ @@ -30,9 +28,12 @@ DIRDEPS = \ lib/libbsnmp/libbsnmp \ lib/libbz2 \ lib/libc \ + lib/libc_nonshared \ lib/libc++ \ + lib/libc++experimental \ lib/libcalendar \ lib/libcam \ + lib/libcapsicum \ lib/libcom_err/doc \ lib/libcompat \ lib/libcompiler_rt \ @@ -51,6 +52,7 @@ DIRDEPS = \ lib/libexecinfo \ lib/libexpat \ lib/libfetch \ + lib/libfigpar \ lib/libgeom \ lib/libgssapi \ lib/libiconv_modules/BIG5 \ @@ -76,6 +78,7 @@ DIRDEPS = \ lib/libiconv_modules/mapper_serial \ lib/libiconv_modules/mapper_std \ lib/libiconv_modules/mapper_zone \ + lib/libifconfig \ lib/libipsec \ lib/libipx \ lib/libjail \ @@ -128,6 +131,7 @@ DIRDEPS = \ lib/libradius \ lib/librpcsec_gss \ lib/librpcsvc \ + lib/librss \ lib/librt \ lib/librtld_db \ lib/libsbuf \ @@ -144,6 +148,7 @@ DIRDEPS = \ lib/libtelnet \ lib/libthr \ lib/libthread_db \ + lib/libucl \ lib/libufs \ lib/libugidfw \ lib/libulog \ @@ -158,6 +163,7 @@ DIRDEPS = \ lib/libyaml \ lib/libypclnt \ lib/libz \ + lib/libzstd \ lib/msun \ lib/ncurses/form \ lib/ncurses/formw \ @@ -175,15 +181,22 @@ DIRDEPS = \ DIRDEPS+= \ lib/libclang_rt/asan-preinit \ lib/libclang_rt/asan \ + lib/libclang_rt/asan_dynamic \ lib/libclang_rt/asan_cxx \ lib/libclang_rt/include \ lib/libclang_rt/profile \ lib/libclang_rt/safestack \ + lib/libclang_rt/stats \ + lib/libclang_rt/stats_client \ lib/libclang_rt/ubsan_standalone \ lib/libclang_rt/ubsan_standalone_cxx \ .endif +.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mfilter} +DIRDEPS+= lib/libdl +.endif + .if ${MK_NAND} != "no" DIRDEPS+= lib/libnandfs .endif @@ -199,6 +212,18 @@ DIRDEPS+= \ .endif +.if ${MK_DIALOG} != "no" +DIRDEPS+= lib/libdpv +.endif + +.if ${MK_GPIO} != "no" +DIRDEPS+= lib/libgpio +.endif + +.if ${MK_EFI} != "no" +DIRDEPS+= lib/libefivar +.endif + .if ${MK_OFED} != "no" DIRDEPS+= \ contrib/ofed/usr.lib/libcxgb4 \ diff --git a/targets/pseudo/userland/share/Makefile.depend b/targets/pseudo/userland/share/Makefile.depend index 3f5ea1da5889..5465f31daa01 100644 --- a/targets/pseudo/userland/share/Makefile.depend +++ b/targets/pseudo/userland/share/Makefile.depend @@ -15,76 +15,7 @@ DIRDEPS = \ share/doc/legal/intel_wpi \ share/doc/legal/realtek \ share/doc/llvm/clang \ - share/doc/papers/beyond4.3 \ - share/doc/papers/bufbio \ - share/doc/papers/contents \ - share/doc/papers/devfs \ - share/doc/papers/diskperf \ - share/doc/papers/fsinterface \ - share/doc/papers/hwpmc \ - share/doc/papers/jail \ - share/doc/papers/kernmalloc \ - share/doc/papers/kerntune \ - share/doc/papers/malloc \ - share/doc/papers/newvm \ - share/doc/papers/relengr \ - share/doc/papers/sysperf \ - share/doc/papers/timecounter \ share/doc/pjdfstest \ - share/doc/psd/01.cacm \ - share/doc/psd/02.implement \ - share/doc/psd/03.iosys \ - share/doc/psd/04.uprog \ - share/doc/psd/05.sysman \ - share/doc/psd/06.Clang \ - share/doc/psd/12.make \ - share/doc/psd/13.rcs/rcs \ - share/doc/psd/13.rcs/rcs_func \ - share/doc/psd/15.yacc \ - share/doc/psd/16.lex \ - share/doc/psd/17.m4 \ - share/doc/psd/18.gprof \ - share/doc/psd/20.ipctut \ - share/doc/psd/21.ipc \ - share/doc/psd/22.rpcgen \ - share/doc/psd/23.rpc \ - share/doc/psd/24.xdr \ - share/doc/psd/25.xdrrfc \ - share/doc/psd/26.rpcrfc \ - share/doc/psd/27.nfsrpc \ - share/doc/psd/contents \ - share/doc/psd/title \ - share/doc/smm/01.setup \ - share/doc/smm/02.config \ - share/doc/smm/03.fsck \ - share/doc/smm/04.quotas \ - share/doc/smm/05.fastfs \ - share/doc/smm/06.nfs \ - share/doc/smm/07.lpd \ - share/doc/smm/08.sendmailop \ - share/doc/smm/11.timedop \ - share/doc/smm/12.timed \ - share/doc/smm/18.net \ - share/doc/smm/contents \ - share/doc/smm/title \ - share/doc/usd/04.csh \ - share/doc/usd/05.dc \ - share/doc/usd/06.bc \ - share/doc/usd/07.mail \ - share/doc/usd/10.exref/exref \ - share/doc/usd/10.exref/summary \ - share/doc/usd/11.vitut \ - share/doc/usd/12.vi/summary \ - share/doc/usd/12.vi/vi \ - share/doc/usd/12.vi/viapwh \ - share/doc/usd/13.viref \ - share/doc/usd/18.msdiffs \ - share/doc/usd/19.memacros \ - share/doc/usd/20.meref \ - share/doc/usd/21.troff \ - share/doc/usd/22.trofftut \ - share/doc/usd/contents \ - share/doc/usd/title \ share/dtrace \ share/dtrace/toolkit \ share/examples \ diff --git a/tools/build/options/WITH_RCMDS b/tools/build/options/WITH_RCMDS new file mode 100644 index 000000000000..dddc4ecabac3 --- /dev/null +++ b/tools/build/options/WITH_RCMDS @@ -0,0 +1,8 @@ +.\" $FreeBSD$ +Enable building of the +.Bx +r-commands. +This includes +.Xr rlogin 1 , +.Xr rsh 1 , +etc. diff --git a/tools/build/options/WITH_ZONEINFO_LEAPSECONDS_SUPPORT b/tools/build/options/WITH_ZONEINFO_LEAPSECONDS_SUPPORT new file mode 100644 index 000000000000..535f60365cf6 --- /dev/null +++ b/tools/build/options/WITH_ZONEINFO_LEAPSECONDS_SUPPORT @@ -0,0 +1,2 @@ +.\" $FreeBSD$ +Set to build leapsecond information in to the timezone database. diff --git a/tools/build/options/WITH_ZONEINFO_OLD_TIMEZONES_SUPPORT b/tools/build/options/WITH_ZONEINFO_OLD_TIMEZONES_SUPPORT new file mode 100644 index 000000000000..664b032886cf --- /dev/null +++ b/tools/build/options/WITH_ZONEINFO_OLD_TIMEZONES_SUPPORT @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Set to build backward compatibility timezone aliases in to the timezone +database. diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 98f5a71f960c..c32ff16b5b02 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -306,8 +306,6 @@ SUBDIR+= mkesdb_static .include -SUBDIR:= ${SUBDIR:O:u} - SUBDIR_PARALLEL= .include diff --git a/usr.bin/bsdcat/Makefile b/usr.bin/bsdcat/Makefile index 718eefabf5ff..077bf88d00ac 100644 --- a/usr.bin/bsdcat/Makefile +++ b/usr.bin/bsdcat/Makefile @@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive _LIBARCHIVECONFDIR= ${SRCTOP}/lib/libarchive PROG= bsdcat -BSDCAT_VERSION_STRING= 3.3.1 +BSDCAT_VERSION_STRING= 3.3.2 .PATH: ${_LIBARCHIVEDIR}/cat SRCS= bsdcat.c cmdline.c diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile index 84b7cfbe6a39..2d5e5bd8f8b1 100644 --- a/usr.bin/cpio/Makefile +++ b/usr.bin/cpio/Makefile @@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive _LIBARCHIVECONFDIR= ${SRCTOP}/lib/libarchive PROG= bsdcpio -BSDCPIO_VERSION_STRING= 3.3.1 +BSDCPIO_VERSION_STRING= 3.3.2 .PATH: ${_LIBARCHIVEDIR}/cpio SRCS= cpio.c cmdline.c diff --git a/usr.bin/grep/tests/grep_freebsd_test.sh b/usr.bin/grep/tests/grep_freebsd_test.sh index ab998ecee893..e3d35d233084 100755 --- a/usr.bin/grep/tests/grep_freebsd_test.sh +++ b/usr.bin/grep/tests/grep_freebsd_test.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2017 Kyle Evans +# Copyright (c) 2017 Kyle Evans # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c index 2fc0016c1025..39bf82def8a1 100644 --- a/usr.bin/grep/util.c +++ b/usr.bin/grep/util.c @@ -5,7 +5,7 @@ /*- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav * Copyright (C) 2008-2010 Gabor Kovesdan - * Copyright (C) 2017 Kyle Evans + * Copyright (C) 2017 Kyle Evans * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/usr.bin/hexdump/Makefile b/usr.bin/hexdump/Makefile index 4cd3cc5dc62f..d3c417f9ef75 100644 --- a/usr.bin/hexdump/Makefile +++ b/usr.bin/hexdump/Makefile @@ -1,6 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +.include + PROG= hexdump SRCS= conv.c display.c hexdump.c hexsyntax.c odsyntax.c parse.c MAN= hexdump.1 od.1 @@ -8,4 +10,8 @@ MLINKS= hexdump.1 hd.1 LINKS= ${BINDIR}/hexdump ${BINDIR}/od LINKS+= ${BINDIR}/hexdump ${BINDIR}/hd +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include diff --git a/usr.bin/hexdump/tests/Makefile b/usr.bin/hexdump/tests/Makefile new file mode 100644 index 000000000000..192e10670025 --- /dev/null +++ b/usr.bin/hexdump/tests/Makefile @@ -0,0 +1,31 @@ +# $FreeBSD$ + +PACKAGE= tests + +ATF_TESTS_SH= hexdump_test + +${PACKAGE}FILES+= d_hexdump_a.in +${PACKAGE}FILES+= d_hexdump_b.in +${PACKAGE}FILES+= d_hexdump_c.in +${PACKAGE}FILES+= d_hexdump_bflag_a.out +${PACKAGE}FILES+= d_hexdump_bflag_b.out +${PACKAGE}FILES+= d_hexdump_bflag_c.out +${PACKAGE}FILES+= d_hexdump_cflag_a.out +${PACKAGE}FILES+= d_hexdump_cflag_b.out +${PACKAGE}FILES+= d_hexdump_cflag_c.out +${PACKAGE}FILES+= d_hexdump_dflag_a.out +${PACKAGE}FILES+= d_hexdump_dflag_b.out +${PACKAGE}FILES+= d_hexdump_dflag_c.out +${PACKAGE}FILES+= d_hexdump_nflag_a.out +${PACKAGE}FILES+= d_hexdump_oflag_a.out +${PACKAGE}FILES+= d_hexdump_oflag_b.out +${PACKAGE}FILES+= d_hexdump_oflag_c.out +${PACKAGE}FILES+= d_hexdump_sflag_a.out +${PACKAGE}FILES+= d_hexdump_UCflag_a.out +${PACKAGE}FILES+= d_hexdump_UCflag_b.out +${PACKAGE}FILES+= d_hexdump_UCflag_c.out +${PACKAGE}FILES+= d_hexdump_xflag_a.out +${PACKAGE}FILES+= d_hexdump_xflag_b.out +${PACKAGE}FILES+= d_hexdump_xflag_c.out + +.include diff --git a/usr.bin/hexdump/tests/d_hexdump_UCflag_a.out b/usr.bin/hexdump/tests/d_hexdump_UCflag_a.out new file mode 100644 index 000000000000..b929e8f6e299 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_UCflag_a.out @@ -0,0 +1,2 @@ +00000000 54 65 73 74 0a |Test.| +00000005 diff --git a/usr.bin/hexdump/tests/d_hexdump_UCflag_b.out b/usr.bin/hexdump/tests/d_hexdump_UCflag_b.out new file mode 100644 index 000000000000..44c0fb3ac1af --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_UCflag_b.out @@ -0,0 +1,4 @@ +00000000 54 68 65 20 71 75 69 63 6b 20 62 72 6f 77 6e 20 |The quick brown | +00000010 66 6f 78 20 6a 75 6d 70 65 64 20 6f 76 65 72 20 |fox jumped over | +00000020 74 68 65 20 62 6c 75 65 20 68 6f 75 73 65 0a 0a |the blue house..| +00000030 diff --git a/usr.bin/hexdump/tests/d_hexdump_UCflag_c.out b/usr.bin/hexdump/tests/d_hexdump_UCflag_c.out new file mode 100644 index 000000000000..ee16184cd74a --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_UCflag_c.out @@ -0,0 +1,4 @@ +00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA| +* +00000020 41 41 41 41 41 41 41 0a |AAAAAAA.| +00000028 diff --git a/usr.bin/hexdump/tests/d_hexdump_a.in b/usr.bin/hexdump/tests/d_hexdump_a.in new file mode 100644 index 000000000000..345e6aef7132 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_a.in @@ -0,0 +1 @@ +Test diff --git a/usr.bin/hexdump/tests/d_hexdump_b.in b/usr.bin/hexdump/tests/d_hexdump_b.in new file mode 100644 index 000000000000..0fa918480ebe --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_b.in @@ -0,0 +1,2 @@ +The quick brown fox jumped over the blue house + diff --git a/usr.bin/hexdump/tests/d_hexdump_bflag_a.out b/usr.bin/hexdump/tests/d_hexdump_bflag_a.out new file mode 100644 index 000000000000..232ab776f0f3 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_bflag_a.out @@ -0,0 +1,2 @@ +0000000 124 145 163 164 012 +0000005 diff --git a/usr.bin/hexdump/tests/d_hexdump_bflag_b.out b/usr.bin/hexdump/tests/d_hexdump_bflag_b.out new file mode 100644 index 000000000000..1bd7c9ddbabb --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_bflag_b.out @@ -0,0 +1,4 @@ +0000000 124 150 145 040 161 165 151 143 153 040 142 162 157 167 156 040 +0000010 146 157 170 040 152 165 155 160 145 144 040 157 166 145 162 040 +0000020 164 150 145 040 142 154 165 145 040 150 157 165 163 145 012 012 +0000030 diff --git a/usr.bin/hexdump/tests/d_hexdump_bflag_c.out b/usr.bin/hexdump/tests/d_hexdump_bflag_c.out new file mode 100644 index 000000000000..c19f2671a8ae --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_bflag_c.out @@ -0,0 +1,4 @@ +0000000 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101 +* +0000020 101 101 101 101 101 101 101 012 +0000028 diff --git a/usr.bin/hexdump/tests/d_hexdump_c.in b/usr.bin/hexdump/tests/d_hexdump_c.in new file mode 100644 index 000000000000..2304918bcccb --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_c.in @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/usr.bin/hexdump/tests/d_hexdump_cflag_a.out b/usr.bin/hexdump/tests/d_hexdump_cflag_a.out new file mode 100644 index 000000000000..c0f49ff32051 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_cflag_a.out @@ -0,0 +1,2 @@ +0000000 T e s t \n +0000005 diff --git a/usr.bin/hexdump/tests/d_hexdump_cflag_b.out b/usr.bin/hexdump/tests/d_hexdump_cflag_b.out new file mode 100644 index 000000000000..0d087ed042f9 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_cflag_b.out @@ -0,0 +1,4 @@ +0000000 T h e q u i c k b r o w n +0000010 f o x j u m p e d o v e r +0000020 t h e b l u e h o u s e \n \n +0000030 diff --git a/usr.bin/hexdump/tests/d_hexdump_cflag_c.out b/usr.bin/hexdump/tests/d_hexdump_cflag_c.out new file mode 100644 index 000000000000..edebd59246dc --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_cflag_c.out @@ -0,0 +1,4 @@ +0000000 A A A A A A A A A A A A A A A A +* +0000020 A A A A A A A \n +0000028 diff --git a/usr.bin/hexdump/tests/d_hexdump_dflag_a.out b/usr.bin/hexdump/tests/d_hexdump_dflag_a.out new file mode 100644 index 000000000000..148b1bcecbb5 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_dflag_a.out @@ -0,0 +1,2 @@ +0000000 25940 29811 00010 +0000005 diff --git a/usr.bin/hexdump/tests/d_hexdump_dflag_b.out b/usr.bin/hexdump/tests/d_hexdump_dflag_b.out new file mode 100644 index 000000000000..e8b486c9bba6 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_dflag_b.out @@ -0,0 +1,4 @@ +0000000 26708 08293 30065 25449 08299 29282 30575 08302 +0000010 28518 08312 30058 28781 25701 28448 25974 08306 +0000020 26740 08293 27746 25973 26656 30063 25971 02570 +0000030 diff --git a/usr.bin/hexdump/tests/d_hexdump_dflag_c.out b/usr.bin/hexdump/tests/d_hexdump_dflag_c.out new file mode 100644 index 000000000000..7a2d17714263 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_dflag_c.out @@ -0,0 +1,4 @@ +0000000 16705 16705 16705 16705 16705 16705 16705 16705 +* +0000020 16705 16705 16705 02625 +0000028 diff --git a/usr.bin/hexdump/tests/d_hexdump_nflag_a.out b/usr.bin/hexdump/tests/d_hexdump_nflag_a.out new file mode 100644 index 000000000000..2b7b61b4fc8b --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_nflag_a.out @@ -0,0 +1,2 @@ +0000000 124 +0000001 diff --git a/usr.bin/hexdump/tests/d_hexdump_oflag_a.out b/usr.bin/hexdump/tests/d_hexdump_oflag_a.out new file mode 100644 index 000000000000..92b8c177f5d8 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_oflag_a.out @@ -0,0 +1,2 @@ +0000000 062524 072163 000012 +0000005 diff --git a/usr.bin/hexdump/tests/d_hexdump_oflag_b.out b/usr.bin/hexdump/tests/d_hexdump_oflag_b.out new file mode 100644 index 000000000000..6e8c2615cc3d --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_oflag_b.out @@ -0,0 +1,4 @@ +0000000 064124 020145 072561 061551 020153 071142 073557 020156 +0000010 067546 020170 072552 070155 062145 067440 062566 020162 +0000020 064164 020145 066142 062565 064040 072557 062563 005012 +0000030 diff --git a/usr.bin/hexdump/tests/d_hexdump_oflag_c.out b/usr.bin/hexdump/tests/d_hexdump_oflag_c.out new file mode 100644 index 000000000000..26a076074b69 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_oflag_c.out @@ -0,0 +1,4 @@ +0000000 040501 040501 040501 040501 040501 040501 040501 040501 +* +0000020 040501 040501 040501 005101 +0000028 diff --git a/usr.bin/hexdump/tests/d_hexdump_sflag_a.out b/usr.bin/hexdump/tests/d_hexdump_sflag_a.out new file mode 100644 index 000000000000..c7179d5c62ed --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_sflag_a.out @@ -0,0 +1,2 @@ +0000004 012 +0000005 diff --git a/usr.bin/hexdump/tests/d_hexdump_xflag_a.out b/usr.bin/hexdump/tests/d_hexdump_xflag_a.out new file mode 100644 index 000000000000..adba00a2ae03 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_xflag_a.out @@ -0,0 +1,2 @@ +0000000 6554 7473 000a +0000005 diff --git a/usr.bin/hexdump/tests/d_hexdump_xflag_b.out b/usr.bin/hexdump/tests/d_hexdump_xflag_b.out new file mode 100644 index 000000000000..75911e776375 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_xflag_b.out @@ -0,0 +1,4 @@ +0000000 6854 2065 7571 6369 206b 7262 776f 206e +0000010 6f66 2078 756a 706d 6465 6f20 6576 2072 +0000020 6874 2065 6c62 6575 6820 756f 6573 0a0a +0000030 diff --git a/usr.bin/hexdump/tests/d_hexdump_xflag_c.out b/usr.bin/hexdump/tests/d_hexdump_xflag_c.out new file mode 100644 index 000000000000..39bb73adc326 --- /dev/null +++ b/usr.bin/hexdump/tests/d_hexdump_xflag_c.out @@ -0,0 +1,4 @@ +0000000 4141 4141 4141 4141 4141 4141 4141 4141 +* +0000020 4141 4141 4141 0a41 +0000028 diff --git a/usr.bin/hexdump/tests/hexdump_test.sh b/usr.bin/hexdump/tests/hexdump_test.sh new file mode 100755 index 000000000000..400ccf3f7128 --- /dev/null +++ b/usr.bin/hexdump/tests/hexdump_test.sh @@ -0,0 +1,192 @@ +# +# Copyright (c) 2017 Kyle Evans +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +atf_test_case b_flag +b_flag_head() +{ + atf_set "descr" "Verify -b output" +} +b_flag_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_bflag_a.out" \ + hexdump -b "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_bflag_b.out" \ + hexdump -b "$(atf_get_srcdir)/d_hexdump_b.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_bflag_c.out" \ + hexdump -b "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_test_case c_flag +c_flag_head() +{ + atf_set "descr" "Verify -c output" +} +c_flag_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_cflag_a.out" \ + hexdump -c "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_cflag_b.out" \ + hexdump -c "$(atf_get_srcdir)/d_hexdump_b.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_cflag_c.out" \ + hexdump -c "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_test_case C_flag +C_flag_head() +{ + atf_set "descr" "Verify -C output" +} +C_flag_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_UCflag_a.out" \ + hexdump -C "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_UCflag_b.out" \ + hexdump -C "$(atf_get_srcdir)/d_hexdump_b.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_UCflag_c.out" \ + hexdump -C "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_test_case hd_name +hd_name_head() +{ + atf_set "descr" "Verify hd output matching -C output" +} +hd_name_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_UCflag_a.out" \ + hd "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_UCflag_b.out" \ + hd "$(atf_get_srcdir)/d_hexdump_b.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_UCflag_c.out" \ + hd "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_test_case d_flag +d_flag_head() +{ + atf_set "descr" "Verify -d output" +} +d_flag_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_dflag_a.out" \ + hexdump -d "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_dflag_b.out" \ + hexdump -d "$(atf_get_srcdir)/d_hexdump_b.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_dflag_c.out" \ + hexdump -d "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_test_case n_flag +n_flag_head() +{ + atf_set "descr" "Check -n functionality" +} +n_flag_body() +{ + atf_check -o empty hexdump -bn 0 "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_nflag_a.out" \ + hexdump -bn 1 "$(atf_get_srcdir)/d_hexdump_a.in" +} + +atf_test_case o_flag +o_flag_head() +{ + atf_set "descr" "Verify -o output" +} +o_flag_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_oflag_a.out" \ + hexdump -o "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_oflag_b.out" \ + hexdump -o "$(atf_get_srcdir)/d_hexdump_b.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_oflag_c.out" \ + hexdump -o "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_test_case s_flag +s_flag_head() +{ + atf_set "descr" "Verify -s output" +} +s_flag_body() +{ + atf_expect_fail "-s option is currently broken due to capsicum (PR 219173)" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_sflag_a.out" \ + hexdump -bs 4 "$(atf_get_srcdir)/d_hexdump_a.in" + + atf_check -o not-empty hexdump -n 100 -s 1024 /dev/random +} + +atf_test_case v_flag +v_flag_head() +{ + atf_set "descr" "Verify -v functionality" +} +v_flag_body() +{ + atf_expect_fail "-s option is currently broken due to capsicum (PR 219173)" + for i in $(seq 0 7); do + atf_check -o match:"^\*$" \ + hexdump -s ${i} "$(atf_get_srcdir)/d_hexdump_c.in" + atf_check -o not-match:"^\*$" \ + hexdump -vs ${i} "$(atf_get_srcdir)/d_hexdump_c.in" + done + + atf_check -o not-match:"^\*$" \ + hexdump -s 8 "$(atf_get_srcdir)/d_hexdump_c.in" + atf_check -o not-match:"^\*$" \ + hexdump -vs 8 "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_test_case x_flag +x_flag_head() +{ + atf_set "descr" "Verify -x output" +} +x_flag_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_xflag_a.out" \ + hexdump -x "$(atf_get_srcdir)/d_hexdump_a.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_xflag_b.out" \ + hexdump -x "$(atf_get_srcdir)/d_hexdump_b.in" + atf_check -o file:"$(atf_get_srcdir)/d_hexdump_xflag_c.out" \ + hexdump -x "$(atf_get_srcdir)/d_hexdump_c.in" +} + +atf_init_test_cases() +{ + atf_add_test_case b_flag + atf_add_test_case c_flag + atf_add_test_case C_flag + atf_add_test_case hd_name + atf_add_test_case d_flag + atf_add_test_case n_flag + atf_add_test_case o_flag + atf_add_test_case s_flag + atf_add_test_case v_flag + atf_add_test_case x_flag +} diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index 95853b507ee2..563c539b5686 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -264,6 +264,7 @@ intuit_diff_type(void) char *s, *t; int indent, retval; struct file_name names[MAX_FILE]; + int piece_of_git = 0; memset(names, 0, sizeof(names)); ok_to_create_file = false; @@ -308,14 +309,20 @@ intuit_diff_type(void) if (!stars_last_line && strnEQ(s, "*** ", 4)) names[OLD_FILE].path = fetchname(s + 4, &names[OLD_FILE].exists, strippath); - else if (strnEQ(s, "--- ", 4)) - names[NEW_FILE].path = fetchname(s + 4, + else if (strnEQ(s, "--- ", 4)) { + size_t off = 4; + if (piece_of_git && strippath == 957) + off = 6; + names[NEW_FILE].path = fetchname(s + off, &names[NEW_FILE].exists, strippath); - else if (strnEQ(s, "+++ ", 4)) + } else if (strnEQ(s, "+++ ", 4)) { /* pretend it is the old name */ - names[OLD_FILE].path = fetchname(s + 4, + size_t off = 4; + if (piece_of_git && strippath == 957) + off = 6; + names[OLD_FILE].path = fetchname(s + off, &names[OLD_FILE].exists, strippath); - else if (strnEQ(s, "Index:", 6)) + } else if (strnEQ(s, "Index:", 6)) names[INDEX_FILE].path = fetchname(s + 6, &names[INDEX_FILE].exists, strippath); else if (strnEQ(s, "Prereq:", 7)) { @@ -330,6 +337,9 @@ intuit_diff_type(void) free(revision); revision = NULL; } + } else if (strnEQ(s, "diff --git a/", 13)) { + /* Git-style diffs. */ + piece_of_git = 1; } else if (strnEQ(s, "==== ", 5)) { /* Perforce-style diffs. */ if ((t = strstr(s + 5, " - ")) != NULL) diff --git a/usr.bin/rlogin/rlogin.1 b/usr.bin/rlogin/rlogin.1 index 6f32dd45e1a9..5b974382cc5c 100644 --- a/usr.bin/rlogin/rlogin.1 +++ b/usr.bin/rlogin/rlogin.1 @@ -28,7 +28,7 @@ .\" @(#)rlogin.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd September 26, 2003 +.Dd July 3, 2017 .Dt RLOGIN 1 .Os .Sh NAME @@ -41,6 +41,15 @@ .Op Fl i Ar localname .Op Fl l Ar username .Ar host +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/usr.bin/rsh/rsh.1 b/usr.bin/rsh/rsh.1 index cc7790d0dddb..56c5e6c3dece 100644 --- a/usr.bin/rsh/rsh.1 +++ b/usr.bin/rsh/rsh.1 @@ -28,7 +28,7 @@ .\" @(#)rsh.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd October 16, 2002 +.Dd July 3, 2017 .Dt RSH 1 .Os .Sh NAME @@ -41,6 +41,15 @@ .Op Fl t Ar timeout .Ar host .Op command +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/usr.bin/ruptime/ruptime.1 b/usr.bin/ruptime/ruptime.1 index aabec193f7bc..63426eaefca3 100644 --- a/usr.bin/ruptime/ruptime.1 +++ b/usr.bin/ruptime/ruptime.1 @@ -28,7 +28,7 @@ .\" @(#)ruptime.1 8.2 (Berkeley) 4/5/94 .\" $FreeBSD$ .\" -.Dd March 1, 2003 +.Dd July 3, 2017 .Dt RUPTIME 1 .Os .Sh NAME @@ -38,6 +38,15 @@ .Nm .Op Fl alrtu .Op Ar host ... +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/usr.bin/rwho/rwho.1 b/usr.bin/rwho/rwho.1 index fd002b86dac2..6a0845c27dad 100644 --- a/usr.bin/rwho/rwho.1 +++ b/usr.bin/rwho/rwho.1 @@ -28,7 +28,7 @@ .\" @(#)rwho.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd June 6, 1993 +.Dd July 3, 2017 .Dt RWHO 1 .Os .Sh NAME @@ -37,6 +37,15 @@ .Sh SYNOPSIS .Nm .Op Fl a +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/usr.bin/sdiotool/Makefile b/usr.bin/sdiotool/Makefile new file mode 100644 index 000000000000..76d091f42956 --- /dev/null +++ b/usr.bin/sdiotool/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +PROG= sdiotool +SRCS= sdiotool.c + +LIBADD= cam util +MAN= + +.include diff --git a/usr.bin/sdiotool/sdiotool.c b/usr.bin/sdiotool/sdiotool.c new file mode 100644 index 000000000000..f665535bcc35 --- /dev/null +++ b/usr.bin/sdiotool/sdiotool.c @@ -0,0 +1,649 @@ +/*- + * Copyright (c) 2016-2017 Ilya Bakulin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct cis_info { + uint16_t man_id; + uint16_t prod_id; + uint16_t max_block_size; +}; + +static int sdio_rw_direct(struct cam_device *dev, + uint8_t func_number, + uint32_t addr, + uint8_t is_write, + uint8_t *data, + uint8_t *resp); +static uint8_t sdio_read_1(struct cam_device *dev, uint8_t func_number, uint32_t addr); +static void sdio_write_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint8_t val); +static int sdio_is_func_ready(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); +static int sdio_is_func_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); +static int sdio_func_enable(struct cam_device *dev, uint8_t func_number, int enable); +static int sdio_is_func_intr_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); +static int sdio_func_intr_enable(struct cam_device *dev, uint8_t func_number, int enable); +static void sdio_card_reset(struct cam_device *dev); +static uint32_t sdio_get_common_cis_addr(struct cam_device *dev); +static void probe_bcrm(struct cam_device *dev); + +/* Use CMD52 to read or write a single byte */ +int +sdio_rw_direct(struct cam_device *dev, + uint8_t func_number, + uint32_t addr, + uint8_t is_write, + uint8_t *data, uint8_t *resp) { + union ccb *ccb; + uint32_t flags; + uint32_t arg; + int retval = 0; + + ccb = cam_getccb(dev); + if (ccb == NULL) { + warnx("%s: error allocating CCB", __func__); + return (1); + } + bzero(&(&ccb->ccb_h)[1], + sizeof(union ccb) - sizeof(struct ccb_hdr)); + + flags = MMC_RSP_R5 | MMC_CMD_AC; + arg = SD_IO_RW_FUNC(func_number) | SD_IO_RW_ADR(addr); + if (is_write) + arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(*data); + + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ CAM_DIR_NONE, + /*mmc_opcode*/ SD_IO_RW_DIRECT, + /*mmc_arg*/ arg, + /*mmc_flags*/ flags, + /*mmc_data*/ 0, + /*timeout*/ 5000); + + if (((retval = cam_send_ccb(dev, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + const char warnstr[] = "error sending command"; + + if (retval < 0) + warn(warnstr); + else + warnx(warnstr); + return (-1); + } + + *resp = ccb->mmcio.cmd.resp[0] & 0xFF; + cam_freeccb(ccb); + return (retval); +} + +#if 0 +/* + * CMD53 -- IO_RW_EXTENDED + * Use to read or write memory blocks + * + * is_increment=1: FIFO mode + * blk_count > 0: block mode + */ +int +sdio_rw_extended(struct cam_device *dev, + uint8_t func_number, + uint32_t addr, + uint8_t is_write, + uint8_t *data, size_t datalen, + uint8_t is_increment, + uint16_t blk_count) { + union ccb *ccb; + uint32_t flags; + uint32_t arg; + int retval = 0; + + if (blk_count != 0) { + warnx("%s: block mode is not supported yet", __func__); + return (1); + } + + ccb = cam_getccb(dev); + if (ccb == NULL) { + warnx("%s: error allocating CCB", __func__); + return (1); + } + bzero(&(&ccb->ccb_h)[1], + sizeof(union ccb) - sizeof(struct ccb_hdr)); + + flags = MMC_RSP_R5 | MMC_CMD_AC; + arg = SD_IO_RW_FUNC(func_number) | SD_IO_RW_ADR(addr); + if (is_write) + arg |= SD_IO_RW_WR; + + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ CAM_DIR_NONE, + /*mmc_opcode*/ SD_IO_RW_DIRECT, + /*mmc_arg*/ arg, + /*mmc_flags*/ flags, + /*mmc_data*/ 0, + /*timeout*/ 5000); + + if (((retval = cam_send_ccb(dev, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + const char warnstr[] = "error sending command"; + + if (retval < 0) + warn(warnstr); + else + warnx(warnstr); + return (-1); + } + + *resp = ccb->mmcio.cmd.resp[0] & 0xFF; + cam_freeccb(ccb); + return (retval); +} +#endif + +static int +sdio_read_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, uint8_t *is_enab) { + uint8_t resp; + int ret; + + ret = sdio_rw_direct(dev, 0, addr, 0, NULL, &resp); + if (ret < 0) + return ret; + + *is_enab = (resp & (1 << func_number)) > 0 ? 1 : 0; + + return (0); +} + +static int +sdio_set_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, int enable) { + uint8_t resp; + int ret; + uint8_t is_enabled; + + ret = sdio_rw_direct(dev, 0, addr, 0, NULL, &resp); + if (ret != 0) + return ret; + + is_enabled = resp & (1 << func_number); + if ((is_enabled !=0 && enable == 1) || (is_enabled == 0 && enable == 0)) + return 0; + + if (enable) + resp |= 1 << func_number; + else + resp &= ~ (1 << func_number); + + ret = sdio_rw_direct(dev, 0, addr, 1, &resp, &resp); + + return ret; +} + +static uint8_t +sdio_read_1(struct cam_device *dev, uint8_t func_number, uint32_t addr) { + uint8_t val; + sdio_rw_direct(dev, func_number, addr, 0, NULL, &val); + return val; +} + +__unused static void +sdio_write_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint8_t val) { + uint8_t _val; + sdio_rw_direct(dev, func_number, addr, 0, &val, &_val); +} + +static int +sdio_is_func_ready(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { + return sdio_read_bool_for_func(dev, SD_IO_CCCR_FN_READY, func_number, is_enab); +} + +static int +sdio_is_func_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { + return sdio_read_bool_for_func(dev, SD_IO_CCCR_FN_ENABLE, func_number, is_enab); +} + +static int +sdio_func_enable(struct cam_device *dev, uint8_t func_number, int enable) { + return sdio_set_bool_for_func(dev, SD_IO_CCCR_FN_ENABLE, func_number, enable); +} + +static int +sdio_is_func_intr_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { + return sdio_read_bool_for_func(dev, SD_IO_CCCR_INT_ENABLE, func_number, is_enab); +} + +static int +sdio_func_intr_enable(struct cam_device *dev, uint8_t func_number, int enable) { + return sdio_set_bool_for_func(dev, SD_IO_CCCR_INT_ENABLE, func_number, enable); +} + +static int +sdio_card_set_bus_width(struct cam_device *dev, enum mmc_bus_width bw) { + int ret; + uint8_t ctl_val; + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_BUS_WIDTH, 0, NULL, &ctl_val); + if (ret < 0) { + warn("Error getting CCCR_BUS_WIDTH value"); + return ret; + } + ctl_val &= ~0x3; + switch (bw) { + case bus_width_1: + /* Already set to 1-bit */ + break; + case bus_width_4: + ctl_val |= CCCR_BUS_WIDTH_4; + break; + case bus_width_8: + warn("Cannot do 8-bit on SDIO yet"); + return -1; + break; + } + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_BUS_WIDTH, 1, &ctl_val, &ctl_val); + if (ret < 0) { + warn("Error setting CCCR_BUS_WIDTH value"); + return ret; + } + return ret; +} + +static int +sdio_func_read_cis(struct cam_device *dev, uint8_t func_number, + uint32_t cis_addr, struct cis_info *info) { + uint8_t tuple_id, tuple_len, tuple_count; + uint32_t addr; + + char *cis1_info[4]; + int start, i, ch, count; + char cis1_info_buf[256]; + + tuple_count = 0; /* Use to prevent infinite loop in case of parse errors */ + memset(cis1_info_buf, 0, 256); + do { + addr = cis_addr; + tuple_id = sdio_read_1(dev, 0, addr++); + if (tuple_id == SD_IO_CISTPL_END) + break; + if (tuple_id == 0) { + cis_addr++; + continue; + } + tuple_len = sdio_read_1(dev, 0, addr++); + if (tuple_len == 0 && tuple_id != 0x00) { + warn("Parse error: 0-length tuple %02X\n", tuple_id); + return -1; + } + + switch (tuple_id) { + case SD_IO_CISTPL_VERS_1: + addr += 2; + for (count = 0, start = 0, i = 0; + (count < 4) && ((i + 4) < 256); i++) { + ch = sdio_read_1(dev, 0, addr + i); + printf("count=%d, start=%d, i=%d, Got %c (0x%02x)\n", count, start, i, ch, ch); + if (ch == 0xff) + break; + cis1_info_buf[i] = ch; + if (ch == 0) { + cis1_info[count] = + cis1_info_buf + start; + start = i + 1; + count++; + } + } + printf("Card info:"); + for (i=0; i<4; i++) + if (cis1_info[i]) + printf(" %s", cis1_info[i]); + printf("\n"); + break; + case SD_IO_CISTPL_MANFID: + info->man_id = sdio_read_1(dev, 0, addr++); + info->man_id |= sdio_read_1(dev, 0, addr++) << 8; + + info->prod_id = sdio_read_1(dev, 0, addr++); + info->prod_id |= sdio_read_1(dev, 0, addr++) << 8; + break; + case SD_IO_CISTPL_FUNCID: + /* not sure if we need to parse it? */ + break; + case SD_IO_CISTPL_FUNCE: + if (tuple_len < 4) { + printf("FUNCE is too short: %d\n", tuple_len); + break; + } + if (func_number == 0) { + /* skip extended_data */ + addr++; + info->max_block_size = sdio_read_1(dev, 0, addr++); + info->max_block_size |= sdio_read_1(dev, 0, addr++) << 8; + } else { + info->max_block_size = sdio_read_1(dev, 0, addr + 0xC); + info->max_block_size |= sdio_read_1(dev, 0, addr + 0xD) << 8; + } + break; + default: + printf("Skipping tuple ID %02X len %02X\n", tuple_id, tuple_len); + } + cis_addr += tuple_len + 2; + tuple_count++; + } while (tuple_count < 20); + + return 0; +} + +static uint32_t +sdio_get_common_cis_addr(struct cam_device *dev) { + uint32_t addr; + + addr = sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR); + addr |= sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR + 1) << 8; + addr |= sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR + 2) << 16; + + if (addr < SD_IO_CIS_START || addr > SD_IO_CIS_START + SD_IO_CIS_SIZE) { + warn("Bad CIS address: %04X\n", addr); + addr = 0; + } + + return addr; +} + +static void sdio_card_reset(struct cam_device *dev) { + int ret; + uint8_t ctl_val; + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_CTL, 0, NULL, &ctl_val); + if (ret < 0) + errx(1, "Error getting CCCR_CTL value"); + ctl_val |= CCCR_CTL_RES; + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_CTL, 1, &ctl_val, &ctl_val); + if (ret < 0) + errx(1, "Error setting CCCR_CTL value"); +} + +/* + * How Linux driver works + * + * The probing begins by calling brcmf_ops_sdio_probe() which is defined as probe function in struct sdio_driver. http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c#L1126 + * + * The driver does black magic by copying func struct for F2 and setting func number to zero there, to create an F0 func structure :) + * Driver state changes to BRCMF_SDIOD_DOWN. + * ops_sdio_probe() then calls brcmf_sdio_probe() -- at this point it has filled in sdiodev struct with the pointers to all three functions (F0, F1, F2). + * + * brcmf_sdiod_probe() sets block sizes for F1 and F2. It sets F1 block size to 64 and F2 to 512, not consulting the values stored in SDIO CCCR / FBR registers! + * Then it increases timeout for F2 (what is this?!) + * Then it enables F1 + * Then it attaches "freezer" (without PM this is NOP) + * Finally it calls brcmf_sdio_probe() http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c#L4082 + * + * Here high-level workqueues and sg tables are allocated. + * It then calls brcmf_sdio_probe_attach() + * + * Here at the beginning there is a pr_debug() call with brcmf_sdiod_regrl() inside to addr #define SI_ENUM_BASE 0x18000000. + * Return value is 0x16044330. + * Then turns off PLL: byte-write BRCMF_INIT_CLKCTL1 (0x28) -> SBSDIO_FUNC1_CHIPCLKCSR (0x1000E) + * Then it reads value back, should be 0xe8. + * Then calls brcmf_chip_attach() + * + * http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c#L1054 + * This func enumerates and resets all the cores on the dongle. + * - brcmf_sdio_buscoreprep(): force clock to ALPAvail req only: + * SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ -> SBSDIO_FUNC1_CHIPCLKCSR + * Wait up to 15ms to !SBSDIO_ALPAV(clkval) of the value from CLKCSR. + * Force ALP: + * SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP (0x21)-> SBSDIO_FUNC1_CHIPCLKCSR + * Disaable SDIO pullups: + * byte 0 -> SBSDIO_FUNC1_SDIOPULLUP (0x0001000f) + * + * Calls brcmf_chip_recognition() + * http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c#L908 + * Read 0x18000000. Get 0x16044330: chip 4330 rev 4 + * AXI chip, call brcmf_chip_dmp_erom_scan() to get info about all cores. + * Then brcmf_chip_cores_check() to check that CPU and RAM are found, + * + * Setting cores to passive: not clear which of CR4/CA7/CM3 our chip has. + * Quite a few r/w calls to different parts of the chip to reset cores.... + * Finally get_raminfo() called to fill in RAM info: + * brcmf_chip_get_raminfo: RAM: base=0x0 size=294912 (0x48000) sr=0 (0x0) + * http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c#L700 + * + * Then brcmf_chip_setup() is called, this prints and fills in chipcommon rev and PMU caps: + * brcmf_chip_setup: ccrev=39, pmurev=12, pmucaps=0x19583c0c + * http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c#L1015 + * Bus-specific setup code is NOP for SDIO. + * + * brcmf_sdio_kso_init() is called. + * Here it first reads 0x1 from SBSDIO_FUNC1_SLEEPCSR 0x18000650 and then writes it back... WTF? + * + * brcmf_sdio_drivestrengthinit() is called + * http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c#L3630 + * + * Set card control so an SDIO card reset does a WLAN backplane reset + * set PMUControl so a backplane reset does PMU state reload + * === end of brcmf_sdio_probe_attach === + + **** Finished reading at http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c#L4152, line 2025 in the dump + + * === How register reading works === + * http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c#L357 + * The address to read from is written to three byte-sized registers of F1: + * - SBSDIO_FUNC1_SBADDRLOW 0x1000A + * - SBSDIO_FUNC1_SBADDRMID 0x1000B + * - SBSDIO_FUNC1_SBADDRHIGH 0x1000C + * If this is 32-bit read , a flag is set. The address is ANDed with SBSDIO_SB_OFT_ADDR_MASK which is 0x07FFF. + * Then brcmf_sdiod_regrw_helper() is called to read the reply. + * http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c#L306 + * Based on the address it figures out where to read it from (CCCR / FBR in F0, or somewhere in F1). + * Reads are retried three times. + * 1-byte IO is done with CMD52, more is read with CMD53 with address increment (not FIFO mode). + * http://lxr.free-electrons.com/source/drivers/mmc/core/sdio_io.c#L458 + * ================================== + * + * + */ +__unused +static void +probe_bcrm(struct cam_device *dev) { + uint32_t cis_addr; + struct cis_info info; + + sdio_card_set_bus_width(dev, bus_width_4); + cis_addr = sdio_get_common_cis_addr(dev); + printf("CIS address: %04X\n", cis_addr); + + memset(&info, 0, sizeof(info)); + sdio_func_read_cis(dev, 0, cis_addr, &info); + printf("Vendor 0x%04X product 0x%04X\n", info.man_id, info.prod_id); +} +__unused +static uint8_t * +mmap_fw() { + const char fw_path[] = "/home/kibab/repos/fbsd-bbb/brcm-firmware/brcmfmac4330-sdio.bin"; + struct stat sb; + uint8_t *fw_ptr; + + int fd = open(fw_path, O_RDONLY); + if (fd < 0) + errx(1, "Cannot open firmware file"); + if (fstat(fd, &sb) < 0) + errx(1, "Cannot get file stat"); + fw_ptr = mmap(NULL, sb.st_size, PROT_READ, 0, fd, 0); + if (fw_ptr == MAP_FAILED) + errx(1, "Cannot map the file"); + + return fw_ptr; +} + +static void +usage() { + printf("sdiotool -u \n"); + exit(0); +} + +static void +get_sdio_card_info(struct cam_device *dev) { + uint32_t cis_addr; + uint32_t fbr_addr; + struct cis_info info; + + cis_addr = sdio_get_common_cis_addr(dev); + + memset(&info, 0, sizeof(info)); + sdio_func_read_cis(dev, 0, cis_addr, &info); + printf("F0: Vendor 0x%04X product 0x%04X max block size %d bytes\n", + info.man_id, info.prod_id, info.max_block_size); + for (int i = 1; i <= 2; i++) { + fbr_addr = SD_IO_FBR_START * i + 0x9; + cis_addr = sdio_read_1(dev, 0, fbr_addr++); + cis_addr |= sdio_read_1(dev, 0, fbr_addr++) << 8; + cis_addr |= sdio_read_1(dev, 0, fbr_addr++) << 16; + memset(&info, 0, sizeof(info)); + sdio_func_read_cis(dev, i, cis_addr, &info); + printf("F%d: Vendor 0x%04X product 0x%04X max block size %d bytes\n", + i, info.man_id, info.prod_id, info.max_block_size); + } +} + +/* Test interrupt delivery when select() */ +__unused static int +sdio_signal_intr(struct cam_device *dev) { + uint8_t resp; + int ret; + + ret = sdio_rw_direct(dev, 0, 0x666, 0, NULL, &resp); + if (ret < 0) + return ret; + return (0); +} + +static void +do_intr_test(__unused struct cam_device *dev) { +} + +int +main(int argc, char **argv) { + char device[] = "pass"; + int unit = 0; + int func = 0; + uint8_t resp; + uint8_t is_enab; + __unused uint8_t *fw_ptr; + int ch; + struct cam_device *cam_dev; + int is_intr_test = 0; + + //fw_ptr = mmap_fw(); + + while ((ch = getopt(argc, argv, "Iu:")) != -1) { + switch (ch) { + case 'u': + unit = (int) strtol(optarg, NULL, 10); + break; + case 'f': + func = (int) strtol(optarg, NULL, 10); + case 'I': + is_intr_test = 1; + case '?': + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if ((cam_dev = cam_open_spec_device(device, unit, O_RDWR, NULL)) == NULL) + errx(1, "Cannot open device"); + + get_sdio_card_info(cam_dev); + if (is_intr_test > 0) + do_intr_test(cam_dev); + exit(0); + sdio_card_reset(cam_dev); + + /* Read Addr 7 of func 0 */ + int ret = sdio_rw_direct(cam_dev, 0, 7, 0, NULL, &resp); + if (ret < 0) + errx(1, "Error sending CAM command"); + printf("Result: %02x\n", resp); + + /* Check if func 1 is enabled */ + ret = sdio_is_func_enabled(cam_dev, 1, &is_enab); + if (ret < 0) + errx(1, "Cannot check if func is enabled"); + printf("F1 enabled: %d\n", is_enab); + ret = sdio_func_enable(cam_dev, 1, 1 - is_enab); + if (ret < 0) + errx(1, "Cannot enable/disable func"); + printf("F1 en/dis result: %d\n", ret); + + /* Check if func 1 is ready */ + ret = sdio_is_func_ready(cam_dev, 1, &is_enab); + if (ret < 0) + errx(1, "Cannot check if func is ready"); + printf("F1 ready: %d\n", is_enab); + + /* Check if interrupts are enabled */ + ret = sdio_is_func_intr_enabled(cam_dev, 1, &is_enab); + if (ret < 0) + errx(1, "Cannot check if func intr is enabled"); + printf("F1 intr enabled: %d\n", is_enab); + ret = sdio_func_intr_enable(cam_dev, 1, 1 - is_enab); + if (ret < 0) + errx(1, "Cannot enable/disable func intr"); + printf("F1 intr en/dis result: %d\n", ret); + + cam_close_spec_device(cam_dev); +} diff --git a/usr.bin/stat/tests/stat_test.sh b/usr.bin/stat/tests/stat_test.sh index 6088b924c0d5..55ec47107051 100755 --- a/usr.bin/stat/tests/stat_test.sh +++ b/usr.bin/stat/tests/stat_test.sh @@ -60,14 +60,23 @@ l_flag_body() paths="a b c d" + ls_out=ls.output + stat_out=stat.output + # NOTE: # - Even though stat -l claims to be equivalent to `ls -lT`, the # whitespace is a bit more liberal in the `ls -lT` output. # - `ls -ldT` is used to not recursively list the contents of # directories. for path in $paths; do - atf_check -o inline:"$(ls -ldT $path | sed -e 's, , ,g')\n" \ - stat -l $path + atf_check -o save:$ls_out ls -ldT $path + cat $ls_out + atf_check -o save:$stat_out stat -l $path + cat $stat_out + echo "Comparing normalized whitespace" + atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $ls_out + atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $stat_out + atf_check cmp $ls_out $stat_out done } @@ -165,7 +174,7 @@ t_flag_body() x_output_date() { - local date_format='%a %b %d %H:%M:%S %Y' + local date_format='%a %b %e %H:%M:%S %Y' stat -t "$date_format" "$@" } diff --git a/usr.bin/stdbuf/stdbuf.c b/usr.bin/stdbuf/stdbuf.c index 4346cc85f1a1..c05a44de7da5 100644 --- a/usr.bin/stdbuf/stdbuf.c +++ b/usr.bin/stdbuf/stdbuf.c @@ -40,7 +40,7 @@ static void usage(int s) { - fprintf(stderr, "Usage: %s [-e 0|L|] [-i 0|L|] [-o 0|L|] " + fprintf(stderr, "Usage: %s [-e 0|L|B|] [-i 0|L|B|] [-o 0|L|B|] " " [args ...]\n", __progname); exit(s); } diff --git a/usr.bin/tar/Makefile b/usr.bin/tar/Makefile index 4832314b75b4..c7d306eaad94 100644 --- a/usr.bin/tar/Makefile +++ b/usr.bin/tar/Makefile @@ -4,7 +4,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive PROG= bsdtar -BSDTAR_VERSION_STRING= 3.3.1 +BSDTAR_VERSION_STRING= 3.3.2 .PATH: ${_LIBARCHIVEDIR}/tar SRCS= bsdtar.c \ diff --git a/usr.bin/xo/tests/functional_test.sh b/usr.bin/xo/tests/functional_test.sh index 2a26faa4962e..c57c88211d1e 100755 --- a/usr.bin/xo/tests/functional_test.sh +++ b/usr.bin/xo/tests/functional_test.sh @@ -42,8 +42,8 @@ check() atf_check -s exit:0 -e file:${err_file} -o file:${out_file} \ env LC_ALL=en_US.UTF-8 \ - LIBXO_OPTIONS=":W${xo_fmt}" TZ="EST" "${SRCDIR}/${tc}" \ - ${XO} + TZ="EST" "${SRCDIR}/${tc}" \ + "${XO} --libxo:W${xo_fmt}" } add_testcase() diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 0aa63a8fb947..b1b5c5026678 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -218,8 +218,6 @@ SUBDIR.${MK_TESTS}+= tests .include -SUBDIR:= ${SUBDIR:O} - SUBDIR_PARALLEL= .include diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index d056023c1b3c..9b6a76983d92 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -270,6 +270,10 @@ acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first, end = (char *)table + table->Length; while ((char *)subtable < end) { printf("\n"); + if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) { + warnx("invalid subtable length %u", subtable->Length); + return; + } action(subtable); subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + subtable->Length); diff --git a/usr.sbin/bhyve/Makefile.depend b/usr.sbin/bhyve/Makefile.depend index 681b1277639b..6a1e47258af7 100644 --- a/usr.sbin/bhyve/Makefile.depend +++ b/usr.sbin/bhyve/Makefile.depend @@ -16,6 +16,7 @@ DIRDEPS = \ lib/libutil \ lib/libvmmapi \ lib/libz \ + secure/lib/libcrypto \ .include diff --git a/usr.sbin/bsdinstall/scripts/config b/usr.sbin/bsdinstall/scripts/config index e93e0aec276e..6a5bbfb39b58 100755 --- a/usr.sbin/bsdinstall/scripts/config +++ b/usr.sbin/bsdinstall/scripts/config @@ -35,6 +35,11 @@ rm $BSDINSTALL_TMPETC/rc.conf.* cat $BSDINSTALL_CHROOT/etc/sysctl.conf $BSDINSTALL_TMPETC/sysctl.conf.* >> $BSDINSTALL_TMPETC/sysctl.conf rm $BSDINSTALL_TMPETC/sysctl.conf.* +if [ -f $BSDINSTALL_TMPTEC/ttys.hardening ]; then + cat $BSDINSTALL_TMPTEC/ttys.hardening > $BSDINSTALL_TMPTEC/ttys + rm $BSDINSTALL_TMPTEC/ttys.hardening +fi + cp $BSDINSTALL_TMPETC/* $BSDINSTALL_CHROOT/etc cat $BSDINSTALL_TMPBOOT/loader.conf.* >> $BSDINSTALL_TMPBOOT/loader.conf diff --git a/usr.sbin/bsdinstall/scripts/hardening b/usr.sbin/bsdinstall/scripts/hardening index 2d7566dad48e..471108013d21 100755 --- a/usr.sbin/bsdinstall/scripts/hardening +++ b/usr.sbin/bsdinstall/scripts/hardening @@ -42,10 +42,11 @@ FEATURES=$( dialog --backtitle "FreeBSD Installer" \ "3 read_msgbuf" "Disable reading kernel message buffer for unprivileged users" ${read_msgbuf:-off} \ "4 proc_debug" "Disable process debugging facilities for unprivileged users" ${proc_debug:-off} \ "5 random_pid" "Randomize the PID of newly created processes" ${random_pid:-off} \ - "6 stack_guard" "Insert stack guard page ahead of the growable segments" ${stack_guard:-off} \ + "6 stack_guard" "Set stack guard buffer size to 2MB" ${stack_guard:-off} \ "7 clear_tmp" "Clean the /tmp filesystem on system startup" ${clear_tmp:-off} \ "8 disable_syslogd" "Disable opening Syslogd network socket (disables remote logging)" ${disable_syslogd:-off} \ "9 disable_sendmail" "Disable Sendmail service" ${disable_sendmail:-off} \ + "10 secure_console" "Enable console password prompt" ${secure_console:-off} \ 2>&1 1>&3 ) exec 3>&- @@ -69,7 +70,7 @@ for feature in $FEATURES; do echo kern.randompid=$(jot -r 1 9999) >> $BSDINSTALL_TMPETC/sysctl.conf.hardening fi if [ "$feature" = "stack_guard" ]; then - echo security.bsd.stack_guard_page=1 >> $BSDINSTALL_TMPETC/sysctl.conf.hardening + echo security.bsd.stack_guard_page=512 >> $BSDINSTALL_TMPETC/sysctl.conf.hardening fi if [ "$feature" = "clear_tmp" ]; then echo 'clear_tmp_enable="YES"' >> $BSDINSTALL_TMPETC/rc.conf.hardening @@ -80,5 +81,8 @@ for feature in $FEATURES; do if [ "$feature" = "disable_sendmail" ]; then echo 'sendmail_enable="NONE"' >> $BSDINSTALL_TMPETC/rc.conf.hardening fi + if [ "$feature" = "secure_console" ]; then + sed "s/unknown off secure/unknown off insecure/g" $BSDINSTALL_CHROOT/etc/ttys > $BSDINSTALL_TMPETC/ttys.hardening + fi done diff --git a/usr.sbin/diskinfo/diskinfo.8 b/usr.sbin/diskinfo/diskinfo.8 index a50accc3dffb..a30337a7c020 100644 --- a/usr.sbin/diskinfo/diskinfo.8 +++ b/usr.sbin/diskinfo/diskinfo.8 @@ -1,5 +1,6 @@ .\" .\" Copyright (c) 2003 Poul-Henning Kamp +.\" Copyright (c) 2017 Alexander Motin .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -28,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 1, 2017 +.Dd July 4, 2017 .Dt DISKINFO 8 .Os .Sh NAME @@ -36,7 +37,7 @@ .Nd get information about disk device .Sh SYNOPSIS .Nm -.Op Fl citv +.Op Fl citSvw .Ar disk ... .Nm .Op Fl p @@ -61,12 +62,19 @@ Perform a simple IOPS benchmark. .It Fl p Return the physical path of the disk. This is a string that identifies the physical path to the disk in the -storage enclsoure. +storage enclosure. .It Fl s Return the disk serial number +.It Fl S +Perform synchronous random write test (ZFS SLOG test), +measuring time required to write data blocks of different size and +flush disk cache. +Blocks of more then 128KB are written with multiple parallel operations. .It Fl t Perform a simple and rather naive benchmark of the disks seek and transfer performance. +.It Fl w +Allow disruptive write tests. .El .Pp If given no arguments, the output will be a single line per specified device @@ -79,7 +87,7 @@ Return the disk ident, usually the serial number. .It Fl p Return the physical path of the disk. This is a string that identifies the physical path to the disk in the -storage enclsoure. +storage enclosure. .El .Sh HISTORY The diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c index 8c79f2f07fe8..e6ae46f8c3f0 100644 --- a/usr.sbin/diskinfo/diskinfo.c +++ b/usr.sbin/diskinfo/diskinfo.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2003 Poul-Henning Kamp * Copyright (c) 2015 Spectra Logic Corporation + * Copyright (c) 2017 Alexander Motin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -51,15 +54,16 @@ static void usage(void) { - fprintf(stderr, "usage: diskinfo [-citv] disk ...\n"); + fprintf(stderr, "usage: diskinfo [-cipsStvw] disk ...\n"); exit (1); } -static int opt_c, opt_i, opt_p, opt_s, opt_t, opt_v; +static int opt_c, opt_i, opt_p, opt_s, opt_S, opt_t, opt_v, opt_w; static void speeddisk(int fd, off_t mediasize, u_int sectorsize); static void commandtime(int fd, off_t mediasize, u_int sectorsize); static void iopsbench(int fd, off_t mediasize, u_int sectorsize); +static void slogbench(int fd, int isreg, off_t mediasize, u_int sectorsize); static int zonecheck(int fd, uint32_t *zone_mode, char *zone_str, size_t zone_str_len); @@ -70,11 +74,12 @@ main(int argc, char **argv) int i, ch, fd, error, exitval = 0; char buf[BUFSIZ], ident[DISK_IDENT_SIZE], physpath[MAXPATHLEN]; char zone_desc[64]; + struct diocgattr_arg arg; off_t mediasize, stripesize, stripeoffset; - u_int sectorsize, fwsectors, fwheads, zoned = 0; + u_int sectorsize, fwsectors, fwheads, zoned = 0, isreg; uint32_t zone_mode; - while ((ch = getopt(argc, argv, "cipstv")) != -1) { + while ((ch = getopt(argc, argv, "cipsStvw")) != -1) { switch (ch) { case 'c': opt_c = 1; @@ -90,6 +95,10 @@ main(int argc, char **argv) case 's': opt_s = 1; break; + case 'S': + opt_S = 1; + opt_v = 1; + break; case 't': opt_t = 1; opt_v = 1; @@ -97,6 +106,9 @@ main(int argc, char **argv) case 'v': opt_v = 1; break; + case 'w': + opt_w = 1; + break; default: usage(); } @@ -112,8 +124,13 @@ main(int argc, char **argv) usage(); } + if (opt_S && !opt_w) { + warnx("-S require also -w"); + usage(); + } + for (i = 0; i < argc; i++) { - fd = open(argv[i], O_RDONLY | O_DIRECT); + fd = open(argv[i], (opt_w ? O_RDWR : O_RDONLY) | O_DIRECT); if (fd < 0 && errno == ENOENT && *argv[i] != '/') { snprintf(buf, BUFSIZ, "%s%s", _PATH_DEV, argv[i]); fd = open(buf, O_RDONLY); @@ -128,7 +145,8 @@ main(int argc, char **argv) exitval = 1; goto out; } - if (S_ISREG(sb.st_mode)) { + isreg = S_ISREG(sb.st_mode); + if (isreg) { mediasize = sb.st_size; sectorsize = S_BLKSIZE; fwsectors = 0; @@ -214,6 +232,10 @@ main(int argc, char **argv) printf("\t%-12u\t# Heads according to firmware.\n", fwheads); printf("\t%-12u\t# Sectors according to firmware.\n", fwsectors); } + strlcpy(arg.name, "GEOM::descr", sizeof(arg.name)); + arg.len = sizeof(arg.value.str); + if (ioctl(fd, DIOCGATTR, &arg) == 0) + printf("\t%-12s\t# Disk descr.\n", arg.value.str); if (ioctl(fd, DIOCGIDENT, ident) == 0) printf("\t%-12s\t# Disk ident.\n", ident); if (ioctl(fd, DIOCGPHYSPATH, physpath) == 0) @@ -228,15 +250,17 @@ main(int argc, char **argv) speeddisk(fd, mediasize, sectorsize); if (opt_i) iopsbench(fd, mediasize, sectorsize); + if (opt_S) + slogbench(fd, isreg, mediasize, sectorsize); out: close(fd); } exit (exitval); } - -static char sector[65536]; -static char mega[1024 * 1024]; +#define MAXTX (8*1024*1024) +#define MEGATX (1024*1024) +static uint8_t buf[MAXTX]; static void rdsect(int fd, off_t blockno, u_int sectorsize) @@ -245,7 +269,7 @@ rdsect(int fd, off_t blockno, u_int sectorsize) if (lseek(fd, (off_t)blockno * sectorsize, SEEK_SET) == -1) err(1, "lseek"); - error = read(fd, sector, sectorsize); + error = read(fd, buf, sectorsize); if (error == -1) err(1, "read"); if (error != (int)sectorsize) @@ -257,10 +281,10 @@ rdmega(int fd) { int error; - error = read(fd, mega, sizeof(mega)); + error = read(fd, buf, MEGATX); if (error == -1) err(1, "read"); - if (error != sizeof(mega)) + if (error != MEGATX) errx(1, "disk too small for test."); } @@ -320,6 +344,16 @@ TI(double count) count, dt, count / dt); } +static void +TS(u_int size, int count) +{ + double dt; + + dt = delta_t(); + printf("%8.1f usec/IO = %8.1f Mbytes/s\n", + dt * 1000000.0 / count, size * count / dt / (1024 * 1024)); +} + static void speeddisk(int fd, off_t mediasize, u_int sectorsize) { @@ -557,6 +591,69 @@ iopsbench(int fd, off_t mediasize, u_int sectorsize) printf("\n"); } +#define MAXIO (128*1024) +#define MAXIOS (MAXTX / MAXIO) + +static void +parwrite(int fd, size_t size, off_t off) +{ + struct aiocb aios[MAXIOS]; + off_t o; + size_t s; + int n, error; + struct aiocb *aiop; + + for (n = 0, o = 0; size > MAXIO; n++, size -= s, o += s) { + s = (size >= MAXIO) ? MAXIO : size; + aiop = &aios[n]; + bzero(aiop, sizeof(*aiop)); + aiop->aio_buf = &buf[o]; + aiop->aio_fildes = fd; + aiop->aio_offset = off + o; + aiop->aio_nbytes = s; + error = aio_write(aiop); + if (error != 0) + err(EX_IOERR, "AIO write submit error"); + } + error = pwrite(fd, &buf[o], size, off + o); + if (error < 0) + err(EX_IOERR, "Sync write error"); + for (; n > 0; n--) { + error = aio_waitcomplete(&aiop, NULL); + if (error < 0) + err(EX_IOERR, "AIO write wait error"); + } +} + +static void +slogbench(int fd, int isreg, off_t mediasize, u_int sectorsize) +{ + off_t off; + u_int size; + int error, n, N; + + printf("Synchronous random writes:\n"); + for (size = sectorsize; size <= MAXTX; size *= 2) { + printf("\t%4.4g kbytes: ", (double)size / 1024); + N = 0; + T0(); + do { + for (n = 0; n < 250; n++) { + off = random() % (mediasize / size); + parwrite(fd, size, off * size); + if (isreg) + error = fsync(fd); + else + error = ioctl(fd, DIOCGFLUSH); + if (error < 0) + err(EX_IOERR, "Flush error"); + } + N += 250; + } while (delta_t() < 1.0); + TS(size, N); + } +} + static int zonecheck(int fd, uint32_t *zone_mode, char *zone_str, size_t zone_str_len) { diff --git a/usr.sbin/nfsuserd/nfsuserd.8 b/usr.sbin/nfsuserd/nfsuserd.8 index d750d0a50652..e249d7ceffba 100644 --- a/usr.sbin/nfsuserd/nfsuserd.8 +++ b/usr.sbin/nfsuserd/nfsuserd.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 21, 2017 +.Dd July 6, 2017 .Dt NFSUSERD 8 .Os .Sh NAME @@ -40,21 +40,34 @@ services plus support manage-gids for all NFS versions .Op Fl verbose .Op Fl force .Op Fl manage-gids +.Op Fl use-udpsock .Op Ar num_servers .Sh DESCRIPTION .Nm loads user and group information into the kernel for NFSv4. -It must be running for NFSv4 to function correctly, either client or server. It also provides support for manage-gids and must be running on the server if this is being used for any version of NFS. .Pp Upon startup, it loads the machines DNS domain name, plus timeout and cache size limit into the kernel. It then preloads the cache with group and user information, up to the cache size limit and forks off N children -(default 4), that service requests from the kernel for cache misses. The -master server is there for the sole purpose of killing off the slaves. +(only 1 child for AF_LOCAL sockets), that service requests from the kernel for cache misses. +The master server is there for the sole purpose of killing off the slave(s). To stop the nfsuserd, send a SIGUSR1 to the master server. .Pp +By default, upcalls from the kernel use an AF_LOCAL socket. +For this case, only one server daemon will be running. +The +.Fl use-udpsock +option may be used to make the +.Nm +daemon use a UDP socket, with upcalls done via 127.0.0.1, which was the +old behaviour for +.Nm . +Use of the UDP socket can only be done if +.Xr jail 8 +are not being used. +.Pp The following options are available: .Bl -tag -width Ds .It Fl domain Ar domain_name @@ -91,14 +104,12 @@ and uses the group list for that uid provided by .Xr getgrouplist 3 on the server instead of the list of groups provided in the RPC authenticator. This can be used to avoid the 16 group limit for AUTH_SYS. +.It Fl use-udpsock +This flag forces use of the old behaviour of a UDP socket with upcalls done via 127.0.0.1. .It Ar num_servers Specifies how many servers to create (max 20). -The default of 4 may be sufficient. You should run enough servers, so that -.Xr ps 1 -shows almost no running time for one or two of the slaves after the system -has been running for a long period. Running too few will have a major -performance impact, whereas running too many will only tie up some resources, -such as a process table entry and swap space. +This option has been deprecated and is ignored for AF_LOCAL upcall sockets, +which always use a single server. .El .Sh SEE ALSO .Xr getgrent 3 , @@ -126,3 +137,12 @@ those requests fail and the library functions don't return. See and .Xr passwd 5 for more information on how the databases are accessed. +.Pp +For the +.Fl use-udpsock +option, since the kernel communicates with the +.Nm +daemon via an upcall that uses the IP address 127.0.0.1, it does not work correctly when +.Xr jail 8 +are used and can crash the system. +This is not a problem when a AF_LOCAL socket is used. diff --git a/usr.sbin/nfsuserd/nfsuserd.c b/usr.sbin/nfsuserd/nfsuserd.c index 413e5cedbb9b..761d01d937f6 100644 --- a/usr.sbin/nfsuserd/nfsuserd.c +++ b/usr.sbin/nfsuserd/nfsuserd.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -73,6 +75,9 @@ static bool_t xdr_getid(XDR *, caddr_t); static bool_t xdr_getname(XDR *, caddr_t); static bool_t xdr_retval(XDR *, caddr_t); +#ifndef _PATH_NFSUSERDSOCK +#define _PATH_NFSUSERDSOCK "/var/run/nfsuserd.sock" +#endif #define MAXNAME 1024 #define MAXNFSUSERD 20 #define DEFNFSUSERD 4 @@ -92,6 +97,7 @@ uid_t defaultuid = 65534; u_char *defaultgroup = "nogroup"; gid_t defaultgid = 65533; int verbose = 0, im_a_slave = 0, nfsuserdcnt = -1, forcestart = 0; +int use_udpsock = 0; int defusertimeout = DEFUSERTIMEOUT, manage_gids = 0; pid_t slaves[MAXNFSUSERD]; @@ -103,15 +109,17 @@ main(int argc, char *argv[]) struct nfsd_idargs nid; struct passwd *pwd; struct group *grp; - int sock, one = 1; + int oldmask, one = 1, sock; SVCXPRT *udptransp; u_short portnum; + SVCXPRT *xprt; sigset_t signew; char hostname[MAXHOSTNAMELEN + 1], *cp; struct addrinfo *aip, hints; static uid_t check_dups[MAXUSERMAX]; gid_t grps[NGROUPS]; int ngroup; + struct sockaddr_un sun; if (modfind("nfscommon") < 0) { /* Not present in kernel, try loading it */ @@ -164,6 +172,8 @@ main(int argc, char *argv[]) forcestart = 1; } else if (!strcmp(*argv, "-manage-gids")) { manage_gids = 1; + } else if (!strcmp(*argv, "-use-udpsock")) { + use_udpsock = 1; } else if (!strcmp(*argv, "-usermax")) { if (argc == 1) usage(); @@ -207,6 +217,9 @@ main(int argc, char *argv[]) } if (nfsuserdcnt < 1) nfsuserdcnt = DEFNFSUSERD; + if (use_udpsock == 0) + /* For AF_LOCAL socket, only allow one server daemon. */ + nfsuserdcnt = 1; /* * Strip off leading and trailing '.'s in domain name and map @@ -245,49 +258,93 @@ main(int argc, char *argv[]) for (i = 0; i < nfsuserdcnt; i++) slaves[i] = (pid_t)-1; - /* - * Set up the service port to accept requests via UDP from - * localhost (127.0.0.1). - */ - if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) - err(1, "cannot create udp socket"); - - /* - * Not sure what this does, so I'll leave it here for now. - */ - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + if (use_udpsock != 0) { + /* + * Set up the service port to accept requests via UDP from + * localhost (127.0.0.1). + */ + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + err(1, "cannot create udp socket"); - if ((udptransp = svcudp_create(sock)) == NULL) - err(1, "Can't set up socket"); - - /* - * By not specifying a protocol, it is linked into the - * dispatch queue, but not registered with portmapper, - * which is just what I want. - */ - if (!svc_register(udptransp, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, - nfsuserdsrv, 0)) - err(1, "Can't register nfsuserd"); - - /* - * Tell the kernel what my port# is. - */ - portnum = htons(udptransp->xp_port); + /* + * Not sure what this does, so I'll leave it here for now. + */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + + if ((udptransp = svcudp_create(sock)) == NULL) + err(1, "Can't set up socket"); + + /* + * By not specifying a protocol, it is linked into the + * dispatch queue, but not registered with portmapper, + * which is just what I want. + */ + if (!svc_register(udptransp, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, + nfsuserdsrv, 0)) + err(1, "Can't register nfsuserd"); + + /* + * Tell the kernel what my port# is. + */ + portnum = htons(udptransp->xp_port); #ifdef DEBUG - printf("portnum=0x%x\n", portnum); + printf("portnum=0x%x\n", portnum); #else - if (nfssvc(NFSSVC_NFSUSERDPORT, (caddr_t)&portnum) < 0) { - if (errno == EPERM) { - fprintf(stderr, - "Can't start nfsuserd when already running"); - fprintf(stderr, - " If not running, use the -force option.\n"); - } else { - fprintf(stderr, "Can't do nfssvc() to add port\n"); + if (nfssvc(NFSSVC_NFSUSERDPORT, (caddr_t)&portnum) < 0) { + if (errno == EPERM) + fprintf(stderr, "Can't start nfsuserd when" + " already running\nIf not running," + " use the -force option.\n"); + else + fprintf(stderr, + "Can't do nfssvc() to add socket\n"); + exit(1); } - exit(1); - } #endif + } else { + /* Use the AF_LOCAL socket. */ + memset(&sun, 0, sizeof sun); + sun.sun_family = AF_LOCAL; + unlink(_PATH_NFSUSERDSOCK); + strcpy(sun.sun_path, _PATH_NFSUSERDSOCK); + sun.sun_len = SUN_LEN(&sun); + sock = socket(AF_LOCAL, SOCK_STREAM, 0); + if (sock < 0) + err(1, "Can't create local nfsuserd socket"); + oldmask = umask(S_IXUSR | S_IRWXG | S_IRWXO); + if (bind(sock, (struct sockaddr *)&sun, sun.sun_len) < 0) + err(1, "Can't bind local nfsuserd socket"); + umask(oldmask); + if (listen(sock, SOMAXCONN) < 0) + err(1, "Can't listen on local nfsuserd socket"); + xprt = svc_vc_create(sock, RPC_MAXDATASIZE, RPC_MAXDATASIZE); + if (xprt == NULL) + err(1, + "Can't create transport for local nfsuserd socket"); + if (!svc_reg(xprt, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, + nfsuserdsrv, NULL)) + err(1, + "Can't register service for local nfsuserd socket"); + + /* + * Tell the kernel what the socket's path is. + */ +#ifdef DEBUG + printf("sockpath=%s\n", _PATH_NFSUSERDSOCK); +#else + if (nfssvc(NFSSVC_NFSUSERDPORT | NFSSVC_NEWSTRUCT, + _PATH_NFSUSERDSOCK) < 0) { + if (errno == EPERM) + fprintf(stderr, "Can't start nfsuserd when" + " already running\nIf not running," + " use the -force option.\n"); + else + fprintf(stderr, + "Can't do nfssvc() to add socket\n"); + exit(1); + } +#endif + } pwd = getpwnam(defaultuser); if (pwd) @@ -462,21 +519,25 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXPRT *transp) gid_t grps[NGROUPS]; int ngroup; - /* - * Only handle requests from 127.0.0.1 on a reserved port number. - * (Since a reserved port # at localhost implies a client with - * local root, there won't be a security breach. This is about - * the only case I can think of where a reserved port # means - * something.) - */ - sport = ntohs(transp->xp_raddr.sin_port); - saddr = ntohl(transp->xp_raddr.sin_addr.s_addr); - if ((rqstp->rq_proc != NULLPROC && sport >= IPPORT_RESERVED) || - saddr != 0x7f000001) { - syslog(LOG_ERR, "req from ip=0x%x port=%d\n", saddr, sport); - svcerr_weakauth(transp); - return; + if (use_udpsock != 0) { + /* + * Only handle requests from 127.0.0.1 on a reserved port + * number. (Since a reserved port # at localhost implies a + * client with local root, there won't be a security breach. + * This is about the only case I can think of where a reserved + * port # means something.) + */ + sport = ntohs(transp->xp_raddr.sin_port); + saddr = ntohl(transp->xp_raddr.sin_addr.s_addr); + if ((rqstp->rq_proc != NULLPROC && sport >= IPPORT_RESERVED) || + saddr != 0x7f000001) { + syslog(LOG_ERR, "req from ip=0x%x port=%d, consider" + " using an AF_LOCAL socket\n", saddr, sport); + svcerr_weakauth(transp); + return; + } } + switch (rqstp->rq_proc) { case NULLPROC: if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) @@ -720,6 +781,7 @@ static void usage(void) { - errx(1, - "usage: nfsuserd [-usermax cache_size] [-usertimeout minutes] [-verbose] [-manage-gids] [-domain domain_name] [n]"); + errx(1, "usage: nfsuserd [-usermax cache_size] [-usertimeout minutes]" + " [-verbose] [-manage-gids] [-use-udpsock] [-domain domain_name]" + " [n]"); } diff --git a/usr.sbin/rpc.statd/Makefile.depend b/usr.sbin/rpc.statd/Makefile.depend index 6401ed61118e..bdd7bc273d10 100644 --- a/usr.sbin/rpc.statd/Makefile.depend +++ b/usr.sbin/rpc.statd/Makefile.depend @@ -7,6 +7,7 @@ DIRDEPS = \ include \ include/arpa \ include/rpc \ + include/rpcsvc \ include/xlocale \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/rwhod/rwhod.8 b/usr.sbin/rwhod/rwhod.8 index bcf7cb1fdec7..2d181815c737 100644 --- a/usr.sbin/rwhod/rwhod.8 +++ b/usr.sbin/rwhod/rwhod.8 @@ -28,7 +28,7 @@ .\" @(#)rwhod.8 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd January 21, 2010 +.Dd July 3, 2017 .Dt RWHOD 8 .Os .Sh NAME @@ -40,6 +40,15 @@ .Op Fl p .Op Fl l .Op Fl m Op Ar ttl +.Sh DEPRECATION NOTICE +.Nm +is deprecated and will be removed from future versions of the +.Fx +base system. +If +.Nm +is still required, it can be installed from ports or packages +(net/bsdrcmds). .Sh DESCRIPTION The .Nm diff --git a/usr.sbin/sesutil/Makefile.depend b/usr.sbin/sesutil/Makefile.depend index 757244ae167f..137678c21e46 100644 --- a/usr.sbin/sesutil/Makefile.depend +++ b/usr.sbin/sesutil/Makefile.depend @@ -8,7 +8,9 @@ DIRDEPS = \ include/xlocale \ lib/${CSU_DIR} \ lib/libc \ - lib/libcompiler_rt + lib/libcompiler_rt \ + lib/libutil \ + lib/libxo \ .include