diff --git a/bin/pax/ftree.c b/bin/pax/ftree.c index b780dbbf5..591de2616 100644 --- a/bin/pax/ftree.c +++ b/bin/pax/ftree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ftree.c,v 1.42 2019/06/28 13:34:59 deraadt Exp $ */ +/* $OpenBSD: ftree.c,v 1.43 2024/08/15 00:47:44 guenther Exp $ */ /* $NetBSD: ftree.c,v 1.4 1995/03/21 09:07:21 cgd Exp $ */ /*- @@ -52,8 +52,7 @@ */ typedef struct ftree { char *fname; /* file tree name */ - int refcnt; /* has tree had a selected file? */ - int newercnt; /* skipped due to -u/-D */ + int refcnt; /* had a selected (or skipped) file? */ int chflg; /* change directory flag */ struct ftree *fow; /* pointer to next entry on list */ } FTREE; @@ -173,7 +172,6 @@ ftree_add(char *str, int chflg) str[len] = '\0'; ft->fname = str; ft->refcnt = 0; - ft->newercnt = 0; ft->chflg = chflg; ft->fow = NULL; if (fthead == NULL) { @@ -228,7 +226,7 @@ ftree_skipped_newer(ARCHD *arcn) { /* skipped due to -u/-D, mark accordingly */ if (ftcur != NULL) - ftcur->newercnt = 1; + ftcur->refcnt = 1; } /* @@ -254,7 +252,7 @@ ftree_chk(void) * that never had a match */ for (ft = fthead; ft != NULL; ft = ft->fow) { - if ((ft->refcnt > 0) || ft->newercnt > 0 || ft->chflg) + if ((ft->refcnt > 0) || ft->chflg) continue; if (wban == 0) { paxwarn(1,"WARNING! These file names were not selected:"); diff --git a/bin/test/test.c b/bin/test/test.c index 575664557..21c276424 100644 --- a/bin/test/test.c +++ b/bin/test/test.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test.c,v 1.21 2024/06/18 16:41:39 schwarze Exp $ */ +/* $OpenBSD: test.c,v 1.22 2024/08/15 06:27:24 guenther Exp $ */ /* $NetBSD: test.c,v 1.15 1995/03/21 07:04:06 cgd Exp $ */ /* @@ -424,19 +424,6 @@ filstat(char *nm, enum token mode) struct stat s; mode_t i; - if (mode == FILSYM) { -#ifdef S_IFLNK - if (lstat(nm, &s) == 0) { - i = S_IFLNK; - goto filetype; - } -#endif - return 0; - } - - if (stat(nm, &s) != 0) - return 0; - switch (mode) { case FILRD: return access(nm, R_OK) == 0; @@ -446,6 +433,22 @@ filstat(char *nm, enum token mode) return access(nm, X_OK) == 0; case FILEXIST: return access(nm, F_OK) == 0; + default: + break; + } + + if (mode == FILSYM) { + if (lstat(nm, &s) == 0) { + i = S_IFLNK; + goto filetype; + } + return 0; + } + + if (stat(nm, &s) != 0) + return 0; + + switch (mode) { case FILREG: i = S_IFREG; goto filetype; @@ -459,19 +462,11 @@ filstat(char *nm, enum token mode) i = S_IFBLK; goto filetype; case FILFIFO: -#ifdef S_IFIFO i = S_IFIFO; goto filetype; -#else - return 0; -#endif case FILSOCK: -#ifdef S_IFSOCK i = S_IFSOCK; goto filetype; -#else - return 0; -#endif case FILSUID: i = S_ISUID; goto filebit; diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index 3bbebd1d3..e9fc7725b 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -357,6 +357,8 @@ ./usr/include/dev/ic/qlwvar.h ./usr/include/dev/ic/qwxreg.h ./usr/include/dev/ic/qwxvar.h +./usr/include/dev/ic/qwzreg.h +./usr/include/dev/ic/qwzvar.h ./usr/include/dev/ic/r92creg.h ./usr/include/dev/ic/ramdac.h ./usr/include/dev/ic/revar.h diff --git a/lib/check_sym b/lib/check_sym index 8ab01ca32..0d5421b7d 100755 --- a/lib/check_sym +++ b/lib/check_sym @@ -1,5 +1,5 @@ #!/bin/ksh -# $OpenBSD: check_sym,v 1.11 2022/01/03 03:40:48 guenther Exp $ +# $OpenBSD: check_sym,v 1.12 2024/08/15 01:25:13 guenther Exp $ # # Copyright (c) 2016,2019,2022 Philip Guenther # @@ -17,10 +17,10 @@ # # # check_sym -- compare the symbols and external function references in two -# versions of a shared library +# versions of a library # # SYNOPSIS -# check_sym [-chkv] [old [new]] +# check_sym [-chkSv] [old [new]] # # DESCRIPTION # Library developers need to be aware when they have changed the @@ -33,6 +33,8 @@ # In each case, additions and removals are reported; for exported # symbols it also reports when a symbol is weakened or strengthened. # +# With the -S option, a similar analysis is done but for the static lib. +# # The shared libraries to compare can be specified on the # command-line. Otherwise, check_sym expects to be run from the # source directory of a library with a shlib_version file specifying @@ -50,7 +52,7 @@ # files left behind by the -k option can be cleaned up by invoking # check_syms with the -c option. # -# The -v option enables verbose output. +# The -v option enables verbose output, showing relocation counts. # # The *basic* rules of thumb for library versions are: if you # * stop exporting a symbol, or @@ -81,7 +83,7 @@ get_lib_name() { - sed -n 's/^[ ]*LIB[ ]*=[ ]*\([^ ]*\).*/\1/p' "$@" + sed -n '/^[ ]*LIB[ ]*=/{ s/^[^=]*=[ ]*\([^ ]*\).*/\1/p; q;}' "$@" } pick_highest() @@ -104,31 +106,205 @@ pick_highest() [[ $old != "" ]] } +fail() { echo "$*" >&2; exit 1; } + usage() { - usage="usage: check_sym [-chkv] [old [new]]" - if [[ $# -gt 0 ]] - then - echo "check_sym: $@ -$usage" >&2 - exit 1 - fi + usage="usage: check_sym [-chkSv] [old [new]]" + [[ $# -eq 0 ]] || fail "check_sym: $* +$usage" echo "$usage" exit 0 } + +# +# Output helpers +# +data_sym_changes() +{ + join "$@" | awk '$2 != $3 { print $1 " " $2 " --> " $3 }' +} + +output_if_not_empty() +{ + leader=$1 + shift + if "$@" | grep -q . + then + echo "$leader" + "$@" | sed 's:^: :' + echo + fi +} + + +# +# Dynamic library routines +# + +dynamic_collect() +{ + readelf -sW $old | filt_symtab > $odir/Ds1 + readelf -sW $new | filt_symtab > $odir/Ds2 + + readelf -rW $old > $odir/r1 + readelf -rW $new > $odir/r2 + + case $(readelf -h $new | grep '^ *Machine:') in + *MIPS*) cpu=mips64 + gotsym1=$(readelf -d $old | awk '$2 ~ /MIPS_GOTSYM/{print $3}') + gotsym2=$(readelf -d $new | awk '$2 ~ /MIPS_GOTSYM/{print $3}') + ;; + *HPPA*) cpu=hppa;; + *) cpu=dontcare;; + esac +} + +jump_slots() +{ + case $cpu in + hppa) awk '/IPLT/ && $5 != ""{print $5}' r$1 + ;; + mips64) # the $((gotsym$1)) converts hex to decimal + awk -v g=$((gotsym$1)) \ + '/^Symbol table ..symtab/{exit} + $6 == "PROTECTED" { next } + $1+0 >= g && $4 == "FUNC" {print $8}' Ds$1 + ;; + *) awk '/JU*MP_SL/ && $5 != ""{print $5}' r$1 + ;; + esac | sort -o j$1 +} + +dynamic_sym() +{ + awk -v s=$1 '/^Symbol table ..symtab/{exit} + ! /^ *[1-9]/ {next} + $5 == "LOCAL" {next} + $7 == "UND" {print $8 | ("sort -o DU" s); next } + $5 == "GLOBAL" {print $8 | ("sort -o DS" s) } + $5 == "WEAK" {print $8 | ("sort -o DW" s) } + $4 == "OBJECT" {print $8, $3 | ("sort -o DO" s) } + {print $8 | ("sort -o D" s) + print $4, $5, $6, $8}' Ds$1 | sort -o d$1 +} + +static_sym() +{ + awk '/^Symbol table ..symtab/{s=1} + /LOCAL/{next} + s&&/^ *[1-9]/{print $4, $5, $6, $8}' Ds$1 | sort -o s$1 +} + +dynamic_analysis() +{ + jump_slots $1 + dynamic_sym $1 + #static_sym $1 + comm -23 j$1 DU$1 >J$1 + return 0 +} + +dynamic_output() +{ + if cmp -s d[12] && cmp -s DO[12] + then + printf "No dynamic export changes\n" + else + printf "Dynamic export changes:\n" + output_if_not_empty "added:" comm -13 D[12] + output_if_not_empty "removed:" comm -23 D[12] + output_if_not_empty "weakened:" comm -12 DS1 DW2 + output_if_not_empty "strengthened:" comm -12 DW1 DS2 + output_if_not_empty "data object sizes changes:" \ + data_sym_changes DO[12] + fi + if ! cmp -s DU[12] + then + printf "External reference changes:\n" + output_if_not_empty "added:" comm -13 DU[12] + output_if_not_empty "removed:" comm -23 DU[12] + fi + + if $verbose; then + printf "\nReloc counts:\nbefore:\n" + grep ^R r1 + printf "\nafter:\n" + grep ^R r2 + fi + + output_if_not_empty "PLT added:" comm -13 J[12] + output_if_not_empty "PLT removed:" comm -23 J[12] +} + + +# +# Static library routines +# +static_collect() +{ + readelf -sW $old | filt_ret | filt_symtab > $odir/Ss1 + readelf -sW $new | filt_ret | filt_symtab > $odir/Ss2 +} + +static_analysis() +{ + awk -v s=$1 '!/^ *[1-9]/{next} + $5 == "LOCAL" {next} + $7 == "UND" {print $8 | ("sort -uo SU" s); next } + $6 == "HIDDEN" {print $8 | ("sort -uo SH" s) } + $5 == "GLOBAL" {print $8 | ("sort -o SS" s) } + $5 == "WEAK" {print $8 | ("sort -o SW" s) } + $4 == "OBJECT" {print $8, $3 | ("sort -o SO" s) } + {print $8 | ("sort -o S" s) + print $4, $5, $6, $8}' Ss$1 | sort -o s$1 + grep -v '^_' SH$1 >Sh$1 || : +} + +static_output() +{ + output_if_not_empty "hidden but not reserved:" comm -13 Sh[12] + if cmp -s s[12] && cmp -s SO[12] + then + printf "No static export changes\n" + else + printf "Static export changes:\n" + output_if_not_empty "added:" comm -13 S[12] + output_if_not_empty "removed:" comm -23 S[12] + output_if_not_empty "weakened:" comm -12 SS1 SW2 + output_if_not_empty "strengthened:" comm -12 SW1 SS2 + output_if_not_empty "data object sizes changes:" \ + data_sym_changes SO[12] + fi + if ! cmp -s SU[12] + then + printf "External reference changes:\n" + output_if_not_empty "added:" comm -13 SU[12] + output_if_not_empty "removed:" comm -23 SU[12] + fi +} + + unset odir -file_list={D{,S,W,O},J,S,U,d,j,r,s}{1,2} +file_list={D{,O,S,s,W,U},J,d,j,r}{1,2} +static_file_list={S{,H,h,O,S,U,W},U,s}{1,2} keep_temp=false +dynamic=true +static=false verbose=false -while getopts :chkv opt "$@" + +do_static() { static=true dynamic=false file_list=$static_file_list; } + +while getopts :chkSv opt "$@" do case $opt in c) rm -f /tmp/$file_list exit 0;; h) usage;; k) keep_temp=true;; + S) do_static;; v) verbose=true;; \?) usage "unknown option -- $OPTARG";; esac @@ -137,17 +313,30 @@ shift $((OPTIND - 1)) [[ $# -gt 2 ]] && usage "too many arguments" # Old library? -if [[ $1 = ?(*/)lib*.so* ]] +if ! $static && [[ $1 = ?(*/)lib*.so* ]] then - if [[ ! -f $1 ]] - then - echo "$1 doesn't exist" >&2 - exit 1 - fi + [[ -f $1 ]] || fail "$1 doesn't exist" old=$1 lib=${old##*/} lib=${lib%%.so.*} shift +elif [[ $1 = ?(*/)lib*.a ]] +then + # woo hoo, static library mode + do_static + if [[ -f $1 ]] + then + old=$1 + lib=${old##*/} + elif [[ $1 = lib*.a && -f /usr/lib/$1 ]] + then + old=/usr/lib/$1 + lib=$1 + else + fail "$1 doesn't exist" + fi + lib=${lib%%.a} + shift else # try determining it from the current directory if [[ -f Makefile ]] && lib=$(get_lib_name Makefile) && @@ -160,35 +349,39 @@ else # Is there a copy of that lib in the current directory? # If so, use the highest numbered one - if ! pick_highest $lib.so.* && ! pick_highest /usr/lib/$lib.so.* + if ! $static && + ! pick_highest $lib.so.* && + ! pick_highest /usr/lib/$lib.so.* then - echo "unable to find $lib.so.*" >&2 - exit 1 + fail "unable to find $lib.so.*" + elif $static + then + old=/usr/lib/${lib}.a + [[ -f $old ]] || fail "$old doesn't exist" fi fi # New library? -if [[ $1 = ?(*/)lib*.so* ]] +if [[ $1 = ?(*/)lib*.so* ]] || + { $static && [[ $1 = ?(*/)lib*.a ]]; } then new=$1 shift +elif $static +then + new=obj/${lib}.a else # Dig info out of the just built library . ./shlib_version new=obj/${lib}.so.${major}.${minor} fi -if [[ ! -f $new ]] -then - echo "$new doesn't exist" >&2 - exit 1 -fi +[[ -f $new ]] || fail "$new doesn't exist" # Filter the output of readelf -s to be easier to parse by removing a # field that only appears on some symbols: [: 88] # Not really arch-specific, but I've only seen it on alpha -filt_symtab() { - sed 's/\[: [0-9a-f]*\]//' -} +filt_symtab() { sed 's/\[: [0-9a-f]*\]//'; } +filt_ret() { egrep -v ' (__retguard_[0-9]+|__llvm_retpoline_[a-z]+[0-9]*)$'; } if $keep_temp then @@ -210,112 +403,29 @@ do done set +C -readelf -rW $old > $odir/r1 -readelf -rW $new > $odir/r2 -readelf -sW $old | filt_symtab > $odir/s1 -readelf -sW $new | filt_symtab > $odir/s2 - - -case $(readelf -h $new | grep '^ *Machine:') in -*MIPS*) cpu=mips64;; -*HPPA*) cpu=hppa;; -*) cpu=dontcare;; -esac - -if [[ $cpu = mips64 ]] -then - gotsym1=$(readelf -d $old | awk '$2 ~ /MIPS_GOTSYM/{print $3}') - gotsym2=$(readelf -d $new | awk '$2 ~ /MIPS_GOTSYM/{print $3}') -fi +# +# Collect data +# +$dynamic && dynamic_collect +$static && static_collect # Now that we're done accessing $old and $new (which could be # relative paths), chdir into our work directory, whatever it is cd $odir -jump_slots() { - case $cpu in - hppa) awk '/IPLT/ && $5 != ""{print $5}' r$1 - ;; - mips64) # the $((gotsym$1)) converts hex to decimal - awk -v g=$((gotsym$1)) \ - '/^Symbol table ..symtab/{exit} - $6 == "PROTECTED" { next } - $1+0 >= g && $4 == "FUNC" {print $8}' s$1 - ;; - *) awk '/JU*MP_SL/ && $5 != ""{print $5}' r$1 - ;; - esac | sort -o j$1 -} - -dynamic_sym() { - awk -v s=$1 '/^Symbol table ..symtab/{exit} - ! /^ *[1-9]/ {next} - $7 == "UND" {print $8 | ("sort -o U" s); next } - $5 == "GLOBAL" {print $8 | ("sort -o DS" s) } - $5 == "WEAK" {print $8 | ("sort -o DW" s) } - $5 != "LOCAL" {print $8 | ("sort -o D" s) } - $5 != "LOCAL" && $4 == "OBJECT" { - print $8, $3 | ("sort -o DO" s) } - {print $4, $5, $6, $8}' s$1 | sort -o d$1 -} - -static_sym() { - awk '/^Symbol table ..symtab/{s=1} - /LOCAL/{next} - s&&/^ *[1-9]/{print $4, $5, $6, $8}' s$1 | sort -o S$1 -} - -data_sym_changes() { - join "$@" | awk '$2 != $3 { print $1 " " $2 " --> " $3 }' -} - -output_if_not_empty() { - leader=$1 - shift - if "$@" | grep -q . - then - echo "$leader" - "$@" | sed 's:^: :' - echo - fi -} - - +# +# Do The Job +# for i in 1 2 do - jump_slots $i - dynamic_sym $i - static_sym $i - comm -23 j$i U$i >J$i + $dynamic && dynamic_analysis $i + $static && static_analysis $i done -echo "$old --> $new" -if cmp -s d[12] && cmp -s DO[12] -then - printf "No dynamic export changes\n" -else - printf "Dynamic export changes:\n" - output_if_not_empty "added:" comm -13 D[12] - output_if_not_empty "removed:" comm -23 D[12] - output_if_not_empty "weakened:" comm -12 DS1 DW2 - output_if_not_empty "strengthened:" comm -12 DW1 DS2 - output_if_not_empty "data object sizes changes:" \ - data_sym_changes DO[12] -fi -if ! cmp -s U[12] -then - printf "External reference changes:\n" - output_if_not_empty "added:" comm -13 U[12] - output_if_not_empty "removed:" comm -23 U[12] -fi +{ + echo "$old --> $new" + $dynamic && dynamic_output + $static && static_output +} -if $verbose; then - printf "\nReloc counts:\nbefore:\n" - grep ^R r1 - printf "\nafter:\n" - grep ^R r2 -fi - -output_if_not_empty "PLT added:" comm -13 J1 J2 -output_if_not_empty "PLT removed:" comm -23 J1 J2 diff --git a/regress/lib/libc/sys/README b/regress/lib/libc/sys/README index b0092c4e0..526832e5a 100644 --- a/regress/lib/libc/sys/README +++ b/regress/lib/libc/sys/README @@ -63,8 +63,6 @@ t_ptrace_wait4 - t_ptrace_wait6 - not implemented t_ptrace_waitid - t_ptrace_waitpid - -t_recvmmsg - not implemented, not POSIX -t_sendmmsg - not implemented, not POSIX t_sigqueue - not implemented, added in POSIX.1-2004 t_sigtimedwait - not implemented, added in POSIX.1-2004 t_swapcontext - not available, removed in POSIX.1-2008 diff --git a/regress/usr.bin/ssh/unittests/sshkey/common.c b/regress/usr.bin/ssh/unittests/sshkey/common.c index 1e19fa5b4..4e7c90060 100644 --- a/regress/usr.bin/ssh/unittests/sshkey/common.c +++ b/regress/usr.bin/ssh/unittests/sshkey/common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: common.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: common.c,v 1.6 2024/08/15 00:52:23 djm Exp $ */ /* * Helpers for key API tests * @@ -78,8 +78,8 @@ rsa_n(struct sshkey *k) const BIGNUM *n = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_key(k->rsa, &n, NULL, NULL); + ASSERT_PTR_NE(k->pkey, NULL); + RSA_get0_key(EVP_PKEY_get0_RSA(k->pkey), &n, NULL, NULL); return n; } @@ -89,8 +89,8 @@ rsa_e(struct sshkey *k) const BIGNUM *e = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_key(k->rsa, NULL, &e, NULL); + ASSERT_PTR_NE(k->pkey, NULL); + RSA_get0_key(EVP_PKEY_get0_RSA(k->pkey), NULL, &e, NULL); return e; } @@ -100,8 +100,8 @@ rsa_p(struct sshkey *k) const BIGNUM *p = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_factors(k->rsa, &p, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k->pkey), NULL); + RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), &p, NULL); return p; } @@ -111,8 +111,8 @@ rsa_q(struct sshkey *k) const BIGNUM *q = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_factors(k->rsa, NULL, &q); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k->pkey), NULL); + RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), NULL, &q); return q; } diff --git a/regress/usr.bin/ssh/unittests/sshkey/test_file.c b/regress/usr.bin/ssh/unittests/sshkey/test_file.c index 6c22548d5..5665f48e6 100644 --- a/regress/usr.bin/ssh/unittests/sshkey/test_file.c +++ b/regress/usr.bin/ssh/unittests/sshkey/test_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_file.c,v 1.11 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_file.c,v 1.12 2024/08/15 00:52:23 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -258,11 +258,12 @@ sshkey_file_tests(void) sshbuf_free(buf); a = load_bignum("ecdsa_1.param.priv"); b = load_bignum("ecdsa_1.param.pub"); - c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), - EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, - NULL, NULL); + c = EC_POINT_point2bn(EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(k1->pkey)), + EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), + POINT_CONVERSION_UNCOMPRESSED, NULL, NULL); ASSERT_PTR_NE(c, NULL); - ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); + ASSERT_BIGNUM_EQ( + EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), a); ASSERT_BIGNUM_EQ(b, c); BN_free(a); BN_free(b); diff --git a/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c b/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c index fe331d259..718ffc92a 100644 --- a/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c +++ b/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshkey.c,v 1.24 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_sshkey.c,v 1.25 2024/08/15 00:52:23 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -188,7 +188,7 @@ sshkey_tests(void) TEST_START("new/free KEY_RSA"); k1 = sshkey_new(KEY_RSA); ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(k1->pkey, NULL); sshkey_free(k1); TEST_DONE(); @@ -204,7 +204,7 @@ sshkey_tests(void) TEST_START("new/free KEY_ECDSA"); k1 = sshkey_new(KEY_ECDSA); ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ + ASSERT_PTR_EQ(k1->pkey, NULL); /* Can't allocate without NID */ sshkey_free(k1); TEST_DONE(); @@ -250,7 +250,7 @@ sshkey_tests(void) SSH_ERR_KEY_LENGTH); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_PTR_NE(kr, NULL); - ASSERT_PTR_NE(kr->rsa, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(kr->pkey), NULL); ASSERT_PTR_NE(rsa_n(kr), NULL); ASSERT_PTR_NE(rsa_e(kr), NULL); ASSERT_PTR_NE(rsa_p(kr), NULL); @@ -270,9 +270,11 @@ sshkey_tests(void) TEST_START("generate KEY_ECDSA"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); ASSERT_PTR_NE(ke, NULL); - ASSERT_PTR_NE(ke->ecdsa, NULL); - ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); - ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(ke->pkey), NULL); + ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), + NULL); + ASSERT_PTR_NE(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), + NULL); TEST_DONE(); TEST_START("generate KEY_ED25519"); @@ -288,7 +290,7 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kr, k1); ASSERT_INT_EQ(k1->type, KEY_RSA); - ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k1->pkey), NULL); ASSERT_PTR_NE(rsa_n(k1), NULL); ASSERT_PTR_NE(rsa_e(k1), NULL); ASSERT_PTR_EQ(rsa_p(k1), NULL); @@ -321,10 +323,12 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(ke, k1); ASSERT_INT_EQ(k1->type, KEY_ECDSA); - ASSERT_PTR_NE(k1->ecdsa, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(k1->pkey), NULL); ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); - ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); - ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); + ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), + NULL); + ASSERT_PTR_EQ(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), + NULL); TEST_DONE(); TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); diff --git a/regress/usr.sbin/bgpd/integrationtests/exabgp.attr.ok b/regress/usr.sbin/bgpd/integrationtests/exabgp.attr.ok index d1097d623..18a1b9460 100644 --- a/regress/usr.sbin/bgpd/integrationtests/exabgp.attr.ok +++ b/regress/usr.sbin/bgpd/integrationtests/exabgp.attr.ok @@ -1,5 +1,5 @@ flags: * = Valid, > = Selected, I = via IBGP, A = Announced, - S = Stale, E = Error + S = Stale, E = Error, F = Filtered origin validation state: N = not-found, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid origin: i = IGP, e = EGP, ? = Incomplete diff --git a/regress/usr.sbin/bgpd/integrationtests/exabgp.med.ok b/regress/usr.sbin/bgpd/integrationtests/exabgp.med.ok index 5fc40043b..1b5f73d3c 100644 --- a/regress/usr.sbin/bgpd/integrationtests/exabgp.med.ok +++ b/regress/usr.sbin/bgpd/integrationtests/exabgp.med.ok @@ -1,5 +1,5 @@ flags: * = Valid, > = Selected, I = via IBGP, A = Announced, - S = Stale, E = Error + S = Stale, E = Error, F = Filtered origin validation state: N = not-found, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid origin: i = IGP, e = EGP, ? = Incomplete diff --git a/regress/usr.sbin/bgpd/integrationtests/exabgp.med_2.ok b/regress/usr.sbin/bgpd/integrationtests/exabgp.med_2.ok index 1bd4aa702..a8bf0f325 100644 --- a/regress/usr.sbin/bgpd/integrationtests/exabgp.med_2.ok +++ b/regress/usr.sbin/bgpd/integrationtests/exabgp.med_2.ok @@ -1,5 +1,5 @@ flags: * = Valid, > = Selected, I = via IBGP, A = Announced, - S = Stale, E = Error + S = Stale, E = Error, F = Filtered origin validation state: N = not-found, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid origin: i = IGP, e = EGP, ? = Incomplete diff --git a/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain1.ok b/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain1.ok index bb90aab04..89b0771e7 100644 --- a/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain1.ok +++ b/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain1.ok @@ -1,5 +1,5 @@ flags: * = Valid, > = Selected, I = via IBGP, A = Announced, - S = Stale, E = Error + S = Stale, E = Error, F = Filtered origin validation state: N = not-found, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid origin: i = IGP, e = EGP, ? = Incomplete diff --git a/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain2.ok b/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain2.ok index f92a39f07..314355e3f 100644 --- a/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain2.ok +++ b/regress/usr.sbin/bgpd/integrationtests/lladdr.rdomain2.ok @@ -1,5 +1,5 @@ flags: * = Valid, > = Selected, I = via IBGP, A = Announced, - S = Stale, E = Error + S = Stale, E = Error, F = Filtered origin validation state: N = not-found, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid origin: i = IGP, e = EGP, ? = Incomplete diff --git a/regress/usr.sbin/bgpd/integrationtests/maxcomm.ok b/regress/usr.sbin/bgpd/integrationtests/maxcomm.ok index ec56254e4..65fe6a458 100644 --- a/regress/usr.sbin/bgpd/integrationtests/maxcomm.ok +++ b/regress/usr.sbin/bgpd/integrationtests/maxcomm.ok @@ -1,5 +1,5 @@ flags: * = Valid, > = Selected, I = via IBGP, A = Announced, - S = Stale, E = Error + S = Stale, E = Error, F = Filtered origin validation state: N = not-found, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid origin: i = IGP, e = EGP, ? = Incomplete diff --git a/share/man/man4/bpf.4 b/share/man/man4/bpf.4 index 4990dc8a1..2c5d476c6 100644 --- a/share/man/man4/bpf.4 +++ b/share/man/man4/bpf.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bpf.4,v 1.46 2024/08/05 23:56:10 dlg Exp $ +.\" $OpenBSD: bpf.4,v 1.47 2024/08/15 12:20:20 dlg Exp $ .\" $NetBSD: bpf.4,v 1.7 1995/09/27 18:31:50 thorpej Exp $ .\" .\" Copyright (c) 1990 The Regents of the University of California. @@ -23,7 +23,7 @@ .\" This document is derived in part from the enet man page (enet.4) .\" distributed with 4.3BSD Unix. .\" -.Dd $Mdocdate: August 5 2024 $ +.Dd $Mdocdate: August 15 2024 $ .Dt BPF 4 .Os .Sh NAME @@ -318,6 +318,7 @@ readable. The maximum wait time that can be set is 5 minutes (300 seconds). .Pp .It Dv BIOCSETF Fa "struct bpf_program *" +.It Dv BIOCSETFNR Fa "struct bpf_program *" Sets the filter program used by the kernel to discard uninteresting packets. An array of instructions and its length are passed in using the following structure: @@ -335,9 +336,11 @@ field, while its length in units of is given by the .Fa bf_len field. -Also, the actions of +If +.Dv BIOCSETF +is used, the actions of .Dv BIOCFLUSH -are performed. +are also performed. .Pp See section .Sx FILTER MACHINE @@ -350,8 +353,6 @@ network. See .Dv BIOCSETF for a description of the filter program. -This ioctl also acts as -.Dv BIOCFLUSH . .Pp Note that the filter operates on the packet data written to the descriptor. If the diff --git a/share/man/man5/bsd.port.mk.5 b/share/man/man5/bsd.port.mk.5 index 672876fb6..075745e66 100644 --- a/share/man/man5/bsd.port.mk.5 +++ b/share/man/man5/bsd.port.mk.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bsd.port.mk.5,v 1.644 2023/11/11 10:46:37 espie Exp $ +.\" $OpenBSD: bsd.port.mk.5,v 1.646 2024/08/15 09:46:39 tb Exp $ .\" .\" Copyright (c) 2000-2008 Marc Espie .\" @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 11 2023 $ +.Dd $Mdocdate: August 15 2024 $ .Dt BSD.PORT.MK 5 .Os .Sh NAME @@ -1843,6 +1843,20 @@ package and to perform introspection and obtain .Nm Ns 's default values for variables without needing to access any specific port. +.It Ev DWZ +Command line invocation of +.Xr dwz 1 +to shrink debug information while building debug packages. +Defaults to +.Sq dwz -L 100000000 +Can be set to +.Sq \&: +to not run +.Xr dwz 1 +at all. +See +.Sx THE DEBUG_PACKAGES INFRASTRUCTURE +for details. .It Ev ECHO_MSG User settings. Used to display @@ -3136,7 +3150,7 @@ Actually lives in Set to .Sq Yes to randomize tree traversal, as used by -.Xr dbp 1 Ns 's Fl r +.Xr dpb 1 Ns 's Fl r option. Defaults to .Sq \&No Ns . @@ -3671,10 +3685,9 @@ bfd's .Xr ld 1 .Pc . .Sq ports -force the use of +forces the use of .Xr ld.lld 1 from lang/clang module. -.Pc Defaults to the appropriate value for the current architecture .Po see @@ -3961,7 +3974,7 @@ target , .Xr build-debug-info 1 will be invoked to deduce debug packing-lists from the normal packing-lists, and some extra makefile rules will be invoked to set aside the debug -information. +information, and shrink it by processing it through ${DWZ}. .Pp Then each normal package will have a "shadow" debug-* package built alongside it, with the exact same package signature, except it will also be tied closely diff --git a/sys/dev/acpi/acpisurface.c b/sys/dev/acpi/acpisurface.c index f00421060..93f72fad4 100644 --- a/sys/dev/acpi/acpisurface.c +++ b/sys/dev/acpi/acpisurface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpisurface.c,v 1.2 2022/04/06 18:59:27 naddy Exp $ */ +/* $OpenBSD: acpisurface.c,v 1.3 2024/08/15 17:30:40 deraadt Exp $ */ /* * Copyright (c) 2018 Mike Larkin * @@ -136,7 +136,7 @@ surface_hotkey(struct aml_node *node, int notify_type, void *arg) case SURFACE_POWER_BUTTON_RELEASED: DPRINTF("%s: power button released\n", __func__); acpi_addtask(sc->sc_acpi, acpi_powerdown_task, - sc->sc_acpi, 0); + sc->sc_acpi, 0); break; case SURFACE_WINDOWS_KEY_PRESSED: DPRINTF("%s: windows key pressed\n", __func__); diff --git a/sys/dev/ic/qwz.c b/sys/dev/ic/qwz.c index 9d4f5fcb6..063631bc0 100644 --- a/sys/dev/ic/qwz.c +++ b/sys/dev/ic/qwz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qwz.c,v 1.1 2024/08/14 14:40:46 patrick Exp $ */ +/* $OpenBSD: qwz.c,v 1.4 2024/08/16 00:26:54 patrick Exp $ */ /* * Copyright 2023 Stefan Sperling @@ -594,7 +594,7 @@ qwz_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, /* Keys removed implicitly when firmware station is removed. */ return; } - + /* * net80211 calls us with a NULL node when deleting group keys, * but firmware expects a MAC address in the command. @@ -1008,110 +1008,7 @@ qwz_init_wmi_config_qca6390(struct qwz_softc *sc, } void -qwz_hw_ipq8074_reo_setup(struct qwz_softc *sc) -{ - uint32_t reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; - uint32_t val; - /* Each hash entry uses three bits to map to a particular ring. */ - uint32_t ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 | - HAL_HASH_ROUTING_RING_SW2 << 3 | - HAL_HASH_ROUTING_RING_SW3 << 6 | - HAL_HASH_ROUTING_RING_SW4 << 9 | - HAL_HASH_ROUTING_RING_SW1 << 12 | - HAL_HASH_ROUTING_RING_SW2 << 15 | - HAL_HASH_ROUTING_RING_SW3 << 18 | - HAL_HASH_ROUTING_RING_SW4 << 21; - - val = sc->ops.read32(sc, reo_base + HAL_REO1_GEN_ENABLE); - - val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; - val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, - HAL_SRNG_RING_ID_REO2SW1) | - FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | - FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); - sc->ops.write32(sc, reo_base + HAL_REO1_GEN_ENABLE, val); - - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_0(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_1(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_2(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_3(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, - FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, - FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, - FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, - FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); -} - -void -qwz_init_wmi_config_ipq8074(struct qwz_softc *sc, - struct target_resource_config *config) -{ - config->num_vdevs = sc->num_radios * TARGET_NUM_VDEVS(sc); - - if (sc->num_radios == 2) { - config->num_peers = TARGET_NUM_PEERS(sc, DBS); - config->num_tids = TARGET_NUM_TIDS(sc, DBS); - } else if (sc->num_radios == 3) { - config->num_peers = TARGET_NUM_PEERS(sc, DBS_SBS); - config->num_tids = TARGET_NUM_TIDS(sc, DBS_SBS); - } else { - /* Control should not reach here */ - config->num_peers = TARGET_NUM_PEERS(sc, SINGLE); - config->num_tids = TARGET_NUM_TIDS(sc, SINGLE); - } - config->num_offload_peers = TARGET_NUM_OFFLD_PEERS; - config->num_offload_reorder_buffs = TARGET_NUM_OFFLD_REORDER_BUFFS; - config->num_peer_keys = TARGET_NUM_PEER_KEYS; - config->ast_skid_limit = TARGET_AST_SKID_LIMIT; - config->tx_chain_mask = (1 << sc->target_caps.num_rf_chains) - 1; - config->rx_chain_mask = (1 << sc->target_caps.num_rf_chains) - 1; - config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; - - if (test_bit(ATH12K_FLAG_RAW_MODE, sc->sc_flags)) - config->rx_decap_mode = TARGET_DECAP_MODE_RAW; - else - config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; - - config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; - config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; - config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; - config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; - config->num_mcast_groups = TARGET_NUM_MCAST_GROUPS; - config->num_mcast_table_elems = TARGET_NUM_MCAST_TABLE_ELEMS; - config->mcast2ucast_mode = TARGET_MCAST2UCAST_MODE; - config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; - config->num_wds_entries = TARGET_NUM_WDS_ENTRIES; - config->dma_burst_size = TARGET_DMA_BURST_SIZE; - config->rx_skip_defrag_timeout_dup_detection_check = - TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; - config->vow_config = TARGET_VOW_CONFIG; - config->gtk_offload_max_vdev = TARGET_GTK_OFFLOAD_MAX_VDEV; - config->num_msdu_desc = TARGET_NUM_MSDU_DESC; - config->beacon_tx_offload_max_vdev = sc->num_radios * TARGET_MAX_BCN_OFFLD; - config->rx_batchmode = TARGET_RX_BATCHMODE; - config->peer_map_unmap_v2_support = 1; - config->twt_ap_pdev_count = sc->num_radios; - config->twt_ap_sta_count = 1000; - config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; - config->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI; - config->ema_max_vap_cnt = sc->num_radios; - config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD; - config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt; -} - -void -qwz_hw_wcn6855_reo_setup(struct qwz_softc *sc) +qwz_hw_wcn7850_reo_setup(struct qwz_softc *sc) { uint32_t reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; uint32_t val; @@ -1130,11 +1027,14 @@ qwz_hw_wcn6855_reo_setup(struct qwz_softc *sc) FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); sc->ops.write32(sc, reo_base + HAL_REO1_GEN_ENABLE, val); - val = sc->ops.read32(sc, reo_base + HAL_REO1_MISC_CTL(sc)); - val &= ~HAL_REO1_MISC_CTL_FRAGMENT_DST_RING; - val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAGMENT_DST_RING, - HAL_SRNG_RING_ID_REO2SW1); - sc->ops.write32(sc, reo_base + HAL_REO1_MISC_CTL(sc), val); + val = sc->ops.read32(sc, reo_base + HAL_REO1_MISC_CTRL_ADDR(sc)); + val &= ~HAL_REO1_MISC_CTL_FRAG_DST_RING; + val &= ~HAL_REO1_MISC_CTL_BAR_DST_RING; + val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAG_DST_RING, + HAL_SRNG_RING_ID_REO2SW0); + val |= FIELD_PREP(HAL_REO1_MISC_CTL_BAR_DST_RING, + HAL_SRNG_RING_ID_REO2SW0); + sc->ops.write32(sc, reo_base + HAL_REO1_MISC_CTRL_ADDR(sc), val); sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_0(sc), HAL_DEFAULT_REO_TIMEOUT_USEC); @@ -1143,7 +1043,7 @@ qwz_hw_wcn6855_reo_setup(struct qwz_softc *sc) sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_2(sc), HAL_DEFAULT_REO_TIMEOUT_USEC); sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_3(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); + ATH12K_HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, ring_hash_map); @@ -1151,50 +1051,6 @@ qwz_hw_wcn6855_reo_setup(struct qwz_softc *sc) ring_hash_map); } -void -qwz_hw_ipq5018_reo_setup(struct qwz_softc *sc) -{ - uint32_t reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; - uint32_t val; - - /* Each hash entry uses three bits to map to a particular ring. */ - uint32_t ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 | - HAL_HASH_ROUTING_RING_SW2 << 4 | - HAL_HASH_ROUTING_RING_SW3 << 8 | - HAL_HASH_ROUTING_RING_SW4 << 12 | - HAL_HASH_ROUTING_RING_SW1 << 16 | - HAL_HASH_ROUTING_RING_SW2 << 20 | - HAL_HASH_ROUTING_RING_SW3 << 24 | - HAL_HASH_ROUTING_RING_SW4 << 28; - - val = sc->ops.read32(sc, reo_base + HAL_REO1_GEN_ENABLE); - - val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; - val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, - HAL_SRNG_RING_ID_REO2SW1) | - FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | - FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); - sc->ops.write32(sc, reo_base + HAL_REO1_GEN_ENABLE, val); - - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_0(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_1(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_2(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - sc->ops.write32(sc, reo_base + HAL_REO1_AGING_THRESH_IX_3(sc), - HAL_DEFAULT_REO_TIMEOUT_USEC); - - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, - ring_hash_map); - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, - ring_hash_map); - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, - ring_hash_map); - sc->ops.write32(sc, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, - ring_hash_map); -} - int qwz_hw_mac_id_to_pdev_id_ipq8074(struct ath12k_hw_params *hw, int mac_id) { @@ -1857,328 +1713,11 @@ qwz_hw_get_mac_from_pdev_id(struct qwz_softc *sc, int pdev_idx) return 0; } -const struct ath12k_hw_ops ipq8074_ops = { - .get_hw_mac_from_pdev_id = qwz_hw_ipq8074_mac_from_pdev_id, - .wmi_init_config = qwz_init_wmi_config_ipq8074, - .mac_id_to_pdev_id = qwz_hw_mac_id_to_pdev_id_ipq8074, - .mac_id_to_srng_id = qwz_hw_mac_id_to_srng_id_ipq8074, -#if notyet - .tx_mesh_enable = ath12k_hw_ipq8074_tx_mesh_enable, -#endif - .rx_desc_get_first_msdu = qwz_hw_ipq8074_rx_desc_get_first_msdu, -#if notyet - .rx_desc_get_last_msdu = ath12k_hw_ipq8074_rx_desc_get_last_msdu, -#endif - .rx_desc_get_l3_pad_bytes = qwz_hw_ipq8074_rx_desc_get_l3_pad_bytes, - .rx_desc_get_hdr_status = qwz_hw_ipq8074_rx_desc_get_hdr_status, - .rx_desc_encrypt_valid = qwz_hw_ipq8074_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = qwz_hw_ipq8074_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = qwz_hw_ipq8074_rx_desc_get_decap_type, -#ifdef notyet - .rx_desc_get_mesh_ctl = ath12k_hw_ipq8074_rx_desc_get_mesh_ctl, - .rx_desc_get_ldpc_support = ath12k_hw_ipq8074_rx_desc_get_ldpc_support, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_ipq8074_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_ipq8074_rx_desc_get_mpdu_start_seq_no, -#endif - .rx_desc_get_msdu_len = qwz_hw_ipq8074_rx_desc_get_msdu_len, -#ifdef notyet - .rx_desc_get_msdu_sgi = ath12k_hw_ipq8074_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_ipq8074_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_ipq8074_rx_desc_get_msdu_rx_bw, -#endif - .rx_desc_get_msdu_freq = qwz_hw_ipq8074_rx_desc_get_msdu_freq, -#ifdef notyet - .rx_desc_get_msdu_pkt_type = ath12k_hw_ipq8074_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_ipq8074_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_ipq8074_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_ipq8074_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_attn_end_tlv = ath12k_hw_ipq8074_rx_desc_copy_attn_end, - .rx_desc_get_mpdu_start_tag = ath12k_hw_ipq8074_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_ipq8074_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_ipq8074_rx_desc_set_msdu_len, -#endif - .rx_desc_get_attention = qwz_hw_ipq8074_rx_desc_get_attention, -#ifdef notyet - .rx_desc_get_msdu_payload = ath12k_hw_ipq8074_rx_desc_get_msdu_payload, -#endif - .reo_setup = qwz_hw_ipq8074_reo_setup, -#ifdef notyet - .mpdu_info_get_peerid = ath12k_hw_ipq8074_mpdu_info_get_peerid, - .rx_desc_mac_addr2_valid = ath12k_hw_ipq8074_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_ipq8074_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath12k_hw_ipq8074_get_tcl_ring_selector, -#endif -}; - -const struct ath12k_hw_ops ipq6018_ops = { +const struct ath12k_hw_ops wcn7850_ops = { .get_hw_mac_from_pdev_id = qwz_hw_ipq6018_mac_from_pdev_id, - .wmi_init_config = qwz_init_wmi_config_ipq8074, - .mac_id_to_pdev_id = qwz_hw_mac_id_to_pdev_id_ipq8074, - .mac_id_to_srng_id = qwz_hw_mac_id_to_srng_id_ipq8074, -#if notyet - .tx_mesh_enable = ath12k_hw_ipq8074_tx_mesh_enable, -#endif - .rx_desc_get_first_msdu = qwz_hw_ipq8074_rx_desc_get_first_msdu, -#if notyet - .rx_desc_get_last_msdu = ath12k_hw_ipq8074_rx_desc_get_last_msdu, -#endif - .rx_desc_get_l3_pad_bytes = qwz_hw_ipq8074_rx_desc_get_l3_pad_bytes, - .rx_desc_get_hdr_status = qwz_hw_ipq8074_rx_desc_get_hdr_status, - .rx_desc_encrypt_valid = qwz_hw_ipq8074_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = qwz_hw_ipq8074_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = qwz_hw_ipq8074_rx_desc_get_decap_type, -#ifdef notyet - .rx_desc_get_mesh_ctl = ath12k_hw_ipq8074_rx_desc_get_mesh_ctl, - .rx_desc_get_ldpc_support = ath12k_hw_ipq8074_rx_desc_get_ldpc_support, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_ipq8074_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_ipq8074_rx_desc_get_mpdu_start_seq_no, -#endif - .rx_desc_get_msdu_len = qwz_hw_ipq8074_rx_desc_get_msdu_len, -#ifdef notyet - .rx_desc_get_msdu_sgi = ath12k_hw_ipq8074_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_ipq8074_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_ipq8074_rx_desc_get_msdu_rx_bw, -#endif - .rx_desc_get_msdu_freq = qwz_hw_ipq8074_rx_desc_get_msdu_freq, -#ifdef notyet - .rx_desc_get_msdu_pkt_type = ath12k_hw_ipq8074_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_ipq8074_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_ipq8074_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_ipq8074_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_attn_end_tlv = ath12k_hw_ipq8074_rx_desc_copy_attn_end, - .rx_desc_get_mpdu_start_tag = ath12k_hw_ipq8074_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_ipq8074_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_ipq8074_rx_desc_set_msdu_len, -#endif - .rx_desc_get_attention = qwz_hw_ipq8074_rx_desc_get_attention, -#ifdef notyet - .rx_desc_get_msdu_payload = ath12k_hw_ipq8074_rx_desc_get_msdu_payload, -#endif - .reo_setup = qwz_hw_ipq8074_reo_setup, -#ifdef notyet - .mpdu_info_get_peerid = ath12k_hw_ipq8074_mpdu_info_get_peerid, - .rx_desc_mac_addr2_valid = ath12k_hw_ipq8074_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_ipq8074_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath12k_hw_ipq8074_get_tcl_ring_selector, -#endif -}; - -const struct ath12k_hw_ops qca6390_ops = { - .get_hw_mac_from_pdev_id = qwz_hw_ipq8074_mac_from_pdev_id, - .wmi_init_config = qwz_init_wmi_config_qca6390, .mac_id_to_pdev_id = qwz_hw_mac_id_to_pdev_id_qca6390, .mac_id_to_srng_id = qwz_hw_mac_id_to_srng_id_qca6390, -#if notyet - .tx_mesh_enable = ath12k_hw_ipq8074_tx_mesh_enable, -#endif - .rx_desc_get_first_msdu = qwz_hw_ipq8074_rx_desc_get_first_msdu, -#if notyet - .rx_desc_get_last_msdu = ath12k_hw_ipq8074_rx_desc_get_last_msdu, -#endif - .rx_desc_get_l3_pad_bytes = qwz_hw_ipq8074_rx_desc_get_l3_pad_bytes, - .rx_desc_get_hdr_status = qwz_hw_ipq8074_rx_desc_get_hdr_status, - .rx_desc_encrypt_valid = qwz_hw_ipq8074_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = qwz_hw_ipq8074_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = qwz_hw_ipq8074_rx_desc_get_decap_type, -#ifdef notyet - .rx_desc_get_mesh_ctl = ath12k_hw_ipq8074_rx_desc_get_mesh_ctl, - .rx_desc_get_ldpc_support = ath12k_hw_ipq8074_rx_desc_get_ldpc_support, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_ipq8074_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_ipq8074_rx_desc_get_mpdu_start_seq_no, -#endif - .rx_desc_get_msdu_len = qwz_hw_ipq8074_rx_desc_get_msdu_len, -#ifdef notyet - .rx_desc_get_msdu_sgi = ath12k_hw_ipq8074_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_ipq8074_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_ipq8074_rx_desc_get_msdu_rx_bw, -#endif - .rx_desc_get_msdu_freq = qwz_hw_ipq8074_rx_desc_get_msdu_freq, -#ifdef notyet - .rx_desc_get_msdu_pkt_type = ath12k_hw_ipq8074_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_ipq8074_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_ipq8074_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_ipq8074_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_attn_end_tlv = ath12k_hw_ipq8074_rx_desc_copy_attn_end, - .rx_desc_get_mpdu_start_tag = ath12k_hw_ipq8074_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_ipq8074_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_ipq8074_rx_desc_set_msdu_len, -#endif - .rx_desc_get_attention = qwz_hw_ipq8074_rx_desc_get_attention, -#ifdef notyet - .rx_desc_get_msdu_payload = ath12k_hw_ipq8074_rx_desc_get_msdu_payload, -#endif - .reo_setup = qwz_hw_ipq8074_reo_setup, -#ifdef notyet - .mpdu_info_get_peerid = ath12k_hw_ipq8074_mpdu_info_get_peerid, - .rx_desc_mac_addr2_valid = ath12k_hw_ipq8074_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_ipq8074_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath12k_hw_ipq8074_get_tcl_ring_selector, -#endif -}; - -const struct ath12k_hw_ops qcn9074_ops = { - .get_hw_mac_from_pdev_id = qwz_hw_ipq6018_mac_from_pdev_id, - .wmi_init_config = qwz_init_wmi_config_ipq8074, - .mac_id_to_pdev_id = qwz_hw_mac_id_to_pdev_id_ipq8074, - .mac_id_to_srng_id = qwz_hw_mac_id_to_srng_id_ipq8074, -#if notyet - .tx_mesh_enable = ath12k_hw_qcn9074_tx_mesh_enable, -#endif - .rx_desc_get_first_msdu = qwz_hw_qcn9074_rx_desc_get_first_msdu, -#if notyet - .rx_desc_get_last_msdu = ath12k_hw_qcn9074_rx_desc_get_last_msdu, -#endif - .rx_desc_get_l3_pad_bytes = qwz_hw_qcn9074_rx_desc_get_l3_pad_bytes, - .rx_desc_get_hdr_status = qwz_hw_qcn9074_rx_desc_get_hdr_status, - .rx_desc_encrypt_valid = qwz_hw_qcn9074_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = qwz_hw_qcn9074_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = qwz_hw_qcn9074_rx_desc_get_decap_type, -#ifdef notyet - .rx_desc_get_mesh_ctl = ath12k_hw_qcn9074_rx_desc_get_mesh_ctl, - .rx_desc_get_ldpc_support = ath12k_hw_qcn9074_rx_desc_get_ldpc_support, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9074_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no, -#endif - .rx_desc_get_msdu_len = qwz_hw_qcn9074_rx_desc_get_msdu_len, -#ifdef notyet - .rx_desc_get_msdu_sgi = ath12k_hw_qcn9074_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9074_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9074_rx_desc_get_msdu_rx_bw, -#endif - .rx_desc_get_msdu_freq = qwz_hw_qcn9074_rx_desc_get_msdu_freq, -#ifdef notyet - .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9074_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_qcn9074_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_qcn9074_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9074_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_attn_end_tlv = ath12k_hw_qcn9074_rx_desc_copy_attn_end, - .rx_desc_get_mpdu_start_tag = ath12k_hw_qcn9074_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_qcn9074_rx_desc_set_msdu_len, -#endif - .rx_desc_get_attention = qwz_hw_qcn9074_rx_desc_get_attention, -#ifdef notyet - .rx_desc_get_msdu_payload = ath12k_hw_qcn9074_rx_desc_get_msdu_payload, -#endif - .reo_setup = qwz_hw_ipq8074_reo_setup, -#ifdef notyet - .mpdu_info_get_peerid = ath12k_hw_ipq8074_mpdu_info_get_peerid, - .rx_desc_mac_addr2_valid = ath12k_hw_ipq9074_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_ipq9074_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath12k_hw_ipq8074_get_tcl_ring_selector, -#endif -}; - -const struct ath12k_hw_ops wcn6855_ops = { - .get_hw_mac_from_pdev_id = qwz_hw_ipq8074_mac_from_pdev_id, - .wmi_init_config = qwz_init_wmi_config_qca6390, - .mac_id_to_pdev_id = qwz_hw_mac_id_to_pdev_id_qca6390, - .mac_id_to_srng_id = qwz_hw_mac_id_to_srng_id_qca6390, -#if notyet - .tx_mesh_enable = ath12k_hw_wcn6855_tx_mesh_enable, -#endif - .rx_desc_get_first_msdu = qwz_hw_wcn6855_rx_desc_get_first_msdu, -#if notyet - .rx_desc_get_last_msdu = ath12k_hw_wcn6855_rx_desc_get_last_msdu, -#endif - .rx_desc_get_l3_pad_bytes = qwz_hw_wcn6855_rx_desc_get_l3_pad_bytes, - .rx_desc_get_hdr_status = qwz_hw_wcn6855_rx_desc_get_hdr_status, - .rx_desc_encrypt_valid = qwz_hw_wcn6855_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = qwz_hw_wcn6855_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = qwz_hw_wcn6855_rx_desc_get_decap_type, -#ifdef notyet - .rx_desc_get_mesh_ctl = ath12k_hw_wcn6855_rx_desc_get_mesh_ctl, - .rx_desc_get_ldpc_support = ath12k_hw_wcn6855_rx_desc_get_ldpc_support, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_wcn6855_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_wcn6855_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_wcn6855_rx_desc_get_mpdu_start_seq_no, -#endif - .rx_desc_get_msdu_len = qwz_hw_wcn6855_rx_desc_get_msdu_len, -#ifdef notyet - .rx_desc_get_msdu_sgi = ath12k_hw_wcn6855_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_wcn6855_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_wcn6855_rx_desc_get_msdu_rx_bw, -#endif - .rx_desc_get_msdu_freq = qwz_hw_wcn6855_rx_desc_get_msdu_freq, -#ifdef notyet - .rx_desc_get_msdu_pkt_type = ath12k_hw_wcn6855_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_wcn6855_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_wcn6855_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_wcn6855_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_attn_end_tlv = ath12k_hw_wcn6855_rx_desc_copy_attn_end, - .rx_desc_get_mpdu_start_tag = ath12k_hw_wcn6855_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_wcn6855_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_wcn6855_rx_desc_set_msdu_len, -#endif - .rx_desc_get_attention = qwz_hw_wcn6855_rx_desc_get_attention, -#ifdef notyet - .rx_desc_get_msdu_payload = ath12k_hw_wcn6855_rx_desc_get_msdu_payload, -#endif - .reo_setup = qwz_hw_wcn6855_reo_setup, -#ifdef notyet - .mpdu_info_get_peerid = ath12k_hw_wcn6855_mpdu_info_get_peerid, - .rx_desc_mac_addr2_valid = ath12k_hw_wcn6855_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_wcn6855_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath12k_hw_ipq8074_get_tcl_ring_selector, -#endif -}; - -const struct ath12k_hw_ops wcn6750_ops = { - .get_hw_mac_from_pdev_id = qwz_hw_ipq8074_mac_from_pdev_id, - .wmi_init_config = qwz_init_wmi_config_qca6390, - .mac_id_to_pdev_id = qwz_hw_mac_id_to_pdev_id_qca6390, - .mac_id_to_srng_id = qwz_hw_mac_id_to_srng_id_qca6390, -#if notyet - .tx_mesh_enable = ath12k_hw_qcn9074_tx_mesh_enable, -#endif - .rx_desc_get_first_msdu = qwz_hw_qcn9074_rx_desc_get_first_msdu, -#if notyet - .rx_desc_get_last_msdu = ath12k_hw_qcn9074_rx_desc_get_last_msdu, -#endif - .rx_desc_get_l3_pad_bytes = qwz_hw_qcn9074_rx_desc_get_l3_pad_bytes, - .rx_desc_get_hdr_status = qwz_hw_qcn9074_rx_desc_get_hdr_status, - .rx_desc_encrypt_valid = qwz_hw_qcn9074_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = qwz_hw_qcn9074_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = qwz_hw_qcn9074_rx_desc_get_decap_type, -#ifdef notyet - .rx_desc_get_mesh_ctl = ath12k_hw_qcn9074_rx_desc_get_mesh_ctl, - .rx_desc_get_ldpc_support = ath12k_hw_qcn9074_rx_desc_get_ldpc_support, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9074_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no, -#endif - .rx_desc_get_msdu_len = qwz_hw_qcn9074_rx_desc_get_msdu_len, -#ifdef notyet - .rx_desc_get_msdu_sgi = ath12k_hw_qcn9074_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9074_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9074_rx_desc_get_msdu_rx_bw, -#endif - .rx_desc_get_msdu_freq = qwz_hw_qcn9074_rx_desc_get_msdu_freq, -#ifdef notyet - .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9074_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_qcn9074_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_qcn9074_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9074_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_attn_end_tlv = ath12k_hw_qcn9074_rx_desc_copy_attn_end, - .rx_desc_get_mpdu_start_tag = ath12k_hw_qcn9074_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_qcn9074_rx_desc_set_msdu_len, -#endif - .rx_desc_get_attention = qwz_hw_qcn9074_rx_desc_get_attention, -#ifdef notyet - .rx_desc_get_msdu_payload = ath12k_hw_qcn9074_rx_desc_get_msdu_payload, -#endif - .reo_setup = qwz_hw_wcn6855_reo_setup, -#ifdef notyet - .mpdu_info_get_peerid = ath12k_hw_ipq8074_mpdu_info_get_peerid, - .rx_desc_mac_addr2_valid = ath12k_hw_ipq9074_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_ipq9074_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath12k_hw_wcn6750_get_tcl_ring_selector, -#endif + .reo_setup = qwz_hw_wcn7850_reo_setup, }; #define ATH12K_TX_RING_MASK_0 BIT(0) @@ -2248,6 +1787,8 @@ const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_ipq8074 = { ATH12K_HOST2RXDMA_RING_MASK_1, ATH12K_HOST2RXDMA_RING_MASK_2, }, + .tx_mon_dest = { + }, }; const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qca6390 = { @@ -2283,6 +1824,8 @@ const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qca6390 = { }, .host2rxdma = { }, + .tx_mon_dest = { + }, }; const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9074 = { @@ -2324,6 +1867,8 @@ const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9074 = { 0, 0, 0, ATH12K_HOST2RXDMA_RING_MASK_0, }, + .tx_mon_dest = { + }, }; const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn6750 = { @@ -2361,6 +1906,40 @@ const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn6750 = { }, .host2rxdma = { }, + .tx_mon_dest = { + }, +}; + +const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = { + .tx = { + ATH12K_TX_RING_MASK_0, + ATH12K_TX_RING_MASK_2, + ATH12K_TX_RING_MASK_4, + }, + .rx_mon_status = { + }, + .rx = { + 0, 0, 0, + ATH12K_RX_RING_MASK_0, + ATH12K_RX_RING_MASK_1, + ATH12K_RX_RING_MASK_2, + ATH12K_RX_RING_MASK_3, + }, + .rx_err = { + ATH12K_RX_ERR_RING_MASK_0, + }, + .rx_wbm_rel = { + ATH12K_RX_WBM_REL_RING_MASK_0, + }, + .reo_status = { + ATH12K_REO_STATUS_RING_MASK_0, + }, + .rxdma2host = { + }, + .host2rxdma = { + }, + .tx_mon_dest = { + }, }; /* Target firmware's Copy Engine configuration. */ @@ -3078,7 +2657,6 @@ const struct ce_attr qwz_host_ce_config_ipq8074[QWZ_CE_COUNT_IPQ8074] = { .src_nentries = 16, .src_sz_max = 2048, .dest_nentries = 0, - .send_cb = qwz_htc_tx_completion_handler, }, /* CE1: target->host HTT + HTC control */ @@ -3105,7 +2683,6 @@ const struct ce_attr qwz_host_ce_config_ipq8074[QWZ_CE_COUNT_IPQ8074] = { .src_nentries = 32, .src_sz_max = 2048, .dest_nentries = 0, - .send_cb = qwz_htc_tx_completion_handler, }, /* CE4: host->target HTT */ @@ -3139,7 +2716,6 @@ const struct ce_attr qwz_host_ce_config_ipq8074[QWZ_CE_COUNT_IPQ8074] = { .src_nentries = 32, .src_sz_max = 2048, .dest_nentries = 0, - .send_cb = qwz_htc_tx_completion_handler, }, /* CE8: target autonomous hif_memcpy */ @@ -3156,7 +2732,6 @@ const struct ce_attr qwz_host_ce_config_ipq8074[QWZ_CE_COUNT_IPQ8074] = { .src_nentries = 32, .src_sz_max = 2048, .dest_nentries = 0, - .send_cb = qwz_htc_tx_completion_handler, }, /* CE10: target->host HTT */ @@ -3212,7 +2787,6 @@ const struct ce_attr qwz_host_ce_config_qca6390[QWZ_CE_COUNT_QCA6390] = { .src_nentries = 32, .src_sz_max = 2048, .dest_nentries = 0, - .send_cb = qwz_htc_tx_completion_handler, }, /* CE4: host->target HTT */ @@ -3246,7 +2820,6 @@ const struct ce_attr qwz_host_ce_config_qca6390[QWZ_CE_COUNT_QCA6390] = { .src_nentries = 32, .src_sz_max = 2048, .dest_nentries = 0, - .send_cb = qwz_htc_tx_completion_handler, }, /* CE8: target autonomous hif_memcpy */ @@ -3294,7 +2867,6 @@ const struct ce_attr qwz_host_ce_config_qcn9074[QWZ_CE_COUNT_QCN9074] = { .src_nentries = 32, .src_sz_max = 2048, .dest_nentries = 0, - .send_cb = qwz_htc_tx_completion_handler, }, /* CE4: host->target HTT */ @@ -3315,25 +2887,83 @@ const struct ce_attr qwz_host_ce_config_qcn9074[QWZ_CE_COUNT_QCN9074] = { }, }; -static const struct ath12k_hw_tcl2wbm_rbm_map ath12k_hw_tcl2wbm_rbm_map_ipq8074[] = { +const struct ce_attr qwz_host_ce_config_wcn7850[QWZ_CE_COUNT_QCA6390] = { + /* CE0: host->target HTC control and raw streams */ { - .tcl_ring_num = 0, - .wbm_ring_num = 0, - .rbm_id = HAL_RX_BUF_RBM_SW0_BM, + .flags = CE_ATTR_FLAGS, + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, }, + + /* CE1: target->host HTT + HTC control */ { - .tcl_ring_num = 1, - .wbm_ring_num = 1, - .rbm_id = HAL_RX_BUF_RBM_SW1_BM, + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = qwz_htc_rx_completion_handler, }, + + /* CE2: target->host WMI */ { - .tcl_ring_num = 2, - .wbm_ring_num = 2, - .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 64, + .recv_cb = qwz_htc_rx_completion_handler, + }, + + /* CE3: host->target WMI (mac0) */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE4: host->target HTT */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 2048, + .src_sz_max = 256, + .dest_nentries = 0, + }, + + /* CE5: target->host pktlog */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE6: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE7: host->target WMI (mac1) */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE8: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, }, }; -static const struct ath12k_hw_tcl2wbm_rbm_map ath12k_hw_tcl2wbm_rbm_map_wcn6750[] = { +static const struct ath12k_hw_tcl2wbm_rbm_map ath12k_hw_tcl2wbm_rbm_map_wcn7850[] = { { .tcl_ring_num = 0, .wbm_ring_num = 0, @@ -3341,1098 +2971,140 @@ static const struct ath12k_hw_tcl2wbm_rbm_map ath12k_hw_tcl2wbm_rbm_map_wcn6750[ }, { .tcl_ring_num = 1, + .wbm_ring_num = 2, + .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + }, + { + .tcl_ring_num = 2, .wbm_ring_num = 4, .rbm_id = HAL_RX_BUF_RBM_SW4_BM, }, - { - .tcl_ring_num = 2, - .wbm_ring_num = 2, - .rbm_id = HAL_RX_BUF_RBM_SW2_BM, - }, }; - -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq8074 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, - .tcl2wbm_rbm_map = ath12k_hw_tcl2wbm_rbm_map_ipq8074, -}; - -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_qca6390 = { +static const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, - .tcl2wbm_rbm_map = ath12k_hw_tcl2wbm_rbm_map_ipq8074, -}; - -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn6750 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, - .tcl2wbm_rbm_map = ath12k_hw_tcl2wbm_rbm_map_wcn6750, + .tcl2wbm_rbm_map = ath12k_hw_tcl2wbm_rbm_map_wcn7850, + .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; static const struct ath12k_hw_params ath12k_hw_params[] = { { - .hw_rev = ATH12K_HW_IPQ8074, - .name = "ipq8074 hw2.0", + .name = "wcn7850 hw2.0", + .hw_rev = ATH12K_HW_WCN7850_HW20, .fw = { - .dir = "ipq8074-hw2.0", + .dir = "wcn7850-hw2.0", .board_size = 256 * 1024, - .cal_offset = 128 * 1024, - }, - .max_radios = 3, - .bdf_addr = 0x4B0C0000, - .hw_ops = &ipq8074_ops, - .ring_mask = &ath12k_hw_ring_mask_ipq8074, - .internal_sleep_clock = false, - .regs = &ipq8074_regs, - .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074, - .host_ce_config = qwz_host_ce_config_ipq8074, - .ce_count = QWZ_CE_COUNT_IPQ8074, - .target_ce_config = ath12k_target_ce_config_wlan_ipq8074, - .target_ce_count = 11, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_ipq8074, - .svc_to_ce_map_len = 21, - .single_pdev_only = false, - .rxdma1_enable = true, - .num_rxmda_per_pdev = 1, - .rx_mac_buf_ring = false, - .vdev_start_delay = false, - .htt_peer_map_v2 = true, -#if notyet - .spectral = { - .fft_sz = 2, - /* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes. - * so added pad size as 2 bytes to compensate the BIN size - */ - .fft_pad_sz = 2, - .summary_pad_sz = 0, - .fft_hdr_len = 16, - .max_fft_bins = 512, - .fragment_160mhz = true, - }, - - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_MESH_POINT), - .supports_monitor = true, - .full_monitor_mode = false, -#endif - .supports_shadow_regs = false, - .idle_ps = false, - .supports_sta_ps = false, - .cold_boot_calib = true, - .cbcal_restart_fw = true, - .fw_mem_mode = 0, - .num_vdevs = 16 + 1, - .num_peers = 512, - .supports_suspend = false, - .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), - .supports_regdb = false, - .fix_l1ss = true, - .credit_flow = false, - .max_tx_ring = DP_TCL_NUM_RING_MAX, - .hal_params = &ath12k_hw_hal_params_ipq8074, -#if notyet - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = true, - .supports_rssi_stats = false, -#endif - .fw_wmi_diag_event = false, - .current_cc_support = false, - .dbr_debug_support = true, - .global_reset = false, -#ifdef notyet - .bios_sar_capa = NULL, -#endif - .m3_fw_support = false, - .fixed_bdf_addr = true, - .fixed_mem_region = true, - .static_window_map = false, -#if notyet - .hybrid_bus_type = false, - .fixed_fw_mem = false, - .support_off_channel_tx = false, - .supports_multi_bssid = false, - - .sram_dump = {}, - - .tcl_ring_retry = true, -#endif - .tx_ring_size = DP_TCL_DATA_RING_SIZE, -#ifdef notyet - .smp2p_wow_exit = false, -#endif - }, - { - .hw_rev = ATH12K_HW_IPQ6018_HW10, - .name = "ipq6018 hw1.0", - .fw = { - .dir = "ipq6018-hw1.0", - .board_size = 256 * 1024, - .cal_offset = 128 * 1024, - }, - .max_radios = 2, - .bdf_addr = 0x4ABC0000, - .hw_ops = &ipq6018_ops, - .ring_mask = &ath12k_hw_ring_mask_ipq8074, - .internal_sleep_clock = false, - .regs = &ipq8074_regs, - .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074, - .host_ce_config = qwz_host_ce_config_ipq8074, - .ce_count = QWZ_CE_COUNT_IPQ8074, - .target_ce_config = ath12k_target_ce_config_wlan_ipq8074, - .target_ce_count = 11, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_ipq6018, - .svc_to_ce_map_len = 19, - .single_pdev_only = false, - .rxdma1_enable = true, - .num_rxmda_per_pdev = 1, - .rx_mac_buf_ring = false, - .vdev_start_delay = false, - .htt_peer_map_v2 = true, -#if notyet - .spectral = { - .fft_sz = 4, - .fft_pad_sz = 0, - .summary_pad_sz = 0, - .fft_hdr_len = 16, - .max_fft_bins = 512, - .fragment_160mhz = true, - }, - - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_MESH_POINT), - .supports_monitor = true, - .full_monitor_mode = false, -#endif - .supports_shadow_regs = false, - .idle_ps = false, - .supports_sta_ps = false, - .cold_boot_calib = true, - .cbcal_restart_fw = true, - .fw_mem_mode = 0, - .num_vdevs = 16 + 1, - .num_peers = 512, - .supports_suspend = false, - .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), - .supports_regdb = false, - .fix_l1ss = true, - .credit_flow = false, - .max_tx_ring = DP_TCL_NUM_RING_MAX, - .hal_params = &ath12k_hw_hal_params_ipq8074, -#if notyet - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = true, - .supports_rssi_stats = false, -#endif - .fw_wmi_diag_event = false, - .current_cc_support = false, - .dbr_debug_support = true, - .global_reset = false, -#ifdef notyet - .bios_sar_capa = NULL, -#endif - .m3_fw_support = false, - .fixed_bdf_addr = true, - .fixed_mem_region = true, - .static_window_map = false, - .hybrid_bus_type = false, - .fixed_fw_mem = false, -#if notyet - .support_off_channel_tx = false, - .supports_multi_bssid = false, - - .sram_dump = {}, - - .tcl_ring_retry = true, -#endif - .tx_ring_size = DP_TCL_DATA_RING_SIZE, -#ifdef notyet - .smp2p_wow_exit = false, -#endif - }, - { - .name = "qca6390 hw2.0", - .hw_rev = ATH12K_HW_QCA6390_HW20, - .fw = { - .dir = "qca6390-hw2.0", - .board_size = 256 * 1024, - .cal_offset = 128 * 1024, - }, - .max_radios = 3, - .bdf_addr = 0x4B0C0000, - .hw_ops = &qca6390_ops, - .ring_mask = &ath12k_hw_ring_mask_qca6390, - .internal_sleep_clock = true, - .regs = &qca6390_regs, - .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, - .host_ce_config = qwz_host_ce_config_qca6390, - .ce_count = QWZ_CE_COUNT_QCA6390, - .target_ce_config = ath12k_target_ce_config_wlan_qca6390, - .target_ce_count = 9, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qca6390, - .svc_to_ce_map_len = 14, - .single_pdev_only = true, - .rxdma1_enable = false, - .num_rxmda_per_pdev = 2, - .rx_mac_buf_ring = true, - .vdev_start_delay = true, - .htt_peer_map_v2 = false, -#if notyet - .spectral = { - .fft_sz = 0, - .fft_pad_sz = 0, - .summary_pad_sz = 0, - .fft_hdr_len = 0, - .max_fft_bins = 0, - .fragment_160mhz = false, - }, - - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP), - .supports_monitor = false, - .full_monitor_mode = false, -#endif - .supports_shadow_regs = true, - .idle_ps = true, - .supports_sta_ps = true, - .cold_boot_calib = false, - .cbcal_restart_fw = false, - .fw_mem_mode = 0, - .num_vdevs = 16 + 1, - .num_peers = 512, - .supports_suspend = true, - .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), - .supports_regdb = false, - .fix_l1ss = true, - .credit_flow = true, - .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, - .hal_params = &ath12k_hw_hal_params_qca6390, -#if notyet - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = false, - .supports_rssi_stats = true, -#endif - .fw_wmi_diag_event = true, - .current_cc_support = true, - .dbr_debug_support = false, - .global_reset = true, -#ifdef notyet - .bios_sar_capa = NULL, -#endif - .m3_fw_support = true, - .fixed_bdf_addr = false, - .fixed_mem_region = false, - .static_window_map = false, - .hybrid_bus_type = false, - .fixed_fw_mem = false, -#if notyet - .support_off_channel_tx = true, - .supports_multi_bssid = true, - - .sram_dump = { - .start = 0x01400000, - .end = 0x0171ffff, - }, - - .tcl_ring_retry = true, -#endif - .tx_ring_size = DP_TCL_DATA_RING_SIZE, -#ifdef notyet - .smp2p_wow_exit = false, -#endif - }, - { - .name = "qcn9074 hw1.0", - .hw_rev = ATH12K_HW_QCN9074_HW10, - .fw = { - .dir = "qcn9074-hw1.0", - .board_size = 256 * 1024, - .cal_offset = 128 * 1024, + .cal_offset = 256 * 1024, }, .max_radios = 1, -#if notyet - .single_pdev_only = false, - .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074, -#endif - .hw_ops = &qcn9074_ops, - .ring_mask = &ath12k_hw_ring_mask_qcn9074, - .internal_sleep_clock = false, - .regs = &qcn9074_regs, - .host_ce_config = qwz_host_ce_config_qcn9074, - .ce_count = QWZ_CE_COUNT_QCN9074, - .target_ce_config = ath12k_target_ce_config_wlan_qcn9074, - .target_ce_count = 9, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qcn9074, - .svc_to_ce_map_len = 18, - .rxdma1_enable = true, - .num_rxmda_per_pdev = 1, - .rx_mac_buf_ring = false, - .vdev_start_delay = false, - .htt_peer_map_v2 = true, -#if notyet - .spectral = { - .fft_sz = 2, - .fft_pad_sz = 0, - .summary_pad_sz = 16, - .fft_hdr_len = 24, - .max_fft_bins = 1024, - .fragment_160mhz = false, - }, - - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_MESH_POINT), - .supports_monitor = true, - .full_monitor_mode = true, -#endif - .supports_shadow_regs = false, - .idle_ps = false, - .supports_sta_ps = false, - .cold_boot_calib = false, - .cbcal_restart_fw = false, - .fw_mem_mode = 2, - .num_vdevs = 8, - .num_peers = 128, - .supports_suspend = false, - .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), - .supports_regdb = false, - .fix_l1ss = true, - .credit_flow = false, - .max_tx_ring = DP_TCL_NUM_RING_MAX, - .hal_params = &ath12k_hw_hal_params_ipq8074, -#if notyet - .supports_dynamic_smps_6ghz = true, - .alloc_cacheable_memory = true, - .supports_rssi_stats = false, -#endif - .fw_wmi_diag_event = false, - .current_cc_support = false, - .dbr_debug_support = true, - .global_reset = false, -#ifdef notyet - .bios_sar_capa = NULL, -#endif - .m3_fw_support = true, - .fixed_bdf_addr = false, - .fixed_mem_region = false, - .static_window_map = true, - .hybrid_bus_type = false, - .fixed_fw_mem = false, -#if notyet - .support_off_channel_tx = false, - .supports_multi_bssid = false, - - .sram_dump = {}, - - .tcl_ring_retry = true, -#endif - .tx_ring_size = DP_TCL_DATA_RING_SIZE, -#ifdef notyet - .smp2p_wow_exit = false, -#endif - }, - { - .name = "wcn6855 hw2.0", - .hw_rev = ATH12K_HW_WCN6855_HW20, - .fw = { - .dir = "wcn6855-hw2.0", - .board_size = 256 * 1024, - .cal_offset = 128 * 1024, - }, - .max_radios = 3, - .bdf_addr = 0x4B0C0000, - .hw_ops = &wcn6855_ops, - .ring_mask = &ath12k_hw_ring_mask_qca6390, .internal_sleep_clock = true, - .regs = &wcn6855_regs, - .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, - .host_ce_config = qwz_host_ce_config_qca6390, + .hw_ops = &wcn7850_ops, + .ring_mask = &ath12k_hw_ring_mask_wcn7850, + .regs = &wcn7850_regs, + .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, + .host_ce_config = qwz_host_ce_config_wcn7850, .ce_count = QWZ_CE_COUNT_QCA6390, .target_ce_config = ath12k_target_ce_config_wlan_qca6390, .target_ce_count = 9, .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qca6390, .svc_to_ce_map_len = 14, - .single_pdev_only = true, .rxdma1_enable = false, .num_rxmda_per_pdev = 2, - .rx_mac_buf_ring = true, - .vdev_start_delay = true, - .htt_peer_map_v2 = false, -#if notyet - .spectral = { - .fft_sz = 0, - .fft_pad_sz = 0, - .summary_pad_sz = 0, - .fft_hdr_len = 0, - .max_fft_bins = 0, - .fragment_160mhz = false, - }, - - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP), - .supports_monitor = false, - .full_monitor_mode = false, -#endif - .supports_shadow_regs = true, - .idle_ps = true, - .supports_sta_ps = true, - .cold_boot_calib = false, - .cbcal_restart_fw = false, - .fw_mem_mode = 0, - .num_vdevs = 16 + 1, - .num_peers = 512, - .supports_suspend = true, - .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), - .supports_regdb = true, - .fix_l1ss = false, - .credit_flow = true, - .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, - .hal_params = &ath12k_hw_hal_params_qca6390, -#if notyet - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = false, - .supports_rssi_stats = true, -#endif - .fw_wmi_diag_event = true, - .current_cc_support = true, - .dbr_debug_support = false, - .global_reset = true, -#ifdef notyet - .bios_sar_capa = &ath12k_hw_sar_capa_wcn6855, -#endif - .m3_fw_support = true, - .fixed_bdf_addr = false, - .fixed_mem_region = false, - .static_window_map = false, - .hybrid_bus_type = false, - .fixed_fw_mem = false, -#if notyet - .support_off_channel_tx = true, - .supports_multi_bssid = true, - - .sram_dump = { - .start = 0x01400000, - .end = 0x0177ffff, - }, - - .tcl_ring_retry = true, -#endif - .tx_ring_size = DP_TCL_DATA_RING_SIZE, -#ifdef notyet - .smp2p_wow_exit = false, -#endif - }, - { - .name = "wcn6855 hw2.1", - .hw_rev = ATH12K_HW_WCN6855_HW21, - .fw = { - .dir = "wcn6855-hw2.1", - .board_size = 256 * 1024, - .cal_offset = 128 * 1024, - }, - .max_radios = 3, - .bdf_addr = 0x4B0C0000, - .hw_ops = &wcn6855_ops, - .ring_mask = &ath12k_hw_ring_mask_qca6390, - .internal_sleep_clock = true, - .regs = &wcn6855_regs, - .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, - .host_ce_config = qwz_host_ce_config_qca6390, - .ce_count = QWZ_CE_COUNT_QCA6390, - .target_ce_config = ath12k_target_ce_config_wlan_qca6390, - .target_ce_count = 9, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qca6390, - .svc_to_ce_map_len = 14, - .single_pdev_only = true, - .rxdma1_enable = false, - .num_rxmda_per_pdev = 2, - .rx_mac_buf_ring = true, - .vdev_start_delay = true, - .htt_peer_map_v2 = false, -#if notyet - .spectral = { - .fft_sz = 0, - .fft_pad_sz = 0, - .summary_pad_sz = 0, - .fft_hdr_len = 0, - .max_fft_bins = 0, - .fragment_160mhz = false, - }, - - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP), - .supports_monitor = false, -#endif - .supports_shadow_regs = true, - .idle_ps = true, - .supports_sta_ps = true, - .cold_boot_calib = false, - .cbcal_restart_fw = false, - .fw_mem_mode = 0, - .num_vdevs = 16 + 1, - .num_peers = 512, - .supports_suspend = true, - .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), - .supports_regdb = true, - .fix_l1ss = false, - .credit_flow = true, - .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, - .hal_params = &ath12k_hw_hal_params_qca6390, -#if notyet - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = false, - .supports_rssi_stats = true, -#endif - .fw_wmi_diag_event = true, - .current_cc_support = true, - .dbr_debug_support = false, - .global_reset = true, -#ifdef notyet - .bios_sar_capa = &ath12k_hw_sar_capa_wcn6855, -#endif - .m3_fw_support = true, - .fixed_bdf_addr = false, - .fixed_mem_region = false, - .static_window_map = false, - .hybrid_bus_type = false, - .fixed_fw_mem = false, -#if notyet - .support_off_channel_tx = true, - .supports_multi_bssid = true, - - .sram_dump = { - .start = 0x01400000, - .end = 0x0177ffff, - }, - - .tcl_ring_retry = true, -#endif - .tx_ring_size = DP_TCL_DATA_RING_SIZE, -#ifdef notyet - .smp2p_wow_exit = false, -#endif - }, - { - .name = "wcn6750 hw1.0", - .hw_rev = ATH12K_HW_WCN6750_HW10, - .fw = { - .dir = "wcn6750-hw1.0", - .board_size = 256 * 1024, - .cal_offset = 128 * 1024, - }, - .max_radios = 1, - .bdf_addr = 0x4B0C0000, - .hw_ops = &wcn6750_ops, - .ring_mask = &ath12k_hw_ring_mask_wcn6750, - .internal_sleep_clock = false, - .regs = &wcn6750_regs, - .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750, - .host_ce_config = qwz_host_ce_config_qca6390, - .ce_count = QWZ_CE_COUNT_QCA6390, - .target_ce_config = ath12k_target_ce_config_wlan_qca6390, - .target_ce_count = 9, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qca6390, - .svc_to_ce_map_len = 14, - .single_pdev_only = true, - .rxdma1_enable = false, - .num_rxmda_per_pdev = 1, - .rx_mac_buf_ring = true, - .vdev_start_delay = true, - .htt_peer_map_v2 = false, -#if notyet - .spectral = { - .fft_sz = 0, - .fft_pad_sz = 0, - .summary_pad_sz = 0, - .fft_hdr_len = 0, - .max_fft_bins = 0, - .fragment_160mhz = false, - }, - - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP), - .supports_monitor = false, -#endif - .supports_shadow_regs = true, - .idle_ps = true, - .supports_sta_ps = true, - .cold_boot_calib = true, - .cbcal_restart_fw = false, - .fw_mem_mode = 0, - .num_vdevs = 16 + 1, - .num_peers = 512, - .supports_suspend = false, - .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), - .supports_regdb = true, - .fix_l1ss = false, + .num_rxdma_dst_ring = 1, .credit_flow = true, .max_tx_ring = DP_TCL_NUM_RING_MAX, - .hal_params = &ath12k_hw_hal_params_wcn6750, -#if notyet - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = false, - .supports_rssi_stats = true, -#endif - .fw_wmi_diag_event = false, - .current_cc_support = true, - .dbr_debug_support = false, - .global_reset = false, -#ifdef notyet - .bios_sar_capa = NULL, -#endif - .m3_fw_support = false, - .fixed_bdf_addr = false, - .fixed_mem_region = false, - .static_window_map = true, - .hybrid_bus_type = true, - .fixed_fw_mem = true, -#if notyet - .support_off_channel_tx = true, - .supports_multi_bssid = true, - - .sram_dump = {}, - - .tcl_ring_retry = false, -#endif - .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, -#ifdef notyet - .smp2p_wow_exit = true, -#endif + .htt_peer_map_v2 = false, + .supports_shadow_regs = true, + .fix_l1ss = false, + .hal_params = &ath12k_hw_hal_params_wcn7850, + .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | + BIT(CNSS_PCIE_PERST_NO_PULL_V01), + .tx_ring_size = DP_TCL_DATA_RING_SIZE, }, }; -const struct ath12k_hw_regs ipq8074_regs = { +const struct ath12k_hw_regs wcn7850_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_base_lsb = 0x00000510, - .hal_tcl1_ring_base_msb = 0x00000514, - .hal_tcl1_ring_id = 0x00000518, - .hal_tcl1_ring_misc = 0x00000520, - .hal_tcl1_ring_tp_addr_lsb = 0x0000052c, - .hal_tcl1_ring_tp_addr_msb = 0x00000530, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000540, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000544, - .hal_tcl1_ring_msi1_base_lsb = 0x00000558, - .hal_tcl1_ring_msi1_base_msb = 0x0000055c, - .hal_tcl1_ring_msi1_data = 0x00000560, - .hal_tcl2_ring_base_lsb = 0x00000568, - .hal_tcl_ring_base_lsb = 0x00000618, + .hal_tcl1_ring_id = 0x00000908, + .hal_tcl1_ring_misc = 0x00000910, + .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, + .hal_tcl1_ring_tp_addr_msb = 0x00000920, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .hal_tcl1_ring_msi1_base_lsb = 0x00000948, + .hal_tcl1_ring_msi1_base_msb = 0x0000094c, + .hal_tcl1_ring_msi1_data = 0x00000950, + .hal_tcl_ring_base_lsb = 0x00000b58, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000720, + .hal_tcl_status_ring_base_lsb = 0x00000d38, - /* REO2SW(x) R0 ring configuration address */ - .hal_reo1_ring_base_lsb = 0x0000029c, - .hal_reo1_ring_base_msb = 0x000002a0, - .hal_reo1_ring_id = 0x000002a4, - .hal_reo1_ring_misc = 0x000002ac, - .hal_reo1_ring_hp_addr_lsb = 0x000002b0, - .hal_reo1_ring_hp_addr_msb = 0x000002b4, - .hal_reo1_ring_producer_int_setup = 0x000002c0, - .hal_reo1_ring_msi1_base_lsb = 0x000002e4, - .hal_reo1_ring_msi1_base_msb = 0x000002e8, - .hal_reo1_ring_msi1_data = 0x000002ec, - .hal_reo2_ring_base_lsb = 0x000002f4, - .hal_reo1_aging_thresh_ix_0 = 0x00000564, - .hal_reo1_aging_thresh_ix_1 = 0x00000568, - .hal_reo1_aging_thresh_ix_2 = 0x0000056c, - .hal_reo1_aging_thresh_ix_3 = 0x00000570, + .hal_wbm_idle_ring_base_lsb = 0x00000d3c, + .hal_wbm_idle_ring_misc_addr = 0x00000d4c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, + .hal_wbm_r0_idle_list_size_addr = 0x00000244, + .hal_wbm_scattered_ring_base_lsb = 0x00000250, + .hal_wbm_scattered_ring_base_msb = 0x00000254, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, - /* REO2SW(x) R2 ring pointers (head/tail) address */ - .hal_reo1_ring_hp = 0x00003038, - .hal_reo1_ring_tp = 0x0000303c, - .hal_reo2_ring_hp = 0x00003040, - - /* REO2TCL R0 ring configuration address */ - .hal_reo_tcl_ring_base_lsb = 0x000003fc, - .hal_reo_tcl_ring_hp = 0x00003058, - - /* REO CMD ring address */ - .hal_reo_cmd_ring_base_lsb = 0x00000194, - .hal_reo_cmd_ring_hp = 0x00003020, - - /* REO status address */ - .hal_reo_status_ring_base_lsb = 0x00000504, - .hal_reo_status_hp = 0x00003070, - - /* SW2REO ring address */ - .hal_sw2reo_ring_base_lsb = 0x000001ec, - .hal_sw2reo_ring_hp = 0x00003028, - - /* WCSS relative address */ - .hal_seq_wcss_umac_ce0_src_reg = 0x00a00000, - .hal_seq_wcss_umac_ce0_dst_reg = 0x00a01000, - .hal_seq_wcss_umac_ce1_src_reg = 0x00a02000, - .hal_seq_wcss_umac_ce1_dst_reg = 0x00a03000, - - /* WBM Idle address */ - .hal_wbm_idle_link_ring_base_lsb = 0x00000860, - .hal_wbm_idle_link_ring_misc = 0x00000870, - - /* SW2WBM release address */ - .hal_wbm_release_ring_base_lsb = 0x000001d8, - - /* WBM2SW release address */ - .hal_wbm0_release_ring_base_lsb = 0x00000910, - .hal_wbm1_release_ring_base_lsb = 0x00000968, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x0, - .pcie_pcs_osc_dtct_config_base = 0x0, - - /* Shadow register area */ - .hal_shadow_base_addr = 0x0, - - /* REO misc control register, not used in IPQ8074 */ - .hal_reo1_misc_ctl = 0x0, -}; - -const struct ath12k_hw_regs qca6390_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_base_lsb = 0x00000684, - .hal_tcl1_ring_base_msb = 0x00000688, - .hal_tcl1_ring_id = 0x0000068c, - .hal_tcl1_ring_misc = 0x00000694, - .hal_tcl1_ring_tp_addr_lsb = 0x000006a0, - .hal_tcl1_ring_tp_addr_msb = 0x000006a4, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006b4, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006b8, - .hal_tcl1_ring_msi1_base_lsb = 0x000006cc, - .hal_tcl1_ring_msi1_base_msb = 0x000006d0, - .hal_tcl1_ring_msi1_data = 0x000006d4, - .hal_tcl2_ring_base_lsb = 0x000006dc, - .hal_tcl_ring_base_lsb = 0x0000078c, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000894, - - /* REO2SW(x) R0 ring configuration address */ - .hal_reo1_ring_base_lsb = 0x00000244, - .hal_reo1_ring_base_msb = 0x00000248, - .hal_reo1_ring_id = 0x0000024c, - .hal_reo1_ring_misc = 0x00000254, - .hal_reo1_ring_hp_addr_lsb = 0x00000258, - .hal_reo1_ring_hp_addr_msb = 0x0000025c, - .hal_reo1_ring_producer_int_setup = 0x00000268, - .hal_reo1_ring_msi1_base_lsb = 0x0000028c, - .hal_reo1_ring_msi1_base_msb = 0x00000290, - .hal_reo1_ring_msi1_data = 0x00000294, - .hal_reo2_ring_base_lsb = 0x0000029c, - .hal_reo1_aging_thresh_ix_0 = 0x0000050c, - .hal_reo1_aging_thresh_ix_1 = 0x00000510, - .hal_reo1_aging_thresh_ix_2 = 0x00000514, - .hal_reo1_aging_thresh_ix_3 = 0x00000518, - - /* REO2SW(x) R2 ring pointers (head/tail) address */ - .hal_reo1_ring_hp = 0x00003030, - .hal_reo1_ring_tp = 0x00003034, - .hal_reo2_ring_hp = 0x00003038, - - /* REO2TCL R0 ring configuration address */ - .hal_reo_tcl_ring_base_lsb = 0x000003a4, - .hal_reo_tcl_ring_hp = 0x00003050, - - /* REO CMD ring address */ - .hal_reo_cmd_ring_base_lsb = 0x00000194, - .hal_reo_cmd_ring_hp = 0x00003020, - - /* REO status address */ - .hal_reo_status_ring_base_lsb = 0x000004ac, - .hal_reo_status_hp = 0x00003068, - - /* SW2REO ring address */ - .hal_sw2reo_ring_base_lsb = 0x000001ec, - .hal_sw2reo_ring_hp = 0x00003028, - - /* WCSS relative address */ - .hal_seq_wcss_umac_ce0_src_reg = 0x00a00000, - .hal_seq_wcss_umac_ce0_dst_reg = 0x00a01000, - .hal_seq_wcss_umac_ce1_src_reg = 0x00a02000, - .hal_seq_wcss_umac_ce1_dst_reg = 0x00a03000, - - /* WBM Idle address */ - .hal_wbm_idle_link_ring_base_lsb = 0x00000860, - .hal_wbm_idle_link_ring_misc = 0x00000870, - - /* SW2WBM release address */ - .hal_wbm_release_ring_base_lsb = 0x000001d8, - - /* WBM2SW release address */ - .hal_wbm0_release_ring_base_lsb = 0x00000910, - .hal_wbm1_release_ring_base_lsb = 0x00000968, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, - .pcie_pcs_osc_dtct_config_base = 0x01e0c628, - - /* Shadow register area */ - .hal_shadow_base_addr = 0x000008fc, - - /* REO misc control register, not used in QCA6390 */ - .hal_reo1_misc_ctl = 0x0, -}; - -const struct ath12k_hw_regs qcn9074_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_base_lsb = 0x000004f0, - .hal_tcl1_ring_base_msb = 0x000004f4, - .hal_tcl1_ring_id = 0x000004f8, - .hal_tcl1_ring_misc = 0x00000500, - .hal_tcl1_ring_tp_addr_lsb = 0x0000050c, - .hal_tcl1_ring_tp_addr_msb = 0x00000510, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000520, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000524, - .hal_tcl1_ring_msi1_base_lsb = 0x00000538, - .hal_tcl1_ring_msi1_base_msb = 0x0000053c, - .hal_tcl1_ring_msi1_data = 0x00000540, - .hal_tcl2_ring_base_lsb = 0x00000548, - .hal_tcl_ring_base_lsb = 0x000005f8, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000700, - - /* REO2SW(x) R0 ring configuration address */ - .hal_reo1_ring_base_lsb = 0x0000029c, - .hal_reo1_ring_base_msb = 0x000002a0, - .hal_reo1_ring_id = 0x000002a4, - .hal_reo1_ring_misc = 0x000002ac, - .hal_reo1_ring_hp_addr_lsb = 0x000002b0, - .hal_reo1_ring_hp_addr_msb = 0x000002b4, - .hal_reo1_ring_producer_int_setup = 0x000002c0, - .hal_reo1_ring_msi1_base_lsb = 0x000002e4, - .hal_reo1_ring_msi1_base_msb = 0x000002e8, - .hal_reo1_ring_msi1_data = 0x000002ec, - .hal_reo2_ring_base_lsb = 0x000002f4, - .hal_reo1_aging_thresh_ix_0 = 0x00000564, - .hal_reo1_aging_thresh_ix_1 = 0x00000568, - .hal_reo1_aging_thresh_ix_2 = 0x0000056c, - .hal_reo1_aging_thresh_ix_3 = 0x00000570, - - /* REO2SW(x) R2 ring pointers (head/tail) address */ - .hal_reo1_ring_hp = 0x00003038, - .hal_reo1_ring_tp = 0x0000303c, - .hal_reo2_ring_hp = 0x00003040, - - /* REO2TCL R0 ring configuration address */ - .hal_reo_tcl_ring_base_lsb = 0x000003fc, - .hal_reo_tcl_ring_hp = 0x00003058, - - /* REO CMD ring address */ - .hal_reo_cmd_ring_base_lsb = 0x00000194, - .hal_reo_cmd_ring_hp = 0x00003020, - - /* REO status address */ - .hal_reo_status_ring_base_lsb = 0x00000504, - .hal_reo_status_hp = 0x00003070, - - /* SW2REO ring address */ - .hal_sw2reo_ring_base_lsb = 0x000001ec, - .hal_sw2reo_ring_hp = 0x00003028, - - /* WCSS relative address */ - .hal_seq_wcss_umac_ce0_src_reg = 0x01b80000, - .hal_seq_wcss_umac_ce0_dst_reg = 0x01b81000, - .hal_seq_wcss_umac_ce1_src_reg = 0x01b82000, - .hal_seq_wcss_umac_ce1_dst_reg = 0x01b83000, - - /* WBM Idle address */ - .hal_wbm_idle_link_ring_base_lsb = 0x00000874, - .hal_wbm_idle_link_ring_misc = 0x00000884, - - /* SW2WBM release address */ - .hal_wbm_release_ring_base_lsb = 0x000001ec, - - /* WBM2SW release address */ - .hal_wbm0_release_ring_base_lsb = 0x00000924, - .hal_wbm1_release_ring_base_lsb = 0x0000097c, + .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, + .hal_wbm0_release_ring_base_lsb = 0x00000e08, + .hal_wbm1_release_ring_base_lsb = 0x00000e80, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, - /* Shadow register area */ - .hal_shadow_base_addr = 0x0, + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000043c, - /* REO misc control register, not used in QCN9074 */ - .hal_reo1_misc_ctl = 0x0, -}; + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x0000055c, + .hal_reo1_misc_ctrl_addr = 0x00000b7c, + .hal_reo1_sw_cookie_cfg0 = 0x00000050, + .hal_reo1_sw_cookie_cfg1 = 0x00000054, + .hal_reo1_qdesc_lut_base0 = 0x00000058, + .hal_reo1_qdesc_lut_base1 = 0x0000005c, + .hal_reo1_ring_base_lsb = 0x000004e4, + .hal_reo1_ring_base_msb = 0x000004e8, + .hal_reo1_ring_id = 0x000004ec, + .hal_reo1_ring_misc = 0x000004f4, + .hal_reo1_ring_hp_addr_lsb = 0x000004f8, + .hal_reo1_ring_hp_addr_msb = 0x000004fc, + .hal_reo1_ring_producer_int_setup = 0x00000508, + .hal_reo1_ring_msi1_base_lsb = 0x0000052C, + .hal_reo1_ring_msi1_base_msb = 0x00000530, + .hal_reo1_ring_msi1_data = 0x00000534, + .hal_reo1_aging_thres_ix0 = 0x00000b08, + .hal_reo1_aging_thres_ix1 = 0x00000b0c, + .hal_reo1_aging_thres_ix2 = 0x00000b10, + .hal_reo1_aging_thres_ix3 = 0x00000b14, -const struct ath12k_hw_regs wcn6855_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_base_lsb = 0x00000690, - .hal_tcl1_ring_base_msb = 0x00000694, - .hal_tcl1_ring_id = 0x00000698, - .hal_tcl1_ring_misc = 0x000006a0, - .hal_tcl1_ring_tp_addr_lsb = 0x000006ac, - .hal_tcl1_ring_tp_addr_msb = 0x000006b0, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c0, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c4, - .hal_tcl1_ring_msi1_base_lsb = 0x000006d8, - .hal_tcl1_ring_msi1_base_msb = 0x000006dc, - .hal_tcl1_ring_msi1_data = 0x000006e0, - .hal_tcl2_ring_base_lsb = 0x000006e8, - .hal_tcl_ring_base_lsb = 0x00000798, + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008a4, - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x000008a0, + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000304, + .hal_sw2reo1_ring_base = 0x0000037c, - /* REO2SW(x) R0 ring configuration address */ - .hal_reo1_ring_base_lsb = 0x00000244, - .hal_reo1_ring_base_msb = 0x00000248, - .hal_reo1_ring_id = 0x0000024c, - .hal_reo1_ring_misc = 0x00000254, - .hal_reo1_ring_hp_addr_lsb = 0x00000258, - .hal_reo1_ring_hp_addr_msb = 0x0000025c, - .hal_reo1_ring_producer_int_setup = 0x00000268, - .hal_reo1_ring_msi1_base_lsb = 0x0000028c, - .hal_reo1_ring_msi1_base_msb = 0x00000290, - .hal_reo1_ring_msi1_data = 0x00000294, - .hal_reo2_ring_base_lsb = 0x0000029c, - .hal_reo1_aging_thresh_ix_0 = 0x000005bc, - .hal_reo1_aging_thresh_ix_1 = 0x000005c0, - .hal_reo1_aging_thresh_ix_2 = 0x000005c4, - .hal_reo1_aging_thresh_ix_3 = 0x000005c8, + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x0000028c, - /* REO2SW(x) R2 ring pointers (head/tail) address */ - .hal_reo1_ring_hp = 0x00003030, - .hal_reo1_ring_tp = 0x00003034, - .hal_reo2_ring_hp = 0x00003038, - - /* REO2TCL R0 ring configuration address */ - .hal_reo_tcl_ring_base_lsb = 0x00000454, - .hal_reo_tcl_ring_hp = 0x00003060, - - /* REO CMD ring address */ - .hal_reo_cmd_ring_base_lsb = 0x00000194, - .hal_reo_cmd_ring_hp = 0x00003020, - - /* REO status address */ - .hal_reo_status_ring_base_lsb = 0x0000055c, - .hal_reo_status_hp = 0x00003078, - - /* SW2REO ring address */ - .hal_sw2reo_ring_base_lsb = 0x000001ec, - .hal_sw2reo_ring_hp = 0x00003028, - - /* WCSS relative address */ - .hal_seq_wcss_umac_ce0_src_reg = 0x1b80000, - .hal_seq_wcss_umac_ce0_dst_reg = 0x1b81000, - .hal_seq_wcss_umac_ce1_src_reg = 0x1b82000, - .hal_seq_wcss_umac_ce1_dst_reg = 0x1b83000, - - /* WBM Idle address */ - .hal_wbm_idle_link_ring_base_lsb = 0x00000870, - .hal_wbm_idle_link_ring_misc = 0x00000880, - - /* SW2WBM release address */ - .hal_wbm_release_ring_base_lsb = 0x000001e8, - - /* WBM2SW release address */ - .hal_wbm0_release_ring_base_lsb = 0x00000920, - .hal_wbm1_release_ring_base_lsb = 0x00000978, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, - .pcie_pcs_osc_dtct_config_base = 0x01e0c628, - - /* Shadow register area */ - .hal_shadow_base_addr = 0x000008fc, - - /* REO misc control register, used for fragment - * destination ring config in WCN6855. - */ - .hal_reo1_misc_ctl = 0x00000630, -}; - -const struct ath12k_hw_regs wcn6750_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_base_lsb = 0x00000694, - .hal_tcl1_ring_base_msb = 0x00000698, - .hal_tcl1_ring_id = 0x0000069c, - .hal_tcl1_ring_misc = 0x000006a4, - .hal_tcl1_ring_tp_addr_lsb = 0x000006b0, - .hal_tcl1_ring_tp_addr_msb = 0x000006b4, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c4, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c8, - .hal_tcl1_ring_msi1_base_lsb = 0x000006dc, - .hal_tcl1_ring_msi1_base_msb = 0x000006e0, - .hal_tcl1_ring_msi1_data = 0x000006e4, - .hal_tcl2_ring_base_lsb = 0x000006ec, - .hal_tcl_ring_base_lsb = 0x0000079c, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x000008a4, - - /* REO2SW(x) R0 ring configuration address */ - .hal_reo1_ring_base_lsb = 0x000001ec, - .hal_reo1_ring_base_msb = 0x000001f0, - .hal_reo1_ring_id = 0x000001f4, - .hal_reo1_ring_misc = 0x000001fc, - .hal_reo1_ring_hp_addr_lsb = 0x00000200, - .hal_reo1_ring_hp_addr_msb = 0x00000204, - .hal_reo1_ring_producer_int_setup = 0x00000210, - .hal_reo1_ring_msi1_base_lsb = 0x00000234, - .hal_reo1_ring_msi1_base_msb = 0x00000238, - .hal_reo1_ring_msi1_data = 0x0000023c, - .hal_reo2_ring_base_lsb = 0x00000244, - .hal_reo1_aging_thresh_ix_0 = 0x00000564, - .hal_reo1_aging_thresh_ix_1 = 0x00000568, - .hal_reo1_aging_thresh_ix_2 = 0x0000056c, - .hal_reo1_aging_thresh_ix_3 = 0x00000570, - - /* REO2SW(x) R2 ring pointers (head/tail) address */ - .hal_reo1_ring_hp = 0x00003028, - .hal_reo1_ring_tp = 0x0000302c, - .hal_reo2_ring_hp = 0x00003030, - - /* REO2TCL R0 ring configuration address */ - .hal_reo_tcl_ring_base_lsb = 0x000003fc, - .hal_reo_tcl_ring_hp = 0x00003058, - - /* REO CMD ring address */ - .hal_reo_cmd_ring_base_lsb = 0x000000e4, - .hal_reo_cmd_ring_hp = 0x00003010, - - /* REO status address */ - .hal_reo_status_ring_base_lsb = 0x00000504, - .hal_reo_status_hp = 0x00003070, - - /* SW2REO ring address */ - .hal_sw2reo_ring_base_lsb = 0x0000013c, - .hal_sw2reo_ring_hp = 0x00003018, - - /* WCSS relative address */ - .hal_seq_wcss_umac_ce0_src_reg = 0x01b80000, - .hal_seq_wcss_umac_ce0_dst_reg = 0x01b81000, - .hal_seq_wcss_umac_ce1_src_reg = 0x01b82000, - .hal_seq_wcss_umac_ce1_dst_reg = 0x01b83000, - - /* WBM Idle address */ - .hal_wbm_idle_link_ring_base_lsb = 0x00000874, - .hal_wbm_idle_link_ring_misc = 0x00000884, - - /* SW2WBM release address */ - .hal_wbm_release_ring_base_lsb = 0x000001ec, - - /* WBM2SW release address */ - .hal_wbm0_release_ring_base_lsb = 0x00000924, - .hal_wbm1_release_ring_base_lsb = 0x0000097c, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x0, - .pcie_pcs_osc_dtct_config_base = 0x0, - - /* Shadow register area */ - .hal_shadow_base_addr = 0x00000504, - - /* REO misc control register, used for fragment - * destination ring config in WCN6750. - */ - .hal_reo1_misc_ctl = 0x000005d8, + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000a84, }; #define QWZ_SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 #define QWZ_HOST_CSTATE_BIT 0x04 #define QWZ_PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08 -#define QWZ_PLATFORM_CAP_PCIE_PME_D3COLD 0x10 static const struct qmi_elem_info qmi_response_type_v01_ei[] = { { @@ -4725,6 +3397,50 @@ static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { }, }; +static const struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01, + chip_id), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01, + num_local_links), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01, + .elem_size = sizeof(uint8_t), + .array_type = STATIC_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01, + hw_link_id), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01, + .elem_size = sizeof(uint8_t), + .array_type = STATIC_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01, + valid_mlo_link_id), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, @@ -4969,6 +3685,205 @@ static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, mem_cfg_mode), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1D, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + cal_duration_valid), + }, + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint16_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1D, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + cal_duraiton), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1E, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + platform_name_valid), + }, + { + .data_type = QMI_STRING, + .elem_len = QMI_WLANFW_MAX_PLATFORM_NAME_LEN_V01 + 1, + .elem_size = sizeof(char), + .array_type = NO_ARRAY, + .tlv_type = 0x1E, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + platform_name), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1F, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + ddr_range_valid), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLANFW_MAX_HOST_DDR_RANGE_SIZE_V01, + .elem_size = sizeof(struct qmi_wlanfw_host_ddr_range), + .array_type = STATIC_ARRAY, + .tlv_type = 0x1F, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + ddr_range), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x20, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + host_build_type_valid), + }, + { + .data_type = QMI_SIGNED_4_BYTE_ENUM, + .elem_len = 1, + .elem_size = sizeof(enum qmi_wlanfw_host_build_type), + .array_type = NO_ARRAY, + .tlv_type = 0x20, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + host_build_type), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x21, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_capable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x21, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_capable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x22, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_chip_id_valid), + }, + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint16_t), + .array_type = NO_ARRAY, + .tlv_type = 0x22, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_chip_id), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x23, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_group_id_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x23, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_group_id), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x24, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + max_mlo_peer_valid), + }, + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x24, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + max_mlo_peer), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x25, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_num_chips_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x25, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_num_chips), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x26, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_chip_info_valid), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MLO_CHIPS_V01, + .elem_size = sizeof(struct wlfw_host_mlo_chip_info_s_v01), + .array_type = STATIC_ARRAY, + .tlv_type = 0x26, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + mlo_chip_info), + .ei_array = wlfw_host_mlo_chip_info_s_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x27, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + feature_list_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .array_type = NO_ARRAY, + .tlv_type = 0x27, + .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, + feature_list), + }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -4993,6 +3908,85 @@ static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { }, }; +static const struct qmi_elem_info qmi_wlanfw_phy_cap_req_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, + num_phy_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, + num_phy), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, + board_id_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, + board_id), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x13, + .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, + single_chip_mlo_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x13, + .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, + single_chip_mlo_support), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, @@ -5246,6 +4240,32 @@ static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { }, }; +static const struct qmi_elem_info qmi_wlanfw_dev_mem_info_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct qmi_wlanfw_dev_mem_info_s_v01, + start), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct qmi_wlanfw_dev_mem_info_s_v01, + size), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, @@ -5466,6 +4486,59 @@ static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, eeprom_read_timeout), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1A, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + fw_caps_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1A, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, fw_caps), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1B, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + rd_card_chain_cap_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1B, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + rd_card_chain_cap), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x1C, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + dev_mem_info_valid), + }, + { + .data_type = QMI_STRUCT, + .elem_len = ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01, + .elem_size = sizeof(struct qmi_wlanfw_dev_mem_info_s_v01), + .array_type = STATIC_ARRAY, + .tlv_type = 0x1C, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, dev_mem), + .ei_array = qmi_wlanfw_dev_mem_info_s_v01_ei, + }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -5823,14 +4896,14 @@ static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { }, }; -static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .array_type = NO_ARRAY, .tlv_type = 0, - .offset = offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01, + .offset = offsetof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01, addr), }, { @@ -6002,28 +5075,28 @@ static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { .elem_len = 1, .elem_size = sizeof(uint8_t), .array_type = NO_ARRAY, - .tlv_type = 0x14, + .tlv_type = 0x17, .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, - shadow_reg_v2_valid), + shadow_reg_v3_valid), }, { .data_type = QMI_DATA_LEN, .elem_len = 1, .elem_size = sizeof(uint8_t), .array_type = NO_ARRAY, - .tlv_type = 0x14, + .tlv_type = 0x17, .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, - shadow_reg_v2_len), + shadow_reg_v3_len), }, { .data_type = QMI_STRUCT, - .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01, - .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01), + .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01, + .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01), .array_type = VAR_LEN_ARRAY, - .tlv_type = 0x14, + .tlv_type = 0x17, .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, - shadow_reg_v2), - .ei_array = qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei, + shadow_reg_v3), + .ei_array = qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei, }, { .data_type = QMI_EOTI, @@ -6375,7 +5448,7 @@ qwz_qmi_decode_datalen(struct qwz_softc *sc, size_t *used, uint32_t *datalen, printf("%s: bad datalen element size %u\n", sc->sc_dev.dv_xname, ei->elem_size); return -1; - + } *used = ei->elem_size; @@ -6865,6 +5938,42 @@ qwz_qmi_decode_msg(struct qwz_softc *sc, void *output, size_t output_len, return 0; } +void +qwz_qmi_recv_wlanfw_phy_cap_req_v1(struct qwz_softc *sc, struct mbuf *m, + uint16_t txn_id, uint16_t msg_len) +{ + struct qmi_wlanfw_phy_cap_resp_msg_v01 resp; + const struct qmi_elem_info *ei; + uint8_t *msg = mtod(m, uint8_t *); + + DNPRINTF(QWZ_D_QMI, "%s\n", __func__); + + ei = qmi_wlanfw_phy_cap_resp_msg_v01_ei; + if (qwz_qmi_decode_msg(sc, &resp, sizeof(resp), ei, msg, msg_len)) + return; + + DNPRINTF(QWZ_D_QMI, "%s: resp.resp.result=0x%x\n", + __func__, le16toh(resp.resp.result)); + DNPRINTF(QWZ_D_QMI, "%s: resp.resp.error=0x%x\n", + __func__, le16toh(resp.resp.error)); + DNPRINTF(QWZ_D_QMI, "%s: resp.num_phy_valid=0x%x\n", + __func__, resp.num_phy_valid); + DNPRINTF(QWZ_D_QMI, "%s: resp.num_phy=0x%x\n", + __func__, resp.num_phy); + DNPRINTF(QWZ_D_QMI, "%s: resp.board_id_valid=0x%x\n", + __func__, resp.board_id_valid); + DNPRINTF(QWZ_D_QMI, "%s: resp.board_id=0x%x\n", + __func__, le32toh(resp.board_id)); + DNPRINTF(QWZ_D_QMI, "%s: resp.single_chip_mlo_support_valid=0x%x\n", + __func__, resp.single_chip_mlo_support_valid); + DNPRINTF(QWZ_D_QMI, "%s: resp.single_chip_mlo_support=0x%x\n", + __func__, resp.single_chip_mlo_support); + + sc->qmi_resp.result = le16toh(resp.resp.result); + sc->qmi_resp.error = le16toh(resp.resp.error); + wakeup(&sc->qmi_resp); +} + void qwz_qmi_recv_wlanfw_ind_register_req_v1(struct qwz_softc *sc, struct mbuf *m, uint16_t txn_id, uint16_t msg_len) @@ -6946,6 +6055,7 @@ qwz_qmi_recv_wlanfw_cap_resp_v1(struct qwz_softc *sc, struct mbuf *m, struct qmi_wlanfw_cap_resp_msg_v01 resp; const struct qmi_elem_info *ei; uint8_t *msg = mtod(m, uint8_t *); + int i; DNPRINTF(QWZ_D_QMI, "%s\n", __func__); @@ -6979,6 +6089,20 @@ qwz_qmi_recv_wlanfw_cap_resp_v1(struct qwz_softc *sc, struct mbuf *m, strlcpy(sc->qmi_target.fw_build_id, resp.fw_build_id, sizeof(sc->qmi_target.fw_build_id)); + if (resp.dev_mem_info_valid) { + for (i = 0; i < ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01; i++) { + sc->qmi_dev_mem[i].start = + resp.dev_mem[i].start; + sc->qmi_dev_mem[i].size = + resp.dev_mem[i].size; + DNPRINTF(QWZ_D_QMI, + "%s: devmem [%d] start 0x%llx size %llu\n", + sc->sc_dev.dv_xname, i, + sc->qmi_dev_mem[i].start, + sc->qmi_dev_mem[i].size); + } + } + if (resp.eeprom_read_timeout_valid) { sc->qmi_target.eeprom_caldata = resp.eeprom_read_timeout; DNPRINTF(QWZ_D_QMI, @@ -7130,6 +6254,9 @@ qwz_qmi_recv_response(struct qwz_softc *sc, struct mbuf *m, uint16_t txn_id, uint16_t msg_id, uint16_t msg_len) { switch (msg_id) { + case QMI_WLANFW_PHY_CAP_REQ_V01: + qwz_qmi_recv_wlanfw_phy_cap_req_v1(sc, m, txn_id, msg_len); + break; case QMI_WLANFW_IND_REGISTER_REQ_V01: qwz_qmi_recv_wlanfw_ind_register_req_v1(sc, m, txn_id, msg_len); break; @@ -7207,9 +6334,9 @@ qwz_qmi_recv_indication(struct qwz_softc *sc, struct mbuf *m, sc->fwmem_ready = 1; wakeup(&sc->fwmem_ready); break; - case QMI_WLFW_FW_INIT_DONE_IND_V01: - sc->fw_init_done = 1; - wakeup(&sc->fw_init_done); + case QMI_WLFW_FW_READY_IND_V01: + sc->fw_ready = 1; + wakeup(&sc->fw_ready); break; default: printf("%s: unhandled QMI indication 0x%x\n", @@ -7931,7 +7058,7 @@ qwz_qmi_send_request(struct qwz_softc *sc, uint16_t msg_id, size_t msg_len, hdr.src_port_id = htole32(0x4000); /* TODO make human-readable */ hdr.dst_node_id = htole32(0x07); /* TODO make human-readable */ hdr.dst_port_id = htole32(0x01); /* TODO make human-readable */ - hdr.size = htole32(encoded_len); + hdr.size = htole32(encoded_len); err = m_copyback(m, 0, sizeof(hdr), &hdr, M_NOWAIT); if (err) @@ -7957,6 +7084,39 @@ done: return err; } +int +qwz_qmi_phy_cap_send(struct qwz_softc *sc) +{ + struct qmi_wlanfw_phy_cap_req_msg_v01 req; + int ret; + + memset(&req, 0, sizeof(req)); + + DNPRINTF(QWZ_D_QMI, "%s: qmi phy cap request\n", __func__); + + ret = qwz_qmi_send_request(sc, QMI_WLANFW_PHY_CAP_REQ_V01, + QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_phy_cap_req_msg_v01_ei, + &req, sizeof(req)); + if (ret) { + printf("%s: failed to send phy cap request: %d\n", + sc->sc_dev.dv_xname, ret); + return -1; + } + + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { + ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzphycap", + SEC_TO_NSEC(1)); + if (ret) { + /* Not having a phy cap is OK */ + return 0; + } + } + + return 0; +} + int qwz_qmi_fw_ind_register_send(struct qwz_softc *sc) { @@ -7969,6 +7129,10 @@ qwz_qmi_fw_ind_register_send(struct qwz_softc *sc) req.client_id = QMI_WLANFW_CLIENT_ID; req.fw_ready_enable_valid = 1; req.fw_ready_enable = 1; + req.request_mem_enable_valid = 1; + req.request_mem_enable = 1; + req.fw_mem_ready_enable_valid = 1; + req.fw_mem_ready_enable = 1; req.cal_done_enable_valid = 1; req.cal_done_enable = 1; req.fw_init_done_enable_valid = 1; @@ -7977,17 +7141,6 @@ qwz_qmi_fw_ind_register_send(struct qwz_softc *sc) req.pin_connect_result_enable_valid = 0; req.pin_connect_result_enable = 0; - /* - * WCN6750 doesn't request for DDR memory via QMI, - * instead it uses a fixed 12MB reserved memory region in DDR. - */ - if (!sc->hw_params.fixed_fw_mem) { - req.request_mem_enable_valid = 1; - req.request_mem_enable = 1; - req.fw_mem_ready_enable_valid = 1; - req.fw_mem_ready_enable = 1; - } - DNPRINTF(QWZ_D_QMI, "%s: qmi indication register request\n", __func__); ret = qwz_qmi_send_request(sc, QMI_WLANFW_IND_REGISTER_REQ_V01, @@ -8000,7 +7153,7 @@ qwz_qmi_fw_ind_register_send(struct qwz_softc *sc) return -1; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzfwind", SEC_TO_NSEC(1)); @@ -8023,26 +7176,24 @@ qwz_qmi_host_cap_send(struct qwz_softc *sc) memset(&req, 0, sizeof(req)); req.num_clients_valid = 1; req.num_clients = 1; - req.mem_cfg_mode = sc->hw_params.fw_mem_mode; + req.mem_cfg_mode = ATH12K_QMI_TARGET_MEM_MODE_DEFAULT; req.mem_cfg_mode_valid = 1; req.bdf_support_valid = 1; req.bdf_support = 1; - if (sc->hw_params.m3_fw_support) { - req.m3_support_valid = 1; - req.m3_support = 1; - req.m3_cache_support_valid = 1; - req.m3_cache_support = 1; - } else { - req.m3_support_valid = 0; - req.m3_support = 0; - req.m3_cache_support_valid = 0; - req.m3_cache_support = 0; - } + req.m3_support_valid = 1; + req.m3_support = 1; + req.m3_cache_support_valid = 1; + req.m3_cache_support = 1; req.cal_done_valid = 1; req.cal_done = sc->qmi_cal_done; + if (sc->hw_params.qmi_cnss_feature_bitmap) { + req.feature_list_valid = 1; + req.feature_list = sc->hw_params.qmi_cnss_feature_bitmap; + } + if (sc->hw_params.internal_sleep_clock) { req.nm_modem_valid = 1; @@ -8055,12 +7206,8 @@ qwz_qmi_host_cap_send(struct qwz_softc *sc) * clock. */ req.nm_modem |= QWZ_SLEEP_CLOCK_SELECT_INTERNAL_BIT; - } - - if (sc->hw_params.global_reset) req.nm_modem |= QWZ_PLATFORM_CAP_PCIE_GLOBAL_RESET; - - req.nm_modem |= QWZ_PLATFORM_CAP_PCIE_PME_D3COLD; + } DNPRINTF(QWZ_D_QMI, "%s: qmi host cap request\n", __func__); @@ -8074,7 +7221,7 @@ qwz_qmi_host_cap_send(struct qwz_softc *sc) return -1; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzfwhcap", SEC_TO_NSEC(1)); @@ -8151,7 +7298,7 @@ qwz_qmi_mem_seg_send(struct qwz_softc *sc) sc->sc_dev.dv_xname); mem_seg_len = 0; } else if (sc->fwmem == NULL || QWZ_DMA_LEN(sc->fwmem) < total_size) { - if (sc->fwmem != NULL) + if (sc->fwmem != NULL) qwz_dmamem_free(sc->sc_dmat, sc->fwmem); sc->fwmem = qwz_dmamem_alloc(sc->sc_dmat, total_size, 65536); if (sc->fwmem == NULL) { @@ -8202,7 +7349,7 @@ qwz_qmi_mem_seg_send(struct qwz_softc *sc) sc->qmi_resp.result = QMI_RESULT_SUCCESS_V01; } else { expected_result = QMI_RESULT_SUCCESS_V01; - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; } while (sc->qmi_resp.result != expected_result) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzfwrespmem", @@ -8219,15 +7366,13 @@ qwz_qmi_mem_seg_send(struct qwz_softc *sc) return EBUSY; /* retry */ } - if (!sc->hw_params.fixed_fw_mem) { - while (!sc->fwmem_ready) { - ret = tsleep_nsec(&sc->fwmem_ready, 0, "qwzfwrdy", - SEC_TO_NSEC(10)); - if (ret) { - printf("%s: fw memory ready timeout\n", - sc->sc_dev.dv_xname); - return -1; - } + while (!sc->fwmem_ready) { + ret = tsleep_nsec(&sc->fwmem_ready, 0, "qwzfwrdy", + SEC_TO_NSEC(10)); + if (ret) { + printf("%s: fw memory ready timeout\n", + sc->sc_dev.dv_xname); + return -1; } } @@ -8246,7 +7391,7 @@ qwz_core_check_dt(struct qwz_softc *sc) #ifdef __HAVE_FDT if (sc->sc_node == 0) return 0; - + OF_getprop(sc->sc_node, "qcom,ath12k-calibration-variant", sc->qmi_target.bdf_ext, sizeof(sc->qmi_target.bdf_ext) - 1); #endif @@ -8274,7 +7419,7 @@ qwz_qmi_request_target_cap(struct qwz_softc *sc) goto out; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzfwcap", SEC_TO_NSEC(1)); @@ -8311,17 +7456,6 @@ out: return ret; } -int -qwz_qmi_request_device_info(struct qwz_softc *sc) -{ - /* device info message req is only sent for hybrid bus devices */ - if (!sc->hw_params.hybrid_bus_type) - return 0; - - /* TODO */ - return -1; -} - int _qwz_core_create_board_name(struct qwz_softc *sc, char *name, size_t name_len, int with_variant, int bus_type_mode) @@ -8637,22 +7771,6 @@ qwz_qmi_load_file_target_mem(struct qwz_softc *sc, const u_char *data, return ENOMEM; } - if (sc->hw_params.fixed_bdf_addr) { -#ifdef notyet - bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size); - if (!bdf_addr) { - ath12k_warn(ab, "qmi ioremap error for bdf_addr\n"); - ret = -EIO; - goto err_free_req; - } -#else - printf("%s: fixed bdf address not yet supported\n", - sc->sc_dev.dv_xname); - ret = EIO; - goto err_free_req; -#endif - } - while (remaining) { req->valid = 1; req->file_id_valid = 1; @@ -8673,22 +7791,13 @@ qwz_qmi_load_file_target_mem(struct qwz_softc *sc, const u_char *data, req->end = 1; } - if (sc->hw_params.fixed_bdf_addr || - type == ATH12K_QMI_FILE_TYPE_EEPROM) { + if (type == ATH12K_QMI_FILE_TYPE_EEPROM) { req->data_valid = 0; req->end = 1; req->data_len = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE; } else { memcpy(req->data, p, req->data_len); } -#ifdef notyet - if (ab->hw_params.fixed_bdf_addr) { - if (type == ATH12K_QMI_FILE_TYPE_CALDATA) - bdf_addr += ab->hw_params.fw.cal_offset; - - memcpy_toio(bdf_addr, p, len); - } -#endif DPRINTF("%s: bdf download req fixed addr type %d\n", __func__, type); @@ -8700,22 +7809,21 @@ qwz_qmi_load_file_target_mem(struct qwz_softc *sc, const u_char *data, if (ret) { printf("%s: failed to send bdf download request\n", sc->sc_dev.dv_xname); - goto err_iounmap; + goto err_free_req; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzbdf", SEC_TO_NSEC(1)); if (ret) { printf("%s: bdf download request timeout\n", sc->sc_dev.dv_xname); - goto err_iounmap; + goto err_free_req; } } - if (sc->hw_params.fixed_bdf_addr || - type == ATH12K_QMI_FILE_TYPE_EEPROM) { + if (type == ATH12K_QMI_FILE_TYPE_EEPROM) { remaining = 0; } else { remaining -= req->data_len; @@ -8726,11 +7834,6 @@ qwz_qmi_load_file_target_mem(struct qwz_softc *sc, const u_char *data, } } -err_iounmap: -#ifdef notyet - if (ab->hw_params.fixed_bdf_addr) - iounmap(bdf_addr); -#endif err_free_req: free(req, M_DEVBUF, sizeof(*req)); @@ -8752,23 +7855,22 @@ qwz_qmi_load_bdf_qmi(struct qwz_softc *sc, int regdb) const uint8_t *tmp; uint32_t file_type; #endif - int fw_idx = regdb ? QWZ_FW_REGDB : QWZ_FW_BOARD; - if (sc->fw_img[fw_idx].data) { - boardfw = sc->fw_img[fw_idx].data; - boardfw_len = sc->fw_img[fw_idx].size; + if (sc->fw_img[QWZ_FW_BOARD].data) { + boardfw = sc->fw_img[QWZ_FW_BOARD].data; + boardfw_len = sc->fw_img[QWZ_FW_BOARD].size; } else { ret = qwz_core_fetch_bdf(sc, &data, &len, &boardfw, &boardfw_len, - regdb ? ATH12K_REGDB_FILE : ATH12K_BOARD_API2_FILE); + ATH12K_BOARD_API2_FILE); if (ret) return ret; - sc->fw_img[fw_idx].data = malloc(boardfw_len, M_DEVBUF, + sc->fw_img[QWZ_FW_BOARD].data = malloc(boardfw_len, M_DEVBUF, M_NOWAIT); - if (sc->fw_img[fw_idx].data) { - memcpy(sc->fw_img[fw_idx].data, boardfw, boardfw_len); - sc->fw_img[fw_idx].size = boardfw_len; + if (sc->fw_img[QWZ_FW_BOARD].data) { + memcpy(sc->fw_img[QWZ_FW_BOARD].data, boardfw, boardfw_len); + sc->fw_img[QWZ_FW_BOARD].size = boardfw_len; } } @@ -8861,16 +7963,13 @@ qwz_qmi_event_load_bdf(struct qwz_softc *sc) return ret; } - ret = qwz_qmi_request_device_info(sc); + ret = qwz_qmi_load_bdf_qmi(sc, 1); if (ret < 0) { - printf("%s: failed to request qmi device info: %d\n", + printf("%s: failed to load regdb file: %d\n", sc->sc_dev.dv_xname, ret); return ret; } - if (sc->hw_params.supports_regdb) - qwz_qmi_load_bdf_qmi(sc, 1); - ret = qwz_qmi_load_bdf_qmi(sc, 0); if (ret < 0) { printf("%s: failed to load board data file: %d\n", @@ -8935,23 +8034,18 @@ qwz_qmi_wlanfw_m3_info_send(struct qwz_softc *sc) memset(&req, 0, sizeof(req)); - if (sc->hw_params.m3_fw_support) { - ret = qwz_qmi_m3_load(sc); - if (ret) { - printf("%s: failed to load m3 firmware: %d", - sc->sc_dev.dv_xname, ret); - return ret; - } - - paddr = QWZ_DMA_DVA(sc->m3_mem); - size = QWZ_DMA_LEN(sc->m3_mem); - req.addr = htole64(paddr); - req.size = htole32(size); - } else { - req.addr = 0; - req.size = 0; + ret = qwz_qmi_m3_load(sc); + if (ret) { + printf("%s: failed to load m3 firmware: %d", + sc->sc_dev.dv_xname, ret); + return ret; } + paddr = QWZ_DMA_DVA(sc->m3_mem); + size = QWZ_DMA_LEN(sc->m3_mem); + req.addr = htole64(paddr); + req.size = htole32(size); + ret = qwz_qmi_send_request(sc, QMI_WLANFW_M3_INFO_REQ_V01, QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN, qmi_wlanfw_m3_info_req_msg_v01_ei, &req, sizeof(req)); @@ -8961,7 +8055,7 @@ qwz_qmi_wlanfw_m3_info_send(struct qwz_softc *sc) return ret; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzfwm3", SEC_TO_NSEC(1)); @@ -9017,7 +8111,7 @@ qwz_hal_srng_dst_get_next_entry(struct qwz_softc *sc, struct hal_srng *srng) srng->u.dst_ring.tp += srng->entry_size; - /* wrap around to start of ring*/ + /* wrap around to start of ring */ if (srng->u.dst_ring.tp == srng->ring_size) srng->u.dst_ring.tp = 0; #ifdef notyet @@ -9132,6 +8226,9 @@ qwz_dp_srng_calculate_msi_group(struct qwz_softc *sc, enum hal_ring_type type, case HAL_RXDMA_MONITOR_DST: grp_mask = &sc->hw_params.ring_mask->rx_mon_status[0]; break; + case HAL_TX_MONITOR_DST: + grp_mask = &sc->hw_params.ring_mask->tx_mon_dest[0]; + break; case HAL_RXDMA_DST: grp_mask = &sc->hw_params.ring_mask->rxdma2host[0]; break; @@ -9260,6 +8357,12 @@ qwz_dp_srng_setup(struct qwz_softc *sc, struct dp_srng *ring, params.intr_batch_cntr_thres_entries = 0; params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX; break; + case HAL_TX_MONITOR_DST: + params.low_threshold = DP_TX_MONITOR_BUF_SIZE_MAX >> 3; + params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN; + params.intr_batch_cntr_thres_entries = 0; + params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX; + break; case HAL_WBM2SW_RELEASE: if (ring_num < 3) { params.intr_batch_cntr_thres_entries = @@ -9456,6 +8559,7 @@ qwz_hal_setup_link_idle_list(struct qwz_softc *sc, struct ath12k_buffer_addr *link_addr; int i; uint32_t reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; + uint32_t val; link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE; @@ -9472,19 +8576,19 @@ qwz_hal_setup_link_idle_list(struct qwz_softc *sc, } sc->ops.write32(sc, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR, + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(sc), FIELD_PREP(HAL_WBM_SCATTER_BUFFER_SIZE, reg_scatter_buf_sz) | FIELD_PREP(HAL_WBM_LINK_DESC_IDLE_LIST_MODE, 0x1)); sc->ops.write32(sc, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR, + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(sc), FIELD_PREP(HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST, reg_scatter_buf_sz * nsbufs)); sc->ops.write32(sc, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_RING_BASE_LSB, + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_RING_BASE_LSB(sc), FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK)); sc->ops.write32(sc, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_MSB, + HAL_WBM_SCATTERED_RING_BASE_MSB(sc), FIELD_PREP(HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32, (uint64_t)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT) | FIELD_PREP(HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG, @@ -9493,35 +8597,37 @@ qwz_hal_setup_link_idle_list(struct qwz_softc *sc, /* Setup head and tail pointers for the idle list */ sc->ops.write32(sc, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0, + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(sc), FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[nsbufs - 1].paddr)); sc->ops.write32(sc, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1, + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(sc), FIELD_PREP(HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32, ((uint64_t)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT)) | FIELD_PREP(HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1, (end_offset >> 2))); sc->ops.write32(sc, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0, + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(sc), FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[0].paddr)); sc->ops.write32(sc, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0, + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(sc), FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[0].paddr)); sc->ops.write32(sc, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1, + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(sc), FIELD_PREP(HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32, ((uint64_t)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT)) | FIELD_PREP(HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1, 0)); sc->ops.write32(sc, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR, + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(sc), 2 * tot_link_desc); /* Enable the SRNG */ + val = HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE; + val |= HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE; sc->ops.write32(sc, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_MISC_ADDR(sc), - 0x40); + val); } void @@ -9570,6 +8676,7 @@ qwz_dp_scatter_idle_link_desc_setup(struct qwz_softc *sc, int size, int i; int ret = 0; uint32_t end_offset; + uint32_t cookie; n_entries_per_buf = HAL_WBM_IDLE_SCATTER_BUF_SIZE / qwz_hal_srng_get_entrysize(sc, HAL_WBM_IDLE_LINK); @@ -9598,7 +8705,8 @@ qwz_dp_scatter_idle_link_desc_setup(struct qwz_softc *sc, int size, n_entries = DP_LINK_DESC_ALLOC_SIZE_THRESH / HAL_LINK_DESC_SIZE; paddr = link_desc_banks[i].paddr; while (n_entries) { - qwz_hal_set_link_desc_addr(scatter_buf, i, paddr); + cookie = DP_LINK_DESC_COOKIE_SET(n_entries, i); + qwz_hal_set_link_desc_addr(scatter_buf, cookie, paddr); n_entries--; paddr += HAL_LINK_DESC_SIZE; if (rem_entries) { @@ -9825,7 +8933,7 @@ qwz_dp_shadow_timer_handler(void *arg) #endif s = splnet(); - /* + /* * Update HP if there were no TX operations during the timeout interval, * and stop the timer. Timer will be restarted if more TX happens. */ @@ -9859,7 +8967,6 @@ qwz_dp_srng_common_cleanup(struct qwz_softc *sc) struct qwz_dp *dp = &sc->dp; int i; - qwz_dp_stop_shadow_timers(sc); qwz_dp_srng_cleanup(sc, &dp->wbm_desc_rel_ring); qwz_dp_srng_cleanup(sc, &dp->tcl_cmd_ring); qwz_dp_srng_cleanup(sc, &dp->tcl_status_ring); @@ -10272,7 +9379,6 @@ qwz_hal_reo_cmd_send(struct qwz_softc *sc, struct hal_srng *srng, break; } - qwz_dp_shadow_start_timer(sc, srng, &sc->dp.reo_cmd_timer); out: qwz_hal_srng_access_end(sc, srng); #ifdef notyet @@ -10337,10 +9443,6 @@ qwz_dp_srng_common_setup(struct qwz_softc *sc) srng = &sc->hal.srng_list[dp->tx_ring[i].tcl_data_ring.ring_id]; qwz_hal_tx_init_data_ring(sc, srng); - - qwz_dp_shadow_init_timer(sc, &dp->tx_ring_timer[i], - ATH12K_SHADOW_DP_TIMER_INTERVAL, - dp->tx_ring[i].tcl_data_ring.ring_id); } ret = qwz_dp_srng_setup(sc, &dp->reo_reinject_ring, HAL_REO_REINJECT, @@ -10378,9 +9480,6 @@ qwz_dp_srng_common_setup(struct qwz_softc *sc) srng = &sc->hal.srng_list[dp->reo_cmd_ring.ring_id]; qwz_hal_reo_init_cmd_ring(sc, srng); - qwz_dp_shadow_init_timer(sc, &dp->reo_cmd_timer, - ATH12K_SHADOW_CTRL_TIMER_INTERVAL, dp->reo_cmd_ring.ring_id); - ret = qwz_dp_srng_setup(sc, &dp->reo_status_ring, HAL_REO_STATUS, 0, 0, DP_REO_STATUS_RING_SIZE); if (ret) { @@ -10460,6 +9559,313 @@ qwz_dp_tx_ring_alloc_tx_data(struct qwz_softc *sc, struct dp_tx_ring *tx_ring) return 0; } +enum ath12k_dp_desc_type { + ATH12K_DP_TX_DESC, + ATH12K_DP_RX_DESC, +}; + +int +qwz_dp_cmem_init(struct qwz_softc *sc, struct qwz_dp *dp, + enum ath12k_dp_desc_type type) +{ + uint32_t cmem_base; + int i, start, end; + + cmem_base = sc->qmi_dev_mem[ATH12K_QMI_DEVMEM_CMEM_INDEX].start; + + switch (type) { + case ATH12K_DP_TX_DESC: + start = ATH12K_TX_SPT_PAGE_OFFSET; + end = start + ATH12K_NUM_TX_SPT_PAGES; + break; + case ATH12K_DP_RX_DESC: + start = ATH12K_RX_SPT_PAGE_OFFSET; + end = start + ATH12K_NUM_RX_SPT_PAGES; + break; + default: + printf("%s: invalid descriptor type %d in cmem init\n", + sc->sc_dev.dv_xname, type); + return EINVAL; + } + + /* Write to PPT in CMEM */ + for (i = start; i < end; i++) + sc->ops.write32(sc, cmem_base + ATH12K_PPT_ADDR_OFFSET(i), + QWZ_DMA_DVA(dp->spt_info[i].mem) >> ATH12K_SPT_4K_ALIGN_OFFSET); + + return 0; +} + +uint32_t qwz_dp_cc_cookie_gen(uint16_t ppt_idx, uint16_t spt_idx) +{ + return (uint32_t)ppt_idx << ATH12K_CC_PPT_SHIFT | spt_idx; +} + +void *ath12k_dp_cc_get_desc_addr_ptr(struct qwz_softc *sc, + uint16_t ppt_idx, uint16_t spt_idx) +{ + struct qwz_dp *dp = &sc->dp; + + return QWZ_DMA_KVA(dp->spt_info[ppt_idx].mem) + spt_idx; +} + +int +qwz_dp_cc_desc_init(struct qwz_softc *sc) +{ + struct qwz_dp *dp = &sc->dp; + struct ath12k_rx_desc_info *rx_descs, **rx_desc_addr; + struct ath12k_tx_desc_info *tx_descs, **tx_desc_addr; + uint32_t i, j, pool_id, tx_spt_page; + uint32_t ppt_idx; + +#ifdef notyet + spin_lock_bh(&dp->rx_desc_lock); +#endif + + /* First ATH12K_NUM_RX_SPT_PAGES of allocated SPT pages are used for RX */ + for (i = 0; i < ATH12K_NUM_RX_SPT_PAGES; i++) { + rx_descs = mallocarray(ATH12K_MAX_SPT_ENTRIES, sizeof(*rx_descs), + M_DEVBUF, M_NOWAIT | M_ZERO); + + if (!rx_descs) { +#ifdef notyet + spin_unlock_bh(&dp->rx_desc_lock); +#endif + return ENOMEM; + } + + ppt_idx = ATH12K_RX_SPT_PAGE_OFFSET + i; + dp->spt_info->rxbaddr[i] = &rx_descs[0]; + + for (j = 0; j < ATH12K_MAX_SPT_ENTRIES; j++) { + rx_descs[j].cookie = qwz_dp_cc_cookie_gen(ppt_idx, j); + rx_descs[j].magic = ATH12K_DP_RX_DESC_MAGIC; + TAILQ_INSERT_TAIL(&dp->rx_desc_free_list, + &rx_descs[j], entry); + + /* Update descriptor VA in SPT */ + rx_desc_addr = ath12k_dp_cc_get_desc_addr_ptr(sc, ppt_idx, j); + *rx_desc_addr = &rx_descs[j]; + } + } + +#ifdef notyet + spin_unlock_bh(&dp->rx_desc_lock); +#endif + + for (pool_id = 0; pool_id < ATH12K_HW_MAX_QUEUES; pool_id++) { +#ifdef notyet + spin_lock_bh(&dp->tx_desc_lock[pool_id]); +#endif + for (i = 0; i < ATH12K_TX_SPT_PAGES_PER_POOL; i++) { + tx_descs = mallocarray(ATH12K_MAX_SPT_ENTRIES, sizeof(*tx_descs), + M_DEVBUF, M_NOWAIT | M_ZERO); + + if (!tx_descs) { +#ifdef notyet + spin_unlock_bh(&dp->tx_desc_lock[pool_id]); +#endif + /* Caller takes care of TX pending and RX desc cleanup */ + return ENOMEM; + } + + tx_spt_page = i + pool_id * ATH12K_TX_SPT_PAGES_PER_POOL; + ppt_idx = ATH12K_TX_SPT_PAGE_OFFSET + tx_spt_page; + + dp->spt_info->txbaddr[tx_spt_page] = &tx_descs[0]; + + for (j = 0; j < ATH12K_MAX_SPT_ENTRIES; j++) { + tx_descs[j].desc_id = qwz_dp_cc_cookie_gen(ppt_idx, j); + tx_descs[j].pool_id = pool_id; + TAILQ_INSERT_TAIL(&dp->tx_desc_free_list[pool_id], + &tx_descs[j], entry); + + /* Update descriptor VA in SPT */ + tx_desc_addr = + ath12k_dp_cc_get_desc_addr_ptr(sc, ppt_idx, j); + *tx_desc_addr = &tx_descs[j]; + } + } +#ifdef notyet + spin_unlock_bh(&dp->tx_desc_lock[pool_id]); +#endif + } + return 0; +} + +void +qwz_dp_cc_cleanup(struct qwz_softc *sc) +{ + // FIXME +} + +int +qwz_dp_cc_init(struct qwz_softc *sc) +{ + struct qwz_dp *dp = &sc->dp; + int i, ret = 0; + + TAILQ_INIT(&dp->rx_desc_free_list); +#ifdef notyet + spin_lock_init(&dp->rx_desc_lock); +#endif + + for (i = 0; i < ATH12K_HW_MAX_QUEUES; i++) { + TAILQ_INIT(&dp->tx_desc_free_list[i]); + TAILQ_INIT(&dp->tx_desc_used_list[i]); +#ifdef notyet + spin_lock_init(&dp->tx_desc_lock[i]); +#endif + } + + dp->num_spt_pages = ATH12K_NUM_SPT_PAGES; + if (dp->num_spt_pages > ATH12K_MAX_PPT_ENTRIES) + dp->num_spt_pages = ATH12K_MAX_PPT_ENTRIES; + + dp->spt_info = mallocarray(dp->num_spt_pages, + sizeof(struct ath12k_spt_info), + M_DEVBUF, M_NOWAIT | M_ZERO); + if (!dp->spt_info) { + printf("%s: SPT page allocation failure\n", + sc->sc_dev.dv_xname); + return ENOMEM; + } + + for (i = 0; i < dp->num_spt_pages; i++) { + dp->spt_info[i].mem = qwz_dmamem_alloc(sc->sc_dmat, + ATH12K_PAGE_SIZE, PAGE_SIZE); + if (!dp->spt_info[i].mem) { + ret = ENOMEM; + goto free; + } + + if (QWZ_DMA_DVA(dp->spt_info[i].mem) & ATH12K_SPT_4K_ALIGN_CHECK) { + printf("%s: SPT allocated memory is not 4K aligned\n", + sc->sc_dev.dv_xname); + ret = EINVAL; + goto free; + } + } + + ret = qwz_dp_cmem_init(sc, dp, ATH12K_DP_TX_DESC); + if (ret) { + printf("%s: HW CC Tx cmem init failed: %d\n", + sc->sc_dev.dv_xname, ret); + goto free; + } + + ret = qwz_dp_cmem_init(sc, dp, ATH12K_DP_RX_DESC); + if (ret) { + printf("%s: HW CC Rx cmem init failed: %d\n", + sc->sc_dev.dv_xname, ret); + goto free; + } + + ret = qwz_dp_cc_desc_init(sc); + if (ret) { + printf("%s: HW CC desc init failed: %d\n", + sc->sc_dev.dv_xname, ret); + goto free; + } + + return 0; +free: + qwz_dp_cc_cleanup(sc); + return ret; +} + +int +qwz_dp_init_bank_profiles(struct qwz_softc *sc) +{ + return 0; +} + +void +qwz_dp_deinit_bank_profiles(struct qwz_softc *sc) +{ + // FIXME +} + +int qwz_dp_rxdma_ring_buf_setup(struct qwz_softc *, struct dp_rxdma_ring *, uint32_t); + +int +qwz_dp_rxdma_buf_setup(struct qwz_softc *sc) +{ + struct qwz_pdev_dp *dp = &sc->pdev_dp; + struct dp_rxdma_ring *rx_ring; + int ret; + + rx_ring = &dp->rx_refill_buf_ring; + ret = qwz_dp_rxdma_ring_buf_setup(sc, rx_ring, HAL_RXDMA_BUF); + if (ret) + return ret; + + return 0; +} + +int +qwz_dp_rx_alloc(struct qwz_softc *sc) +{ + struct qwz_pdev_dp *dp = &sc->pdev_dp; + int i, ret; + +#if notyet + idr_init(&dp->rxdma_mon_buf_ring.bufs_idr); + spin_lock_init(&dp->rxdma_mon_buf_ring.idr_lock); + + idr_init(&dp->tx_mon_buf_ring.bufs_idr); + spin_lock_init(&dp->tx_mon_buf_ring.idr_lock); +#endif + + ret = qwz_dp_srng_setup(sc, &dp->rx_refill_buf_ring.refill_buf_ring, + HAL_RXDMA_BUF, 0, dp->mac_id, DP_RXDMA_BUF_RING_SIZE); + if (ret) { + printf("%s: failed to setup rx_refill_buf_ring\n", + sc->sc_dev.dv_xname); + return ret; + } + + if (sc->hw_params.rx_mac_buf_ring) { + for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) { + ret = qwz_dp_srng_setup(sc, &dp->rx_mac_buf_ring[i], + HAL_RXDMA_BUF, 1, dp->mac_id + i, 2048); + if (ret) { + printf("%s: failed to setup " + "rx_mac_buf_ring %d\n", + sc->sc_dev.dv_xname, i); + return ret; + } + } + } + + for (i = 0; i < sc->hw_params.num_rxdma_dst_ring; i++) { + ret = qwz_dp_srng_setup(sc, &dp->rxdma_err_dst_ring[i], + HAL_RXDMA_BUF, 0, dp->mac_id + i, + DP_RXDMA_ERR_DST_RING_SIZE); + if (ret) { + printf("%s: failed to setup " + "rxdma_err_dst_Ring %d\n", + sc->sc_dev.dv_xname, i); + return ret; + } + } + + ret = qwz_dp_rxdma_buf_setup(sc); + if (ret) { + printf("%s: failed to setup rxdma ring\n", + sc->sc_dev.dv_xname); + return ret; + } + + return 0; +} + +void +qwz_dp_rx_free(struct qwz_softc *sc) +{ + /* FIXME */ +} + int qwz_dp_alloc(struct qwz_softc *sc) { @@ -10498,10 +9904,18 @@ qwz_dp_alloc(struct qwz_softc *sc) return ret; } - ret = qwz_dp_srng_common_setup(sc); + ret = qwz_dp_cc_init(sc); if (ret) goto fail_link_desc_cleanup; + ret = qwz_dp_init_bank_profiles(sc); + if (ret) + goto fail_hw_cc_cleanup; + + ret = qwz_dp_srng_common_setup(sc); + if (ret) + goto fail_dp_bank_profiles_cleanup; + size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; for (i = 0; i < sc->hw_params.max_tx_ring; i++) { @@ -10529,11 +9943,21 @@ qwz_dp_alloc(struct qwz_softc *sc) for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++) qwz_hal_tx_set_dscp_tid_map(sc, i); + ret = qwz_dp_rx_alloc(sc); + if (ret) + goto fail_dp_rx_free; + /* Init any SOC level resource for DP */ return 0; +fail_dp_rx_free: + qwz_dp_rx_free(sc); fail_cmn_srng_cleanup: qwz_dp_srng_common_cleanup(sc); +fail_dp_bank_profiles_cleanup: + qwz_dp_deinit_bank_profiles(sc); +fail_hw_cc_cleanup: + qwz_dp_cc_cleanup(sc); fail_link_desc_cleanup: qwz_dp_link_desc_cleanup(sc, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); @@ -10611,20 +10035,14 @@ qwz_dp_free(struct qwz_softc *sc) /* Deinit any SOC level resource */ } -void -qwz_qmi_process_coldboot_calibration(struct qwz_softc *sc) -{ - printf("%s not implemented\n", __func__); -} - int -qwz_qmi_wlanfw_wlan_ini_send(struct qwz_softc *sc, int enable) +qwz_qmi_wlanfw_wlan_ini_send(struct qwz_softc *sc) { int ret; struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {}; req.enablefwlog_valid = 1; - req.enablefwlog = enable ? 1 : 0; + req.enablefwlog = 1; ret = qwz_qmi_send_request(sc, QMI_WLANFW_WLAN_INI_REQ_V01, QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN, @@ -10635,7 +10053,7 @@ qwz_qmi_wlanfw_wlan_ini_send(struct qwz_softc *sc, int enable) return ret; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzini", SEC_TO_NSEC(1)); @@ -10687,31 +10105,31 @@ qwz_qmi_wlanfw_wlan_cfg_send(struct qwz_softc *sc) req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir; req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum; } - req->shadow_reg_valid = 0; - /* set shadow v2 configuration */ + /* set shadow v3 configuration */ if (sc->hw_params.supports_shadow_regs) { - req->shadow_reg_v2_valid = 1; - req->shadow_reg_v2_len = MIN(sc->qmi_ce_cfg.shadow_reg_v2_len, - QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01); - memcpy(&req->shadow_reg_v2, sc->qmi_ce_cfg.shadow_reg_v2, - sizeof(uint32_t) * req->shadow_reg_v2_len); + req->shadow_reg_v3_valid = 1; + req->shadow_reg_v3_len = MIN(sc->qmi_ce_cfg.shadow_reg_v3_len, + QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01); + memcpy(&req->shadow_reg_v3, sc->qmi_ce_cfg.shadow_reg_v3, + sizeof(uint32_t) * req->shadow_reg_v3_len); } else { - req->shadow_reg_v2_valid = 0; + req->shadow_reg_v3_valid = 0; } DNPRINTF(QWZ_D_QMI, "%s: wlan cfg req\n", __func__); ret = qwz_qmi_send_request(sc, QMI_WLANFW_WLAN_CFG_REQ_V01, QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN, - qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req, sizeof(*req)); + qmi_wlanfw_wlan_cfg_req_msg_v01_ei, + req, sizeof(*req)); if (ret) { printf("%s: failed to send wlan config request: %d\n", sc->sc_dev.dv_xname, ret); goto out; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzwlancfg", SEC_TO_NSEC(1)); @@ -10745,7 +10163,7 @@ qwz_qmi_wlanfw_mode_send(struct qwz_softc *sc, enum ath12k_firmware_mode mode) return ret; } - sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; + sc->qmi_resp.result = QMI_RESULT_FAILURE_V01; while (sc->qmi_resp.result != QMI_RESULT_SUCCESS_V01) { ret = tsleep_nsec(&sc->qmi_resp, 0, "qwzfwmode", SEC_TO_NSEC(1)); @@ -10768,13 +10186,11 @@ qwz_qmi_firmware_start(struct qwz_softc *sc, enum ath12k_firmware_mode mode) DPRINTF("%s: firmware start\n", sc->sc_dev.dv_xname); - if (sc->hw_params.fw_wmi_diag_event) { - ret = qwz_qmi_wlanfw_wlan_ini_send(sc, 1); - if (ret < 0) { - printf("%s: qmi failed to send wlan fw ini: %d\n", - sc->sc_dev.dv_xname, ret); - return ret; - } + ret = qwz_qmi_wlanfw_wlan_ini_send(sc); + if (ret < 0) { + printf("%s: qmi failed to send wlan fw ini: %d\n", + sc->sc_dev.dv_xname, ret); + return ret; } ret = qwz_qmi_wlanfw_wlan_cfg_send(sc); @@ -10811,8 +10227,8 @@ qwz_core_start_firmware(struct qwz_softc *sc, enum ath12k_firmware_mode mode) { int ret; - qwz_ce_get_shadow_config(sc, &sc->qmi_ce_cfg.shadow_reg_v2, - &sc->qmi_ce_cfg.shadow_reg_v2_len); + qwz_ce_get_shadow_config(sc, &sc->qmi_ce_cfg.shadow_reg_v3, + &sc->qmi_ce_cfg.shadow_reg_v3_len); ret = qwz_qmi_firmware_start(sc, mode); if (ret) { @@ -13726,6 +13142,8 @@ qwz_htc_service_name(enum ath12k_htc_svc_id id) return "IPA TX"; case ATH12K_HTC_SVC_ID_PKT_LOG: return "PKT LOG"; + case ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG: + return "WMI DIAG"; } return "Unknown"; @@ -14236,12 +13654,6 @@ qwz_htc_wait_target(struct qwz_softc *sc) return EINVAL; } - /* For QCA6390, wmi endpoint uses 1 credit to avoid - * back-to-back write. - */ - if (sc->hw_params.supports_shadow_regs) - htc->total_transmit_credits = 1; - qwz_htc_setup_target_buffer_assignments(htc); return 0; @@ -14514,43 +13926,32 @@ int qwz_dp_rx_pdev_srng_alloc(struct qwz_softc *sc) { struct qwz_pdev_dp *dp = &sc->pdev_dp; -#if 0 struct dp_srng *srng = NULL; -#endif int i; int ret; - ret = qwz_dp_srng_setup(sc, &dp->rx_refill_buf_ring.refill_buf_ring, - HAL_RXDMA_BUF, 0, dp->mac_id, DP_RXDMA_BUF_RING_SIZE); - if (ret) { - printf("%s: failed to setup rx_refill_buf_ring\n", - sc->sc_dev.dv_xname); - return ret; - } - - if (sc->hw_params.rx_mac_buf_ring) { - for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) { - ret = qwz_dp_srng_setup(sc, &dp->rx_mac_buf_ring[i], - HAL_RXDMA_BUF, 1, dp->mac_id + i, 1024); - if (ret) { - printf("%s: failed to setup " - "rx_mac_buf_ring %d\n", - sc->sc_dev.dv_xname, i); - return ret; - } - } - } - for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) { - ret = qwz_dp_srng_setup(sc, &dp->rxdma_err_dst_ring[i], - HAL_RXDMA_DST, 0, dp->mac_id + i, - DP_RXDMA_ERR_DST_RING_SIZE); + srng = &dp->rxdma_mon_dst_ring[i]; + ret = qwz_dp_srng_setup(sc, srng, HAL_RXDMA_MONITOR_DST, 0, + dp->mac_id + i, DP_RXDMA_MONITOR_DST_RING_SIZE); if (ret) { - printf("%s: failed to setup rxdma_err_dst_ring %d\n", - sc->sc_dev.dv_xname, i); + printf("%s: failed to setup " + "rxdma_mon_dst_ring %d\n", + sc->sc_dev.dv_xname, i); + return ret; + } + + srng = &dp->tx_mon_dst_ring[i]; + ret = qwz_dp_srng_setup(sc, srng, HAL_TX_MONITOR_DST, 0, + dp->mac_id + i, DP_TX_MONITOR_DEST_RING_SIZE); + if (ret) { + printf("%s: failed to setup " + "tx_mon_dst_ring %d\n", + sc->sc_dev.dv_xname, i); return ret; } } + #if 0 for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) { srng = &dp->rx_mon_status_refill_ring[i].refill_buf_ring; @@ -14563,7 +13964,6 @@ qwz_dp_rx_pdev_srng_alloc(struct qwz_softc *sc) return ret; } } -#endif /* if rxdma1_enable is false, then it doesn't need * to setup rxdam_mon_buf_ring, rxdma_mon_dst_ring * and rxdma_mon_desc_ring. @@ -14573,7 +13973,7 @@ qwz_dp_rx_pdev_srng_alloc(struct qwz_softc *sc) timeout_set(&sc->mon_reap_timer, qwz_dp_service_mon_ring, sc); return 0; } -#if 0 + ret = ath12k_dp_srng_setup(ar->ab, &dp->rxdma_mon_buf_ring.refill_buf_ring, HAL_RXDMA_MONITOR_BUF, 0, dp->mac_id, @@ -14750,7 +14150,7 @@ qwz_dp_rxbufs_replenish(struct qwz_softc *sc, int mac_id, if (ret) goto fail_free_mbuf; } - + ret = bus_dmamap_load_mbuf(sc->sc_dmat, rx_data->map, m, BUS_DMA_READ | BUS_DMA_NOWAIT); if (ret) { @@ -14897,25 +14297,19 @@ qwz_dp_tx_get_ring_id_type(struct qwz_softc *sc, int mac_id, uint32_t ring_id, enum hal_ring_type ring_type, enum htt_srng_ring_type *htt_ring_type, enum htt_srng_ring_id *htt_ring_id) { - int lmac_ring_id_offset = 0; - switch (ring_type) { case HAL_RXDMA_BUF: - lmac_ring_id_offset = mac_id * HAL_SRNG_RINGS_PER_LMAC; - /* for QCA6390, host fills rx buffer to fw and fw fills to * rxbuf ring for each rxdma */ if (!sc->hw_params.rx_mac_buf_ring) { - if (!(ring_id == (HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF + - lmac_ring_id_offset) || - ring_id == (HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_BUF + - lmac_ring_id_offset))) + if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 || + ring_id == HAL_SRNG_SW2RXDMA_BUF1)) return EINVAL; *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; *htt_ring_type = HTT_SW_TO_HW_RING; } else { - if (ring_id == HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF) { + if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) { *htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING; *htt_ring_type = HTT_SW_TO_SW_RING; } else { @@ -15180,12 +14574,14 @@ qwz_dp_rx_pdev_alloc(struct qwz_softc *sc, int mac_id) return ret; } +#if 0 ret = qwz_dp_rxdma_pdev_buf_setup(sc); if (ret) { printf("%s: failed to setup rxdma ring: %d\n", sc->sc_dev.dv_xname, ret); return ret; } +#endif ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; ret = qwz_dp_tx_htt_srng_setup(sc, ring_id, mac_id, HAL_RXDMA_BUF); @@ -15195,20 +14591,6 @@ qwz_dp_rx_pdev_alloc(struct qwz_softc *sc, int mac_id) return ret; } - if (sc->hw_params.rx_mac_buf_ring) { - for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) { - ring_id = dp->rx_mac_buf_ring[i].ring_id; - ret = qwz_dp_tx_htt_srng_setup(sc, ring_id, - mac_id + i, HAL_RXDMA_BUF); - if (ret) { - printf("%s: failed to configure " - "rx_mac_buf_ring%d: %d\n", - sc->sc_dev.dv_xname, i, ret); - return ret; - } - } - } - for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) { ring_id = dp->rxdma_err_dst_ring[i].ring_id; ret = qwz_dp_tx_htt_srng_setup(sc, ring_id, mac_id + i, @@ -15586,7 +14968,7 @@ qwz_dp_tx_complete_msdu(struct qwz_softc *sc, struct dp_tx_ring *tx_ring, ieee80211_release_node(ic, tx_data->ni); tx_data->ni = NULL; - + if (tx_ring->queued > 0) tx_ring->queued--; } @@ -15620,8 +15002,8 @@ qwz_dp_tx_completion_handler(struct qwz_softc *sc, int ring_id) QWZ_TX_COMPL_NEXT(tx_ring->tx_status_head); } #if 0 - if (unlikely((ath12k_hal_srng_dst_peek(ab, status_ring) != NULL) && - (ATH12K_TX_COMPL_NEXT(tx_ring->tx_status_head) == + if (unlikely((qwz_hal_srng_dst_peek(ab, status_ring) != NULL) && + (QWZ_TX_COMPL_NEXT(tx_ring->tx_status_head) == tx_ring->tx_status_tail))) { /* TODO: Process pending tx_status messages when kfifo_is_full() */ ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n"); @@ -15920,7 +15302,7 @@ qwz_dp_process_rx_err(struct qwz_softc *sc) (paddr - link_desc_banks[desc_bank].paddr); qwz_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, &rbm); - if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST && + if (rbm != HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST && rbm != HAL_RX_BUF_RBM_SW3_BM) { #if 0 ab->soc_stats.invalid_rbm++; @@ -16159,7 +15541,7 @@ qwz_dp_rx_process_wbm_err(struct qwz_softc *sc) if (mac_id >= MAX_RADIOS) continue; - + rx_ring = &sc->pdev_dp.rx_refill_buf_ring; if (idx >= rx_ring->bufs_max || isset(rx_ring->freemap, idx)) continue; @@ -16865,7 +16247,7 @@ qwz_dp_rx_alloc_mon_status_buf(struct qwz_softc *sc, if (ret) goto fail_free_mbuf; } - + ret = bus_dmamap_load_mbuf(sc->sc_dmat, rx_data->map, m, BUS_DMA_READ | BUS_DMA_NOWAIT); if (ret) { @@ -17139,6 +16521,7 @@ qwz_dp_process_rxdma_err(struct qwz_softc *sc, int mac_id) void *desc; int num_buf_freed = 0; uint64_t paddr; + uint32_t cookie; uint32_t desc_bank; void *link_desc_va; int num_msdus; @@ -17156,7 +16539,9 @@ qwz_dp_process_rxdma_err(struct qwz_softc *sc, int mac_id) qwz_hal_srng_access_begin(sc, srng); while ((desc = qwz_hal_srng_dst_get_next_entry(sc, srng))) { - qwz_hal_rx_reo_ent_paddr_get(sc, desc, &paddr, &desc_bank); + qwz_hal_rx_reo_ent_paddr_get(sc, desc, &paddr, &cookie); + desc_bank = FIELD_GET(DP_LINK_DESC_BANK_MASK, + cookie); entr_ring = (struct hal_reo_entrance_ring *)desc; rxdma_err_code = FIELD_GET( @@ -19677,7 +19062,7 @@ qwz_core_stop(struct qwz_softc *sc) { if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, sc->sc_flags)) qwz_qmi_firmware_stop(sc); - + sc->ops.stop(sc); qwz_wmi_detach(sc); qwz_dp_pdev_reo_cleanup(sc); @@ -19862,22 +19247,18 @@ err_firmware_stop: } void -qwz_qmi_fw_init_done(struct qwz_softc *sc) +qwz_qmi_fw_ready(struct qwz_softc *sc) { int ret = 0; clear_bit(ATH12K_FLAG_QMI_FAIL, sc->sc_flags); - if (sc->qmi_cal_done == 0 && sc->hw_params.cold_boot_calib) { - qwz_qmi_process_coldboot_calibration(sc); - } else { - clear_bit(ATH12K_FLAG_CRASH_FLUSH, sc->sc_flags); - clear_bit(ATH12K_FLAG_RECOVERY, sc->sc_flags); - ret = qwz_core_qmi_firmware_ready(sc); - if (ret) { - set_bit(ATH12K_FLAG_QMI_FAIL, sc->sc_flags); - return; - } + clear_bit(ATH12K_FLAG_CRASH_FLUSH, sc->sc_flags); + clear_bit(ATH12K_FLAG_RECOVERY, sc->sc_flags); + ret = qwz_core_qmi_firmware_ready(sc); + if (ret) { + set_bit(ATH12K_FLAG_QMI_FAIL, sc->sc_flags); + return; } } @@ -19886,9 +19267,17 @@ qwz_qmi_event_server_arrive(struct qwz_softc *sc) { int ret; - sc->fw_init_done = 0; + sc->fw_ready = 0; sc->expect_fwmem_req = 1; + ret = qwz_qmi_phy_cap_send(sc); + if (ret < 0) { + printf("%s: failed to send qmi phy cap: %d\n", + sc->sc_dev.dv_xname, ret); + sc->expect_fwmem_req = 0; + return ret; + } + ret = qwz_qmi_fw_ind_register_send(sc); if (ret < 0) { printf("%s: failed to send qmi firmware indication: %d\n", @@ -19929,16 +19318,16 @@ qwz_qmi_event_server_arrive(struct qwz_softc *sc) return ret; } - while (!sc->fw_init_done) { - ret = tsleep_nsec(&sc->fw_init_done, 0, "qwzfwinit", + while (!sc->fw_ready) { + ret = tsleep_nsec(&sc->fw_ready, 0, "qwzfwrdy", SEC_TO_NSEC(10)); if (ret) { - printf("%s: fw init timeout\n", sc->sc_dev.dv_xname); + printf("%s: fw ready timeout\n", sc->sc_dev.dv_xname); return -1; } } - qwz_qmi_fw_init_done(sc); + qwz_qmi_fw_ready(sc); return 0; } @@ -19949,13 +19338,17 @@ qwz_core_init(struct qwz_softc *sc) error = qwz_qmi_init_service(sc); if (error) { - printf("failed to initialize qmi :%d\n", error); + printf("%s: failed to initialize qmi :%d\n", + sc->sc_dev.dv_xname, error); return error; } error = sc->ops.power_up(sc); - if (error) + if (error) { + printf("%s: failed to power up :%d\n", + sc->sc_dev.dv_xname, error); qwz_qmi_deinit_service(sc); + } return error; } @@ -19974,7 +19367,7 @@ qwz_init_hw_params(struct qwz_softc *sc) } if (i == nitems(ath12k_hw_params)) { - printf("%s: Unsupported hardware version: 0x%x\n", + printf("%s: unsupported hardware version: 0x%x\n", sc->sc_dev.dv_xname, sc->sc_hw_rev); return EINVAL; } @@ -19986,186 +19379,200 @@ qwz_init_hw_params(struct qwz_softc *sc) return 0; } -static const struct hal_srng_config hw_srng_config_templ[QWZ_NUM_SRNG_CFG] = { +static const struct hal_srng_config hw_srng_config_templ[] = { /* TODO: max_rings can populated by querying HW capabilities */ - { /* REO_DST */ + [HAL_REO_DST] = { .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, - .max_rings = 4, + .max_rings = 8, .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_DST, .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, }, - - { /* REO_EXCEPTION */ - /* Designating REO2TCL ring as exception ring. This ring is - * similar to other REO2SW rings though it is named as REO2TCL. + [HAL_REO_EXCEPTION] = { + /* Designating REO2SW0 ring as exception ring. * Any of theREO2SW rings can be used as exception ring. */ - .start_ring_id = HAL_SRNG_RING_ID_REO2TCL, + .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, .max_rings = 1, .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_REO_REO2TCL_RING_BASE_MSB_RING_SIZE, + .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, }, - { /* REO_REINJECT */ + [HAL_REO_REINJECT] = { .start_ring_id = HAL_SRNG_RING_ID_SW2REO, - .max_rings = 1, + .max_rings = 4, .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, }, - { /* REO_CMD */ + [HAL_REO_CMD] = { .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_hdr) + - sizeof(struct hal_reo_get_queue_stats)) >> 2, - .lmac_ring = false, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, }, - { /* REO_STATUS */ + [HAL_REO_STATUS] = { .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_hdr) + - sizeof(struct hal_reo_get_queue_stats_status)) >> 2, - .lmac_ring = false, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats_status)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_DST, .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, }, - { /* TCL_DATA */ + [HAL_TCL_DATA] = { .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, - .max_rings = 3, - .entry_size = (sizeof(struct hal_tlv_hdr) + - sizeof(struct hal_tcl_data_cmd)) >> 2, - .lmac_ring = false, + .max_rings = 6, + .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, }, - { /* TCL_CMD */ + [HAL_TCL_CMD] = { .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_hdr) + - sizeof(struct hal_tcl_gse_cmd)) >> 2, - .lmac_ring = false, + .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, }, - { /* TCL_STATUS */ + [HAL_TCL_STATUS] = { .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, .max_rings = 1, .entry_size = (sizeof(struct hal_tlv_hdr) + - sizeof(struct hal_tcl_status_ring)) >> 2, - .lmac_ring = false, + sizeof(struct hal_tcl_status_ring)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_DST, .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, }, - { /* CE_SRC */ + [HAL_CE_SRC] = { .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, - .max_rings = 12, + .max_rings = 16, .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, }, - { /* CE_DST */ + [HAL_CE_DST] = { .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, - .max_rings = 12, + .max_rings = 16, .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, }, - { /* CE_DST_STATUS */ + [HAL_CE_DST_STATUS] = { .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, - .max_rings = 12, + .max_rings = 16, .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_DST, .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, }, - { /* WBM_IDLE_LINK */ + [HAL_WBM_IDLE_LINK] = { .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, .max_rings = 1, .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, }, - { /* SW2WBM_RELEASE */ - .start_ring_id = HAL_SRNG_RING_ID_WBM_SW_RELEASE, - .max_rings = 1, + [HAL_SW2WBM_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, + .max_rings = 2, .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, }, - { /* WBM2SW_RELEASE */ + [HAL_WBM2SW_RELEASE] = { .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, - .max_rings = 5, + .max_rings = 8, .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .lmac_ring = false, + .mac_type = ATH12K_HAL_SRNG_UMAC, .ring_dir = HAL_SRNG_DIR_DST, .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, }, - { /* RXDMA_BUF */ - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF, - .max_rings = 2, + [HAL_RXDMA_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, + .max_rings = 1, .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .lmac_ring = true, + .mac_type = ATH12K_HAL_SRNG_DMAC, .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, - { /* RXDMA_DST */ + [HAL_RXDMA_DST] = { .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, - .max_rings = 1, - .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, - .lmac_ring = true, + .max_rings = 0, + .entry_size = 0, + .mac_type = ATH12K_HAL_SRNG_PMAC, .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, - { /* RXDMA_MONITOR_BUF */ - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA2_BUF, + [HAL_RXDMA_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .lmac_ring = true, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, - { /* RXDMA_MONITOR_STATUS */ - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .lmac_ring = true, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE, - }, - { /* RXDMA_MONITOR_DST */ - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW1, - .max_rings = 1, - .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, - .lmac_ring = true, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE, - }, - { /* RXDMA_MONITOR_DESC */ - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_DESC, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .lmac_ring = true, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE, - }, - { /* RXDMA DIR BUF */ + [HAL_RXDMA_MONITOR_STATUS] = { 0, }, + [HAL_RXDMA_MONITOR_DESC] = { 0, }, + [HAL_RXDMA_DIR_BUF] = { .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, - .max_rings = 1, + .max_rings = 2, .entry_size = 8 >> 2, /* TODO: Define the struct */ - .lmac_ring = true, + .mac_type = ATH12K_HAL_SRNG_PMAC, .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, + [HAL_PPE2TCL] = { + .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_PPE_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TX_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_SW2TXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_TX_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + } }; int @@ -20174,35 +19581,42 @@ qwz_hal_srng_create_config(struct qwz_softc *sc) struct ath12k_hal *hal = &sc->hal; struct hal_srng_config *s; + hal->srng_config = malloc(sizeof(hw_srng_config_templ), + M_DEVBUF, M_NOWAIT | M_ZERO); + if (!hal->srng_config) + return ENOMEM; + memcpy(hal->srng_config, hw_srng_config_templ, - sizeof(hal->srng_config)); + sizeof(hw_srng_config_templ)); s = &hal->srng_config[HAL_REO_DST]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP(sc); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; s->reg_size[0] = HAL_REO2_RING_BASE_LSB(sc) - HAL_REO1_RING_BASE_LSB(sc); - s->reg_size[1] = HAL_REO2_RING_HP(sc) - HAL_REO1_RING_HP(sc); + s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_TCL_RING_BASE_LSB(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_TCL_RING_HP(sc); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(sc); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; s = &hal->srng_config[HAL_REO_REINJECT]; + s->max_rings = 1; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP(sc); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; s = &hal->srng_config[HAL_REO_CMD]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP(sc); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; s = &hal->srng_config[HAL_REO_STATUS]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP(sc); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; s = &hal->srng_config[HAL_TCL_DATA]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(sc); + s->max_rings = 5; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB; s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(sc) - HAL_TCL1_RING_BASE_LSB(sc); + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB - HAL_TCL1_RING_BASE_LSB; s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; s = &hal->srng_config[HAL_TCL_CMD]; @@ -20214,42 +19628,42 @@ qwz_hal_srng_create_config(struct qwz_softc *sc) s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; s = &hal->srng_config[HAL_CE_SRC]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(sc) + HAL_CE_DST_RING_BASE_LSB + - ATH12K_CE_OFFSET(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(sc) + HAL_CE_DST_RING_HP + - ATH12K_CE_OFFSET(sc); - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(sc) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(sc); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(sc) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(sc); + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG; + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG; s = &hal->srng_config[HAL_CE_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc) + HAL_CE_DST_RING_BASE_LSB + - ATH12K_CE_OFFSET(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc) + HAL_CE_DST_RING_HP + - ATH12K_CE_OFFSET(sc); - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(sc) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(sc) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc); + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG; + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG; s = &hal->srng_config[HAL_CE_DST_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc) + - HAL_CE_DST_STATUS_RING_BASE_LSB + ATH12K_CE_OFFSET(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc) + HAL_CE_DST_STATUS_RING_HP + - ATH12K_CE_OFFSET(sc); - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(sc) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(sc) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc); + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + + HAL_CE_DST_STATUS_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG; + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG; s = &hal->srng_config[HAL_WBM_IDLE_LINK]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(sc); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; s = &hal->srng_config[HAL_SW2WBM_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_BASE_LSB(sc); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_HP; + s->max_rings = 1; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SW_RELEASE_RING_BASE_LSB(sc); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; s = &hal->srng_config[HAL_WBM2SW_RELEASE]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(sc); @@ -20258,6 +19672,33 @@ qwz_hal_srng_create_config(struct qwz_softc *sc) HAL_WBM0_RELEASE_RING_BASE_LSB(sc); s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; + s = &hal->srng_config[HAL_RXDMA_BUF]; + s->max_rings = 2; + s->mac_type = ATH12K_HAL_SRNG_PMAC; + + s = &hal->srng_config[HAL_RXDMA_DST]; + s->max_rings = 1; + s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2; + + /* below rings are not used */ + s = &hal->srng_config[HAL_RXDMA_DIR_BUF]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE2TCL]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE_RELEASE]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_TX_MONITOR_BUF]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_TX_MONITOR_DST]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE2TCL]; + s->max_rings = 0; + return 0; } @@ -20274,8 +19715,8 @@ qwz_hal_srng_get_ring_id(struct qwz_softc *sc, } ring_id = srng_config->start_ring_id + ring_num; - if (srng_config->lmac_ring) - ring_id += mac_id * HAL_SRNG_RINGS_PER_LMAC; + if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC) + ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC; if (ring_id >= HAL_SRNG_RING_ID_MAX) { printf("%s: invalid ring ID :%d\n", __func__, ring_id); @@ -20302,11 +19743,11 @@ qwz_hal_srng_update_hp_tp_addr(struct qwz_softc *sc, int shadow_cfg_idx, if (srng_config->ring_dir == HAL_SRNG_DIR_DST) srng->u.dst_ring.tp_addr = (uint32_t *)( - HAL_SHADOW_REG(sc, shadow_cfg_idx) + + HAL_SHADOW_REG(shadow_cfg_idx) + (unsigned long)sc->mem); else srng->u.src_ring.hp_addr = (uint32_t *)( - HAL_SHADOW_REG(sc, shadow_cfg_idx) + + HAL_SHADOW_REG(shadow_cfg_idx) + (unsigned long)sc->mem); } @@ -20351,7 +19792,7 @@ qwz_hal_srng_update_shadow_config(struct qwz_softc *sc, DPRINTF("%s: target_reg %x, shadow reg 0x%x shadow_idx 0x%x, " "ring_type %d, ring num %d\n", __func__, target_reg, - HAL_SHADOW_REG(sc, shadow_cfg_idx), shadow_cfg_idx, + HAL_SHADOW_REG(shadow_cfg_idx), shadow_cfg_idx, ring_type, ring_num); return 0; @@ -20373,7 +19814,8 @@ qwz_hal_srng_shadow_config(struct qwz_softc *sc) ring_type == HAL_CE_DST_STATUS) continue; - if (cfg->lmac_ring) + if (cfg->mac_type == ATH12K_HAL_SRNG_DMAC || + cfg->mac_type == ATH12K_HAL_SRNG_PMAC) continue; for (ring_num = 0; ring_num < cfg->max_rings; ring_num++) { @@ -20432,7 +19874,8 @@ int qwz_hal_alloc_cont_wrp(struct qwz_softc *sc) { struct ath12k_hal *hal = &sc->hal; - size_t size = sizeof(uint32_t) * HAL_SRNG_NUM_LMAC_RINGS; + size_t size = sizeof(uint32_t) * + (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS); if (hal->wrpmem == NULL) { hal->wrpmem = qwz_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE); @@ -20492,6 +19935,8 @@ err_free_cont_rdp: qwz_hal_free_cont_rdp(sc); err_hal: + if (hal->srng_config) + free(hal->srng_config, M_DEVBUF, 0); return ret; } @@ -20554,7 +19999,7 @@ qwz_hal_srng_dst_hw_init(struct qwz_softc *sc, struct hal_srng *srng) /* Initialize head and tail pointers to indicate ring is empty */ reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; sc->ops.write32(sc, reg_base, 0); - sc->ops.write32(sc, reg_base + HAL_REO1_RING_TP_OFFSET(sc), 0); + sc->ops.write32(sc, reg_base + HAL_REO1_RING_TP_OFFSET, 0); *srng->u.dst_ring.hp_addr = 0; reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; @@ -20603,22 +20048,11 @@ qwz_hal_srng_src_hw_init(struct qwz_softc *sc, struct hal_srng *srng) ((uint64_t)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT)) | FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_SIZE, (srng->entry_size * srng->num_entries)); - sc->ops.write32(sc, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(sc), val); + sc->ops.write32(sc, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET, val); val = FIELD_PREP(HAL_REO1_RING_ID_ENTRY_SIZE, srng->entry_size); sc->ops.write32(sc, reg_base + HAL_TCL1_RING_ID_OFFSET(sc), val); - if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) { - sc->ops.write32(sc, reg_base, (uint32_t)srng->ring_base_paddr); - val = FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB, - ((uint64_t)srng->ring_base_paddr >> - HAL_ADDR_MSB_REG_SHIFT)) | - FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_SIZE, - (srng->entry_size * srng->num_entries)); - sc->ops.write32(sc, - reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(sc), val); - } - /* interrupt setup */ /* NOTE: IPQ8074 v2 requires the interrupt timer threshold in the * unit of 8 usecs instead of 1 usec (as required by v1). @@ -20672,6 +20106,9 @@ qwz_hal_srng_src_hw_init(struct qwz_softc *sc, struct hal_srng *srng) val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; + if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) + val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; + sc->ops.write32(sc, reg_base + HAL_TCL1_RING_MISC_OFFSET(sc), val); } @@ -20738,7 +20175,7 @@ qwz_hal_ce_dst_status_get_length(void *buf) uint32_t len; len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags); - desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN; + desc->flags &= ~htole32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN); return len; } @@ -20804,12 +20241,7 @@ qwz_hal_srng_setup(struct qwz_softc *sc, enum hal_ring_type type, srng->u.src_ring.tp_addr = (void *)(hal->rdp.vaddr + ring_id); srng->u.src_ring.low_threshold = params->low_threshold * srng->entry_size; - if (srng_config->lmac_ring) { - lmac_idx = ring_id - HAL_SRNG_RING_ID_LMAC1_ID_START; - srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr + - lmac_idx); - srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; - } else { + if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { if (!sc->hw_params.supports_shadow_regs) srng->u.src_ring.hp_addr = (uint32_t *)((unsigned long)sc->mem + @@ -20820,6 +20252,11 @@ qwz_hal_srng_setup(struct qwz_softc *sc, enum hal_ring_type type, sc->sc_dev.dv_xname, type, ring_num, reg_base, (unsigned long)srng->u.src_ring.hp_addr - (unsigned long)sc->mem); + } else { + lmac_idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START; + srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr + + lmac_idx); + srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; } } else { /* During initialization loop count in all the descriptors @@ -20834,32 +20271,32 @@ qwz_hal_srng_setup(struct qwz_softc *sc, enum hal_ring_type type, srng->u.dst_ring.tp = 0; srng->u.dst_ring.cached_hp = 0; srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id); - if (srng_config->lmac_ring) { - /* For LMAC rings, tail pointer updates will be done - * through FW by writing to a shared memory location - */ - lmac_idx = ring_id - HAL_SRNG_RING_ID_LMAC1_ID_START; - srng->u.dst_ring.tp_addr = (void *)(hal->wrp.vaddr + - lmac_idx); - srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; - } else { + if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { if (!sc->hw_params.supports_shadow_regs) srng->u.dst_ring.tp_addr = (uint32_t *)((unsigned long)sc->mem + - reg_base + (HAL_REO1_RING_TP(sc) - - HAL_REO1_RING_HP(sc))); + reg_base + (HAL_REO1_RING_TP - + HAL_REO1_RING_HP)); else DPRINTF("%s: type %d ring_num %d target_reg " "0x%x shadow 0x%lx\n", sc->sc_dev.dv_xname, type, ring_num, - reg_base + (HAL_REO1_RING_TP(sc) - - HAL_REO1_RING_HP(sc)), + reg_base + (HAL_REO1_RING_TP - + HAL_REO1_RING_HP), (unsigned long)srng->u.dst_ring.tp_addr - (unsigned long)sc->mem); + } else { + /* For LMAC rings, tail pointer updates will be done + * through FW by writing to a shared memory location + */ + lmac_idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START; + srng->u.dst_ring.tp_addr = (void *)(hal->wrp.vaddr + + lmac_idx); + srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; } } - if (srng_config->lmac_ring) + if (srng_config->mac_type != ATH12K_HAL_SRNG_UMAC) return ring_id; qwz_hal_srng_hw_init(sc, srng); @@ -20887,12 +20324,6 @@ qwz_hal_ce_get_desc_size(enum hal_ce_desc type) return 0; } -void -qwz_htc_tx_completion_handler(struct qwz_softc *sc, struct mbuf *m) -{ - printf("%s: not implemented\n", __func__); -} - struct qwz_tx_data * qwz_ce_completed_send_next(struct qwz_ce_pipe *pipe) { @@ -20935,34 +20366,19 @@ err_unlock: } int -qwz_ce_tx_process_cb(struct qwz_ce_pipe *pipe) +qwz_ce_send_done_cb(struct qwz_ce_pipe *pipe) { struct qwz_softc *sc = pipe->sc; struct qwz_tx_data *tx_data; - struct mbuf *m; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); int ret = 0; while ((tx_data = qwz_ce_completed_send_next(pipe)) != NULL) { bus_dmamap_unload(sc->sc_dmat, tx_data->map); - m = tx_data->m; + m_freem(tx_data->m); tx_data->m = NULL; - - if ((!pipe->send_cb) || sc->hw_params.credit_flow) { - m_freem(m); - continue; - } - - ml_enqueue(&ml, m); ret = 1; } - while ((m = ml_dequeue(&ml))) { - DNPRINTF(QWZ_D_CE, "%s: tx ce pipe %d len %d\n", __func__, - pipe->pipe_num, m->m_len); - pipe->send_cb(sc, m); - } - return ret; } @@ -20970,10 +20386,9 @@ void qwz_ce_poll_send_completed(struct qwz_softc *sc, uint8_t pipe_id) { struct qwz_ce_pipe *pipe = &sc->ce.ce_pipe[pipe_id]; - const struct ce_attr *attr = &sc->hw_params.host_ce_config[pipe_id]; - if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && attr->src_nentries) - qwz_ce_tx_process_cb(pipe); + if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && pipe->send_cb) + pipe->send_cb(pipe); } void @@ -21241,7 +20656,7 @@ qwz_ce_free_ring(struct qwz_softc *sc, struct qwz_ce_ring *ring) { bus_size_t dsize; size_t size; - + if (ring == NULL) return; @@ -21287,8 +20702,6 @@ qwz_ce_free_pipes(struct qwz_softc *sc) for (i = 0; i < sc->hw_params.ce_count; i++) { pipe = &sc->ce.ce_pipe[i]; - if (qwz_ce_need_shadow_fix(i)) - qwz_dp_shadow_stop_timer(sc, &sc->ce.hp_timer[i]); if (pipe->src_ring) { qwz_ce_free_ring(sc, pipe->src_ring); pipe->src_ring = NULL; @@ -21437,7 +20850,7 @@ qwz_ce_alloc_pipe(struct qwz_softc *sc, int ce_id) pipe->attr_flags = attr->flags; if (attr->src_nentries) { - pipe->send_cb = attr->send_cb; + pipe->send_cb = qwz_ce_send_done_cb; nentries = qwz_roundup_pow_of_two(attr->src_nentries); desc_sz = qwz_hal_ce_get_desc_size(HAL_CE_DESC_SRC); ring = qwz_ce_alloc_ring(sc, nentries, desc_sz); @@ -21543,8 +20956,6 @@ qwz_ce_cleanup_pipes(struct qwz_softc *sc) struct qwz_ce_pipe *pipe; int pipe_num; - qwz_ce_stop_shadow_timers(sc); - for (pipe_num = 0; pipe_num < sc->hw_params.ce_count; pipe_num++) { pipe = &sc->ce.ce_pipe[pipe_num]; qwz_ce_rx_pipe_cleanup(pipe); @@ -22005,11 +21416,10 @@ int qwz_ce_per_engine_service(struct qwz_softc *sc, uint16_t ce_id) { struct qwz_ce_pipe *pipe = &sc->ce.ce_pipe[ce_id]; - const struct ce_attr *attr = &sc->hw_params.host_ce_config[ce_id]; int ret = 0; - if (attr->src_nentries) { - if (qwz_ce_tx_process_cb(pipe)) + if (pipe->send_cb) { + if (pipe->send_cb(pipe)) ret = 1; } @@ -22103,9 +21513,6 @@ qwz_ce_send(struct qwz_softc *sc, struct mbuf *m, uint8_t pipe_id, qwz_hal_srng_access_end(sc, srng); - if (qwz_ce_need_shadow_fix(pipe_id)) - qwz_dp_shadow_start_timer(sc, srng, &sc->ce.hp_timer[pipe_id]); - err_unlock: #ifdef notyet spin_unlock_bh(&srng->lock); @@ -22230,7 +21637,7 @@ qwz_reg_update_chan_list(struct qwz_softc *sc, uint8_t pdev_id) ch->cfreq1 = ch->mhz; ch->minpower = 0; ch->maxpower = 40; /* XXX from Linux debug trace */ - ch->maxregpower = ch->maxpower; + ch->maxregpower = ch->maxpower; ch->antennamax = 0; /* TODO: Use appropriate phymodes */ @@ -22822,7 +22229,7 @@ struct qwz_vif * qwz_vif_alloc(struct qwz_softc *sc) { struct qwz_vif *arvif; - struct qwz_txmgmt_queue *txmgmt; + struct qwz_txmgmt_queue *txmgmt; int i, ret = 0; const bus_size_t size = IEEE80211_MAX_LEN; @@ -24430,7 +23837,6 @@ qwz_dp_tx(struct qwz_softc *sc, struct qwz_vif *arvif, uint8_t pdev_id, qwz_hal_srng_access_end(sc, tcl_ring); - qwz_dp_shadow_start_timer(sc, tcl_ring, &dp->tx_ring_timer[ti.ring_id]); #ifdef notyet spin_unlock_bh(&tcl_ring->lock); #endif @@ -24438,7 +23844,7 @@ qwz_dp_tx(struct qwz_softc *sc, struct qwz_vif *arvif, uint8_t pdev_id, tx_ring->cur = (tx_ring->cur + 1) % sc->hw_params.tx_ring_size; if (tx_ring->queued >= sc->hw_params.tx_ring_size - 1) - sc->qfullmsk |= (1 << ti.ring_id); + sc->qfullmsk |= (1 << ti.ring_id); return 0; } @@ -25137,7 +24543,7 @@ qwz_auth(struct qwz_softc *sc) qwz_recalculate_mgmt_rate(sc, ni, arvif->vdev_id, pdev->pdev_id); ni->ni_txrate = 0; - + ret = qwz_mac_station_add(sc, arvif, pdev->pdev_id, ni); if (ret) return ret; diff --git a/sys/dev/ic/qwzreg.h b/sys/dev/ic/qwzreg.h index e0cf2645d..02050a404 100644 --- a/sys/dev/ic/qwzreg.h +++ b/sys/dev/ic/qwzreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: qwzreg.h,v 1.1 2024/08/14 14:40:46 patrick Exp $ */ +/* $OpenBSD: qwzreg.h,v 1.4 2024/08/16 00:26:54 patrick Exp $ */ /* * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. @@ -49,13 +49,9 @@ #define ATH12K_CONNECTION_LOSS_HZ (3 * HZ) enum ath12k_hw_rev { - ATH12K_HW_IPQ8074, - ATH12K_HW_QCA6390_HW20, - ATH12K_HW_IPQ6018_HW10, - ATH12K_HW_QCN9074_HW10, - ATH12K_HW_WCN6855_HW20, - ATH12K_HW_WCN6855_HW21, - ATH12K_HW_WCN6750_HW10, + ATH12K_HW_QCN9274_HW10, + ATH12K_HW_QCN9274_HW20, + ATH12K_HW_WCN7850_HW20 }; enum ath12k_firmware_mode { @@ -6500,6 +6496,24 @@ struct qmi_response_type_v01 { uint16_t error; }; +#define QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN 0 +#define QMI_WLANFW_PHY_CAP_REQ_V01 0x0057 +#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN 18 +#define QMI_WLANFW_PHY_CAP_RESP_V01 0x0057 + +struct qmi_wlanfw_phy_cap_req_msg_v01 { +}; + +struct qmi_wlanfw_phy_cap_resp_msg_v01 { + struct qmi_response_type_v01 resp; + uint8_t num_phy_valid; + uint8_t num_phy; + uint8_t board_id_valid; + uint32_t board_id; + uint8_t single_chip_mlo_support_valid; + uint8_t single_chip_mlo_support; +}; + #define QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN 54 #define QMI_WLANFW_IND_REGISTER_REQ_V01 0x0020 #define QMI_WLANFW_IND_REGISTER_RESP_MSG_V01_MAX_LEN 18 @@ -6544,12 +6558,45 @@ struct qmi_wlanfw_ind_register_resp_msg_v01 { #define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7 #define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 #define QMI_WLFW_MAX_NUM_GPIO_V01 32 +#define QMI_WLANFW_MAX_PLATFORM_NAME_LEN_V01 64 +#define QMI_WLANFW_MAX_HOST_DDR_RANGE_SIZE_V01 3 #define QMI_IPQ8074_FW_MEM_MODE 0xFF #define HOST_DDR_REGION_TYPE 0x1 #define BDF_MEM_REGION_TYPE 0x2 #define M3_DUMP_REGION_TYPE 0x3 #define CALDB_MEM_REGION_TYPE 0x4 +struct qmi_wlanfw_host_ddr_range { + uint64_t start; + uint64_t size; +}; + +enum qmi_wlanfw_host_build_type { + WLANFW_HOST_BUILD_TYPE_ENUM_MIN_VAL_V01 = INT_MIN, + QMI_WLANFW_HOST_BUILD_TYPE_UNSPECIFIED_V01 = 0, + QMI_WLANFW_HOST_BUILD_TYPE_PRIMARY_V01 = 1, + QMI_WLANFW_HOST_BUILD_TYPE_SECONDARY_V01 = 2, + WLANFW_HOST_BUILD_TYPE_ENUM_MAX_VAL_V01 = INT_MAX, +}; + +#define QMI_WLFW_MAX_NUM_MLO_CHIPS_V01 3 +#define QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01 2 + +struct wlfw_host_mlo_chip_info_s_v01 { + uint8_t chip_id; + uint8_t num_local_links; + uint8_t hw_link_id[QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01]; + uint8_t valid_mlo_link_id[QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01]; +}; + +enum ath12k_qmi_cnss_feature { + CNSS_FEATURE_MIN_ENUM_VAL_V01 = INT_MIN, + CNSS_QDSS_CFG_MISS_V01 = 3, + CNSS_PCIE_PERST_NO_PULL_V01 = 4, + CNSS_MAX_FEATURE_V01 = 64, + CNSS_FEATURE_MAX_ENUM_VAL_V01 = INT_MAX, +}; + struct qmi_wlanfw_host_cap_req_msg_v01 { uint8_t num_clients_valid; uint32_t num_clients; @@ -6578,6 +6625,28 @@ struct qmi_wlanfw_host_cap_req_msg_v01 { uint32_t mem_bucket; uint8_t mem_cfg_mode_valid; uint8_t mem_cfg_mode; + uint8_t cal_duration_valid; + uint16_t cal_duraiton; + uint8_t platform_name_valid; + char platform_name[QMI_WLANFW_MAX_PLATFORM_NAME_LEN_V01 + 1]; + uint8_t ddr_range_valid; + struct qmi_wlanfw_host_ddr_range ddr_range[QMI_WLANFW_MAX_HOST_DDR_RANGE_SIZE_V01]; + uint8_t host_build_type_valid; + enum qmi_wlanfw_host_build_type host_build_type; + uint8_t mlo_capable_valid; + uint8_t mlo_capable; + uint8_t mlo_chip_id_valid; + uint16_t mlo_chip_id; + uint8_t mlo_group_id_valid; + uint8_t mlo_group_id; + uint8_t max_mlo_peer_valid; + uint16_t max_mlo_peer; + uint8_t mlo_num_chips_valid; + uint8_t mlo_num_chips; + uint8_t mlo_chip_info_valid; + struct wlfw_host_mlo_chip_info_s_v01 mlo_chip_info[QMI_WLFW_MAX_NUM_MLO_CHIPS_V01]; + uint8_t feature_list_valid; + uint64_t feature_list; }; struct qmi_wlanfw_host_cap_resp_msg_v01 { @@ -6592,28 +6661,26 @@ struct qmi_wlanfw_host_cap_resp_msg_v01 { #define ATH12K_QMI_WLFW_SERVICE_ID_V01 0x45 #define ATH12K_QMI_WLFW_SERVICE_VERS_V01 0x01 #define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01 0x02 -#define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390 0x01 -#define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074 0x02 -#define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074 0x07 -#define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750 0x03 +#define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850 0x01 +#define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274 0x07 #define ATH12K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 32 #define ATH12K_QMI_RESP_LEN_MAX 8192 #define ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52 #define ATH12K_QMI_CALDB_SIZE 0x480000 #define ATH12K_QMI_BDF_EXT_STR_LENGTH 0x20 -#define ATH12K_QMI_FW_MEM_REQ_SEGMENT_CNT 5 +#define ATH12K_QMI_FW_MEM_REQ_SEGMENT_CNT 3 +#define ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01 4 +#define ATH12K_QMI_DEVMEM_CMEM_INDEX 0 #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 #define QMI_WLFW_RESPOND_MEM_RESP_V01 0x0036 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 -#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x003E -#define QMI_WLFW_FW_READY_IND_V01 0x0021 -#define QMI_WLFW_FW_INIT_DONE_IND_V01 0x0038 +#define QMI_WLFW_FW_READY_IND_V01 0x0038 #define QMI_WLANFW_MAX_DATA_SIZE_V01 6144 #define ATH12K_FIRMWARE_MODE_OFF 4 -#define ATH12K_COLD_BOOT_FW_RESET_DELAY (40 * HZ) +#define ATH12K_QMI_TARGET_MEM_MODE_DEFAULT 0 #define QMI_WLANFW_REQUEST_MEM_IND_MSG_V01_MAX_LEN 1824 #define QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN 888 @@ -6717,7 +6784,7 @@ struct qmi_wlanfw_shadow_reg_cfg_s_v01 { uint16_t offset; }; -struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01 { +struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01 { uint32_t addr; }; @@ -6745,6 +6812,11 @@ struct qmi_wlanfw_fw_version_info_s_v01 { char fw_build_timestamp[ATH12K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1]; }; +struct qmi_wlanfw_dev_mem_info_s_v01 { + uint64_t start; + uint64_t size; +}; + enum qmi_wlanfw_cal_temp_id_enum_v01 { QMI_WLANFW_CAL_TEMP_IDX_0_V01 = 0, QMI_WLANFW_CAL_TEMP_IDX_1_V01 = 1, @@ -6754,6 +6826,14 @@ enum qmi_wlanfw_cal_temp_id_enum_v01 { QMI_WLANFW_CAL_TEMP_ID_MAX_V01 = 0xFF, }; +enum qmi_wlanfw_rd_card_chain_cap_v01 { + WLFW_RD_CARD_CHAIN_CAP_MIN_VAL_V01 = INT_MIN, + WLFW_RD_CARD_CHAIN_CAP_UNSPECIFIED_V01 = 0, + WLFW_RD_CARD_CHAIN_CAP_1x1_V01 = 1, + WLFW_RD_CARD_CHAIN_CAP_2x2_V01 = 2, + WLFW_RD_CARD_CHAIN_CAP_MAX_VAL_V01 = INT_MAX, +}; + struct qmi_wlanfw_cap_resp_msg_v01 { struct qmi_response_type_v01 resp; uint8_t chip_info_valid; @@ -6776,6 +6856,12 @@ struct qmi_wlanfw_cap_resp_msg_v01 { uint32_t otp_version; uint8_t eeprom_read_timeout_valid; uint32_t eeprom_read_timeout; + uint8_t fw_caps_valid; + uint64_t fw_caps; + uint8_t rd_card_chain_cap_valid; + enum qmi_wlanfw_rd_card_chain_cap_v01 rd_card_chain_cap; + uint8_t dev_mem_info_valid; + struct qmi_wlanfw_dev_mem_info_s_v01 dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01]; }; struct qmi_wlanfw_cap_req_msg_v01 { @@ -6828,7 +6914,7 @@ struct qmi_wlanfw_m3_info_resp_msg_v01 { #define QMI_WLANFW_WLAN_MODE_RESP_MSG_V01_MAX_LEN 7 #define QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN 803 #define QMI_WLANFW_WLAN_CFG_RESP_MSG_V01_MAX_LEN 7 -#define QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN 4 +#define QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN 7 #define QMI_WLANFW_WLAN_MODE_REQ_V01 0x0022 #define QMI_WLANFW_WLAN_MODE_RESP_V01 0x0022 #define QMI_WLANFW_WLAN_CFG_REQ_V01 0x0023 @@ -6839,7 +6925,7 @@ struct qmi_wlanfw_m3_info_resp_msg_v01 { #define QMI_WLANFW_MAX_NUM_CE_V01 12 #define QMI_WLANFW_MAX_NUM_SVC_V01 24 #define QMI_WLANFW_MAX_NUM_SHADOW_REG_V01 24 -#define QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01 36 +#define QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01 60 struct qmi_wlanfw_wlan_mode_req_msg_v01 { uint32_t mode; @@ -6866,10 +6952,10 @@ struct qmi_wlanfw_wlan_cfg_req_msg_v01 { uint32_t shadow_reg_len; struct qmi_wlanfw_shadow_reg_cfg_s_v01 shadow_reg[QMI_WLANFW_MAX_NUM_SHADOW_REG_V01]; - uint8_t shadow_reg_v2_valid; - uint32_t shadow_reg_v2_len; - struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01 - shadow_reg_v2[QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01]; + uint8_t shadow_reg_v3_valid; + uint32_t shadow_reg_v3_len; + struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01 + shadow_reg_v3[QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01]; }; struct qmi_wlanfw_wlan_cfg_resp_msg_v01 { @@ -6915,38 +7001,51 @@ enum ath12k_qmi_bdf_type { #define HAL_WBM_IDLE_SCATTER_BUF_SIZE (HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX - \ HAL_WBM_IDLE_SCATTER_NEXT_PTR_SIZE) -#define HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX 48 +#define HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX 32 #define HAL_DSCP_TID_TBL_SIZE 24 /* calculate the register address from bar0 of shadow register x */ -#define HAL_SHADOW_BASE_ADDR(sc) \ - (sc->hw_params.regs->hal_shadow_base_addr) -#define HAL_SHADOW_NUM_REGS 36 +#define HAL_SHADOW_BASE_ADDR 0x000008fc +#define HAL_SHADOW_NUM_REGS 40 #define HAL_HP_OFFSET_IN_REG_START 1 #define HAL_OFFSET_FROM_HP_TO_TP 4 -#define HAL_SHADOW_REG(sc, x) (HAL_SHADOW_BASE_ADDR(sc) + (4 * (x))) +#define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x))) enum hal_srng_ring_id { - HAL_SRNG_RING_ID_REO2SW1 = 0, + HAL_SRNG_RING_ID_REO2SW0 = 0, + HAL_SRNG_RING_ID_REO2SW1, HAL_SRNG_RING_ID_REO2SW2, HAL_SRNG_RING_ID_REO2SW3, HAL_SRNG_RING_ID_REO2SW4, + HAL_SRNG_RING_ID_REO2SW5, + HAL_SRNG_RING_ID_REO2SW6, + HAL_SRNG_RING_ID_REO2SW7, + HAL_SRNG_RING_ID_REO2SW8, HAL_SRNG_RING_ID_REO2TCL, - HAL_SRNG_RING_ID_SW2REO, + HAL_SRNG_RING_ID_REO2PPE, - HAL_SRNG_RING_ID_REO_CMD = 8, + HAL_SRNG_RING_ID_SW2REO = 16, + HAL_SRNG_RING_ID_SW2REO1, + HAL_SRNG_RING_ID_SW2REO2, + HAL_SRNG_RING_ID_SW2REO3, + + HAL_SRNG_RING_ID_REO_CMD, HAL_SRNG_RING_ID_REO_STATUS, - HAL_SRNG_RING_ID_SW2TCL1 = 16, + HAL_SRNG_RING_ID_SW2TCL1 = 24, HAL_SRNG_RING_ID_SW2TCL2, HAL_SRNG_RING_ID_SW2TCL3, HAL_SRNG_RING_ID_SW2TCL4, + HAL_SRNG_RING_ID_SW2TCL5, + HAL_SRNG_RING_ID_SW2TCL6, + HAL_SRNG_RING_ID_PPE2TCL1 = 30, - HAL_SRNG_RING_ID_SW2TCL_CMD = 24, + HAL_SRNG_RING_ID_SW2TCL_CMD = 40, + HAL_SRNG_RING_ID_SW2TCL1_CMD, HAL_SRNG_RING_ID_TCL_STATUS, - HAL_SRNG_RING_ID_CE0_SRC = 32, + HAL_SRNG_RING_ID_CE0_SRC = 64, HAL_SRNG_RING_ID_CE1_SRC, HAL_SRNG_RING_ID_CE2_SRC, HAL_SRNG_RING_ID_CE3_SRC, @@ -6958,8 +7057,12 @@ enum hal_srng_ring_id { HAL_SRNG_RING_ID_CE9_SRC, HAL_SRNG_RING_ID_CE10_SRC, HAL_SRNG_RING_ID_CE11_SRC, + HAL_SRNG_RING_ID_CE12_SRC, + HAL_SRNG_RING_ID_CE13_SRC, + HAL_SRNG_RING_ID_CE14_SRC, + HAL_SRNG_RING_ID_CE15_SRC, - HAL_SRNG_RING_ID_CE0_DST = 56, + HAL_SRNG_RING_ID_CE0_DST = 81, HAL_SRNG_RING_ID_CE1_DST, HAL_SRNG_RING_ID_CE2_DST, HAL_SRNG_RING_ID_CE3_DST, @@ -6971,8 +7074,12 @@ enum hal_srng_ring_id { HAL_SRNG_RING_ID_CE9_DST, HAL_SRNG_RING_ID_CE10_DST, HAL_SRNG_RING_ID_CE11_DST, + HAL_SRNG_RING_ID_CE12_DST, + HAL_SRNG_RING_ID_CE13_DST, + HAL_SRNG_RING_ID_CE14_DST, + HAL_SRNG_RING_ID_CE15_DST, - HAL_SRNG_RING_ID_CE0_DST_STATUS = 80, + HAL_SRNG_RING_ID_CE0_DST_STATUS = 100, HAL_SRNG_RING_ID_CE1_DST_STATUS, HAL_SRNG_RING_ID_CE2_DST_STATUS, HAL_SRNG_RING_ID_CE3_DST_STATUS, @@ -6984,29 +7091,54 @@ enum hal_srng_ring_id { HAL_SRNG_RING_ID_CE9_DST_STATUS, HAL_SRNG_RING_ID_CE10_DST_STATUS, HAL_SRNG_RING_ID_CE11_DST_STATUS, + HAL_SRNG_RING_ID_CE12_DST_STATUS, + HAL_SRNG_RING_ID_CE13_DST_STATUS, + HAL_SRNG_RING_ID_CE14_DST_STATUS, + HAL_SRNG_RING_ID_CE15_DST_STATUS, - HAL_SRNG_RING_ID_WBM_IDLE_LINK = 104, - HAL_SRNG_RING_ID_WBM_SW_RELEASE, - HAL_SRNG_RING_ID_WBM2SW0_RELEASE, + HAL_SRNG_RING_ID_WBM_IDLE_LINK = 120, + HAL_SRNG_RING_ID_WBM_SW0_RELEASE, + HAL_SRNG_RING_ID_WBM_SW1_RELEASE, + HAL_SRNG_RING_ID_WBM_PPE_RELEASE = 123, + + HAL_SRNG_RING_ID_WBM2SW0_RELEASE = 128, HAL_SRNG_RING_ID_WBM2SW1_RELEASE, HAL_SRNG_RING_ID_WBM2SW2_RELEASE, - HAL_SRNG_RING_ID_WBM2SW3_RELEASE, + HAL_SRNG_RING_ID_WBM2SW3_RELEASE, /* RX ERROR RING */ HAL_SRNG_RING_ID_WBM2SW4_RELEASE, + HAL_SRNG_RING_ID_WBM2SW5_RELEASE, + HAL_SRNG_RING_ID_WBM2SW6_RELEASE, + HAL_SRNG_RING_ID_WBM2SW7_RELEASE, - HAL_SRNG_RING_ID_UMAC_ID_END = 127, - HAL_SRNG_RING_ID_LMAC1_ID_START, + HAL_SRNG_RING_ID_UMAC_ID_END = 159, + + /* Common DMAC rings shared by all LMACs */ + HAL_SRNG_RING_ID_DMAC_CMN_ID_START = 160, + HAL_SRNG_SW2RXDMA_BUF0 = + HAL_SRNG_RING_ID_DMAC_CMN_ID_START, + HAL_SRNG_SW2RXDMA_BUF1 = 161, + HAL_SRNG_SW2RXDMA_BUF2 = 162, + + HAL_SRNG_SW2RXMON_BUF0 = 168, + + HAL_SRNG_SW2TXMON_BUF0 = 176, + + HAL_SRNG_RING_ID_DMAC_CMN_ID_END = 183, + HAL_SRNG_RING_ID_PMAC1_ID_START = 184, + + HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0 = + HAL_SRNG_RING_ID_PMAC1_ID_START, - HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF = HAL_SRNG_RING_ID_LMAC1_ID_START, - HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_BUF, - HAL_SRNG_RING_ID_WMAC1_SW2RXDMA2_BUF, - HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_STATBUF, - HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, HAL_SRNG_RING_ID_WMAC1_RXDMA2SW1, + HAL_SRNG_RING_ID_WMAC1_RXMON2SW0 = + HAL_SRNG_RING_ID_WMAC1_RXDMA2SW1, HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_DESC, HAL_SRNG_RING_ID_RXDMA_DIR_BUF, + HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, + HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, - HAL_SRNG_RING_ID_LMAC1_ID_END = 143 + HAL_SRNG_RING_ID_PMAC1_ID_END, }; /* SRNG registers are split into two groups R0 and R2 */ @@ -7019,11 +7151,21 @@ enum hal_srng_ring_id { #define HAL_SRNG_RINGS_PER_LMAC (HAL_SRNG_RING_ID_LMAC1_ID_END - \ HAL_SRNG_RING_ID_LMAC1_ID_START) #define HAL_SRNG_NUM_LMAC_RINGS (HAL_SRNG_NUM_LMACS * HAL_SRNG_RINGS_PER_LMAC) -#define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_UMAC_ID_END + \ - HAL_SRNG_NUM_LMAC_RINGS) + +/* TODO: number of PMACs */ +#define HAL_SRNG_NUM_PMACS 3 +#define HAL_SRNG_NUM_DMAC_RINGS \ + (HAL_SRNG_RING_ID_DMAC_CMN_ID_END - \ + HAL_SRNG_RING_ID_DMAC_CMN_ID_START) +#define HAL_SRNG_RINGS_PER_PMAC (HAL_SRNG_RING_ID_PMAC1_ID_END - \ + HAL_SRNG_RING_ID_PMAC1_ID_START) +#define HAL_SRNG_NUM_PMAC_RINGS (HAL_SRNG_NUM_PMACS * HAL_SRNG_RINGS_PER_PMAC) +#define HAL_SRNG_RING_ID_MAX \ + (HAL_SRNG_RING_ID_DMAC_CMN_ID_END + HAL_SRNG_NUM_PMAC_RINGS) #define HAL_RX_MAX_BA_WINDOW 256 +#define ATH12K_HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000) #define HAL_DEFAULT_REO_TIMEOUT_USEC (40 * 1000) /** @@ -7077,29 +7219,23 @@ enum hal_reo_cmd_status { #define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 -#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(sc) \ - (sc->hw_params.regs->hal_seq_wcss_umac_ce0_src_reg) -#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(sc) \ - (sc->hw_params.regs->hal_seq_wcss_umac_ce0_dst_reg) -#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(sc) \ - (sc->hw_params.regs->hal_seq_wcss_umac_ce1_src_reg) -#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(sc) \ - (sc->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg) +#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG 0x01b80000 +#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG 0x01b81000 +#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG 0x01b82000 +#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG 0x01b83000 #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 -#define HAL_WLAON_REG_BASE 0x01f80000 + +#define HAL_TCL_SW_CONFIG_BANK_ADDR 0x00a4408c /* SW2TCL(x) R0 ring configuration address */ -#define HAL_TCL1_RING_CMN_CTRL_REG 0x00000014 -#define HAL_TCL1_RING_DSCP_TID_MAP 0x0000002c -#define HAL_TCL1_RING_BASE_LSB(sc) \ - (sc->hw_params.regs->hal_tcl1_ring_base_lsb) -#define HAL_TCL1_RING_BASE_MSB(sc) \ - (sc->hw_params.regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(sc) \ - (sc->hw_params.regs->hal_tcl1_ring_id) -#define HAL_TCL1_RING_MISC(sc) \ +#define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 +#define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 +#define HAL_TCL1_RING_BASE_LSB 0x00000900 +#define HAL_TCL1_RING_BASE_MSB 0x00000904 +#define HAL_TCL1_RING_ID(sc) (sc->hw_params.regs->hal_tcl1_ring_id) +#define HAL_TCL1_RING_MISC(sc) \ (sc->hw_params.regs->hal_tcl1_ring_misc) #define HAL_TCL1_RING_TP_ADDR_LSB(sc) \ (sc->hw_params.regs->hal_tcl1_ring_tp_addr_lsb) @@ -7115,62 +7251,77 @@ enum hal_reo_cmd_status { (sc->hw_params.regs->hal_tcl1_ring_msi1_base_msb) #define HAL_TCL1_RING_MSI1_DATA(sc) \ (sc->hw_params.regs->hal_tcl1_ring_msi1_data) -#define HAL_TCL2_RING_BASE_LSB(sc) \ - (sc->hw_params.regs->hal_tcl2_ring_base_lsb) -#define HAL_TCL_RING_BASE_LSB(sc) \ +#define HAL_TCL2_RING_BASE_LSB 0x00000978 +#define HAL_TCL_RING_BASE_LSB(sc) \ (sc->hw_params.regs->hal_tcl_ring_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(sc) \ - (HAL_TCL1_RING_MSI1_BASE_LSB(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_MSI1_BASE_LSB(sc) - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(sc) \ - (HAL_TCL1_RING_MSI1_BASE_MSB(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_MSI1_BASE_MSB(sc) - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_MSI1_DATA_OFFSET(sc) \ - (HAL_TCL1_RING_MSI1_DATA(sc) - HAL_TCL1_RING_BASE_LSB(sc)) -#define HAL_TCL1_RING_BASE_MSB_OFFSET(sc) \ - (HAL_TCL1_RING_BASE_MSB(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_MSI1_DATA(sc) - HAL_TCL1_RING_BASE_LSB) +#define HAL_TCL1_RING_BASE_MSB_OFFSET \ + (HAL_TCL1_RING_BASE_MSB - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_ID_OFFSET(sc) \ - (HAL_TCL1_RING_ID(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_ID(sc) - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(sc) \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(sc) - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(sc) \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(sc) - \ - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(sc) - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(sc) \ - (HAL_TCL1_RING_TP_ADDR_LSB(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_TP_ADDR_LSB(sc) - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(sc) \ - (HAL_TCL1_RING_TP_ADDR_MSB(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_TP_ADDR_MSB(sc) - HAL_TCL1_RING_BASE_LSB) #define HAL_TCL1_RING_MISC_OFFSET(sc) \ - (HAL_TCL1_RING_MISC(sc) - HAL_TCL1_RING_BASE_LSB(sc)) + (HAL_TCL1_RING_MISC(sc) - HAL_TCL1_RING_BASE_LSB) /* SW2TCL(x) R2 ring pointers (head/tail) address */ #define HAL_TCL1_RING_HP 0x00002000 #define HAL_TCL1_RING_TP 0x00002004 #define HAL_TCL2_RING_HP 0x00002008 -#define HAL_TCL_RING_HP 0x00002018 +#define HAL_TCL_RING_HP 0x00002028 #define HAL_TCL1_RING_TP_OFFSET \ (HAL_TCL1_RING_TP - HAL_TCL1_RING_HP) /* TCL STATUS ring address */ -#define HAL_TCL_STATUS_RING_BASE_LSB(sc) \ +#define HAL_TCL_STATUS_RING_BASE_LSB(sc) \ (sc->hw_params.regs->hal_tcl_status_ring_base_lsb) -#define HAL_TCL_STATUS_RING_HP 0x00002030 +#define HAL_TCL_STATUS_RING_HP 0x00002048 + +/* PPE2TCL1 Ring address */ +#define HAL_TCL_PPE2TCL1_RING_BASE_LSB 0x00000c48 +#define HAL_TCL_PPE2TCL1_RING_HP 0x00002038 + +/* WBM PPE Release Ring address */ +#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_ppe_rel_ring_base) +#define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 +#define HAL_REO1_MISC_CTRL_ADDR(sc) \ + (sc->hw_params.regs->hal_reo1_misc_ctrl_addr) #define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 #define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_MISC_CTL(sc) \ - (sc->hw_params.regs->hal_reo1_misc_ctl) -#define HAL_REO1_RING_BASE_LSB(sc) \ +#define HAL_REO1_SW_COOKIE_CFG0(sc) \ + (sc->hw_params.regs->hal_reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(sc) \ + (sc->hw_params.regs->hal_reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(sc) \ + (sc->hw_params.regs->hal_reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(sc) \ + (sc->hw_params.regs->hal_reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(sc) \ (sc->hw_params.regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(sc) \ +#define HAL_REO1_RING_BASE_MSB(sc) \ (sc->hw_params.regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(sc) \ +#define HAL_REO1_RING_ID(sc) \ (sc->hw_params.regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(sc) \ +#define HAL_REO1_RING_MISC(sc) \ (sc->hw_params.regs->hal_reo1_ring_misc) #define HAL_REO1_RING_HP_ADDR_LSB(sc) \ (sc->hw_params.regs->hal_reo1_ring_hp_addr_lsb) @@ -7184,73 +7335,69 @@ enum hal_reo_cmd_status { (sc->hw_params.regs->hal_reo1_ring_msi1_base_msb) #define HAL_REO1_RING_MSI1_DATA(sc) \ (sc->hw_params.regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(sc) \ - (sc->hw_params.regs->hal_reo2_ring_base_lsb) +#define HAL_REO2_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_reo2_ring_base) #define HAL_REO1_AGING_THRESH_IX_0(sc) \ - (sc->hw_params.regs->hal_reo1_aging_thresh_ix_0) + (sc->hw_params.regs->hal_reo1_aging_thres_ix0) #define HAL_REO1_AGING_THRESH_IX_1(sc) \ - (sc->hw_params.regs->hal_reo1_aging_thresh_ix_1) + (sc->hw_params.regs->hal_reo1_aging_thres_ix1) #define HAL_REO1_AGING_THRESH_IX_2(sc) \ - (sc->hw_params.regs->hal_reo1_aging_thresh_ix_2) + (sc->hw_params.regs->hal_reo1_aging_thres_ix2) #define HAL_REO1_AGING_THRESH_IX_3(sc) \ - (sc->hw_params.regs->hal_reo1_aging_thresh_ix_3) + (sc->hw_params.regs->hal_reo1_aging_thres_ix3) #define HAL_REO1_RING_MSI1_BASE_LSB_OFFSET(sc) \ - (HAL_REO1_RING_MSI1_BASE_LSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) + (HAL_REO1_RING_MSI1_BASE_LSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) #define HAL_REO1_RING_MSI1_BASE_MSB_OFFSET(sc) \ - (HAL_REO1_RING_MSI1_BASE_MSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) + (HAL_REO1_RING_MSI1_BASE_MSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) #define HAL_REO1_RING_MSI1_DATA_OFFSET(sc) \ - (HAL_REO1_RING_MSI1_DATA(sc) - HAL_REO1_RING_BASE_LSB(sc)) + (HAL_REO1_RING_MSI1_DATA(sc) - HAL_REO1_RING_BASE_LSB(sc)) #define HAL_REO1_RING_BASE_MSB_OFFSET(sc) \ - (HAL_REO1_RING_BASE_MSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) -#define HAL_REO1_RING_ID_OFFSET(sc) (HAL_REO1_RING_ID(sc) - \ - HAL_REO1_RING_BASE_LSB(sc)) + (HAL_REO1_RING_BASE_MSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) +#define HAL_REO1_RING_ID_OFFSET(sc) \ + (HAL_REO1_RING_ID(sc) - HAL_REO1_RING_BASE_LSB(sc)) #define HAL_REO1_RING_PRODUCER_INT_SETUP_OFFSET(sc) \ - (HAL_REO1_RING_PRODUCER_INT_SETUP(sc) - \ - HAL_REO1_RING_BASE_LSB(sc)) + (HAL_REO1_RING_PRODUCER_INT_SETUP(sc) - HAL_REO1_RING_BASE_LSB(sc)) #define HAL_REO1_RING_HP_ADDR_LSB_OFFSET(sc) \ - (HAL_REO1_RING_HP_ADDR_LSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) + (HAL_REO1_RING_HP_ADDR_LSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) #define HAL_REO1_RING_HP_ADDR_MSB_OFFSET(sc) \ - (HAL_REO1_RING_HP_ADDR_MSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) + (HAL_REO1_RING_HP_ADDR_MSB(sc) - HAL_REO1_RING_BASE_LSB(sc)) #define HAL_REO1_RING_MISC_OFFSET(sc) \ (HAL_REO1_RING_MISC(sc) - HAL_REO1_RING_BASE_LSB(sc)) /* REO2SW(x) R2 ring pointers (head/tail) address */ -#define HAL_REO1_RING_HP(sc) \ - (sc->hw_params.regs->hal_reo1_ring_hp) -#define HAL_REO1_RING_TP(sc) \ - (sc->hw_params.regs->hal_reo1_ring_tp) -#define HAL_REO2_RING_HP(sc) \ - (sc->hw_params.regs->hal_reo2_ring_hp) +#define HAL_REO1_RING_HP 0x00003048 +#define HAL_REO1_RING_TP 0x0000304c +#define HAL_REO2_RING_HP 0x00003050 -#define HAL_REO1_RING_TP_OFFSET(sc) \ - (HAL_REO1_RING_TP(sc) - HAL_REO1_RING_HP(sc)) +#define HAL_REO1_RING_TP_OFFSET (HAL_REO1_RING_TP - HAL_REO1_RING_HP) -/* REO2TCL R0 ring configuration address */ -#define HAL_REO_TCL_RING_BASE_LSB(sc) \ - (sc->hw_params.regs->hal_reo_tcl_ring_base_lsb) +/* REO2SW0 ring configuration address */ +#define HAL_REO_SW0_RING_BASE_LSB(sc) \ + ((sc)->hw_params.regs->hal_reo2_sw0_ring_base) -/* REO2TCL R2 ring pointer (head/tail) address */ -#define HAL_REO_TCL_RING_HP(sc) \ - (sc->hw_params.regs->hal_reo_tcl_ring_hp) +/* REO2SW0 R2 ring pointer (head/tail) address */ +#define HAL_REO_SW0_RING_HP 0x00003088 /* REO CMD R0 address */ #define HAL_REO_CMD_RING_BASE_LSB(sc) \ - (sc->hw_params.regs->hal_reo_cmd_ring_base_lsb) + (sc->hw_params.regs->hal_reo_cmd_ring_base) /* REO CMD R2 address */ -#define HAL_REO_CMD_HP(sc) \ - (sc->hw_params.regs->hal_reo_cmd_ring_hp) +#define HAL_REO_CMD_HP 0x00003020 /* SW2REO R0 address */ #define HAL_SW2REO_RING_BASE_LSB(sc) \ - (sc->hw_params.regs->hal_sw2reo_ring_base_lsb) + (sc->hw_params.regs->hal_sw2reo_ring_base) +#define HAL_SW2REO1_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_sw2reo1_ring_base) /* SW2REO R2 address */ -#define HAL_SW2REO_RING_HP(sc) \ - (sc->hw_params.regs->hal_sw2reo_ring_hp) +#define HAL_SW2REO_RING_HP 0x00003028 +#define HAL_SW2REO1_RING_HP 0x00003030 /* CE ring R0 address */ +#define HAL_CE_SRC_RING_BASE_LSB 0x00000000 #define HAL_CE_DST_RING_BASE_LSB 0x00000000 #define HAL_CE_DST_STATUS_RING_BASE_LSB 0x00000058 #define HAL_CE_DST_RING_CTRL 0x000000b0 @@ -7261,49 +7408,83 @@ enum hal_reo_cmd_status { /* REO status address */ #define HAL_REO_STATUS_RING_BASE_LSB(sc) \ - (sc->hw_params.regs->hal_reo_status_ring_base_lsb) -#define HAL_REO_STATUS_HP(sc) \ - (sc->hw_params.regs->hal_reo_status_hp) + (sc->hw_params.regs->hal_reo_status_ring_base) +#define HAL_REO_STATUS_HP 0x000030a8 /* WBM Idle R0 address */ -#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(x) \ - (sc->hw_params.regs->hal_wbm_idle_link_ring_base_lsb) -#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(x) \ - (sc->hw_params.regs->hal_wbm_idle_link_ring_misc) -#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR 0x00000048 -#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR 0x0000004c -#define HAL_WBM_SCATTERED_RING_BASE_LSB 0x00000058 -#define HAL_WBM_SCATTERED_RING_BASE_MSB 0x0000005c -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0 0x00000068 -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1 0x0000006c -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0 0x00000078 -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1 0x0000007c -#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR 0x00000084 +#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_wbm_idle_ring_base_lsb) +#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(sc) \ + (sc->hw_params.regs->hal_wbm_idle_ring_misc_addr) +#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(sc) \ + (sc->hw_params.regs->hal_wbm_r0_idle_list_cntl_addr) +#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(sc) \ + (sc->hw_params.regs->hal_wbm_r0_idle_list_size_addr) +#define HAL_WBM_SCATTERED_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_wbm_scattered_ring_base_lsb) +#define HAL_WBM_SCATTERED_RING_BASE_MSB(sc) \ + (sc->hw_params.regs->hal_wbm_scattered_ring_base_msb) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(sc) \ + (sc->hw_params.regs->hal_wbm_scattered_desc_head_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(sc) \ + (sc->hw_params.regs->hal_wbm_scattered_desc_head_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(sc) \ + (sc->hw_params.regs->hal_wbm_scattered_desc_tail_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(sc) \ + (sc->hw_params.regs->hal_wbm_scattered_desc_tail_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(sc) \ + (sc->hw_params.regs->hal_wbm_scattered_desc_ptr_hp_addr) /* WBM Idle R2 address */ -#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b0 +#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 /* SW2WBM R0 release address */ -#define HAL_WBM_RELEASE_RING_BASE_LSB(x) \ - (sc->hw_params.regs->hal_wbm_release_ring_base_lsb) +#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_wbm_sw_release_ring_base_lsb) +#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_wbm_sw1_release_ring_base_lsb) /* SW2WBM R2 release address */ -#define HAL_WBM_RELEASE_RING_HP 0x00003018 +#define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 +#define HAL_WBM_SW1_RELEASE_RING_HP 0x00003018 /* WBM2SW R0 release address */ -#define HAL_WBM0_RELEASE_RING_BASE_LSB(x) \ - (sc->hw_params.regs->hal_wbm0_release_ring_base_lsb) -#define HAL_WBM1_RELEASE_RING_BASE_LSB(x) \ - (sc->hw_params.regs->hal_wbm1_release_ring_base_lsb) +#define HAL_WBM0_RELEASE_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_wbm0_release_ring_base_lsb) + +#define HAL_WBM1_RELEASE_RING_BASE_LSB(sc) \ + (sc->hw_params.regs->hal_wbm1_release_ring_base_lsb) /* WBM2SW R2 release address */ -#define HAL_WBM0_RELEASE_RING_HP 0x000030c0 -#define HAL_WBM1_RELEASE_RING_HP 0x000030c8 +#define HAL_WBM0_RELEASE_RING_HP 0x000030c8 +#define HAL_WBM1_RELEASE_RING_HP 0x000030d0 + +/* WBM cookie config address and mask */ +#define HAL_WBM_SW_COOKIE_CFG0 0x00000040 +#define HAL_WBM_SW_COOKIE_CFG1 0x00000044 +#define HAL_WBM_SW_COOKIE_CFG2 0x00000090 +#define HAL_WBM_SW_COOKIE_CONVERT_CFG 0x00000094 + +#define HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) +#define HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) +#define HAL_WBM_SW_COOKIE_CFG_ALIGN BIT(18) +#define HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN BIT(0) +#define HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN BIT(1) +#define HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN BIT(3) + +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN BIT(1) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN BIT(2) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN BIT(3) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN BIT(4) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN BIT(5) +#define HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN BIT(8) /* TCL ring field mask and offset */ #define HAL_TCL1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) #define HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) #define HAL_TCL1_RING_ID_ENTRY_SIZE GENMASK(7, 0) +#define HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE BIT(0) #define HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE BIT(1) #define HAL_TCL1_RING_MISC_MSI_SWAP BIT(3) #define HAL_TCL1_RING_MISC_HOST_FW_SWAP BIT(4) @@ -7314,7 +7495,7 @@ enum hal_reo_cmd_status { #define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD GENMASK(15, 0) #define HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) #define HAL_TCL1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) -#define HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN BIT(17) +#define HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN BIT(23) #define HAL_TCL1_RING_FIELD_DSCP_TID_MAP GENMASK(31, 0) #define HAL_TCL1_RING_FIELD_DSCP_TID_MAP0 GENMASK(2, 0) #define HAL_TCL1_RING_FIELD_DSCP_TID_MAP1 GENMASK(5, 3) @@ -7338,10 +7519,16 @@ enum hal_reo_cmd_status { #define HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD GENMASK(14, 0) #define HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) #define HAL_REO1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) -#define HAL_REO1_GEN_ENABLE_FRAG_DST_RING GENMASK(25, 23) +#define HAL_REO1_MISC_CTL_FRAG_DST_RING GENMASK(20, 17) +#define HAL_REO1_MISC_CTL_BAR_DST_RING GENMASK(24, 21) #define HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE BIT(2) #define HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE BIT(3) -#define HAL_REO1_MISC_CTL_FRAGMENT_DST_RING GENMASK(20, 17) +#define HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) +#define HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) +#define HAL_REO1_SW_COOKIE_CFG_ALIGN BIT(18) +#define HAL_REO1_SW_COOKIE_CFG_ENABLE BIT(19) +#define HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE BIT(20) /* CE ring bit field mask and shift */ #define HAL_CE_DST_R0_DEST_CTRL_MAX_LEN GENMASK(15, 0) @@ -7360,10 +7547,13 @@ enum hal_reo_cmd_status { #define HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1 GENMASK(20, 8) #define HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1 GENMASK(20, 8) +#define HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE BIT(6) +#define HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE BIT(0) + #define BASE_ADDR_MATCH_TAG_VAL 0x5 #define HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_REO_REO2TCL_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE 0x000fffff #define HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE 0x0000ffff #define HAL_REO_CMD_RING_BASE_MSB_RING_SIZE 0x0000ffff #define HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff @@ -7373,14 +7563,14 @@ enum hal_reo_cmd_status { #define HAL_CE_SRC_RING_BASE_MSB_RING_SIZE 0x0000ffff #define HAL_CE_DST_RING_BASE_MSB_RING_SIZE 0x0000ffff #define HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE 0x000fffff #define HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE 0x0000ffff #define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff #define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff +#define HAL_RXDMA_RING_MAX_SIZE_BE 0x000fffff +#define HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff -/* IPQ5018 ce registers */ -#define HAL_IPQ5018_CE_WFSS_REG_BASE 0x08400000 -#define HAL_IPQ5018_CE_SIZE 0x200000 +#define HAL_WBM2SW_REL_ERR_RING_NUM 3 #define BUFFER_ADDR_INFO0_ADDR GENMASK(31, 0) @@ -7858,6 +8048,14 @@ struct hal_tlv_hdr { uint8_t value[]; } __packed; +#define HAL_TLV_64_HDR_TAG GENMASK(9, 1) +#define HAL_TLV_64_HDR_LEN GENMASK(21, 10) + +struct hal_tlv_64_hdr { + uint64_t tl; + uint8_t value[]; +} __packed; + #define RX_MPDU_DESC_INFO0_MSDU_COUNT 0xff #define RX_MPDU_DESC_INFO0_SEQ_NUM 0xfff00 #define RX_MPDU_DESC_INFO0_FRAG_FLAG (1 << 20) @@ -8021,6 +8219,88 @@ struct rx_msdu_desc { * to the expiration of search timer for this MSDU. */ +struct ath12k_rx_msdu_desc { + uint32_t info0; +} __packed; + +/* rx_msdu_desc + * + * first_msdu_in_mpdu + * Indicates first msdu in mpdu. + * + * last_msdu_in_mpdu + * Indicates last msdu in mpdu. This flag can be true only when + * 'Msdu_continuation' set to 0. This implies that when an msdu + * is spread out over multiple buffers and thus msdu_continuation + * is set, only for the very last buffer of the msdu, can the + * 'last_msdu_in_mpdu' be set. + * + * When both first_msdu_in_mpdu and last_msdu_in_mpdu are set, + * the MPDU that this MSDU belongs to only contains a single MSDU. + * + * msdu_continuation + * When set, this MSDU buffer was not able to hold the entire MSDU. + * The next buffer will therefore contain additional information + * related to this MSDU. + * + * msdu_length + * Field is only valid in combination with the 'first_msdu_in_mpdu' + * being set. Full MSDU length in bytes after decapsulation. This + * field is still valid for MPDU frames without A-MSDU. It still + * represents MSDU length after decapsulation Or in case of RAW + * MPDUs, it indicates the length of the entire MPDU (without FCS + * field). + * + * msdu_drop + * Indicates that REO shall drop this MSDU and not forward it to + * any other ring. + * + * valid_sa + * Indicates OLE found a valid SA entry for this MSDU. + * + * valid_da + * When set, OLE found a valid DA entry for this MSDU. + * + * da_mcbc + * Field Only valid if valid_da is set. Indicates the DA address + * is a Multicast or Broadcast address for this MSDU. + * + * l3_header_padding_msb + * Passed on from 'RX_MSDU_END' TLV (only the MSB is reported as + * the LSB is always zero). Number of bytes padded to make sure + * that the L3 header will always start of a Dword boundary + * + * tcp_udp_checksum_fail + * Passed on from 'RX_ATTENTION' TLV + * Indicates that the computed checksum did not match the checksum + * in the TCP/UDP header. + * + * ip_checksum_fail + * Passed on from 'RX_ATTENTION' TLV + * Indicates that the computed checksum did not match the checksum + * in the IP header. + * + * from_DS + * Set if the 'from DS' bit is set in the frame control. + * + * to_DS + * Set if the 'to DS' bit is set in the frame control. + * + * intra_bss + * This packet needs intra-BSS routing by SW as the 'vdev_id' + * for the destination is the same as the 'vdev_id' that this + * MSDU was got in. + * + * dest_chip_id + * If intra_bss is set, copied by RXOLE/RXDMA from 'ADDR_SEARCH_ENTRY' + * to support intra-BSS routing with multi-chip multi-link operation. + * This indicates into which chip's TCL the packet should be queued. + * + * decap_format + * Indicates the format after decapsulation: + */ + + enum hal_reo_dest_ring_buffer_type { HAL_REO_DEST_RING_BUFFER_TYPE_MSDU, HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC, @@ -8140,6 +8420,87 @@ struct hal_reo_dest_ring { * this ring has looped around the ring. */ +struct ath12k_hal_reo_dest_ring { + struct ath12k_buffer_addr buf_addr_info; + struct rx_mpdu_desc rx_mpdu_info; + struct ath12k_rx_msdu_desc rx_msdu_info; + uint32_t buf_va_lo; + uint32_t buf_va_hi; + uint32_t info0; /* %HAL_REO_DEST_RING_INFO0_ */ +} __packed; + +/* hal_reo_dest_ring + * + * Producer: RXDMA + * Consumer: REO/SW/FW + * + * buf_addr_info + * Details of the physical address of a buffer or MSDU + * link descriptor. + * + * rx_mpdu_info + * General information related to the MPDU that is passed + * on from REO entrance ring to the REO destination ring. + * + * rx_msdu_info + * General information related to the MSDU that is passed + * on from RXDMA all the way to the REO destination ring. + * + * buf_va_lo + * Field only valid if Reo_dest_buffer_type is set to + * MSDU_buf_address. + * Lower 32 bits of the 64-bit virtual address corresponding + * to Buf_or_link_desc_addr_info + * + * buf_va_hi + * Address (upper 32 bits) of the REO queue descriptor. + * Upper 32 bits of the 64-bit virtual address corresponding + * to Buf_or_link_desc_addr_info + * + * buffer_type + * Indicates the type of address provided in the buf_addr_info. + * Values are defined in enum %HAL_REO_DEST_RING_BUFFER_TYPE_. + * + * push_reason + * Reason for pushing this frame to this exit ring. Values are + * defined in enum %HAL_REO_DEST_RING_PUSH_REASON_. + * + * error_code + * Valid only when 'push_reason' is set. All error codes are + * defined in enum %HAL_REO_DEST_RING_ERROR_CODE_. + * + * captured_msdu_data_size + * The number of following REO_DESTINATION STRUCTs that have + * been replaced with msdu_data extracted from the msdu_buffer + * and copied into the ring for easy FW/SW access. + * + * sw_exception + * This field has the same setting as the SW_exception field + * in the corresponding REO_entrance_ring descriptor. + * When set, the REO entrance descriptor is generated by FW, + * and the MPDU was processed in the following way: + * - NO re-order function is needed. + * - MPDU delinking is determined by the setting of Entrance + * ring field: SW_excection_mpdu_delink + * - Destination ring selection is based on the setting of + * the Entrance ring field SW_exception_destination _ring_valid + * + * src_link_id + * Set to the link ID of the PMAC that received the frame + * + * signature + * Set to value 0x8 when msdu capture mode is enabled for this ring + * + * ring_id + * The buffer pointer ring id. + * 0 - Idle ring + * 1 - N refers to other rings. + * + * looping_count + * Indicates the number of times the producer of entries into + * this ring has looped around the ring. + */ + enum hal_reo_entr_rxdma_ecode { HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR, HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR, @@ -8173,7 +8534,6 @@ struct hal_reo_entrance_ring { uint32_t info0; /* %HAL_REO_ENTR_RING_INFO0_ */ uint32_t info1; /* %HAL_REO_ENTR_RING_INFO1_ */ uint32_t info2; /* %HAL_REO_DEST_RING_INFO2_ */ - } __packed; /* hal_reo_entrance_ring @@ -8347,6 +8707,7 @@ struct hal_reo_get_queue_stats { uint32_t queue_addr_lo; uint32_t info0; uint32_t rsvd0[6]; + uint32_t tlv64_pad; } __packed; /* hal_reo_get_queue_stats @@ -8483,6 +8844,7 @@ struct hal_tcl_data_cmd { uint32_t info2; uint32_t info3; uint32_t info4; + uint32_t info5; } __packed; /* hal_tcl_data_cmd @@ -8491,41 +8853,29 @@ struct hal_tcl_data_cmd { * Details of the physical address of a buffer or MSDU * link descriptor. * + * tcl_cmd_type + * used to select the type of TCL Command descriptor + * * desc_type * Indicates the type of address provided in the buf_addr_info. * Values are defined in enum %HAL_REO_DEST_RING_BUFFER_TYPE_. * - * epd - * When this bit is set then input packet is an EPD type. + * bank_id + * used to select one of the TCL register banks for fields removed + * from 'TCL_DATA_CMD' that do not change often within one virtual + * device or a set of virtual devices: * - * encap_type - * Indicates the encapsulation that HW will perform. Values are - * defined in enum %HAL_TCL_ENCAP_TYPE_. + * tx_notify_frame + * TCL copies this value to 'TQM_ENTRANCE_RING' field FW_tx_notify_frame. * - * encrypt_type - * Field only valid for encap_type: RAW - * Values are defined in enum %HAL_ENCRYPT_TYPE_. + * hdr_length_read_sel + * used to select the per 'encap_type' register set for MSDU header + * read length * - * src_buffer_swap - * Treats source memory (packet buffer) organization as big-endian. - * 1'b0: Source memory is little endian - * 1'b1: Source memory is big endian - * - * link_meta_swap - * Treats link descriptor and Metadata as big-endian. - * 1'b0: memory is little endian - * 1'b1: memory is big endian - * - * search_type - * Search type select - * 0 - Normal search, 1 - Index based address search, - * 2 - Index based flow search - * - * addrx_en - * addry_en - * Address X/Y search enable in ASE correspondingly. - * 1'b0: Search disable - * 1'b1: Search Enable + * buffer_timestamp + * buffer_timestamp_valid + * Frame system entrance timestamp. It shall be filled by first + * module (SW, TCL or TQM) that sees the frames first. * * cmd_num * This number can be used to match against status. @@ -8547,18 +8897,6 @@ struct hal_tcl_data_cmd { * packet_offset * Packet offset from Metadata in case of direct buffer descriptor. * - * buffer_timestamp - * buffer_timestamp_valid - * Frame system entrance timestamp. It shall be filled by first - * module (SW, TCL or TQM) that sees the frames first. - * - * mesh_enable - * For raw WiFi frames, this indicates transmission to a mesh STA, - * enabling the interpretation of the 'Mesh Control Present' bit - * (bit 8) of QoS Control. - * For native WiFi frames, this indicates that a 'Mesh Control' - * field is present between the header and the LLC. - * * hlos_tid_overwrite * * When set, TCL shall ignore the IP DSCP and VLAN PCP @@ -8566,21 +8904,52 @@ struct hal_tcl_data_cmd { * shall consider the DSCP and PCP fields as well as HLOS_TID * and choose a final TID based on the configured priority * + * flow_override_enable + * TCL uses this to select the flow pointer from the peer table, + * which can be overridden by SW for pre-encrypted raw WiFi packets + * that cannot be parsed for UDP or for other MLO + * 0 - FP_PARSE_IP: Use the flow-pointer based on parsing the IPv4 + * or IPv6 header. + * 1 - FP_USE_OVERRIDE: Use the who_classify_info_sel and + * flow_override fields to select the flow-pointer + * + * who_classify_info_sel + * Field only valid when flow_override_enable is set to FP_USE_OVERRIDE. + * This field is used to select one of the 'WHO_CLASSIFY_INFO's in the + * peer table in case more than 2 flows are mapped to a single TID. + * 0: To choose Flow 0 and 1 of any TID use this value. + * 1: To choose Flow 2 and 3 of any TID use this value. + * 2: To choose Flow 4 and 5 of any TID use this value. + * 3: To choose Flow 6 and 7 of any TID use this value. + * + * If who_classify_info sel is not in sync with the num_tx_classify_info + * field from address search, then TCL will set 'who_classify_info_sel' + * to 0 use flows 0 and 1. + * * hlos_tid * HLOS MSDU priority * Field is used when HLOS_TID_overwrite is set. * - * lmac_id - * TCL uses this LMAC_ID in address search, i.e, while + * flow_override + * Field only valid when flow_override_enable is set to FP_USE_OVERRIDE + * TCL uses this to select the flow pointer from the peer table, + * which can be overridden by SW for pre-encrypted raw WiFi packets + * that cannot be parsed for UDP or for other MLO + * 0 - FP_USE_NON_UDP: Use the non-UDP flow pointer (flow 0) + * 1 - FP_USE_UDP: Use the UDP flow pointer (flow 1) + * + * pmac_id + * TCL uses this PMAC_ID in address search, i.e, while * finding matching entry for the packet in AST corresponding - * to given LMAC_ID + * to given PMAC_ID * - * If LMAC ID is all 1s (=> value 3), it indicates wildcard - * match for any MAC + * If PMAC ID is all 1s (=> value 3), it indicates wildcard + * match for any PMAC * - * dscp_tid_table_num - * DSCP to TID mapping table number that need to be used - * for the MSDU. + * vdev_id + * Virtual device ID to check against the address search entry to + * avoid security issues from transmitting packets from an incorrect + * virtual device * * search_index * The index that will be used for index based address or @@ -8596,6 +8965,11 @@ struct hal_tcl_data_cmd { * anything when the entry pointed by search index will not be * used for content based search. * + * index_loop_override + * When set, address search and packet routing is forced to use + * 'search_index' instead of following the register configuration + * selected by Bank_id. + * * ring_id * The buffer pointer ring ID. * 0 refers to the IDLE ring @@ -9952,6 +10326,62 @@ struct hal_reo_desc_thresh_reached_status { * entries into this Ring has looped around the ring. */ +struct hal_tcl_entrance_from_ppe_ring { + uint32_t buffer_addr; + uint32_t info0; +} __packed; + +struct hal_mon_buf_ring { + uint32_t paddr_lo; + uint32_t paddr_hi; + uint64_t cookie; +}; + +/* hal_mon_buf_ring + * Producer : SW + * Consumer : Monitor + * + * paddr_lo + * Lower 32-bit physical address of the buffer pointer from the source ring. + * paddr_hi + * bit range 7-0 : upper 8 bit of the physical address. + * bit range 31-8 : reserved. + * cookie + * Consumer: RxMon/TxMon 64 bit cookie of the buffers. + */ + +struct hal_mon_dest_desc { + uint32_t cookie; + uint32_t reserved; + uint32_t ppdu_id; + uint32_t info0; +}; + +/* hal_mon_dest_ring + * Producer : TxMon/RxMon + * Consumer : SW + * cookie + * bit 0 -17 buf_id to track the skb's vaddr. + * ppdu_id + * Phy ppdu_id + * end_offset + * The offset into status buffer where DMA ended, ie., offset to the last + * TLV + last TLV size. + * flush_detected + * Indicates whether 'tx_flush' or 'rx_flush' occurred. + * end_of_ppdu + * Indicates end of ppdu. + * pmac_id + * Indicates PMAC that received from frame. + * empty_descriptor + * This descriptor is written on flush or end of ppdu or end of status + * buffer. + * ring_id + * updated by SRNG. + * looping_count + * updated by SRNG. + */ + #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0 0xDDBEEF #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1 0xADBEEF #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2 0xBDBEEF @@ -9963,11 +10393,11 @@ struct hal_reo_desc_thresh_reached_status { #define HAL_TX_ADDR_SEARCH_DEFAULT 0 #define HAL_TX_ADDR_SEARCH_INDEX 1 -/* +/* * Copy Engine */ -#define CE_COUNT_MAX 12 +#define CE_COUNT_MAX 16 /* Byte swap data words */ #define CE_ATTR_BYTE_SWAP_DATA 2 @@ -10232,6 +10662,7 @@ enum ath12k_htc_svc_id { ATH12K_HTC_SVC_ID_WMI_DATA_VO = SVC(ATH12K_HTC_SVC_GRP_WMI, 4), ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1 = SVC(ATH12K_HTC_SVC_GRP_WMI, 5), ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC2 = SVC(ATH12K_HTC_SVC_GRP_WMI, 6), + ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG = SVC(ATH12K_HTC_SVC_GRP_WMI, 7), ATH12K_HTC_SVC_ID_NMI_CONTROL = SVC(ATH12K_HTC_SVC_GRP_NMI, 0), ATH12K_HTC_SVC_ID_NMI_DATA = SVC(ATH12K_HTC_SVC_GRP_NMI, 1), diff --git a/sys/dev/ic/qwzvar.h b/sys/dev/ic/qwzvar.h index ee27c3f30..c17202069 100644 --- a/sys/dev/ic/qwzvar.h +++ b/sys/dev/ic/qwzvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: qwzvar.h,v 1.1 2024/08/14 14:40:46 patrick Exp $ */ +/* $OpenBSD: qwzvar.h,v 1.4 2024/08/16 00:26:54 patrick Exp $ */ /* * Copyright (c) 2018-2019 The Linux Foundation. @@ -64,6 +64,7 @@ struct ath12k_hw_ring_mask { uint8_t reo_status[ATH12K_EXT_IRQ_GRP_NUM_MAX]; uint8_t rxdma2host[ATH12K_EXT_IRQ_GRP_NUM_MAX]; uint8_t host2rxdma[ATH12K_EXT_IRQ_GRP_NUM_MAX]; + uint8_t tx_mon_dest[ATH12K_EXT_IRQ_GRP_NUM_MAX]; }; #define ATH12K_FW_DIR "qwz" @@ -74,7 +75,6 @@ struct ath12k_hw_ring_mask { #define ATH12K_DEFAULT_CAL_FILE "caldata" #define ATH12K_AMSS_FILE "amss" #define ATH12K_M3_FILE "m3" -#define ATH12K_REGDB_FILE "regdb" #define QWZ_FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING=" @@ -88,29 +88,36 @@ struct ath12k_hw_tcl2wbm_rbm_map { * enum hal_rx_buf_return_buf_manager * * @HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST: Buffer returned to WBM idle buffer list - * @HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST: Descriptor returned to WBM idle - * descriptor list. + * @HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST: Descriptor returned to WBM idle + * descriptor list, where the chip 0 WBM is chosen in case of a + * multi-chip config * @HAL_RX_BUF_RBM_FW_BM: Buffer returned to FW * @HAL_RX_BUF_RBM_SW0_BM: For Tx completion -- returned to host * @HAL_RX_BUF_RBM_SW1_BM: For Tx completion -- returned to host * @HAL_RX_BUF_RBM_SW2_BM: For Tx completion -- returned to host * @HAL_RX_BUF_RBM_SW3_BM: For Rx release -- returned to host + * @HAL_RX_BUF_RBM_SW4_BM: For Tx completion -- returned to host + * @HAL_RX_BUF_RBM_SW5_BM: For ring 5 -- returned to host + * @HAL_RX_BUF_RBM_SW6_BM: For ring 6 -- returned to host */ enum hal_rx_buf_return_buf_manager { HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST, - HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST, + HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST, HAL_RX_BUF_RBM_FW_BM, HAL_RX_BUF_RBM_SW0_BM, HAL_RX_BUF_RBM_SW1_BM, HAL_RX_BUF_RBM_SW2_BM, HAL_RX_BUF_RBM_SW3_BM, HAL_RX_BUF_RBM_SW4_BM, + HAL_RX_BUF_RBM_SW5_BM, + HAL_RX_BUF_RBM_SW6_BM, }; struct ath12k_hw_hal_params { enum hal_rx_buf_return_buf_manager rx_buf_rbm; const struct ath12k_hw_tcl2wbm_rbm_map *tcl2wbm_rbm_map; + uint32_t wbm2sw_cc_enable; }; struct hal_tx_info { @@ -190,6 +197,7 @@ struct ath12k_hw_params { bool rxdma1_enable; int num_rxmda_per_pdev; + int num_rxdma_dst_ring; bool rx_mac_buf_ring; bool vdev_start_delay; bool htt_peer_map_v2; @@ -210,37 +218,24 @@ struct ath12k_hw_params { bool supports_shadow_regs; bool idle_ps; bool supports_sta_ps; - bool cold_boot_calib; - bool cbcal_restart_fw; - int fw_mem_mode; uint32_t num_vdevs; uint32_t num_peers; bool supports_suspend; uint32_t hal_desc_sz; - bool supports_regdb; bool fix_l1ss; bool credit_flow; uint8_t max_tx_ring; const struct ath12k_hw_hal_params *hal_params; + uint64_t qmi_cnss_feature_bitmap; #if notyet bool supports_dynamic_smps_6ghz; bool alloc_cacheable_memory; bool supports_rssi_stats; #endif - bool fw_wmi_diag_event; bool current_cc_support; bool dbr_debug_support; - bool global_reset; #ifdef notyet const struct cfg80211_sar_capa *bios_sar_capa; -#endif - bool m3_fw_support; - bool fixed_bdf_addr; - bool fixed_mem_region; - bool static_window_map; - bool hybrid_bus_type; - bool fixed_fw_mem; -#if notyet bool support_off_channel_tx; bool supports_multi_bssid; @@ -312,21 +307,9 @@ struct ath12k_hw_ops { #endif }; -extern const struct ath12k_hw_ops ipq8074_ops; -extern const struct ath12k_hw_ops ipq6018_ops; -extern const struct ath12k_hw_ops qca6390_ops; -extern const struct ath12k_hw_ops qcn9074_ops; -extern const struct ath12k_hw_ops wcn6855_ops; -extern const struct ath12k_hw_ops wcn6750_ops; - -extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_ipq8074; -extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qca6390; -extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9074; -extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn6750; +extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850; struct ath12k_hw_regs { - uint32_t hal_tcl1_ring_base_lsb; - uint32_t hal_tcl1_ring_base_msb; uint32_t hal_tcl1_ring_id; uint32_t hal_tcl1_ring_misc; uint32_t hal_tcl1_ring_tp_addr_lsb; @@ -336,11 +319,38 @@ struct ath12k_hw_regs { uint32_t hal_tcl1_ring_msi1_base_lsb; uint32_t hal_tcl1_ring_msi1_base_msb; uint32_t hal_tcl1_ring_msi1_data; - uint32_t hal_tcl2_ring_base_lsb; uint32_t hal_tcl_ring_base_lsb; uint32_t hal_tcl_status_ring_base_lsb; + uint32_t hal_wbm_idle_ring_base_lsb; + uint32_t hal_wbm_idle_ring_misc_addr; + uint32_t hal_wbm_r0_idle_list_cntl_addr; + uint32_t hal_wbm_r0_idle_list_size_addr; + uint32_t hal_wbm_scattered_ring_base_lsb; + uint32_t hal_wbm_scattered_ring_base_msb; + uint32_t hal_wbm_scattered_desc_head_info_ix0; + uint32_t hal_wbm_scattered_desc_head_info_ix1; + uint32_t hal_wbm_scattered_desc_tail_info_ix0; + uint32_t hal_wbm_scattered_desc_tail_info_ix1; + uint32_t hal_wbm_scattered_desc_ptr_hp_addr; + + uint32_t hal_wbm_sw_release_ring_base_lsb; + uint32_t hal_wbm_sw1_release_ring_base_lsb; + uint32_t hal_wbm0_release_ring_base_lsb; + uint32_t hal_wbm1_release_ring_base_lsb; + + uint32_t pcie_qserdes_sysclk_en_sel; + uint32_t pcie_pcs_osc_dtct_config_base; + + uint32_t hal_ppe_rel_ring_base; + + uint32_t hal_reo2_ring_base; + uint32_t hal_reo1_misc_ctrl_addr; + uint32_t hal_reo1_sw_cookie_cfg0; + uint32_t hal_reo1_sw_cookie_cfg1; + uint32_t hal_reo1_qdesc_lut_base0; + uint32_t hal_reo1_qdesc_lut_base1; uint32_t hal_reo1_ring_base_lsb; uint32_t hal_reo1_ring_base_msb; uint32_t hal_reo1_ring_id; @@ -351,53 +361,22 @@ struct ath12k_hw_regs { uint32_t hal_reo1_ring_msi1_base_lsb; uint32_t hal_reo1_ring_msi1_base_msb; uint32_t hal_reo1_ring_msi1_data; - uint32_t hal_reo2_ring_base_lsb; - uint32_t hal_reo1_aging_thresh_ix_0; - uint32_t hal_reo1_aging_thresh_ix_1; - uint32_t hal_reo1_aging_thresh_ix_2; - uint32_t hal_reo1_aging_thresh_ix_3; + uint32_t hal_reo1_aging_thres_ix0; + uint32_t hal_reo1_aging_thres_ix1; + uint32_t hal_reo1_aging_thres_ix2; + uint32_t hal_reo1_aging_thres_ix3; - uint32_t hal_reo1_ring_hp; - uint32_t hal_reo1_ring_tp; - uint32_t hal_reo2_ring_hp; + uint32_t hal_reo2_sw0_ring_base; - uint32_t hal_reo_tcl_ring_base_lsb; - uint32_t hal_reo_tcl_ring_hp; + uint32_t hal_sw2reo_ring_base; + uint32_t hal_sw2reo1_ring_base; - uint32_t hal_reo_status_ring_base_lsb; - uint32_t hal_reo_status_hp; + uint32_t hal_reo_cmd_ring_base; - uint32_t hal_reo_cmd_ring_base_lsb; - uint32_t hal_reo_cmd_ring_hp; - - uint32_t hal_sw2reo_ring_base_lsb; - uint32_t hal_sw2reo_ring_hp; - - uint32_t hal_seq_wcss_umac_ce0_src_reg; - uint32_t hal_seq_wcss_umac_ce0_dst_reg; - uint32_t hal_seq_wcss_umac_ce1_src_reg; - uint32_t hal_seq_wcss_umac_ce1_dst_reg; - - uint32_t hal_wbm_idle_link_ring_base_lsb; - uint32_t hal_wbm_idle_link_ring_misc; - - uint32_t hal_wbm_release_ring_base_lsb; - - uint32_t hal_wbm0_release_ring_base_lsb; - uint32_t hal_wbm1_release_ring_base_lsb; - - uint32_t pcie_qserdes_sysclk_en_sel; - uint32_t pcie_pcs_osc_dtct_config_base; - - uint32_t hal_shadow_base_addr; - uint32_t hal_reo1_misc_ctl; + uint32_t hal_reo_status_ring_base; }; -extern const struct ath12k_hw_regs ipq8074_regs; -extern const struct ath12k_hw_regs qca6390_regs; -extern const struct ath12k_hw_regs qcn9074_regs; -extern const struct ath12k_hw_regs wcn6855_regs; -extern const struct ath12k_hw_regs wcn6750_regs; +extern const struct ath12k_hw_regs wcn7850_regs; enum ath12k_dev_flags { ATH12K_CAC_RUNNING, @@ -647,9 +626,19 @@ enum hal_ring_type { HAL_RXDMA_MONITOR_DST, HAL_RXDMA_MONITOR_DESC, HAL_RXDMA_DIR_BUF, + HAL_PPE2TCL, + HAL_PPE_RELEASE, + HAL_TX_MONITOR_BUF, + HAL_TX_MONITOR_DST, HAL_MAX_RING_TYPES, }; +enum hal_srng_mac_type { + ATH12K_HAL_SRNG_UMAC, + ATH12K_HAL_SRNG_DMAC, + ATH12K_HAL_SRNG_PMAC +}; + /* HW SRNG configuration table */ struct hal_srng_config { int start_ring_id; @@ -657,7 +646,7 @@ struct hal_srng_config { uint16_t entry_size; uint32_t reg_start[HAL_SRNG_NUM_REG_GRP]; uint16_t reg_size[HAL_SRNG_NUM_REG_GRP]; - uint8_t lmac_ring; + enum hal_srng_mac_type mac_type; enum hal_srng_dir ring_dir; uint32_t max_size; }; @@ -767,7 +756,7 @@ struct ath12k_hal { struct hal_srng srng_list[HAL_SRNG_RING_ID_MAX]; /* SRNG configuration table */ - struct hal_srng_config srng_config[QWZ_NUM_SRNG_CFG]; + struct hal_srng_config *srng_config; /* Remote pointer memory for HW/FW updates */ struct qwz_dmamem *rdpmem; @@ -837,7 +826,6 @@ struct ce_attr { unsigned int dest_nentries; void (*recv_cb)(struct qwz_softc *, struct mbuf *); - void (*send_cb)(struct qwz_softc *, struct mbuf *); }; #define CE_DESC_RING_ALIGN 8 @@ -912,7 +900,7 @@ struct qwz_ce_ring { uint32_t hal_ring_id; /* - * Per-transfer data. + * Per-transfer data. * Size and type of this data depends on how the ring is used. * * For transfers using DMA, the context contains pointers to @@ -982,6 +970,12 @@ struct qwz_dp_htt_wbm_tx_status { #define DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 #define DP_RXDMA_MONITOR_DST_RING_SIZE 2048 #define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096 +#define DP_TX_MONITOR_BUF_RING_SIZE 4096 +#define DP_TX_MONITOR_DEST_RING_SIZE 2048 + +#define DP_TX_MONITOR_BUF_SIZE 2048 +#define DP_TX_MONITOR_BUF_SIZE_MIN 48 +#define DP_TX_MONITOR_BUF_SIZE_MAX 8192 #define DP_RX_RELEASE_RING_NUM 3 @@ -999,6 +993,74 @@ struct qwz_dp_htt_wbm_tx_status { #define DP_TX_DESC_ID_MSDU_ID GENMASK(18, 2) #define DP_TX_DESC_ID_POOL_ID GENMASK(20, 19) +#define ATH12K_NUM_POOL_TX_DESC 32768 + +/* TODO: revisit this count during testing */ +#define ATH12K_RX_DESC_COUNT (12288) + +#define ATH12K_PAGE_SIZE PAGE_SIZE + +/* Total 1024 entries in PPT, i.e 4K/4 considering 4K aligned + * SPT pages which makes lower 12bits 0 + */ +#define ATH12K_MAX_PPT_ENTRIES 1024 + +/* Total 512 entries in a SPT, i.e 4K Page/8 */ +#define ATH12K_MAX_SPT_ENTRIES 512 + +#define ATH12K_NUM_RX_SPT_PAGES ((ATH12K_RX_DESC_COUNT) / ATH12K_MAX_SPT_ENTRIES) + +#define ATH12K_TX_SPT_PAGES_PER_POOL (ATH12K_NUM_POOL_TX_DESC / \ + ATH12K_MAX_SPT_ENTRIES) +#define ATH12K_NUM_TX_SPT_PAGES (ATH12K_TX_SPT_PAGES_PER_POOL * ATH12K_HW_MAX_QUEUES) +#define ATH12K_NUM_SPT_PAGES (ATH12K_NUM_RX_SPT_PAGES + ATH12K_NUM_TX_SPT_PAGES) + +#define ATH12K_TX_SPT_PAGE_OFFSET 0 +#define ATH12K_RX_SPT_PAGE_OFFSET ATH12K_NUM_TX_SPT_PAGES + +/* The SPT pages are divided for RX and TX, first block for RX + * and remaining for TX + */ +#define ATH12K_NUM_TX_SPT_PAGE_START ATH12K_NUM_RX_SPT_PAGES + +#define ATH12K_DP_RX_DESC_MAGIC 0xBABABABA + +/* 4K aligned address have last 12 bits set to 0, this check is done + * so that two spt pages address can be stored per 8bytes + * of CMEM (PPT) + */ +#define ATH12K_SPT_4K_ALIGN_CHECK 0xFFF +#define ATH12K_SPT_4K_ALIGN_OFFSET 12 +#define ATH12K_PPT_ADDR_OFFSET(ppt_index) (4 * (ppt_index)) + +/* To indicate HW of CMEM address, b0-31 are cmem base received via QMI */ +#define ATH12K_CMEM_ADDR_MSB 0x10 + +/* Of 20 bits cookie, b0-b8 is to indicate SPT offset and b9-19 for PPT */ +#define ATH12K_CC_SPT_MSB 8 +#define ATH12K_CC_PPT_MSB 19 +#define ATH12K_CC_PPT_SHIFT 9 +#define ATH12K_DP_CC_COOKIE_SPT GENMASK(8, 0) +#define ATH12K_DP_CC_COOKIE_PPT GENMASK(19, 9) + +#define DP_REO_QREF_NUM GENMASK(31, 16) +#define DP_MAX_PEER_ID 2047 + +/* Total size of the LUT is based on 2K peers, each having reference + * for 17tids, note each entry is of type ath12k_reo_queue_ref + * hence total size is 2048 * 17 * 8 = 278528 + */ +#define DP_REOQ_LUT_SIZE 278528 + +/* Invalid TX Bank ID value */ +#define DP_INVALID_BANK_ID -1 + +struct ath12k_dp_tx_bank_profile { + uint8_t is_configured; + uint32_t num_users; + uint32_t bank_config; +}; + struct qwz_hp_update_timer { struct timeout timer; int started; @@ -1010,6 +1072,29 @@ struct qwz_hp_update_timer { struct qwz_softc *sc; }; +struct ath12k_rx_desc_info { + TAILQ_ENTRY(ath12k_rx_desc_info) entry; +// struct sk_buff *skb; + uint32_t cookie; + uint32_t magic; + uint8_t in_use : 1, + reserved : 7; +}; + +struct ath12k_tx_desc_info { + TAILQ_ENTRY(ath12k_tx_desc_info) entry; +// struct sk_buff *skb; + uint32_t desc_id; /* Cookie */ + uint8_t mac_id; + uint8_t pool_id; +}; + +struct ath12k_spt_info { + struct qwz_dmamem *mem; + struct ath12k_rx_desc_info *rxbaddr[ATH12K_NUM_RX_SPT_PAGES]; + struct ath12k_tx_desc_info *txbaddr[ATH12K_NUM_TX_SPT_PAGES]; +}; + struct dp_rx_tid { uint8_t tid; struct qwz_dmamem *mem; @@ -1089,6 +1174,14 @@ struct dp_link_desc_bank { #define DP_LINK_DESC_ALLOC_SIZE_THRESH 0x200000 #define DP_LINK_DESC_BANKS_MAX 8 +#define DP_LINK_DESC_START 0x4000 +#define DP_LINK_DESC_SHIFT 3 + +#define DP_LINK_DESC_COOKIE_SET(id, page) \ + ((((id) + DP_LINK_DESC_START) << DP_LINK_DESC_SHIFT) | (page)) + +#define DP_LINK_DESC_BANK_MASK GENMASK(2, 0) + struct hal_wbm_idle_scatter_list { struct qwz_dmamem *mem; bus_addr_t paddr; @@ -1131,6 +1224,19 @@ struct qwz_dp { #endif struct qwz_hp_update_timer reo_cmd_timer; struct qwz_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; + struct ath12k_spt_info *spt_info; + uint32_t num_spt_pages; + TAILQ_HEAD(,ath12k_rx_desc_info) rx_desc_free_list; +#ifdef notyet + /* protects the free desc list */ + spinlock_t rx_desc_lock; +#endif + TAILQ_HEAD(,ath12k_tx_desc_info) tx_desc_free_list[ATH12K_HW_MAX_QUEUES]; + TAILQ_HEAD(,ath12k_tx_desc_info) tx_desc_used_list[ATH12K_HW_MAX_QUEUES]; +#ifdef notyet + /* protects the free and used desc lists */ + spinlock_t tx_desc_lock[ATH12K_HW_MAX_QUEUES]; +#endif }; #define ATH12K_SHADOW_DP_TIMER_INTERVAL 20 @@ -1143,7 +1249,7 @@ struct qwz_ce_pipe { unsigned int buf_sz; unsigned int rx_buf_needed; - void (*send_cb)(struct qwz_softc *, struct mbuf *); + int (*send_cb)(struct qwz_ce_pipe *pipe); void (*recv_cb)(struct qwz_softc *, struct mbuf *); #ifdef notyet @@ -1171,8 +1277,8 @@ struct qwz_ce { struct qwz_qmi_ce_cfg { const uint8_t *shadow_reg; int shadow_reg_len; - uint32_t *shadow_reg_v2; - uint32_t shadow_reg_v2_len; + uint32_t *shadow_reg_v3; + uint32_t shadow_reg_v3_len; }; struct qwz_qmi_target_info { @@ -1187,6 +1293,11 @@ struct qwz_qmi_target_info { char bdf_ext[ATH12K_QMI_BDF_EXT_STR_LENGTH]; }; +struct qwz_qmi_dev_mem_info { + uint64_t start; + uint64_t size; +}; + enum ath12k_bdf_search { ATH12K_BDF_SEARCH_DEFAULT, ATH12K_BDF_SEARCH_BUS_AND_BOARD, @@ -1631,7 +1742,8 @@ struct qwz_pdev_dp { struct dp_rxdma_ring rx_refill_buf_ring; struct dp_srng rx_mac_buf_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng rxdma_err_dst_ring[MAX_RXDMA_PER_PDEV]; - struct dp_srng rxdma_mon_dst_ring; + struct dp_srng rxdma_mon_dst_ring[MAX_RXDMA_PER_PDEV]; + struct dp_srng tx_mon_dst_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng rxdma_mon_desc_ring; struct dp_rxdma_ring rxdma_mon_buf_ring; struct dp_rxdma_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV]; @@ -1810,11 +1922,10 @@ struct qwz_softc { struct { u_char *data; size_t size; - } fw_img[4]; + } fw_img[3]; #define QWZ_FW_AMSS 0 #define QWZ_FW_BOARD 1 #define QWZ_FW_M3 2 -#define QWZ_FW_REGDB 3 int sc_tx_timer; uint32_t qfullmsk; @@ -1839,6 +1950,7 @@ struct qwz_softc { int qmi_cal_done; struct qwz_qmi_ce_cfg qmi_ce_cfg; struct qwz_qmi_target_info qmi_target; + struct qwz_qmi_dev_mem_info qmi_dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01]; struct ath12k_targ_cap target_caps; int num_radios; uint32_t cc_freq_hz; @@ -1888,7 +2000,7 @@ struct qwz_softc { struct qwz_dmamem *fwmem; int expect_fwmem_req; int fwmem_ready; - int fw_init_done; + int fw_ready; int ctl_resp; @@ -1901,6 +2013,7 @@ struct qwz_softc { struct qwz_ops ops; bus_dma_tag_t sc_dmat; enum ath12k_hw_rev sc_hw_rev; + int static_window_map; struct qwz_device_id id; char sc_bus_str[4]; /* "pci" or "ahb" */ int num_msivec; diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c index 81464ea3a..948b0fe07 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c @@ -3593,6 +3593,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, rw_init(&adev->grbm_idx_mutex, "grbmidx"); rw_init(&adev->mn_lock, "agpumn"); rw_init(&adev->virt.vf_errors.lock, "vferr"); + rw_init(&adev->virt.rlcg_reg_lock, "vrlcg"); hash_init(adev->mn_hash); rw_init(&adev->psp.mutex, "agpsp"); rw_init(&adev->notifier_lock, "agnf"); diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_job.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_job.c index de9d7f3dc..99dd86337 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_job.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_job.c @@ -258,9 +258,8 @@ amdgpu_job_prepare_job(struct drm_sched_job *sched_job, struct dma_fence *fence = NULL; int r; - /* Ignore soft recovered fences here */ r = drm_sched_entity_error(s_entity); - if (r && r != -ENODATA) + if (r) goto error; if (!fence && job->gang_submit) diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp_ta.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp_ta.c index ca5c86e5f..8e8afbd23 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp_ta.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp_ta.c @@ -334,7 +334,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size set_ta_context_funcs(psp, ta_type, &context); - if (!context->initialized) { + if (!context || !context->initialized) { dev_err(adev->dev, "TA is not initialized\n"); ret = -EINVAL; goto err_free_shared_buf; diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_ras.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_ras.c index 36af1f4e4..290999151 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_ras.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_ras.c @@ -1800,12 +1800,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work) int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev, struct ras_dispatch_if *info) { - struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head); - struct ras_ih_data *data = &obj->ih_data; + struct ras_manager *obj; + struct ras_ih_data *data; + obj = amdgpu_ras_find_obj(adev, &info->head); if (!obj) return -EINVAL; + data = &obj->ih_data; + if (data->inuse == 0) return 0; diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.c index f43b5ca1b..2be313e5f 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.c @@ -1004,6 +1004,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2; scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3; + + mutex_lock(&adev->virt.rlcg_reg_lock); + if (reg_access_ctrl->spare_int) spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int; @@ -1059,6 +1062,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v } ret = readl(scratch_reg0); + + mutex_unlock(&adev->virt.rlcg_reg_lock); + return ret; } diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.h b/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.h index b62bfd895..4362955f6 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.h +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_virt.h @@ -263,6 +263,8 @@ struct amdgpu_virt { /* the ucode id to signal the autoload */ uint32_t autoload_ucode_id; + + struct rwlock rlcg_reg_lock; }; struct amdgpu_video_codec_info; diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm_sdma.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm_sdma.c index 349416e17..1cf149820 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm_sdma.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm_sdma.c @@ -102,6 +102,11 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p, if (!r) r = amdgpu_sync_push_to_job(&sync, p->job); amdgpu_sync_free(&sync); + + if (r) { + p->num_dw_left = 0; + amdgpu_job_free(p->job); + } return r; } diff --git a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c index cf5afb43c..6a3d1f463 100644 --- a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2632,7 +2632,8 @@ static int dm_suspend(void *handle) dm->cached_dc_state = dc_copy_state(dm->dc->current_state); - dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); + if (dm->cached_dc_state) + dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); amdgpu_dm_commit_zero_streams(dm->dc); @@ -6487,7 +6488,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector) aconnector->dc_sink = aconnector->dc_link->local_sink ? aconnector->dc_link->local_sink : aconnector->dc_em_sink; - dc_sink_retain(aconnector->dc_sink); + if (aconnector->dc_sink) + dc_sink_retain(aconnector->dc_sink); } } @@ -7300,7 +7302,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) drm_add_modes_noedid(connector, 1920, 1080); } else { amdgpu_dm_connector_ddc_get_modes(connector, edid); - amdgpu_dm_connector_add_common_modes(encoder, connector); + if (encoder) + amdgpu_dm_connector_add_common_modes(encoder, connector); amdgpu_dm_connector_add_freesync_modes(connector, edid); } amdgpu_dm_fbc_init(connector); diff --git a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 2104511f3..3880ddf1c 100644 --- a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -1266,6 +1266,9 @@ static bool is_dsc_need_re_compute( } } + if (new_stream_on_link_num == 0) + return false; + /* check current_state if there stream on link but it is not in * new request state */ diff --git a/sys/dev/pci/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c b/sys/dev/pci/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c index 710f190b4..664a3545c 100644 --- a/sys/dev/pci/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c +++ b/sys/dev/pci/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c @@ -162,7 +162,12 @@ static void set_hpo_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *lin link_res->hpo_dp_link_enc->funcs->set_link_test_pattern( link_res->hpo_dp_link_enc, tp_params); } + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); + + // Give retimer extra time to lock before updating DP_TRAINING_PATTERN_SET to TPS1 + if (tp_params->dp_phy_pattern == DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE) + drm_msleep(30); } static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link, diff --git a/sys/dev/pci/drm/amd/pm/powerplay/amd_powerplay.c b/sys/dev/pci/drm/amd/pm/powerplay/amd_powerplay.c index 9e17da000..d5aebe1c4 100644 --- a/sys/dev/pci/drm/amd/pm/powerplay/amd_powerplay.c +++ b/sys/dev/pci/drm/amd/pm/powerplay/amd_powerplay.c @@ -927,7 +927,7 @@ static int pp_dpm_switch_power_profile(void *handle, enum PP_SMC_POWER_PROFILE type, bool en) { struct pp_hwmgr *hwmgr = handle; - long workload; + long workload[1]; uint32_t index; if (!hwmgr || !hwmgr->pm_en) @@ -945,12 +945,12 @@ static int pp_dpm_switch_power_profile(void *handle, hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); index = fls(hwmgr->workload_mask); index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; - workload = hwmgr->workload_setting[index]; + workload[0] = hwmgr->workload_setting[index]; } else { hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); index = fls(hwmgr->workload_mask); index = index <= Workload_Policy_Max ? index - 1 : 0; - workload = hwmgr->workload_setting[index]; + workload[0] = hwmgr->workload_setting[index]; } if (type == PP_SMC_POWER_PROFILE_COMPUTE && @@ -960,7 +960,7 @@ static int pp_dpm_switch_power_profile(void *handle, } if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) - hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); + hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); return 0; } diff --git a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/pp_psm.c index 1d829402c..f4bd8e935 100644 --- a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/pp_psm.c +++ b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/pp_psm.c @@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set struct pp_power_state *new_ps) { uint32_t index; - long workload; + long workload[1]; if (hwmgr->not_vf) { if (!skip_display_settings) @@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { index = fls(hwmgr->workload_mask); index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; - workload = hwmgr->workload_setting[index]; + workload[0] = hwmgr->workload_setting[index]; - if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) - hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); + if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode) + hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); } return 0; diff --git a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index 89134b53d..4cd7e0e27 100644 --- a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -2957,6 +2957,7 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr) static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) { + struct amdgpu_device *adev = hwmgr->adev; struct smu7_hwmgr *data; int result = 0; @@ -2993,40 +2994,37 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) /* Initalize Dynamic State Adjustment Rule Settings */ result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr); - if (0 == result) { - struct amdgpu_device *adev = hwmgr->adev; + if (result) + goto fail; - data->is_tlu_enabled = false; + data->is_tlu_enabled = false; - hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = + hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = SMU7_MAX_HARDWARE_POWERLEVELS; - hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; - hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; + hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; + hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; - data->pcie_gen_cap = adev->pm.pcie_gen_mask; - if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) - data->pcie_spc_cap = 20; - else - data->pcie_spc_cap = 16; - data->pcie_lane_cap = adev->pm.pcie_mlw_mask; + data->pcie_gen_cap = adev->pm.pcie_gen_mask; + if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) + data->pcie_spc_cap = 20; + else + data->pcie_spc_cap = 16; + data->pcie_lane_cap = adev->pm.pcie_mlw_mask; - hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ -/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ - hwmgr->platform_descriptor.clockStep.engineClock = 500; - hwmgr->platform_descriptor.clockStep.memoryClock = 500; - smu7_thermal_parameter_init(hwmgr); - } else { - /* Ignore return value in here, we are cleaning up a mess. */ - smu7_hwmgr_backend_fini(hwmgr); - } + hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ + /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ + hwmgr->platform_descriptor.clockStep.engineClock = 500; + hwmgr->platform_descriptor.clockStep.memoryClock = 500; + smu7_thermal_parameter_init(hwmgr); result = smu7_update_edc_leakage_table(hwmgr); - if (result) { - smu7_hwmgr_backend_fini(hwmgr); - return result; - } + if (result) + goto fail; return 0; +fail: + smu7_hwmgr_backend_fini(hwmgr); + return result; } static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr) @@ -3316,8 +3314,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, const struct pp_power_state *current_ps) { struct amdgpu_device *adev = hwmgr->adev; - struct smu7_power_state *smu7_ps = - cast_phw_smu7_power_state(&request_ps->hardware); + struct smu7_power_state *smu7_ps; uint32_t sclk; uint32_t mclk; struct PP_Clocks minimum_clocks = {0}; @@ -3334,6 +3331,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, uint32_t latency; bool latency_allowed = false; + smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware); + if (!smu7_ps) + return -EINVAL; + data->battery_state = (PP_StateUILabel_Battery == request_ps->classification.ui_label); data->mclk_ignore_signal = false; diff --git a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c index f8d864e7e..20a844b2b 100644 --- a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +++ b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c @@ -1065,16 +1065,18 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, struct pp_power_state *prequest_ps, const struct pp_power_state *pcurrent_ps) { - struct smu8_power_state *smu8_ps = - cast_smu8_power_state(&prequest_ps->hardware); - - const struct smu8_power_state *smu8_current_ps = - cast_const_smu8_power_state(&pcurrent_ps->hardware); - + struct smu8_power_state *smu8_ps; + const struct smu8_power_state *smu8_current_ps; struct smu8_hwmgr *data = hwmgr->backend; struct PP_Clocks clocks = {0, 0, 0, 0}; bool force_high; + smu8_ps = cast_smu8_power_state(&prequest_ps->hardware); + smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware); + + if (!smu8_ps || !smu8_current_ps) + return -EINVAL; + smu8_ps->need_dfs_bypass = true; data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); diff --git a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 7f72fd3f1..19a468e03 100644 --- a/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/sys/dev/pci/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -3259,8 +3259,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, const struct pp_power_state *current_ps) { struct amdgpu_device *adev = hwmgr->adev; - struct vega10_power_state *vega10_ps = - cast_phw_vega10_power_state(&request_ps->hardware); + struct vega10_power_state *vega10_ps; uint32_t sclk; uint32_t mclk; struct PP_Clocks minimum_clocks = {0}; @@ -3278,6 +3277,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; uint32_t latency; + vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware); + if (!vega10_ps) + return -EINVAL; + data->battery_state = (PP_StateUILabel_Battery == request_ps->classification.ui_label); @@ -3415,13 +3418,17 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co const struct vega10_power_state *vega10_ps = cast_const_phw_vega10_power_state(states->pnew_state); struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); - uint32_t sclk = vega10_ps->performance_levels - [vega10_ps->performance_level_count - 1].gfx_clock; struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); - uint32_t mclk = vega10_ps->performance_levels - [vega10_ps->performance_level_count - 1].mem_clock; + uint32_t sclk, mclk; uint32_t i; + if (vega10_ps == NULL) + return -EINVAL; + sclk = vega10_ps->performance_levels + [vega10_ps->performance_level_count - 1].gfx_clock; + mclk = vega10_ps->performance_levels + [vega10_ps->performance_level_count - 1].mem_clock; + for (i = 0; i < sclk_table->count; i++) { if (sclk == sclk_table->dpm_levels[i].value) break; @@ -3728,6 +3735,9 @@ static int vega10_generate_dpm_level_enable_mask( cast_const_phw_vega10_power_state(states->pnew_state); int i; + if (vega10_ps == NULL) + return -EINVAL; + PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps), "Attempt to Trim DPM States Failed!", return -1); @@ -4995,6 +5005,8 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr, vega10_psa = cast_const_phw_vega10_power_state(pstate1); vega10_psb = cast_const_phw_vega10_power_state(pstate2); + if (vega10_psa == NULL || vega10_psb == NULL) + return -EINVAL; /* If the two states don't even have the same number of performance levels * they cannot be the same state. @@ -5128,6 +5140,8 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) return -EINVAL; vega10_ps = cast_phw_vega10_power_state(&ps->hardware); + if (vega10_ps == NULL) + return -EINVAL; vega10_ps->performance_levels [vega10_ps->performance_level_count - 1].gfx_clock = @@ -5179,6 +5193,8 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) return -EINVAL; vega10_ps = cast_phw_vega10_power_state(&ps->hardware); + if (vega10_ps == NULL) + return -EINVAL; vega10_ps->performance_levels [vega10_ps->performance_level_count - 1].mem_clock = @@ -5420,6 +5436,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) return; vega10_ps = cast_phw_vega10_power_state(&ps->hardware); + if (vega10_ps == NULL) + return; + max_level = vega10_ps->performance_level_count - 1; if (vega10_ps->performance_levels[max_level].gfx_clock != @@ -5442,6 +5461,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1)); vega10_ps = cast_phw_vega10_power_state(&ps->hardware); + if (vega10_ps == NULL) + return; + max_level = vega10_ps->performance_level_count - 1; if (vega10_ps->performance_levels[max_level].gfx_clock != @@ -5632,6 +5654,8 @@ static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_ return -EINVAL; vega10_ps = cast_const_phw_vega10_power_state(state); + if (vega10_ps == NULL) + return -EINVAL; i = index > vega10_ps->performance_level_count - 1 ? vega10_ps->performance_level_count - 1 : index; diff --git a/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c b/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c index 7c4a436de..d6daf3c1c 100644 --- a/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1846,7 +1846,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, { int ret = 0; int index = 0; - long workload; + long workload[1]; struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); if (!skip_display_settings) { @@ -1886,10 +1886,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { index = fls(smu->workload_mask); index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; - workload = smu->workload_setting[index]; + workload[0] = smu->workload_setting[index]; - if (smu->power_profile_mode != workload) - smu_bump_power_profile_mode(smu, &workload, 0); + if (smu->power_profile_mode != workload[0]) + smu_bump_power_profile_mode(smu, workload, 0); } return ret; @@ -1939,7 +1939,7 @@ static int smu_switch_power_profile(void *handle, { struct smu_context *smu = handle; struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); - long workload; + long workload[1]; uint32_t index; if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) @@ -1952,17 +1952,17 @@ static int smu_switch_power_profile(void *handle, smu->workload_mask &= ~(1 << smu->workload_prority[type]); index = fls(smu->workload_mask); index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; - workload = smu->workload_setting[index]; + workload[0] = smu->workload_setting[index]; } else { smu->workload_mask |= (1 << smu->workload_prority[type]); index = fls(smu->workload_mask); index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; - workload = smu->workload_setting[index]; + workload[0] = smu->workload_setting[index]; } if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) - smu_bump_power_profile_mode(smu, &workload, 0); + smu_bump_power_profile_mode(smu, workload, 0); return 0; } diff --git a/sys/dev/pci/drm/display/drm_dp_mst_topology.c b/sys/dev/pci/drm/display/drm_dp_mst_topology.c index 2b77d44f3..92511c4c1 100644 --- a/sys/dev/pci/drm/display/drm_dp_mst_topology.c +++ b/sys/dev/pci/drm/display/drm_dp_mst_topology.c @@ -4034,6 +4034,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { const struct drm_dp_connection_status_notify *conn_stat = &up_req->msg.u.conn_stat; + bool handle_csn; drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", conn_stat->port_number, @@ -4042,6 +4043,16 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) conn_stat->message_capability_status, conn_stat->input_port, conn_stat->peer_device_type); + + mutex_lock(&mgr->probe_lock); + handle_csn = mgr->mst_primary->link_address_sent; + mutex_unlock(&mgr->probe_lock); + + if (!handle_csn) { + drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it."); + kfree(up_req); + goto out; + } } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { const struct drm_dp_resource_status_notify *res_stat = &up_req->msg.u.resource_stat; diff --git a/sys/dev/pci/drm/drm_client_modeset.c b/sys/dev/pci/drm/drm_client_modeset.c index 21b9c6b5a..5c5b0a962 100644 --- a/sys/dev/pci/drm/drm_client_modeset.c +++ b/sys/dev/pci/drm/drm_client_modeset.c @@ -879,6 +879,11 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, kfree(modeset->mode); modeset->mode = drm_mode_duplicate(dev, mode); + if (!modeset->mode) { + ret = -ENOMEM; + break; + } + drm_connector_get(connector); modeset->connectors[modeset->num_connectors++] = connector; modeset->x = offset->x; diff --git a/sys/dev/pci/drm/i915/gem/i915_gem_mman.c b/sys/dev/pci/drm/i915/gem/i915_gem_mman.c index a5585e4c8..dcbb86323 100644 --- a/sys/dev/pci/drm/i915/gem/i915_gem_mman.c +++ b/sys/dev/pci/drm/i915/gem/i915_gem_mman.c @@ -325,6 +325,41 @@ out: return i915_error_to_vmf_fault(err); } +static void set_address_limits(struct vm_area_struct *area, + struct i915_vma *vma, + unsigned long obj_offset, + unsigned long *start_vaddr, + unsigned long *end_vaddr) +{ + unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */ + long start, end; /* memory boundaries */ + + /* + * Let's move into the ">> PAGE_SHIFT" + * domain to be sure not to lose bits + */ + vm_start = area->vm_start >> PAGE_SHIFT; + vm_end = area->vm_end >> PAGE_SHIFT; + vma_size = vma->size >> PAGE_SHIFT; + + /* + * Calculate the memory boundaries by considering the offset + * provided by the user during memory mapping and the offset + * provided for the partial mapping. + */ + start = vm_start; + start -= obj_offset; + start += vma->gtt_view.partial.offset; + end = start + vma_size; + + start = max_t(long, start, vm_start); + end = min_t(long, end, vm_end); + + /* Let's move back into the "<< PAGE_SHIFT" domain */ + *start_vaddr = (unsigned long)start << PAGE_SHIFT; + *end_vaddr = (unsigned long)end << PAGE_SHIFT; +} + static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) { #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT) @@ -337,14 +372,18 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) struct i915_ggtt *ggtt = to_gt(i915)->ggtt; bool write = area->vm_flags & VM_WRITE; struct i915_gem_ww_ctx ww; + unsigned long obj_offset; + unsigned long start, end; /* memory boundaries */ intel_wakeref_t wakeref; struct i915_vma *vma; pgoff_t page_offset; + unsigned long pfn; int srcu; int ret; - /* We don't use vmf->pgoff since that has the fake offset */ + obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node); page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT; + page_offset += obj_offset; trace_i915_gem_object_fault(obj, page_offset, true, write); @@ -437,12 +476,14 @@ retry: if (ret) goto err_unpin; + set_address_limits(area, vma, obj_offset, &start, &end); + + pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT; + pfn += (start - area->vm_start) >> PAGE_SHIFT; + pfn += obj_offset - vma->gtt_view.partial.offset; + /* Finally, remap it using the new GTT offset */ - ret = remap_io_mapping(area, - area->vm_start + (vma->gtt_view.partial.offset << PAGE_SHIFT), - (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT, - min_t(u64, vma->size, area->vm_end - area->vm_start), - &ggtt->iomap); + ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap); if (ret) goto err_fence; @@ -655,6 +696,41 @@ remap_io_mapping(pmap_t pm, vm_prot_t mapprot, return 0; } +static void set_address_limits(struct vm_map_entry *entry, + struct i915_vma *vma, + unsigned long obj_offset, + unsigned long *start_vaddr, + unsigned long *end_vaddr) +{ + unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */ + long start, end; /* memory boundaries */ + + /* + * Let's move into the ">> PAGE_SHIFT" + * domain to be sure not to lose bits + */ + vm_start = entry->start >> PAGE_SHIFT; + vm_end = entry->end >> PAGE_SHIFT; + vma_size = vma->size >> PAGE_SHIFT; + + /* + * Calculate the memory boundaries by considering the offset + * provided by the user during memory mapping and the offset + * provided for the partial mapping. + */ + start = vm_start; + start -= obj_offset; + start += vma->gtt_view.partial.offset; + end = start + vma_size; + + start = max_t(long, start, vm_start); + end = min_t(long, end, vm_end); + + /* Let's move back into the "<< PAGE_SHIFT" domain */ + *start_vaddr = (unsigned long)start << PAGE_SHIFT; + *end_vaddr = (unsigned long)end << PAGE_SHIFT; +} + static int vm_fault_gtt(struct i915_mmap_offset *mmo, struct uvm_faultinfo *ufi, vaddr_t vaddr, vm_prot_t access_type) @@ -668,13 +744,16 @@ vm_fault_gtt(struct i915_mmap_offset *mmo, struct uvm_faultinfo *ufi, struct i915_ggtt *ggtt = to_gt(i915)->ggtt; int write = !!(access_type & PROT_WRITE); struct i915_gem_ww_ctx ww; + unsigned long obj_offset; + unsigned long start, end; /* memory boundaries */ intel_wakeref_t wakeref; struct i915_vma *vma; pgoff_t page_offset; + unsigned long pfn; int srcu; int ret; - /* We don't use vmf->pgoff since that has the fake offset */ + obj_offset = entry->offset - drm_vma_node_start(&mmo->vma_node); page_offset = (vaddr - entry->start) >> PAGE_SHIFT; trace_i915_gem_object_fault(obj, page_offset, true, write); @@ -768,11 +847,15 @@ retry: if (ret) goto err_unpin; + set_address_limits(entry, vma, obj_offset, &start, &end); + + pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT; + pfn += (start - entry->start) >> PAGE_SHIFT; + pfn += obj_offset - vma->gtt_view.partial.offset; + /* Finally, remap it using the new GTT offset */ ret = remap_io_mapping(ufi->orig_map->pmap, entry->protection, - entry->start + (vma->gtt_view.partial.offset << PAGE_SHIFT), - (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT, - min_t(u64, vma->size, entry->end - entry->start)); + start, pfn, end - start); if (ret) goto err_fence; @@ -1507,6 +1590,8 @@ int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma mmo = mmap_offset_attach(obj, mmap_type, NULL); if (IS_ERR(mmo)) return PTR_ERR(mmo); + + vma->vm_pgoff += drm_vma_node_start(&mmo->vma_node); } /* diff --git a/sys/dev/pci/drm/radeon/pptable.h b/sys/dev/pci/drm/radeon/pptable.h index 572ac8ddc..ce8832916 100644 --- a/sys/dev/pci/drm/radeon/pptable.h +++ b/sys/dev/pci/drm/radeon/pptable.h @@ -114,8 +114,8 @@ typedef struct _ATOM_PPLIB_EXTENDEDHEADER USHORT usUVDTableOffset; //points to ATOM_PPLIB_UVD_Table USHORT usSAMUTableOffset; //points to ATOM_PPLIB_SAMU_Table USHORT usPPMTableOffset; //points to ATOM_PPLIB_PPM_Table - USHORT usACPTableOffset; //points to ATOM_PPLIB_ACP_Table - USHORT usPowerTuneTableOffset; //points to ATOM_PPLIB_POWERTUNE_Table + USHORT usACPTableOffset; //points to ATOM_PPLIB_ACP_Table + USHORT usPowerTuneTableOffset; //points to ATOM_PPLIB_POWERTUNE_Table } ATOM_PPLIB_EXTENDEDHEADER; //// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps @@ -196,14 +196,14 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 typedef struct _ATOM_PPLIB_POWERPLAYTABLE4 { ATOM_PPLIB_POWERPLAYTABLE3 basicTable3; - ULONG ulGoldenPPID; // PPGen use only + ULONG ulGoldenPPID; // PPGen use only ULONG ulGoldenRevision; // PPGen use only USHORT usVddcDependencyOnSCLKOffset; USHORT usVddciDependencyOnMCLKOffset; USHORT usVddcDependencyOnMCLKOffset; USHORT usMaxClockVoltageOnDCOffset; USHORT usVddcPhaseShedLimitsTableOffset; // Points to ATOM_PPLIB_PhaseSheddingLimits_Table - USHORT usMvddDependencyOnMCLKOffset; + USHORT usMvddDependencyOnMCLKOffset; } ATOM_PPLIB_POWERPLAYTABLE4, *LPATOM_PPLIB_POWERPLAYTABLE4; typedef struct _ATOM_PPLIB_POWERPLAYTABLE5 @@ -347,23 +347,23 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO UCHAR ucPadding; // For proper alignment and size. USHORT usVDDC; // For the 780, use: None, Low, High, Variable UCHAR ucMaxHTLinkWidth; // From SBIOS - {2, 4, 8, 16} - UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could + UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could USHORT usHTLinkFreq; // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200). - ULONG ulFlags; + ULONG ulFlags; } ATOM_PPLIB_RS780_CLOCK_INFO; -#define ATOM_PPLIB_RS780_VOLTAGE_NONE 0 -#define ATOM_PPLIB_RS780_VOLTAGE_LOW 1 -#define ATOM_PPLIB_RS780_VOLTAGE_HIGH 2 -#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE 3 +#define ATOM_PPLIB_RS780_VOLTAGE_NONE 0 +#define ATOM_PPLIB_RS780_VOLTAGE_LOW 1 +#define ATOM_PPLIB_RS780_VOLTAGE_HIGH 2 +#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE 3 #define ATOM_PPLIB_RS780_SPMCLK_NONE 0 // We cannot change the side port memory clock, leave it as it is. #define ATOM_PPLIB_RS780_SPMCLK_LOW 1 #define ATOM_PPLIB_RS780_SPMCLK_HIGH 2 -#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE 0 -#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 -#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 +#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE 0 +#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 +#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 typedef struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO { @@ -405,14 +405,14 @@ typedef struct _ATOM_PPLIB_CI_CLOCK_INFO USHORT usMemoryClockLow; UCHAR ucMemoryClockHigh; - + UCHAR ucPCIEGen; USHORT usPCIELane; } ATOM_PPLIB_CI_CLOCK_INFO; typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO{ USHORT usEngineClockLow; //clockfrequency & 0xFFFF. The unit is in 10khz - UCHAR ucEngineClockHigh; //clockfrequency >> 16. + UCHAR ucEngineClockHigh; //clockfrequency >> 16. UCHAR vddcIndex; //2-bit vddc index; USHORT tdpLimit; //please initalize to 0 @@ -423,10 +423,10 @@ typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO{ typedef struct _ATOM_PPLIB_STATE_V2 { - //number of valid dpm levels in this state; Driver uses it to calculate the whole + //number of valid dpm levels in this state; Driver uses it to calculate the whole //size of the state: struct_size(ATOM_PPLIB_STATE_V2, clockInfoIndex, ucNumDPMLevels) UCHAR ucNumDPMLevels; - + //a index to the array of nonClockInfos UCHAR nonClockInfoIndex; /** @@ -436,20 +436,20 @@ typedef struct _ATOM_PPLIB_STATE_V2 } ATOM_PPLIB_STATE_V2; typedef struct _StateArray{ - //how many states we have + //how many states we have UCHAR ucNumEntries; - - ATOM_PPLIB_STATE_V2 states[] __counted_by(ucNumEntries); + + ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */; }StateArray; typedef struct _ClockInfoArray{ //how many clock levels we have UCHAR ucNumEntries; - + //sizeof(ATOM_PPLIB_CLOCK_INFO) UCHAR ucEntrySize; - + UCHAR clockInfo[] __counted_by(ucNumEntries); }ClockInfoArray; @@ -459,7 +459,7 @@ typedef struct _NonClockInfoArray{ UCHAR ucNumEntries; //sizeof(ATOM_PPLIB_NONCLOCK_INFO) UCHAR ucEntrySize; - + ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries); }NonClockInfoArray; @@ -680,7 +680,7 @@ typedef struct _ATOM_PPLIB_PPM_Table ULONG ulPlatformTDC; ULONG ulSmallACPlatformTDC; ULONG ulApuTDP; - ULONG ulDGpuTDP; + ULONG ulDGpuTDP; ULONG ulDGpuUlvPower; ULONG ulTjmax; } ATOM_PPLIB_PPM_Table; diff --git a/sys/dev/pci/if_qwz_pci.c b/sys/dev/pci/if_qwz_pci.c index 3a45b27fb..d4cad8d5b 100644 --- a/sys/dev/pci/if_qwz_pci.c +++ b/sys/dev/pci/if_qwz_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_qwz_pci.c,v 1.1 2024/08/14 14:40:46 patrick Exp $ */ +/* $OpenBSD: if_qwz_pci.c,v 1.3 2024/08/16 00:26:54 patrick Exp $ */ /* * Copyright 2023 Stefan Sperling @@ -116,11 +116,12 @@ #define ATH12K_PCI_WINDOW_VALUE_MASK GENMASK(24, 19) #define ATH12K_PCI_WINDOW_START 0x80000 #define ATH12K_PCI_WINDOW_RANGE_MASK GENMASK(18, 0) +#define ATH12K_PCI_WINDOW_STATIC_MASK GENMASK(31, 6) /* BAR0 + 4k is always accessible, and no need to force wakeup. */ #define ATH12K_PCI_ACCESS_ALWAYS_OFF 0xFE0 /* 4K - 32 = 0xFE0 */ -#define TCSR_SOC_HW_VERSION 0x0224 +#define TCSR_SOC_HW_VERSION 0x1b00000 #define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 0) @@ -145,7 +146,7 @@ #define PCIE_PCIE_PARF_LTSSM 0x1e081b0 #define PARM_LTSSM_VALUE 0x111 -#define GCC_GCC_PCIE_HOT_RST 0x1e402bc +#define GCC_GCC_PCIE_HOT_RST 0x1e38338 #define GCC_GCC_PCIE_HOT_RST_VAL 0x10 #define PCIE_PCIE_INT_ALL_CLEAR 0x1e08228 @@ -170,6 +171,9 @@ #define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 +#define PCI_MHIREGLEN_REG 0x1e0e100 +#define PCI_MHI_REGION_END 0x1e0effc + /* * mhi.h */ @@ -374,11 +378,9 @@ struct qwz_pci_softc { struct qwz_dmamem *cmd_ctxt; - struct qwz_pci_xfer_ring xfer_rings[4]; -#define QWZ_PCI_XFER_RING_LOOPBACK_OUTBOUND 0 -#define QWZ_PCI_XFER_RING_LOOPBACK_INBOUND 1 -#define QWZ_PCI_XFER_RING_IPCR_OUTBOUND 2 -#define QWZ_PCI_XFER_RING_IPCR_INBOUND 3 + struct qwz_pci_xfer_ring xfer_rings[2]; +#define QWZ_PCI_XFER_RING_IPCR_OUTBOUND 0 +#define QWZ_PCI_XFER_RING_IPCR_INBOUND 1 struct qwz_pci_event_ring event_rings[QWZ_NUM_EVENT_CTX]; struct qwz_pci_cmd_ring cmd_ring; }; @@ -482,28 +484,14 @@ struct qwz_pci_ops { }; -static const struct qwz_pci_ops qwz_pci_ops_qca6390 = { +static const struct qwz_pci_ops qwz_pci_ops_wcn7850 = { .wakeup = qwz_pci_bus_wake_up, .release = qwz_pci_bus_release, -#if notyet - .get_msi_irq = qwz_pci_get_msi_irq, -#endif .window_write32 = qwz_pci_window_write32, .window_read32 = qwz_pci_window_read32, .alloc_xfer_rings = qwz_pci_alloc_xfer_rings_qca6390, }; -static const struct qwz_pci_ops qwz_pci_ops_qcn9074 = { - .wakeup = NULL, - .release = NULL, -#if notyet - .get_msi_irq = qwz_pci_get_msi_irq, -#endif - .window_write32 = qwz_pci_window_write32, - .window_read32 = qwz_pci_window_read32, - .alloc_xfer_rings = qwz_pci_alloc_xfer_rings_qcn9074, -}; - const struct cfattach qwz_pci_ca = { sizeof(struct qwz_pci_softc), qwz_pci_match, @@ -512,16 +500,8 @@ const struct cfattach qwz_pci_ca = { qwz_activate }; -/* XXX pcidev */ -#define PCI_PRODUCT_QUALCOMM_QCA6390 0x1101 -#define PCI_PRODUCT_QUALCOMM_QCN9074 0x1104 - static const struct pci_matchid qwz_pci_devices[] = { -#if notyet - { PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCA6390 }, - { PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCN9074 }, -#endif - { PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCNFA765 } + { PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_WCN7850 } }; int @@ -535,8 +515,8 @@ qwz_pci_init_qmi_ce_config(struct qwz_softc *sc) { struct qwz_qmi_ce_cfg *cfg = &sc->qmi_ce_cfg; - qwz_ce_get_shadow_config(sc, &cfg->shadow_reg_v2, - &cfg->shadow_reg_v2_len); + qwz_ce_get_shadow_config(sc, &cfg->shadow_reg_v3, + &cfg->shadow_reg_v3_len); } const struct qwz_msi_config qwz_msi_config_one_msi = { @@ -551,17 +531,6 @@ const struct qwz_msi_config qwz_msi_config_one_msi = { }; const struct qwz_msi_config qwz_msi_config[] = { - { - .total_vectors = 32, - .total_users = 4, - .users = (struct qwz_msi_user[]) { - { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, - { .name = "CE", .num_vectors = 10, .base_vector = 3 }, - { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, - { .name = "DP", .num_vectors = 18, .base_vector = 14 }, - }, - .hw_rev = ATH12K_HW_QCA6390_HW20, - }, { .total_vectors = 16, .total_users = 3, @@ -570,38 +539,7 @@ const struct qwz_msi_config qwz_msi_config[] = { { .name = "CE", .num_vectors = 5, .base_vector = 3 }, { .name = "DP", .num_vectors = 8, .base_vector = 8 }, }, - .hw_rev = ATH12K_HW_QCN9074_HW10, - }, - { - .total_vectors = 32, - .total_users = 4, - .users = (struct qwz_msi_user[]) { - { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, - { .name = "CE", .num_vectors = 10, .base_vector = 3 }, - { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, - { .name = "DP", .num_vectors = 18, .base_vector = 14 }, - }, - .hw_rev = ATH12K_HW_WCN6855_HW20, - }, - { - .total_vectors = 32, - .total_users = 4, - .users = (struct qwz_msi_user[]) { - { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, - { .name = "CE", .num_vectors = 10, .base_vector = 3 }, - { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, - { .name = "DP", .num_vectors = 18, .base_vector = 14 }, - }, - .hw_rev = ATH12K_HW_WCN6855_HW21, - }, - { - .total_vectors = 28, - .total_users = 2, - .users = (struct qwz_msi_user[]) { - { .name = "CE", .num_vectors = 10, .base_vector = 0 }, - { .name = "DP", .num_vectors = 18, .base_vector = 10 }, - }, - .hw_rev = ATH12K_HW_WCN6750_HW10, + .hw_rev = ATH12K_HW_WCN7850_HW20, }, }; @@ -745,7 +683,6 @@ qwz_pci_attach(struct device *parent, struct device *self, void *aux) struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; uint32_t soc_hw_version_major, soc_hw_version_minor; - const struct qwz_pci_ops *pci_ops; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; pcireg_t memtype, reg; @@ -885,54 +822,22 @@ qwz_pci_attach(struct device *parent, struct device *self, void *aux) pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); switch (PCI_PRODUCT(pa->pa_id)) { - case PCI_PRODUCT_QUALCOMM_QCA6390: - qwz_pci_read_hw_version(sc, &soc_hw_version_major, - &soc_hw_version_minor); - switch (soc_hw_version_major) { - case 2: - sc->sc_hw_rev = ATH12K_HW_QCA6390_HW20; - break; - default: - printf(": unsupported QCA6390 SOC version: %d %d\n", - soc_hw_version_major, soc_hw_version_minor); - return; - } - - pci_ops = &qwz_pci_ops_qca6390; - psc->max_chan = QWZ_MHI_CONFIG_QCA6390_MAX_CHANNELS; - break; - case PCI_PRODUCT_QUALCOMM_QCN9074: - pci_ops = &qwz_pci_ops_qcn9074; - sc->sc_hw_rev = ATH12K_HW_QCN9074_HW10; - psc->max_chan = QWZ_MHI_CONFIG_QCA9074_MAX_CHANNELS; - break; - case PCI_PRODUCT_QUALCOMM_QCNFA765: + case PCI_PRODUCT_QUALCOMM_WCN7850: + sc->static_window_map = 0; + psc->sc_pci_ops = &qwz_pci_ops_wcn7850; sc->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; qwz_pci_read_hw_version(sc, &soc_hw_version_major, &soc_hw_version_minor); switch (soc_hw_version_major) { case 2: - switch (soc_hw_version_minor) { - case 0x00: - case 0x01: - sc->sc_hw_rev = ATH12K_HW_WCN6855_HW20; - break; - case 0x10: - case 0x11: - sc->sc_hw_rev = ATH12K_HW_WCN6855_HW21; - break; - default: - goto unsupported_wcn6855_soc; - } + sc->sc_hw_rev = ATH12K_HW_WCN7850_HW20; break; default: -unsupported_wcn6855_soc: - printf(": unsupported WCN6855 SOC version: %d %d\n", - soc_hw_version_major, soc_hw_version_minor); + printf(": unknown hardware version found for WCN785: " + "%d\n", soc_hw_version_major); return; } - pci_ops = &qwz_pci_ops_qca6390; psc->max_chan = QWZ_MHI_CONFIG_QCA6390_MAX_CHANNELS; break; default: @@ -940,9 +845,6 @@ unsupported_wcn6855_soc: return; } - /* register PCI ops */ - psc->sc_pci_ops = pci_ops; - error = qwz_pcic_init_msi_config(sc); if (error) goto err_pci_free_region; @@ -1020,8 +922,6 @@ unsupported_wcn6855_soc: if (sc->sc_nswq == NULL) goto err_ce_free; - qwz_pci_init_qmi_ce_config(sc); - error = qwz_pcic_config_irq(sc, pa); if (error) { printf("%s: failed to config irq: %d\n", @@ -1227,7 +1127,7 @@ qwz_pci_alloc_xfer_ring(struct qwz_softc *sc, struct qwz_pci_xfer_ring *ring, memset(ring->data, 0, sizeof(ring->data)); for (i = 0; i < ring->num_elements; i++) { struct qwz_xfer_data *xfer = &ring->data[i]; - + err = bus_dmamap_create(sc->sc_dmat, QWZ_PCI_XFER_MAX_DATA_SIZE, 1, QWZ_PCI_XFER_MAX_DATA_SIZE, 0, BUS_DMA_NOWAIT, &xfer->map); @@ -1296,18 +1196,6 @@ qwz_pci_alloc_xfer_rings_qca6390(struct qwz_pci_softc *psc) struct qwz_softc *sc = &psc->sc_sc; int ret; - ret = qwz_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_OUTBOUND], - 0, MHI_CHAN_TYPE_OUTBOUND, 0, 32); - if (ret) - goto fail; - - ret = qwz_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_INBOUND], - 1, MHI_CHAN_TYPE_INBOUND, 0, 32); - if (ret) - goto fail; - ret = qwz_pci_alloc_xfer_ring(sc, &psc->xfer_rings[QWZ_PCI_XFER_RING_IPCR_OUTBOUND], 20, MHI_CHAN_TYPE_OUTBOUND, 1, 64); @@ -1332,18 +1220,6 @@ qwz_pci_alloc_xfer_rings_qcn9074(struct qwz_pci_softc *psc) struct qwz_softc *sc = &psc->sc_sc; int ret; - ret = qwz_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_OUTBOUND], - 0, MHI_CHAN_TYPE_OUTBOUND, 1, 32); - if (ret) - goto fail; - - ret = qwz_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_INBOUND], - 1, MHI_CHAN_TYPE_INBOUND, 1, 32); - if (ret) - goto fail; - ret = qwz_pci_alloc_xfer_ring(sc, &psc->xfer_rings[QWZ_PCI_XFER_RING_IPCR_OUTBOUND], 20, MHI_CHAN_TYPE_OUTBOUND, 1, 32); @@ -1602,11 +1478,13 @@ qwz_pcic_ext_irq_config(struct qwz_softc *sc, struct pci_attach_args *pa) struct qwz_pci_softc *psc = (struct qwz_pci_softc *)sc; int i, ret, num_vectors = 0; uint32_t msi_data_start = 0; - uint32_t base_vector = 0; + uint32_t base_idx, base_vector = 0; if (!test_bit(ATH12K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags)) return 0; + base_idx = ATH12K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX; + ret = qwz_pcic_get_user_msi_vector(sc, "DP", &num_vectors, &msi_data_start, &base_vector); if (ret < 0) @@ -1618,7 +1496,7 @@ qwz_pcic_ext_irq_config(struct qwz_softc *sc, struct pci_attach_args *pa) irq_grp->sc = sc; irq_grp->grp_id = i; -#if 0 +#if 0 init_dummy_netdev(&irq_grp->napi_ndev); netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, ath12k_pcic_ext_grp_napi_poll); @@ -1635,7 +1513,7 @@ qwz_pcic_ext_irq_config(struct qwz_softc *sc, struct pci_attach_args *pa) } irq_grp->num_irq = num_irq; - irq_grp->irqs[0] = ATH12K_PCI_IRQ_DP_OFFSET + i; + irq_grp->irqs[0] = base_idx + i; if (num_irq) { int irq_idx = irq_grp->irqs[0]; @@ -1805,13 +1683,13 @@ qwz_pci_bus_release(struct qwz_softc *sc) uint32_t qwz_pci_get_window_start(struct qwz_softc *sc, uint32_t offset) { - if (!sc->hw_params.static_window_map) + if (!sc->static_window_map) return ATH12K_PCI_WINDOW_START; if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH12K_PCI_WINDOW_RANGE_MASK) /* if offset lies within DP register range, use 3rd window */ return 3 * ATH12K_PCI_WINDOW_START; - else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(sc)) < + else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG) < ATH12K_PCI_WINDOW_RANGE_MASK) /* if offset lies within CE register range, use 2nd window */ return 2 * ATH12K_PCI_WINDOW_START; @@ -1829,6 +1707,12 @@ qwz_pci_select_window(struct qwz_softc *sc, uint32_t offset) lockdep_assert_held(&ab_pci->window_lock); #endif + /* + * Preserve the static window configuration and reset only + * dynamic window. + */ + window |= psc->register_window & ATH12K_PCI_WINDOW_STATIC_MASK; + if (window != psc->register_window) { qwz_pci_write(sc, ATH12K_PCI_WINDOW_REG_ADDRESS, ATH12K_PCI_WINDOW_ENABLE_BIT | window); @@ -1837,6 +1721,12 @@ qwz_pci_select_window(struct qwz_softc *sc, uint32_t offset) } } +static inline bool +qwz_pci_is_offset_within_mhi_region(uint32_t offset) +{ + return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END); +} + void qwz_pci_window_write32(struct qwz_softc *sc, uint32_t offset, uint32_t value) { @@ -1849,8 +1739,15 @@ qwz_pci_window_write32(struct qwz_softc *sc, uint32_t offset, uint32_t value) spin_lock_bh(&ab_pci->window_lock); #endif qwz_pci_select_window(sc, offset); - qwz_pci_write(sc, window_start + - (offset & ATH12K_PCI_WINDOW_RANGE_MASK), value); + + if (qwz_pci_is_offset_within_mhi_region(offset)) { + offset = offset - PCI_MHIREGLEN_REG; + qwz_pci_write(sc, offset & ATH12K_PCI_WINDOW_RANGE_MASK, + value); + } else { + qwz_pci_write(sc, window_start + + (offset & ATH12K_PCI_WINDOW_RANGE_MASK), value); + } #if notyet spin_unlock_bh(&ab_pci->window_lock); #endif @@ -1872,8 +1769,15 @@ qwz_pci_window_read32(struct qwz_softc *sc, uint32_t offset) spin_lock_bh(&ab_pci->window_lock); #endif qwz_pci_select_window(sc, offset); - val = qwz_pci_read(sc, window_start + - (offset & ATH12K_PCI_WINDOW_RANGE_MASK)); + + if (qwz_pci_is_offset_within_mhi_region(offset)) { + offset = offset - PCI_MHIREGLEN_REG; + val = qwz_pci_read(sc, + offset & ATH12K_PCI_WINDOW_RANGE_MASK); + } else { + val = qwz_pci_read(sc, window_start + + (offset & ATH12K_PCI_WINDOW_RANGE_MASK)); + } #if notyet spin_unlock_bh(&ab_pci->window_lock); #endif @@ -2120,7 +2024,7 @@ qwz_pci_msi_config(struct qwz_softc *sc, bool enable) else val &= ~PCI_MSI_MC_MSIE; - pci_conf_write(psc->sc_pc, psc->sc_tag, psc->sc_msi_off + PCI_MSI_MC, + pci_conf_write(psc->sc_pc, psc->sc_tag, psc->sc_msi_off + PCI_MSI_MC, val); } @@ -2189,7 +2093,7 @@ qwz_pci_power_up(struct qwz_softc *sc) if (error) return error; - if (sc->hw_params.static_window_map) + if (sc->static_window_map) qwz_pci_select_static_window(sc); return 0; @@ -3273,7 +3177,7 @@ qwz_mhi_fw_load_bhi(struct qwz_pci_softc *psc, uint8_t *data, size_t len) qwz_pci_write(sc, psc->bhi_off + MHI_BHI_IMGADDR_LOW, paddr & 0xffffffff); qwz_pci_write(sc, psc->bhi_off + MHI_BHI_IMGSIZE, len); - + /* Set a random transaction sequence number. */ do { seq = arc4random_uniform(MHI_BHI_TXDB_SEQNUM_BMSK); diff --git a/sys/dev/pci/pcidevs b/sys/dev/pci/pcidevs index cae259b8a..c3e25564c 100644 --- a/sys/dev/pci/pcidevs +++ b/sys/dev/pci/pcidevs @@ -1,4 +1,4 @@ -$OpenBSD: pcidevs,v 1.2083 2024/08/10 11:00:14 jsg Exp $ +$OpenBSD: pcidevs,v 1.2084 2024/08/15 11:25:37 patrick Exp $ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ /* @@ -8645,6 +8645,7 @@ product QLOGIC ISP8432 0x8432 ISP8432 product QUALCOMM SC8280XP_PCIE 0x010e SC8280XP PCIe product QUALCOMM X1E80100_PCIE 0x0111 X1E80100 PCIe product QUALCOMM QCNFA765 0x1103 QCNFA765 +product QUALCOMM WCN7850 0x1107 WCN7850 /* Quancom products */ product QUANCOM PWDOG1 0x0010 PWDOG1 diff --git a/sys/dev/pci/pcidevs.h b/sys/dev/pci/pcidevs.h index 7630c84d0..e12ab3c45 100644 --- a/sys/dev/pci/pcidevs.h +++ b/sys/dev/pci/pcidevs.h @@ -2,7 +2,7 @@ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: pcidevs,v 1.2083 2024/08/10 11:00:14 jsg Exp + * OpenBSD: pcidevs,v 1.2084 2024/08/15 11:25:37 patrick Exp */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ @@ -8650,6 +8650,7 @@ #define PCI_PRODUCT_QUALCOMM_SC8280XP_PCIE 0x010e /* SC8280XP PCIe */ #define PCI_PRODUCT_QUALCOMM_X1E80100_PCIE 0x0111 /* X1E80100 PCIe */ #define PCI_PRODUCT_QUALCOMM_QCNFA765 0x1103 /* QCNFA765 */ +#define PCI_PRODUCT_QUALCOMM_WCN7850 0x1107 /* WCN7850 */ /* Quancom products */ #define PCI_PRODUCT_QUANCOM_PWDOG1 0x0010 /* PWDOG1 */ diff --git a/sys/dev/pci/pcidevs_data.h b/sys/dev/pci/pcidevs_data.h index 8413ebc5d..31593fc58 100644 --- a/sys/dev/pci/pcidevs_data.h +++ b/sys/dev/pci/pcidevs_data.h @@ -2,7 +2,7 @@ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: pcidevs,v 1.2083 2024/08/10 11:00:14 jsg Exp + * OpenBSD: pcidevs,v 1.2084 2024/08/15 11:25:37 patrick Exp */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ @@ -31207,6 +31207,10 @@ static const struct pci_known_product pci_known_products[] = { PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCNFA765, "QCNFA765", }, + { + PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_WCN7850, + "WCN7850", + }, { PCI_VENDOR_QUANCOM, PCI_PRODUCT_QUANCOM_PWDOG1, "PWDOG1", diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index e2ca8e805..75792693b 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.132 2024/08/06 17:30:04 kettenis Exp $ */ +/* $OpenBSD: xhci.c,v 1.133 2024/08/15 17:17:05 kettenis Exp $ */ /* * Copyright (c) 2014-2015 Martin Pieuchot @@ -415,6 +415,7 @@ xhci_config(struct xhci_softc *sc) { uint64_t paddr; uint32_t hcr; + int i; /* Make sure to program a number of device slots we can handle. */ if (sc->sc_noslot > USB_MAX_DEVICES) @@ -457,6 +458,27 @@ xhci_config(struct xhci_softc *sc) DPRINTF(("%s: ERDP=%#x%#x\n", DEVNAME(sc), XRREAD4(sc, XHCI_ERDP_HI(0)), XRREAD4(sc, XHCI_ERDP_LO(0)))); + /* + * If we successfully saved the state during suspend, restore + * it here. Otherwise some Intel controllers don't function + * correctly after resume. + */ + if (sc->sc_saved_state) { + XOWRITE4(sc, XHCI_USBCMD, XHCI_CMD_CRS); /* Restore state */ + hcr = XOREAD4(sc, XHCI_USBSTS); + for (i = 0; i < 100; i++) { + usb_delay_ms(&sc->sc_bus, 1); + hcr = XOREAD4(sc, XHCI_USBSTS) & XHCI_STS_RSS; + if (!hcr) + break; + } + + if (hcr) + printf("%s: restore state timeout\n", DEVNAME(sc)); + + sc->sc_saved_state = 0; + } + /* Enable interrupts. */ hcr = XRREAD4(sc, XHCI_IMAN(0)); XRWRITE4(sc, XHCI_IMAN(0), hcr | XHCI_IMAN_INTR_ENA); @@ -603,10 +625,6 @@ xhci_suspend(struct xhci_softc *sc) * unless they have seen a save state command. This in turn * will prevent the SoC from reaching its lowest idle state. * So save the state here. - * - * Note that we don't restore this saved state anywhere. - * Instead we reset the controller and reinitialize it from - * scratch when we resume. */ XOWRITE4(sc, XHCI_USBCMD, XHCI_CMD_CSS); /* Save state */ @@ -624,6 +642,8 @@ xhci_suspend(struct xhci_softc *sc) return; } + sc->sc_saved_state = 1; + /* Disable interrupts. */ XRWRITE4(sc, XHCI_IMOD(0), 0); XRWRITE4(sc, XHCI_IMAN(0), 0); diff --git a/sys/dev/usb/xhcivar.h b/sys/dev/usb/xhcivar.h index d1a4a8313..cf1e86feb 100644 --- a/sys/dev/usb/xhcivar.h +++ b/sys/dev/usb/xhcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xhcivar.h,v 1.14 2022/12/12 19:18:25 kettenis Exp $ */ +/* $OpenBSD: xhcivar.h,v 1.15 2024/08/15 17:17:05 kettenis Exp $ */ /* * Copyright (c) 2014 Martin Pieuchot @@ -89,6 +89,7 @@ struct xhci_softc { bus_size_t sc_size; int sc_dead; + int sc_saved_state; bus_size_t sc_oper_off; /* Operational Register space */ bus_size_t sc_runt_off; /* Runtime */ diff --git a/sys/net/bpf.c b/sys/net/bpf.c index b7c2f1bfd..d77ad57ac 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.c,v 1.224 2024/08/12 17:02:58 mvs Exp $ */ +/* $OpenBSD: bpf.c,v 1.225 2024/08/15 12:20:20 dlg Exp $ */ /* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */ /* @@ -760,7 +760,8 @@ bpf_get_wtimeout(struct bpf_d *d, struct timeval *tv) /* * FIONREAD Check for read packet available. * BIOCGBLEN Get buffer len [for read()]. - * BIOCSETF Set ethernet read filter. + * BIOCSETF Set read filter. + * BIOCSETFNR Set read filter without resetting descriptor. * BIOCFLUSH Flush read packet buffer. * BIOCPROMISC Put interface into promiscuous mode. * BIOCGDLTLIST Get supported link layer types. @@ -867,17 +868,12 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) break; /* - * Set link layer read filter. + * Set link layer read/write filter. */ case BIOCSETF: - error = bpf_setf(d, (struct bpf_program *)addr, 0); - break; - - /* - * Set link layer write filter. - */ + case BIOCSETFNR: case BIOCSETWF: - error = bpf_setf(d, (struct bpf_program *)addr, 1); + error = bpf_setf(d, (struct bpf_program *)addr, cmd); break; /* @@ -1122,7 +1118,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) * free it and replace it. Returns EINVAL for bogus requests. */ int -bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf) +bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd) { struct bpf_program_smr *bps, *old_bps; struct bpf_insn *fcode; @@ -1157,7 +1153,7 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf) bps->bps_bf.bf_insns = fcode; } - if (wf == 0) { + if (cmd != BIOCSETWF) { old_bps = SMR_PTR_GET_LOCKED(&d->bd_rfilter); SMR_PTR_SET_LOCKED(&d->bd_rfilter, bps); } else { @@ -1165,9 +1161,12 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf) SMR_PTR_SET_LOCKED(&d->bd_wfilter, bps); } - mtx_enter(&d->bd_mtx); - bpf_resetd(d); - mtx_leave(&d->bd_mtx); + if (cmd == BIOCSETF) { + mtx_enter(&d->bd_mtx); + bpf_resetd(d); + mtx_leave(&d->bd_mtx); + } + if (old_bps != NULL) smr_call(&old_bps->bps_smr, bpf_prog_smr, old_bps); diff --git a/sys/net/bpf.h b/sys/net/bpf.h index ab64061fb..91b367c13 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.h,v 1.72 2024/01/26 21:14:08 jan Exp $ */ +/* $OpenBSD: bpf.h,v 1.73 2024/08/15 12:20:20 dlg Exp $ */ /* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */ /* @@ -122,6 +122,7 @@ struct bpf_version { #define BIOCSWTIMEOUT _IOW('B',126, struct timeval) #define BIOCGWTIMEOUT _IOR('B',126, struct timeval) #define BIOCDWTIMEOUT _IO('B',126) +#define BIOCSETFNR _IOW('B',127, struct bpf_program) /* * Direction filters for BIOCSDIRFILT/BIOCGDIRFILT diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h index 76b75ff5a..4b558c4eb 100644 --- a/sys/net/bpfdesc.h +++ b/sys/net/bpfdesc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bpfdesc.h,v 1.48 2023/03/09 05:56:58 dlg Exp $ */ +/* $OpenBSD: bpfdesc.h,v 1.49 2024/08/15 12:20:20 dlg Exp $ */ /* $NetBSD: bpfdesc.h,v 1.11 1995/09/27 18:30:42 thorpej Exp $ */ /* @@ -123,6 +123,6 @@ struct bpf_if { struct ifnet *bif_ifp; /* corresponding interface */ }; -int bpf_setf(struct bpf_d *, struct bpf_program *, int); +int bpf_setf(struct bpf_d *, struct bpf_program *, u_long); #endif /* _KERNEL */ #endif /* _NET_BPFDESC_H_ */ diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c index 70c98dd0f..07e7e1d99 100644 --- a/usr.bin/ssh/packet.c +++ b/usr.bin/ssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.315 2024/05/31 08:49:35 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.316 2024/08/15 00:51:51 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -2617,6 +2617,11 @@ sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g) return sshbuf_put_ec(ssh->state->outgoing_packet, v, g); } +int +sshpkt_put_ec_pkey(struct ssh *ssh, EVP_PKEY *pkey) +{ + return sshbuf_put_ec_pkey(ssh->state->outgoing_packet, pkey); +} int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h index fc2c3278b..db6113666 100644 --- a/usr.bin/ssh/packet.h +++ b/usr.bin/ssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.98 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: packet.h,v 1.99 2024/08/15 00:51:51 djm Exp $ */ /* * Author: Tatu Ylonen @@ -25,10 +25,12 @@ #include #include #include +#include #else /* OPENSSL */ #define BIGNUM void #define EC_GROUP void #define EC_POINT void +#define EVP_PKEY void #endif /* WITH_OPENSSL */ struct kex; @@ -185,6 +187,7 @@ int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len); int sshpkt_put_cstring(struct ssh *ssh, const void *v); int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); +int sshpkt_put_ec_pkey(struct ssh *ssh, EVP_PKEY *pkey); int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); int sshpkt_get(struct ssh *ssh, void *valp, size_t len); diff --git a/usr.bin/ssh/ssh-ecdsa-sk.c b/usr.bin/ssh/ssh-ecdsa-sk.c index 15e993c44..0502a4999 100644 --- a/usr.bin/ssh/ssh-ecdsa-sk.c +++ b/usr.bin/ssh/ssh-ecdsa-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa-sk.c,v 1.18 2023/03/08 04:43:12 guenther Exp $ */ +/* $OpenBSD: ssh-ecdsa-sk.c,v 1.19 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -219,11 +219,13 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, struct sshkey_sig_details **detailsp) { ECDSA_SIG *esig = NULL; + EVP_MD_CTX *md_ctx = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; u_char sig_flags; - u_char msghash[32], apphash[32], sighash[32]; + u_char msghash[32], apphash[32]; u_int sig_counter; - int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR; + u_char *sigb = NULL, *cp; + int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR, len = 0; struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL; struct sshbuf *webauthn_wrapper = NULL, *webauthn_exts = NULL; char *ktype = NULL, *webauthn_origin = NULL; @@ -234,7 +236,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, if (detailsp != NULL) *detailsp = NULL; - if (key == NULL || key->ecdsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_ECDSA_SK || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; @@ -345,21 +347,43 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, (ret = sshbuf_putb(original_signed, webauthn_exts)) != 0 || (ret = sshbuf_put(original_signed, msghash, sizeof(msghash))) != 0) goto out; - /* Signature is over H(original_signed) */ - if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed, - sighash, sizeof(sighash))) != 0) - goto out; details->sk_counter = sig_counter; details->sk_flags = sig_flags; #ifdef DEBUG_SK fprintf(stderr, "%s: signed buf:\n", __func__); sshbuf_dump(original_signed, stderr); - fprintf(stderr, "%s: signed hash:\n", __func__); - sshbuf_dump_data(sighash, sizeof(sighash), stderr); #endif + if ((md_ctx = EVP_MD_CTX_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((len = i2d_ECDSA_SIG(esig, NULL)) <= 0) { + len = 0; + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if ((sigb = calloc(1, len)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + cp = sigb; /* ASN1_item_i2d increments the pointer past the object */ + if (i2d_ECDSA_SIG(esig, &cp) != len) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +#ifdef DEBUG_SK + fprintf(stderr, "%s: signed hash:\n", __func__); + sshbuf_dump_data(sigb, len, stderr); +#endif /* Verify it */ - switch (ECDSA_do_verify(sighash, sizeof(sighash), esig, key->ecdsa)) { + if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, + key->pkey) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + switch (EVP_DigestVerify(md_ctx, sigb, len, + sshbuf_ptr(original_signed), sshbuf_len(original_signed))) { case 1: ret = 0; break; @@ -379,7 +403,6 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, explicit_bzero(&sig_flags, sizeof(sig_flags)); explicit_bzero(&sig_counter, sizeof(sig_counter)); explicit_bzero(msghash, sizeof(msghash)); - explicit_bzero(sighash, sizeof(msghash)); explicit_bzero(apphash, sizeof(apphash)); sshkey_sig_details_free(details); sshbuf_free(webauthn_wrapper); @@ -392,6 +415,8 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, BN_clear_free(sig_r); BN_clear_free(sig_s); free(ktype); + freezero(sigb, len); + EVP_MD_CTX_free(md_ctx); return ret; } diff --git a/usr.bin/ssh/ssh-ecdsa.c b/usr.bin/ssh/ssh-ecdsa.c index 59ed0c84d..aa59b33cd 100644 --- a/usr.bin/ssh/ssh-ecdsa.c +++ b/usr.bin/ssh/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.26 2023/03/08 04:43:12 guenther Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -39,6 +39,59 @@ #define SSHKEY_INTERNAL #include "sshkey.h" +int +sshkey_ecdsa_fixup_group(EVP_PKEY *k) +{ + int nids[] = { + NID_X9_62_prime256v1, + NID_secp384r1, + NID_secp521r1, + -1 + }; + int nid = -1; + u_int i; + const EC_GROUP *g; + EC_KEY *ec = NULL; + EC_GROUP *eg = NULL; + + if ((ec = EVP_PKEY_get1_EC_KEY(k)) == NULL || + (g = EC_KEY_get0_group(ec)) == NULL) + goto out; + /* + * The group may be stored in a ASN.1 encoded private key in one of two + * ways: as a "named group", which is reconstituted by ASN.1 object ID + * or explicit group parameters encoded into the key blob. Only the + * "named group" case sets the group NID for us, but we can figure + * it out for the other case by comparing against all the groups that + * are supported. + */ + if ((nid = EC_GROUP_get_curve_name(g)) > 0) + goto out; + nid = -1; + for (i = 0; nids[i] != -1; i++) { + if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) + goto out; + if (EC_GROUP_cmp(g, eg, NULL) == 0) + break; + EC_GROUP_free(eg); + eg = NULL; + } + if (nids[i] == -1) + goto out; + + /* Use the group with the NID attached */ + EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(ec, eg) != 1 || + EVP_PKEY_set1_EC_KEY(k, ec) != 1) + goto out; + /* success */ + nid = nids[i]; + out: + EC_KEY_free(ec); + EC_GROUP_free(eg); + return nid; +} + static u_int ssh_ecdsa_size(const struct sshkey *key) { @@ -57,30 +110,16 @@ ssh_ecdsa_size(const struct sshkey *key) static void ssh_ecdsa_cleanup(struct sshkey *k) { - EC_KEY_free(k->ecdsa); - k->ecdsa = NULL; + EVP_PKEY_free(k->pkey); + k->pkey = NULL; } static int ssh_ecdsa_equal(const struct sshkey *a, const struct sshkey *b) { - const EC_GROUP *grp_a, *grp_b; - const EC_POINT *pub_a, *pub_b; - - if (a->ecdsa == NULL || b->ecdsa == NULL) + if (a->pkey == NULL || b->pkey == NULL) return 0; - if ((grp_a = EC_KEY_get0_group(a->ecdsa)) == NULL || - (grp_b = EC_KEY_get0_group(b->ecdsa)) == NULL) - return 0; - if ((pub_a = EC_KEY_get0_public_key(a->ecdsa)) == NULL || - (pub_b = EC_KEY_get0_public_key(b->ecdsa)) == NULL) - return 0; - if (EC_GROUP_cmp(grp_a, grp_b, NULL) != 0) - return 0; - if (EC_POINT_cmp(grp_a, pub_a, pub_b, NULL) != 0) - return 0; - - return 1; + return EVP_PKEY_cmp(a->pkey, b->pkey) == 1; } static int @@ -89,11 +128,11 @@ ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b, { int r; - if (key->ecdsa == NULL) + if (key->pkey == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((r = sshbuf_put_cstring(b, sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || - (r = sshbuf_put_eckey(b, key->ecdsa)) != 0) + (r = sshbuf_put_ec_pkey(b, key->pkey)) != 0) return r; return 0; @@ -110,7 +149,7 @@ ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b, return r; } if ((r = sshbuf_put_bignum2(b, - EC_KEY_get0_private_key(key->ecdsa))) != 0) + EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(key->pkey)))) != 0) return r; return 0; } @@ -118,31 +157,64 @@ ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b, static int ssh_ecdsa_generate(struct sshkey *k, int bits) { - EC_KEY *private; + EVP_PKEY *res = NULL; + EVP_PKEY_CTX *ctx = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) return SSH_ERR_KEY_LENGTH; - if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) + + if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) return SSH_ERR_ALLOC_FAIL; - if (EC_KEY_generate_key(private) != 1) { - EC_KEY_free(private); - return SSH_ERR_LIBCRYPTO_ERROR; + + if (EVP_PKEY_keygen_init(ctx) <= 0 || + EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, k->ecdsa_nid) <= 0 || + EVP_PKEY_keygen(ctx, &res) <= 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; } - EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); - k->ecdsa = private; - return 0; + /* success */ + k->pkey = res; + res = NULL; + ret = 0; + out: + EVP_PKEY_free(res); + EVP_PKEY_CTX_free(ctx); + return ret; } static int ssh_ecdsa_copy_public(const struct sshkey *from, struct sshkey *to) { + const EC_KEY *ec_from; + EC_KEY *ec_to = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + + ec_from = EVP_PKEY_get0_EC_KEY(from->pkey); + if (ec_from == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + to->ecdsa_nid = from->ecdsa_nid; - if ((to->ecdsa = EC_KEY_new_by_curve_name(from->ecdsa_nid)) == NULL) + if ((ec_to = EC_KEY_new_by_curve_name(from->ecdsa_nid)) == NULL) return SSH_ERR_ALLOC_FAIL; - if (EC_KEY_set_public_key(to->ecdsa, - EC_KEY_get0_public_key(from->ecdsa)) != 1) - return SSH_ERR_LIBCRYPTO_ERROR; /* caller will free k->ecdsa */ - return 0; + if (EC_KEY_set_public_key(ec_to, + EC_KEY_get0_public_key(ec_from)) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + EVP_PKEY_free(to->pkey); + if ((to->pkey = EVP_PKEY_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(to->pkey, ec_to) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + ret = 0; + out: + EC_KEY_free(ec_to); + return ret; } static int @@ -151,6 +223,8 @@ ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b, { int r; char *curve = NULL; + EVP_PKEY *pkey = NULL; + EC_KEY *ec = NULL; if ((key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype)) == -1) return SSH_ERR_INVALID_ARGUMENT; @@ -160,31 +234,39 @@ ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b, r = SSH_ERR_EC_CURVE_MISMATCH; goto out; } - EC_KEY_free(key->ecdsa); - key->ecdsa = NULL; - if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) { + if ((ec = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((r = sshbuf_get_eckey(b, key->ecdsa)) != 0) + if ((r = sshbuf_get_eckey(b, ec)) != 0) goto out; - if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), - EC_KEY_get0_public_key(key->ecdsa)) != 0) { + if (sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec)) != 0) { r = SSH_ERR_KEY_INVALID_EC_VALUE; goto out; } + if ((pkey = EVP_PKEY_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(pkey, ec) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + EVP_PKEY_free(key->pkey); + key->pkey = pkey; + pkey = NULL; /* success */ r = 0; #ifdef DEBUG_PK - sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), - EC_KEY_get0_public_key(key->ecdsa)); + sshkey_dump_ec_point( + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(key->pkey)), + EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(key->pkey))); #endif out: + EC_KEY_free(ec); + EVP_PKEY_free(pkey); free(curve); - if (r != 0) { - EC_KEY_free(key->ecdsa); - key->ecdsa = NULL; - } return r; } @@ -194,6 +276,7 @@ ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b, { int r; BIGNUM *exponent = NULL; + EC_KEY *ec = NULL; if (!sshkey_is_cert(key)) { if ((r = ssh_ecdsa_deserialize_public(ktype, b, key)) != 0) @@ -201,16 +284,25 @@ ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b, } if ((r = sshbuf_get_bignum2(b, &exponent)) != 0) goto out; - if (EC_KEY_set_private_key(key->ecdsa, exponent) != 1) { + if ((ec = EVP_PKEY_get1_EC_KEY(key->pkey)) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((r = sshkey_ec_validate_private(key->ecdsa)) != 0) + if (EC_KEY_set_private_key(ec, exponent) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; goto out; + } + if ((r = sshkey_ec_validate_private(ec)) != 0) + goto out; + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } /* success */ r = 0; out: BN_clear_free(exponent); + EC_KEY_free(ec); return r; } @@ -221,34 +313,35 @@ ssh_ecdsa_sign(struct sshkey *key, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { ECDSA_SIG *esig = NULL; + unsigned char *sigb = NULL; + const unsigned char *psig; const BIGNUM *sig_r, *sig_s; int hash_alg; - u_char digest[SSH_DIGEST_MAX_LENGTH]; - size_t len, hlen; + size_t slen = 0; struct sshbuf *b = NULL, *bb = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; + int len = 0, ret = SSH_ERR_INTERNAL_ERROR; if (lenp != NULL) *lenp = 0; if (sigp != NULL) *sigp = NULL; - if (key == NULL || key->ecdsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_ECDSA) return SSH_ERR_INVALID_ARGUMENT; - if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || - (hlen = ssh_digest_bytes(hash_alg)) == 0) + if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) return SSH_ERR_INTERNAL_ERROR; - if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) + + if ((ret = sshkey_pkey_digest_sign(key->pkey, hash_alg, &sigb, &slen, + data, dlen)) != 0) goto out; - if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { + psig = sigb; + if ((esig = d2i_ECDSA_SIG(NULL, &psig, slen)) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; @@ -272,7 +365,7 @@ ssh_ecdsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - explicit_bzero(digest, sizeof(digest)); + freezero(sigb, slen); sshbuf_free(b); sshbuf_free(bb); ECDSA_SIG_free(esig); @@ -287,20 +380,18 @@ ssh_ecdsa_verify(const struct sshkey *key, { ECDSA_SIG *esig = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; - int hash_alg; - u_char digest[SSH_DIGEST_MAX_LENGTH]; - size_t hlen; + int hash_alg, len = 0; int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL, *sigbuf = NULL; char *ktype = NULL; + unsigned char *sigb = NULL, *cp; - if (key == NULL || key->ecdsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_ECDSA || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; - if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || - (hlen = ssh_digest_bytes(hash_alg)) == 0) + if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) return SSH_ERR_INTERNAL_ERROR; /* fetch signature */ @@ -326,6 +417,11 @@ ssh_ecdsa_verify(const struct sshkey *key, ret = SSH_ERR_INVALID_FORMAT; goto out; } + if (sshbuf_len(sigbuf) != 0) { + ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; + goto out; + } + if ((esig = ECDSA_SIG_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; @@ -336,28 +432,26 @@ ssh_ecdsa_verify(const struct sshkey *key, } sig_r = sig_s = NULL; /* transferred */ - if (sshbuf_len(sigbuf) != 0) { - ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; - goto out; - } - if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) - goto out; - - switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) { - case 1: - ret = 0; - break; - case 0: - ret = SSH_ERR_SIGNATURE_INVALID; - goto out; - default: + if ((len = i2d_ECDSA_SIG(esig, NULL)) <= 0) { + len = 0; ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - + if ((sigb = calloc(1, len)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + cp = sigb; /* ASN1_item_i2d increments the pointer past the object */ + if (i2d_ECDSA_SIG(esig, &cp) != len) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if ((ret = sshkey_pkey_digest_verify(key->pkey, hash_alg, + data, dlen, sigb, len)) != 0) + goto out; + /* success */ out: - explicit_bzero(digest, sizeof(digest)); + freezero(sigb, len); sshbuf_free(sigbuf); sshbuf_free(b); ECDSA_SIG_free(esig); diff --git a/usr.bin/ssh/ssh-keygen.c b/usr.bin/ssh/ssh-keygen.c index 844802650..4a95c5515 100644 --- a/usr.bin/ssh/ssh-keygen.c +++ b/usr.bin/ssh/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.472 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.473 2024/08/15 00:51:51 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -362,7 +362,8 @@ do_convert_to_pkcs8(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { case KEY_RSA: - if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) + if (!PEM_write_RSA_PUBKEY(stdout, + EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSA_PUBKEY failed"); break; #ifdef WITH_DSA @@ -372,7 +373,8 @@ do_convert_to_pkcs8(struct sshkey *k) break; #endif case KEY_ECDSA: - if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) + if (!PEM_write_EC_PUBKEY(stdout, + EVP_PKEY_get0_EC_KEY(k->pkey))) fatal("PEM_write_EC_PUBKEY failed"); break; default: @@ -386,7 +388,8 @@ do_convert_to_pem(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { case KEY_RSA: - if (!PEM_write_RSAPublicKey(stdout, k->rsa)) + if (!PEM_write_RSAPublicKey(stdout, + EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSAPublicKey failed"); break; #ifdef WITH_DSA @@ -396,7 +399,8 @@ do_convert_to_pem(struct sshkey *k) break; #endif case KEY_ECDSA: - if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) + if (!PEM_write_EC_PUBKEY(stdout, + EVP_PKEY_get0_EC_KEY(k->pkey))) fatal("PEM_write_EC_PUBKEY failed"); break; default: @@ -473,6 +477,8 @@ do_convert_private_ssh2(struct sshbuf *b) #endif BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; + BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; + RSA *rsa = NULL; if ((r = sshbuf_get_u32(b, &magic)) != 0) fatal_fr(r, "parse magic"); @@ -567,15 +573,25 @@ do_convert_private_ssh2(struct sshbuf *b) buffer_get_bignum_bits(b, rsa_iqmp); buffer_get_bignum_bits(b, rsa_q); buffer_get_bignum_bits(b, rsa_p); - if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d)) + if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, + rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) + fatal_fr(r, "generate RSA CRT parameters"); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal_f("EVP_PKEY_new failed"); + if ((rsa = RSA_new()) == NULL) + fatal_f("RSA_new failed"); + if (!RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d)) fatal_f("RSA_set0_key failed"); rsa_n = rsa_e = rsa_d = NULL; /* transferred */ - if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) + if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) fatal_f("RSA_set0_factors failed"); rsa_p = rsa_q = NULL; /* transferred */ - if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) - fatal_fr(r, "generate RSA parameters"); - BN_clear_free(rsa_iqmp); + if (RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp) != 1) + fatal_f("RSA_set0_crt_params failed"); + rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) + fatal_f("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa); alg = "rsa-sha2-256"; break; } @@ -695,7 +711,8 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); (*k)->type = KEY_RSA; - (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); + (*k)->pkey = pubkey; + pubkey = NULL; break; #ifdef WITH_DSA case EVP_PKEY_DSA: @@ -708,9 +725,11 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) case EVP_PKEY_EC: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); + if (((*k)->ecdsa_nid = sshkey_ecdsa_fixup_group(pubkey)) == -1) + fatal("sshkey_ecdsa_fixup_group failed"); (*k)->type = KEY_ECDSA; - (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); - (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa); + (*k)->pkey = pubkey; + pubkey = NULL; break; default: fatal_f("unsupported pubkey type %d", @@ -731,8 +750,12 @@ do_convert_from_pem(struct sshkey **k, int *private) if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); + if (((*k)->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); (*k)->type = KEY_RSA; - (*k)->rsa = rsa; + if (EVP_PKEY_set1_RSA((*k)->pkey, rsa) != 1) + fatal("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa); fclose(fp); return; } @@ -779,12 +802,14 @@ do_convert_from(struct passwd *pw) break; #endif case KEY_ECDSA: - ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, - NULL, 0, NULL, NULL); + ok = PEM_write_ECPrivateKey(stdout, + EVP_PKEY_get0_EC_KEY(k->pkey), NULL, NULL, 0, + NULL, NULL); break; case KEY_RSA: - ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, - NULL, 0, NULL, NULL); + ok = PEM_write_RSAPrivateKey(stdout, + EVP_PKEY_get0_RSA(k->pkey), NULL, NULL, 0, + NULL, NULL); break; default: fatal_f("unsupported key type %s", sshkey_type(k)); diff --git a/usr.bin/ssh/ssh-pkcs11-client.c b/usr.bin/ssh/ssh-pkcs11-client.c index af9ad1b88..205139f43 100644 --- a/usr.bin/ssh/ssh-pkcs11-client.c +++ b/usr.bin/ssh/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.19 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.20 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -247,14 +247,17 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) debug3_f("signing with PKCS11 provider %s", helper->path); if (padding != RSA_PKCS1_PADDING) goto fail; - key = sshkey_new(KEY_UNSPEC); - if (key == NULL) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { error_f("sshkey_new failed"); goto fail; } + if ((key->pkey = EVP_PKEY_new()) == NULL || + EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { + error_f("pkey setup failed"); + goto fail; + } + key->type = KEY_RSA; - RSA_up_ref(rsa); - key->rsa = rsa; if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { error_fr(r, "encode key"); goto fail; @@ -321,21 +324,22 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1) fatal_f("no helper for PKCS11 key"); debug3_f("signing with PKCS11 provider %s", helper->path); - nid = sshkey_ecdsa_key_to_nid(ec); - if (nid < 0) { - error_f("couldn't get curve nid"); - goto fail; - } - key = sshkey_new(KEY_UNSPEC); - if (key == NULL) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { error_f("sshkey_new failed"); goto fail; } - key->ecdsa = ec; + if ((key->pkey = EVP_PKEY_new()) == NULL || + EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { + error("pkey setup failed"); + goto fail; + } + if ((nid = sshkey_ecdsa_pkey_to_nid(key->pkey)) < 0) { + error("couldn't get curve nid"); + goto fail; + } key->ecdsa_nid = nid; key->type = KEY_ECDSA; - EC_KEY_up_ref(ec); if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { error_fr(r, "encode key"); @@ -389,15 +393,30 @@ ecdsa_do_finish(EC_KEY *ec) static void wrap_key(struct helper *helper, struct sshkey *k) { + RSA *rsa = NULL; + EC_KEY *ecdsa = NULL; + debug3_f("wrap %s for provider %s", sshkey_type(k), helper->path); if (k->type == KEY_RSA) { - RSA_set_method(k->rsa, helper->rsa_meth); + if ((rsa = EVP_PKEY_get1_RSA(k->pkey)) == NULL) + fatal_f("no RSA key"); + if (RSA_set_method(rsa, helper->rsa_meth) != 1) + fatal_f("RSA_set_method failed"); if (helper->nrsa++ >= INT_MAX) fatal_f("RSA refcount error"); + if (EVP_PKEY_set1_RSA(k->pkey, rsa) != 1) + fatal_f("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa); } else if (k->type == KEY_ECDSA) { - EC_KEY_set_method(k->ecdsa, helper->ec_meth); + if ((ecdsa = EVP_PKEY_get1_EC_KEY(k->pkey)) == NULL) + fatal_f("no ECDSA key"); + if (EC_KEY_set_method(ecdsa, helper->ec_meth) != 1) + fatal_f("EC_KEY_set_method failed"); if (helper->nec++ >= INT_MAX) fatal_f("EC refcount error"); + if (EVP_PKEY_set1_EC_KEY(k->pkey, ecdsa) != 1) + fatal_f("EVP_PKEY_set1_EC_KEY failed"); + EC_KEY_free(ecdsa); } else fatal_f("unknown key type"); k->flags |= SSHKEY_FLAG_EXT; @@ -416,6 +435,8 @@ pkcs11_make_cert(const struct sshkey *priv, struct helper *helper = NULL; struct sshkey *ret; int r; + RSA *rsa_priv = NULL, *rsa_cert = NULL; + EC_KEY *ec_priv = NULL, *ec_cert = NULL; debug3_f("private key type %s cert type %s", sshkey_type(priv), sshkey_type(certpub)); @@ -428,23 +449,41 @@ pkcs11_make_cert(const struct sshkey *priv, } *certprivp = NULL; if (priv->type == KEY_RSA) { - if ((helper = helper_by_rsa(priv->rsa)) == NULL || + if ((rsa_priv = EVP_PKEY_get1_RSA(priv->pkey)) == NULL) + fatal_f("no RSA pkey"); + if ((helper = helper_by_rsa(rsa_priv)) == NULL || helper->fd == -1) fatal_f("no helper for PKCS11 RSA key"); if ((r = sshkey_from_private(priv, &ret)) != 0) fatal_fr(r, "copy key"); - RSA_set_method(ret->rsa, helper->rsa_meth); + if ((rsa_cert = EVP_PKEY_get1_RSA(ret->pkey)) == NULL) + fatal_f("no RSA cert pkey"); + if (RSA_set_method(rsa_cert, helper->rsa_meth) != 1) + fatal_f("RSA_set_method failed"); if (helper->nrsa++ >= INT_MAX) fatal_f("RSA refcount error"); + if (EVP_PKEY_set1_RSA(ret->pkey, rsa_cert) != 1) + fatal_f("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa_priv); + RSA_free(rsa_cert); } else if (priv->type == KEY_ECDSA) { - if ((helper = helper_by_ec(priv->ecdsa)) == NULL || + if ((ec_priv = EVP_PKEY_get1_EC_KEY(priv->pkey)) == NULL) + fatal_f("no EC pkey"); + if ((helper = helper_by_ec(ec_priv)) == NULL || helper->fd == -1) fatal_f("no helper for PKCS11 EC key"); if ((r = sshkey_from_private(priv, &ret)) != 0) fatal_fr(r, "copy key"); - EC_KEY_set_method(ret->ecdsa, helper->ec_meth); + if ((ec_cert = EVP_PKEY_get1_EC_KEY(ret->pkey)) == NULL) + fatal_f("no EC cert pkey"); + if (EC_KEY_set_method(ec_cert, helper->ec_meth) != 1) + fatal_f("EC_KEY_set_method failed"); if (helper->nec++ >= INT_MAX) fatal_f("EC refcount error"); + if (EVP_PKEY_set1_EC_KEY(ret->pkey, ec_cert) != 1) + fatal_f("EVP_PKEY_set1_EC_KEY failed"); + EC_KEY_free(ec_priv); + EC_KEY_free(ec_cert); } else fatal_f("unknown key type %s", sshkey_type(priv)); diff --git a/usr.bin/ssh/ssh-pkcs11-helper.c b/usr.bin/ssh/ssh-pkcs11-helper.c index 1a62757c1..3f79a0061 100644 --- a/usr.bin/ssh/ssh-pkcs11-helper.c +++ b/usr.bin/ssh/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.26 2021/11/18 03:31:44 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -36,6 +36,8 @@ #include "ssherr.h" #ifdef WITH_OPENSSL +#include +#include /* borrows code from sftp-server and ssh-agent */ @@ -176,10 +178,13 @@ static void process_sign(void) { u_char *blob, *data, *signature = NULL; - size_t blen, dlen, slen = 0; - int r, ok = -1; - struct sshkey *key, *found; + size_t blen, dlen; + u_int slen = 0; + int len, r, ok = -1; + struct sshkey *key = NULL, *found; struct sshbuf *msg; + RSA *rsa = NULL; + EC_KEY *ecdsa = NULL; /* XXX support SHA2 signature flags */ if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 || @@ -189,39 +194,43 @@ process_sign(void) if ((r = sshkey_from_blob(blob, blen, &key)) != 0) fatal_fr(r, "decode key"); - else { - if ((found = lookup_key(key)) != NULL) { -#ifdef WITH_OPENSSL - int ret; + if ((found = lookup_key(key)) == NULL) + goto reply; - if (key->type == KEY_RSA) { - slen = RSA_size(key->rsa); - signature = xmalloc(slen); - ret = RSA_private_encrypt(dlen, data, signature, - found->rsa, RSA_PKCS1_PADDING); - if (ret != -1) { - slen = ret; - ok = 0; - } - } else if (key->type == KEY_ECDSA) { - u_int xslen = ECDSA_size(key->ecdsa); - - signature = xmalloc(xslen); - /* "The parameter type is ignored." */ - ret = ECDSA_sign(-1, data, dlen, signature, - &xslen, found->ecdsa); - if (ret != 0) - ok = 0; - else - error_f("ECDSA_sign returned %d", ret); - slen = xslen; - } else - error_f("don't know how to sign with key " - "type %d", (int)key->type); -#endif /* WITH_OPENSSL */ + /* XXX use pkey API properly for signing */ + switch (key->type) { + case KEY_RSA: + if ((rsa = EVP_PKEY_get1_RSA(found->pkey)) == NULL) + fatal_f("no RSA in pkey"); + if ((len = RSA_size(rsa)) < 0) + fatal_f("bad RSA length"); + signature = xmalloc(len); + if ((len = RSA_private_encrypt(dlen, data, signature, + rsa, RSA_PKCS1_PADDING)) < 0) { + error_f("RSA_private_encrypt failed"); + goto reply; } - sshkey_free(key); + slen = (u_int)len; + break; + case KEY_ECDSA: + if ((ecdsa = EVP_PKEY_get1_EC_KEY(found->pkey)) == NULL) + fatal_f("no ECDSA in pkey"); + if ((len = ECDSA_size(ecdsa)) < 0) + fatal_f("bad ECDSA length"); + slen = (u_int)len; + signature = xmalloc(slen); + /* "The parameter type is ignored." */ + if (!ECDSA_sign(-1, data, dlen, signature, &slen, ecdsa)) { + error_f("ECDSA_sign failed"); + goto reply; + } + break; + default: + fatal_f("unsupported key type %d", key->type); } + /* success */ + ok = 0; + reply: if ((msg = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); if (ok == 0) { @@ -232,6 +241,9 @@ process_sign(void) if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0) fatal_fr(r, "compose failure response"); } + sshkey_free(key); + RSA_free(rsa); + EC_KEY_free(ecdsa); free(data); free(blob); free(signature); diff --git a/usr.bin/ssh/ssh-pkcs11.c b/usr.bin/ssh/ssh-pkcs11.c index e6c53f00e..97c98cc94 100644 --- a/usr.bin/ssh/ssh-pkcs11.c +++ b/usr.bin/ssh/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.62 2024/04/02 12:22:38 deraadt Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.63 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -493,8 +493,10 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } - RSA_set_method(rsa, rsa_method); - RSA_set_ex_data(rsa, rsa_idx, k11); + if (RSA_set_method(rsa, rsa_method) != 1) + fatal_f("RSA_set_method failed"); + if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) + fatal_f("RSA_set_ex_data failed"); return (0); } @@ -605,8 +607,10 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } - EC_KEY_set_method(ec, ec_key_method); - EC_KEY_set_ex_data(ec, ec_key_idx, k11); + if (EC_KEY_set_method(ec, ec_key_method) != 1) + fatal_f("EC_KEY_set_method failed"); + if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) + fatal_f("EC_KEY_set_ex_data failed"); return (0); } @@ -791,11 +795,14 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - key->ecdsa = ec; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) + fatal("EVP_PKEY_set1_EC_KEY failed"); key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; - ec = NULL; /* now owned by key */ fail: for (i = 0; i < 3; i++) @@ -886,10 +893,13 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - key->rsa = rsa; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) + fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; - rsa = NULL; /* now owned by key */ fail: for (i = 0; i < 3; i++) @@ -997,10 +1007,13 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } - key->rsa = rsa; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) + fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; - rsa = NULL; /* now owned by key */ } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { error("invalid x509; no ec key"); @@ -1026,11 +1039,14 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } - key->ecdsa = ec; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) + fatal("EVP_PKEY_set1_EC_KEY failed"); key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; - ec = NULL; /* now owned by key */ } else { error("unknown certificate key type"); goto out; diff --git a/usr.bin/ssh/ssh-rsa.c b/usr.bin/ssh/ssh-rsa.c index 59f7cd28a..6492e607b 100644 --- a/usr.bin/ssh/ssh-rsa.c +++ b/usr.bin/ssh/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.79 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.80 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -29,23 +29,18 @@ #include "digest.h" #include "log.h" -static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); - static u_int -ssh_rsa_size(const struct sshkey *key) +ssh_rsa_size(const struct sshkey *k) { - const BIGNUM *rsa_n; - - if (key->rsa == NULL) + if (k->pkey == NULL) return 0; - RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); - return BN_num_bits(rsa_n); + return EVP_PKEY_bits(k->pkey); } static int ssh_rsa_alloc(struct sshkey *k) { - if ((k->rsa = RSA_new()) == NULL) + if ((k->pkey = EVP_PKEY_new()) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; } @@ -53,29 +48,16 @@ ssh_rsa_alloc(struct sshkey *k) static void ssh_rsa_cleanup(struct sshkey *k) { - RSA_free(k->rsa); - k->rsa = NULL; + EVP_PKEY_free(k->pkey); + k->pkey = NULL; } static int ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b) { - const BIGNUM *rsa_e_a, *rsa_n_a; - const BIGNUM *rsa_e_b, *rsa_n_b; - - if (a->rsa == NULL || b->rsa == NULL) + if (a->pkey == NULL || b->pkey == NULL) return 0; - RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL); - RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL); - if (rsa_e_a == NULL || rsa_e_b == NULL) - return 0; - if (rsa_n_a == NULL || rsa_n_b == NULL) - return 0; - if (BN_cmp(rsa_e_a, rsa_e_b) != 0) - return 0; - if (BN_cmp(rsa_n_a, rsa_n_b) != 0) - return 0; - return 1; + return EVP_PKEY_cmp(a->pkey, b->pkey) == 1; } static int @@ -84,10 +66,14 @@ ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b, { int r; const BIGNUM *rsa_n, *rsa_e; + const RSA *rsa; - if (key->rsa == NULL) + if (key->pkey == NULL) return SSH_ERR_INVALID_ARGUMENT; - RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL); + if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + + RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); if ((r = sshbuf_put_bignum2(b, rsa_e)) != 0 || (r = sshbuf_put_bignum2(b, rsa_n)) != 0) return r; @@ -101,10 +87,13 @@ ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b, { int r; const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; + const RSA *rsa; - RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d); - RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); - RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); + if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); + RSA_get0_factors(rsa, &rsa_p, &rsa_q); + RSA_get0_crt_params(rsa, NULL, NULL, &rsa_iqmp); if (!sshkey_is_cert(key)) { /* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */ @@ -124,28 +113,36 @@ ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b, static int ssh_rsa_generate(struct sshkey *k, int bits) { - RSA *private = NULL; - BIGNUM *f4 = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *res = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_KEY_LENGTH; - if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { + + if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - if (!BN_set_word(f4, RSA_F4) || - !RSA_generate_key_ex(private, bits, f4, NULL)) { + if (EVP_PKEY_keygen_init(ctx) <= 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - k->rsa = private; - private = NULL; + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) { + ret = SSH_ERR_KEY_LENGTH; + goto out; + } + if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == NULL) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + /* success */ + k->pkey = res; ret = 0; out: - RSA_free(private); - BN_free(f4); + EVP_PKEY_CTX_free(ctx); return ret; } @@ -155,21 +152,33 @@ ssh_rsa_copy_public(const struct sshkey *from, struct sshkey *to) const BIGNUM *rsa_n, *rsa_e; BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL; int r = SSH_ERR_INTERNAL_ERROR; + const RSA *rsa_from; + RSA *rsa_to = NULL; - RSA_get0_key(from->rsa, &rsa_n, &rsa_e, NULL); + if ((rsa_from = EVP_PKEY_get0_RSA(from->pkey)) == NULL || + (rsa_to = RSA_new()) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + + RSA_get0_key(rsa_from, &rsa_n, &rsa_e, NULL); if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || (rsa_e_dup = BN_dup(rsa_e)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } - if (!RSA_set0_key(to->rsa, rsa_n_dup, rsa_e_dup, NULL)) { + if (!RSA_set0_key(rsa_to, rsa_n_dup, rsa_e_dup, NULL)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_n_dup = rsa_e_dup = NULL; /* transferred */ + + if (EVP_PKEY_set1_RSA(to->pkey, rsa_to) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } /* success */ r = 0; out: + RSA_free(rsa_to); BN_clear_free(rsa_n_dup); BN_clear_free(rsa_e_dup); return r; @@ -181,25 +190,34 @@ ssh_rsa_deserialize_public(const char *ktype, struct sshbuf *b, { int ret = SSH_ERR_INTERNAL_ERROR; BIGNUM *rsa_n = NULL, *rsa_e = NULL; + RSA *rsa = NULL; + + if ((rsa = RSA_new()) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; if (sshbuf_get_bignum2(b, &rsa_e) != 0 || sshbuf_get_bignum2(b, &rsa_n) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } - if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) { + if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_n = rsa_e = NULL; /* transferred */ + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } if ((ret = sshkey_check_rsa_length(key, 0)) != 0) goto out; #ifdef DEBUG_PK - RSA_print_fp(stderr, key->rsa, 8); + RSA_print_fp(stderr, rsa, 8); #endif /* success */ ret = 0; out: + RSA_free(rsa); BN_clear_free(rsa_n); BN_clear_free(rsa_e); return ret; @@ -212,13 +230,25 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b, int r; BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL; + BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; + RSA *rsa = NULL; - /* Note: can't reuse ssh_rsa_deserialize_public: e, n vs. n, e */ - if (!sshkey_is_cert(key)) { + if (sshkey_is_cert(key)) { + /* sshkey_private_deserialize already has pubkey from cert */ + if ((rsa = EVP_PKEY_get1_RSA(key->pkey)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + } else { + if ((rsa = RSA_new()) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + /* Note: can't reuse ssh_rsa_deserialize_public: e,n vs. n,e */ if ((r = sshbuf_get_bignum2(b, &rsa_n)) != 0 || (r = sshbuf_get_bignum2(b, &rsa_e)) != 0) goto out; - if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) { + if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -229,33 +259,46 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b, (r = sshbuf_get_bignum2(b, &rsa_p)) != 0 || (r = sshbuf_get_bignum2(b, &rsa_q)) != 0) goto out; - if (!RSA_set0_key(key->rsa, NULL, NULL, rsa_d)) { + if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, + rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) + goto out; + if (!RSA_set0_key(rsa, NULL, NULL, rsa_d)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_d = NULL; /* transferred */ - if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) { + if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_p = rsa_q = NULL; /* transferred */ - if ((r = sshkey_check_rsa_length(key, 0)) != 0) - goto out; - if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) - goto out; - if (RSA_blinding_on(key->rsa, NULL) != 1) { + if (!RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } + rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; + if (RSA_blinding_on(rsa, NULL) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if ((r = sshkey_check_rsa_length(key, 0)) != 0) + goto out; /* success */ r = 0; out: + RSA_free(rsa); BN_clear_free(rsa_n); BN_clear_free(rsa_e); BN_clear_free(rsa_d); BN_clear_free(rsa_p); BN_clear_free(rsa_q); BN_clear_free(rsa_iqmp); + BN_clear_free(rsa_dmp1); + BN_clear_free(rsa_dmq1); return r; } @@ -310,45 +353,23 @@ rsa_hash_id_from_keyname(const char *alg) return -1; } -static int -rsa_hash_alg_nid(int type) -{ - switch (type) { - case SSH_DIGEST_SHA1: - return NID_sha1; - case SSH_DIGEST_SHA256: - return NID_sha256; - case SSH_DIGEST_SHA512: - return NID_sha512; - default: - return -1; - } -} - int -ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) +ssh_rsa_complete_crt_parameters(const BIGNUM *rsa_d, const BIGNUM *rsa_p, + const BIGNUM *rsa_q, const BIGNUM *rsa_iqmp, BIGNUM **rsa_dmp1, + BIGNUM **rsa_dmq1) { - const BIGNUM *rsa_p, *rsa_q, *rsa_d; BIGNUM *aux = NULL, *d_consttime = NULL; - BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL; BN_CTX *ctx = NULL; int r; - if (key == NULL || key->rsa == NULL || - sshkey_type_plain(key->type) != KEY_RSA) - return SSH_ERR_INVALID_ARGUMENT; - - RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); - RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); - + *rsa_dmq1 = *rsa_dmp1 = NULL; if ((ctx = BN_CTX_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((aux = BN_new()) == NULL || - (rsa_dmq1 = BN_new()) == NULL || - (rsa_dmp1 = BN_new()) == NULL) + (*rsa_dmq1 = BN_new()) == NULL || + (*rsa_dmp1 = BN_new()) == NULL) return SSH_ERR_ALLOC_FAIL; - if ((d_consttime = BN_dup(rsa_d)) == NULL || - (rsa_iqmp = BN_dup(iqmp)) == NULL) { + if ((d_consttime = BN_dup(rsa_d)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -356,25 +377,17 @@ ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) BN_set_flags(d_consttime, BN_FLG_CONSTTIME); if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) || - (BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) || + (BN_mod(*rsa_dmq1, d_consttime, aux, ctx) == 0) || (BN_sub(aux, rsa_p, BN_value_one()) == 0) || - (BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) { + (BN_mod(*rsa_dmp1, d_consttime, aux, ctx) == 0)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */ /* success */ r = 0; out: BN_clear_free(aux); BN_clear_free(d_consttime); - BN_clear_free(rsa_dmp1); - BN_clear_free(rsa_dmq1); - BN_clear_free(rsa_iqmp); BN_CTX_free(ctx); return r; } @@ -386,11 +399,10 @@ ssh_rsa_sign(struct sshkey *key, const u_char *data, size_t datalen, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { - const BIGNUM *rsa_n; - u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; - size_t slen = 0; - u_int hlen, len; - int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; + u_char *sig = NULL; + size_t diff, len = 0; + int slen = 0; + int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; if (lenp != NULL) @@ -402,41 +414,28 @@ ssh_rsa_sign(struct sshkey *key, hash_alg = SSH_DIGEST_SHA1; else hash_alg = rsa_hash_id_from_keyname(alg); - if (key == NULL || key->rsa == NULL || hash_alg == -1 || + + if (key == NULL || key->pkey == NULL || hash_alg == -1 || sshkey_type_plain(key->type) != KEY_RSA) return SSH_ERR_INVALID_ARGUMENT; - RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); - if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_KEY_LENGTH; - slen = RSA_size(key->rsa); + slen = EVP_PKEY_size(key->pkey); if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) return SSH_ERR_INVALID_ARGUMENT; + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_KEY_LENGTH; - /* hash the data */ - nid = rsa_hash_alg_nid(hash_alg); - if ((hlen = ssh_digest_bytes(hash_alg)) == 0) - return SSH_ERR_INTERNAL_ERROR; - if ((ret = ssh_digest_memory(hash_alg, data, datalen, - digest, sizeof(digest))) != 0) + if ((ret = sshkey_pkey_digest_sign(key->pkey, hash_alg, &sig, &len, + data, datalen)) < 0) goto out; - - if ((sig = malloc(slen)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } - - if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (len < slen) { - size_t diff = slen - len; + if (len < (size_t)slen) { + diff = slen - len; memmove(sig + diff, sig, len); explicit_bzero(sig, diff); - } else if (len > slen) { + } else if (len > (size_t)slen) { ret = SSH_ERR_INTERNAL_ERROR; goto out; } + /* encode signature */ if ((b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; @@ -457,7 +456,6 @@ ssh_rsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - explicit_bzero(digest, sizeof(digest)); freezero(sig, slen); sshbuf_free(b); return ret; @@ -469,19 +467,17 @@ ssh_rsa_verify(const struct sshkey *key, const u_char *data, size_t dlen, const char *alg, u_int compat, struct sshkey_sig_details **detailsp) { - const BIGNUM *rsa_n; char *sigtype = NULL; int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; - size_t len = 0, diff, modlen, hlen; + size_t len = 0, diff, modlen, rsasize; struct sshbuf *b = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; - if (key == NULL || key->rsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_RSA || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; - RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); - if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) return SSH_ERR_KEY_LENGTH; if ((b = sshbuf_from(sig, siglen)) == NULL) @@ -517,7 +513,7 @@ ssh_rsa_verify(const struct sshkey *key, goto out; } /* RSA_verify expects a signature of RSA_size */ - modlen = RSA_size(key->rsa); + modlen = EVP_PKEY_size(key->pkey); if (len > modlen) { ret = SSH_ERR_KEY_BITS_MISMATCH; goto out; @@ -533,16 +529,16 @@ ssh_rsa_verify(const struct sshkey *key, explicit_bzero(sigblob, diff); len = modlen; } - if ((hlen = ssh_digest_bytes(hash_alg)) == 0) { - ret = SSH_ERR_INTERNAL_ERROR; + + rsasize = EVP_PKEY_size(key->pkey); + if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || + len == 0 || len > rsasize) { + ret = SSH_ERR_INVALID_ARGUMENT; goto out; } - if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) - goto out; + ret = sshkey_pkey_digest_verify(key->pkey, hash_alg, data, dlen, + sigblob, len); - ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len, - key->rsa); out: freezero(sigblob, len); free(sigtype); @@ -551,125 +547,6 @@ ssh_rsa_verify(const struct sshkey *key, return ret; } -/* - * See: - * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn - */ - -/* - * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) - * oiw(14) secsig(3) algorithms(2) 26 } - */ -static const u_char id_sha1[] = { - 0x30, 0x21, /* type Sequence, length 0x21 (33) */ - 0x30, 0x09, /* type Sequence, length 0x09 */ - 0x06, 0x05, /* type OID, length 0x05 */ - 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ - 0x05, 0x00, /* NULL */ - 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ -}; - -/* - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html - * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) - * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) - * id-sha256(1) } - */ -static const u_char id_sha256[] = { - 0x30, 0x31, /* type Sequence, length 0x31 (49) */ - 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ - 0x06, 0x09, /* type OID, length 0x09 */ - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ - 0x05, 0x00, /* NULL */ - 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */ -}; - -/* - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html - * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) - * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) - * id-sha256(3) } - */ -static const u_char id_sha512[] = { - 0x30, 0x51, /* type Sequence, length 0x51 (81) */ - 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ - 0x06, 0x09, /* type OID, length 0x09 */ - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */ - 0x05, 0x00, /* NULL */ - 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */ -}; - -static int -rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp) -{ - switch (hash_alg) { - case SSH_DIGEST_SHA1: - *oidp = id_sha1; - *oidlenp = sizeof(id_sha1); - break; - case SSH_DIGEST_SHA256: - *oidp = id_sha256; - *oidlenp = sizeof(id_sha256); - break; - case SSH_DIGEST_SHA512: - *oidp = id_sha512; - *oidlenp = sizeof(id_sha512); - break; - default: - return SSH_ERR_INVALID_ARGUMENT; - } - return 0; -} - -static int -openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, - u_char *sigbuf, size_t siglen, RSA *rsa) -{ - size_t rsasize = 0, oidlen = 0, hlen = 0; - int ret, len, oidmatch, hashmatch; - const u_char *oid = NULL; - u_char *decrypted = NULL; - - if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0) - return ret; - ret = SSH_ERR_INTERNAL_ERROR; - hlen = ssh_digest_bytes(hash_alg); - if (hashlen != hlen) { - ret = SSH_ERR_INVALID_ARGUMENT; - goto done; - } - rsasize = RSA_size(rsa); - if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || - siglen == 0 || siglen > rsasize) { - ret = SSH_ERR_INVALID_ARGUMENT; - goto done; - } - if ((decrypted = malloc(rsasize)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto done; - } - if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, - RSA_PKCS1_PADDING)) < 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto done; - } - if (len < 0 || (size_t)len != hlen + oidlen) { - ret = SSH_ERR_INVALID_FORMAT; - goto done; - } - oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0; - hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0; - if (!oidmatch || !hashmatch) { - ret = SSH_ERR_SIGNATURE_INVALID; - goto done; - } - ret = 0; -done: - freezero(decrypted, rsasize); - return ret; -} - static const struct sshkey_impl_funcs sshkey_rsa_funcs = { /* .size = */ ssh_rsa_size, /* .alloc = */ ssh_rsa_alloc, diff --git a/usr.bin/ssh/ssh-sk.c b/usr.bin/ssh/ssh-sk.c index d6eea2e05..2b36b3ff9 100644 --- a/usr.bin/ssh/ssh-sk.c +++ b/usr.bin/ssh/ssh-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-sk.c,v 1.40 2023/07/19 14:02:27 djm Exp $ */ +/* $OpenBSD: ssh-sk.c,v 1.41 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -26,6 +26,7 @@ #ifdef WITH_OPENSSL #include #include +#include #endif /* WITH_OPENSSL */ #include "log.h" @@ -188,7 +189,9 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp) { struct sshkey *key = NULL; struct sshbuf *b = NULL; + EC_KEY *ecdsa = NULL; EC_POINT *q = NULL; + const EC_GROUP *g = NULL; int r; *keyp = NULL; @@ -198,8 +201,9 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp) goto out; } key->ecdsa_nid = NID_X9_62_prime256v1; - if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || - (q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL || + if ((ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || + (g = EC_KEY_get0_group(ecdsa)) == NULL || + (q = EC_POINT_new(g)) == NULL || (b = sshbuf_new()) == NULL) { error_f("allocation failed"); r = SSH_ERR_ALLOC_FAIL; @@ -210,30 +214,41 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp) error_fr(r, "sshbuf_put_string"); goto out; } - if ((r = sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa))) != 0) { + if ((r = sshbuf_get_ec(b, q, g)) != 0) { error_fr(r, "parse"); r = SSH_ERR_INVALID_FORMAT; goto out; } - if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) { + if (sshkey_ec_validate_public(g, q) != 0) { error("Authenticator returned invalid ECDSA key"); r = SSH_ERR_KEY_INVALID_EC_VALUE; goto out; } - if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { + if (EC_KEY_set_public_key(ecdsa, q) != 1) { /* XXX assume it is a allocation error */ error_f("allocation failed"); r = SSH_ERR_ALLOC_FAIL; goto out; } + if ((key->pkey = EVP_PKEY_new()) == NULL) { + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(key->pkey, ecdsa) != 1) { + error_f("Assigning EC_KEY failed"); + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } /* success */ *keyp = key; key = NULL; /* transferred */ r = 0; out: - EC_POINT_free(q); sshkey_free(key); sshbuf_free(b); + EC_KEY_free(ecdsa); + EC_POINT_free(q); return r; } #endif /* WITH_OPENSSL */ diff --git a/usr.bin/ssh/sshbuf-getput-crypto.c b/usr.bin/ssh/sshbuf-getput-crypto.c index 02daaa11b..dad46c956 100644 --- a/usr.bin/ssh/sshbuf-getput-crypto.c +++ b/usr.bin/ssh/sshbuf-getput-crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-getput-crypto.c,v 1.11 2024/02/01 02:37:33 djm Exp $ */ +/* $OpenBSD: sshbuf-getput-crypto.c,v 1.12 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -169,3 +169,12 @@ sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v) EC_KEY_get0_group(v)); } +int +sshbuf_put_ec_pkey(struct sshbuf *buf, EVP_PKEY *pkey) +{ + const EC_KEY *ec; + + if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + return sshbuf_put_eckey(buf, ec); +} diff --git a/usr.bin/ssh/sshbuf.h b/usr.bin/ssh/sshbuf.h index 37c28a127..b159e8899 100644 --- a/usr.bin/ssh/sshbuf.h +++ b/usr.bin/ssh/sshbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.h,v 1.28 2022/12/02 04:40:27 djm Exp $ */ +/* $OpenBSD: sshbuf.h,v 1.29 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -26,11 +26,13 @@ #include #include #include +#include #else /* OPENSSL */ #define BIGNUM void #define EC_KEY void #define EC_GROUP void #define EC_POINT void +#define EVP_PKEY void #endif /* WITH_OPENSSL */ #define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */ @@ -226,6 +228,7 @@ int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g); int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v); int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g); int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v); +int sshbuf_put_ec_pkey(struct sshbuf *buf, EVP_PKEY *pkey); /* Dump the contents of the buffer in a human-readable format */ void sshbuf_dump(const struct sshbuf *buf, FILE *f); diff --git a/usr.bin/ssh/sshkey.c b/usr.bin/ssh/sshkey.c index 5203cc663..ef9c85845 100644 --- a/usr.bin/ssh/sshkey.c +++ b/usr.bin/ssh/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.142 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.143 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -460,6 +460,98 @@ sshkey_type_certified(int type) } #ifdef WITH_OPENSSL +static const EVP_MD * +ssh_digest_to_md(int hash_alg) +{ + switch (hash_alg) { + case SSH_DIGEST_SHA1: + return EVP_sha1(); + case SSH_DIGEST_SHA256: + return EVP_sha256(); + case SSH_DIGEST_SHA384: + return EVP_sha384(); + case SSH_DIGEST_SHA512: + return EVP_sha512(); + } + return NULL; +} + +int +sshkey_pkey_digest_sign(EVP_PKEY *pkey, int hash_alg, u_char **sigp, + size_t *lenp, const u_char *data, size_t datalen) +{ + EVP_MD_CTX *ctx = NULL; + u_char *sig = NULL; + int ret; + size_t slen; + const EVP_MD *evpmd; + + *sigp = NULL; + *lenp = 0; + + slen = EVP_PKEY_size(pkey); + if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM || + (evpmd = ssh_digest_to_md(hash_alg)) == NULL) + return SSH_ERR_INVALID_ARGUMENT; + + if ((sig = malloc(slen)) == NULL) + return SSH_ERR_ALLOC_FAIL; + + if ((ctx = EVP_MD_CTX_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_DigestSignInit(ctx, NULL, evpmd, NULL, pkey) != 1 || + EVP_DigestSign(ctx, sig, &slen, data, datalen) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + + *sigp = sig; + *lenp = slen; + /* Now owned by the caller */ + sig = NULL; + ret = 0; + + out: + EVP_MD_CTX_free(ctx); + free(sig); + return ret; +} + +int +sshkey_pkey_digest_verify(EVP_PKEY *pkey, int hash_alg, const u_char *data, + size_t datalen, u_char *sigbuf, size_t siglen) +{ + EVP_MD_CTX *ctx = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + const EVP_MD *evpmd; + + if ((evpmd = ssh_digest_to_md(hash_alg)) == NULL) + return SSH_ERR_INVALID_ARGUMENT; + if ((ctx = EVP_MD_CTX_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if (EVP_DigestVerifyInit(ctx, NULL, evpmd, NULL, pkey) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + switch (EVP_DigestVerify(ctx, sigbuf, siglen, data, datalen)) { + case 1: + ret = 0; + break; + case 0: + ret = SSH_ERR_SIGNATURE_INVALID; + break; + default: + ret = SSH_ERR_LIBCRYPTO_ERROR; + break; + } + + out: + EVP_MD_CTX_free(ctx); + return ret; +} + /* XXX: these are really begging for a table-driven approach */ int sshkey_curve_name_to_nid(const char *name) @@ -1302,14 +1394,12 @@ int sshkey_check_rsa_length(const struct sshkey *k, int min_size) { #ifdef WITH_OPENSSL - const BIGNUM *rsa_n; int nbits; - if (k == NULL || k->rsa == NULL || + if (k == NULL || k->pkey == NULL || (k->type != KEY_RSA && k->type != KEY_RSA_CERT)) return 0; - RSA_get0_key(k->rsa, &rsa_n, NULL, NULL); - nbits = BN_num_bits(rsa_n); + nbits = EVP_PKEY_bits(k->pkey); if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE || (min_size > 0 && nbits < min_size)) return SSH_ERR_KEY_LENGTH; @@ -1319,45 +1409,22 @@ sshkey_check_rsa_length(const struct sshkey *k, int min_size) #ifdef WITH_OPENSSL int -sshkey_ecdsa_key_to_nid(EC_KEY *k) +sshkey_ecdsa_key_to_nid(const EC_KEY *k) { - EC_GROUP *eg; - int nids[] = { - NID_X9_62_prime256v1, - NID_secp384r1, - NID_secp521r1, - -1 - }; + const EC_GROUP *g; int nid; - u_int i; - const EC_GROUP *g = EC_KEY_get0_group(k); - /* - * The group may be stored in a ASN.1 encoded private key in one of two - * ways: as a "named group", which is reconstituted by ASN.1 object ID - * or explicit group parameters encoded into the key blob. Only the - * "named group" case sets the group NID for us, but we can figure - * it out for the other case by comparing against all the groups that - * are supported. - */ - if ((nid = EC_GROUP_get_curve_name(g)) > 0) - return nid; - for (i = 0; nids[i] != -1; i++) { - if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) - return -1; - if (EC_GROUP_cmp(g, eg, NULL) == 0) - break; - EC_GROUP_free(eg); - } - if (nids[i] != -1) { - /* Use the group with the NID attached */ - EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(k, eg) != 1) { - EC_GROUP_free(eg); - return -1; - } - } - return nids[i]; + if (k == NULL || (g = EC_KEY_get0_group(k)) == NULL) + return -1; + if ((nid = EC_GROUP_get_curve_name(g)) <= 0) + return -1; + return nid; +} + +int +sshkey_ecdsa_pkey_to_nid(EVP_PKEY *pkey) +{ + return sshkey_ecdsa_key_to_nid(EVP_PKEY_get0_EC_KEY(pkey)); } #endif /* WITH_OPENSSL */ @@ -3193,10 +3260,6 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, r = SSH_ERR_ALLOC_FAIL; goto out; } - if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } if ((r = sshkey_unshield_private(key)) != 0) goto out; @@ -3207,24 +3270,34 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, cipher, passphrase, len, NULL, NULL); } else { + if ((pkey = EVP_PKEY_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } success = EVP_PKEY_set1_DSA(pkey, key->dsa); } break; #endif case KEY_ECDSA: if (format == SSHKEY_PRIVATE_PEM) { - success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, + success = PEM_write_bio_ECPrivateKey(bio, + EVP_PKEY_get0_EC_KEY(key->pkey), cipher, passphrase, len, NULL, NULL); } else { - success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); + pkey = key->pkey; + EVP_PKEY_up_ref(key->pkey); + success = 1; } break; case KEY_RSA: if (format == SSHKEY_PRIVATE_PEM) { - success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, + success = PEM_write_bio_RSAPrivateKey(bio, + EVP_PKEY_get0_RSA(key->pkey), cipher, passphrase, len, NULL, NULL); } else { - success = EVP_PKEY_set1_RSA(pkey, key->rsa); + pkey = key->pkey; + EVP_PKEY_up_ref(key->pkey); + success = 1; } break; default: @@ -3373,6 +3446,8 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, struct sshkey *prv = NULL; BIO *bio = NULL; int r; + RSA *rsa = NULL; + EC_KEY *ecdsa = NULL; if (keyp != NULL) *keyp = NULL; @@ -3406,15 +3481,21 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_ALLOC_FAIL; goto out; } - prv->rsa = EVP_PKEY_get1_RSA(pk); - prv->type = KEY_RSA; -#ifdef DEBUG_PK - RSA_print_fp(stderr, prv->rsa, 8); -#endif - if (RSA_blinding_on(prv->rsa, NULL) != 1) { + if ((rsa = EVP_PKEY_get1_RSA(pk)) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } + prv->type = KEY_RSA; +#ifdef DEBUG_PK + RSA_print_fp(stderr, rsa, 8); +#endif + if (RSA_blinding_on(rsa, NULL) != 1 || + EVP_PKEY_set1_RSA(pk, rsa) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + EVP_PKEY_up_ref(pk); + prv->pkey = pk; if ((r = sshkey_check_rsa_length(prv, 0)) != 0) goto out; #ifdef WITH_DSA @@ -3436,20 +3517,24 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_ALLOC_FAIL; goto out; } - prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); + if ((prv->ecdsa_nid = sshkey_ecdsa_fixup_group(pk)) == -1 || + (ecdsa = EVP_PKEY_get1_EC_KEY(pk)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } prv->type = KEY_ECDSA; - prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); - if (prv->ecdsa_nid == -1 || - sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || - sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), - EC_KEY_get0_public_key(prv->ecdsa)) != 0 || - sshkey_ec_validate_private(prv->ecdsa) != 0) { + if (sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || + sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), + EC_KEY_get0_public_key(ecdsa)) != 0 || + sshkey_ec_validate_private(ecdsa) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } + EVP_PKEY_up_ref(pk); + prv->pkey = pk; #ifdef DEBUG_PK - if (prv != NULL && prv->ecdsa != NULL) - sshkey_dump_ec_key(prv->ecdsa); + if (prv != NULL && prv->pkey != NULL) + sshkey_dump_ec_key(EVP_PKEY_get0_EC_KEY(prv->pkey)); #endif } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_ED25519 && (type == KEY_UNSPEC || type == KEY_ED25519)) { @@ -3498,6 +3583,8 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, out: BIO_free(bio); EVP_PKEY_free(pk); + RSA_free(rsa); + EC_KEY_free(ecdsa); sshkey_free(prv); return r; } diff --git a/usr.bin/ssh/sshkey.h b/usr.bin/ssh/sshkey.h index e6877becd..21298c6f2 100644 --- a/usr.bin/ssh/sshkey.h +++ b/usr.bin/ssh/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.63 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: sshkey.h,v 1.64 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -33,6 +33,7 @@ #include #include #include +#include #define SSH_OPENSSL_VERSION OpenSSL_version(OPENSSL_VERSION) #else /* OPENSSL */ #define BIGNUM void @@ -41,6 +42,7 @@ #define EC_KEY void #define EC_GROUP void #define EC_POINT void +#define EVP_PKEY void #define SSH_OPENSSL_VERSION "without OpenSSL" #endif /* WITH_OPENSSL */ @@ -119,13 +121,12 @@ struct sshkey_cert { struct sshkey { int type; int flags; - /* KEY_RSA */ - RSA *rsa; /* KEY_DSA */ DSA *dsa; /* KEY_ECDSA and KEY_ECDSA_SK */ int ecdsa_nid; /* NID of curve */ - EC_KEY *ecdsa; + /* libcrypto-backed keys */ + EVP_PKEY *pkey; /* KEY_ED25519 and KEY_ED25519_SK */ u_char *ed25519_sk; u_char *ed25519_pk; @@ -252,7 +253,8 @@ int sshkey_curve_name_to_nid(const char *); const char * sshkey_curve_nid_to_name(int); u_int sshkey_curve_nid_to_bits(int); int sshkey_ecdsa_bits_to_nid(int); -int sshkey_ecdsa_key_to_nid(EC_KEY *); +int sshkey_ecdsa_key_to_nid(const EC_KEY *); +int sshkey_ecdsa_pkey_to_nid(EVP_PKEY *); int sshkey_ec_nid_to_hash_alg(int nid); int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *); int sshkey_ec_validate_private(const EC_KEY *); @@ -281,6 +283,12 @@ int sshkey_check_sigtype(const u_char *, size_t, const char *); const char *sshkey_sigalg_by_name(const char *); int sshkey_get_sigtype(const u_char *, size_t, char **); +/* Signing and verification backend for libcrypto-backed keys */ +int sshkey_pkey_digest_sign(EVP_PKEY*, int, u_char **, + size_t *, const u_char *, size_t); +int sshkey_pkey_digest_verify(EVP_PKEY *, int, const u_char *, + size_t, u_char *, size_t); + /* for debug */ void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); void sshkey_dump_ec_key(const EC_KEY *); @@ -304,7 +312,8 @@ int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int sshkey_check_rsa_length(const struct sshkey *, int); /* XXX should be internal, but used by ssh-keygen */ -int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); +int ssh_rsa_complete_crt_parameters(const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, BIGNUM **, BIGNUM **); /* stateful keys (e.g. XMSS) */ int sshkey_set_filename(struct sshkey *, const char *); @@ -315,6 +324,10 @@ int sshkey_private_serialize_maxsign(struct sshkey *key, void sshkey_sig_details_free(struct sshkey_sig_details *); +#ifdef WITH_OPENSSL +int sshkey_ecdsa_fixup_group(EVP_PKEY *k); /* ssh-ecdsa.c */ +#endif + #ifdef SSHKEY_INTERNAL int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); void sshkey_sk_cleanup(struct sshkey *k); @@ -335,6 +348,7 @@ int check_rsa_length(const RSA *rsa); /* XXX remove */ #undef EC_KEY #undef EC_GROUP #undef EC_POINT +#undef EVP_PKEY #endif /* WITH_OPENSSL */ #endif /* SSHKEY_H */ diff --git a/usr.sbin/bgplgd/bgplgd.8 b/usr.sbin/bgplgd/bgplgd.8 index 2b62b7785..fb3d0db12 100644 --- a/usr.sbin/bgplgd/bgplgd.8 +++ b/usr.sbin/bgplgd/bgplgd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgplgd.8,v 1.8 2024/01/26 18:11:49 job Exp $ +.\" $OpenBSD: bgplgd.8,v 1.9 2024/08/15 09:13:13 claudio Exp $ .\" .\" Copyright (c) 2021 Claudio Jeker .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 26 2024 $ +.Dd $Mdocdate: August 15 2024 $ .Dt BGPLGD 8 .Os .Sh NAME @@ -148,6 +148,8 @@ Show only prefixes that match the specified ASPA Validation State. Show only selected routes. .It Cm error Ns = Ns 1 Show only prefixes which are marked invalid and were treated as withdrawn. +.It Cm filtered Ns = Ns 1 +Show only prefixes which are marked filtered by the input filter. .It Cm invalid Ns = Ns 1 Show only prefixes which are not eligible. .It Cm leaked Ns = Ns 1 diff --git a/usr.sbin/bgplgd/bgplgd.h b/usr.sbin/bgplgd/bgplgd.h index 1a6603786..4cf62b73a 100644 --- a/usr.sbin/bgplgd/bgplgd.h +++ b/usr.sbin/bgplgd/bgplgd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgplgd.h,v 1.3 2023/03/13 17:31:28 claudio Exp $ */ +/* $OpenBSD: bgplgd.h,v 1.4 2024/08/15 09:13:13 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker * @@ -32,7 +32,8 @@ #define QS_AVS 15 #define QS_INVALID 16 #define QS_LEAKED 17 -#define QS_MAX 18 +#define QS_FILTERED 18 +#define QS_MAX 19 /* too add: empty-as, in, out, peer-as, source-as, transit-as */ @@ -44,7 +45,7 @@ (1 << QS_AF) | (1 << QS_RIB) | (1 << QS_OVS) | \ (1 << QS_BEST) | (1 << QS_ALL) | (1 << QS_SHORTER) | \ (1 << QS_ERROR) | (1 << QS_AVS) | (1 << QS_INVALID) | \ - (1 << QS_LEAKED)) + (1 << QS_LEAKED) | (1 << QS_FILTERED)) struct cmd; struct lg_ctx { diff --git a/usr.sbin/bgplgd/qs.c b/usr.sbin/bgplgd/qs.c index 0aa10f6d4..ee865810f 100644 --- a/usr.sbin/bgplgd/qs.c +++ b/usr.sbin/bgplgd/qs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qs.c,v 1.5 2023/05/09 14:35:45 claudio Exp $ */ +/* $OpenBSD: qs.c,v 1.6 2024/08/15 09:13:13 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker * @@ -57,6 +57,7 @@ const struct qs { { QS_AVS, "avs", AVS }, { QS_INVALID, "invalid", ONE }, { QS_LEAKED, "leaked", ONE }, + { QS_FILTERED, "filtered", ONE }, { 0, NULL } }; @@ -382,13 +383,16 @@ qs_argv(char **argv, size_t argc, size_t len, struct lg_ctx *ctx, int barenbr) if (argc < len) argv[argc++] = ctx->qs_args[QS_AVS].string; } - /* BEST, ERROR, INVALID and LEAKED are exclusive */ + /* BEST, ERROR, FILTERED, INVALID and LEAKED are exclusive */ if (ctx->qs_args[QS_BEST].one) { if (argc < len) argv[argc++] = "best"; } else if (ctx->qs_args[QS_ERROR].one) { if (argc < len) argv[argc++] = "error"; + } else if (ctx->qs_args[QS_FILTERED].one) { + if (argc < len) + argv[argc++] = "filtered"; } else if (ctx->qs_args[QS_INVALID].one) { if (argc < len) argv[argc++] = "disqualified"; diff --git a/usr.sbin/radiusd/parse.y b/usr.sbin/radiusd/parse.y index ec062b0f1..cd1fe7a0d 100644 --- a/usr.sbin/radiusd/parse.y +++ b/usr.sbin/radiusd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.26 2024/07/14 16:09:23 yasuoka Exp $ */ +/* $OpenBSD: parse.y,v 1.27 2024/08/15 07:24:28 yasuoka Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -451,7 +451,8 @@ authopts : authopts '\n' authopt | authopt ; -authopt : AUTHENTICATE_BY STRING { +authopt : /* empty */ + | AUTHENTICATE_BY STRING { struct radiusd_module_ref *modref; if (authen.auth != NULL) { diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index f722f9e95..da095f9cf 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.262 2024/07/12 09:27:32 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.263 2024/08/15 09:22:12 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -1285,14 +1285,14 @@ main(int argc, char *argv[]) while (entity_queue > 0 && !killme) { int polltim; + polltim = repo_check_timeout(INFTIM); + for (i = 0; i < NPFD; i++) { pfd[i].events = POLLIN; if (queues[i]->queued) pfd[i].events |= POLLOUT; } - polltim = repo_check_timeout(INFTIM); - if (poll(pfd, NPFD, polltim) == -1) { if (errno == EINTR) continue; diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c index ce97015ae..0d6777792 100644 --- a/usr.sbin/rpki-client/repo.c +++ b/usr.sbin/rpki-client/repo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: repo.c,v 1.61 2024/07/12 09:27:32 claudio Exp $ */ +/* $OpenBSD: repo.c,v 1.62 2024/08/15 11:30:43 job Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -1376,12 +1376,15 @@ repo_abort(struct repo *rp) /* reset the alarm */ rp->alarm = getmonotime() + repo_timeout; - if (rp->rsync) + if (rp->rsync) { + warnx("%s: synchronisation timeout", rp->repouri); rsync_abort(rp->rsync->id); - else if (rp->rrdp) + } else if (rp->rrdp) { + warnx("%s: synchronisation timeout", rp->notifyuri); rrdp_abort(rp->rrdp->id); - else - repo_fail(rp); + } + + repo_fail(rp); } int @@ -1412,11 +1415,9 @@ repo_check_timeout(int timeout) /* Look up in repository table. (Lookup should actually fail here) */ SLIST_FOREACH(rp, &repos, entry) { if (repo_state(rp) == REPO_LOADING) { - if (rp->alarm <= now) { - warnx("%s: synchronisation timeout", - rp->repouri); + if (rp->alarm <= now) repo_abort(rp); - } else { + else { diff = rp->alarm - now; diff *= 1000; if (timeout == INFTIM || diff < timeout)